Skip to content

Commit

Permalink
fix pytest-dev#6341 - disallow session/config in Node.from_parent
Browse files Browse the repository at this point in the history
RonnyPfannschmidt committed Jan 15, 2020
1 parent 466bbbf commit 8ba0b7b
Showing 6 changed files with 49 additions and 9 deletions.
4 changes: 4 additions & 0 deletions changelog/5975.deprecation.rst
Original file line number Diff line number Diff line change
@@ -4,3 +4,7 @@ Instead they are new constructed via ``Node.from_parent``.

This transitional mechanism enables us to detangle the very intensely
entangled ``Node`` relationships by enforcing more controlled creation/configruation patterns.

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.

Subclasses are expected to use `super().from_parent` if they intend to expand the creation of `Nodes`.
10 changes: 8 additions & 2 deletions src/_pytest/doctest.py
Original file line number Diff line number Diff line change
@@ -216,8 +216,14 @@ def __init__(self, name, parent, runner=None, dtest=None):
self.fixture_request = None

@classmethod
def from_parent(cls, parent, *, name, runner, dtest):
return cls._create(name=name, parent=parent, runner=runner, dtest=dtest)
def from_parent( # type: ignore
cls, parent: "Union[DoctestTextfile, DoctestModule]", *, name, runner, dtest
):
# incompatible signature due to to imposed limits on sublcass
"""
the public named constructor
"""
return super().from_parent(name=name, parent=parent, runner=runner, dtest=dtest)

def setup(self):
if self.dtest is not None:
23 changes: 20 additions & 3 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
@@ -144,8 +144,22 @@ def __init__(
self._nodeid += "::" + self.name

@classmethod
def from_parent(cls, parent, *, name):
return cls._create(parent=parent, name=name)
def from_parent(cls, parent: "Node", **kw):
"""
Public Constructor for Nodes
This indirection got introduced in order to enable removing
the fragile logic from the node constructors.
Subclasses can use ``super().from_parent(...)`` when overriding the construction
:param parent: the parent node of this test Node
"""
if "config" in kw:
raise TypeError("config is not a valid argument for from_parent")
if "session" in kw:
raise TypeError("session is not a valid argument for from_parent")
return cls._create(parent=parent, **kw)

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

@classmethod
def from_parent(cls, parent, *, fspath):
return cls._create(parent=parent, fspath=fspath)
"""
The public constructor
"""
return super().from_parent(parent=parent, fspath=fspath)


class File(FSCollector):
12 changes: 9 additions & 3 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
@@ -679,7 +679,10 @@ class Class(PyCollector):

@classmethod
def from_parent(cls, parent, *, name, obj=None):
return cls._create(name=name, parent=parent)
"""
The public constructor
"""
return super().from_parent(name=name, parent=parent)

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

@classmethod
def from_parent(cls, parent, **kw):
return cls._create(parent=parent, **kw)
def from_parent(cls, parent, **kw): # todo: determine sound type limitations
"""
The public constructor
"""
return super().from_parent(parent=parent, **kw)

def _initrequest(self):
self.funcargs = {}
2 changes: 1 addition & 1 deletion testing/python/collect.py
Original file line number Diff line number Diff line change
@@ -284,7 +284,7 @@ def make_function(testdir, **kwargs):
session = testdir.Session.from_config(config)
session._fixturemanager = FixtureManager(session)

return pytest.Function.from_parent(config=config, parent=session, **kwargs)
return pytest.Function.from_parent(parent=session, **kwargs)

def test_function_equality(self, testdir, tmpdir):
def func1():
7 changes: 7 additions & 0 deletions testing/test_nodes.py
Original file line number Diff line number Diff line change
@@ -22,6 +22,13 @@ def test_ischildnode(baseid, nodeid, expected):
assert result is expected


def test_node_from_parent_disallowed_arguments():
with pytest.raises(TypeError, match="session is"):
nodes.Node.from_parent(None, session=None)
with pytest.raises(TypeError, match="config is"):
nodes.Node.from_parent(None, config=None)


def test_std_warn_not_pytestwarning(testdir):
items = testdir.getitems(
"""

0 comments on commit 8ba0b7b

Please sign in to comment.