(
items: OrderedSet[nodes.Item],
argkeys_by_item: Mapping[Scope, Mapping[nodes.Item, OrderedSet[ParamArgKey]]],
items_by_argkey: Mapping[
Scope, Mapping[ParamArgKey, OrderedDict[nodes.Item, None]]
],
scope: Scope,
)
| 274 | |
| 275 | |
| 276 | def reorder_items_atscope( |
| 277 | items: OrderedSet[nodes.Item], |
| 278 | argkeys_by_item: Mapping[Scope, Mapping[nodes.Item, OrderedSet[ParamArgKey]]], |
| 279 | items_by_argkey: Mapping[ |
| 280 | Scope, Mapping[ParamArgKey, OrderedDict[nodes.Item, None]] |
| 281 | ], |
| 282 | scope: Scope, |
| 283 | ) -> OrderedSet[nodes.Item]: |
| 284 | if scope is Scope.Function or len(items) < 3: |
| 285 | return items |
| 286 | |
| 287 | scoped_items_by_argkey = items_by_argkey[scope] |
| 288 | scoped_argkeys_by_item = argkeys_by_item[scope] |
| 289 | |
| 290 | ignore: set[ParamArgKey] = set() |
| 291 | items_deque = deque(items) |
| 292 | items_done: OrderedSet[nodes.Item] = {} |
| 293 | while items_deque: |
| 294 | no_argkey_items: OrderedSet[nodes.Item] = {} |
| 295 | slicing_argkey = None |
| 296 | while items_deque: |
| 297 | item = items_deque.popleft() |
| 298 | if item in items_done or item in no_argkey_items: |
| 299 | continue |
| 300 | argkeys = dict.fromkeys( |
| 301 | k for k in scoped_argkeys_by_item.get(item, ()) if k not in ignore |
| 302 | ) |
| 303 | if not argkeys: |
| 304 | no_argkey_items[item] = None |
| 305 | else: |
| 306 | slicing_argkey, _ = argkeys.popitem() |
| 307 | # We don't have to remove relevant items from later in the |
| 308 | # deque because they'll just be ignored. |
| 309 | matching_items = [ |
| 310 | i for i in scoped_items_by_argkey[slicing_argkey] if i in items |
| 311 | ] |
| 312 | for i in reversed(matching_items): |
| 313 | items_deque.appendleft(i) |
| 314 | # Fix items_by_argkey order. |
| 315 | for other_scope in HIGH_SCOPES: |
| 316 | other_scoped_items_by_argkey = items_by_argkey[other_scope] |
| 317 | for argkey in argkeys_by_item[other_scope].get(i, ()): |
| 318 | argkey_dict = other_scoped_items_by_argkey[argkey] |
| 319 | if not hasattr(sys, "pypy_version_info"): |
| 320 | argkey_dict[i] = None |
| 321 | argkey_dict.move_to_end(i, last=False) |
| 322 | else: |
| 323 | # Work around a bug in PyPy: |
| 324 | # https://github.com/pypy/pypy/issues/5257 |
| 325 | # https://github.com/pytest-dev/pytest/issues/13312 |
| 326 | bkp = argkey_dict.copy() |
| 327 | argkey_dict.clear() |
| 328 | argkey_dict[i] = None |
| 329 | argkey_dict.update(bkp) |
| 330 | break |
| 331 | if no_argkey_items: |
| 332 | reordered_no_argkey_items = reorder_items_atscope( |
| 333 | no_argkey_items, argkeys_by_item, items_by_argkey, scope.next_lower() |
no test coverage detected