mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-08-21 05:43:16 -07:00
Update vendored windows libs
This commit is contained in:
parent
f61c211655
commit
b1cefa94e5
226 changed files with 33472 additions and 11882 deletions
1614
libs/win/path/__init__.py
Normal file
1614
libs/win/path/__init__.py
Normal file
File diff suppressed because it is too large
Load diff
483
libs/win/path/__init__.pyi
Normal file
483
libs/win/path/__init__.pyi
Normal file
|
@ -0,0 +1,483 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import builtins
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from io import (
|
||||
BufferedRandom,
|
||||
BufferedReader,
|
||||
BufferedWriter,
|
||||
FileIO,
|
||||
TextIOWrapper,
|
||||
)
|
||||
from types import ModuleType, TracebackType
|
||||
from typing import (
|
||||
Any,
|
||||
AnyStr,
|
||||
BinaryIO,
|
||||
Callable,
|
||||
Generator,
|
||||
Iterable,
|
||||
Iterator,
|
||||
IO,
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
Type,
|
||||
Union,
|
||||
overload,
|
||||
)
|
||||
|
||||
from _typeshed import (
|
||||
OpenBinaryMode,
|
||||
OpenBinaryModeUpdating,
|
||||
OpenBinaryModeReading,
|
||||
OpenBinaryModeWriting,
|
||||
OpenTextMode,
|
||||
Self,
|
||||
)
|
||||
from typing_extensions import Literal
|
||||
|
||||
from . import classes
|
||||
|
||||
# Type for the match argument for several methods
|
||||
_Match = Optional[Union[str, Callable[[str], bool], Callable[[Path], bool]]]
|
||||
|
||||
class TreeWalkWarning(Warning):
|
||||
pass
|
||||
|
||||
class Traversal:
|
||||
follow: Callable[[Path], bool]
|
||||
def __init__(self, follow: Callable[[Path], bool]): ...
|
||||
def __call__(
|
||||
self,
|
||||
walker: Generator[Path, Optional[Callable[[], bool]], None],
|
||||
) -> Iterator[Path]: ...
|
||||
|
||||
class Path(str):
|
||||
module: Any
|
||||
def __init__(self, other: Any = ...) -> None: ...
|
||||
@classmethod
|
||||
def using_module(cls, module: ModuleType) -> Type[Path]: ...
|
||||
@classes.ClassProperty
|
||||
@classmethod
|
||||
def _next_class(cls: Type[Self]) -> Type[Self]: ...
|
||||
def __repr__(self) -> str: ...
|
||||
def __add__(self: Self, more: str) -> Self: ...
|
||||
def __radd__(self: Self, other: str) -> Self: ...
|
||||
def __div__(self: Self, rel: str) -> Self: ...
|
||||
def __truediv__(self: Self, rel: str) -> Self: ...
|
||||
def __rdiv__(self: Self, rel: str) -> Self: ...
|
||||
def __rtruediv__(self: Self, rel: str) -> Self: ...
|
||||
def __enter__(self: Self) -> Self: ...
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[type[BaseException]],
|
||||
exc_val: Optional[BaseException],
|
||||
exc_tb: Optional[TracebackType],
|
||||
) -> None: ...
|
||||
@classmethod
|
||||
def getcwd(cls: Type[Self]) -> Self: ...
|
||||
def abspath(self: Self) -> Self: ...
|
||||
def normcase(self: Self) -> Self: ...
|
||||
def normpath(self: Self) -> Self: ...
|
||||
def realpath(self: Self) -> Self: ...
|
||||
def expanduser(self: Self) -> Self: ...
|
||||
def expandvars(self: Self) -> Self: ...
|
||||
def dirname(self: Self) -> Self: ...
|
||||
def basename(self: Self) -> Self: ...
|
||||
def expand(self: Self) -> Self: ...
|
||||
@property
|
||||
def stem(self) -> str: ...
|
||||
@property
|
||||
def ext(self) -> str: ...
|
||||
def with_suffix(self: Self, suffix: str) -> Self: ...
|
||||
@property
|
||||
def drive(self: Self) -> Self: ...
|
||||
@property
|
||||
def parent(self: Self) -> Self: ...
|
||||
@property
|
||||
def name(self: Self) -> Self: ...
|
||||
def splitpath(self: Self) -> Tuple[Self, str]: ...
|
||||
def splitdrive(self: Self) -> Tuple[Self, Self]: ...
|
||||
def splitext(self: Self) -> Tuple[Self, str]: ...
|
||||
def stripext(self: Self) -> Self: ...
|
||||
@classes.multimethod
|
||||
def joinpath(cls: Self, first: str, *others: str) -> Self: ...
|
||||
def splitall(self: Self) -> List[Union[Self, str]]: ...
|
||||
def parts(self: Self) -> Tuple[Union[Self, str], ...]: ...
|
||||
def _parts(self: Self) -> Iterator[Union[Self, str]]: ...
|
||||
def _parts_iter(self: Self) -> Iterator[Union[Self, str]]: ...
|
||||
def relpath(self: Self, start: str = ...) -> Self: ...
|
||||
def relpathto(self: Self, dest: str) -> Self: ...
|
||||
# --- Listing, searching, walking, and matching
|
||||
def listdir(self: Self, match: _Match = ...) -> List[Self]: ...
|
||||
def dirs(self: Self, match: _Match = ...) -> List[Self]: ...
|
||||
def files(self: Self, match: _Match = ...) -> List[Self]: ...
|
||||
def walk(
|
||||
self: Self,
|
||||
match: _Match = ...,
|
||||
errors: str = ...,
|
||||
) -> Generator[Self, Optional[Callable[[], bool]], None]: ...
|
||||
def walkdirs(
|
||||
self: Self,
|
||||
match: _Match = ...,
|
||||
errors: str = ...,
|
||||
) -> Iterator[Self]: ...
|
||||
def walkfiles(
|
||||
self: Self,
|
||||
match: _Match = ...,
|
||||
errors: str = ...,
|
||||
) -> Iterator[Self]: ...
|
||||
def fnmatch(
|
||||
self,
|
||||
pattern: Union[Path, str],
|
||||
normcase: Optional[Callable[[str], str]] = ...,
|
||||
) -> bool: ...
|
||||
def glob(self: Self, pattern: str) -> List[Self]: ...
|
||||
def iglob(self: Self, pattern: str) -> Iterator[Self]: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenTextMode = ...,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Optional[Callable[[str, int], int]] = ...,
|
||||
) -> TextIOWrapper: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenBinaryMode,
|
||||
buffering: Literal[0],
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> FileIO: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenBinaryModeUpdating,
|
||||
buffering: Literal[-1, 1] = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> BufferedRandom: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenBinaryModeReading,
|
||||
buffering: Literal[-1, 1] = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> BufferedReader: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenBinaryModeWriting,
|
||||
buffering: Literal[-1, 1] = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> BufferedWriter: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: OpenBinaryMode,
|
||||
buffering: int,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> BinaryIO: ...
|
||||
@overload
|
||||
def open(
|
||||
self,
|
||||
mode: str,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Callable[[str, int], int] = ...,
|
||||
) -> IO[Any]: ...
|
||||
def bytes(self) -> builtins.bytes: ...
|
||||
@overload
|
||||
def chunks(
|
||||
self,
|
||||
size: int,
|
||||
mode: OpenTextMode = ...,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Optional[Callable[[str, int], int]] = ...,
|
||||
) -> Iterator[str]: ...
|
||||
@overload
|
||||
def chunks(
|
||||
self,
|
||||
size: int,
|
||||
mode: OpenBinaryMode,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Optional[Callable[[str, int], int]] = ...,
|
||||
) -> Iterator[builtins.bytes]: ...
|
||||
@overload
|
||||
def chunks(
|
||||
self,
|
||||
size: int,
|
||||
mode: str,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
closefd: bool = ...,
|
||||
opener: Optional[Callable[[str, int], int]] = ...,
|
||||
) -> Iterator[Union[str, builtins.bytes]]: ...
|
||||
def write_bytes(self, bytes: builtins.bytes, append: bool = ...) -> None: ...
|
||||
def read_text(
|
||||
self, encoding: Optional[str] = ..., errors: Optional[str] = ...
|
||||
) -> str: ...
|
||||
def read_bytes(self) -> builtins.bytes: ...
|
||||
def text(self, encoding: Optional[str] = ..., errors: str = ...) -> str: ...
|
||||
@overload
|
||||
def write_text(
|
||||
self,
|
||||
text: str,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: str = ...,
|
||||
linesep: Optional[str] = ...,
|
||||
append: bool = ...,
|
||||
) -> None: ...
|
||||
@overload
|
||||
def write_text(
|
||||
self,
|
||||
text: builtins.bytes,
|
||||
encoding: None = ...,
|
||||
errors: str = ...,
|
||||
linesep: Optional[str] = ...,
|
||||
append: bool = ...,
|
||||
) -> None: ...
|
||||
def lines(
|
||||
self,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
retain: bool = ...,
|
||||
) -> List[str]: ...
|
||||
def write_lines(
|
||||
self,
|
||||
lines: List[str],
|
||||
encoding: Optional[str] = ...,
|
||||
errors: str = ...,
|
||||
linesep: Optional[str] = ...,
|
||||
append: bool = ...,
|
||||
) -> None: ...
|
||||
def read_md5(self) -> builtins.bytes: ...
|
||||
def read_hash(self, hash_name: str) -> builtins.bytes: ...
|
||||
def read_hexhash(self, hash_name: str) -> str: ...
|
||||
def isabs(self) -> bool: ...
|
||||
def exists(self) -> bool: ...
|
||||
def isdir(self) -> bool: ...
|
||||
def isfile(self) -> bool: ...
|
||||
def islink(self) -> bool: ...
|
||||
def ismount(self) -> bool: ...
|
||||
def samefile(self, other: str) -> bool: ...
|
||||
def getatime(self) -> float: ...
|
||||
@property
|
||||
def atime(self) -> float: ...
|
||||
def getmtime(self) -> float: ...
|
||||
@property
|
||||
def mtime(self) -> float: ...
|
||||
def getctime(self) -> float: ...
|
||||
@property
|
||||
def ctime(self) -> float: ...
|
||||
def getsize(self) -> int: ...
|
||||
@property
|
||||
def size(self) -> int: ...
|
||||
def access(
|
||||
self,
|
||||
mode: int,
|
||||
*,
|
||||
dir_fd: Optional[int] = ...,
|
||||
effective_ids: bool = ...,
|
||||
follow_symlinks: bool = ...,
|
||||
) -> bool: ...
|
||||
def stat(self) -> os.stat_result: ...
|
||||
def lstat(self) -> os.stat_result: ...
|
||||
def get_owner(self) -> str: ...
|
||||
@property
|
||||
def owner(self) -> str: ...
|
||||
if sys.platform != 'win32':
|
||||
def statvfs(self) -> os.statvfs_result: ...
|
||||
def pathconf(self, name: Union[str, int]) -> int: ...
|
||||
|
||||
def utime(
|
||||
self,
|
||||
times: Union[Tuple[int, int], Tuple[float, float], None] = ...,
|
||||
*,
|
||||
ns: Tuple[int, int] = ...,
|
||||
dir_fd: Optional[int] = ...,
|
||||
follow_symlinks: bool = ...,
|
||||
) -> Path: ...
|
||||
def chmod(self: Self, mode: Union[str, int]) -> Self: ...
|
||||
if sys.platform != 'win32':
|
||||
def chown(
|
||||
self: Self, uid: Union[int, str] = ..., gid: Union[int, str] = ...
|
||||
) -> Self: ...
|
||||
|
||||
def rename(self: Self, new: str) -> Self: ...
|
||||
def renames(self: Self, new: str) -> Self: ...
|
||||
def mkdir(self: Self, mode: int = ...) -> Self: ...
|
||||
def mkdir_p(self: Self, mode: int = ...) -> Self: ...
|
||||
def makedirs(self: Self, mode: int = ...) -> Self: ...
|
||||
def makedirs_p(self: Self, mode: int = ...) -> Self: ...
|
||||
def rmdir(self: Self) -> Self: ...
|
||||
def rmdir_p(self: Self) -> Self: ...
|
||||
def removedirs(self: Self) -> Self: ...
|
||||
def removedirs_p(self: Self) -> Self: ...
|
||||
def touch(self: Self) -> Self: ...
|
||||
def remove(self: Self) -> Self: ...
|
||||
def remove_p(self: Self) -> Self: ...
|
||||
def unlink(self: Self) -> Self: ...
|
||||
def unlink_p(self: Self) -> Self: ...
|
||||
def link(self: Self, newpath: str) -> Self: ...
|
||||
def symlink(self: Self, newlink: Optional[str] = ...) -> Self: ...
|
||||
def readlink(self: Self) -> Self: ...
|
||||
def readlinkabs(self: Self) -> Self: ...
|
||||
def copyfile(self, dst: str, *, follow_symlinks: bool = ...) -> str: ...
|
||||
def copymode(self, dst: str, *, follow_symlinks: bool = ...) -> None: ...
|
||||
def copystat(self, dst: str, *, follow_symlinks: bool = ...) -> None: ...
|
||||
def copy(self, dst: str, *, follow_symlinks: bool = ...) -> Any: ...
|
||||
def copy2(self, dst: str, *, follow_symlinks: bool = ...) -> Any: ...
|
||||
def copytree(
|
||||
self,
|
||||
dst: str,
|
||||
symlinks: bool = ...,
|
||||
ignore: Optional[Callable[[str, list[str]], Iterable[str]]] = ...,
|
||||
copy_function: Callable[[str, str], None] = ...,
|
||||
ignore_dangling_symlinks: bool = ...,
|
||||
dirs_exist_ok: bool = ...,
|
||||
) -> Any: ...
|
||||
def move(
|
||||
self, dst: str, copy_function: Callable[[str, str], None] = ...
|
||||
) -> Any: ...
|
||||
def rmtree(
|
||||
self,
|
||||
ignore_errors: bool = ...,
|
||||
onerror: Optional[Callable[[Any, Any, Any], Any]] = ...,
|
||||
) -> None: ...
|
||||
def rmtree_p(self: Self) -> Self: ...
|
||||
def chdir(self) -> None: ...
|
||||
def cd(self) -> None: ...
|
||||
def merge_tree(
|
||||
self,
|
||||
dst: str,
|
||||
symlinks: bool = ...,
|
||||
*,
|
||||
copy_function: Callable[[str, str], None] = ...,
|
||||
ignore: Callable[[Any, List[str]], Union[List[str], Set[str]]] = ...,
|
||||
) -> None: ...
|
||||
if sys.platform != 'win32':
|
||||
def chroot(self) -> None: ...
|
||||
if sys.platform == 'win32':
|
||||
def startfile(self: Self, operation: Optional[str] = ...) -> Self: ...
|
||||
|
||||
@contextlib.contextmanager
|
||||
def in_place(
|
||||
self,
|
||||
mode: str = ...,
|
||||
buffering: int = ...,
|
||||
encoding: Optional[str] = ...,
|
||||
errors: Optional[str] = ...,
|
||||
newline: Optional[str] = ...,
|
||||
backup_extension: Optional[str] = ...,
|
||||
) -> Iterator[Tuple[IO[Any], IO[Any]]]: ...
|
||||
@classes.ClassProperty
|
||||
@classmethod
|
||||
def special(cls) -> Callable[[Optional[str]], SpecialResolver]: ...
|
||||
|
||||
class DirectoryNotEmpty(OSError):
|
||||
@staticmethod
|
||||
def translate() -> Iterator[None]: ...
|
||||
|
||||
def only_newer(copy_func: Callable[[str, str], None]) -> Callable[[str, str], None]: ...
|
||||
|
||||
class ExtantPath(Path):
|
||||
def _validate(self) -> None: ...
|
||||
|
||||
class ExtantFile(Path):
|
||||
def _validate(self) -> None: ...
|
||||
|
||||
class SpecialResolver:
|
||||
class ResolverScope:
|
||||
def __init__(self, paths: SpecialResolver, scope: str) -> None: ...
|
||||
def __getattr__(self, class_: str) -> MultiPathType: ...
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path_class: type,
|
||||
appname: Optional[str] = ...,
|
||||
appauthor: Optional[str] = ...,
|
||||
version: Optional[str] = ...,
|
||||
roaming: bool = ...,
|
||||
multipath: bool = ...,
|
||||
): ...
|
||||
def __getattr__(self, scope: str) -> ResolverScope: ...
|
||||
def get_dir(self, scope: str, class_: str) -> MultiPathType: ...
|
||||
|
||||
class Multi:
|
||||
@classmethod
|
||||
def for_class(cls, path_cls: type) -> Type[MultiPathType]: ...
|
||||
@classmethod
|
||||
def detect(cls, input: str) -> MultiPathType: ...
|
||||
def __iter__(self) -> Iterator[Path]: ...
|
||||
@classes.ClassProperty
|
||||
@classmethod
|
||||
def _next_class(cls) -> Type[Path]: ...
|
||||
|
||||
class MultiPathType(Multi, Path):
|
||||
pass
|
||||
|
||||
class TempDir(Path):
|
||||
@classes.ClassProperty
|
||||
@classmethod
|
||||
def _next_class(cls) -> Type[Path]: ...
|
||||
def __new__(
|
||||
cls: Type[Self],
|
||||
suffix: Optional[AnyStr] = ...,
|
||||
prefix: Optional[AnyStr] = ...,
|
||||
dir: Optional[Union[AnyStr, os.PathLike[AnyStr]]] = ...,
|
||||
) -> Self: ...
|
||||
def __init__(self) -> None: ...
|
||||
def __enter__(self) -> Path: ... # type: ignore
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: Optional[type[BaseException]],
|
||||
exc_val: Optional[BaseException],
|
||||
exc_tb: Optional[TracebackType],
|
||||
) -> None: ...
|
||||
|
||||
class Handlers:
|
||||
@classmethod
|
||||
def _resolve(
|
||||
cls, param: Union[str, Callable[[str], None]]
|
||||
) -> Callable[[str], None]: ...
|
27
libs/win/path/classes.py
Normal file
27
libs/win/path/classes.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
import functools
|
||||
|
||||
|
||||
class ClassProperty(property):
|
||||
def __get__(self, cls, owner):
|
||||
return self.fget.__get__(None, owner)()
|
||||
|
||||
|
||||
class multimethod:
|
||||
"""
|
||||
Acts like a classmethod when invoked from the class and like an
|
||||
instancemethod when invoked from the instance.
|
||||
"""
|
||||
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
"""
|
||||
If called on an instance, pass the instance as the first
|
||||
argument.
|
||||
"""
|
||||
return (
|
||||
functools.partial(self.func, owner)
|
||||
if instance is None
|
||||
else functools.partial(self.func, owner, instance)
|
||||
)
|
8
libs/win/path/classes.pyi
Normal file
8
libs/win/path/classes.pyi
Normal file
|
@ -0,0 +1,8 @@
|
|||
from typing import Any, Callable, Optional
|
||||
|
||||
class ClassProperty(property):
|
||||
def __get__(self, cls: Any, owner: Optional[type] = ...) -> Any: ...
|
||||
|
||||
class multimethod:
|
||||
def __init__(self, func: Callable[..., Any]): ...
|
||||
def __get__(self, instance: Any, owner: Optional[type]) -> Any: ...
|
85
libs/win/path/masks.py
Normal file
85
libs/win/path/masks.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
import re
|
||||
import functools
|
||||
import operator
|
||||
|
||||
|
||||
# from jaraco.functools
|
||||
def compose(*funcs):
|
||||
compose_two = lambda f1, f2: lambda *args, **kwargs: f1(f2(*args, **kwargs)) # noqa
|
||||
return functools.reduce(compose_two, funcs)
|
||||
|
||||
|
||||
def compound(mode):
|
||||
"""
|
||||
Support multiple, comma-separated Unix chmod symbolic modes.
|
||||
|
||||
>>> oct(compound('a=r,u+w')(0))
|
||||
'0o644'
|
||||
"""
|
||||
return compose(*map(simple, reversed(mode.split(','))))
|
||||
|
||||
|
||||
def simple(mode):
|
||||
"""
|
||||
Convert a Unix chmod symbolic mode like ``'ugo+rwx'`` to a function
|
||||
suitable for applying to a mask to affect that change.
|
||||
|
||||
>>> mask = simple('ugo+rwx')
|
||||
>>> mask(0o554) == 0o777
|
||||
True
|
||||
|
||||
>>> simple('go-x')(0o777) == 0o766
|
||||
True
|
||||
|
||||
>>> simple('o-x')(0o445) == 0o444
|
||||
True
|
||||
|
||||
>>> simple('a+x')(0) == 0o111
|
||||
True
|
||||
|
||||
>>> simple('a=rw')(0o057) == 0o666
|
||||
True
|
||||
|
||||
>>> simple('u=x')(0o666) == 0o166
|
||||
True
|
||||
|
||||
>>> simple('g=')(0o157) == 0o107
|
||||
True
|
||||
|
||||
>>> simple('gobbledeegook')
|
||||
Traceback (most recent call last):
|
||||
ValueError: ('Unrecognized symbolic mode', 'gobbledeegook')
|
||||
"""
|
||||
# parse the symbolic mode
|
||||
parsed = re.match('(?P<who>[ugoa]+)(?P<op>[-+=])(?P<what>[rwx]*)$', mode)
|
||||
if not parsed:
|
||||
raise ValueError("Unrecognized symbolic mode", mode)
|
||||
|
||||
# generate a mask representing the specified permission
|
||||
spec_map = dict(r=4, w=2, x=1)
|
||||
specs = (spec_map[perm] for perm in parsed.group('what'))
|
||||
spec = functools.reduce(operator.or_, specs, 0)
|
||||
|
||||
# now apply spec to each subject in who
|
||||
shift_map = dict(u=6, g=3, o=0)
|
||||
who = parsed.group('who').replace('a', 'ugo')
|
||||
masks = (spec << shift_map[subj] for subj in who)
|
||||
mask = functools.reduce(operator.or_, masks)
|
||||
|
||||
op = parsed.group('op')
|
||||
|
||||
# if op is -, invert the mask
|
||||
if op == '-':
|
||||
mask ^= 0o777
|
||||
|
||||
# if op is =, retain extant values for unreferenced subjects
|
||||
if op == '=':
|
||||
masks = (0o7 << shift_map[subj] for subj in who)
|
||||
retain = functools.reduce(operator.or_, masks) ^ 0o777
|
||||
|
||||
op_map = {
|
||||
'+': operator.or_,
|
||||
'-': operator.and_,
|
||||
'=': lambda mask, target: target & retain ^ mask,
|
||||
}
|
||||
return functools.partial(op_map[op], mask)
|
5
libs/win/path/masks.pyi
Normal file
5
libs/win/path/masks.pyi
Normal file
|
@ -0,0 +1,5 @@
|
|||
from typing import Any, Callable
|
||||
|
||||
def compose(*funcs: Callable[..., Any]) -> Callable[..., Any]: ...
|
||||
def compound(mode: str) -> Callable[[int], int]: ...
|
||||
def simple(mode: str) -> Callable[[int], int]: ...
|
59
libs/win/path/matchers.py
Normal file
59
libs/win/path/matchers.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
import ntpath
|
||||
import fnmatch
|
||||
|
||||
|
||||
def load(param):
|
||||
"""
|
||||
If the supplied parameter is a string, assume it's a simple
|
||||
pattern.
|
||||
"""
|
||||
return (
|
||||
Pattern(param)
|
||||
if isinstance(param, str)
|
||||
else param
|
||||
if param is not None
|
||||
else Null()
|
||||
)
|
||||
|
||||
|
||||
class Base:
|
||||
pass
|
||||
|
||||
|
||||
class Null(Base):
|
||||
def __call__(self, path):
|
||||
return True
|
||||
|
||||
|
||||
class Pattern(Base):
|
||||
def __init__(self, pattern):
|
||||
self.pattern = pattern
|
||||
|
||||
def get_pattern(self, normcase):
|
||||
try:
|
||||
return self._pattern
|
||||
except AttributeError:
|
||||
pass
|
||||
self._pattern = normcase(self.pattern)
|
||||
return self._pattern
|
||||
|
||||
def __call__(self, path):
|
||||
normcase = getattr(self, 'normcase', path.module.normcase)
|
||||
pattern = self.get_pattern(normcase)
|
||||
return fnmatch.fnmatchcase(normcase(path.name), pattern)
|
||||
|
||||
|
||||
class CaseInsensitive(Pattern):
|
||||
"""
|
||||
A Pattern with a ``'normcase'`` property, suitable for passing to
|
||||
:meth:`listdir`, :meth:`dirs`, :meth:`files`, :meth:`walk`,
|
||||
:meth:`walkdirs`, or :meth:`walkfiles` to match case-insensitive.
|
||||
|
||||
For example, to get all files ending in .py, .Py, .pY, or .PY in the
|
||||
current directory::
|
||||
|
||||
from path import Path, matchers
|
||||
Path('.').files(matchers.CaseInsensitive('*.py'))
|
||||
"""
|
||||
|
||||
normcase = staticmethod(ntpath.normcase)
|
28
libs/win/path/matchers.pyi
Normal file
28
libs/win/path/matchers.pyi
Normal file
|
@ -0,0 +1,28 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable, overload
|
||||
|
||||
from typing_extensions import Literal
|
||||
|
||||
from path import Path
|
||||
|
||||
@overload
|
||||
def load(param: None) -> Null: ...
|
||||
@overload
|
||||
def load(param: str) -> Pattern: ...
|
||||
@overload
|
||||
def load(param: Any) -> Any: ...
|
||||
|
||||
class Base:
|
||||
pass
|
||||
|
||||
class Null(Base):
|
||||
def __call__(self, path: str) -> Literal[True]: ...
|
||||
|
||||
class Pattern(Base):
|
||||
def __init__(self, pattern: str) -> None: ...
|
||||
def get_pattern(self, normcase: Callable[[str], str]) -> str: ...
|
||||
def __call__(self, path: Path) -> bool: ...
|
||||
|
||||
class CaseInsensitive(Pattern):
|
||||
normcase: Callable[[str], str]
|
0
libs/win/path/py.typed
Normal file
0
libs/win/path/py.typed
Normal file
125
libs/win/path/py37compat.py
Normal file
125
libs/win/path/py37compat.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
import functools
|
||||
import os
|
||||
|
||||
|
||||
def best_realpath(module):
|
||||
"""
|
||||
Given a path module (i.e. ntpath, posixpath),
|
||||
determine the best 'realpath' function to use
|
||||
for best future compatibility.
|
||||
"""
|
||||
needs_backport = module.realpath is module.abspath
|
||||
return realpath_backport if needs_backport else module.realpath
|
||||
|
||||
|
||||
# backport taken from jaraco.windows 5
|
||||
def realpath_backport(path):
|
||||
if isinstance(path, str):
|
||||
prefix = '\\\\?\\'
|
||||
unc_prefix = prefix + 'UNC'
|
||||
new_unc_prefix = '\\'
|
||||
cwd = os.getcwd()
|
||||
else:
|
||||
prefix = b'\\\\?\\'
|
||||
unc_prefix = prefix + b'UNC'
|
||||
new_unc_prefix = b'\\'
|
||||
cwd = os.getcwdb()
|
||||
had_prefix = path.startswith(prefix)
|
||||
path, ok = _resolve_path(cwd, path, {})
|
||||
# The path returned by _getfinalpathname will always start with \\?\ -
|
||||
# strip off that prefix unless it was already provided on the original
|
||||
# path.
|
||||
if not had_prefix:
|
||||
# For UNC paths, the prefix will actually be \\?\UNC - handle that
|
||||
# case as well.
|
||||
if path.startswith(unc_prefix):
|
||||
path = new_unc_prefix + path[len(unc_prefix) :]
|
||||
elif path.startswith(prefix):
|
||||
path = path[len(prefix) :]
|
||||
return path
|
||||
|
||||
|
||||
def _resolve_path(path, rest, seen): # noqa: C901
|
||||
# Windows normalizes the path before resolving symlinks; be sure to
|
||||
# follow the same behavior.
|
||||
rest = os.path.normpath(rest)
|
||||
|
||||
if isinstance(rest, str):
|
||||
sep = '\\'
|
||||
else:
|
||||
sep = b'\\'
|
||||
|
||||
if os.path.isabs(rest):
|
||||
drive, rest = os.path.splitdrive(rest)
|
||||
path = drive + sep
|
||||
rest = rest[1:]
|
||||
|
||||
while rest:
|
||||
name, _, rest = rest.partition(sep)
|
||||
new_path = os.path.join(path, name) if path else name
|
||||
if os.path.exists(new_path):
|
||||
if not rest:
|
||||
# The whole path exists. Resolve it using the OS.
|
||||
path = os.path._getfinalpathname(new_path)
|
||||
else:
|
||||
# The OS can resolve `new_path`; keep traversing the path.
|
||||
path = new_path
|
||||
elif not os.path.lexists(new_path):
|
||||
# `new_path` does not exist on the filesystem at all. Use the
|
||||
# OS to resolve `path`, if it exists, and then append the
|
||||
# remainder.
|
||||
if os.path.exists(path):
|
||||
path = os.path._getfinalpathname(path)
|
||||
rest = os.path.join(name, rest) if rest else name
|
||||
return os.path.join(path, rest), True
|
||||
else:
|
||||
# We have a symbolic link that the OS cannot resolve. Try to
|
||||
# resolve it ourselves.
|
||||
|
||||
# On Windows, symbolic link resolution can be partially or
|
||||
# fully disabled [1]. The end result of a disabled symlink
|
||||
# appears the same as a broken symlink (lexists() returns True
|
||||
# but exists() returns False). And in both cases, the link can
|
||||
# still be read using readlink(). Call stat() and check the
|
||||
# resulting error code to ensure we don't circumvent the
|
||||
# Windows symbolic link restrictions.
|
||||
# [1] https://technet.microsoft.com/en-us/library/cc754077.aspx
|
||||
try:
|
||||
os.stat(new_path)
|
||||
except OSError as e:
|
||||
# WinError 1463: The symbolic link cannot be followed
|
||||
# because its type is disabled.
|
||||
if e.winerror == 1463:
|
||||
raise
|
||||
|
||||
key = os.path.normcase(new_path)
|
||||
if key in seen:
|
||||
# This link has already been seen; try to use the
|
||||
# previously resolved value.
|
||||
path = seen[key]
|
||||
if path is None:
|
||||
# It has not yet been resolved, which means we must
|
||||
# have a symbolic link loop. Return what we have
|
||||
# resolved so far plus the remainder of the path (who
|
||||
# cares about the Zen of Python?).
|
||||
path = os.path.join(new_path, rest) if rest else new_path
|
||||
return path, False
|
||||
else:
|
||||
# Mark this link as in the process of being resolved.
|
||||
seen[key] = None
|
||||
# Try to resolve it.
|
||||
path, ok = _resolve_path(path, os.readlink(new_path), seen)
|
||||
if ok:
|
||||
# Resolution succeded; store the resolved value.
|
||||
seen[key] = path
|
||||
else:
|
||||
# Resolution failed; punt.
|
||||
return (os.path.join(path, rest) if rest else path), False
|
||||
return path, True
|
||||
|
||||
|
||||
def lru_cache(user_function):
|
||||
"""
|
||||
Support for lru_cache(user_function)
|
||||
"""
|
||||
return functools.lru_cache()(user_function)
|
17
libs/win/path/py37compat.pyi
Normal file
17
libs/win/path/py37compat.pyi
Normal file
|
@ -0,0 +1,17 @@
|
|||
import os
|
||||
|
||||
from types import ModuleType
|
||||
from typing import Any, AnyStr, Callable, Dict, Tuple, overload
|
||||
|
||||
def best_realpath(module: ModuleType) -> Callable[[AnyStr], AnyStr]: ...
|
||||
@overload
|
||||
def realpath_backport(path: str) -> str: ...
|
||||
@overload
|
||||
def realpath_backport(path: bytes) -> bytes: ...
|
||||
@overload
|
||||
def _resolve_path(path: str, rest: str, seen: Dict[Any, Any]) -> Tuple[str, bool]: ...
|
||||
@overload
|
||||
def _resolve_path(
|
||||
path: bytes, rest: bytes, seen: Dict[Any, Any]
|
||||
) -> Tuple[bytes, bool]: ...
|
||||
def lru_cache(user_function: Callable[..., Any]) -> Callable[..., Any]: ...
|
Loading…
Add table
Add a link
Reference in a new issue