Skip to content

[7.4.x] reference: improve the node types docs a bit #11181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 76 additions & 62 deletions doc/en/reference/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -783,25 +783,17 @@ reporting or interaction with exceptions:
.. autofunction:: pytest_leave_pdb


Objects
-------

Full reference to objects accessible from :ref:`fixtures <fixture>` or :ref:`hooks <hook-reference>`.
Collection tree objects
-----------------------

These are the collector and item classes (collectively called "nodes") which
make up the collection tree.

CallInfo
~~~~~~~~

.. autoclass:: pytest.CallInfo()
:members:


Class
~~~~~
Node
~~~~

.. autoclass:: pytest.Class()
.. autoclass:: _pytest.nodes.Node()
:members:
:show-inheritance:

Collector
~~~~~~~~~
Expand All @@ -810,52 +802,52 @@ Collector
:members:
:show-inheritance:

CollectReport
~~~~~~~~~~~~~
Item
~~~~

.. autoclass:: pytest.CollectReport()
.. autoclass:: pytest.Item()
:members:
:show-inheritance:
:inherited-members:

Config
~~~~~~
File
~~~~

.. autoclass:: pytest.Config()
.. autoclass:: pytest.File()
:members:
:show-inheritance:

ExceptionInfo
~~~~~~~~~~~~~
FSCollector
~~~~~~~~~~~

.. autoclass:: pytest.ExceptionInfo()
.. autoclass:: _pytest.nodes.FSCollector()
:members:
:show-inheritance:

Session
~~~~~~~

ExitCode
~~~~~~~~

.. autoclass:: pytest.ExitCode
.. autoclass:: pytest.Session()
:members:
:show-inheritance:

File
~~~~
Package
~~~~~~~

.. autoclass:: pytest.File()
.. autoclass:: pytest.Package()
:members:
:show-inheritance:

Module
~~~~~~

FixtureDef
~~~~~~~~~~

.. autoclass:: _pytest.fixtures.FixtureDef()
.. autoclass:: pytest.Module()
:members:
:show-inheritance:

FSCollector
~~~~~~~~~~~
Class
~~~~~

.. autoclass:: _pytest.nodes.FSCollector()
.. autoclass:: pytest.Class()
:members:
:show-inheritance:

Expand All @@ -873,10 +865,52 @@ FunctionDefinition
:members:
:show-inheritance:

Item
~~~~

.. autoclass:: pytest.Item()
Objects
-------

Objects accessible from :ref:`fixtures <fixture>` or :ref:`hooks <hook-reference>`
or importable from ``pytest``.


CallInfo
~~~~~~~~

.. autoclass:: pytest.CallInfo()
:members:

CollectReport
~~~~~~~~~~~~~

.. autoclass:: pytest.CollectReport()
:members:
:show-inheritance:
:inherited-members:

Config
~~~~~~

.. autoclass:: pytest.Config()
:members:

ExceptionInfo
~~~~~~~~~~~~~

.. autoclass:: pytest.ExceptionInfo()
:members:


ExitCode
~~~~~~~~

.. autoclass:: pytest.ExitCode
:members:


FixtureDef
~~~~~~~~~~

.. autoclass:: _pytest.fixtures.FixtureDef()
:members:
:show-inheritance:

Expand Down Expand Up @@ -907,19 +941,6 @@ Metafunc
.. autoclass:: pytest.Metafunc()
:members:

Module
~~~~~~

.. autoclass:: pytest.Module()
:members:
:show-inheritance:

Node
~~~~

.. autoclass:: _pytest.nodes.Node()
:members:

Parser
~~~~~~

Expand All @@ -941,13 +962,6 @@ PytestPluginManager
:inherited-members:
:show-inheritance:

Session
~~~~~~~

.. autoclass:: pytest.Session()
:members:
:show-inheritance:

TestReport
~~~~~~~~~~

Expand Down
5 changes: 5 additions & 0 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ def __missing__(self, path: Path) -> str:

@final
class Session(nodes.FSCollector):
"""The root of the collection tree.

``Session`` collects the initial paths given as arguments to pytest.
"""

Interrupted = Interrupted
Failed = Failed
# Set on the session by runner.pytest_sessionstart.
Expand Down
21 changes: 13 additions & 8 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ def _create(self, *k, **kw):


class Node(metaclass=NodeMeta):
"""Base class for Collector and Item, the components of the test
collection tree.
r"""Base class of :class:`Collector` and :class:`Item`, the components of
the test collection tree.

Collector subclasses have children; Items are leaf nodes.
``Collector``\'s are the internal nodes of the tree, and ``Item``\'s are the
leaf nodes.
"""

# Implemented in the legacypath plugin.
Expand Down Expand Up @@ -525,15 +526,17 @@ def get_fslocation_from_item(node: "Node") -> Tuple[Union[str, Path], Optional[i


class Collector(Node):
"""Collector instances create children through collect() and thus
iteratively build a tree."""
"""Base class of all collectors.

Collector create children through `collect()` and thus iteratively build
the collection tree.
"""

class CollectError(Exception):
"""An error during collection, contains a custom message."""

def collect(self) -> Iterable[Union["Item", "Collector"]]:
"""Return a list of children (items and collectors) for this
collection node."""
"""Collect children (items and collectors) for this collector."""
raise NotImplementedError("abstract")

# TODO: This omits the style= parameter which breaks Liskov Substitution.
Expand Down Expand Up @@ -577,6 +580,8 @@ def _check_initialpaths_for_relpath(session: "Session", path: Path) -> Optional[


class FSCollector(Collector):
"""Base class for filesystem collectors."""

def __init__(
self,
fspath: Optional[LEGACY_PATH] = None,
Expand Down Expand Up @@ -660,7 +665,7 @@ class File(FSCollector):


class Item(Node):
"""A basic test invocation item.
"""Base class of all test invocation items.

Note that for a single function there might be multiple test invocation items.
"""
Expand Down
15 changes: 8 additions & 7 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def _genfunctions(self, name: str, funcobj) -> Iterator["Function"]:


class Module(nodes.File, PyCollector):
"""Collector for test classes and functions."""
"""Collector for test classes and functions in a Python module."""

def _getobj(self):
return self._importtestmodule()
Expand Down Expand Up @@ -659,6 +659,9 @@ def _importtestmodule(self):


class Package(Module):
"""Collector for files and directories in a Python packages -- directories
with an `__init__.py` file."""

def __init__(
self,
fspath: Optional[LEGACY_PATH],
Expand Down Expand Up @@ -788,7 +791,7 @@ def _get_first_non_fixture_func(obj: object, names: Iterable[str]) -> Optional[o


class Class(PyCollector):
"""Collector for test methods."""
"""Collector for test methods (and nested classes) in a Python class."""

@classmethod
def from_parent(cls, parent, *, name, obj=None, **kw):
Expand Down Expand Up @@ -1673,7 +1676,7 @@ 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.
"""Item responsible for setting up and executing a Python test function.

:param name:
The full function name, including any decorations like those
Expand Down Expand Up @@ -1830,10 +1833,8 @@ def repr_failure( # type: ignore[override]


class FunctionDefinition(Function):
"""
This class is a step gap solution until we evolve to have actual function definition nodes
and manage to get rid of ``metafunc``.
"""
"""This class is a stop gap solution until we evolve to have actual function
definition nodes and manage to get rid of ``metafunc``."""

def runtest(self) -> None:
raise RuntimeError("function definitions are not supposed to be run as tests")
Expand Down