diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 2ac32c0cb2..2cb820f8a8 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -443,13 +443,9 @@ def trunc(x): return x except TypeError: pass - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_stat_attributes(self): self.check_stat_attributes(self.fname) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_stat_attributes_bytes(self): try: fname = self.fname.encode(sys.getfilesystemencoding()) diff --git a/vm/src/builtins/int.rs b/vm/src/builtins/int.rs index ae4298919b..54724bcd8a 100644 --- a/vm/src/builtins/int.rs +++ b/vm/src/builtins/int.rs @@ -118,6 +118,12 @@ impl_try_from_object_int!( (u64, to_u64), ); +impl TryFromBorrowedObject for BigInt { + fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { + try_value_from_borrowed_object(vm, obj, |int: &PyInt| Ok(int.as_bigint().clone())) + } +} + // _PyLong_AsUnsignedLongMask pub fn bigint_unsigned_mask(v: &BigInt) -> u32 { v.to_u32() diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index c1dcf74cc8..5fd976b60d 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -9,6 +9,7 @@ use std::{env, fs}; use crate::crt_fd::Fd; use crossbeam_utils::atomic::AtomicCell; +use itertools::Itertools; use num_bigint::BigInt; #[cfg(unix)] use strum_macros::EnumString; @@ -1042,24 +1043,40 @@ mod _os { #[pyattr] #[pyclass(module = "os", name = "stat_result")] - #[derive(Debug, PyStructSequence)] + #[derive(Debug, PyStructSequence, FromArgs)] struct StatResult { + #[pyarg(any)] pub st_mode: BigInt, + #[pyarg(any)] pub st_ino: BigInt, + #[pyarg(any)] pub st_dev: BigInt, + #[pyarg(any)] pub st_nlink: BigInt, + #[pyarg(any)] pub st_uid: BigInt, + #[pyarg(any)] pub st_gid: BigInt, + #[pyarg(any)] pub st_size: BigInt, // TODO: unnamed structsequence fields + #[pyarg(positional, default)] pub __st_atime_int: BigInt, + #[pyarg(positional, default)] pub __st_mtime_int: BigInt, + #[pyarg(positional, default)] pub __st_ctime_int: BigInt, + #[pyarg(any, default)] pub st_atime: f64, + #[pyarg(any, default)] pub st_mtime: f64, + #[pyarg(any, default)] pub st_ctime: f64, + #[pyarg(any, default)] pub st_atime_ns: BigInt, + #[pyarg(any, default)] pub st_mtime_ns: BigInt, + #[pyarg(any, default)] pub st_ctime_ns: BigInt, } @@ -1102,6 +1119,32 @@ mod _os { st_ctime_ns: to_ns(ctime).into(), } } + + #[pyslot] + fn tp_new(_cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { + let flatten_args = |r: &[PyObjectRef]| { + let mut vec_args = Vec::from(r); + loop { + if let Ok(obj) = vec_args.iter().exactly_one() { + match obj.payload::() { + Some(t) => { + vec_args = Vec::from(t.as_slice()); + } + None => { + return vec_args; + } + } + } else { + return vec_args; + } + } + }; + + let args: FuncArgs = flatten_args(args.args.as_slice()).into(); + + let stat: StatResult = args.bind(vm)?; + Ok(stat.into_pyobject(vm)) + } } #[cfg(not(windows))]