Skip to content

Commit 294c68f

Browse files
committed
pyproperty generates PyGetSet instead of PyProperty
1 parent daf1f08 commit 294c68f

File tree

7 files changed

+40
-99
lines changed

7 files changed

+40
-99
lines changed

derive/src/pyclass.rs

Lines changed: 10 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ enum ClassItem {
3636
py_name: String,
3737
setter: bool,
3838
},
39-
GetSet {
40-
item_ident: Ident,
41-
py_name: String,
42-
setter: bool,
43-
},
4439
Slot {
4540
slot_ident: Ident,
4641
item_ident: Ident,
@@ -296,27 +291,6 @@ impl Class {
296291
})
297292
}
298293

299-
fn extract_data(sig: &Signature, meta: Meta) -> Result<ClassItem, Diagnostic> {
300-
let nesteds = meta_to_vec(meta).map_err(|meta| {
301-
err_span!(
302-
meta,
303-
"#[pydata = \"...\"] cannot be a name/value, you probably meant \
304-
#[pydata(name = \"...\")]"
305-
)
306-
})?;
307-
let item_meta = ClassItemMeta::from_nested_meta(
308-
"pydata",
309-
sig,
310-
&nesteds,
311-
ClassItemMeta::PROPERTY_NAMES,
312-
)?;
313-
Ok(ClassItem::GetSet {
314-
py_name: item_meta.property_name()?,
315-
item_ident: sig.ident.clone(),
316-
setter: item_meta.setter()?,
317-
})
318-
}
319-
320294
fn extract_slot(sig: &Signature, meta: Meta) -> Result<ClassItem, Diagnostic> {
321295
let pyslot_err = "#[pyslot] must be of the form #[pyslot] or #[pyslot(slotname)]";
322296
let nesteds = meta_to_vec(meta).map_err(|meta| err_span!(meta, "{}", pyslot_err))?;
@@ -367,8 +341,6 @@ impl Class {
367341
self.add_item(Self::extract_classmethod(sig, meta)?, meta_span)?;
368342
} else if name == "pyproperty" {
369343
self.add_item(Self::extract_property(sig, meta)?, meta_span)?;
370-
} else if name == "pydata" {
371-
self.add_item(Self::extract_data(sig, meta)?, meta_span)?;
372344
} else if name == "pyslot" {
373345
self.add_item(Self::extract_slot(sig, meta)?, meta_span)?;
374346
} else {
@@ -410,57 +382,6 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
410382
);
411383
}
412384

