Skip to content

Commit 7f1a5dc

Browse files
authored
Fix CloudPath.__truediv__ to return NotImplemented (#480)
Co-authored-by: Jay Qi <[email protected]>
1 parent 5f5e054 commit 7f1a5dc

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

HISTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# cloudpathlib Changelog
22

3+
## Unreleased
4+
5+
- Fixed `CloudPath(...) / other` to correctly attempt to fall back on `other`'s `__rtruediv__` implementation, in order to support classes that explicitly support the `/` with a `CloudPath` instance. Previously, this would always raise a `TypeError` if `other` were not a `str` or `PurePosixPath`. (PR [#479](https://github.com/drivendataorg/cloudpathlib/pull/479))
6+
37
## v0.20.0 (2024-10-18)
48

59
- Added support for custom schemes in CloudPath and Client subclases. (Issue [#466](https://github.com/drivendataorg/cloudpathlib/issues/466), PR [#467](https://github.com/drivendataorg/cloudpathlib/pull/467))

cloudpathlib/cloudpath.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ def _dispatch_to_path(self, func: str, *args, **kwargs) -> Any:
888888

889889
def __truediv__(self, other: Union[str, PurePosixPath]) -> Self:
890890
if not isinstance(other, (str, PurePosixPath)):
891-
raise TypeError(f"Can only join path {repr(self)} with strings or posix paths.")
891+
return NotImplemented
892892

893893
return self._dispatch_to_path("__truediv__", other)
894894

tests/test_cloudpath_manipulation.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,28 @@ def test_parser(rig):
204204
else:
205205
# always posixpath since our dispath goes to PurePosixPath
206206
assert rig.create_cloud_path("a/b/c").parser == posixpath
207+
208+
209+
def test_truediv_fallback(rig):
210+
"""Another class with __rtruediv__ method should be able to use / operator with CloudPath."""
211+
212+
class CustomClassSupportsCloudPath:
213+
def __init__(self, value: str):
214+
self.value = value
215+
216+
def __rtruediv__(self, other):
217+
if isinstance(other, CloudPath):
218+
return other / self.value
219+
return NotImplemented
220+
221+
assert rig.create_cloud_path("a/b") / CustomClassSupportsCloudPath(
222+
"c"
223+
) == rig.create_cloud_path("a/b/c")
224+
225+
# Expect TypeError if / operation with CloudPath is not supported
226+
class CustomClassDoesNotSupportCloudPath:
227+
def __init__(self, value: str):
228+
self.value = value
229+
230+
with pytest.raises(TypeError):
231+
rig.create_cloud_path("a/b") / CustomClassDoesNotSupportCloudPath("c")

0 commit comments

Comments
 (0)