Always use getfixturemarker() to access _pytestfixturefunction

Keep knowledge of how the marker is stored encapsulated in one place.
This commit is contained in:
Ran Benita 2020-11-26 14:50:44 +02:00
parent ade253c790
commit 8ee6d0a866
2 changed files with 18 additions and 10 deletions

View File

@ -2,11 +2,12 @@
from _pytest import python from _pytest import python
from _pytest import unittest from _pytest import unittest
from _pytest.config import hookimpl from _pytest.config import hookimpl
from _pytest.fixtures import getfixturemarker
from _pytest.nodes import Item from _pytest.nodes import Item
@hookimpl(trylast=True) @hookimpl(trylast=True)
def pytest_runtest_setup(item): def pytest_runtest_setup(item) -> None:
if is_potential_nosetest(item): if is_potential_nosetest(item):
if not call_optional(item.obj, "setup"): if not call_optional(item.obj, "setup"):
# Call module level setup if there is no object level one. # Call module level setup if there is no object level one.
@ -15,7 +16,7 @@ def pytest_runtest_setup(item):
item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item) item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)
def teardown_nose(item): def teardown_nose(item) -> None:
if is_potential_nosetest(item): if is_potential_nosetest(item):
if not call_optional(item.obj, "teardown"): if not call_optional(item.obj, "teardown"):
call_optional(item.parent.obj, "teardown") call_optional(item.parent.obj, "teardown")
@ -29,11 +30,16 @@ def is_potential_nosetest(item: Item) -> bool:
) )
def call_optional(obj, name): def call_optional(obj: object, name: str) -> bool:
method = getattr(obj, name, None) method = getattr(obj, name, None)
isfixture = hasattr(method, "_pytestfixturefunction") if method is None:
if method is not None and not isfixture and callable(method): return False
# If there's any problems allow the exception to raise rather than is_fixture = getfixturemarker(method) is not None
# silently ignoring them. if is_fixture:
method() return False
return True if not callable(method):
return False
# If there are any problems allow the exception to raise rather than
# silently ignoring it.
method()
return True

View File

@ -3,6 +3,7 @@ from typing import Any
import pytest import pytest
from _pytest import runner from _pytest import runner
from _pytest._code import getfslineno from _pytest._code import getfslineno
from _pytest.fixtures import getfixturemarker
from _pytest.pytester import Pytester from _pytest.pytester import Pytester
@ -334,7 +335,8 @@ class TestReRunTests:
def test_pytestconfig_is_session_scoped() -> None: def test_pytestconfig_is_session_scoped() -> None:
from _pytest.fixtures import pytestconfig from _pytest.fixtures import pytestconfig
marker = pytestconfig._pytestfixturefunction # type: ignore marker = getfixturemarker(pytestconfig)
assert marker is not None
assert marker.scope == "session" assert marker.scope == "session"