Skip to content

Commit 52aaf3c

Browse files
RonnyPfannschmidtCursor AIclaude
committed
refactor(python): move marker/fixture/request setup from Function.__init__ to from_parent
Function.__init__ now only stores _obj, _instance, originalname, and callspec. The marker extension, keyword updates, fixture resolution (getfixtureinfo), and _initrequest() are extracted into a new _setup_markers_and_fixtures method called from from_parent after construction. This keeps __init__ focused on storing values while from_parent handles all post-construction initialization logic. Co-authored-by: Cursor AI <ai@cursor.sh> Co-authored-by: Anthropic Claude <claude@anthropic.com>
1 parent 0d507c4 commit 52aaf3c

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

src/_pytest/python.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,16 +1599,22 @@ def __init__(
15991599
#: .. versionadded:: 3.0
16001600
self.originalname = originalname or name
16011601

1602-
# Note: when FunctionDefinition is introduced, we should change ``originalname``
1603-
# to a readonly property that returns FunctionDefinition.name.
1604-
1605-
self.own_markers.extend(get_unpacked_marks(self.obj))
16061602
if callspec:
16071603
self.callspec = callspec
1608-
self.own_markers.extend(callspec.marks)
16091604

1610-
# todo: this is a hell of a hack
1611-
# https://github.com/pytest-dev/pytest/issues/4569
1605+
def _setup_markers_and_fixtures(
1606+
self,
1607+
keywords: Mapping[str, Any] | None = None,
1608+
fixtureinfo: FuncFixtureInfo | None = None,
1609+
) -> None:
1610+
"""Set up markers, keywords, fixture info, and the fixture request.
1611+
1612+
Called from :meth:`from_parent` after the node is fully constructed.
1613+
"""
1614+
self.own_markers.extend(get_unpacked_marks(self.obj))
1615+
if hasattr(self, "callspec"):
1616+
self.own_markers.extend(self.callspec.marks)
1617+
16121618
# Note: the order of the updates is important here; indicates what
16131619
# takes priority (ctor argument over function attributes over markers).
16141620
# Take own_markers only; NodeKeywords handles parent traversal on its own.
@@ -1624,11 +1630,17 @@ def __init__(
16241630
self.fixturenames = fixtureinfo.names_closure
16251631
self._initrequest()
16261632

1627-
# todo: determine sound type limitations
16281633
@classmethod
16291634
def from_parent(cls, parent, **kw) -> Self:
16301635
"""The public constructor."""
1631-
return super().from_parent(parent=parent, **kw)
1636+
keywords = kw.pop("keywords", None)
1637+
fixtureinfo = kw.pop("fixtureinfo", None)
1638+
item = super().from_parent(parent=parent, **kw)
1639+
item._setup_markers_and_fixtures(
1640+
keywords=keywords,
1641+
fixtureinfo=fixtureinfo,
1642+
)
1643+
return item
16321644

16331645
def _initrequest(self) -> None:
16341646
self.funcargs: dict[str, object] = {}

0 commit comments

Comments
 (0)