diff --git a/doc/en/conf.py b/doc/en/conf.py index b6709ef5b..a217f5499 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -23,9 +23,11 @@ import shutil from textwrap import dedent 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: import sphinx.application @@ -191,6 +193,7 @@ nitpick_ignore = [ ("py:class", "SubRequest"), ("py:class", "TerminalReporter"), ("py:class", "_pytest._code.code.TerminalRepr"), + ("py:class", "TerminalRepr"), ("py:class", "_pytest.fixtures.FixtureFunctionMarker"), ("py:class", "_pytest.logging.LogCaptureHandler"), ("py:class", "_pytest.mark.structures.ParameterSet"), @@ -212,13 +215,16 @@ nitpick_ignore = [ ("py:class", "_PluggyPlugin"), # TypeVars ("py:class", "_pytest._code.code.E"), + ("py:class", "E"), # due to delayed annotation ("py:class", "_pytest.fixtures.FixtureFunction"), ("py:class", "_pytest.nodes._NodeType"), + ("py:class", "_NodeType"), # due to delayed annotation ("py:class", "_pytest.python_api.E"), ("py:class", "_pytest.recwarn.T"), ("py:class", "_pytest.runner.TResult"), ("py:obj", "_pytest.fixtures.FixtureValue"), ("py:obj", "_pytest.stash.T"), + ("py:class", "_ScopeName"), ] diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index d002a6810..323cf7d9a 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -620,7 +620,8 @@ class ExceptionInfo(Generic[E]): showlocals: bool = False, style: _TracebackStyle = "long", abspath: bool = False, - tbfilter: bool | Callable[[ExceptionInfo[BaseException]], Traceback] = True, + tbfilter: bool + | Callable[[ExceptionInfo[BaseException]], _pytest._code.code.Traceback] = True, funcargs: bool = False, truncate_locals: bool = True, chain: bool = True, diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 01542908f..1e2dedbb6 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -13,7 +13,7 @@ import glob import importlib.metadata import inspect import os -from pathlib import Path +import pathlib import re import shlex import sys @@ -113,7 +113,7 @@ class ExitCode(enum.IntEnum): class ConftestImportFailure(Exception): def __init__( self, - path: Path, + path: pathlib.Path, *, cause: Exception, ) -> None: @@ -289,7 +289,7 @@ def get_config( invocation_params=Config.InvocationParams( args=args or (), plugins=plugins, - dir=Path.cwd(), + dir=pathlib.Path.cwd(), ), ) @@ -346,7 +346,7 @@ def _prepareconfig( 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.""" if path.is_file(): return path.parent @@ -407,9 +407,9 @@ class PytestPluginManager(PluginManager): # All conftest modules applicable for a directory. # This includes the directory's own conftest modules as well # 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. - self._confcutdir: Path | None = None + self._confcutdir: pathlib.Path | None = None # If set, conftest loading is skipped. self._noconftest = False @@ -543,12 +543,12 @@ class PytestPluginManager(PluginManager): # def _set_initial_conftests( self, - args: Sequence[str | Path], + args: Sequence[str | pathlib.Path], pyargs: bool, noconftest: bool, - rootpath: Path, - confcutdir: Path | None, - invocation_dir: Path, + rootpath: pathlib.Path, + confcutdir: pathlib.Path | None, + invocation_dir: pathlib.Path, importmode: ImportMode | str, *, consider_namespace_packages: bool, @@ -592,7 +592,7 @@ class PytestPluginManager(PluginManager): 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.""" if self._confcutdir is None: return True @@ -609,9 +609,9 @@ class PytestPluginManager(PluginManager): def _try_load_conftest( self, - anchor: Path, + anchor: pathlib.Path, importmode: str | ImportMode, - rootpath: Path, + rootpath: pathlib.Path, *, consider_namespace_packages: bool, ) -> None: @@ -634,9 +634,9 @@ class PytestPluginManager(PluginManager): def _loadconftestmodules( self, - path: Path, + path: pathlib.Path, importmode: str | ImportMode, - rootpath: Path, + rootpath: pathlib.Path, *, consider_namespace_packages: bool, ) -> None: @@ -664,14 +664,14 @@ class PytestPluginManager(PluginManager): clist.append(mod) 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) return self._dirpath2confmods.get(directory, ()) def _rget_with_confmod( self, name: str, - path: Path, + path: pathlib.Path, ) -> tuple[types.ModuleType, Any]: modules = self._getconftestmodules(path) for mod in reversed(modules): @@ -683,9 +683,9 @@ class PytestPluginManager(PluginManager): def _importconftest( self, - conftestpath: Path, + conftestpath: pathlib.Path, importmode: str | ImportMode, - rootpath: Path, + rootpath: pathlib.Path, *, consider_namespace_packages: bool, ) -> types.ModuleType: @@ -737,7 +737,7 @@ class PytestPluginManager(PluginManager): def _check_non_top_pytest_plugins( self, mod: types.ModuleType, - conftestpath: Path, + conftestpath: pathlib.Path, ) -> None: if ( hasattr(mod, "pytest_plugins") @@ -995,15 +995,15 @@ class Config: """The command-line arguments as passed to :func:`pytest.main`.""" plugins: Sequence[str | _PluggyPlugin] | None """Extra plugins, might be `None`.""" - dir: Path - """The directory from which :func:`pytest.main` was invoked.""" + dir: pathlib.Path + """The directory from which :func:`pytest.main` was invoked. :type: pathlib.Path""" def __init__( self, *, args: Iterable[str], plugins: Sequence[str | _PluggyPlugin] | None, - dir: Path, + dir: pathlib.Path, ) -> None: object.__setattr__(self, "args", tuple(args)) object.__setattr__(self, "plugins", plugins) @@ -1034,7 +1034,7 @@ class Config: if invocation_params is None: invocation_params = self.InvocationParams( - args=(), plugins=None, dir=Path.cwd() + args=(), plugins=None, dir=pathlib.Path.cwd() ) self.option = argparse.Namespace() @@ -1090,7 +1090,7 @@ class Config: self.cache: Optional[Cache] = None @property - def rootpath(self) -> Path: + def rootpath(self) -> pathlib.Path: """The path to the :ref:`rootdir `. :type: pathlib.Path @@ -1100,11 +1100,9 @@ class Config: return self._rootpath @property - def inipath(self) -> Path | None: + def inipath(self) -> pathlib.Path | None: """The path to the :ref:`configfile `. - :type: Optional[pathlib.Path] - .. versionadded:: 6.1 """ return self._inipath @@ -1315,8 +1313,8 @@ class Config: args: list[str], pyargs: bool, testpaths: list[str], - invocation_dir: Path, - rootpath: Path, + invocation_dir: pathlib.Path, + rootpath: pathlib.Path, warn: bool, ) -> tuple[list[str], ArgsSource]: """Decide the args (initial paths/nodeids) to use given the relevant inputs. @@ -1642,17 +1640,19 @@ class Config: else: 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: mod, relroots = self.pluginmanager._rget_with_confmod(name, path) except KeyError: return None assert mod.__file__ is not None - modpath = Path(mod.__file__).parent - values: list[Path] = [] + modpath = pathlib.Path(mod.__file__).parent + values: list[pathlib.Path] = [] for relroot in relroots: if isinstance(relroot, os.PathLike): - relroot = Path(relroot) + relroot = pathlib.Path(relroot) else: relroot = relroot.replace("/", os.sep) relroot = absolutepath(modpath / relroot) diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index d10264218..f8fc7a8b4 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -320,6 +320,7 @@ def pytest_ignore_collect( Stops at first non-None result, see :ref:`firstresult`. :param collection_path: The path to analyze. + :type collection_path: pathlib.Path :param path: The path to analyze (deprecated). :param config: The pytest config object. @@ -353,6 +354,7 @@ def pytest_collect_directory(path: Path, parent: Collector) -> Collector | None: Stops at first non-None result, see :ref:`firstresult`. :param path: The path to analyze. + :type path: pathlib.Path See :ref:`custom directory collectors` for a simple example of use of this hook. @@ -385,6 +387,7 @@ def pytest_collect_file( The new node needs to have the specified ``parent`` as a parent. :param file_path: The path to analyze. + :type file_path: pathlib.Path :param path: The path to collect (deprecated). .. versionchanged:: 7.0.0 @@ -506,6 +509,7 @@ def pytest_pycollect_makemodule( Stops at first non-None result, see :ref:`firstresult`. :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). .. versionchanged:: 7.0.0 @@ -1025,6 +1029,7 @@ def pytest_report_header( # type:ignore[empty-body] :param config: The pytest config object. :param start_path: The starting dir. + :type start_path: pathlib.Path :param startdir: The starting dir (deprecated). .. note:: @@ -1068,6 +1073,7 @@ def pytest_report_collectionfinish( # type:ignore[empty-body] :param config: The pytest config object. :param start_path: The starting dir. + :type start_path: pathlib.Path :param startdir: The starting dir (deprecated). :param items: List of pytest items that are going to be executed; this list should not be modified. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 2683e15ad..843de5d9a 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -509,6 +509,7 @@ class Dir(nodes.Directory): :param parent: The parent collector of this Dir. :param path: The directory's path. + :type path: pathlib.Path """ return super().from_parent(parent=parent, path=path) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 56479610a..16233fc16 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -906,6 +906,7 @@ class Pytester: The name of the directory, relative to the pytester path. :returns: The created directory. + :rtype: pathlib.Path """ p = self.path / name p.mkdir() @@ -929,6 +930,7 @@ class Pytester: The name of the file to copy. :return: Path to the copied directory (inside ``self.path``). + :rtype: pathlib.Path """ example_dir_ = self._request.config.getini("pytester_example_dir") if example_dir_ is None: @@ -1385,8 +1387,10 @@ class Pytester: - Otherwise, it is passed through to :py:class:`subprocess.Popen`. For further information in this case, consult the document of the ``stdin`` parameter in :py:class:`subprocess.Popen`. + :type stdin: _pytest.compat.NotSetType | bytes | IO[Any] | int :returns: The result. + """ __tracebackhide__ = True diff --git a/src/_pytest/python.py b/src/_pytest/python.py index d659cac0b..2dd2031ec 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1164,7 +1164,7 @@ class Metafunc: If N argnames were specified, argvalues must be a list of N-tuples, where each tuple-element specifies a value for its respective argname. - + :type argvalues: Iterable[_pytest.mark.structures.ParameterSet | Sequence[object] | object] :param indirect: A list of arguments' names (subset of argnames) or a boolean. If True the list contains all names from the argnames. Each diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index a2c4c8b37..f97cf9517 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -322,6 +322,7 @@ class CallInfo(Generic[TResult]): :param func: The function to call. Called without arguments. + :type func: Callable[[], _pytest.runner.TResult] :param when: The phase in which the function is called. :param reraise: diff --git a/tox.ini b/tox.ini index 6ec19f5ae..a7bf6d242 100644 --- a/tox.ini +++ b/tox.ini @@ -81,7 +81,7 @@ setenv = PYTHONWARNDEFAULTENCODING= [testenv:docs] -basepython = python3 +basepython = python3.9 # sync with rtd to get errors usedevelop = True deps = -r{toxinidir}/doc/en/requirements.txt @@ -92,7 +92,11 @@ commands = -git fetch --unshallow -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 = # Sphinx is not clean of this warning. PYTHONWARNDEFAULTENCODING=