[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-04-13 00:00:18 +00:00
parent 72ad6dc953
commit f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions

View file

@ -1,16 +1,23 @@
# mypy: allow-untyped-defs
from __future__ import annotations
import atexit
import contextlib
import fnmatch
import importlib.util
import itertools
import os
import shutil
import sys
import types
import uuid
import warnings
from enum import Enum
from errno import EBADF
from errno import ELOOP
from errno import ENOENT
from errno import ENOTDIR
import fnmatch
from functools import partial
import importlib.util
import itertools
import os
from os.path import expanduser
from os.path import expandvars
from os.path import isabs
@ -18,9 +25,6 @@ from os.path import sep
from pathlib import Path
from pathlib import PurePath
from posixpath import sep as posix_sep
import shutil
import sys
import types
from types import ModuleType
from typing import Callable
from typing import Dict
@ -33,8 +37,6 @@ from typing import Tuple
from typing import Type
from typing import TypeVar
from typing import Union
import uuid
import warnings
from _pytest.compat import assert_never
from _pytest.outcomes import skip
@ -44,7 +46,7 @@ from _pytest.warning_types import PytestWarning
LOCK_TIMEOUT = 60 * 60 * 24 * 3
_AnyPurePath = TypeVar("_AnyPurePath", bound=PurePath)
_AnyPurePath = TypeVar('_AnyPurePath', bound=PurePath)
# The following function, variables and comments were
# copied from cpython 3.9 Lib/pathlib.py file.
@ -60,22 +62,22 @@ _IGNORED_WINERRORS = (
def _ignore_error(exception):
return (
getattr(exception, "errno", None) in _IGNORED_ERRORS
or getattr(exception, "winerror", None) in _IGNORED_WINERRORS
getattr(exception, 'errno', None) in _IGNORED_ERRORS or
getattr(exception, 'winerror', None) in _IGNORED_WINERRORS
)
def get_lock_path(path: _AnyPurePath) -> _AnyPurePath:
return path.joinpath(".lock")
return path.joinpath('.lock')
def on_rm_rf_error(
func,
path: str,
excinfo: Union[
BaseException,
Tuple[Type[BaseException], BaseException, Optional[types.TracebackType]],
],
excinfo: (
BaseException |
tuple[type[BaseException], BaseException, types.TracebackType | None]
),
*,
start_path: Path,
) -> bool:
@ -95,7 +97,7 @@ def on_rm_rf_error(
if not isinstance(exc, PermissionError):
warnings.warn(
PytestWarning(f"(rm_rf) error removing {path}\n{type(exc)}: {exc}")
PytestWarning(f'(rm_rf) error removing {path}\n{type(exc)}: {exc}'),
)
return False
@ -103,8 +105,8 @@ def on_rm_rf_error(
if func not in (os.open,):
warnings.warn(
PytestWarning(
f"(rm_rf) unknown function {func} when removing {path}:\n{type(exc)}: {exc}"
)
f'(rm_rf) unknown function {func} when removing {path}:\n{type(exc)}: {exc}',
),
)
return False
@ -142,7 +144,7 @@ def ensure_extended_length_path(path: Path) -> Path:
On Windows, this function returns the extended-length absolute version of path.
On other platforms it returns path unchanged.
"""
if sys.platform.startswith("win32"):
if sys.platform.startswith('win32'):
path = path.resolve()
path = Path(get_extended_length_path_str(str(path)))
return path
@ -150,12 +152,12 @@ def ensure_extended_length_path(path: Path) -> Path:
def get_extended_length_path_str(path: str) -> str:
"""Convert a path to a Windows extended length path."""
long_path_prefix = "\\\\?\\"
unc_long_path_prefix = "\\\\?\\UNC\\"
long_path_prefix = '\\\\?\\'
unc_long_path_prefix = '\\\\?\\UNC\\'
if path.startswith((long_path_prefix, unc_long_path_prefix)):
return path
# UNC
if path.startswith("\\\\"):
if path.startswith('\\\\'):
return unc_long_path_prefix + path[2:]
return long_path_prefix + path
@ -171,7 +173,7 @@ def rm_rf(path: Path) -> None:
shutil.rmtree(str(path), onerror=onerror)
def find_prefixed(root: Path, prefix: str) -> Iterator["os.DirEntry[str]"]:
def find_prefixed(root: Path, prefix: str) -> Iterator[os.DirEntry[str]]:
"""Find all elements in root that begin with the prefix, case insensitive."""
l_prefix = prefix.lower()
for x in os.scandir(root):
@ -179,7 +181,7 @@ def find_prefixed(root: Path, prefix: str) -> Iterator["os.DirEntry[str]"]:
yield x
def extract_suffixes(iter: Iterable["os.DirEntry[str]"], prefix: str) -> Iterator[str]:
def extract_suffixes(iter: Iterable[os.DirEntry[str]], prefix: str) -> Iterator[str]:
"""Return the parts of the paths following the prefix.
:param iter: Iterator over path names.
@ -204,7 +206,7 @@ def parse_num(maybe_num) -> int:
def _force_symlink(
root: Path, target: Union[str, PurePath], link_to: Union[str, Path]
root: Path, target: str | PurePath, link_to: str | Path,
) -> None:
"""Helper to create the current symlink.
@ -231,18 +233,18 @@ def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:
# try up to 10 times to create the folder
max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1)
new_number = max_existing + 1
new_path = root.joinpath(f"{prefix}{new_number}")
new_path = root.joinpath(f'{prefix}{new_number}')
try:
new_path.mkdir(mode=mode)
except Exception:
pass
else:
_force_symlink(root, prefix + "current", new_path)
_force_symlink(root, prefix + 'current', new_path)
return new_path
else:
raise OSError(
"could not create numbered dir with prefix "
f"{prefix} in {root} after 10 tries"
'could not create numbered dir with prefix '
f'{prefix} in {root} after 10 tries',
)
@ -252,14 +254,14 @@ def create_cleanup_lock(p: Path) -> Path:
try:
fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
except FileExistsError as e:
raise OSError(f"cannot create lockfile in {p}") from e
raise OSError(f'cannot create lockfile in {p}') from e
else:
pid = os.getpid()
spid = str(pid).encode()
os.write(fd, spid)
os.close(fd)
if not lock_path.is_file():
raise OSError("lock path got renamed after successful creation")
raise OSError('lock path got renamed after successful creation')
return lock_path
@ -289,7 +291,7 @@ def maybe_delete_a_numbered_dir(path: Path) -> None:
lock_path = create_cleanup_lock(path)
parent = path.parent
garbage = parent.joinpath(f"garbage-{uuid.uuid4()}")
garbage = parent.joinpath(f'garbage-{uuid.uuid4()}')
path.rename(garbage)
rm_rf(garbage)
except OSError:
@ -362,14 +364,14 @@ def cleanup_dead_symlinks(root: Path):
def cleanup_numbered_dir(
root: Path, prefix: str, keep: int, consider_lock_dead_if_created_before: float
root: Path, prefix: str, keep: int, consider_lock_dead_if_created_before: float,
) -> None:
"""Cleanup for lock driven numbered directories."""
if not root.exists():
return
for path in cleanup_candidates(root, prefix, keep):
try_cleanup(path, consider_lock_dead_if_created_before)
for path in root.glob("garbage-*"):
for path in root.glob('garbage-*'):
try_cleanup(path, consider_lock_dead_if_created_before)
cleanup_dead_symlinks(root)
@ -417,7 +419,7 @@ def resolve_from_str(input: str, rootpath: Path) -> Path:
return rootpath.joinpath(input)
def fnmatch_ex(pattern: str, path: Union[str, "os.PathLike[str]"]) -> bool:
def fnmatch_ex(pattern: str, path: str | os.PathLike[str]) -> bool:
"""A port of FNMatcher from py.path.common which works with PurePath() instances.
The difference between this algorithm and PurePath.match() is that the
@ -436,7 +438,7 @@ def fnmatch_ex(pattern: str, path: Union[str, "os.PathLike[str]"]) -> bool:
* https://bugs.python.org/issue34731
"""
path = PurePath(path)
iswin32 = sys.platform.startswith("win")
iswin32 = sys.platform.startswith('win')
if iswin32 and sep not in pattern and posix_sep in pattern:
# Running on Windows, the pattern has no Windows path separators,
@ -449,11 +451,11 @@ def fnmatch_ex(pattern: str, path: Union[str, "os.PathLike[str]"]) -> bool:
else:
name = str(path)
if path.is_absolute() and not os.path.isabs(pattern):
pattern = f"*{os.sep}{pattern}"
pattern = f'*{os.sep}{pattern}'
return fnmatch.fnmatch(name, pattern)
def parts(s: str) -> Set[str]:
def parts(s: str) -> set[str]:
parts = s.split(sep)
return {sep.join(parts[: i + 1]) or sep for i in range(len(parts))}
@ -463,15 +465,15 @@ def symlink_or_skip(src, dst, **kwargs):
try:
os.symlink(str(src), str(dst), **kwargs)
except OSError as e:
skip(f"symlinks not supported: {e}")
skip(f'symlinks not supported: {e}')
class ImportMode(Enum):
"""Possible values for `mode` parameter of `import_path`."""
prepend = "prepend"
append = "append"
importlib = "importlib"
prepend = 'prepend'
append = 'append'
importlib = 'importlib'
class ImportPathMismatchError(ImportError):
@ -484,9 +486,9 @@ class ImportPathMismatchError(ImportError):
def import_path(
path: Union[str, "os.PathLike[str]"],
path: str | os.PathLike[str],
*,
mode: Union[str, ImportMode] = ImportMode.prepend,
mode: str | ImportMode = ImportMode.prepend,
root: Path,
consider_namespace_packages: bool,
) -> ModuleType:
@ -534,7 +536,7 @@ def import_path(
# without touching sys.path.
try:
pkg_root, module_name = resolve_pkg_root_and_module_name(
path, consider_namespace_packages=consider_namespace_packages
path, consider_namespace_packages=consider_namespace_packages,
)
except CouldNotResolvePathError:
pass
@ -544,7 +546,7 @@ def import_path(
return sys.modules[module_name]
mod = _import_module_using_spec(
module_name, path, pkg_root, insert_modules=False
module_name, path, pkg_root, insert_modules=False,
)
if mod is not None:
return mod
@ -556,7 +558,7 @@ def import_path(
return sys.modules[module_name]
mod = _import_module_using_spec(
module_name, path, path.parent, insert_modules=True
module_name, path, path.parent, insert_modules=True,
)
if mod is None:
raise ImportError(f"Can't find module {module_name} at location {path}")
@ -564,7 +566,7 @@ def import_path(
try:
pkg_root, module_name = resolve_pkg_root_and_module_name(
path, consider_namespace_packages=consider_namespace_packages
path, consider_namespace_packages=consider_namespace_packages,
)
except CouldNotResolvePathError:
pkg_root, module_name = path.parent, path.stem
@ -584,19 +586,19 @@ def import_path(
importlib.import_module(module_name)
mod = sys.modules[module_name]
if path.name == "__init__.py":
if path.name == '__init__.py':
return mod
ignore = os.environ.get("PY_IGNORE_IMPORTMISMATCH", "")
if ignore != "1":
ignore = os.environ.get('PY_IGNORE_IMPORTMISMATCH', '')
if ignore != '1':
module_file = mod.__file__
if module_file is None:
raise ImportPathMismatchError(module_name, module_file, path)
if module_file.endswith((".pyc", ".pyo")):
if module_file.endswith(('.pyc', '.pyo')):
module_file = module_file[:-1]
if module_file.endswith(os.sep + "__init__.py"):
module_file = module_file[: -(len(os.sep + "__init__.py"))]
if module_file.endswith(os.sep + '__init__.py'):
module_file = module_file[: -(len(os.sep + '__init__.py'))]
try:
is_same = _is_same(str(path), module_file)
@ -610,8 +612,8 @@ def import_path(
def _import_module_using_spec(
module_name: str, module_path: Path, module_location: Path, *, insert_modules: bool
) -> Optional[ModuleType]:
module_name: str, module_path: Path, module_location: Path, *, insert_modules: bool,
) -> ModuleType | None:
"""
Tries to import a module by its canonical name, path to the .py file, and its
parent location.
@ -645,7 +647,7 @@ def _import_module_using_spec(
# Implement a special _is_same function on Windows which returns True if the two filenames
# compare equal, to circumvent os.path.samefile returning False for mounts in UNC (#7678).
if sys.platform.startswith("win"):
if sys.platform.startswith('win'):
def _is_same(f1: str, f2: str) -> bool:
return Path(f1) == Path(f2) or os.path.samefile(f1, f2)
@ -663,7 +665,7 @@ def module_name_from_path(path: Path, root: Path) -> str:
For example: path="projects/src/tests/test_foo.py" and root="/projects", the
resulting module name will be "src.tests.test_foo".
"""
path = path.with_suffix("")
path = path.with_suffix('')
try:
relative_path = path.relative_to(root)
except ValueError:
@ -676,18 +678,18 @@ def module_name_from_path(path: Path, root: Path) -> str:
# Module name for packages do not contain the __init__ file, unless
# the `__init__.py` file is at the root.
if len(path_parts) >= 2 and path_parts[-1] == "__init__":
if len(path_parts) >= 2 and path_parts[-1] == '__init__':
path_parts = path_parts[:-1]
# Module names cannot contain ".", normalize them to "_". This prevents
# a directory having a "." in the name (".env.310" for example) causing extra intermediate modules.
# Also, important to replace "." at the start of paths, as those are considered relative imports.
path_parts = tuple(x.replace(".", "_") for x in path_parts)
path_parts = tuple(x.replace('.', '_') for x in path_parts)
return ".".join(path_parts)
return '.'.join(path_parts)
def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> None:
def insert_missing_modules(modules: dict[str, ModuleType], module_name: str) -> None:
"""
Used by ``import_path`` to create intermediate modules when using mode=importlib.
@ -695,10 +697,10 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
to create empty modules "src" and "src.tests" after inserting "src.tests.test_foo",
otherwise "src.tests.test_foo" is not importable by ``__import__``.
"""
module_parts = module_name.split(".")
child_module: Union[ModuleType, None] = None
module: Union[ModuleType, None] = None
child_name: str = ""
module_parts = module_name.split('.')
child_module: ModuleType | None = None
module: ModuleType | None = None
child_name: str = ''
while module_name:
if module_name not in modules:
try:
@ -723,12 +725,12 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
setattr(module, child_name, child_module)
modules[module_name] = module
# Keep track of the child module while moving up the tree.
child_module, child_name = module, module_name.rpartition(".")[-1]
child_module, child_name = module, module_name.rpartition('.')[-1]
module_parts.pop(-1)
module_name = ".".join(module_parts)
module_name = '.'.join(module_parts)
def resolve_package_path(path: Path) -> Optional[Path]:
def resolve_package_path(path: Path) -> Path | None:
"""Return the Python package path by looking for the last
directory upwards which still contains an __init__.py.
@ -737,7 +739,7 @@ def resolve_package_path(path: Path) -> Optional[Path]:
result = None
for parent in itertools.chain((path,), path.parents):
if parent.is_dir():
if not (parent / "__init__.py").is_file():
if not (parent / '__init__.py').is_file():
break
if not parent.name.isidentifier():
break
@ -746,8 +748,8 @@ def resolve_package_path(path: Path) -> Optional[Path]:
def resolve_pkg_root_and_module_name(
path: Path, *, consider_namespace_packages: bool = False
) -> Tuple[Path, str]:
path: Path, *, consider_namespace_packages: bool = False,
) -> tuple[Path, str]:
"""
Return the path to the directory of the root package that contains the
given Python file, and its module name:
@ -779,20 +781,20 @@ def resolve_pkg_root_and_module_name(
for parent in pkg_root.parents:
# If any of the parent paths has a __init__.py, it means it is not
# a namespace package (see the docs linked above).
if (parent / "__init__.py").is_file():
if (parent / '__init__.py').is_file():
break
if str(parent) in sys.path:
# Point the pkg_root to the root of the namespace package.
pkg_root = parent
break
names = list(path.with_suffix("").relative_to(pkg_root).parts)
if names[-1] == "__init__":
names = list(path.with_suffix('').relative_to(pkg_root).parts)
if names[-1] == '__init__':
names.pop()
module_name = ".".join(names)
module_name = '.'.join(names)
return pkg_root, module_name
raise CouldNotResolvePathError(f"Could not resolve for {path}")
raise CouldNotResolvePathError(f'Could not resolve for {path}')
class CouldNotResolvePathError(Exception):
@ -800,9 +802,9 @@ class CouldNotResolvePathError(Exception):
def scandir(
path: Union[str, "os.PathLike[str]"],
sort_key: Callable[["os.DirEntry[str]"], object] = lambda entry: entry.name,
) -> List["os.DirEntry[str]"]:
path: str | os.PathLike[str],
sort_key: Callable[[os.DirEntry[str]], object] = lambda entry: entry.name,
) -> list[os.DirEntry[str]]:
"""Scan a directory recursively, in breadth-first order.
The returned entries are sorted according to the given key.
@ -825,8 +827,8 @@ def scandir(
def visit(
path: Union[str, "os.PathLike[str]"], recurse: Callable[["os.DirEntry[str]"], bool]
) -> Iterator["os.DirEntry[str]"]:
path: str | os.PathLike[str], recurse: Callable[[os.DirEntry[str]], bool],
) -> Iterator[os.DirEntry[str]]:
"""Walk a directory recursively, in breadth-first order.
The `recurse` predicate determines whether a directory is recursed.
@ -840,7 +842,7 @@ def visit(
yield from visit(entry.path, recurse)
def absolutepath(path: Union[Path, str]) -> Path:
def absolutepath(path: Path | str) -> Path:
"""Convert a path to an absolute path using os.path.abspath.
Prefer this over Path.resolve() (see #6523).
@ -849,7 +851,7 @@ def absolutepath(path: Union[Path, str]) -> Path:
return Path(os.path.abspath(str(path)))
def commonpath(path1: Path, path2: Path) -> Optional[Path]:
def commonpath(path1: Path, path2: Path) -> Path | None:
"""Return the common part shared with the other path, or None if there is
no common part.