Skip to content

Commit 629b084

Browse files
committed
temp
1 parent 51f96a7 commit 629b084

File tree

10 files changed

+244
-152
lines changed

10 files changed

+244
-152
lines changed

crates/derive-impl/src/pystructseq.rs

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct PyStructSeqMeta {
9393
}
9494

9595
impl ItemMeta for PyStructSeqMeta {
96-
const ALLOWED_NAMES: &'static [&'static str] = &["name", "module"];
96+
const ALLOWED_NAMES: &'static [&'static str] = &["name", "module", "try_from_object"];
9797

9898
fn from_inner(inner: ItemMetaInner) -> Self {
9999
Self { inner }
@@ -155,6 +155,32 @@ impl PyStructSeqMeta {
155155
Ok(None)
156156
}
157157
}
158+
159+
fn try_from_object(&self) -> Result<bool> {
160+
const KEY: &str = "try_from_object";
161+
let inner = self.inner();
162+
if let Some((_, meta)) = inner.meta_map.get(KEY) {
163+
match meta {
164+
Meta::NameValue(syn::MetaNameValue {
165+
value:
166+
syn::Expr::Lit(syn::ExprLit {
167+
lit: syn::Lit::Bool(lit),
168+
..
169+
}),
170+
..
171+
}) => return Ok(lit.value()),
172+
Meta::Path(_) => return Ok(true), // #[pystructseq(try_from_object)] means true
173+
_ => {}
174+
}
175+
bail_span!(
176+
inner.meta_ident,
177+
"#[pystructseq({KEY}=value)] expects a boolean value"
178+
)
179+
} else {
180+
// Default: true for backward compatibility
181+
Ok(true)
182+
}
183+
}
158184
}
159185

160186
/// New attribute macro: #[pystructseq(name = "...", module = "...")]
@@ -164,11 +190,13 @@ pub(crate) fn impl_pystructseq(attr: PunctuatedNestedMeta, item: Item) -> Result
164190
};
165191

166192
let data_ident = struct_item.ident.clone();
193+
let data_vis = struct_item.vis.clone();
167194
let fake_ident = Ident::new("pystructseq", data_ident.span());
168195
let meta = PyStructSeqMeta::from_nested(data_ident.clone(), fake_ident, attr.into_iter())?;
169196

170197
let class_name = meta.class_name()?;
171198
let module_name = meta.module()?;
199+
let try_from_object = meta.try_from_object()?;
172200
let pytype_ident = derive_pytype_name(&data_ident);
173201

174202
// Parse fields from struct
@@ -204,6 +232,28 @@ pub(crate) fn impl_pystructseq(attr: PunctuatedNestedMeta, item: Item) -> Result
204232
class_name.clone()
205233
};
206234

235+
// Generate TryFromObject impl if requested
236+
let try_from_object_impl = if try_from_object {
237+
quote! {
238+
// TryFromObject for Data struct
239+
impl ::rustpython_vm::TryFromObject for #data_ident {
240+
fn try_from_object(vm: &::rustpython_vm::VirtualMachine, seq: ::rustpython_vm::PyObjectRef) -> ::rustpython_vm::PyResult<Self> {
241+
let seq = <#pytype_ident as ::rustpython_vm::types::PyStructSequence>::try_elements_from(seq, vm)?;
242+
let mut iter = seq.into_iter();
243+
Ok(Self {
244+
#(#not_skipped_fields: iter.next().unwrap().clone().try_into_value(vm)?,)*
245+
#(#skipped_fields: match iter.next() {
246+
Some(v) => v.clone().try_into_value(vm)?,
247+
None => vm.ctx.none(),
248+
},)*
249+
})
250+
}
251+
}
252+
}
253+
} else {
254+
quote! {}
255+
};
256+
207257
// Generate the output
208258
let output = quote! {
209259
// Original Data struct (with #[pystruct] attrs removed from fields)
@@ -239,24 +289,11 @@ pub(crate) fn impl_pystructseq(attr: PunctuatedNestedMeta, item: Item) -> Result
239289
}
240290
}
241291

