Skip to content

Commit a852ba7

Browse files
fix #6341 - disallow session/config in Node.from_parent
1 parent 466bbbf commit a852ba7

File tree

5 files changed

+45
-9
lines changed

5 files changed

+45
-9
lines changed

src/_pytest/doctest.py

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

218218
@classmethod
219-
def from_parent(cls, parent, *, name, runner, dtest):
220-
return cls._create(name=name, parent=parent, runner=runner, dtest=dtest)
219+
def from_parent( # type: ignore
220+
cls, parent: "Union[DoctestTextfile, DoctestModule]", *, name, runner, dtest
221+
):
222+
# incompatible signature due to to imposed limits on sublcass
223+
"""
224+
the public named constructor
225+
"""
226+
return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest)
221227

222228
def setup(self):
223229
if self.dtest is not None:

src/_pytest/nodes.py

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

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

150164
@property
151165
def ihook(self):
@@ -434,7 +448,10 @@ def __init__(
434448

435449
@classmethod
436450
def from_parent(cls, parent, *, fspath):
437-
return cls._create(parent=parent, fspath=fspath)
451+
"""
452+
The public constructor
453+
"""
454+
return super().from_parent(parent=parent, fspath=fspath)
438455

439456

440457
class File(FSCollector):

src/_pytest/python.py

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

680680
@classmethod
681681
def from_parent(cls, parent, *, name, obj=None):
682-
return cls._create(name=name, parent=parent)
682+
"""
683+
The public constructor
684+
"""
685+
return super().from_parent(name=name, parent=parent)
683686

684687
def collect(self):
685688
if not safe_getattr(self.obj, "__test__", True):
@@ -1458,8 +1461,11 @@ def __init__(
14581461
self.originalname = originalname
14591462

14601463
@classmethod
1461-
def from_parent(cls, parent, **kw):
1462-
return cls._create(parent=parent, **kw)
1464+
def from_parent(cls, parent, **kw): # todo: determine sound type limitations
1465+
"""
1466+
The public constructor
1467+
"""
1468+
return super().from_parent(parent=parent, **kw)
14631469

14641470
def _initrequest(self):
14651471
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, tmpdir):
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)