Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit from pathlib_abc.PathBase #270

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f78efed
upath: add pathlib-abc to upath._abc
ap-- Sep 2, 2024
be349df
upath._compat: move make_instance
ap-- Sep 2, 2024
e0ed7fd
upath: update core, introduce _parser and _uris
ap-- Sep 3, 2024
608ae5f
typesafety: adjust typing of walk, and simplify link_to tests
ap-- Sep 3, 2024
9b33d3e
tests: UPath.lstat returns but throws warning
ap-- Sep 3, 2024
b8a3da5
tests: xfail obsolete private api test
ap-- Sep 3, 2024
ff0d1f3
tests: add timeouts to http tests to improve runs behind vpn
ap-- Sep 3, 2024
9cd2e23
upath.implementations: remove obsolote _compat imports
ap-- Sep 3, 2024
f870943
upath.implementations.local: reimplement PosixUPath WindowsUPath (wip)
ap-- Sep 3, 2024
30ca2ea
upath._compat: typing fixes
ap-- Sep 3, 2024
54cf9d5
tests: define subclass behavior for PosixUPath and WindowsUPath
ap-- Sep 3, 2024
36068bf
upath.implementations.local: fix PosixUPath and WindowsUPath impl
ap-- Sep 3, 2024
50bd74e
upath.implementations.local: Path.__init__ quirks on python 3.8-3.12
ap-- Sep 3, 2024
07fb39f
upath.implementations.webdav: remove obsolete accessor shim
ap-- Sep 3, 2024
6ee0c47
upath.implementations.cloud: comment 'missing bucket' check for now
ap-- Sep 3, 2024
1e30310
tests: add more test cases for rename/replace
ap-- Sep 3, 2024
3f2a0fc
upath: fix rename replace test cases
ap-- Sep 3, 2024
4ae1d71
tests: fix data path tests
ap-- Sep 3, 2024
02c86af
upath.core: fix storage_options parsing from urlpath
ap-- Sep 3, 2024
f265730
tests: fix readonly github tests
ap-- Sep 3, 2024
491e638
upath.implementations.local: guard import Self
ap-- Sep 3, 2024
d96496b
Merge branch 'main' into pathlib-pathbase
ap-- Nov 8, 2024
3d73178
tests: support gcs tests without internet connection
ap-- Nov 18, 2024
8f98c6c
tests: cleanup azure tests
ap-- Nov 18, 2024
19e7859
tests: fix error with s3 fixture with global moto install
ap-- Nov 18, 2024
bc1e10d
tests: remove obsolete accessor tests
ap-- Nov 18, 2024
8084de6
tests: remove deprecated private attributes
ap-- Nov 18, 2024
a1d0049
Merge remote-tracking branch 'origin/main' into pathlib-pathbase
ap-- Nov 20, 2024
ee8f4f1
upath.core: fix .name and glob
ap-- Nov 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ show_source = true
count = true
per-file-ignores =
upath/__init__.py: F401
upath/_parser.py: E501
exclude =
.noxfile,
.nox,
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ maintainers = [
requires-python = ">=3.8"
dependencies = [
"fsspec >=2022.1.0,!=2024.3.1",
"pathlib-abc ==0.3.1",
]
classifiers = [
"Programming Language :: Python :: 3",
Expand Down Expand Up @@ -160,6 +161,10 @@ ignore_missing_imports = true
module = "webdav4.*"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "pathlib_abc.*"
ignore_missing_imports = true

[tool.pylint.format]
max-line-length = 88

Expand Down
6 changes: 3 additions & 3 deletions typesafety/test_upath_interface.yml
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,15 @@
main: |
from upath import UPath

UPath("abc").walk # E: "UPath" has no attribute "walk" [attr-defined]
reveal_type(UPath("abc").walk()) # N: Revealed type is "typing.Generator[Tuple[upath.core.UPath, builtins.list[builtins.str], builtins.list[builtins.str]], None, None]"

- case: upath_walk_py312plus
disable_cache: false
mypy_config: python_version = 3.12
main: |
from upath import UPath
from upath import UPath

reveal_type(UPath("abc").walk()) # N: Revealed type is "typing.Iterator[tuple[upath.core.UPath, builtins.list[builtins.str], builtins.list[builtins.str]]]"
reveal_type(UPath("abc").walk()) # N: Revealed type is "typing.Generator[tuple[upath.core.UPath, builtins.list[builtins.str], builtins.list[builtins.str]], None, None]"

- case: upath_rename_extra_kwargs
disable_cache: false
Expand Down
18 changes: 18 additions & 0 deletions upath/_abc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""upath._abc

Re-export of the `pathlib_abc` base classes `PathBase`, `PurePathBase`,
and `ParserBase`. This allows for type hinting of these classes more
easily via the stub file `upath/_abc.pyi`.
"""

from pathlib_abc import ParserBase as ParserBase
from pathlib_abc import PathBase as PathBase
from pathlib_abc import PurePathBase as PurePathBase
from pathlib_abc import UnsupportedOperation as UnsupportedOperation

__all__ = [
"ParserBase",
"PurePathBase",
"PathBase",
"UnsupportedOperation",
]
163 changes: 163 additions & 0 deletions upath/_abc.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
"""upath._abc type stubs

Type stubs for the pathlib-abc classes we use in universal-pathlib.
"""

import sys
from typing import IO
from typing import Any
from typing import Callable
from typing import Generator
from typing import Sequence

if sys.version_info > (3, 11):
from typing import Self
elif sys.version_info > (3, 8):

from typing_extensions import Self
else:
from typing_extensions import Self

from upath._stat import _StatResultType as StatResultType

class UnsupportedOperation(NotImplementedError): ...

class ParserBase:
sep: str
def join(self, path: str, *paths: str) -> str: ...
def split(self, path: str) -> tuple[str, str]: ...
def splitdrive(self, path: str) -> tuple[str, str]: ...
def splitext(self, path: str) -> tuple[str, str]: ...
def normcase(self, path: str) -> str: ...
def isabs(self, path: str) -> bool: ...

class PurePathBase:
_raw_path: str
_resolving: bool

@classmethod
def _unsupported_msg(cls, attribute) -> str: ...
def __init__(self, path, *paths) -> None: ...
def with_segments(self, *pathsegments: str) -> Self: ...
def __str__(self) -> str: ...
def as_posix(self) -> str: ...
drive: str
root: str
anchor: str
name: str
suffix: str
suffixes: list[str]
stem: str
def with_name(self, name: str) -> Self: ...
def with_stem(self, stem: str) -> Self: ...
def with_suffix(self, suffix: str) -> Self: ...
def relative_to(
self, other: str | PurePathBase, *, walk_up: bool = False
) -> Self: ...
def is_relative_to(self, other: str | PurePathBase) -> bool: ...
parts: tuple[str, ...]
def joinpath(self, *pathsegments: str) -> Self: ...
def __truediv__(self, other: str) -> Self: ...
def __rtruediv__(self, other: str) -> Self: ...
_stack: tuple[str, list[str]]
parent: Self
parents: Sequence[Self]
def is_absolute(self) -> bool: ...
_pattern_str: str
def match(
self, path_pattern: str, *, case_sensitive: bool | None = None
) -> bool: ...
def full_match(
self, pattern: str, *, case_sensitive: bool | None = None
) -> bool: ...

class PathBase(PurePathBase):
_max_symlinks: int

def stat(self, *, follow_symlinks: bool = True) -> StatResultType: ...
def lstat(self) -> StatResultType: ...
def exists(self, *, follow_symlinks: bool = True) -> bool: ...
def is_dir(self, *, follow_symlinks: bool = True) -> bool: ...
def is_file(self, *, follow_symlinks: bool = True) -> bool: ...
def is_mount(self) -> bool: ...
def is_symlink(self) -> bool: ...
def is_junction(self) -> bool: ...
def is_block_device(self) -> bool: ...
def is_char_device(self) -> bool: ...
def is_fifo(self) -> bool: ...
def is_socket(self) -> bool: ...
def samefile(self, other_path: str | Self) -> bool: ...
def open(
self,
mode: str = "r",
buffering: int = -1,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> IO[Any]: ...
def read_bytes(self) -> bytes: ...
def read_text(
self,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> str: ...
def write_bytes(self, data: bytes) -> int: ...
def write_text(
self,
data: str,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> int: ...
def iterdir(self) -> Generator[Self, None, None]: ...
def _glob_selector(
self, parts: list[str], case_sensitive: bool | None, recurse_symlinks: bool
) -> Callable[[Self], Generator[Self, None, None]]: ...
def glob(
self,
pattern: str,
*,
case_sensitive: bool | None = None,
recurse_symlinks: bool = True,
) -> Generator[Self, None, None]: ...
def rglob(
self,
pattern: str,
*,
case_sensitive: bool | None = None,
recurse_symlinks: bool = True,
) -> Generator[Self, None, None]: ...
def walk(
self,
top_down: bool = True,
on_error: Callable[[Exception], None] | None = None,
follow_symlinks: bool = False,
) -> Generator[tuple[Self, list[str], list[str]], None, None]: ...
def absolute(self) -> Self: ...
@classmethod
def cwd(cls) -> Self: ...
def expanduser(self) -> Self: ...
@classmethod
def home(cls) -> Self: ...
def readlink(self) -> Self: ...
def resolve(self, strict: bool = False) -> Self: ...
def symlink_to(
self, target: str | Self, target_is_directory: bool = False
) -> None: ...
def hardlink_to(self, target: str | Self) -> None: ...
def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None: ...
def mkdir(
self, mode: int = 0o777, parents: bool = False, exist_ok: bool = False
) -> None: ...
def rename(self, target: str | Self) -> Self: ...
def replace(self, target: str | Self) -> Self: ...
def chmod(self, mode: int, *, follow_symlinks: bool = True) -> None: ...
def lchmod(self, mode: int) -> None: ...
def unlink(self, missing_ok: bool = False) -> None: ...
def rmdir(self) -> None: ...
def owner(self, *, follow_symlinks: bool = True) -> str: ...
def group(self, *, follow_symlinks: bool = True) -> str: ...
@classmethod
def from_uri(cls, uri: str) -> Self: ...
def as_uri(self) -> str: ...
Loading
Loading