From 375be235d759059b4c7df3c0d360829d99a1d2c0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 10 Jan 2022 11:51:07 +0100 Subject: [PATCH] Add additional docs for uncooperative ctor deprecation Fixes #9488 --- doc/en/deprecations.rst | 40 ++++++++++++++++++++++++++++ doc/en/example/nonpython/conftest.py | 4 +-- src/_pytest/nodes.py | 4 ++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 6351d1f6e6a..bcc71f4a383 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -56,6 +56,10 @@ Plugins which implement custom items and collectors are encouraged to replace ``fspath`` parameters (``py.path.local``) with ``path`` parameters (``pathlib.Path``), and drop any other usage of the ``py`` library if possible. +If possible, plugins with custom items should use :ref:`cooperative +constructors ` to avoid hardcoding +arguments they only pass on to the superclass. + .. note:: The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the new attribute being ``path``) is **the opposite** of the situation for @@ -191,6 +195,42 @@ Instead, a separate collector node should be used, which collects the item. See .. _example pr fixing inheritance: https://github.com/asmeurer/pytest-flakes/pull/40/files +.. _uncooperative-constructors-deprecated: + +Constructors of custom :class:`pytest.Node` subclasses should take ``**kwargs`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 7.0 + +If custom subclasses of nodes like :class:`pytest.Item` override the +``__init__`` method, they should take ``**kwargs``. Thus, + +.. code-block:: python + + class CustomItem(pytest.Item): + + def __init__(self, name, parent, additional_arg): + super().__init__(name, parent) + self.additional_arg = additional_arg + +should be turned into: + +.. code-block:: python + + class CustomItem(pytest.Item): + + def __init__(self, additional_arg, **kwargs): + super().__init__(**kwargs) + self.additional_arg = additional_arg + +to avoid hard-coding the arguments pytest can pass to the superclass. +See :ref:`non-python tests` for a full example. + +For cases without conflicts, no deprecation warning is emitted. For cases with +conflicts (such as :class:`pytest.File` now taking ``path`` instead of +``fspath``, as :ref:`outlined above `), a +deprecation warning is now raised. + Backward compatibilities in ``Parser.addoption`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/en/example/nonpython/conftest.py b/doc/en/example/nonpython/conftest.py index 7ec4134036c..f9b76387022 100644 --- a/doc/en/example/nonpython/conftest.py +++ b/doc/en/example/nonpython/conftest.py @@ -18,8 +18,8 @@ def collect(self): class YamlItem(pytest.Item): - def __init__(self, name, parent, spec): - super().__init__(name, parent) + def __init__(self, spec, **kwargs): + super().__init__(**kwargs) self.spec = spec def runtest(self): diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 53dea04e795..e77525212b9 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -145,7 +145,9 @@ def _create(self, *k, **kw): warnings.warn( PytestDeprecationWarning( - f"{self} is not using a cooperative constructor and only takes {set(known_kw)}" + f"{self} is not using a cooperative constructor and only takes {set(known_kw)}.\n" + "See https://docs.pytest.org/en/stable/deprecations.html#constructors-of-custom-pytest-node-subclasses-should-take-kwargs" + " for more details." ) )