242-
// TryFromObject for Data struct
243-
impl ::rustpython_vm::TryFromObject for #data_ident {
244-
fn try_from_object(vm: &::rustpython_vm::VirtualMachine, seq: ::rustpython_vm::PyObjectRef) -> ::rustpython_vm::PyResult<Self> {
245-
let seq = <#pytype_ident as ::rustpython_vm::types::PyStructSequence>::try_elements_from(seq, vm)?;
246-
let mut iter = seq.into_iter();
247-
Ok(Self {
248-
#(#not_skipped_fields: iter.next().unwrap().clone().try_into_value(vm)?,)*
249-
#(#skipped_fields: match iter.next() {
250-
Some(v) => v.clone().try_into_value(vm)?,
251-
None => vm.ctx.none(),
252-
},)*
253-
})
254-
}
255-
}
292+
#try_from_object_impl
256293

257294
// Empty Python type struct
258295
#[doc(hidden)]
259-
pub struct #pytype_ident;
296+
#data_vis struct #pytype_ident;
260297

261298
// PyClassDef for Python type
262299
impl ::rustpython_vm::class::PyClassDef for #pytype_ident {

crates/stdlib/src/grp.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,38 @@ pub(crate) use grp::make_module;
55
mod grp {
66
use crate::vm::{
77
PyObjectRef, PyResult, VirtualMachine,
8-
builtins::{PyIntRef, PyListRef, PyStrRef},
8+
builtins::{PyIntRef, PyListRef, PyStrRef, PyTypeRef},
9+
class::PyClassImpl,
910
convert::{IntoPyException, ToPyObject},
1011
exceptions,
11-
types::PyStructSequenceLegacy,
12+
types::PyStructSequence,
1213
};
1314
use nix::unistd;
1415
use std::ptr::NonNull;
1516

16-
#[pyattr]
17-
#[pyclass(module = "grp", name = "struct_group", traverse)]
18-
#[derive(PyStructSequence)]
19-
struct Group {
20-
#[pytraverse(skip)]
17+
#[pystructseq(name = "struct_group", module = "grp")]
18+
struct GroupData {
2119
gr_name: String,
22-
#[pytraverse(skip)]
2320
gr_passwd: String,
24-
#[pytraverse(skip)]
2521
gr_gid: u32,
2622
gr_mem: PyListRef,
2723
}
28-
#[pyclass(with(PyStructSequenceLegacy))]
29-
impl Group {
24+
25+
#[pyattr]
26+
fn struct_group(vm: &VirtualMachine) -> PyTypeRef {
27+
PyGroup::make_class(&vm.ctx)
28+
}
29+
30+
#[pyclass(with(PyStructSequence))]
31+
impl PyGroup {}
32+
33+
impl GroupData {
3034
fn from_unistd_group(group: unistd::Group, vm: &VirtualMachine) -> Self {
3135
let cstr_lossy = |s: std::ffi::CString| {
3236
s.into_string()
3337
.unwrap_or_else(|e| e.into_cstring().to_string_lossy().into_owned())
3438
};
35-
Group {
39+
GroupData {
3640
gr_name: group.name,
3741
gr_passwd: cstr_lossy(group.passwd),
3842
gr_gid: group.gid.as_raw(),
@@ -44,7 +48,7 @@ mod grp {
4448
}
4549

4650
#[pyfunction]
47-
fn getgrgid(gid: PyIntRef, vm: &VirtualMachine) -> PyResult<Group> {
51+
fn getgrgid(gid: PyIntRef, vm: &VirtualMachine) -> PyResult<GroupData> {
4852
let gr_gid = gid.as_bigint();
4953
let gid = libc::gid_t::try_from(gr_gid)
5054
.map(unistd::Gid::from_raw)
@@ -61,11 +65,11 @@ mod grp {
6165
.into(),
6266
)
6367
})?;
64-
Ok(Group::from_unistd_group(group, vm))
68+
Ok(GroupData::from_unistd_group(group, vm))
6569
}
6670

6771
#[pyfunction]
68-
fn getgrnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult<Group> {
72+
fn getgrnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult<GroupData> {
6973
let gr_name = name.as_str();
7074
if gr_name.contains('\0') {
7175
return Err(exceptions::cstring_error(vm));
@@ -78,7 +82,7 @@ mod grp {
7882
.into(),
7983
)
8084
})?;
81-
Ok(Group::from_unistd_group(group, vm))
85+
Ok(GroupData::from_unistd_group(group, vm))
8286
}
8387

8488
#[pyfunction]
@@ -91,7 +95,7 @@ mod grp {
9195
unsafe { libc::setgrent() };
9296
while let Some(ptr) = NonNull::new(unsafe { libc::getgrent() }) {
9397
let group = unistd::Group::from(unsafe { ptr.as_ref() });
94-
let group = Group::from_unistd_group(group, vm).to_pyobject(vm);
98+
let group = GroupData::from_unistd_group(group, vm).to_pyobject(vm);
9599
list.push(group);
96100
}
97101
unsafe { libc::endgrent() };

crates/stdlib/src/resource.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ pub(crate) use resource::make_module;
66
mod resource {
77
use crate::vm::{
88
PyObject, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine,
9+
builtins::PyTypeRef,
10+
class::PyClassImpl,
911
convert::{ToPyException, ToPyObject},
1012
stdlib::os,
11-
types::PyStructSequenceLegacy,
13+
types::PyStructSequence,
1214
};
1315
use std::{io, mem};
1416

@@ -63,10 +65,8 @@ mod resource {
6365
#[pyattr]
6466
use libc::{RUSAGE_CHILDREN, RUSAGE_SELF};
6567

66-
#[pyattr]
67-
#[pyclass(name = "struct_rusage")]
68-
#[derive(PyStructSequence)]
69-
struct Rusage {
68+
#[pystructseq(name = "struct_rusage", module = "resource")]
69+
struct RusageData {
7070
ru_utime: f64,
7171
ru_stime: f64,
7272
ru_maxrss: libc::c_long,
@@ -85,10 +85,15 @@ mod resource {
8585
ru_nivcsw: libc::c_long,
8686
}
8787

88-
#[pyclass(with(PyStructSequenceLegacy))]
89-
impl Rusage {}
88+
#[pyattr]
89+
fn struct_rusage(vm: &VirtualMachine) -> PyTypeRef {
90+
PyRusage::make_class(&vm.ctx)
91+
}
92+
93+
#[pyclass(with(PyStructSequence))]
94+
impl PyRusage {}
9095

91-
impl From<libc::rusage> for Rusage {
96+
impl From<libc::rusage> for RusageData {
9297
fn from(rusage: libc::rusage) -> Self {
9398
let tv = |tv: libc::timeval| tv.tv_sec as f64 + (tv.tv_usec as f64 / 1_000_000.0);
9499
Self {
@@ -113,7 +118,7 @@ mod resource {
113118
}
114119

115120
#[pyfunction]
116-
fn getrusage(who: i32, vm: &VirtualMachine) -> PyResult<Rusage> {
121+
fn getrusage(who: i32, vm: &VirtualMachine) -> PyResult<RusageData> {
117122
let res = unsafe {
118123
let mut rusage = mem::MaybeUninit::<libc::rusage>::uninit();
119124
if libc::getrusage(who, rusage.as_mut_ptr()) == -1 {
@@ -122,7 +127,7 @@ mod resource {
122127
Ok(rusage.assume_init())
123128
}
124129
};
125-
res.map(Rusage::from).map_err(|e| {
130+
res.map(RusageData::from).map_err(|e| {
126131
if e.kind() == io::ErrorKind::InvalidInput {
127132
vm.new_value_error("invalid who parameter")
128133
} else {

crates/vm/src/stdlib/nt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ pub(crate) mod module {
179179
fn get_terminal_size(
180180
fd: OptionalArg<i32>,
181181
vm: &VirtualMachine,
182-
) -> PyResult<_os::PyTerminalSize> {
182+
) -> PyResult<_os::TerminalSizeData> {
183183
let (columns, lines) = {
184184
let stdhandle = match fd {
185185
OptionalArg::Present(0) => Console::STD_INPUT_HANDLE,
@@ -206,7 +206,7 @@ pub(crate) mod module {
206206
(w.Bottom - w.Top + 1) as usize,
207207
)
208208
};
209-
Ok(_os::PyTerminalSize { columns, lines })
209+
Ok(_os::TerminalSizeData { columns, lines })
210210
}
211211

212212
#[cfg(target_env = "msvc")]

0 commit comments

Comments
 (0)