diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index a024dd167..f508f6e58 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1878,10 +1878,6 @@ class TestInvalidFD(unittest.TestCase): if hasattr(os, f): self.check(getattr(os, f)) - # TODO: RUSTPYTHON; io.FileIO(fd) should check if the fd passed is valid - if f == "fdopen": - # this is test_fdopen - helper = unittest.expectedFailure(helper) return helper for f in singles: diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index a1b86fd5d..d18d8be30 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -8,6 +8,9 @@ cfg_if::cfg_if! { type Offset = i64; } } + +#[cfg(unix)] +use crate::stdlib::os::{errno_err, PathOrFd}; use crate::VirtualMachine; use crate::{PyObjectRef, PyResult, TryFromObject}; pub(crate) use _io::io_open as open; @@ -3571,6 +3574,12 @@ mod _io { } } + // check file descriptor validity + #[cfg(unix)] + if let Ok(PathOrFd::Fd(fd)) = PathOrFd::try_from_object(vm, file.clone()) { + nix::fcntl::fcntl(fd, nix::fcntl::F_GETFD).map_err(|_| errno_err(vm))?; + } + // Construct a FileIO (subclass of RawIOBase) // This is subsequently consumed by a Buffered Class. let file_io_class = { diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index e3b853710..24a883cf1 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -217,7 +217,7 @@ impl TryFromObject for PyPathLike { } } -enum PathOrFd { +pub(crate) enum PathOrFd { Path(PyPathLike), Fd(i32), }