Skip to content

Commit

Permalink
[7.0.x] Add additional docs for uncooperative ctor deprecation (#9552)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Bruhin <me@the-compiler.org>
  • Loading branch information
github-actions[bot] and The-Compiler authored Jan 27, 2022
1 parent e854d05 commit 28e5b3b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
38 changes: 38 additions & 0 deletions doc/en/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <uncooperative-constructors-deprecated>` 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
Expand Down Expand Up @@ -191,6 +195,40 @@ 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 <node-ctor-fspath-deprecation>`), a
deprecation warning is now raised.

Backward compatibilities in ``Parser.addoption``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
4 changes: 2 additions & 2 deletions doc/en/example/nonpython/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
5 changes: 4 additions & 1 deletion src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ 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."
)
)

Expand Down

0 comments on commit 28e5b3b

Please sign in to comment.