Warn when a mark is applied to a fixture

Fixes #3664
This commit is contained in:
Thomas Grainger 2021-03-10 13:47:14 +00:00
parent 35df3e68d5
commit 3f71680ac0
No known key found for this signature in database
GPG Key ID: E452A1247BAC1A88
6 changed files with 30 additions and 2 deletions

View File

@ -0,0 +1 @@
Deprecate applying a mark to a fixture

View File

@ -1667,8 +1667,7 @@ into an ini-file:
def my_fixture_that_sadly_wont_use_my_other_fixture():
...
Currently this will not generate any error or warning, but this is intended
to be handled by `#3664 <https://github.com/pytest-dev/pytest/issues/3664>`_.
Currently this will generate a deprecation warning.
.. _`override fixtures`:

View File

@ -95,6 +95,8 @@ NODE_FSPATH = UnformattedWarning(
"see https://docs.pytest.org/en/latest/deprecations.html#node-fspath-in-favor-of-pathlib-and-node-path",
)
MARKED_FIXTURE = PytestDeprecationWarning("Marks cannot be applied to fixtures")
# You want to make some `__init__` or function "private".
#
# def my_private_function(some, args):

View File

@ -54,6 +54,7 @@ from _pytest.config import Config
from _pytest.config.argparsing import Parser
from _pytest.deprecated import check_ispytest
from _pytest.deprecated import FILLFUNCARGS
from _pytest.deprecated import MARKED_FIXTURE
from _pytest.deprecated import NODE_FSPATH
from _pytest.deprecated import YIELD_FIXTURE
from _pytest.mark import Mark
@ -1222,6 +1223,9 @@ class FixtureFunctionMarker:
"fixture is being applied more than once to the same function"
)
if hasattr(function, "pytestmark"):
warnings.warn(MARKED_FIXTURE, stacklevel=2)
function = wrap_function_to_error_out_if_called_directly(function, self)
name = self.name or function.__name__

View File

@ -29,6 +29,7 @@ from ..compat import NOTSET
from ..compat import NotSetType
from _pytest.config import Config
from _pytest.deprecated import check_ispytest
from _pytest.deprecated import MARKED_FIXTURE
from _pytest.outcomes import fail
from _pytest.warning_types import PytestUnknownMarkWarning
@ -399,6 +400,9 @@ def store_mark(obj, mark: Mark) -> None:
assert isinstance(mark, Mark), mark
# Always reassign name to avoid updating pytestmark in a reference that
# was only borrowed.
if hasattr(obj, "_pytestfixturefunction"):
warnings.warn(MARKED_FIXTURE, stacklevel=2)
obj.pytestmark = get_unpacked_marks(obj) + [mark]

View File

@ -3612,6 +3612,24 @@ class TestShowFixtures:
def foo():
raise NotImplementedError()
def test_fixture_disallow_on_marked_functions(self):
"""Test that applying @pytest.fixture to a marked function warns (#3364)."""
with pytest.warns(pytest.PytestDeprecationWarning):
@pytest.fixture
@pytest.mark.usefixtures("tmp_path")
def foo():
raise NotImplementedError()
def test_fixture_disallow_marks_on_fixtures(self):
"""Test that applying a mark to a fixture warns (#3364)."""
with pytest.warns(pytest.PytestDeprecationWarning):
@pytest.mark.usefixtures("tmp_path")
@pytest.fixture
def foo():
raise NotImplementedError()
class TestContextManagerFixtureFuncs:
def test_simple(self, pytester: Pytester) -> None: