|
49 | 49 | tracebackcutdir = Path(_pytest.__file__).parent
|
50 | 50 |
|
51 | 51 |
|
52 |
| -def iterparentnodes(node: "Node") -> Iterator["Node"]: |
53 |
| - """Return the parent nodes, including the node itself, from the node |
54 |
| - upwards.""" |
55 |
| - parent: Optional[Node] = node |
56 |
| - while parent is not None: |
57 |
| - yield parent |
58 |
| - parent = parent.parent |
59 |
| - |
60 |
| - |
61 | 52 | _NodeType = TypeVar("_NodeType", bound="Node")
|
62 | 53 |
|
63 | 54 |
|
@@ -265,12 +256,20 @@ def setup(self) -> None:
|
265 | 256 | def teardown(self) -> None:
|
266 | 257 | pass
|
267 | 258 |
|
268 |
| - def listchain(self) -> List["Node"]: |
269 |
| - """Return list of all parent collectors up to self, starting from |
270 |
| - the root of collection tree. |
| 259 | + def iterchain(self) -> Iterator["Node"]: |
| 260 | + """Iterate over self and all parent collectors up to root of the |
| 261 | + collection tree, starting from self. |
271 | 262 |
|
272 |
| - :returns: The nodes. |
| 263 | + .. versionadded:: 8.1 |
273 | 264 | """
|
| 265 | + parent: Optional[Node] = self |
| 266 | + while parent is not None: |
| 267 | + yield parent |
| 268 | + parent = parent.parent |
| 269 | + |
| 270 | + def listchain(self) -> List["Node"]: |
| 271 | + """Return a list of all parent collectors up to and including self, |
| 272 | + starting from the root of the collection tree.""" |
274 | 273 | chain = []
|
275 | 274 | item: Optional[Node] = self
|
276 | 275 | while item is not None:
|
@@ -319,7 +318,7 @@ def iter_markers_with_node(
|
319 | 318 | :param name: If given, filter the results by the name attribute.
|
320 | 319 | :returns: An iterator of (node, mark) tuples.
|
321 | 320 | """
|
322 |
| - for node in reversed(self.listchain()): |
| 321 | + for node in self.iterchain(): |
323 | 322 | for mark in node.own_markers:
|
324 | 323 | if name is None or getattr(mark, "name", None) == name:
|
325 | 324 | yield node, mark
|
@@ -363,17 +362,16 @@ def addfinalizer(self, fin: Callable[[], object]) -> None:
|
363 | 362 | self.session._setupstate.addfinalizer(fin, self)
|
364 | 363 |
|
365 | 364 | def getparent(self, cls: Type[_NodeType]) -> Optional[_NodeType]:
|
366 |
| - """Get the next parent node (including self) which is an instance of |
| 365 | + """Get the closest parent node (including self) which is an instance of |
367 | 366 | the given class.
|
368 | 367 |
|
369 | 368 | :param cls: The node class to search for.
|
370 | 369 | :returns: The node, if found.
|
371 | 370 | """
|
372 |
| - current: Optional[Node] = self |
373 |
| - while current and not isinstance(current, cls): |
374 |
| - current = current.parent |
375 |
| - assert current is None or isinstance(current, cls) |
376 |
| - return current |
| 371 | + for node in self.iterchain(): |
| 372 | + if isinstance(node, cls): |
| 373 | + return node |
| 374 | + return None |
377 | 375 |
|
378 | 376 | def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback:
|
379 | 377 | return excinfo.traceback
|
|
0 commit comments