From 70b989d51771e0e4a95f8ac69cb70f0d04d7964b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 26 Nov 2021 15:40:17 +0100 Subject: [PATCH 1/5] Improve reference and path/fspath docs Closes #9283 --- changelog/8144.feature.rst | 5 +++++ changelog/8251.feature.rst | 7 ++++++- doc/en/deprecations.rst | 17 +++++++++++++++-- src/_pytest/nodes.py | 33 +++++++++++++++++++++++++++++---- src/_pytest/python.py | 18 +++++++++--------- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/changelog/8144.feature.rst b/changelog/8144.feature.rst index effd4bf84d8..752ee042549 100644 --- a/changelog/8144.feature.rst +++ b/changelog/8144.feature.rst @@ -5,3 +5,8 @@ The following hooks now receive an additional ``pathlib.Path`` argument, equival - :func:`pytest_pycollect_makemodule <_pytest.hookspec.pytest_pycollect_makemodule>` - The ``module_path`` parameter (equivalent to existing ``path`` parameter). - :func:`pytest_report_header <_pytest.hookspec.pytest_report_header>` - The ``start_path`` parameter (equivalent to existing ``startdir`` parameter). - :func:`pytest_report_collectionfinish <_pytest.hookspec.pytest_report_collectionfinish>` - The ``start_path`` parameter (equivalent to existing ``startdir`` parameter). + +.. note:: + The name of the ``Node`` arguments and attributes (the new attribute being + ``path``) is **the opposite** of the situation for hooks (the old argument + being ``path``). diff --git a/changelog/8251.feature.rst b/changelog/8251.feature.rst index 49aede797a0..e1cf29715b0 100644 --- a/changelog/8251.feature.rst +++ b/changelog/8251.feature.rst @@ -1 +1,6 @@ -Implement ``Node.path`` as a ``pathlib.Path``. +Implement ``Node.path`` as a ``pathlib.Path``. This attribute gets set no matter whether ``path`` or (deprecated) ``fspath`` is passed to the constructor. It is a replacement for the ``fspath`` attribute (which represents the same path as ``py.path.local``). While ``fspath`` is not deprecated yet +due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`, we expect to deprecate it in a future release. + +.. note:: + The name of the attributes (old ``fspath``, new ``path``) is **the opposite** + of the situation for hooks. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 84f7b8fa8bd..a45d376f3ba 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -53,9 +53,18 @@ Plugins which construct nodes should pass the ``path`` argument, of type :class:`pathlib.Path`, instead of the ``fspath`` argument. Plugins which implement custom items and collectors are encouraged to replace -``py.path.local`` ``fspath`` parameters with ``pathlib.Path`` parameters, and -drop any other usage of the ``py`` library if possible. +``fspath`` parameters (``py.path.local``) with ``path`` parameters +(``pathlib.Path``), and drop any other usage of the ``py`` library if possible. +.. note:: + The name of the arguments (old ``fspath``, new ``path``) is **the opposite** + of the situation for hooks, :ref:`outlined below <_legacy-path-hooks-deprecated>`. + +Due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo` +which still is expected to return a ``py.path.local`` object, nodes still have +both ``fspath`` (``py.path.local``) and ``path`` (``pathlib.Path``) attributes, +no matter what argument was used in the constructor. We expect to deprecate the +``fspath`` attribute in a future release. .. _legacy-path-hooks-deprecated: @@ -74,6 +83,10 @@ In order to support the transition from ``py.path.local`` to :mod:`pathlib`, the The accompanying ``py.path.local`` based paths have been deprecated: plugins which manually invoke those hooks should only pass the new ``pathlib.Path`` arguments, and users should change their hook implementations to use the new ``pathlib.Path`` arguments. +.. note:: + The name of the arguments (old ``path``, new ``fspath``) is **the opposite** + of the situation for the :class:`~_pytest.nodes.Node` class, :ref:`outlined above <_node-ctor-fspath-deprecation>`. + Directly constructing internal classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 72747e6e6ff..064d06995a1 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -159,6 +159,13 @@ class Node(metaclass=NodeMeta): Collector subclasses have children; Items are leaf nodes. """ + # Implemented in the legacypath plugin. + #: A ``LEGACY_PATH`` copy of the :attr:`path` attribute. Intended for usage + #: for methods not migrated to ``pathlib.Path`` yet, such as + #: :meth:`Item.reportinfo`. Will be deprecated in a future release, prefer + #: using :attr:`path` instead. + fspath: LEGACY_PATH + # Use __slots__ to make attribute access faster. # Note that __dict__ is still available. __slots__ = ( @@ -188,26 +195,26 @@ def __init__( #: The parent collector node. self.parent = parent - #: The pytest config object. if config: + #: The pytest config object. self.config: Config = config else: if not parent: raise TypeError("config or parent must be provided") self.config = parent.config - #: The pytest session this node is part of. if session: + #: The pytest session this node is part of. self.session = session else: if not parent: raise TypeError("session or parent must be provided") self.session = parent.session - #: Filesystem path where this node was collected from (can be None). if path is None and fspath is None: path = getattr(parent, "path", None) - self.path = _imply_path(type(self), path, fspath=fspath) + #: Filesystem path where this node was collected from (can be None). + self.path: Path = _imply_path(type(self), path, fspath=fspath) # The explicit annotation is to avoid publicly exposing NodeKeywords. #: Keywords/markers collected from all scopes. @@ -478,6 +485,8 @@ def repr_failure( ) -> Union[str, TerminalRepr]: """Return a representation of a collection or test failure. + .. seealso:: :ref:`non-python tests` + :param excinfo: Exception information for the failure. """ return self._repr_failure_py(excinfo, style) @@ -686,6 +695,12 @@ def __init__( self.user_properties: List[Tuple[str, object]] = [] def runtest(self) -> None: + """Run the test case for this item. + + Must be implemented by subclasses. + + .. seealso:: :ref:`non-python tests` + """ raise NotImplementedError("runtest must be implemented by Item subclass") def add_report_section(self, when: str, key: str, content: str) -> None: @@ -706,6 +721,16 @@ def add_report_section(self, when: str, key: str, content: str) -> None: self._report_sections.append((when, key, content)) def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str]: + """Get location information for this item for test reports. + + Returns a tuple with three elements: + + - The path of the test (default ``self.path``) + - The line number of the test (default ``None``) + - A name of the test to be shown (default ``""``) + + .. seealso:: :ref:`non-python tests` + """ return self.path, None, "" @cached_property diff --git a/src/_pytest/python.py b/src/_pytest/python.py index ff623625bff..b557cd8fa77 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1578,26 +1578,26 @@ def write_docstring(tw: TerminalWriter, doc: str, indent: str = " ") -> None: class Function(PyobjMixin, nodes.Item): """An Item responsible for setting up and executing a Python test function. - param name: + :param name: The full function name, including any decorations like those added by parametrization (``my_func[my_param]``). - param parent: + :param parent: The parent Node. - param config: + :param config: The pytest Config object. - param callspec: + :param callspec: If given, this is function has been parametrized and the callspec contains meta information about the parametrization. - param callobj: + :param callobj: If given, the object which will be called when the Function is invoked, otherwise the callobj will be obtained from ``parent`` using ``originalname``. - param keywords: + :param keywords: Keywords bound to the function object for "-k" matching. - param session: + :param session: The pytest Session object. - param fixtureinfo: + :param fixtureinfo: Fixture information already resolved at this fixture node.. - param originalname: + :param originalname: The attribute name to use for accessing the underlying function object. Defaults to ``name``. Set this if name is different from the original name, for example when it contains decorations like those added by parametrization From 2c981ee07df9e61f44997a25c321f2d863101c02 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 26 Nov 2021 14:46:46 +0000 Subject: [PATCH 2/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/_pytest/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 064d06995a1..53dea04e795 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -696,7 +696,7 @@ def __init__( def runtest(self) -> None: """Run the test case for this item. - + Must be implemented by subclasses. .. seealso:: :ref:`non-python tests` From 05cf2fdae4e77f8ccf310b6daf4d9ffd109d0353 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 26 Nov 2021 15:49:01 +0100 Subject: [PATCH 3/5] fixups --- changelog/7259.deprecation.rst | 4 ++++ changelog/8251.feature.rst | 2 +- changelog/9341.doc.rst | 1 + doc/en/deprecations.rst | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 changelog/9341.doc.rst diff --git a/changelog/7259.deprecation.rst b/changelog/7259.deprecation.rst index c0307740d55..0668efdf9b3 100644 --- a/changelog/7259.deprecation.rst +++ b/changelog/7259.deprecation.rst @@ -1,3 +1,7 @@ ``py.path.local`` arguments for hooks have been deprecated. See :ref:`the deprecation note ` for full details. ``py.path.local`` arguments to Node constructors have been deprecated. See :ref:`the deprecation note ` for full details. + +.. note:: + The name of the ``Node`` arguments and attributes (old ``fspath``, new ``path``) is **the opposite** + of the situation for hooks (old ``path``, new ``fspath``). diff --git a/changelog/8251.feature.rst b/changelog/8251.feature.rst index e1cf29715b0..c6c677c9677 100644 --- a/changelog/8251.feature.rst +++ b/changelog/8251.feature.rst @@ -1,4 +1,4 @@ -Implement ``Node.path`` as a ``pathlib.Path``. This attribute gets set no matter whether ``path`` or (deprecated) ``fspath`` is passed to the constructor. It is a replacement for the ``fspath`` attribute (which represents the same path as ``py.path.local``). While ``fspath`` is not deprecated yet +Implement ``Node.path`` as a ``pathlib.Path``. Both the old ``fspath`` and this new attribute gets set no matter whether ``path`` or ``fspath`` (deprecated) is passed to the constructor. It is a replacement for the ``fspath`` attribute (which represents the same path as ``py.path.local``). While ``fspath`` is not deprecated yet due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`, we expect to deprecate it in a future release. .. note:: diff --git a/changelog/9341.doc.rst b/changelog/9341.doc.rst new file mode 100644 index 00000000000..1b97a581247 --- /dev/null +++ b/changelog/9341.doc.rst @@ -0,0 +1 @@ +Various methods commonly used for :ref:`non-python tests` are now correctly documented in the reference docs. They were undocumented previously. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index a45d376f3ba..4f1521a9379 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -58,7 +58,7 @@ Plugins which implement custom items and collectors are encouraged to replace .. note:: The name of the arguments (old ``fspath``, new ``path``) is **the opposite** - of the situation for hooks, :ref:`outlined below <_legacy-path-hooks-deprecated>`. + of the situation for hooks, :ref:`outlined below `. Due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo` which still is expected to return a ``py.path.local`` object, nodes still have @@ -85,7 +85,7 @@ The accompanying ``py.path.local`` based paths have been deprecated: plugins whi .. note:: The name of the arguments (old ``path``, new ``fspath``) is **the opposite** - of the situation for the :class:`~_pytest.nodes.Node` class, :ref:`outlined above <_node-ctor-fspath-deprecation>`. + of the situation for the :class:`~_pytest.nodes.Node` class, :ref:`outlined above `. Directly constructing internal classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From aa3c8a1d3ca0381337c23bbcc75998f26c84a93c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 29 Nov 2021 13:30:11 +0100 Subject: [PATCH 4/5] Add explanation --- changelog/7259.deprecation.rst | 3 +++ changelog/8144.feature.rst | 8 ++++++-- changelog/8251.feature.rst | 3 +++ doc/en/deprecations.rst | 6 ++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/changelog/7259.deprecation.rst b/changelog/7259.deprecation.rst index 0668efdf9b3..f9f5a662946 100644 --- a/changelog/7259.deprecation.rst +++ b/changelog/7259.deprecation.rst @@ -5,3 +5,6 @@ .. note:: The name of the ``Node`` arguments and attributes (old ``fspath``, new ``path``) is **the opposite** of the situation for hooks (old ``path``, new ``fspath``). + This is an unfortunate artifact due to historical reasons, which should be + resolved in future versions as we slowly get rid of the :pypi:`py` + dependency (see :issue:`9283` for a longer discussion). diff --git a/changelog/8144.feature.rst b/changelog/8144.feature.rst index 752ee042549..03a3e4f2b9f 100644 --- a/changelog/8144.feature.rst +++ b/changelog/8144.feature.rst @@ -8,5 +8,9 @@ The following hooks now receive an additional ``pathlib.Path`` argument, equival .. note:: The name of the ``Node`` arguments and attributes (the new attribute being - ``path``) is **the opposite** of the situation for hooks (the old argument - being ``path``). + ``path``) is **the opposite** of the situation for hooks (the old argument + being ``path``). + + This is an unfortunate artifact due to historical reasons, which should be + resolved in future versions as we slowly get rid of the :pypi:`py` + dependency (see :issue:`9283` for a longer discussion). diff --git a/changelog/8251.feature.rst b/changelog/8251.feature.rst index c6c677c9677..f4fbf5b5da5 100644 --- a/changelog/8251.feature.rst +++ b/changelog/8251.feature.rst @@ -4,3 +4,6 @@ due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`, w .. note:: The name of the attributes (old ``fspath``, new ``path``) is **the opposite** of the situation for hooks. + This is an unfortunate artifact due to historical reasons, which should be + resolved in future versions as we slowly get rid of the :pypi:`py` + dependency (see :issue:`9283` for a longer discussion). diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 4f1521a9379..b88cd16c77e 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -59,6 +59,9 @@ Plugins which implement custom items and collectors are encouraged to replace .. note:: The name of the arguments (old ``fspath``, new ``path``) is **the opposite** of the situation for hooks, :ref:`outlined below `. + This is an unfortunate artifact due to historical reasons, which should be + resolved in future versions as we slowly get rid of the :pypi:`py` + dependency (see :issue:`9283` for a longer discussion). Due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo` which still is expected to return a ``py.path.local`` object, nodes still have @@ -86,6 +89,9 @@ The accompanying ``py.path.local`` based paths have been deprecated: plugins whi .. note:: The name of the arguments (old ``path``, new ``fspath``) is **the opposite** of the situation for the :class:`~_pytest.nodes.Node` class, :ref:`outlined above `. + This is an unfortunate artifact due to historical reasons, which should be + resolved in future versions as we slowly get rid of the :pypi:`py` + dependency (see :issue:`9283` for a longer discussion). Directly constructing internal classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 69659a92a645d83aa4921bdc5b63f08e25800b46 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 3 Dec 2021 14:48:29 +0100 Subject: [PATCH 5/5] Update wording after #9363 --- changelog/7259.deprecation.rst | 6 ++++-- changelog/8144.feature.rst | 6 +++--- changelog/8251.feature.rst | 6 ++++-- doc/en/deprecations.rst | 14 ++++++++++---- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/changelog/7259.deprecation.rst b/changelog/7259.deprecation.rst index f9f5a662946..ae857c0d826 100644 --- a/changelog/7259.deprecation.rst +++ b/changelog/7259.deprecation.rst @@ -3,8 +3,10 @@ ``py.path.local`` arguments to Node constructors have been deprecated. See :ref:`the deprecation note ` for full details. .. note:: - The name of the ``Node`` arguments and attributes (old ``fspath``, new ``path``) is **the opposite** - of the situation for hooks (old ``path``, new ``fspath``). + The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the + new attribute being ``path``) is **the opposite** of the situation for hooks + (the old argument being ``path``). + This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the :pypi:`py` dependency (see :issue:`9283` for a longer discussion). diff --git a/changelog/8144.feature.rst b/changelog/8144.feature.rst index 03a3e4f2b9f..fe576eeffa8 100644 --- a/changelog/8144.feature.rst +++ b/changelog/8144.feature.rst @@ -7,9 +7,9 @@ The following hooks now receive an additional ``pathlib.Path`` argument, equival - :func:`pytest_report_collectionfinish <_pytest.hookspec.pytest_report_collectionfinish>` - The ``start_path`` parameter (equivalent to existing ``startdir`` parameter). .. note:: - The name of the ``Node`` arguments and attributes (the new attribute being - ``path``) is **the opposite** of the situation for hooks (the old argument - being ``path``). + The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the + new attribute being ``path``) is **the opposite** of the situation for hooks + (the old argument being ``path``). This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the :pypi:`py` diff --git a/changelog/8251.feature.rst b/changelog/8251.feature.rst index f4fbf5b5da5..fe157cc98b7 100644 --- a/changelog/8251.feature.rst +++ b/changelog/8251.feature.rst @@ -2,8 +2,10 @@ Implement ``Node.path`` as a ``pathlib.Path``. Both the old ``fspath`` and this due to the ongoing migration of methods like :meth:`~_pytest.Item.reportinfo`, we expect to deprecate it in a future release. .. note:: - The name of the attributes (old ``fspath``, new ``path``) is **the opposite** - of the situation for hooks. + The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the + new attribute being ``path``) is **the opposite** of the situation for hooks + (the old argument being ``path``). + This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the :pypi:`py` dependency (see :issue:`9283` for a longer discussion). diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index b88cd16c77e..ea9ef2aa35d 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -57,8 +57,11 @@ Plugins which implement custom items and collectors are encouraged to replace (``pathlib.Path``), and drop any other usage of the ``py`` library if possible. .. note:: - The name of the arguments (old ``fspath``, new ``path``) is **the opposite** - of the situation for hooks, :ref:`outlined below `. + The name of the :class:`~_pytest.nodes.Node` arguments and attributes (the + new attribute being ``path``) is **the opposite** of the situation for + hooks, :ref:`outlined below ` (the old + argument being ``path``). + This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the :pypi:`py` dependency (see :issue:`9283` for a longer discussion). @@ -87,8 +90,11 @@ In order to support the transition from ``py.path.local`` to :mod:`pathlib`, the The accompanying ``py.path.local`` based paths have been deprecated: plugins which manually invoke those hooks should only pass the new ``pathlib.Path`` arguments, and users should change their hook implementations to use the new ``pathlib.Path`` arguments. .. note:: - The name of the arguments (old ``path``, new ``fspath``) is **the opposite** - of the situation for the :class:`~_pytest.nodes.Node` class, :ref:`outlined above `. + The name of the :class:`~_pytest.nodes.Node` arguments and attributes, + :ref:`outlined above ` (the new attribute + being ``path``) is **the opposite** of the situation for hooks (the old + argument being ``path``). + This is an unfortunate artifact due to historical reasons, which should be resolved in future versions as we slowly get rid of the :pypi:`py` dependency (see :issue:`9283` for a longer discussion).