resolve most sphinx lookup errors

add the extra sphinx annotations to refer to Path instances

add Path to nitpicky ignore
This commit is contained in:
Ronny Pfannschmidt 2024-06-17 18:03:10 +02:00
parent b7c0295e1a
commit 5e1649f59a
9 changed files with 62 additions and 39 deletions

View File

@ -23,9 +23,11 @@ import shutil
from textwrap import dedent from textwrap import dedent
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from _pytest import __version__ as version from _pytest import __version__ as full_version
version = full_version.split("+")[0]
if TYPE_CHECKING: if TYPE_CHECKING:
import sphinx.application import sphinx.application
@ -191,6 +193,7 @@ nitpick_ignore = [
("py:class", "SubRequest"), ("py:class", "SubRequest"),
("py:class", "TerminalReporter"), ("py:class", "TerminalReporter"),
("py:class", "_pytest._code.code.TerminalRepr"), ("py:class", "_pytest._code.code.TerminalRepr"),
("py:class", "TerminalRepr"),
("py:class", "_pytest.fixtures.FixtureFunctionMarker"), ("py:class", "_pytest.fixtures.FixtureFunctionMarker"),
("py:class", "_pytest.logging.LogCaptureHandler"), ("py:class", "_pytest.logging.LogCaptureHandler"),
("py:class", "_pytest.mark.structures.ParameterSet"), ("py:class", "_pytest.mark.structures.ParameterSet"),
@ -212,13 +215,16 @@ nitpick_ignore = [
("py:class", "_PluggyPlugin"), ("py:class", "_PluggyPlugin"),
# TypeVars # TypeVars
("py:class", "_pytest._code.code.E"), ("py:class", "_pytest._code.code.E"),
("py:class", "E"), # due to delayed annotation
("py:class", "_pytest.fixtures.FixtureFunction"), ("py:class", "_pytest.fixtures.FixtureFunction"),
("py:class", "_pytest.nodes._NodeType"), ("py:class", "_pytest.nodes._NodeType"),
("py:class", "_NodeType"), # due to delayed annotation
("py:class", "_pytest.python_api.E"), ("py:class", "_pytest.python_api.E"),
("py:class", "_pytest.recwarn.T"), ("py:class", "_pytest.recwarn.T"),
("py:class", "_pytest.runner.TResult"), ("py:class", "_pytest.runner.TResult"),
("py:obj", "_pytest.fixtures.FixtureValue"), ("py:obj", "_pytest.fixtures.FixtureValue"),
("py:obj", "_pytest.stash.T"), ("py:obj", "_pytest.stash.T"),
("py:class", "_ScopeName"),
] ]

View File

@ -620,7 +620,8 @@ class ExceptionInfo(Generic[E]):
showlocals: bool = False, showlocals: bool = False,
style: TracebackStyle = "long", style: TracebackStyle = "long",
abspath: bool = False, abspath: bool = False,
tbfilter: bool | Callable[[ExceptionInfo[BaseException]], Traceback] = True, tbfilter: bool
| Callable[[ExceptionInfo[BaseException]], _pytest._code.code.Traceback] = True,
funcargs: bool = False, funcargs: bool = False,
truncate_locals: bool = True, truncate_locals: bool = True,
truncate_args: bool = True, truncate_args: bool = True,

View File

