@@ -1412,9 +1412,10 @@ def __init__(self, session: "Session") -> None:
1412
1412
self .config : Config = session .config
1413
1413
self ._arg2fixturedefs : Dict [str , List [FixtureDef [Any ]]] = {}
1414
1414
self ._holderobjseen : Set [object ] = set ()
1415
- self ._nodeid_and_autousenames : List [Tuple [str , List [str ]]] = [
1416
- ("" , self .config .getini ("usefixtures" ))
1417
- ]
1415
+ # A mapping from a nodeid to a list of autouse fixtures it defines.
1416
+ self ._nodeid_autousenames : Dict [str , List [str ]] = {
1417
+ "" : self .config .getini ("usefixtures" ),
1418
+ }
1418
1419
session .config .pluginmanager .register (self , "funcmanage" )
1419
1420
1420
1421
def _get_direct_parametrize_args (self , node : nodes .Node ) -> List [str ]:
@@ -1476,18 +1477,12 @@ def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
1476
1477
1477
1478
self .parsefactories (plugin , nodeid )
1478
1479
1479
- def _getautousenames (self , nodeid : str ) -> List [str ]:
1480
- """Return a list of fixture names to be used."""
1481
- autousenames : List [str ] = []
1482
- for baseid , basenames in self ._nodeid_and_autousenames :
1483
- if nodeid .startswith (baseid ):
1484
- if baseid :
1485
- i = len (baseid )
1486
- nextchar = nodeid [i : i + 1 ]
1487
- if nextchar and nextchar not in ":/" :
1488
- continue
1489
- autousenames .extend (basenames )
1490
- return autousenames
1480
+ def _getautousenames (self , nodeid : str ) -> Iterator [str ]:
1481
+ """Return the names of autouse fixtures applicable to nodeid."""
1482
+ for parentnodeid in nodes .iterparentnodeids (nodeid ):
1483
+ basenames = self ._nodeid_autousenames .get (parentnodeid )
1484
+ if basenames :
1485
+ yield from basenames
1491
1486
1492
1487
def getfixtureclosure (
1493
1488
self ,
@@ -1503,7 +1498,7 @@ def getfixtureclosure(
1503
1498
# (discovering matching fixtures for a given name/node is expensive).
1504
1499
1505
1500
parentid = parentnode .nodeid
1506
- fixturenames_closure = self ._getautousenames (parentid )
1501
+ fixturenames_closure = list ( self ._getautousenames (parentid ) )
1507
1502
1508
1503
def merge (otherlist : Iterable [str ]) -> None :
1509
1504
for arg in otherlist :
@@ -1648,7 +1643,7 @@ def parsefactories(
1648
1643
autousenames .append (name )
1649
1644
1650
1645
if autousenames :
1651
- self ._nodeid_and_autousenames . append (( nodeid or "" , autousenames ) )
1646
+ self ._nodeid_autousenames . setdefault ( nodeid or "" , []). extend ( autousenames )
1652
1647
1653
1648
def getfixturedefs (
1654
1649
self , argname : str , nodeid : str
@@ -1668,6 +1663,7 @@ def getfixturedefs(
1668
1663
def _matchfactories (
1669
1664
self , fixturedefs : Iterable [FixtureDef [Any ]], nodeid : str
1670
1665
) -> Iterator [FixtureDef [Any ]]:
1666
+ parentnodeids = set (nodes .iterparentnodeids (nodeid ))
1671
1667
for fixturedef in fixturedefs :
1672
- if nodes . ischildnode ( fixturedef .baseid , nodeid ) :
1668
+ if fixturedef .baseid in parentnodeids :
1673
1669
yield fixturedef
0 commit comments