413-
let mut data_items: HashMap<&str, (Option<&Ident>, Option<&Ident>)> = HashMap::new();
414-
for item in class.items.iter() {
415-
if let ClassItem::GetSet {
416-
ref item_ident,
417-
ref py_name,
418-
setter,
419-
} = item
420-
{
421-
let entry = data_items.entry(py_name).or_default();
422-
let func = if *setter { &mut entry.1 } else { &mut entry.0 };
423-
if func.is_some() {
424-
bail_span!(
425-
item_ident,
426-
"Multiple data accessors with name {:?}",
427-
py_name
428-
)
429-
}
430-
*func = Some(item_ident);
431-
}
432-
}
433-
let data_items = data_items
434-
.into_iter()
435-
.map(|(name, data)| {
436-
let getter_func = match data.0 {
437-
Some(func) => func,
438-
None => {
439-
push_err_span!(
440-
diagnostics,
441-
data.0.unwrap(),
442-
"Data {:?} is missing a getter",
443-
name
444-
);
445-
return TokenStream2::new();
446-
}
447-
};
448-
let (new, setter) = match data.1 {
449-
Some(func) => (quote! { with_get_set }, quote! { , &Self::#func }),
450-
None => (quote! { with_get }, quote! { }),
451-
};
452-
let str_name = name.to_string();
453-
quote! {
454-
class.set_str_attr(
455-
#name,
456-
::rustpython_vm::pyobject::PyObject::new(
457-
::rustpython_vm::obj::objgetset::PyGetSet::#new(#str_name.into(), &Self::#getter_func #setter),
458-
ctx.getset_type(), None)
459-
);
460-
}
461-
})
462-
.collect::<Vec<_>>();
463-
464385
let mut properties: HashMap<&str, (Option<&Ident>, Option<&Ident>)> = HashMap::new();
465386
for item in class.items.iter() {
466387
if let ClassItem::Property {
@@ -485,8 +406,8 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
485406
let properties = properties
486407
.into_iter()
487408
.map(|(name, prop)| {
488-
let getter = match prop.0 {
489-
Some(getter) => getter,
409+
let getter_func = match prop.0 {
410+
Some(func) => func,
490411
None => {
491412
push_err_span!(
492413
diagnostics,
@@ -497,14 +418,17 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
497418
return TokenStream2::new();
498419
}
499420
};
500-
let add_setter = prop.1.map(|setter| quote!(.add_setter(Self::#setter)));
421+
let (new, setter) = match prop.1 {
422+
Some(func) => (quote! { with_get_set }, quote! { , &Self::#func }),
423+
None => (quote! { with_get }, quote! { }),
424+
};
425+
let str_name = name.to_string();
501426
quote! {
502427
class.set_str_attr(
503428
#name,
504-
::rustpython_vm::obj::objproperty::PropertyBuilder::new(ctx)
505-
.add_getter(Self::#getter)
506-
#add_setter
507-
.create(),
429+
::rustpython_vm::pyobject::PyObject::new(
430+
::rustpython_vm::obj::objgetset::PyGetSet::#new(#str_name.into(), &Self::#getter_func #setter),
431+
ctx.getset_type(), None)
508432
);
509433
}
510434
})
@@ -553,7 +477,6 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
553477
Ok(quote! {
554478
#(#methods)*
555479
#(#properties)*
556-
#(#data_items)*
557480
})
558481
}
559482

vm/src/exceptions.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,20 @@ impl PyBaseException {
6767
Ok(())
6868
}
6969

70-
#[pydata(name = "args")]
70+
#[pyproperty(name = "args")]
7171
fn get_args(&self, _vm: &VirtualMachine) -> PyTupleRef {
7272
self.args.borrow().clone()
7373
}
7474

75-
#[pydata(setter)]
75+
#[pyproperty(setter)]
7676
fn set_args(&self, args: PyIterable, vm: &VirtualMachine) -> PyResult<()> {
7777
let args = args.iter(vm)?.collect::<PyResult<Vec<_>>>()?;
7878
self.args.replace(PyTuple::from(args).into_ref(vm));
7979
Ok(())
8080
}
8181

8282
#[pyproperty(name = "__traceback__")]
83-
fn get_traceback(&self, _vm: &VirtualMachine) -> Option<PyTracebackRef> {
83+
fn get_traceback(&self) -> Option<PyTracebackRef> {
8484
self.traceback.borrow().clone()
8585
}
8686

@@ -95,8 +95,13 @@ impl PyBaseException {
9595
}
9696

9797
#[pyproperty(name = "__cause__", setter)]
98-
fn setter_cause(&self, cause: Option<PyBaseExceptionRef>, _vm: &VirtualMachine) {
98+
fn setter_cause(
99+
&self,
100+
cause: Option<PyBaseExceptionRef>,
101+
_vm: &VirtualMachine,
102+
) -> PyResult<()> {
99103
self.cause.replace(cause);
104+
Ok(())
100105
}
101106

102107
#[pyproperty(name = "__context__")]
@@ -105,8 +110,13 @@ impl PyBaseException {
105110
}
106111

107112
#[pyproperty(name = "__context__", setter)]
108-
fn setter_context(&self, context: Option<PyBaseExceptionRef>, _vm: &VirtualMachine) {
113+
fn setter_context(
114+
&self,
115+
context: Option<PyBaseExceptionRef>,
116+
_vm: &VirtualMachine,
117+
) -> PyResult<()> {
109118
self.context.replace(context);
119+
Ok(())
110120
}
111121

112122
#[pyproperty(name = "__suppress_context__")]

vm/src/obj/objfloat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,12 +498,12 @@ impl PyFloat {
498498
pyhash::hash_float(self.value)
499499
}
500500

501-
#[pyproperty(name = "real")]
501+
#[pyproperty]
502502
fn real(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyFloatRef {
503503
zelf
504504
}
505505

506-
#[pyproperty(name = "imag")]
506+
#[pyproperty]
507507
fn imag(&self, _vm: &VirtualMachine) -> f64 {
508508
0.0f64
509509
}

vm/src/obj/objfunction.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,17 +249,17 @@ impl PyFunction {
249249
self.invoke(args, vm)
250250
}
251251

252-
#[pyproperty(name = "__code__")]
252+
#[pyproperty(magic)]
253253
fn code(&self, _vm: &VirtualMachine) -> PyCodeRef {
254254
self.code.clone()
255255
}
256256

257-
#[pyproperty(name = "__defaults__")]
257+
#[pyproperty(magic)]
258258
fn defaults(&self, _vm: &VirtualMachine) -> Option<PyTupleRef> {
259259
self.defaults.clone()
260260
}
261261

262-
#[pyproperty(name = "__kwdefaults__")]
262+
#[pyproperty(magic)]
263263
fn kwdefaults(&self, _vm: &VirtualMachine) -> Option<PyDictRef> {
264264
self.kw_only_defaults.clone()
265265
}

vm/src/obj/objint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ impl PyInt {
626626
}
627627
#[pyproperty]
628628
fn real(&self, vm: &VirtualMachine) -> PyObjectRef {
629+
// subclasses must return int here
629630
vm.ctx.new_bigint(&self.value)
630631
}
631632

vm/src/obj/objobject.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,12 @@ impl PyBaseObject {
174174
Ok(vm.ctx.none())
175175
}
176176

177-
#[pydata(name = "__class__")]
177+
#[pyproperty(name = "__class__")]
178178
fn get_class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
179179
obj.class().into_object()
180180
}
181181

182-
#[pydata(name = "__class__", setter)]
182+
#[pyproperty(name = "__class__", setter)]
183183
fn set_class(instance: PyObjectRef, _value: PyObjectRef, vm: &VirtualMachine) -> PySetResult {
184184
let type_repr = vm.to_pystr(&instance.class())?;
185185
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))

vm/src/obj/objtype.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ impl PyClassRef {
145145
.unwrap_or_else(|| vm.ctx.new_str("builtins".to_owned()))
146146
}
147147

148+
#[pyproperty(magic, setter)]
149+
fn set_module(self, value: PyObjectRef) {
150+
self.attributes
151+
.borrow_mut()
152+
.insert("__module__".to_owned(), value);
153+
}
154+
148155
#[pymethod(magic)]
149156
fn prepare(_name: PyStringRef, _bases: PyObjectRef, vm: &VirtualMachine) -> PyDictRef {
150157
vm.ctx.new_dict()

0 commit comments

Comments
 (0)