Skip to content

Commit

Permalink
os: fix stat_result test
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
deantvv committed Sep 19, 2021
1 parent a006aad commit 96dcd68
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
4 changes: 0 additions & 4 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
6 changes: 6 additions & 0 deletions vm/src/builtins/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Self> {
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()
Expand Down
45 changes: 44 additions & 1 deletion vm/src/stdlib/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -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::<PyTuple>() {
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))]
Expand Down

0 comments on commit 96dcd68

Please sign in to comment.