Skip to content

Commit 4797dea

Browse files
Add FixtureArgKey class to represent fixture deps in fixtures.py (#11231)
1 parent c916340 commit 4797dea

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

src/_pytest/fixtures.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,17 @@ def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]:
239239
)
240240

241241

242-
# Parametrized fixture key, helper alias for code below.
243-
_Key = Tuple[object, ...]
242+
@dataclasses.dataclass(frozen=True)
243+
class FixtureArgKey:
244+
argname: str
245+
param_index: int
246+
scoped_item_path: Optional[Path]
247+
item_cls: Optional[type]
244248

245249

246-
def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_Key]:
250+
def get_parametrized_fixture_keys(
251+
item: nodes.Item, scope: Scope
252+
) -> Iterator[FixtureArgKey]:
247253
"""Return list of keys for all parametrized arguments which match
248254
the specified scope."""
249255
assert scope is not Scope.Function
@@ -253,24 +259,28 @@ def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_K
253259
pass
254260
else:
255261
cs: CallSpec2 = callspec
256-
# cs.indices.items() is random order of argnames. Need to
262+
# cs.indices is random order of argnames. Need to
257263
# sort this so that different calls to
258264
# get_parametrized_fixture_keys will be deterministic.
259-
for argname, param_index in sorted(cs.indices.items()):
265+
for argname in sorted(cs.indices):
260266
if cs._arg2scope[argname] != scope:
261267
continue
268+
269+
item_cls = None
262270
if scope is Scope.Session:
263-
key: _Key = (argname, param_index)
271+
scoped_item_path = None
264272
elif scope is Scope.Package:
265-
key = (argname, param_index, item.path)
273+
scoped_item_path = item.path
266274
elif scope is Scope.Module:
267-
key = (argname, param_index, item.path)
275+
scoped_item_path = item.path
268276
elif scope is Scope.Class:
277+
scoped_item_path = item.path
269278
item_cls = item.cls # type: ignore[attr-defined]
270-
key = (argname, param_index, item.path, item_cls)
271279
else:
272280
assert_never(scope)
273-
yield key
281+
282+
param_index = cs.indices[argname]
283+
yield FixtureArgKey(argname, param_index, scoped_item_path, item_cls)
274284

275285

276286
# Algorithm for sorting on a per-parametrized resource setup basis.
@@ -280,12 +290,12 @@ def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_K
280290

281291

282292
def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
283-
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]] = {}
284-
items_by_argkey: Dict[Scope, Dict[_Key, Deque[nodes.Item]]] = {}
293+
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]] = {}
294+
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, Deque[nodes.Item]]] = {}
285295
for scope in HIGH_SCOPES:
286-
d: Dict[nodes.Item, Dict[_Key, None]] = {}
296+
d: Dict[nodes.Item, Dict[FixtureArgKey, None]] = {}
287297
argkeys_cache[scope] = d
288-
item_d: Dict[_Key, Deque[nodes.Item]] = defaultdict(deque)
298+
item_d: Dict[FixtureArgKey, Deque[nodes.Item]] = defaultdict(deque)
289299
items_by_argkey[scope] = item_d
290300
for item in items:
291301
keys = dict.fromkeys(get_parametrized_fixture_keys(item, scope), None)
@@ -301,8 +311,8 @@ def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
301311

302312
def fix_cache_order(
303313
item: nodes.Item,
304-
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]],
305-
items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]],
314+
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]],
315+
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]],
306316
) -> None:
307317
for scope in HIGH_SCOPES:
308318
for key in argkeys_cache[scope].get(item, []):
@@ -311,13 +321,13 @@ def fix_cache_order(
311321

312322
def reorder_items_atscope(
313323
items: Dict[nodes.Item, None],
314-
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]],
315-
items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]],
324+
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]],
325+
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]],
316326
scope: Scope,
317327
) -> Dict[nodes.Item, None]:
318328
if scope is Scope.Function or len(items) < 3:
319329
return items
320-
ignore: Set[Optional[_Key]] = set()
330+
ignore: Set[Optional[FixtureArgKey]] = set()
321331
items_deque = deque(items)
322332
items_done: Dict[nodes.Item, None] = {}
323333
scoped_items_by_argkey = items_by_argkey[scope]

0 commit comments

Comments
 (0)