@@ -155,11 +155,17 @@ def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]:
155155 )
156156
157157
158- # Parametrized fixture key, helper alias for code below.
159- _Key = Tuple [object , ...]
158+ @dataclasses .dataclass (frozen = True )
159+ class FixtureArgKey :
160+ argname : str
161+ param_index : int
162+ scoped_item_path : Optional [Path ]
163+ item_cls : Optional [type ]
160164
161165
162- def get_parametrized_fixture_keys (item : nodes .Item , scope : Scope ) -> Iterator [_Key ]:
166+ def get_parametrized_fixture_keys (
167+ item : nodes .Item , scope : Scope
168+ ) -> Iterator [FixtureArgKey ]:
163169 """Return list of keys for all parametrized arguments which match
164170 the specified scope."""
165171 assert scope is not Scope .Function
@@ -169,24 +175,28 @@ def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_K
169175 pass
170176 else :
171177 cs : CallSpec2 = callspec
172- # cs.indices.items() is random order of argnames. Need to
178+ # cs.indices is random order of argnames. Need to
173179 # sort this so that different calls to
174180 # get_parametrized_fixture_keys will be deterministic.
175- for argname , param_index in sorted (cs .indices . items () ):
181+ for argname in sorted (cs .indices ):
176182 if cs ._arg2scope [argname ] != scope :
177183 continue
184+
185+ item_cls = None
178186 if scope is Scope .Session :
179- key : _Key = ( argname , param_index )
187+ scoped_item_path = None
180188 elif scope is Scope .Package :
181- key = ( argname , param_index , item .path )
189+ scoped_item_path = item .path
182190 elif scope is Scope .Module :
183- key = ( argname , param_index , item .path )
191+ scoped_item_path = item .path
184192 elif scope is Scope .Class :
193+ scoped_item_path = item .path
185194 item_cls = item .cls # type: ignore[attr-defined]
186- key = (argname , param_index , item .path , item_cls )
187195 else :
188196 assert_never (scope )
189- yield key
197+
198+ param_index = cs .indices [argname ]
199+ yield FixtureArgKey (argname , param_index , scoped_item_path , item_cls )
190200
191201
192202# Algorithm for sorting on a per-parametrized resource setup basis.
@@ -196,12 +206,12 @@ def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_K
196206
197207
198208def reorder_items (items : Sequence [nodes .Item ]) -> List [nodes .Item ]:
199- argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [_Key , None ]]] = {}
200- items_by_argkey : Dict [Scope , Dict [_Key , Deque [nodes .Item ]]] = {}
209+ argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [FixtureArgKey , None ]]] = {}
210+ items_by_argkey : Dict [Scope , Dict [FixtureArgKey , Deque [nodes .Item ]]] = {}
201211 for scope in HIGH_SCOPES :
202- d : Dict [nodes .Item , Dict [_Key , None ]] = {}
212+ d : Dict [nodes .Item , Dict [FixtureArgKey , None ]] = {}
203213 argkeys_cache [scope ] = d
204- item_d : Dict [_Key , Deque [nodes .Item ]] = defaultdict (deque )
214+ item_d : Dict [FixtureArgKey , Deque [nodes .Item ]] = defaultdict (deque )
205215 items_by_argkey [scope ] = item_d
206216 for item in items :
207217 keys = dict .fromkeys (get_parametrized_fixture_keys (item , scope ), None )
@@ -217,8 +227,8 @@ def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
217227
218228def fix_cache_order (
219229 item : nodes .Item ,
220- argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [_Key , None ]]],
221- items_by_argkey : Dict [Scope , Dict [_Key , "Deque[nodes.Item]" ]],
230+ argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [FixtureArgKey , None ]]],
231+ items_by_argkey : Dict [Scope , Dict [FixtureArgKey , "Deque[nodes.Item]" ]],
222232) -> None :
223233 for scope in HIGH_SCOPES :
224234 for key in argkeys_cache [scope ].get (item , []):
@@ -227,13 +237,13 @@ def fix_cache_order(
227237
228238def reorder_items_atscope (
229239 items : Dict [nodes .Item , None ],
230- argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [_Key , None ]]],
231- items_by_argkey : Dict [Scope , Dict [_Key , "Deque[nodes.Item]" ]],
240+ argkeys_cache : Dict [Scope , Dict [nodes .Item , Dict [FixtureArgKey , None ]]],
241+ items_by_argkey : Dict [Scope , Dict [FixtureArgKey , "Deque[nodes.Item]" ]],
232242 scope : Scope ,
233243) -> Dict [nodes .Item , None ]:
234244 if scope is Scope .Function or len (items ) < 3 :
235245 return items
236- ignore : Set [Optional [_Key ]] = set ()
246+ ignore : Set [Optional [FixtureArgKey ]] = set ()
237247 items_deque = deque (items )
238248 items_done : Dict [nodes .Item , None ] = {}
239249 scoped_items_by_argkey = items_by_argkey [scope ]
@@ -394,7 +404,7 @@ def node(self):
394404 node : Optional [Union [nodes .Item , nodes .Collector ]] = self ._pyfuncitem
395405 elif scope is Scope .Package :
396406 # FIXME: _fixturedef is not defined on FixtureRequest (this class),
397- # but on FixtureRequest (a subclass).
407+ # but on SubRequest (a subclass).
398408 node = get_scope_package (self ._pyfuncitem , self ._fixturedef ) # type: ignore[attr-defined]
399409 else :
400410 node = get_scope_node (self ._pyfuncitem , scope )
0 commit comments