Add `FixtureArgKey` class to represent fixture deps in `fixtures.py` (#11231)
This commit is contained in:
parent
c9163402e0
commit
4797deab99
|
@ -239,11 +239,17 @@ def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Parametrized fixture key, helper alias for code below.
|
@dataclasses.dataclass(frozen=True)
|
||||||
_Key = Tuple[object, ...]
|
class FixtureArgKey:
|
||||||
|
argname: str
|
||||||
|
param_index: int
|
||||||
|
scoped_item_path: Optional[Path]
|
||||||
|
item_cls: Optional[type]
|
||||||
|
|
||||||
|
|
||||||
def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_Key]:
|
def get_parametrized_fixture_keys(
|
||||||
|
item: nodes.Item, scope: Scope
|
||||||
|
) -> Iterator[FixtureArgKey]:
|
||||||
"""Return list of keys for all parametrized arguments which match
|
"""Return list of keys for all parametrized arguments which match
|
||||||
the specified scope."""
|
the specified scope."""
|
||||||
assert scope is not Scope.Function
|
assert scope is not Scope.Function
|
||||||
|
@ -253,24 +259,28 @@ def get_parametrized_fixture_keys(item: nodes.Item, scope: Scope) -> Iterator[_K
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
cs: CallSpec2 = callspec
|
cs: CallSpec2 = callspec
|
||||||
# cs.indices.items() is random order of argnames. Need to
|
# cs.indices is random order of argnames. Need to
|
||||||
# sort this so that different calls to
|
# sort this so that different calls to
|
||||||
# get_parametrized_fixture_keys will be deterministic.
|
# get_parametrized_fixture_keys will be deterministic.
|
||||||
for argname, param_index in sorted(cs.indices.items()):
|
for argname in sorted(cs.indices):
|
||||||
if cs._arg2scope[argname] != scope:
|
if cs._arg2scope[argname] != scope:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
item_cls = None
|
||||||
if scope is Scope.Session:
|
if scope is Scope.Session:
|
||||||
key: _Key = (argname, param_index)
|
scoped_item_path = None
|
||||||
elif scope is Scope.Package:
|
elif scope is Scope.Package:
|
||||||
key = (argname, param_index, item.path)
|
scoped_item_path = item.path
|
||||||
elif scope is Scope.Module:
|
elif scope is Scope.Module:
|
||||||
key = (argname, param_index, item.path)
|
scoped_item_path = item.path
|
||||||
elif scope is Scope.Class:
|
elif scope is Scope.Class:
|
||||||
|
scoped_item_path = item.path
|
||||||
item_cls = item.cls # type: ignore[attr-defined]
|
item_cls = item.cls # type: ignore[attr-defined]
|
||||||
key = (argname, param_index, item.path, item_cls)
|
|
||||||
else:
|
else:
|
||||||
assert_never(scope)
|
assert_never(scope)
|
||||||
yield key
|
|
||||||
|
param_index = cs.indices[argname]
|
||||||
|
yield FixtureArgKey(argname, param_index, scoped_item_path, item_cls)
|
||||||
|
|
||||||
|
|
||||||
# Algorithm for sorting on a per-parametrized resource setup basis.
|
# 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
|
||||||
|
|
||||||
|
|
||||||
def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
|
def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
|
||||||
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]] = {}
|
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]] = {}
|
||||||
items_by_argkey: Dict[Scope, Dict[_Key, Deque[nodes.Item]]] = {}
|
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, Deque[nodes.Item]]] = {}
|
||||||
for scope in HIGH_SCOPES:
|
for scope in HIGH_SCOPES:
|
||||||
d: Dict[nodes.Item, Dict[_Key, None]] = {}
|
d: Dict[nodes.Item, Dict[FixtureArgKey, None]] = {}
|
||||||
argkeys_cache[scope] = d
|
argkeys_cache[scope] = d
|
||||||
item_d: Dict[_Key, Deque[nodes.Item]] = defaultdict(deque)
|
item_d: Dict[FixtureArgKey, Deque[nodes.Item]] = defaultdict(deque)
|
||||||
items_by_argkey[scope] = item_d
|
items_by_argkey[scope] = item_d
|
||||||
for item in items:
|
for item in items:
|
||||||
keys = dict.fromkeys(get_parametrized_fixture_keys(item, scope), None)
|
keys = dict.fromkeys(get_parametrized_fixture_keys(item, scope), None)
|
||||||
|
@ -301,8 +311,8 @@ def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
|
||||||
|
|
||||||
def fix_cache_order(
|
def fix_cache_order(
|
||||||
item: nodes.Item,
|
item: nodes.Item,
|
||||||
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]],
|
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]],
|
||||||
items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]],
|
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]],
|
||||||
) -> None:
|
) -> None:
|
||||||
for scope in HIGH_SCOPES:
|
for scope in HIGH_SCOPES:
|
||||||
for key in argkeys_cache[scope].get(item, []):
|
for key in argkeys_cache[scope].get(item, []):
|
||||||
|
@ -311,13 +321,13 @@ def fix_cache_order(
|
||||||
|
|
||||||
def reorder_items_atscope(
|
def reorder_items_atscope(
|
||||||
items: Dict[nodes.Item, None],
|
items: Dict[nodes.Item, None],
|
||||||
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[_Key, None]]],
|
argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]],
|
||||||
items_by_argkey: Dict[Scope, Dict[_Key, "Deque[nodes.Item]"]],
|
items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]],
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
) -> Dict[nodes.Item, None]:
|
) -> Dict[nodes.Item, None]:
|
||||||
if scope is Scope.Function or len(items) < 3:
|
if scope is Scope.Function or len(items) < 3:
|
||||||
return items
|
return items
|
||||||
ignore: Set[Optional[_Key]] = set()
|
ignore: Set[Optional[FixtureArgKey]] = set()
|
||||||
items_deque = deque(items)
|
items_deque = deque(items)
|
||||||
items_done: Dict[nodes.Item, None] = {}
|
items_done: Dict[nodes.Item, None] = {}
|
||||||
scoped_items_by_argkey = items_by_argkey[scope]
|
scoped_items_by_argkey = items_by_argkey[scope]
|
||||||
|
|
Loading…
Reference in New Issue