Skip to content
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

reference: improve the node types docs a bit #11106

Merged
merged 2 commits into from
Jul 8, 2023
Merged
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
@@ -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
~~~~~~~~~
@@ -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:

@@ -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:

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

Module
~~~~~~

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

Node
~~~~

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

Parser
~~~~~~

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

Session
~~~~~~~

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

TestReport
~~~~~~~~~~

5 changes: 5 additions & 0 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
@@ -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.
21 changes: 13 additions & 8 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
@@ -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.
@@ -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.
@@ -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,
@@ -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.
"""
15 changes: 8 additions & 7 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
@@ -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()
@@ -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],
@@ -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):
@@ -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
@@ -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")