diff --git a/upath/_flavour.py b/upath/_flavour.py index 34c7a8de..3b64e0fb 100644 --- a/upath/_flavour.py +++ b/upath/_flavour.py @@ -4,7 +4,9 @@ import os.path import posixpath import sys +import warnings from functools import lru_cache +from functools import wraps from typing import Any from typing import Callable from typing import Iterable @@ -28,6 +30,23 @@ ] +def _deprecated(func): + if sys.version_info >= (3, 12): + + @wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + f"{func.__name__} is deprecated on py3.12", + DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + else: + return func + + class FSSpecFlavour: """fsspec flavour for universal_pathlib @@ -181,48 +200,49 @@ def normcase(self, __path: PathOrStr) -> str: else: return os.path.normcase(__path) - if sys.version_info < (3, 12): - - def parse_parts(self, parts): - parsed = [] - sep = self.sep - drv = root = "" - it = reversed(parts) - for part in it: - if part: - drv, root, rel = self.splitroot(part) - if not root or root and rel: - for x in reversed(rel.split(sep)): - parsed.append(sys.intern(x)) - - if drv or root: - parsed.append(drv + root) - parsed.reverse() - return drv, root, parsed - - def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): - """ - Join the two paths represented by the respective - (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. - """ - if root2: - if not drv2 and drv: - return drv, root2, [drv + root2] + parts2[1:] - elif drv2: - if drv2 == drv or self.casefold(drv2) == self.casefold(drv): - # Same drive => second path is relative to the first - return drv, root, parts + parts2[1:] - else: - # Second path is non-anchored (common case) - return drv, root, parts + parts2 - return drv2, root2, parts2 - - def casefold(self, s: str) -> str: - """Casefold the string s.""" - if self.posixpath_only or os.name != "nt": - return s - else: - return s.lower() + @_deprecated + def parse_parts(self, parts): + parsed = [] + sep = self.sep + drv = root = "" + it = reversed(parts) + for part in it: + if part: + drv, root, rel = self.splitroot(part) + if not root or root and rel: + for x in reversed(rel.split(sep)): + parsed.append(sys.intern(x)) + + if drv or root: + parsed.append(drv + root) + parsed.reverse() + return drv, root, parsed + + @_deprecated + def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): + """ + Join the two paths represented by the respective + (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. + """ + if root2: + if not drv2 and drv: + return drv, root2, [drv + root2] + parts2[1:] + elif drv2: + if drv2 == drv or self.casefold(drv2) == self.casefold(drv): + # Same drive => second path is relative to the first + return drv, root, parts + parts2[1:] + else: + # Second path is non-anchored (common case) + return drv, root, parts + parts2 + return drv2, root2, parts2 + + @_deprecated + def casefold(self, s: str) -> str: + """Casefold the string s.""" + if self.posixpath_only or os.name != "nt": + return s + else: + return s.lower() @lru_cache diff --git a/upath/core.py b/upath/core.py index c57da2ce..e697f1ad 100644 --- a/upath/core.py +++ b/upath/core.py @@ -397,6 +397,37 @@ def _from_parts(cls, parts, **kwargs): obj.__init__(*parts, **kwargs) return obj + @classmethod + def _parse_args(cls, args): + warnings.warn( + "UPath._parse_args is deprecated and should not be used." + " Please follow the universal_pathlib==0.2.0 migration guide at" + " https://github.com/fsspec/universal_pathlib for more" + " information.", + DeprecationWarning, + stacklevel=2, + ) + pth = cls._flavour.join(*args) + return cls._parse_path(pth) + + @classmethod + def _format_parsed_parts(cls, drv, root, tail, **kwargs): + if kwargs: + warnings.warn( + "UPath._format_parsed_parts should not be used with" + " additional kwargs. Please follow the" + " universal_pathlib==0.2.0 migration guide at" + " https://github.com/fsspec/universal_pathlib for more" + " information.", + DeprecationWarning, + stacklevel=2, + ) + if "url" in kwargs and tail[:1] == [f"{drv}{root}"]: + # This was called from code that expected py38-py311 behavior + # of _format_parsed_parts, which takes drv, root and parts + tail = tail[1:] + return super()._format_parsed_parts(drv, root, tail) + @property def _drv(self): # direct access to ._drv should emit a warning,