From 20dfa94c4e832d9110b47b58e9dff141e224b74f Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Sun, 20 Mar 2022 14:07:49 +0100 Subject: [PATCH 1/7] adds copy-constructor to UPath --- upath/core.py | 18 ++++++++++++++++++ upath/tests/test_core.py | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/upath/core.py b/upath/core.py index 90ef6d8e..7fb4942a 100644 --- a/upath/core.py +++ b/upath/core.py @@ -123,6 +123,24 @@ class UPath(pathlib.Path, PureUPath, metaclass=UPathMeta): _default_accessor = _FSSpecAccessor def __new__(cls, *args, **kwargs): + if len(args) == 1 and isinstance(args[0], cls): + other = args[0] + new_args = ( + other._format_parsed_parts( + other._drv, other._root, other._parts + ), + ) + new_kwargs = {} + if hasattr(other, "_kwargs"): + new_kwargs = other._kwargs.copy() + new_kwargs.pop("_url", None) + + return cls.__new__( + cls, + *new_args, + **new_kwargs, + ) + if issubclass(cls, UPath): args_list = list(args) url = args_list.pop(0) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index 7a9b7e05..bfddcfc2 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -176,3 +176,15 @@ def test_pickling_child_path(): assert path._root == recovered_path._root assert path._parts == recovered_path._parts assert path.fs.storage_options == recovered_path.fs.storage_options + + +def test_copy_path(): + path = UPath("gcs://bucket/folder", anon=True) + copy_path = UPath(path) + + assert type(path) == type(copy_path) + assert str(path) == str(copy_path) + assert path._drv == copy_path._drv + assert path._root == copy_path._root + assert path._parts == copy_path._parts + assert path.fs.storage_options == copy_path.fs.storage_options From 18770d53b43be3c1d60005ebf45b7598f3b86afb Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Sun, 20 Mar 2022 14:20:51 +0100 Subject: [PATCH 2/7] more tests --- upath/tests/cases.py | 11 +++++++++++ upath/tests/test_core.py | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/upath/tests/cases.py b/upath/tests/cases.py index 6968d88b..9ee6a5ff 100644 --- a/upath/tests/cases.py +++ b/upath/tests/cases.py @@ -259,3 +259,14 @@ def test_child_path(self): assert path_a._drv == path_b._drv assert path_a._parts == path_b._parts assert path_a._url == path_b._url + + def test_copy_path(self): + path = self.path + copy_path = UPath(path) + + assert type(path) == type(copy_path) + assert str(path) == str(copy_path) + assert path._drv == copy_path._drv + assert path._root == copy_path._root + assert path._parts == copy_path._parts + assert path.fs.storage_options == copy_path.fs.storage_options diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index bfddcfc2..5fb3a1b2 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -188,3 +188,14 @@ def test_copy_path(): assert path._root == copy_path._root assert path._parts == copy_path._parts assert path.fs.storage_options == copy_path.fs.storage_options + + +def test_copy_path_posix(): + path = UPath("/tmp/folder", anon=True) + copy_path = UPath(path) + + assert type(path) == type(copy_path) + assert str(path) == str(copy_path) + assert path._drv == copy_path._drv + assert path._root == copy_path._root + assert path._parts == copy_path._parts From e282c7b60783254354dd503700d115fb1d8ead0d Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Sun, 20 Mar 2022 14:21:31 +0100 Subject: [PATCH 3/7] more tests --- upath/tests/test_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index 5fb3a1b2..32bd0f1f 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -191,10 +191,10 @@ def test_copy_path(): def test_copy_path_posix(): - path = UPath("/tmp/folder", anon=True) + path = UPath("/tmp/folder") copy_path = UPath(path) - assert type(path) == type(copy_path) + assert type(path) == type(copy_path) == pathlib.PosixPath assert str(path) == str(copy_path) assert path._drv == copy_path._drv assert path._root == copy_path._root From caf94a91a9f93b2bd08882045f453f69d928f77e Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Sun, 20 Mar 2022 14:25:23 +0100 Subject: [PATCH 4/7] fix tests --- upath/tests/test_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index 32bd0f1f..03c1aa9e 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -190,6 +190,7 @@ def test_copy_path(): assert path.fs.storage_options == copy_path.fs.storage_options +@pytest.mark.skipif(sys.platform.startswith("win")) def test_copy_path_posix(): path = UPath("/tmp/folder") copy_path = UPath(path) From b6c4c64fb268091d65fdaf81016ae0a94f7cda1c Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Sun, 20 Mar 2022 14:37:51 +0100 Subject: [PATCH 5/7] fix tests --- upath/tests/test_core.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index 03c1aa9e..a84b8a31 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -190,12 +190,11 @@ def test_copy_path(): assert path.fs.storage_options == copy_path.fs.storage_options -@pytest.mark.skipif(sys.platform.startswith("win")) def test_copy_path_posix(): path = UPath("/tmp/folder") copy_path = UPath(path) - assert type(path) == type(copy_path) == pathlib.PosixPath + assert type(path) == type(copy_path) == type(pathlib.Path("")) assert str(path) == str(copy_path) assert path._drv == copy_path._drv assert path._root == copy_path._root From 4a6b28788cfc1d41aed696ea3240634a3c58c54d Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Thu, 7 Apr 2022 14:39:11 +0200 Subject: [PATCH 6/7] fixes --- upath/core.py | 38 +++++++++++++++++++------------------- upath/tests/test_core.py | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/upath/core.py b/upath/core.py index 7d549a51..d315364a 100644 --- a/upath/core.py +++ b/upath/core.py @@ -123,28 +123,28 @@ class UPath(pathlib.Path, PureUPath, metaclass=UPathMeta): _default_accessor = _FSSpecAccessor def __new__(cls, *args, **kwargs): - if len(args) == 1 and isinstance(args[0], cls): - other = args[0] - new_args = ( - other._format_parsed_parts( - other._drv, other._root, other._parts - ), - ) - new_kwargs = {} - if hasattr(other, "_kwargs"): - new_kwargs = other._kwargs.copy() + if issubclass(cls, UPath): + args_list = list(args) + first = args_list.pop(0) + if isinstance(first, pathlib.PurePath): + # Create a (modified) copy, if first arg is a Path object + other = first + parts = args_list + drv, root, parts = other._parse_args(parts) + drv, root, parts = other._flavour.join_parsed_parts( + other._drv, other._root, other._parts, drv, root, parts + ) + + new_kwargs = getattr(other, "_kwargs", {}).copy() new_kwargs.pop("_url", None) + new_kwargs.update(kwargs) - return cls.__new__( - cls, - *new_args, - **new_kwargs, - ) + return other.__class__( + other._format_parsed_parts(drv, root, parts), + **new_kwargs, + ) - if issubclass(cls, UPath): - args_list = list(args) - url = args_list.pop(0) - url = stringify_path(url) + url = stringify_path(first) parsed_url = urllib.parse.urlparse(url) for key in ["scheme", "netloc"]: val = kwargs.get(key) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index a84b8a31..ee67c858 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -182,6 +182,8 @@ def test_copy_path(): path = UPath("gcs://bucket/folder", anon=True) copy_path = UPath(path) + print(type(path), type(copy_path)) + assert type(path) == type(copy_path) assert str(path) == str(copy_path) assert path._drv == copy_path._drv @@ -199,3 +201,26 @@ def test_copy_path_posix(): assert path._drv == copy_path._drv assert path._root == copy_path._root assert path._parts == copy_path._parts + + +def test_copy_path_append(): + path = UPath("/tmp/folder") + copy_path = UPath(path, "folder2") + + assert type(path) == type(copy_path) == type(pathlib.Path("")) + assert f"{path}/folder2" == str(copy_path) + + path = UPath("/tmp/folder") + copy_path = UPath(path, "folder2/folder3") + + assert f"{path}/folder2/folder3" == str(copy_path) + + +def test_copy_path_append_kwargs(): + path = UPath("gcs://bucket/folder", anon=True) + copy_path = UPath(path, anon=False) + + assert type(path) == type(copy_path) + assert str(path) == str(copy_path) + assert not copy_path._kwargs["anon"] + assert path._kwargs["anon"] From 363f1d754e03747b8dd9a67643102af7970410b6 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Thu, 7 Apr 2022 14:45:04 +0200 Subject: [PATCH 7/7] tests --- upath/tests/test_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upath/tests/test_core.py b/upath/tests/test_core.py index ee67c858..8de66dd8 100644 --- a/upath/tests/test_core.py +++ b/upath/tests/test_core.py @@ -208,12 +208,12 @@ def test_copy_path_append(): copy_path = UPath(path, "folder2") assert type(path) == type(copy_path) == type(pathlib.Path("")) - assert f"{path}/folder2" == str(copy_path) + assert str(path / "folder2") == str(copy_path) path = UPath("/tmp/folder") copy_path = UPath(path, "folder2/folder3") - assert f"{path}/folder2/folder3" == str(copy_path) + assert str(path / "folder2" / "folder3") == str(copy_path) def test_copy_path_append_kwargs():