Skip to content

Commit 0b6490c

Browse files
authored
upath.implementations: switch cloud, http and webdav to recommended _transform_init_args (#181)
1 parent f6e9adc commit 0b6490c

File tree

3 files changed

+43
-29
lines changed

3 files changed

+43
-29
lines changed

upath/implementations/cloud.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import os
34
from typing import Any
45

56
from upath._compat import FSSpecAccessorShim as _FSSpecAccessorShim
@@ -25,18 +26,22 @@ class CloudPath(UPath):
2526
supports_netloc=True,
2627
)
2728

28-
def __init__(
29-
self, *args, protocol: str | None = None, **storage_options: Any
30-
) -> None:
29+
@classmethod
30+
def _transform_init_args(
31+
cls,
32+
args: tuple[str | os.PathLike, ...],
33+
protocol: str,
34+
storage_options: dict[str, Any],
35+
) -> tuple[tuple[str | os.PathLike, ...], str, dict[str, Any]]:
3136
for key in ["bucket", "netloc"]:
3237
bucket = storage_options.pop(key, None)
3338
if bucket:
34-
if args[0].startswith("/"):
35-
args = (f"{self._protocol}://{bucket}{args[0]}", *args[1:])
39+
if str(args[0]).startswith("/"):
40+
args = (f"{protocol}://{bucket}{args[0]}", *args[1:])
3641
else:
37-
args = (f"{self._protocol}://{bucket}/", *args)
42+
args = (f"{protocol}://{bucket}/", *args)
3843
break
39-
super().__init__(*args, protocol=protocol, **storage_options)
44+
return super()._transform_init_args(args, protocol, storage_options)
4045

4146
def mkdir(
4247
self, mode: int = 0o777, parents: bool = False, exist_ok: bool = False

upath/implementations/http.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import annotations
22

3+
import os
34
import warnings
45
from itertools import chain
6+
from typing import Any
57

68
from fsspec.asyn import sync
79

@@ -25,6 +27,18 @@ class HTTPPath(UPath):
2527
supports_fragments=True,
2628
)
2729

30+
@classmethod
31+
def _transform_init_args(
32+
cls,
33+
args: tuple[str | os.PathLike, ...],
34+
protocol: str,
35+
storage_options: dict[str, Any],
36+
) -> tuple[tuple[str | os.PathLike, ...], str, dict[str, Any]]:
37+
# allow initialization via a path argument and protocol keyword
38+
if args and not str(args[0]).startswith(protocol):
39+
args = (f"{protocol}://{args[0].lstrip('/')}", *args[1:])
40+
return args, protocol, storage_options
41+
2842
@property
2943
def root(self) -> str:
3044
return super().root or "/"

upath/implementations/webdav.py

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import annotations
22

3+
import os
34
from typing import Any
45
from urllib.parse import urlsplit
5-
from urllib.parse import urlunsplit
66

77
from fsspec.registry import known_implementations
88
from fsspec.registry import register_implementation
@@ -30,32 +30,27 @@
3030
class WebdavPath(UPath):
3131
__slots__ = ()
3232

33-
def __init__(
34-
self, *args, protocol: str | None = None, **storage_options: Any
35-
) -> None:
36-
base_options = getattr(self, "_storage_options", {}) # when unpickling
37-
if args:
33+
@classmethod
34+
def _transform_init_args(
35+
cls,
36+
args: tuple[str | os.PathLike, ...],
37+
protocol: str,
38+
storage_options: dict[str, Any],
39+
) -> tuple[tuple[str | os.PathLike, ...], str, dict[str, Any]]:
40+
if not args:
41+
args = ("/",)
42+
elif args and protocol in {"webdav+http", "webdav+https"}:
3843
args0, *argsN = args
3944
url = urlsplit(str(args0))
40-
args0 = urlunsplit(url._replace(scheme="", netloc="")) or "/"
41-
if "base_url" not in storage_options:
42-
if self._protocol == "webdav+http":
43-
storage_options["base_url"] = urlunsplit(
44-
url._replace(scheme="http", path="")
45-
)
46-
elif self._protocol == "webdav+https":
47-
storage_options["base_url"] = urlunsplit(
48-
url._replace(scheme="https", path="")
49-
)
50-
else:
51-
args0, argsN = "/", []
52-
storage_options = {**base_options, **storage_options}
45+
base = url._replace(scheme=protocol.split("+")[1], path="").geturl()
46+
args0 = url._replace(scheme="", netloc="").geturl() or "/"
47+
storage_options["base_url"] = base
48+
args = (args0, *argsN)
5349
if "base_url" not in storage_options:
5450
raise ValueError(
5551
f"must provide `base_url` storage option for args: {args!r}"
5652
)
57-
self._protocol = "webdav"
58-
super().__init__(args0, *argsN, protocol="webdav", **storage_options)
53+
return super()._transform_init_args(args, "webdav", storage_options)
5954

6055
@property
6156
def path(self) -> str:
@@ -64,4 +59,4 @@ def path(self) -> str:
6459

6560
def __str__(self):
6661
base_url = str_remove_suffix(self.storage_options["base_url"], "/")
67-
return super().__str__().replace("webdav://", f"webdav+{base_url}", 1)
62+
return super().__str__().replace("webdav://", f"webdav+{base_url}/", 1)

0 commit comments

Comments
 (0)