From 12e39c52945c855fe890fa6cefd7e8beada31f13 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Fri, 3 Oct 2025 19:32:19 +0200 Subject: [PATCH 1/4] upath: add from_uri classmethod --- upath/core.py | 4 ++++ upath/implementations/local.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/upath/core.py b/upath/core.py index 36af6dd9..e7857de4 100644 --- a/upath/core.py +++ b/upath/core.py @@ -1117,6 +1117,10 @@ def __reduce__(self): kwargs["_relative_base"] = self._relative_base return _make_instance, (type(self), args, kwargs) + @classmethod + def from_uri(cls, uri: str, **storage_options: Any) -> Self: + return UPath(uri, **storage_options) # type: ignore[return-value] + def as_uri(self) -> str: if self._relative_base is not None: raise ValueError( diff --git a/upath/implementations/local.py b/upath/implementations/local.py index e6d4a27d..36485912 100644 --- a/upath/implementations/local.py +++ b/upath/implementations/local.py @@ -394,6 +394,10 @@ def full_match(self, pattern: str) -> bool: # todo: revisit return self.match(pattern) + @classmethod + def from_uri(cls, uri: str, **storage_options: Any) -> Self: + return cls(uri, **storage_options) + if sys.version_info < (3, 12): def is_junction(self) -> bool: From c4025bc91798d8a8eacfaa62a528ca5b464fa406 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Fri, 3 Oct 2025 19:33:47 +0200 Subject: [PATCH 2/4] upath.extensions: add from_uri --- upath/extensions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/upath/extensions.py b/upath/extensions.py index 8c83873c..6e6eeb0a 100644 --- a/upath/extensions.py +++ b/upath/extensions.py @@ -344,6 +344,10 @@ def root(self) -> str: def __reduce__(self): return type(self)._from_upath, (self.__wrapped__,) + @classmethod + def from_uri(cls, uri: str, **storage_options: Any) -> Self: + return cls(uri, **storage_options) + def as_uri(self) -> str: return self.__wrapped__.as_uri() From 339ab88226f61a2758d3290e0436c6bde6123686 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Fri, 3 Oct 2025 19:36:33 +0200 Subject: [PATCH 3/4] upath: apply workaround on local not on core --- upath/core.py | 2 +- upath/implementations/local.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/upath/core.py b/upath/core.py index e7857de4..71a07743 100644 --- a/upath/core.py +++ b/upath/core.py @@ -1119,7 +1119,7 @@ def __reduce__(self): @classmethod def from_uri(cls, uri: str, **storage_options: Any) -> Self: - return UPath(uri, **storage_options) # type: ignore[return-value] + return cls(uri, **storage_options) def as_uri(self) -> str: if self._relative_base is not None: diff --git a/upath/implementations/local.py b/upath/implementations/local.py index 36485912..cc463b12 100644 --- a/upath/implementations/local.py +++ b/upath/implementations/local.py @@ -396,7 +396,7 @@ def full_match(self, pattern: str) -> bool: @classmethod def from_uri(cls, uri: str, **storage_options: Any) -> Self: - return cls(uri, **storage_options) + return UPath(uri, **storage_options) # type: ignore[return-value] if sys.version_info < (3, 12): From bd836d9851d7b6646322f68648c2d9aeeb99f295 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Fri, 3 Oct 2025 19:39:23 +0200 Subject: [PATCH 4/4] typesafety: check from_uri --- typesafety/test_upath_signatures.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/typesafety/test_upath_signatures.yml b/typesafety/test_upath_signatures.yml index 94470af7..36d9f035 100644 --- a/typesafety/test_upath_signatures.yml +++ b/typesafety/test_upath_signatures.yml @@ -897,6 +897,13 @@ reveal_type(UPath.home()) # N: Revealed type is "upath.core.UPath" +- case: upath_classmethod_from_uri + disable_cache: false + main: | + from upath import UPath + + reveal_type(UPath.from_uri("uri")) # N: Revealed type is "upath.core.UPath" + - case: upath_method_relative_to disable_cache: false main: | @@ -1084,3 +1091,4 @@ # Class methods reveal_type({{ cls }}.cwd()) # N: Revealed type is "{{ module }}.{{ cls }}" reveal_type({{ cls }}.home()) # N: Revealed type is "{{ module }}.{{ cls }}" + reveal_type({{ cls }}.from_uri("uri")) # N: Revealed type is "{{ module }}.{{ cls }}"