@ -13,7 +13,7 @@ import glob
import importlib.metadata import importlib.metadata
import inspect import inspect
import os import os
from pathlib import Path import pathlib
import re import re
import shlex import shlex
import sys import sys
@ -114,7 +114,7 @@ class ExitCode(enum.IntEnum):
class ConftestImportFailure(Exception): class ConftestImportFailure(Exception):
def __init__( def __init__(
self, self,
path: Path, path: pathlib.Path,
*, *,
cause: Exception, cause: Exception,
) -> None: ) -> None:
@ -290,7 +290,7 @@ def get_config(
invocation_params=Config.InvocationParams( invocation_params=Config.InvocationParams(
args=args or (), args=args or (),
plugins=plugins, plugins=plugins,
dir=Path.cwd(), dir=pathlib.Path.cwd(),
), ),
) )
@ -347,7 +347,7 @@ def _prepareconfig(
raise raise
def _get_directory(path: Path) -> Path: def _get_directory(path: pathlib.Path) -> pathlib.Path:
"""Get the directory of a path - itself if already a directory.""" """Get the directory of a path - itself if already a directory."""
if path.is_file(): if path.is_file():
return path.parent return path.parent
@ -408,9 +408,9 @@ class PytestPluginManager(PluginManager):
# All conftest modules applicable for a directory. # All conftest modules applicable for a directory.
# This includes the directory's own conftest modules as well # This includes the directory's own conftest modules as well
# as those of its parent directories. # as those of its parent directories.
self._dirpath2confmods: dict[Path, list[types.ModuleType]] = {} self._dirpath2confmods: dict[pathlib.Path, list[types.ModuleType]] = {}
# Cutoff directory above which conftests are no longer discovered. # Cutoff directory above which conftests are no longer discovered.
self._confcutdir: Path | None = None self._confcutdir: pathlib.Path | None = None
# If set, conftest loading is skipped. # If set, conftest loading is skipped.
self._noconftest = False self._noconftest = False
@ -544,12 +544,12 @@ class PytestPluginManager(PluginManager):
# #
def _set_initial_conftests( def _set_initial_conftests(
self, self,
args: Sequence[str | Path], args: Sequence[str | pathlib.Path],
pyargs: bool, pyargs: bool,
noconftest: bool, noconftest: bool,
rootpath: Path, rootpath: pathlib.Path,
confcutdir: Path | None, confcutdir: pathlib.Path | None,
invocation_dir: Path, invocation_dir: pathlib.Path,
importmode: ImportMode | str, importmode: ImportMode | str,
*, *,
consider_namespace_packages: bool, consider_namespace_packages: bool,
@ -593,7 +593,7 @@ class PytestPluginManager(PluginManager):
consider_namespace_packages=consider_namespace_packages, consider_namespace_packages=consider_namespace_packages,
) )
def _is_in_confcutdir(self, path: Path) -> bool: def _is_in_confcutdir(self, path: pathlib.Path) -> bool:
"""Whether to consider the given path to load conftests from.""" """Whether to consider the given path to load conftests from."""
if self._confcutdir is None: if self._confcutdir is None:
return True return True
@ -610,9 +610,9 @@ class PytestPluginManager(PluginManager):
def _try_load_conftest( def _try_load_conftest(
self, self,
anchor: Path, anchor: pathlib.Path,
importmode: str | ImportMode, importmode: str | ImportMode,
rootpath: Path, rootpath: pathlib.Path,
*, *,
consider_namespace_packages: bool, consider_namespace_packages: bool,
) -> None: ) -> None:
@ -635,9 +635,9 @@ class PytestPluginManager(PluginManager):
def _loadconftestmodules( def _loadconftestmodules(
self, self,
path: Path, path: pathlib.Path,
importmode: str | ImportMode, importmode: str | ImportMode,
rootpath: Path, rootpath: pathlib.Path,
*, *,
consider_namespace_packages: bool, consider_namespace_packages: bool,
) -> None: ) -> None:
@ -665,14 +665,14 @@ class PytestPluginManager(PluginManager):
clist.append(mod) clist.append(mod)
self._dirpath2confmods[directory] = clist self._dirpath2confmods[directory] = clist
def _getconftestmodules(self, path: Path) -> Sequence[types.ModuleType]: def _getconftestmodules(self, path: pathlib.Path) -> Sequence[types.ModuleType]:
directory = self._get_directory(path) directory = self._get_directory(path)
return self._dirpath2confmods.get(directory, ()) return self._dirpath2confmods.get(directory, ())
def _rget_with_confmod( def _rget_with_confmod(
self, self,
name: str, name: str,
path: Path, path: pathlib.Path,
) -> tuple[types.ModuleType, Any]: ) -> tuple[types.ModuleType, Any]:
modules = self._getconftestmodules(path) modules = self._getconftestmodules(path)
for mod in reversed(modules): for mod in reversed(modules):
@ -684,9 +684,9 @@ class PytestPluginManager(PluginManager):
def _importconftest( def _importconftest(
self, self,
conftestpath: Path, conftestpath: pathlib.Path,
importmode: str | ImportMode, importmode: str | ImportMode,
rootpath: Path, rootpath: pathlib.Path,
*, *,
consider_namespace_packages: bool, consider_namespace_packages: bool,
) -> types.ModuleType: ) -> types.ModuleType:
@ -738,7 +738,7 @@ class PytestPluginManager(PluginManager):
def _check_non_top_pytest_plugins( def _check_non_top_pytest_plugins(
self, self,
mod: types.ModuleType, mod: types.ModuleType,
conftestpath: Path, conftestpath: pathlib.Path,
) -> None: ) -> None:
if ( if (
hasattr(mod, "pytest_plugins") hasattr(mod, "pytest_plugins")
@ -995,15 +995,15 @@ class Config:
"""The command-line arguments as passed to :func:`pytest.main`.""" """The command-line arguments as passed to :func:`pytest.main`."""
plugins: Sequence[str | _PluggyPlugin] | None plugins: Sequence[str | _PluggyPlugin] | None
"""Extra plugins, might be `None`.""" """Extra plugins, might be `None`."""
dir: Path dir: pathlib.Path
"""The directory from which :func:`pytest.main` was invoked.""" """The directory from which :func:`pytest.main` was invoked. :type: pathlib.Path"""
def __init__( def __init__(
self, self,
*, *,
args: Iterable[str], args: Iterable[str],
plugins: Sequence[str | _PluggyPlugin] | None, plugins: Sequence[str | _PluggyPlugin] | None,
dir: Path, dir: pathlib.Path,
) -> None: ) -> None:
object.__setattr__(self, "args", tuple(args)) object.__setattr__(self, "args", tuple(args))
object.__setattr__(self, "plugins", plugins) object.__setattr__(self, "plugins", plugins)
@ -1037,7 +1037,7 @@ class Config:
if invocation_params is None: if invocation_params is None:
invocation_params = self.InvocationParams( invocation_params = self.InvocationParams(
args=(), plugins=None, dir=Path.cwd() args=(), plugins=None, dir=pathlib.Path.cwd()
) )
self.option = argparse.Namespace() self.option = argparse.Namespace()
@ -1088,7 +1088,7 @@ class Config:
self.args: list[str] = [] self.args: list[str] = []
@property @property
def rootpath(self) -> Path: def rootpath(self) -> pathlib.Path:
"""The path to the :ref:`rootdir <rootdir>`. """The path to the :ref:`rootdir <rootdir>`.
:type: pathlib.Path :type: pathlib.Path
@ -1098,11 +1098,9 @@ class Config:
return self._rootpath return self._rootpath
@property @property
def inipath(self) -> Path | None: def inipath(self) -> pathlib.Path | None:
"""The path to the :ref:`configfile <configfiles>`. """The path to the :ref:`configfile <configfiles>`.
:type: Optional[pathlib.Path]
.. versionadded:: 6.1 .. versionadded:: 6.1
""" """
return self._inipath return self._inipath
@ -1313,8 +1311,8 @@ class Config:
args: list[str], args: list[str],
pyargs: bool, pyargs: bool,
testpaths: list[str], testpaths: list[str],
invocation_dir: Path, invocation_dir: pathlib.Path,
rootpath: Path, rootpath: pathlib.Path,
warn: bool, warn: bool,
) -> tuple[list[str], ArgsSource]: ) -> tuple[list[str], ArgsSource]:
"""Decide the args (initial paths/nodeids) to use given the relevant inputs. """Decide the args (initial paths/nodeids) to use given the relevant inputs.
@ -1640,17 +1638,19 @@ class Config:
else: else:
return self._getini_unknown_type(name, type, value) return self._getini_unknown_type(name, type, value)
def _getconftest_pathlist(self, name: str, path: Path) -> list[Path] | None: def _getconftest_pathlist(
self, name: str, path: pathlib.Path
) -> list[pathlib.Path] | None:
try: try:
mod, relroots = self.pluginmanager._rget_with_confmod(name, path) mod, relroots = self.pluginmanager._rget_with_confmod(name, path)
except KeyError: except KeyError:
return None return None
assert mod.__file__ is not None assert mod.__file__ is not None
modpath = Path(mod.__file__).parent modpath = pathlib.Path(mod.__file__).parent
values: list[Path] = [] values: list[pathlib.Path] = []
for relroot in relroots: for relroot in relroots:
if isinstance(relroot, os.PathLike): if isinstance(relroot, os.PathLike):
relroot = Path(relroot) relroot = pathlib.Path(relroot)
else: else:
relroot = relroot.replace("/", os.sep) relroot = relroot.replace("/", os.sep)
relroot = absolutepath(modpath / relroot) relroot = absolutepath(modpath / relroot)

View File

@ -321,6 +321,7 @@ def pytest_ignore_collect(
Stops at first non-None result, see :ref:`firstresult`. Stops at first non-None result, see :ref:`firstresult`.
:param collection_path: The path to analyze. :param collection_path: The path to analyze.
:type collection_path: pathlib.Path
:param path: The path to analyze (deprecated). :param path: The path to analyze (deprecated).
:param config: The pytest config object. :param config: The pytest config object.
@ -354,6 +355,7 @@ def pytest_collect_directory(path: Path, parent: Collector) -> Collector | None:
Stops at first non-None result, see :ref:`firstresult`. Stops at first non-None result, see :ref:`firstresult`.
:param path: The path to analyze. :param path: The path to analyze.
:type path: pathlib.Path
See :ref:`custom directory collectors` for a simple example of use of this See :ref:`custom directory collectors` for a simple example of use of this
hook. hook.
@ -386,6 +388,7 @@ def pytest_collect_file(
The new node needs to have the specified ``parent`` as a parent. The new node needs to have the specified ``parent`` as a parent.
:param file_path: The path to analyze. :param file_path: The path to analyze.
:type file_path: pathlib.Path
:param path: The path to collect (deprecated). :param path: The path to collect (deprecated).
.. versionchanged:: 7.0.0 .. versionchanged:: 7.0.0
@ -507,6 +510,7 @@ def pytest_pycollect_makemodule(
Stops at first non-None result, see :ref:`firstresult`. Stops at first non-None result, see :ref:`firstresult`.
:param module_path: The path of the module to collect. :param module_path: The path of the module to collect.
:type module_path: pathlib.Path
:param path: The path of the module to collect (deprecated). :param path: The path of the module to collect (deprecated).
.. versionchanged:: 7.0.0 .. versionchanged:: 7.0.0
@ -1026,6 +1030,7 @@ def pytest_report_header( # type:ignore[empty-body]
:param config: The pytest config object. :param config: The pytest config object.
:param start_path: The starting dir. :param start_path: The starting dir.
:type start_path: pathlib.Path
:param startdir: The starting dir (deprecated). :param startdir: The starting dir (deprecated).
.. note:: .. note::
@ -1069,6 +1074,7 @@ def pytest_report_collectionfinish( # type:ignore[empty-body]
:param config: The pytest config object. :param config: The pytest config object.
:param start_path: The starting dir. :param start_path: The starting dir.
:type start_path: pathlib.Path
:param startdir: The starting dir (deprecated). :param startdir: The starting dir (deprecated).
:param items: List of pytest items that are going to be executed; this list should not be modified. :param items: List of pytest items that are going to be executed; this list should not be modified.

View File

@ -510,6 +510,7 @@ class Dir(nodes.Directory):
:param parent: The parent collector of this Dir. :param parent: The parent collector of this Dir.
:param path: The directory's path. :param path: The directory's path.
:type path: pathlib.Path
""" """
return super().from_parent(parent=parent, path=path) return super().from_parent(parent=parent, path=path)

View File

@ -909,6 +909,7 @@ class Pytester:
The name of the directory, relative to the pytester path. The name of the directory, relative to the pytester path.
:returns: :returns:
The created directory. The created directory.
:rtype: pathlib.Path
""" """
p = self.path / name p = self.path / name
p.mkdir() p.mkdir()
@ -932,6 +933,7 @@ class Pytester:
The name of the file to copy. The name of the file to copy.
:return: :return:
Path to the copied directory (inside ``self.path``). Path to the copied directory (inside ``self.path``).
:rtype: pathlib.Path
""" """
example_dir_ = self._request.config.getini("pytester_example_dir") example_dir_ = self._request.config.getini("pytester_example_dir")
if example_dir_ is None: if example_dir_ is None:
@ -1390,8 +1392,10 @@ class Pytester:
- Otherwise, it is passed through to :py:class:`subprocess.Popen`. - Otherwise, it is passed through to :py:class:`subprocess.Popen`.
For further information in this case, consult the document of the For further information in this case, consult the document of the
``stdin`` parameter in :py:class:`subprocess.Popen`. ``stdin`` parameter in :py:class:`subprocess.Popen`.
:type stdin: _pytest.compat.NotSetType | bytes | IO[Any] | int
:returns: :returns:
The result. The result.
""" """
__tracebackhide__ = True __tracebackhide__ = True

View File

@ -1168,7 +1168,7 @@ class Metafunc:
If N argnames were specified, argvalues must be a list of If N argnames were specified, argvalues must be a list of
N-tuples, where each tuple-element specifies a value for its N-tuples, where each tuple-element specifies a value for its
respective argname. respective argname.
:type argvalues: Iterable[_pytest.mark.structures.ParameterSet | Sequence[object] | object]
:param indirect: :param indirect:
A list of arguments' names (subset of argnames) or a boolean. A list of arguments' names (subset of argnames) or a boolean.
If True the list contains all names from the argnames. Each If True the list contains all names from the argnames. Each

View File

@ -327,6 +327,7 @@ class CallInfo(Generic[TResult]):
:param func: :param func:
The function to call. Called without arguments. The function to call. Called without arguments.
:type func: Callable[[], _pytest.runner.TResult]
:param when: :param when:
The phase in which the function is called. The phase in which the function is called.
:param reraise: :param reraise:

View File

@ -81,7 +81,7 @@ setenv =
PYTHONWARNDEFAULTENCODING= PYTHONWARNDEFAULTENCODING=
[testenv:docs] [testenv:docs]
basepython = python3 basepython = python3.9 # sync with rtd to get errors
usedevelop = True usedevelop = True
deps = deps =
-r{toxinidir}/doc/en/requirements.txt -r{toxinidir}/doc/en/requirements.txt
@ -92,7 +92,11 @@ commands =
-git fetch --unshallow -git fetch --unshallow
-git fetch --tags -git fetch --tags
sphinx-build -W --keep-going -b html doc/en doc/en/_build/html {posargs:} sphinx-build \
-j auto \
-W --keep-going \
-b html doc/en doc/en/_build/html \
{posargs:}
setenv = setenv =
# Sphinx is not clean of this warning. # Sphinx is not clean of this warning.
PYTHONWARNDEFAULTENCODING= PYTHONWARNDEFAULTENCODING=