Skip to content

Commit 64ab68f

Browse files
authored
Fix 6341 disallow session config in fromparent (#6387)
Fix 6341 disallow session config in fromparent
2 parents 595d62b + 8ba0b7b commit 64ab68f

File tree

6 files changed

+49
-9
lines changed

6 files changed

+49
-9
lines changed

changelog/5975.deprecation.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ Instead they are new constructed via ``Node.from_parent``.
44

55
This transitional mechanism enables us to detangle the very intensely
66
entangled ``Node`` relationships by enforcing more controlled creation/configruation patterns.
7+
8+
As part of that session/config are already disallowed parameters and as we work on the details we might need disallow a few more as well.
9+
10+
Subclasses are expected to use `super().from_parent` if they intend to expand the creation of `Nodes`.

src/_pytest/doctest.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,14 @@ def __init__(self, name, parent, runner=None, dtest=None):
220220
self.fixture_request = None
221221

222222
@classmethod
223-
def from_parent(cls, parent, *, name, runner, dtest):
224-
return cls._create(name=name, parent=parent, runner=runner, dtest=dtest)
223+
def from_parent( # type: ignore
224+
cls, parent: "Union[DoctestTextfile, DoctestModule]", *, name, runner, dtest
225+
):
226+
# incompatible signature due to to imposed limits on sublcass
227+
"""
228+
the public named constructor
229+
"""
230+
return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest)
225231

226232
def setup(self):
227233
if self.dtest is not None:

src/_pytest/nodes.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,22 @@ def __init__(
145145
self._nodeid += "::" + self.name
146146

147147
@classmethod
148-
def from_parent(cls, parent, *, name):
149-
return cls._create(parent=parent, name=name)
148+
def from_parent(cls, parent: "Node", **kw):
149+
"""
150+
Public Constructor for Nodes
151+
152+
This indirection got introduced in order to enable removing
153+
the fragile logic from the node constructors.
154+
155+
Subclasses can use ``super().from_parent(...)`` when overriding the construction
156+
157+
:param parent: the parent node of this test Node
158+
"""
159+
if "config" in kw:
160+
raise TypeError("config is not a valid argument for from_parent")
161+
if "session" in kw:
162+
raise TypeError("session is not a valid argument for from_parent")
163+
return cls._create(parent=parent, **kw)
150164

151165
@property
152166
def ihook(self):
@@ -435,7 +449,10 @@ def __init__(
435449

436450
@classmethod
437451
def from_parent(cls, parent, *, fspath):
438-
return cls._create(parent=parent, fspath=fspath)
452+
"""
453+
The public constructor
454+
"""
455+
return super().from_parent(parent=parent, fspath=fspath)
439456

440457

441458
class File(FSCollector):

src/_pytest/python.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,10 @@ class Class(PyCollector):
687687

688688
@classmethod
689689
def from_parent(cls, parent, *, name, obj=None):
690-
return cls._create(name=name, parent=parent)
690+
"""
691+
The public constructor
692+
"""
693+
return super().from_parent(name=name, parent=parent)
691694

692695
def collect(self):
693696
if not safe_getattr(self.obj, "__test__", True):
@@ -1475,8 +1478,11 @@ def __init__(
14751478
self.originalname = originalname
14761479

14771480
@classmethod
1478-
def from_parent(cls, parent, **kw):
1479-
return cls._create(parent=parent, **kw)
1481+
def from_parent(cls, parent, **kw): # todo: determine sound type limitations
1482+
"""
1483+
The public constructor
1484+
"""
1485+
return super().from_parent(parent=parent, **kw)
14801486

14811487
def _initrequest(self):
14821488
self.funcargs = {}

testing/python/collect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def make_function(testdir, **kwargs):
284284
session = testdir.Session.from_config(config)
285285
session._fixturemanager = FixtureManager(session)
286286

287-
return pytest.Function.from_parent(config=config, parent=session, **kwargs)
287+
return pytest.Function.from_parent(parent=session, **kwargs)
288288

289289
def test_function_equality(self, testdir):
290290
def func1():

testing/test_nodes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ def test_ischildnode(baseid, nodeid, expected):
2222
assert result is expected
2323

2424

25+
def test_node_from_parent_disallowed_arguments():
26+
with pytest.raises(TypeError, match="session is"):
27+
nodes.Node.from_parent(None, session=None)
28+
with pytest.raises(TypeError, match="config is"):
29+
nodes.Node.from_parent(None, config=None)
30+
31+
2532
def test_std_warn_not_pytestwarning(testdir):
2633
items = testdir.getitems(
2734
"""

0 commit comments

Comments
 (0)