From 8b4c1c9da2514cd4cd846a7d9d5476f3b9f29aef Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sat, 31 Oct 2020 22:44:10 +0200 Subject: [PATCH] fixtures: deprecate pytest.yield_fixture() --- changelog/TBD.deprecation.rst | 3 ++ doc/en/deprecations.rst | 8 ++++++ src/_pytest/deprecated.py | 3 ++ src/_pytest/fixtures.py | 2 ++ testing/deprecated_test.py | 8 ++++++ testing/python/fixtures.py | 52 ++++++++++++----------------------- testing/test_unittest.py | 13 ++++----- 7 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 changelog/TBD.deprecation.rst diff --git a/changelog/TBD.deprecation.rst b/changelog/TBD.deprecation.rst new file mode 100644 index 00000000000..34f646c9ab4 --- /dev/null +++ b/changelog/TBD.deprecation.rst @@ -0,0 +1,3 @@ +The ``@pytest.yield_fixture`` decorator/function is now deprecated. Use :func:`pytest.fixture` instead. + +``yield_fixture`` has been an alias for ``fixture`` for a very long time, so can be search/replaced safely. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 14d1eeb98af..6f9549253b6 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -18,6 +18,14 @@ Deprecated Features Below is a complete list of all pytest features which are considered deprecated. Using those features will issue :class:`PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. +The ``yield_fixture`` function/decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 6.2 + +``pytest.yield_fixture`` is a deprecated alias for :func:`pytest.fixture`. + +It has been so for a very long time, so can be search/replaced safely. The ``pytest_warning_captured`` hook ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index fd00fe2d6d5..a2cf27d3d25 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -32,6 +32,9 @@ "Please update to the new name.", ) +YIELD_FIXTURE = PytestDeprecationWarning( + "@pytest.yield_fixture is deprecated.\nUse @pytest.fixture instead." +) MINUS_K_DASH = PytestDeprecationWarning( "The `-k '-expr'` syntax to -k is deprecated.\nUse `-k 'not expr'` instead." diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 18094f21c3b..cef998c03b7 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -50,6 +50,7 @@ from _pytest.config import Config from _pytest.config.argparsing import Parser from _pytest.deprecated import FILLFUNCARGS +from _pytest.deprecated import YIELD_FIXTURE from _pytest.mark import Mark from _pytest.mark import ParameterSet from _pytest.mark.structures import MarkDecorator @@ -1339,6 +1340,7 @@ def yield_fixture( .. deprecated:: 3.0 Use :py:func:`pytest.fixture` directly instead. """ + warnings.warn(YIELD_FIXTURE, stacklevel=2) return fixture( fixture_function, *args, diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 5fe9ad7305f..fc57d6e3d8c 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -95,3 +95,11 @@ def test_foo(): pass session.gethookproxy(testdir.tmpdir) session.isinitpath(testdir.tmpdir) assert len(rec) == 0 + + +def test_yield_fixture_is_deprecated() -> None: + with pytest.warns(DeprecationWarning, match=r"yield_fixture is deprecated"): + + @pytest.yield_fixture + def fix(): + return 42 diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index a4838ee5167..73cff53682d 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -8,6 +8,7 @@ from _pytest.config import ExitCode from _pytest.fixtures import FixtureRequest from _pytest.pytester import get_public_names +from _pytest.pytester import Testdir def test_getfuncargnames_functions(): @@ -3526,28 +3527,11 @@ def foo(): class TestContextManagerFixtureFuncs: - @pytest.fixture(params=["fixture", "yield_fixture"]) - def flavor(self, request, testdir, monkeypatch): - monkeypatch.setenv("PYTEST_FIXTURE_FLAVOR", request.param) - testdir.makepyfile( - test_context=""" - import os - import pytest - import warnings - VAR = "PYTEST_FIXTURE_FLAVOR" - if VAR not in os.environ: - warnings.warn("PYTEST_FIXTURE_FLAVOR was not set, assuming fixture") - fixture = pytest.fixture - else: - fixture = getattr(pytest, os.environ[VAR]) - """ - ) - - def test_simple(self, testdir, flavor): + def test_simple(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture - @fixture + import pytest + @pytest.fixture def arg1(): print("setup") yield 1 @@ -3571,11 +3555,11 @@ def test_2(arg1): """ ) - def test_scoped(self, testdir, flavor): + def test_scoped(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture - @fixture(scope="module") + import pytest + @pytest.fixture(scope="module") def arg1(): print("setup") yield 1 @@ -3596,11 +3580,11 @@ def test_2(arg1): """ ) - def test_setup_exception(self, testdir, flavor): + def test_setup_exception(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture - @fixture(scope="module") + import pytest + @pytest.fixture(scope="module") def arg1(): pytest.fail("setup") yield 1 @@ -3616,11 +3600,11 @@ def test_1(arg1): """ ) - def test_teardown_exception(self, testdir, flavor): + def test_teardown_exception(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture - @fixture(scope="module") + import pytest + @pytest.fixture(scope="module") def arg1(): yield 1 pytest.fail("teardown") @@ -3636,10 +3620,10 @@ def test_1(arg1): """ ) - def test_yields_more_than_one(self, testdir, flavor): + def test_yields_more_than_one(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture + import pytest @fixture(scope="module") def arg1(): yield 1 @@ -3656,11 +3640,11 @@ def test_1(arg1): """ ) - def test_custom_name(self, testdir, flavor): + def test_custom_name(self, testdir: Testdir) -> None: testdir.makepyfile( """ - from test_context import fixture - @fixture(name='meow') + import pytest + @pytest.fixture(name='meow') def arg1(): return 'mew' def test_1(meow): diff --git a/testing/test_unittest.py b/testing/test_unittest.py index f6c8c48eddc..2c8d03cb981 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -4,6 +4,7 @@ import pytest from _pytest.config import ExitCode +from _pytest.pytester import Testdir def test_simple_unittest(testdir): @@ -781,20 +782,18 @@ def test_passing_test_is_fail(self): assert result.ret == 1 -@pytest.mark.parametrize( - "fix_type, stmt", [("fixture", "return"), ("yield_fixture", "yield")] -) -def test_unittest_setup_interaction(testdir, fix_type, stmt): +@pytest.mark.parametrize("stmt", ["return", "yield"]) +def test_unittest_setup_interaction(testdir: Testdir, stmt: str) -> None: testdir.makepyfile( """ import unittest import pytest class MyTestCase(unittest.TestCase): - @pytest.{fix_type}(scope="class", autouse=True) + @pytest.fixture(scope="class", autouse=True) def perclass(self, request): request.cls.hello = "world" {stmt} - @pytest.{fix_type}(scope="function", autouse=True) + @pytest.fixture(scope="function", autouse=True) def perfunction(self, request): request.instance.funcname = request.function.__name__ {stmt} @@ -809,7 +808,7 @@ def test_method2(self): def test_classattr(self): assert self.__class__.hello == "world" """.format( - fix_type=fix_type, stmt=stmt + stmt=stmt ) ) result = testdir.runpytest()