From de35b077a2b4eed2f7b19b4ab86536a6cb0617e1 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Mon, 30 Sep 2013 13:56:54 +0200 Subject: [PATCH] disallow yield in non-yield-fixtures for now. This is an incompataibility but we want to prepare for possibly merging fixture and yield_fixture some day. --- CHANGELOG | 12 +++++++++--- _pytest/python.py | 5 +++++ testing/python/fixture.py | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 57f8b8369..49212fcb1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,12 +14,18 @@ known incompatibilities: - the pytest_plugin_unregister hook wasn't ever properly called and there is no known implementation of the hook - so it got removed. +- pytest.fixture-decorated functions cannot be generators (i.e. use yield) anymore. + This change might be reversed in 2.4.1 if it causes unforeseen real-life issues. + However, you can always write and return an inner function/generator + and change the fixture consumer to iterate over the returned generator. + This change was done in lieu of the new ``pytest.yield_fixture`` decorator, see below. + new features: -- experimentally introduce a new pytest.yield_fixture decorator which - has exactly the same parameters as pytest.fixture but expects +- experimentally introduce a new ``pytest.yield_fixture`` decorator which + accepts exactly the same parameters as pytest.fixture but mandates a ``yield`` statement instead of a ``return statement`` from fixture functions. - This allows direct integration with with-context managers + This allows direct integration with "with-style" context managers in fixture functions and generally avoids registering of finalization callbacks in favour of treating the "after-yield" as teardown code. Thanks Andreas Pelme, Vladimir Keleshev, Floris Bruynooghe, Ronny Pfannschmidt diff --git a/_pytest/python.py b/_pytest/python.py index 7557ef10c..7ec148ff1 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1705,6 +1705,11 @@ def call_fixture_func(fixturefunc, request, kwargs, yieldctx): "yield_fixture function has more than one 'yield'") request.addfinalizer(teardown) else: + if is_generator(fixturefunc): + fail_fixturefunc(fixturefunc, + msg="pytest.fixture functions cannot use ``yield``. " + "Instead write and return an inner function/generator " + "and let the consumer call and iterate over it.") res = fixturefunc(**kwargs) return res diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 8e1970913..cf30aefbe 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -2087,3 +2087,18 @@ class TestContextManagerFixtureFuncs: *def arg1* """) + def test_yield_not_allowed_in_non_yield(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope="module") + def arg1(): + yield 1 + def test_1(arg1): + pass + """) + result = testdir.runpytest("-s") + result.stdout.fnmatch_lines(""" + *fixture*cannot use*yield* + *def arg1* + """) +