summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linuxnamespaces/atlocation.py35
1 files changed, 25 insertions, 10 deletions
diff --git a/linuxnamespaces/atlocation.py b/linuxnamespaces/atlocation.py
index 04e5852..79f55bb 100644
--- a/linuxnamespaces/atlocation.py
+++ b/linuxnamespaces/atlocation.py
@@ -126,21 +126,36 @@ class AtLocation:
self.fd, self.location, self.flags & ~AtFlags.AT_NO_AUTOMOUNT
)
- def joinpath(self, name: PathConvertible) -> "AtLocation":
+ def joinpath(self, other: "AtLocationLike") -> "AtLocation":
"""Combine an AtLocation and a path by doing the equivalent of joining
- them with a slash as separator.
+ them with a slash as separator. The returned AtLocation borrows its fd
+ if any.
"""
- if self.flags & AtFlags.AT_EMPTY_PATH:
- return AtLocation(
- self.fd, name, self.flags & ~AtFlags.AT_EMPTY_PATH
- )
- if not self.location:
- return AtLocation(self.fd, name, self.flags)
+ if isinstance(other, int):
+ # A an fd is considered an absolute AT_EMPTY_PATH path.
+ return AtLocation(other)
+ non_empty_flags = self.flags & ~AtFlags.AT_EMPTY_PATH
+ if isinstance(other, AtLocation):
+ if other.is_absolute():
+ # Absolute path trumps self.
+ return other
+ if non_empty_flags != other.flags:
+ raise ValueError(
+ "cannot join AtLocations with differing flags"
+ )
+ other = other.location
+ if not other:
+ return self
+ elif pathlib.Path(other).is_absolute():
+ return AtLocation(other, flags=non_empty_flags)
+ # other now is a PathConvertible that isn't absolute.
+ if self.flags & AtFlags.AT_EMPTY_PATH or not self.location:
+ return AtLocation(self.fd, other, non_empty_flags)
return AtLocation(
- self.fd, pathlib.Path(self.location).joinpath(name), self.flags
+ self.fd, pathlib.Path(self.location).joinpath(other), self.flags
)
- def __truediv__(self, name: PathConvertible) -> "AtLocation":
+ def __truediv__(self, name: "AtLocationLike") -> "AtLocation":
return self.joinpath(name)
def fileno(self) -> int: