(fixture) create a new class to represent fixtures
This commit is contained in:
parent
7fd947167d
commit
46d2ccbfd4
|
@ -45,7 +45,8 @@ from _pytest._io import TerminalWriter
|
|||
from _pytest.compat import _PytestWrapper
|
||||
from _pytest.compat import assert_never
|
||||
from _pytest.compat import get_real_func
|
||||
from _pytest.compat import get_real_method
|
||||
|
||||
# from _pytest.compat import get_real_method
|
||||
from _pytest.compat import getfuncargnames
|
||||
from _pytest.compat import getimfunc
|
||||
from _pytest.compat import getlocation
|
||||
|
@ -1186,7 +1187,7 @@ class FixtureFunctionMarker:
|
|||
def __post_init__(self, _ispytest: bool) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
|
||||
def __call__(self, function: FixtureFunction) -> FixtureFunction:
|
||||
def __call__(self, function: FixtureFunction) -> "FixtureFunctionDefinition":
|
||||
if inspect.isclass(function):
|
||||
raise ValueError("class fixtures not supported (maybe in the future)")
|
||||
|
||||
|
@ -1198,7 +1199,9 @@ class FixtureFunctionMarker:
|
|||
if hasattr(function, "pytestmark"):
|
||||
warnings.warn(MARKED_FIXTURE, stacklevel=2)
|
||||
|
||||
function = wrap_function_to_error_out_if_called_directly(function, self)
|
||||
fixture_definition = FixtureFunctionDefinition(function, self)
|
||||
|
||||
# function = wrap_function_to_error_out_if_called_directly(function, self)
|
||||
|
||||
name = self.name or function.__name__
|
||||
if name == "request":
|
||||
|
@ -1209,13 +1212,53 @@ class FixtureFunctionMarker:
|
|||
)
|
||||
|
||||
# Type ignored because https://github.com/python/mypy/issues/2087.
|
||||
function._pytestfixturefunction = self # type: ignore[attr-defined]
|
||||
return function
|
||||
# function._pytestfixturefunction = self # type: ignore[attr-defined]
|
||||
# return function
|
||||
return fixture_definition
|
||||
|
||||
def __repr__(self):
|
||||
return "fixture"
|
||||
|
||||
|
||||
class FixtureFunctionDefinition:
|
||||
def __init__(
|
||||
self,
|
||||
function: Callable[..., object],
|
||||
fixture_function_marker: FixtureFunctionMarker,
|
||||
instance: Optional[type] = None,
|
||||
):
|
||||
self.name = fixture_function_marker.name or function.__name__
|
||||
self._pytestfixturefunction = fixture_function_marker
|
||||
self.__pytest_wrapped__ = _PytestWrapper(function)
|
||||
self.fixture_function = function
|
||||
self.fixture_function_marker = fixture_function_marker
|
||||
self.scope = fixture_function_marker.scope
|
||||
self.params = fixture_function_marker.params
|
||||
self.autouse = fixture_function_marker.autouse
|
||||
self.ids = fixture_function_marker.ids
|
||||
self.fixture_function = function
|
||||
self.instance = instance
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"fixture {self.fixture_function}"
|
||||
|
||||
def __get__(self, instance, owner=None):
|
||||
return FixtureFunctionDefinition(
|
||||
self.fixture_function, self.fixture_function_marker, instance
|
||||
)
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.get_real_func(*args, **kwds)
|
||||
|
||||
def get_real_func(self):
|
||||
if self.instance is not None:
|
||||
return self.fixture_function.__get__(self.instance)
|
||||
return self.fixture_function
|
||||
|
||||
|
||||
@overload
|
||||
def fixture(
|
||||
fixture_function: FixtureFunction,
|
||||
fixture_function: Callable[..., object],
|
||||
*,
|
||||
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ...,
|
||||
params: Optional[Iterable[object]] = ...,
|
||||
|
@ -1224,7 +1267,7 @@ def fixture(
|
|||
Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]
|
||||
] = ...,
|
||||
name: Optional[str] = ...,
|
||||
) -> FixtureFunction: ...
|
||||
) -> FixtureFunctionDefinition: ...
|
||||
|
||||
|
||||
@overload
|
||||
|
@ -1238,7 +1281,7 @@ def fixture(
|
|||
Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]
|
||||
] = ...,
|
||||
name: Optional[str] = None,
|
||||
) -> FixtureFunctionMarker: ...
|
||||
) -> FixtureFunctionDefinition: ...
|
||||
|
||||
|
||||
def fixture(
|
||||
|
@ -1251,7 +1294,7 @@ def fixture(
|
|||
Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]
|
||||
] = None,
|
||||
name: Optional[str] = None,
|
||||
) -> Union[FixtureFunctionMarker, FixtureFunction]:
|
||||
) -> Union[FixtureFunctionMarker, FixtureFunctionDefinition]:
|
||||
"""Decorator to mark a fixture factory function.
|
||||
|
||||
This decorator can be used, with or without parameters, to define a
|
||||
|
@ -1321,7 +1364,7 @@ def fixture(
|
|||
def yield_fixture(
|
||||
fixture_function=None,
|
||||
*args,
|
||||
scope="function",
|
||||
scope: _ScopeName = "function",
|
||||
params=None,
|
||||
autouse=False,
|
||||
ids=None,
|
||||
|
@ -1644,6 +1687,13 @@ class FixtureManager:
|
|||
] = None,
|
||||
autouse: bool = False,
|
||||
) -> None:
|
||||
if name == "fixt2":
|
||||
print(name)
|
||||
print(func)
|
||||
print(nodeid)
|
||||
print(scope)
|
||||
print(ids)
|
||||
print(autouse)
|
||||
"""Register a fixture
|
||||
|
||||
:param name:
|
||||
|
@ -1735,7 +1785,7 @@ class FixtureManager:
|
|||
self._holderobjseen.add(holderobj)
|
||||
for name in dir(holderobj):
|
||||
# The attribute can be an arbitrary descriptor, so the attribute
|
||||
# access below can raise. safe_getatt() ignores such exceptions.
|
||||
# access below can raise. safe_getattr() ignores such exceptions.
|
||||
obj = safe_getattr(holderobj, name, None)
|
||||
marker = getfixturemarker(obj)
|
||||
if not isinstance(marker, FixtureFunctionMarker):
|
||||
|
@ -1750,7 +1800,8 @@ class FixtureManager:
|
|||
# to issue a warning if called directly, so here we unwrap it in
|
||||
# order to not emit the warning when pytest itself calls the
|
||||
# fixture function.
|
||||
func = get_real_method(obj, holderobj)
|
||||
# func = get_real_method(obj, holderobj)
|
||||
func = obj.get_real_func()
|
||||
|
||||
self._register_fixture(
|
||||
name=name,
|
||||
|
|
Loading…
Reference in New Issue