Skip to content

Commit f8a9ff5

Browse files
Merge pull request #52 from scalableminds/copy-upath
adds copy-constructor to UPath
2 parents ab48c4d + 363f1d7 commit f8a9ff5

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

upath/core.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,26 @@ class UPath(pathlib.Path, PureUPath, metaclass=UPathMeta):
119119
def __new__(cls, *args, **kwargs):
120120
if issubclass(cls, UPath):
121121
args_list = list(args)
122-
url = args_list.pop(0)
123-
url = stringify_path(url)
122+
first = args_list.pop(0)
123+
if isinstance(first, pathlib.PurePath):
124+
# Create a (modified) copy, if first arg is a Path object
125+
other = first
126+
parts = args_list
127+
drv, root, parts = other._parse_args(parts)
128+
drv, root, parts = other._flavour.join_parsed_parts(
129+
other._drv, other._root, other._parts, drv, root, parts
130+
)
131+
132+
new_kwargs = getattr(other, "_kwargs", {}).copy()
133+
new_kwargs.pop("_url", None)
134+
new_kwargs.update(kwargs)
135+
136+
return other.__class__(
137+
other._format_parsed_parts(drv, root, parts),
138+
**new_kwargs,
139+
)
140+
141+
url = stringify_path(first)
124142
parsed_url = urllib.parse.urlparse(url)
125143
for key in ["scheme", "netloc"]:
126144
val = kwargs.get(key)

upath/tests/cases.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,14 @@ def test_child_path(self):
253253
assert path_a._drv == path_b._drv
254254
assert path_a._parts == path_b._parts
255255
assert path_a._url == path_b._url
256+
257+
def test_copy_path(self):
258+
path = self.path
259+
copy_path = UPath(path)
260+
261+
assert type(path) == type(copy_path)
262+
assert str(path) == str(copy_path)
263+
assert path._drv == copy_path._drv
264+
assert path._root == copy_path._root
265+
assert path._parts == copy_path._parts
266+
assert path.fs.storage_options == copy_path.fs.storage_options

upath/tests/test_core.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,51 @@ def test_pickling_child_path():
176176
assert path._root == recovered_path._root
177177
assert path._parts == recovered_path._parts
178178
assert path.fs.storage_options == recovered_path.fs.storage_options
179+
180+
181+
def test_copy_path():
182+
path = UPath("gcs://bucket/folder", anon=True)
183+
copy_path = UPath(path)
184+
185+
print(type(path), type(copy_path))
186+
187+
assert type(path) == type(copy_path)
188+
assert str(path) == str(copy_path)
189+
assert path._drv == copy_path._drv
190+
assert path._root == copy_path._root
191+
assert path._parts == copy_path._parts
192+
assert path.fs.storage_options == copy_path.fs.storage_options
193+
194+
195+
def test_copy_path_posix():
196+
path = UPath("/tmp/folder")
197+
copy_path = UPath(path)
198+
199+
assert type(path) == type(copy_path) == type(pathlib.Path(""))
200+
assert str(path) == str(copy_path)
201+
assert path._drv == copy_path._drv
202+
assert path._root == copy_path._root
203+
assert path._parts == copy_path._parts
204+
205+
206+
def test_copy_path_append():
207+
path = UPath("/tmp/folder")
208+
copy_path = UPath(path, "folder2")
209+
210+
assert type(path) == type(copy_path) == type(pathlib.Path(""))
211+
assert str(path / "folder2") == str(copy_path)
212+
213+
path = UPath("/tmp/folder")
214+
copy_path = UPath(path, "folder2/folder3")
215+
216+
assert str(path / "folder2" / "folder3") == str(copy_path)
217+
218+
219+
def test_copy_path_append_kwargs():
220+
path = UPath("gcs://bucket/folder", anon=True)
221+
copy_path = UPath(path, anon=False)
222+
223+
assert type(path) == type(copy_path)
224+
assert str(path) == str(copy_path)
225+
assert not copy_path._kwargs["anon"]
226+
assert path._kwargs["anon"]

0 commit comments

Comments
 (0)