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,15 +1,13 @@
"""create errno-specific classes for IO or os calls."""
from __future__ import annotations
from collections.abc import Callable
import errno
import os
import sys
from typing import Callable
from typing import TYPE_CHECKING
from typing import TypeVar
if TYPE_CHECKING:
from typing_extensions import ParamSpec
@@ -41,7 +39,7 @@ _winerrnomap = {
3: errno.ENOENT,
17: errno.EEXIST,
18: errno.EXDEV,
13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailable
13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailiable
22: errno.ENOTDIR,
20: errno.ENOTDIR,
267: errno.ENOTDIR,
@@ -69,7 +67,7 @@ class ErrorMaker:
try:
return self._errno2class[eno]
except KeyError:
clsname = errno.errorcode.get(eno, f"UnknownErrno{eno}")
clsname = errno.errorcode.get(eno, "UnknownErrno%d" % (eno,))
errorcls = type(
clsname,
(Error,),
@@ -90,23 +88,15 @@ class ErrorMaker:
except OSError as value:
if not hasattr(value, "errno"):
raise
errno = value.errno
if sys.platform == "win32":
try:
# error: Invalid index type "Optional[int]" for "dict[int, int]"; expected type "int" [index]
# OK to ignore because we catch the KeyError below.
cls = self._geterrnoclass(_winerrnomap[value.errno]) # type:ignore[index]
cls = self._geterrnoclass(_winerrnomap[errno])
except KeyError:
raise value
else:
# we are not on Windows, or we got a proper OSError
if value.errno is None:
cls = type(
"UnknownErrnoNone",
(Error,),
{"__module__": "py.error", "__doc__": None},
)
else:
cls = self._geterrnoclass(value.errno)
cls = self._geterrnoclass(errno)
raise cls(f"{func.__name__}{args!r}")

View File

@@ -1,15 +1,16 @@
# mypy: allow-untyped-defs
"""local path implementation."""
from __future__ import annotations
import atexit
from collections.abc import Callable
from contextlib import contextmanager
import fnmatch
import importlib.util
import io
import os
import posixpath
import sys
import uuid
import warnings
from contextlib import contextmanager
from os.path import abspath
from os.path import dirname
from os.path import exists
@@ -18,21 +19,19 @@ from os.path import isdir
from os.path import isfile
from os.path import islink
from os.path import normpath
import posixpath
from stat import S_ISDIR
from stat import S_ISLNK
from stat import S_ISREG
import sys
from typing import Any
from typing import Callable
from typing import cast
from typing import Literal
from typing import overload
from typing import TYPE_CHECKING
import uuid
import warnings
from . import error
if TYPE_CHECKING:
from typing import Literal
# Moved from local.py.
iswin32 = sys.platform == "win32" or (getattr(os, "_name", False) == "nt")
@@ -161,13 +160,15 @@ class Visitor:
)
if not self.breadthfirst:
for subdir in dirs:
yield from self.gen(subdir)
for p in self.gen(subdir):
yield p
for p in self.optsort(entries):
if self.fil is None or self.fil(p):
yield p
if self.breadthfirst:
for subdir in dirs:
yield from self.gen(subdir)
for p in self.gen(subdir):
yield p
class FNMatcher:
@@ -204,10 +205,12 @@ class Stat:
if TYPE_CHECKING:
@property
def size(self) -> int: ...
def size(self) -> int:
...
@property
def mtime(self) -> float: ...
def mtime(self) -> float:
...
def __getattr__(self, name: str) -> Any:
return getattr(self._osstatresult, "st_" + name)
@@ -222,7 +225,7 @@ class Stat:
raise NotImplementedError("XXX win32")
import pwd
entry = error.checked_call(pwd.getpwuid, self.uid) # type:ignore[attr-defined,unused-ignore]
entry = error.checked_call(pwd.getpwuid, self.uid) # type:ignore[attr-defined]
return entry[0]
@property
@@ -232,7 +235,7 @@ class Stat:
raise NotImplementedError("XXX win32")
import grp
entry = error.checked_call(grp.getgrgid, self.gid) # type:ignore[attr-defined,unused-ignore]
entry = error.checked_call(grp.getgrgid, self.gid) # type:ignore[attr-defined]
return entry[0]
def isdir(self):
@@ -250,7 +253,7 @@ def getuserid(user):
import pwd
if not isinstance(user, int):
user = pwd.getpwnam(user)[2] # type:ignore[attr-defined,unused-ignore]
user = pwd.getpwnam(user)[2] # type:ignore[attr-defined]
return user
@@ -258,7 +261,7 @@ def getgroupid(group):
import grp
if not isinstance(group, int):
group = grp.getgrnam(group)[2] # type:ignore[attr-defined,unused-ignore]
group = grp.getgrnam(group)[2] # type:ignore[attr-defined]
return group
@@ -315,7 +318,7 @@ class LocalPath:
def readlink(self) -> str:
"""Return value of a symbolic link."""
# https://github.com/python/mypy/issues/12278
return error.checked_call(os.readlink, self.strpath) # type: ignore[arg-type,return-value,unused-ignore]
return error.checked_call(os.readlink, self.strpath) # type: ignore[arg-type,return-value]
def mklinkto(self, oldname):
"""Posix style hard link to another name."""
@@ -432,7 +435,7 @@ class LocalPath:
"""Return a string which is the relative part of the path
to the given 'relpath'.
"""
if not isinstance(relpath, str | LocalPath):
if not isinstance(relpath, (str, LocalPath)):
raise TypeError(f"{relpath!r}: not a string or path object")
strrelpath = str(relpath)
if strrelpath and strrelpath[-1] != self.sep:
@@ -449,7 +452,7 @@ class LocalPath:
def ensure_dir(self, *args):
"""Ensure the path joined with args is a directory."""
return self.ensure(*args, dir=True)
return self.ensure(*args, **{"dir": True})
def bestrelpath(self, dest):
"""Return a string which is a relative path from self
@@ -652,12 +655,12 @@ class LocalPath:
if not kw:
obj.strpath = self.strpath
return obj
drive, dirname, _basename, purebasename, ext = self._getbyspec(
drive, dirname, basename, purebasename, ext = self._getbyspec(
"drive,dirname,basename,purebasename,ext"
)
if "basename" in kw:
if "purebasename" in kw or "ext" in kw:
raise ValueError(f"invalid specification {kw!r}")
raise ValueError("invalid specification %r" % kw)
else:
pb = kw.setdefault("purebasename", purebasename)
try:
@@ -674,7 +677,7 @@ class LocalPath:
else:
kw.setdefault("dirname", dirname)
kw.setdefault("sep", self.sep)
obj.strpath = normpath("{dirname}{sep}{basename}".format(**kw))
obj.strpath = normpath("%(dirname)s%(sep)s%(basename)s" % kw)
return obj
def _getbyspec(self, spec: str) -> list[str]:
@@ -703,7 +706,7 @@ class LocalPath:
elif name == "ext":
res.append(ext)
else:
raise ValueError(f"invalid part specification {name!r}")
raise ValueError("invalid part specification %r" % name)
return res
def dirpath(self, *args, **kwargs):
@@ -754,12 +757,7 @@ class LocalPath:
if ensure:
self.dirpath().ensure(dir=1)
if encoding:
return error.checked_call(
io.open,
self.strpath,
mode,
encoding=encoding,
)
return error.checked_call(io.open, self.strpath, mode, encoding=encoding)
return error.checked_call(open, self.strpath, mode)
def _fastjoin(self, name):
@@ -777,11 +775,11 @@ class LocalPath:
valid checkers::
file = 1 # is a file
file = 0 # is not a file (may not even exist)
dir = 1 # is a dir
link = 1 # is a link
exists = 1 # exists
file=1 # is a file
file=0 # is not a file (may not even exist)
dir=1 # is a dir
link=1 # is a link
exists=1 # exists
You can specify multiple checker definitions, for example::
@@ -834,7 +832,7 @@ class LocalPath:
def copy(self, target, mode=False, stat=False):
"""Copy path to target.
If mode is True, will copy permission from path to target.
If mode is True, will copy copy permission from path to target.
If stat is True, copy permission, last modification
time, last access time, and flags from path to target.
"""
@@ -959,10 +957,12 @@ class LocalPath:
return p
@overload
def stat(self, raising: Literal[True] = ...) -> Stat: ...
def stat(self, raising: Literal[True] = ...) -> Stat:
...
@overload
def stat(self, raising: Literal[False]) -> Stat | None: ...
def stat(self, raising: Literal[False]) -> Stat | None:
...
def stat(self, raising: bool = True) -> Stat | None:
"""Return an os.stat() tuple."""
@@ -1024,7 +1024,7 @@ class LocalPath:
return self.stat().atime
def __repr__(self):
return f"local({self.strpath!r})"
return "local(%r)" % self.strpath
def __str__(self):
"""Return string representation of the Path."""
@@ -1045,7 +1045,7 @@ class LocalPath:
def pypkgpath(self):
"""Return the Python package path by looking for the last
directory upwards which still contains an __init__.py.
Return None if a pkgpath cannot be determined.
Return None if a pkgpath can not be determined.
"""
pkgpath = None
for parent in self.parts(reverse=True):
@@ -1096,7 +1096,9 @@ class LocalPath:
modname = self.purebasename
spec = importlib.util.spec_from_file_location(modname, str(self))
if spec is None or spec.loader is None:
raise ImportError(f"Can't find module {modname} at location {self!s}")
raise ImportError(
f"Can't find module {modname} at location {str(self)}"
)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
@@ -1161,8 +1163,7 @@ class LocalPath:
where the 'self' path points to executable.
The process is directly invoked and not through a system shell.
"""
from subprocess import PIPE
from subprocess import Popen
from subprocess import Popen, PIPE
popen_opts.pop("stdout", None)
popen_opts.pop("stderr", None)
@@ -1262,14 +1263,13 @@ class LocalPath:
@classmethod
def mkdtemp(cls, rootdir=None):
"""Return a Path object pointing to a fresh new temporary directory
(which we created ourselves).
(which we created ourself).
"""
import tempfile
if rootdir is None:
rootdir = cls.get_temproot()
path = error.checked_call(tempfile.mkdtemp, dir=str(rootdir))
return cls(path)
return cls(error.checked_call(tempfile.mkdtemp, dir=str(rootdir)))
@classmethod
def make_numbered_dir(