From e8ac247f9fafea51be9d1a3c8a06f7462fc0703d Mon Sep 17 00:00:00 2001 From: Matthew Hoffman Date: Mon, 12 Jun 2023 10:23:27 -0700 Subject: [PATCH] Make CloudPath.is_valid_cloudpath a TypeGuard (#337) This allows us to infer that CloudPaths are the same type of object as the class is_valid_cloudpath is called on --- cloudpathlib/cloudpath.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cloudpathlib/cloudpath.py b/cloudpathlib/cloudpath.py index a744ae50..c50989db 100644 --- a/cloudpathlib/cloudpath.py +++ b/cloudpathlib/cloudpath.py @@ -35,6 +35,10 @@ from urllib.parse import urlparse from warnings import warn +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + from typing_extensions import TypeGuard if sys.version_info >= (3, 11): from typing import Self else: @@ -258,8 +262,20 @@ def _no_prefix(self) -> str: def _no_prefix_no_drive(self) -> str: return self._str[len(self.cloud_prefix) + len(self.drive) :] + @overload + @classmethod + def is_valid_cloudpath(cls, path: "CloudPath", raise_on_error: bool = ...) -> TypeGuard[Self]: + ... + + @overload + @classmethod + def is_valid_cloudpath(cls, path: str, raise_on_error: bool = ...) -> bool: + ... + @classmethod - def is_valid_cloudpath(cls, path: Union[str, "CloudPath"], raise_on_error=False) -> bool: + def is_valid_cloudpath( + cls, path: Union[str, "CloudPath"], raise_on_error: bool = False + ) -> Union[bool, TypeGuard[Self]]: valid = str(path).lower().startswith(cls.cloud_prefix.lower()) if raise_on_error and not valid: