diff options
-rw-r--r-- | linuxnamespaces/atlocation.py | 35 |
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: |