Skip to content

Commit 96dcd68

Browse files
committed
os: fix stat_result test
Implement tp_new for `stat_result` To unpack args, this PR implement a `flatten_args` closure to unpack args like ``` args = (1, 2, 3, 4, 5) args = ((1, 2, 3, 4, 5)) args = (((1, 2, 3, 4, 5))) # from pickle load ```
1 parent a006aad commit 96dcd68

3 files changed

Lines changed: 50 additions & 5 deletions

File tree

‎Lib/test/test_os.py‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,9 @@ def trunc(x): return x
443443
except TypeError:
444444
pass
445445

446-
# TODO: RUSTPYTHON
447-
@unittest.expectedFailure
448446
def test_stat_attributes(self):
449447
self.check_stat_attributes(self.fname)
450448

451-
# TODO: RUSTPYTHON
452-
@unittest.expectedFailure
453449
def test_stat_attributes_bytes(self):
454450
try:
455451
fname = self.fname.encode(sys.getfilesystemencoding())

‎vm/src/builtins/int.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ impl_try_from_object_int!(
118118
(u64, to_u64),
119119
);
120120

121+
impl TryFromBorrowedObject for BigInt {
122+
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Self> {
123+
try_value_from_borrowed_object(vm, obj, |int: &PyInt| Ok(int.as_bigint().clone()))
124+
}
125+
}
126+
121127
// _PyLong_AsUnsignedLongMask
122128
pub fn bigint_unsigned_mask(v: &BigInt) -> u32 {
123129
v.to_u32()

‎vm/src/stdlib/os.rs‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::{env, fs};
99

1010
use crate::crt_fd::Fd;
1111
use crossbeam_utils::atomic::AtomicCell;
12+
use itertools::Itertools;
1213
use num_bigint::BigInt;
1314
#[cfg(unix)]
1415
use strum_macros::EnumString;
@@ -1042,24 +1043,40 @@ mod _os {
10421043

10431044
#[pyattr]
10441045
#[pyclass(module = "os", name = "stat_result")]
1045-
#[derive(Debug, PyStructSequence)]
1046+
#[derive(Debug, PyStructSequence, FromArgs)]
10461047
struct StatResult {
1048+
#[pyarg(any)]
10471049
pub st_mode: BigInt,
1050+
#[pyarg(any)]
10481051
pub st_ino: BigInt,
1052+
#[pyarg(any)]
10491053
pub st_dev: BigInt,
1054+
#[pyarg(any)]
10501055
pub st_nlink: BigInt,
1056+
#[pyarg(any)]
10511057
pub st_uid: BigInt,
1058+
#[pyarg(any)]
10521059
pub st_gid: BigInt,
1060+
#[pyarg(any)]
10531061
pub st_size: BigInt,
10541062
// TODO: unnamed structsequence fields
1063+
#[pyarg(positional, default)]
10551064
pub __st_atime_int: BigInt,
1065+
#[pyarg(positional, default)]
10561066
pub __st_mtime_int: BigInt,
1067+
#[pyarg(positional, default)]
10571068
pub __st_ctime_int: BigInt,
1069+
#[pyarg(any, default)]
10581070
pub st_atime: f64,
1071+
#[pyarg(any, default)]
10591072
pub st_mtime: f64,
1073+
#[pyarg(any, default)]
10601074
pub st_ctime: f64,
1075+
#[pyarg(any, default)]
10611076
pub st_atime_ns: BigInt,
1077+
#[pyarg(any, default)]
10621078
pub st_mtime_ns: BigInt,
1079+
#[pyarg(any, default)]
10631080
pub st_ctime_ns: BigInt,
10641081
}
10651082

@@ -1102,6 +1119,32 @@ mod _os {
11021119
st_ctime_ns: to_ns(ctime).into(),
11031120
}
11041121
}
1122+
1123+
#[pyslot]
1124+
fn tp_new(_cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
1125+
let flatten_args = |r: &[PyObjectRef]| {
1126+
let mut vec_args = Vec::from(r);
1127+
loop {
1128+
if let Ok(obj) = vec_args.iter().exactly_one() {
1129+
match obj.payload::<PyTuple>() {
1130+
Some(t) => {
1131+
vec_args = Vec::from(t.as_slice());
1132+
}
1133+
None => {
1134+
return vec_args;
1135+
}
1136+
}
1137+
} else {
1138+
return vec_args;
1139+
}
1140+
}
1141+
};
1142+
1143+
let args: FuncArgs = flatten_args(args.args.as_slice()).into();
1144+
1145+
let stat: StatResult = args.bind(vm)?;
1146+
Ok(stat.into_pyobject(vm))
1147+
}
11051148
}
11061149

11071150
#[cfg(not(windows))]

0 commit comments

Comments
 (0)