@@ -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
929932class 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