Skip to content

Commit

Permalink
Improve reference and path/fspath docs
Browse files Browse the repository at this point in the history
  • Loading branch information
The-Compiler committed Nov 26, 2021
1 parent 8436d69 commit 9a08b87
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 16 deletions.
4 changes: 4 additions & 0 deletions changelog/8144.feature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ The following hooks now receive an additional ``pathlib.Path`` argument, equival
- :func:`pytest_pycollect_makemodule <_pytest.hookspec.pytest_pycollect_makemodule>` - The ``fspath`` parameter (equivalent to existing ``path`` parameter).
- :func:`pytest_report_header <_pytest.hookspec.pytest_report_header>` - The ``startpath`` parameter (equivalent to existing ``startdir`` parameter).
- :func:`pytest_report_collectionfinish <_pytest.hookspec.pytest_report_collectionfinish>` - The ``startpath`` parameter (equivalent to existing ``startdir`` parameter).

.. 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``).
7 changes: 6 additions & 1 deletion changelog/8251.feature.rst
Original file line number Diff line number Diff line change
@@ -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.
17 changes: 15 additions & 2 deletions doc/en/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
33 changes: 29 additions & 4 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__ = (
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
18 changes: 9 additions & 9 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -1576,26 +1576,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
Expand Down

0 comments on commit 9a08b87

Please sign in to comment.