| 1599 | items[:] = reorder_items(items) |
| 1600 | |
| 1601 | def parsefactories( |
| 1602 | self, node_or_obj, nodeid=NOTSET, unittest: bool = False |
| 1603 | ) -> None: |
| 1604 | if nodeid is not NOTSET: |
| 1605 | holderobj = node_or_obj |
| 1606 | else: |
| 1607 | holderobj = node_or_obj.obj |
| 1608 | nodeid = node_or_obj.nodeid |
| 1609 | if holderobj in self._holderobjseen: |
| 1610 | return |
| 1611 | |
| 1612 | self._holderobjseen.add(holderobj) |
| 1613 | autousenames = [] |
| 1614 | for name in dir(holderobj): |
| 1615 | # ugly workaround for one of the fspath deprecated property of node |
| 1616 | # todo: safely generalize |
| 1617 | if isinstance(holderobj, nodes.Node) and name == "fspath": |
| 1618 | continue |
| 1619 | |
| 1620 | # The attribute can be an arbitrary descriptor, so the attribute |
| 1621 | # access below can raise. safe_getatt() ignores such exceptions. |
| 1622 | obj = safe_getattr(holderobj, name, None) |
| 1623 | marker = getfixturemarker(obj) |
| 1624 | if not isinstance(marker, FixtureFunctionMarker): |
| 1625 | # Magic globals with __getattr__ might have got us a wrong |
| 1626 | # fixture attribute. |
| 1627 | continue |
| 1628 | |
| 1629 | if marker.name: |
| 1630 | name = marker.name |
| 1631 | |
| 1632 | # During fixture definition we wrap the original fixture function |
| 1633 | # to issue a warning if called directly, so here we unwrap it in |
| 1634 | # order to not emit the warning when pytest itself calls the |
| 1635 | # fixture function. |
| 1636 | obj = get_real_method(obj, holderobj) |
| 1637 | |
| 1638 | fixture_def = FixtureDef( |
| 1639 | fixturemanager=self, |
| 1640 | baseid=nodeid, |
| 1641 | argname=name, |
| 1642 | func=obj, |
| 1643 | scope=marker.scope, |
| 1644 | params=marker.params, |
| 1645 | unittest=unittest, |
| 1646 | ids=marker.ids, |
| 1647 | ) |
| 1648 | |
| 1649 | faclist = self._arg2fixturedefs.setdefault(name, []) |
| 1650 | if fixture_def.has_location: |
| 1651 | faclist.append(fixture_def) |
| 1652 | else: |
| 1653 | # fixturedefs with no location are at the front |
| 1654 | # so this inserts the current fixturedef after the |
| 1655 | # existing fixturedefs from external plugins but |
| 1656 | # before the fixturedefs provided in conftests. |
| 1657 | i = len([f for f in faclist if not f.has_location]) |
| 1658 | faclist.insert(i, fixture_def) |