Skip to content

Commit

Permalink
Fix CloudPath.__truediv__ to return NotImplemented
Browse files Browse the repository at this point in the history
  • Loading branch information
jayqi committed Oct 22, 2024
1 parent 5f5e054 commit 279fa86
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# cloudpathlib Changelog

## Unreleased

- 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))

## v0.20.0 (2024-10-18)

- 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))
Expand Down
2 changes: 1 addition & 1 deletion cloudpathlib/cloudpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,7 @@ def _dispatch_to_path(self, func: str, *args, **kwargs) -> Any:

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

return self._dispatch_to_path("__truediv__", other)

Expand Down
25 changes: 25 additions & 0 deletions tests/test_cloudpath_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,28 @@ def test_parser(rig):
else:
# always posixpath since our dispath goes to PurePosixPath
assert rig.create_cloud_path("a/b/c").parser == posixpath


def test_truediv_fallback(rig):
"""Another class with __rtruediv__ method should be able to use / operator with CloudPath."""

class CustomClassSupportsCloudPath:
def __init__(self, value: str):
self.value = value

def __rtruediv__(self, other):
if isinstance(other, CloudPath):
return other / self.value
return NotImplemented

assert rig.create_cloud_path("a/b") / CustomClassSupportsCloudPath(
"c"
) == rig.create_cloud_path("a/b/c")

# Expect TypeError if / operation with CloudPath is not supported
class CustomClassDoesNotSupportCloudPath:
def __init__(self, value: str):
self.value = value

with pytest.raises(TypeError):
rig.create_cloud_path("a/b") / CustomClassDoesNotSupportCloudPath("c")

0 comments on commit 279fa86

Please sign in to comment.