summaryrefslogtreecommitdiff
path: root/linuxnamespaces/atlocation.py
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2025-05-21 21:24:28 +0200
committerHelmut Grohne <helmut@subdivi.de>2025-05-21 21:24:28 +0200
commit30a111639ce6a7ad54f77a091451bd5354afaae9 (patch)
treeed1de3ae8f3b9d5baf7384d7fdfd71a878529e30 /linuxnamespaces/atlocation.py
parent3d16d57bf63f18b46dd7c440fefa3e9fb8c112f0 (diff)
downloadpython-linuxnamespaces-30a111639ce6a7ad54f77a091451bd5354afaae9.tar.gz
expand use of FileDescriptor and add FileDescriptorLike type alias
When accepting file descriptors, non-int objects with a fileno method are now generally accepted. When returning a file descriptor, a FileDescriptor instance is now returned.
Diffstat (limited to 'linuxnamespaces/atlocation.py')
-rw-r--r--linuxnamespaces/atlocation.py21
1 files changed, 12 insertions, 9 deletions
diff --git a/linuxnamespaces/atlocation.py b/linuxnamespaces/atlocation.py
index 0003c35..d30e88f 100644
--- a/linuxnamespaces/atlocation.py
+++ b/linuxnamespaces/atlocation.py
@@ -15,7 +15,7 @@ import pathlib
import stat
import typing
-from .filedescriptor import FileDescriptor
+from .filedescriptor import FileDescriptor, FileDescriptorLike, HasFileno
AT_FDCWD = FileDescriptor(-100)
@@ -58,7 +58,7 @@ class AtLocation:
def __new__(
cls,
- thing: typing.Union["AtLocation", int, PathConvertible],
+ thing: typing.Union["AtLocation", FileDescriptorLike, PathConvertible],
location: PathConvertible | None = None,
flags: AtFlags = AtFlags.NONE,
) -> "AtLocation":
@@ -76,13 +76,14 @@ class AtLocation:
)
return thing # Don't copy.
obj = super(AtLocation, cls).__new__(cls)
- if isinstance(thing, int):
+ if not isinstance(thing, FileDescriptor):
+ if isinstance(thing, int) or isinstance(thing, HasFileno):
+ thing = FileDescriptor(thing)
+ if isinstance(thing, FileDescriptor):
if thing < 0 and thing != AT_FDCWD:
raise ValueError("fd cannot be negative")
if isinstance(thing, FileDescriptor):
obj.fd = thing
- else:
- obj.fd = FileDescriptor(thing)
if location is None:
obj.location = ""
obj.flags = flags | AtFlags.AT_EMPTY_PATH
@@ -148,7 +149,7 @@ class AtLocation:
them with a slash as separator. The returned AtLocation borrows its fd
if any.
"""
- if isinstance(other, int):
+ if isinstance(other, int) or isinstance(other, HasFileno):
# A an fd is considered an absolute AT_EMPTY_PATH path.
return AtLocation(other)
non_empty_flags = self.flags & ~AtFlags.AT_EMPTY_PATH
@@ -422,7 +423,7 @@ class AtLocation:
assert self.location
os.mknod(self.location, mode, device, dir_fd=self.fd_or_none)
- def open(self, flags: int, mode: int = 0o777) -> int:
+ def open(self, flags: int, mode: int = 0o777) -> FileDescriptor:
"""Wrapper for os.open supplying path and dir_fd."""
if self.flags == AtFlags.AT_SYMLINK_NOFOLLOW:
flags |= os.O_NOFOLLOW
@@ -431,7 +432,9 @@ class AtLocation:
"opening an AtLocation only supports flag AT_SYMLINK_NOFOLLOW"
)
assert self.location
- return os.open(self.location, flags, mode, dir_fd=self.fd_or_none)
+ return FileDescriptor(
+ os.open(self.location, flags, mode, dir_fd=self.fd_or_none)
+ )
def readlink(self) -> str:
"""Wrapper for os.readlink supplying path and dir_fd."""
@@ -595,4 +598,4 @@ class AtLocation:
return f"{cn}({self.fd}, flags={self.flags!r})"
-AtLocationLike = typing.Union[AtLocation, int, PathConvertible]
+AtLocationLike = typing.Union[AtLocation, FileDescriptorLike, PathConvertible]