From d99f4038e1b30ea06401fd83b69c7ce545ca9229 Mon Sep 17 00:00:00 2001 From: Dean Li Date: Sun, 25 Apr 2021 19:53:06 +0800 Subject: [PATCH] os: Fix `open` keyword arguments Following code used to fail due to the way used to define os.open in rust. To fix this, we need to use `FromArgs` to define `struct OpenArgs {...}`. ``` f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777, dir_fd=None) ``` Noted that the original `open` is now rename to `os_open` and is exported as `open`. Related to #1175 --- Lib/test/test_os.py | 2 -- vm/src/stdlib/io.rs | 8 +------- vm/src/stdlib/os.rs | 24 +++++++++++++++++++++--- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 348d3d104..adaf3b9e3 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -274,8 +274,6 @@ class FileTests(unittest.TestCase): with open(TESTFN2, 'r') as f: self.assertEqual(f.read(), "1") - # TODO: RUSTPYTHON (TypeError: Expected at least 2 arguments (0 given)) - @unittest.expectedFailure def test_open_keywords(self): f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777, dir_fd=None) diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 3541be594..218756fdf 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -2878,13 +2878,7 @@ mod fileio { vm.new_value_error("Cannot use closefd=False with file name".to_owned()) ); } - os::open( - path, - flags as _, - OptionalArg::Missing, - Default::default(), - vm, - )? + os::open(path, flags as _, None, Default::default(), vm)? }; if mode.contains(Mode::APPENDING) { diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 4361500e2..fa2d60040 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -356,12 +356,30 @@ mod _os { } } + #[cfg(any(unix, windows, target_os = "wasi"))] + #[derive(FromArgs)] + struct OpenArgs { + #[pyarg(any)] + path: PyPathLike, + #[pyarg(any)] + flags: OpenFlags, + #[pyarg(any, default)] + mode: Option, + #[pyarg(flatten)] + dir_fd: DirFd, + } + #[cfg(any(unix, windows, target_os = "wasi"))] #[pyfunction] - pub(crate) fn open( + fn open(args: OpenArgs, vm: &VirtualMachine) -> PyResult { + os_open(args.path, args.flags, args.mode, args.dir_fd, vm) + } + + #[cfg(any(unix, windows, target_os = "wasi"))] + pub(crate) fn os_open( name: PyPathLike, flags: OpenFlags, - _mode: OptionalArg, + _mode: Option, dir_fd: DirFd, vm: &VirtualMachine, ) -> PyResult { @@ -1412,7 +1430,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { module } -pub(crate) use _os::open; +pub(crate) use _os::os_open as open; fn to_seconds_from_unix_epoch(sys_time: SystemTime) -> f64 { match sys_time.duration_since(SystemTime::UNIX_EPOCH) {