@@ -132,6 +132,12 @@ def get_scope_package(
132
132
133
133
134
134
def get_scope_node (node : nodes .Node , scope : Scope ) -> nodes .Node | None :
135
+ """Get the closest parent node (including self) which matches the given
136
+ scope.
137
+
138
+ If there is no parent node for the scope (e.g. asking for class scope on a
139
+ Module, or on a Function when not defined in a class), returns None.
140
+ """
135
141
import _pytest .python
136
142
137
143
if scope is Scope .Function :
@@ -165,22 +171,30 @@ def getfixturemarker(obj: object) -> FixtureFunctionMarker | None:
165
171
166
172
167
173
@dataclasses .dataclass (frozen = True )
168
- class FixtureArgKey :
174
+ class ParamArgKey :
175
+ """A key for a high-scoped parameter used by an item.
176
+
177
+ For use as a hashable key in `reorder_items`. The combination of fields
178
+ is meant to uniquely identify a particular "instance" of a param,
179
+ potentially shared by multiple items in a scope.
180
+ """
181
+
182
+ #: The param name.
169
183
argname : str
170
184
param_index : int
185
+ #: For scopes Package, Module, Class, the path to the file (directory in
186
+ #: Package's case) of the package/module/class where the item is defined.
171
187
scoped_item_path : Path | None
188
+ #: For Class scope, the class where the item is defined.
172
189
item_cls : type | None
173
190
174
191
175
192
_V = TypeVar ("_V" )
176
193
OrderedSet = dict [_V , None ]
177
194
178
195
179
- def get_parametrized_fixture_argkeys (
180
- item : nodes .Item , scope : Scope
181
- ) -> Iterator [FixtureArgKey ]:
182
- """Return list of keys for all parametrized arguments which match
183
- the specified scope."""
196
+ def get_param_argkeys (item : nodes .Item , scope : Scope ) -> Iterator [ParamArgKey ]:
197
+ """Return all ParamArgKeys for item matching the specified high scope."""
184
198
assert scope is not Scope .Function
185
199
186
200
try :
@@ -206,19 +220,17 @@ def get_parametrized_fixture_argkeys(
206
220
if callspec ._arg2scope [argname ] != scope :
207
221
continue
208
222
param_index = callspec .indices [argname ]
209
- yield FixtureArgKey (argname , param_index , scoped_item_path , item_cls )
223
+ yield ParamArgKey (argname , param_index , scoped_item_path , item_cls )
210
224
211
225
212
226
def reorder_items (items : Sequence [nodes .Item ]) -> list [nodes .Item ]:
213
- argkeys_by_item : dict [Scope , dict [nodes .Item , OrderedSet [FixtureArgKey ]]] = {}
214
- items_by_argkey : dict [
215
- Scope , dict [FixtureArgKey , OrderedDict [nodes .Item , None ]]
216
- ] = {}
227
+ argkeys_by_item : dict [Scope , dict [nodes .Item , OrderedSet [ParamArgKey ]]] = {}
228
+ items_by_argkey : dict [Scope , dict [ParamArgKey , OrderedDict [nodes .Item , None ]]] = {}
217
229
for scope in HIGH_SCOPES :
218
230
scoped_argkeys_by_item = argkeys_by_item [scope ] = {}
219
231
scoped_items_by_argkey = items_by_argkey [scope ] = defaultdict (OrderedDict )
220
232
for item in items :
221
- argkeys = dict .fromkeys (get_parametrized_fixture_argkeys (item , scope ))
233
+ argkeys = dict .fromkeys (get_param_argkeys (item , scope ))
222
234
if argkeys :
223
235
scoped_argkeys_by_item [item ] = argkeys
224
236
for argkey in argkeys :
@@ -234,9 +246,9 @@ def reorder_items(items: Sequence[nodes.Item]) -> list[nodes.Item]:
234
246
235
247
def reorder_items_atscope (
236
248
items : OrderedSet [nodes .Item ],
237
- argkeys_by_item : Mapping [Scope , Mapping [nodes .Item , OrderedSet [FixtureArgKey ]]],
249
+ argkeys_by_item : Mapping [Scope , Mapping [nodes .Item , OrderedSet [ParamArgKey ]]],
238
250
items_by_argkey : Mapping [
239
- Scope , Mapping [FixtureArgKey , OrderedDict [nodes .Item , None ]]
251
+ Scope , Mapping [ParamArgKey , OrderedDict [nodes .Item , None ]]
240
252
],
241
253
scope : Scope ,
242
254
) -> OrderedSet [nodes .Item ]:
@@ -246,7 +258,7 @@ def reorder_items_atscope(
246
258
scoped_items_by_argkey = items_by_argkey [scope ]
247
259
scoped_argkeys_by_item = argkeys_by_item [scope ]
248
260
249
- ignore : set [FixtureArgKey ] = set ()
261
+ ignore : set [ParamArgKey ] = set ()
250
262
items_deque = deque (items )
251
263
items_done : OrderedSet [nodes .Item ] = {}
252
264
while items_deque :
0 commit comments