From 4a32c6830ee79a5adf1578b4dc63ee57302a8c76 Mon Sep 17 00:00:00 2001 From: Daniel Oriyan Date: Mon, 24 Jul 2023 18:47:21 +0300 Subject: [PATCH] Added with_stem support (#290) * Added with_stem support * Update readme (+small fix to make_support_table) * Added test * Update history.md * Fallback to trivial CPython implementation if `with_stem` is not available * Add a clarification comment --- HISTORY.md | 1 + README.md | 4 +++- cloudpathlib/cloudpath.py | 7 +++++++ docs/make_support_table.py | 2 +- tests/test_cloudpath_manipulation.py | 7 +++++++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6cb0be69..9ec72101 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ ## UNRELEASED - Add "CloudPath" as return type on `__init__` for mypy issues. ([Issue #179](https://github.com/drivendataorg/cloudpathlib/issues/179), [PR #342](https://github.com/drivendataorg/cloudpathlib/pull/342)) + - Add `with_stem` to all path types when python version supports it (>=3.9). ([Issue #287](https://github.com/drivendataorg/cloudpathlib/issues/287), [PR #290](https://github.com/drivendataorg/cloudpathlib/pull/290), thanks to [@Gilthans](https://github.com/Gilthans)) ## v0.15.1 (2023-07-12) diff --git a/README.md b/README.md index 4e77cb4c..1343a840 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ Most methods and properties from `pathlib.Path` are supported except for the one | `touch` | ✅ | ✅ | ✅ | | `unlink` | ✅ | ✅ | ✅ | | `with_name` | ✅ | ✅ | ✅ | +| `with_stem` | ✅ | ✅ | ✅ | | `with_suffix` | ✅ | ✅ | ✅ | | `write_bytes` | ✅ | ✅ | ✅ | | `write_text` | ✅ | ✅ | ✅ | @@ -184,7 +185,7 @@ Most methods and properties from `pathlib.Path` are supported except for the one | `readlink` | ❌ | ❌ | ❌ | | `root` | ❌ | ❌ | ❌ | | `symlink_to` | ❌ | ❌ | ❌ | -| `with_stem` | ❌ | ❌ | ❌ | +| `clear_cache` | ✅ | ✅ | ✅ | | `cloud_prefix` | ✅ | ✅ | ✅ | | `copy` | ✅ | ✅ | ✅ | | `copytree` | ✅ | ✅ | ✅ | @@ -194,6 +195,7 @@ Most methods and properties from `pathlib.Path` are supported except for the one | `is_valid_cloudpath` | ✅ | ✅ | ✅ | | `rmtree` | ✅ | ✅ | ✅ | | `upload_from` | ✅ | ✅ | ✅ | +| `validate` | ✅ | ✅ | ✅ | | `blob` | ✅ | ❌ | ✅ | | `bucket` | ❌ | ✅ | ✅ | | `container` | ✅ | ❌ | ❌ | diff --git a/cloudpathlib/cloudpath.py b/cloudpathlib/cloudpath.py index 09fdb492..898eaf0b 100644 --- a/cloudpathlib/cloudpath.py +++ b/cloudpathlib/cloudpath.py @@ -759,6 +759,13 @@ def suffix(self) -> str: def suffixes(self) -> List[str]: return self._dispatch_to_path("suffixes") + def with_stem(self, stem: str) -> Self: + try: + return self._dispatch_to_path("with_stem", stem) + except AttributeError: + # with_stem was only added in python 3.9, so we fallback for compatibility + return self.with_name(stem + self.suffix) + def with_name(self, name: str) -> Self: return self._dispatch_to_path("with_name", name) diff --git a/docs/make_support_table.py b/docs/make_support_table.py index f170fc1b..ad06142a 100644 --- a/docs/make_support_table.py +++ b/docs/make_support_table.py @@ -19,7 +19,7 @@ def print_table(): for _cls, methods in lib_methods.items(): all_methods = all_methods.union(methods) - df = pd.DataFrame(index=all_methods) + df = pd.DataFrame(index=list(all_methods)) df.index.name = "Methods + properties" for _cls, methods in lib_methods.items(): diff --git a/tests/test_cloudpath_manipulation.py b/tests/test_cloudpath_manipulation.py index 98c2dfa5..1b405957 100644 --- a/tests/test_cloudpath_manipulation.py +++ b/tests/test_cloudpath_manipulation.py @@ -27,6 +27,13 @@ def test_with_suffix(rig): ) +def test_with_stem(rig): + assert ( + str(rig.create_cloud_path("a/b/c/old.file").with_stem("new")) + == f"{rig.cloud_prefix}{rig.drive}/{rig.test_dir}/a/b/c/new.file" + ) + + def test_no_op_actions(rig): path = rig.create_cloud_path("a/b/c/d.file") assert path == path.absolute()