Skip to content

Commit bdbad91

Browse files
authored
Merge pull request pytest-dev#9546 from bluetech/fixturedef-attr-doc
fixtures: document FixtureDef's attributes
2 parents fac8f28 + acd2034 commit bdbad91

File tree

1 file changed

+43
-14
lines changed

1 file changed

+43
-14
lines changed

src/_pytest/fixtures.py

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,17 @@ def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None:
597597
funcitem = self._pyfuncitem
598598
scope = fixturedef._scope
599599
try:
600-
param = funcitem.callspec.getparam(argname)
601-
except (AttributeError, ValueError):
600+
callspec = funcitem.callspec
601+
except AttributeError:
602+
callspec = None
603+
if callspec is not None and argname in callspec.params:
604+
param = callspec.params[argname]
605+
param_index = callspec.indices[argname]
606+
# If a parametrize invocation set a scope it will override
607+
# the static scope defined with the fixture function.
608+
with suppress(KeyError):
609+
scope = callspec._arg2scope[argname]
610+
else:
602611
param = NOTSET
603612
param_index = 0
604613
has_params = fixturedef.params is not None
@@ -638,12 +647,6 @@ def _compute_fixture_value(self, fixturedef: "FixtureDef[object]") -> None:
638647
)
639648
)
640649
fail(msg, pytrace=False)
641-
else:
642-
param_index = funcitem.callspec.indices[argname]
643-
# If a parametrize invocation set a scope it will override
644-
# the static scope defined with the fixture function.
645-
with suppress(KeyError):
646-
scope = funcitem.callspec._arg2scope[argname]
647650

648651
subrequest = SubRequest(
649652
self, scope, param, param_index, fixturedef, _ispytest=True
@@ -927,7 +930,7 @@ def _eval_scope_callable(
927930

928931
@final
929932
class FixtureDef(Generic[FixtureValue]):
930-
"""A container for a factory definition."""
933+
"""A container for a fixture definition."""
931934

932935
def __init__(
933936
self,
@@ -943,26 +946,52 @@ def __init__(
943946
] = None,
944947
) -> None:
945948
self._fixturemanager = fixturemanager
949+
# The "base" node ID for the fixture.
950+
#
951+
# This is a node ID prefix. A fixture is only available to a node (e.g.
952+
# a `Function` item) if the fixture's baseid is a parent of the node's
953+
# nodeid (see the `iterparentnodeids` function for what constitutes a
954+
# "parent" and a "prefix" in this context).
955+
#
956+
# For a fixture found in a Collector's object (e.g. a `Module`s module,
957+
# a `Class`'s class), the baseid is the Collector's nodeid.
958+
#
959+
# For a fixture found in a conftest plugin, the baseid is the conftest's
960+
# directory path relative to the rootdir.
961+
#
962+
# For other plugins, the baseid is the empty string (always matches).
946963
self.baseid = baseid or ""
964+
# Whether the fixture was found from a node or a conftest in the
965+
# collection tree. Will be false for fixtures defined in non-conftest
966+
# plugins.
947967
self.has_location = baseid is not None
968+
# The fixture factory function.
948969
self.func = func
970+
# The name by which the fixture may be requested.
949971
self.argname = argname
950972
if scope is None:
951973
scope = Scope.Function
952974
elif callable(scope):
953975
scope = _eval_scope_callable(scope, argname, fixturemanager.config)
954-
955976
if isinstance(scope, str):
956977
scope = Scope.from_user(
957978
scope, descr=f"Fixture '{func.__name__}'", where=baseid
958979
)
959980
self._scope = scope
981+
# If the fixture is directly parametrized, the parameter values.
960982
self.params: Optional[Sequence[object]] = params
961-
self.argnames: Tuple[str, ...] = getfuncargnames(
962-
func, name=argname, is_method=unittest
963-
)
964-
self.unittest = unittest
983+
# If the fixture is directly parametrized, a tuple of explicit IDs to
984+
# assign to the parameter values, or a callable to generate an ID given
985+
# a parameter value.
965986
self.ids = ids
987+
# The names requested by the fixtures.
988+
self.argnames = getfuncargnames(func, name=argname, is_method=unittest)
989+
# Whether the fixture was collected from a unittest TestCase class.
990+
# Note that it really only makes sense to define autouse fixtures in
991+
# unittest TestCases.
992+
self.unittest = unittest
993+
# If the fixture was executed, the current value of the fixture.
994+
# Can change if the fixture is executed with different parameters.
966995
self.cached_result: Optional[_FixtureCachedResult[FixtureValue]] = None
967996
self._finalizers: List[Callable[[], object]] = []
968997

0 commit comments

Comments
 (0)