diff --git a/doc/en/how-to/failures.rst b/doc/en/how-to/failures.rst index ef8755091..b3d0c155b 100644 --- a/doc/en/how-to/failures.rst +++ b/doc/en/how-to/failures.rst @@ -135,10 +135,6 @@ Warning about unraisable exceptions and unhandled thread exceptions .. versionadded:: 6.2 -.. note:: - - These features only work on Python>=3.8. - Unhandled exceptions are exceptions that are raised in a situation in which they cannot propagate to a caller. The most common case is an exception raised in a :meth:`__del__ ` implementation. diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 58483d2a0..42c5fa8bd 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -393,11 +393,11 @@ class Traceback(List[TracebackEntry]): def filter( self, - # TODO(py38): change to positional only. - _excinfo_or_fn: Union[ + excinfo_or_fn: Union[ "ExceptionInfo[BaseException]", Callable[[TracebackEntry], bool], ], + /, ) -> "Traceback": """Return a Traceback instance with certain items removed. @@ -408,10 +408,10 @@ class Traceback(List[TracebackEntry]): ``TracebackEntry`` instance, and should return True when the item should be added to the ``Traceback``, False when not. """ - if isinstance(_excinfo_or_fn, ExceptionInfo): - fn = lambda x: not x.ishidden(_excinfo_or_fn) # noqa: E731 + if isinstance(excinfo_or_fn, ExceptionInfo): + fn = lambda x: not x.ishidden(excinfo_or_fn) # noqa: E731 else: - fn = _excinfo_or_fn + fn = excinfo_or_fn return Traceback(filter(fn, self)) def recursionindex(self) -> Optional[int]: diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 14fb2e3ae..138a0bdb2 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -769,21 +769,3 @@ def bestrelpath(directory: Path, dest: Path) -> str: # Forward from base to dest. *reldest.parts, ) - - -# Originates from py. path.local.copy(), with siginficant trims and adjustments. -# TODO(py38): Replace with shutil.copytree(..., symlinks=True, dirs_exist_ok=True) -def copytree(source: Path, target: Path) -> None: - """Recursively copy a source directory to target.""" - assert source.is_dir() - for entry in visit(source, recurse=lambda entry: not entry.is_symlink()): - x = Path(entry) - relpath = x.relative_to(source) - newx = target / relpath - newx.parent.mkdir(exist_ok=True) - if x.is_symlink(): - newx.symlink_to(os.readlink(x)) - elif x.is_file(): - shutil.copyfile(x, newx) - elif x.is_dir(): - newx.mkdir(exist_ok=True) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 0129c224f..d8dd3b9de 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -63,7 +63,6 @@ from _pytest.outcomes import fail from _pytest.outcomes import importorskip from _pytest.outcomes import skip from _pytest.pathlib import bestrelpath -from _pytest.pathlib import copytree from _pytest.pathlib import make_numbered_dir from _pytest.reports import CollectReport from _pytest.reports import TestReport @@ -971,7 +970,7 @@ class Pytester: example_path = example_dir.joinpath(name) if example_path.is_dir() and not example_path.joinpath("__init__.py").is_file(): - copytree(example_path, self.path) + shutil.copytree(example_path, self.path, symlinks=True, dirs_exist_ok=True) return self.path elif example_path.is_file(): result = self.path.joinpath(example_path.name)