| 398 | return False |
| 399 | |
| 400 | def collect(self) -> Iterable[nodes.Item | nodes.Collector]: |
| 401 | if not getattr(self.obj, "__test__", True): |
| 402 | return [] |
| 403 | |
| 404 | # Avoid random getattrs and peek in the __dict__ instead. |
| 405 | dicts = [getattr(self.obj, "__dict__", {})] |
| 406 | if isinstance(self.obj, type): |
| 407 | for basecls in self.obj.__mro__: |
| 408 | dicts.append(basecls.__dict__) |
| 409 | |
| 410 | # In each class, nodes should be definition ordered. |
| 411 | # __dict__ is definition ordered. |
| 412 | seen: set[str] = set() |
| 413 | dict_values: list[list[nodes.Item | nodes.Collector]] = [] |
| 414 | collect_imported_tests = self.session.config.getini("collect_imported_tests") |
| 415 | ihook = self.ihook |
| 416 | for dic in dicts: |
| 417 | values: list[nodes.Item | nodes.Collector] = [] |
| 418 | # Note: seems like the dict can change during iteration - |
| 419 | # be careful not to remove the list() without consideration. |
| 420 | for name, obj in list(dic.items()): |
| 421 | if name in IGNORED_ATTRIBUTES: |
| 422 | continue |
| 423 | if name in seen: |
| 424 | continue |
| 425 | seen.add(name) |
| 426 | |
| 427 | if not collect_imported_tests and isinstance(self, Module): |
| 428 | # Do not collect functions and classes from other modules. |
| 429 | if inspect.isfunction(obj) or inspect.isclass(obj): |
| 430 | if obj.__module__ != self._getobj().__name__: |
| 431 | continue |
| 432 | |
| 433 | res = ihook.pytest_pycollect_makeitem( |
| 434 | collector=self, name=name, obj=obj |
| 435 | ) |
| 436 | if res is None: |
| 437 | continue |
| 438 | elif isinstance(res, list): |
| 439 | values.extend(res) |
| 440 | else: |
| 441 | values.append(res) |
| 442 | dict_values.append(values) |
| 443 | |
| 444 | # Between classes in the class hierarchy, reverse-MRO order -- nodes |
| 445 | # inherited from base classes should come before subclasses. |
| 446 | result = [] |
| 447 | for values in reversed(dict_values): |
| 448 | result.extend(values) |
| 449 | return result |
| 450 | |
| 451 | def _genfunctions(self, name: str, funcobj) -> Iterator[Function]: |
| 452 | modulecol = self.getparent(Module) |