@@ -354,16 +354,27 @@ def get_direct_param_fixture_func(request: "FixtureRequest") -> Any:
354354
355355@dataclasses .dataclass (frozen = True )
356356class FuncFixtureInfo :
357+ """Fixture-related information for a fixture-requesting item (e.g. test
358+ function).
359+
360+ This is used to examine the fixtures which an item requests statically
361+ (known during collection). This includes autouse fixtures, fixtures
362+ requested by the `usefixtures` marker, fixtures requested in the function
363+ parameters, and the transitive closure of these.
364+
365+ An item may also request fixtures dynamically (using `request.getfixturevalue`);
366+ these are not reflected here.
367+ """
368+
357369 __slots__ = ("argnames" , "initialnames" , "names_closure" , "name2fixturedefs" )
358370
359- # Original function argument names, i.e. fixture names that the function
360- # requests directly.
371+ # Fixture names that the item requests directly by function parameters.
361372 argnames : Tuple [str , ...]
362- # Fixture names that the function immediately requires. These include
373+ # Fixture names that the item immediately requires. These include
363374 # argnames + fixture names specified via usefixtures and via autouse=True in
364375 # fixture definitions.
365376 initialnames : Tuple [str , ...]
366- # The transitive closure of the fixture names that the function requires.
377+ # The transitive closure of the fixture names that the item requires.
367378 # Note: can't include dynamic dependencies (`request.getfixturevalue` calls).
368379 names_closure : List [str ]
369380 # A map from a fixture name in the transitive closure to the FixtureDefs
@@ -547,8 +558,7 @@ def path(self) -> Path:
547558 """Path where the test function was collected."""
548559 if self .scope not in ("function" , "class" , "module" , "package" ):
549560 raise AttributeError (f"path not available in { self .scope } -scoped context" )
550- # TODO: Remove ignore once _pyfuncitem is properly typed.
551- return self ._pyfuncitem .path # type: ignore
561+ return self ._pyfuncitem .path
552562
553563 @property
554564 def keywords (self ) -> MutableMapping [str , Any ]:
@@ -620,20 +630,17 @@ def getfixturevalue(self, argname: str) -> Any:
620630 def _get_active_fixturedef (
621631 self , argname : str
622632 ) -> Union ["FixtureDef[object]" , PseudoFixtureDef [object ]]:
623- try :
624- return self ._fixture_defs [argname ]
625- except KeyError :
633+ fixturedef = self ._fixture_defs .get (argname )
634+ if fixturedef is None :
626635 try :
627636 fixturedef = self ._getnextfixturedef (argname )
628637 except FixtureLookupError :
629638 if argname == "request" :
630639 cached_result = (self , [0 ], None )
631640 return PseudoFixtureDef (cached_result , Scope .Function )
632641 raise
633- # Remove indent to prevent the python3 exception
634- # from leaking into the call.
635- self ._compute_fixture_value (fixturedef )
636- self ._fixture_defs [argname ] = fixturedef
642+ self ._compute_fixture_value (fixturedef )
643+ self ._fixture_defs [argname ] = fixturedef
637644 return fixturedef
638645
639646 def _get_fixturestack (self ) -> List ["FixtureDef[Any]" ]:
@@ -1467,8 +1474,26 @@ def _get_direct_parametrize_args(self, node: nodes.Node) -> List[str]:
14671474 return parametrize_argnames
14681475
14691476 def getfixtureinfo (
1470- self , node : nodes .Node , func , cls , funcargs : bool = True
1477+ self ,
1478+ node : nodes .Item ,
1479+ func : Callable [..., object ],
1480+ cls : Optional [type ],
1481+ funcargs : bool = True ,
14711482 ) -> FuncFixtureInfo :
1483+ """Calculate the :class:`FuncFixtureInfo` for an item.
1484+
1485+ If ``funcargs`` is false, or if the item sets an attribute
1486+ ``nofuncargs = True``, then ``func`` is not examined at all.
1487+
1488+ :param node:
1489+ The item requesting the fixtures.
1490+ :param func:
1491+ The item's function.
1492+ :param cls:
1493+ If the function is a method, the method's class.
1494+ :param funcargs:
1495+ Whether to look into func's parameters as fixture requests.
1496+ """
14721497 if funcargs and not getattr (node , "nofuncargs" , False ):
14731498 argnames = getfuncargnames (func , name = node .name , cls = cls )
14741499 else :
@@ -1478,8 +1503,7 @@ def getfixtureinfo(
14781503 arg for mark in node .iter_markers (name = "usefixtures" ) for arg in mark .args
14791504 )
14801505 initialnames = usefixtures + argnames
1481- fm = node .session ._fixturemanager
1482- initialnames , names_closure , arg2fixturedefs = fm .getfixtureclosure (
1506+ initialnames , names_closure , arg2fixturedefs = self .getfixtureclosure (
14831507 initialnames , node , ignore_args = self ._get_direct_parametrize_args (node )
14841508 )
14851509 return FuncFixtureInfo (argnames , initialnames , names_closure , arg2fixturedefs )
0 commit comments