|
65 | 65 | from _pytest.pathlib import bestrelpath
|
66 | 66 | from _pytest.scope import HIGH_SCOPES
|
67 | 67 | from _pytest.scope import Scope
|
68 |
| -from _pytest.stash import StashKey |
69 | 68 |
|
70 | 69 |
|
71 | 70 | if TYPE_CHECKING:
|
@@ -149,66 +148,6 @@ def get_scope_node(
|
149 | 148 | assert_never(scope)
|
150 | 149 |
|
151 | 150 |
|
152 |
| -def resolve_unique_values_and_their_indices_in_parametersets( |
153 |
| - argnames: Sequence[str], |
154 |
| - parametersets: Sequence[ParameterSet], |
155 |
| -) -> Tuple[Dict[str, List[object]], List[Tuple[int]]]: |
156 |
| - """Resolve unique values and their indices in parameter sets. The index of a value |
157 |
| - is determined by when it appears in the possible values for the first time. |
158 |
| - For example, given ``argnames`` and ``parametersets`` below, the result would be: |
159 |
| -
|
160 |
| - :: |
161 |
| -
|
162 |
| - argnames = ["A", "B", "C"] |
163 |
| - parametersets = [("a1", "b1", "c1"), ("a1", "b2", "c1"), ("a1", "b3", "c2")] |
164 |
| - result[0] = {"A": ["a1"], "B": ["b1", "b2", "b3"], "C": ["c1", "c2"]} |
165 |
| - result[1] = [(0, 0, 0), (0, 1, 0), (0, 2, 1)] |
166 |
| -
|
167 |
| - result is used in reordering `indirect`ly parametrized with multiple |
168 |
| - parameters or directly parametrized tests to keep items using the same fixture or |
169 |
| - pseudo-fixture values respectively, close together. |
170 |
| -
|
171 |
| - :param argnames: |
172 |
| - Argument names passed to ``parametrize()``. |
173 |
| - :param parametersets: |
174 |
| - The parameter sets, each containing a set of values corresponding |
175 |
| - to ``argnames``. |
176 |
| - :returns: |
177 |
| - Tuple of unique parameter values and their indices in parametersets. |
178 |
| - """ |
179 |
| - indices = [] |
180 |
| - argname_value_indices_for_hashable_ones: Dict[str, Dict[object, int]] = defaultdict( |
181 |
| - dict |
182 |
| - ) |
183 |
| - argvalues_count: Dict[str, int] = defaultdict(lambda: 0) |
184 |
| - unique_values: Dict[str, List[object]] = defaultdict(list) |
185 |
| - for i, argname in enumerate(argnames): |
186 |
| - argname_indices = [] |
187 |
| - for parameterset in parametersets: |
188 |
| - value = parameterset.values[i] |
189 |
| - try: |
190 |
| - argname_indices.append( |
191 |
| - argname_value_indices_for_hashable_ones[argname][value] |
192 |
| - ) |
193 |
| - except KeyError: # New unique value |
194 |
| - argname_value_indices_for_hashable_ones[argname][ |
195 |
| - value |
196 |
| - ] = argvalues_count[argname] |
197 |
| - argname_indices.append(argvalues_count[argname]) |
198 |
| - argvalues_count[argname] += 1 |
199 |
| - unique_values[argname].append(value) |
200 |
| - except TypeError: # `value` is not hashable |
201 |
| - argname_indices.append(argvalues_count[argname]) |
202 |
| - argvalues_count[argname] += 1 |
203 |
| - unique_values[argname].append(value) |
204 |
| - indices.append(argname_indices) |
205 |
| - return unique_values, list(zip(*indices)) |
206 |
| - |
207 |
| - |
208 |
| -# Used for storing artificial fixturedefs for direct parametrization. |
209 |
| -name2pseudofixturedef_key = StashKey[Dict[str, "FixtureDef[Any]"]]() |
210 |
| - |
211 |
| - |
212 | 151 | def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]:
|
213 | 152 | """Return fixturemarker or None if it doesn't exist or raised
|
214 | 153 | exceptions."""
|
@@ -352,15 +291,9 @@ def fix_cache_order(
|
352 | 291 | item: nodes.Item,
|
353 | 292 | argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]],
|
354 | 293 | items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]],
|
355 |
| - ignore: Set[Optional[FixtureArgKey]], |
356 |
| - current_scope: Scope, |
357 | 294 | ) -> None:
|
358 | 295 | for scope in HIGH_SCOPES:
|
359 |
| - if current_scope < scope: |
360 |
| - continue |
361 | 296 | for key in argkeys_cache[scope].get(item, []):
|
362 |
| - if key in ignore: |
363 |
| - continue |
364 | 297 | items_by_argkey[scope][key].appendleft(item)
|
365 | 298 |
|
366 | 299 |
|
@@ -404,11 +337,17 @@ def reorder_items_atscope(
|
404 | 337 | else:
|
405 | 338 | slicing_argkey, _ = argkeys.popitem()
|
406 | 339 | # deque because they'll just be ignored.
|
407 |
| - unique_matching_items = dict.fromkeys(scoped_items_by_argkey[slicing_argkey]) |
408 |
| - for i in reversed(unique_matching_items if sys.version_info.minor > 7 else list(unique_matching_items)): |
| 340 | + unique_matching_items = dict.fromkeys( |
| 341 | + scoped_items_by_argkey[slicing_argkey] |
| 342 | + ) |
| 343 | + for i in reversed( |
| 344 | + unique_matching_items |
| 345 | + if sys.version_info.minor > 7 |
| 346 | + else list(unique_matching_items) |
| 347 | + ): |
409 | 348 | if i not in items:
|
410 | 349 | continue
|
411 |
| - fix_cache_order(i, argkeys_cache, items_by_argkey, ignore, scope) |
| 350 | + fix_cache_order(i, argkeys_cache, items_by_argkey) |
412 | 351 | items_deque.appendleft(i)
|
413 | 352 | break
|
414 | 353 | if no_argkey_group:
|
@@ -447,18 +386,6 @@ class FuncFixtureInfo:
|
447 | 386 | name2fixturedefs: Dict[str, Sequence["FixtureDef[Any]"]]
|
448 | 387 | name2num_fixturedefs_used: Dict[str, int]
|
449 | 388 |
|
450 |
| - def prune_dependency_tree(self) -> None: |
451 |
| - """Recompute names_closure from initialnames and name2fixturedefs. |
452 |
| -
|
453 |
| - Can only reduce names_closure, which means that the new closure will |
454 |
| - always be a subset of the old one. The order is preserved. |
455 |
| -
|
456 |
| - This method is needed because dynamic direct parametrization may shadow |
457 |
| - some of the fixtures that were included in the originally built dependency |
458 |
| - tree. In this way the dependency tree can get pruned, and the closure |
459 |
| - of argnames may get reduced. |
460 |
| - """ |
461 |
| - |
462 | 389 |
|
463 | 390 | class FixtureRequest:
|
464 | 391 | """A request for a fixture from a test or fixture function.
|
@@ -1585,19 +1512,15 @@ def getfixtureclosure(
|
1585 | 1512 | ignore_args: Sequence[str] = (),
|
1586 | 1513 | ) -> Tuple[List[str], Dict[str, List[FixtureDef[Any]]]]:
|
1587 | 1514 | # Collect the closure of all fixtures, starting with the given
|
1588 |
| - # fixturenames as the initial set. As we have to visit all |
1589 |
| - # factory definitions anyway, we also return an arg2fixturedefs |
| 1515 | + # initialnames as the initial set. As we have to visit all |
| 1516 | + # factory definitions anyway, we also populate arg2fixturedefs |
1590 | 1517 | # mapping so that the caller can reuse it and does not have
|
1591 | 1518 | # to re-discover fixturedefs again for each fixturename
|
1592 | 1519 | # (discovering matching fixtures for a given name/node is expensive).
|
1593 | 1520 |
|
1594 | 1521 | parentid = parentnode.nodeid
|
1595 | 1522 | fixturenames_closure: Dict[str, int] = {}
|
1596 | 1523 |
|
1597 |
| - # At this point, fixturenames_closure contains what we call "initialnames", |
1598 |
| - # which is a set of fixturenames the function immediately requests. We |
1599 |
| - # need to return it as well, so save this. |
1600 |
| - |
1601 | 1524 | arg2num_fixturedefs_used: Dict[str, int] = defaultdict(lambda: 0)
|
1602 | 1525 | arg2num_def_used_in_path: Dict[str, int] = defaultdict(lambda: 0)
|
1603 | 1526 | nodes_in_fixture_tree: Deque[Tuple[str, bool]] = deque(
|
|
0 commit comments