This commit is contained in:
Iliyan Angelov
2025-12-06 03:27:35 +02:00
parent 7667eb5eda
commit 5a8ca3c475
2211 changed files with 28086 additions and 37066 deletions

View File

@@ -1,19 +1,17 @@
# mypy: allow-untyped-defs
"""Add backward compatibility support for the legacy py path type."""
from __future__ import annotations
import dataclasses
from pathlib import Path
import shlex
import subprocess
from typing import Final
from typing import final
from pathlib import Path
from typing import List
from typing import Optional
from typing import TYPE_CHECKING
from typing import Union
from iniconfig import SectionWrapper
from _pytest.cacheprovider import Cache
from _pytest.compat import final
from _pytest.compat import LEGACY_PATH
from _pytest.compat import legacy_path
from _pytest.config import Config
@@ -33,8 +31,9 @@ from _pytest.pytester import RunResult
from _pytest.terminal import TerminalReporter
from _pytest.tmpdir import TempPathFactory
if TYPE_CHECKING:
from typing_extensions import Final
import pexpect
@@ -49,8 +48,8 @@ class Testdir:
__test__ = False
CLOSE_STDIN: Final = Pytester.CLOSE_STDIN
TimeoutExpired: Final = Pytester.TimeoutExpired
CLOSE_STDIN: "Final" = Pytester.CLOSE_STDIN
TimeoutExpired: "Final" = Pytester.TimeoutExpired
def __init__(self, pytester: Pytester, *, _ispytest: bool = False) -> None:
check_ispytest(_ispytest)
@@ -90,6 +89,7 @@ class Testdir:
return self._pytester.chdir()
def finalize(self) -> None:
"""See :meth:`Pytester._finalize`."""
return self._pytester._finalize()
def makefile(self, ext, *args, **kwargs) -> LEGACY_PATH:
@@ -144,7 +144,7 @@ class Testdir:
"""See :meth:`Pytester.copy_example`."""
return legacy_path(self._pytester.copy_example(name))
def getnode(self, config: Config, arg) -> Item | Collector | None:
def getnode(self, config: Config, arg) -> Optional[Union[Item, Collector]]:
"""See :meth:`Pytester.getnode`."""
return self._pytester.getnode(config, arg)
@@ -152,7 +152,7 @@ class Testdir:
"""See :meth:`Pytester.getpathnode`."""
return self._pytester.getpathnode(path)
def genitems(self, colitems: list[Item | Collector]) -> list[Item]:
def genitems(self, colitems: List[Union[Item, Collector]]) -> List[Item]:
"""See :meth:`Pytester.genitems`."""
return self._pytester.genitems(colitems)
@@ -204,7 +204,9 @@ class Testdir:
source, configargs=configargs, withinit=withinit
)
def collect_by_name(self, modcol: Collector, name: str) -> Item | Collector | None:
def collect_by_name(
self, modcol: Collector, name: str
) -> Optional[Union[Item, Collector]]:
"""See :meth:`Pytester.collect_by_name`."""
return self._pytester.collect_by_name(modcol, name)
@@ -235,11 +237,13 @@ class Testdir:
"""See :meth:`Pytester.runpytest_subprocess`."""
return self._pytester.runpytest_subprocess(*args, timeout=timeout)
def spawn_pytest(self, string: str, expect_timeout: float = 10.0) -> pexpect.spawn:
def spawn_pytest(
self, string: str, expect_timeout: float = 10.0
) -> "pexpect.spawn":
"""See :meth:`Pytester.spawn_pytest`."""
return self._pytester.spawn_pytest(string, expect_timeout=expect_timeout)
def spawn(self, cmd: str, expect_timeout: float = 10.0) -> pexpect.spawn:
def spawn(self, cmd: str, expect_timeout: float = 10.0) -> "pexpect.spawn":
"""See :meth:`Pytester.spawn`."""
return self._pytester.spawn(cmd, expect_timeout=expect_timeout)
@@ -266,7 +270,7 @@ class LegacyTestdirPlugin:
@final
@dataclasses.dataclass
class TempdirFactory:
"""Backward compatibility wrapper that implements ``py.path.local``
"""Backward compatibility wrapper that implements :class:`py.path.local`
for :class:`TempPathFactory`.
.. note::
@@ -285,11 +289,11 @@ class TempdirFactory:
self._tmppath_factory = tmppath_factory
def mktemp(self, basename: str, numbered: bool = True) -> LEGACY_PATH:
"""Same as :meth:`TempPathFactory.mktemp`, but returns a ``py.path.local`` object."""
"""Same as :meth:`TempPathFactory.mktemp`, but returns a :class:`py.path.local` object."""
return legacy_path(self._tmppath_factory.mktemp(basename, numbered).resolve())
def getbasetemp(self) -> LEGACY_PATH:
"""Same as :meth:`TempPathFactory.getbasetemp`, but returns a ``py.path.local`` object."""
"""Same as :meth:`TempPathFactory.getbasetemp`, but returns a :class:`py.path.local` object."""
return legacy_path(self._tmppath_factory.getbasetemp().resolve())
@@ -304,11 +308,16 @@ class LegacyTmpdirPlugin:
@staticmethod
@fixture
def tmpdir(tmp_path: Path) -> LEGACY_PATH:
"""Return a temporary directory (as `legacy_path`_ object)
which is unique to each test function invocation.
The temporary directory is created as a subdirectory
of the base temporary directory, with configurable retention,
as discussed in :ref:`temporary directory location and retention`.
"""Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
By default, a new base temporary directory is created each test session,
and old bases are removed after 3 sessions, to aid in debugging. If
``--basetemp`` is used then it is cleared each session. See :ref:`base
temporary directory`.
The returned object is a `legacy_path`_ object.
.. note::
These days, it is preferred to use ``tmp_path``.
@@ -364,7 +373,7 @@ def Config_rootdir(self: Config) -> LEGACY_PATH:
return legacy_path(str(self.rootpath))
def Config_inifile(self: Config) -> LEGACY_PATH | None:
def Config_inifile(self: Config) -> Optional[LEGACY_PATH]:
"""The path to the :ref:`configfile <configfiles>`.
Prefer to use :attr:`inipath`, which is a :class:`pathlib.Path`.
@@ -374,7 +383,7 @@ def Config_inifile(self: Config) -> LEGACY_PATH | None:
return legacy_path(str(self.inipath)) if self.inipath else None
def Session_startdir(self: Session) -> LEGACY_PATH:
def Session_stardir(self: Session) -> LEGACY_PATH:
"""The path from which pytest was invoked.
Prefer to use ``startpath`` which is a :class:`pathlib.Path`.
@@ -384,7 +393,9 @@ def Session_startdir(self: Session) -> LEGACY_PATH:
return legacy_path(self.startpath)
def Config__getini_unknown_type(self, name: str, type: str, value: str | list[str]):
def Config__getini_unknown_type(
self, name: str, type: str, value: Union[str, List[str]]
):
if type == "pathlist":
# TODO: This assert is probably not valid in all cases.
assert self.inipath is not None
@@ -427,7 +438,7 @@ def pytest_load_initial_conftests(early_config: Config) -> None:
mp.setattr(Config, "inifile", property(Config_inifile), raising=False)
# Add Session.startdir property.
mp.setattr(Session, "startdir", property(Session_startdir), raising=False)
mp.setattr(Session, "startdir", property(Session_stardir), raising=False)
# Add pathlist configuration type.
mp.setattr(Config, "_getini_unknown_type", Config__getini_unknown_type)