Skip to content

Commit 2edfe4c

Browse files
committed
Migrate usage of member_descriptor and data_descriptor to
new_property/PropertyBuilder
1 parent 3fe32d0 commit 2edfe4c

File tree

6 files changed

+31
-124
lines changed

6 files changed

+31
-124
lines changed

vm/src/obj/objcode.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn init(context: &PyContext) {
4747
("co_kwonlyargcount", code_co_kwonlyargcount),
4848
("co_name", code_co_name),
4949
] {
50-
context.set_attr(code_type, name, context.new_member_descriptor(f))
50+
context.set_attr(code_type, name, context.new_property(f))
5151
}
5252
}
5353

@@ -83,8 +83,7 @@ fn member_code_obj(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult<byteco
8383
vm,
8484
args,
8585
required = [
86-
(zelf, Some(vm.ctx.code_type())),
87-
(_cls, Some(vm.ctx.type_type()))
86+
(zelf, Some(vm.ctx.code_type()))
8887
]
8988
);
9089
Ok(get_value(zelf))

vm/src/obj/objfunction.rs

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn init(context: &PyContext) {
1010
context.set_attr(
1111
&function_type,
1212
"__code__",
13-
context.new_member_descriptor(function_code),
13+
context.new_property(function_code),
1414
);
1515

1616
let builtin_function_or_method_type = &context.builtin_function_or_method_type;
@@ -20,24 +20,6 @@ pub fn init(context: &PyContext) {
2020
context.new_rustfunc(bind_method),
2121
);
2222

23-
let member_descriptor_type = &context.member_descriptor_type;
24-
context.set_attr(
25-
&member_descriptor_type,
26-
"__get__",
27-
context.new_rustfunc(member_get),
28-
);
29-
30-
let data_descriptor_type = &context.data_descriptor_type;
31-
context.set_attr(
32-
&data_descriptor_type,
33-
"__get__",
34-
context.new_rustfunc(data_get),
35-
);
36-
context.set_attr(
37-
&data_descriptor_type,
38-
"__set__",
39-
context.new_rustfunc(data_set),
40-
);
4123

4224
let classmethod_type = &context.classmethod_type;
4325
context.set_attr(
@@ -85,36 +67,6 @@ fn function_code(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8567
}
8668
}
8769

88-
fn member_get(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
89-
match args.shift().get_attr("function") {
90-
Some(function) => vm.invoke(function, args),
91-
None => {
92-
let attribute_error = vm.context().exceptions.attribute_error.clone();
93-
Err(vm.new_exception(attribute_error, String::from("Attribute Error")))
94-
}
95-
}
96-
}
97-
98-
fn data_get(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
99-
match args.shift().get_attr("fget") {
100-
Some(function) => vm.invoke(function, args),
101-
None => {
102-
let attribute_error = vm.context().exceptions.attribute_error.clone();
103-
Err(vm.new_exception(attribute_error, String::from("Attribute Error")))
104-
}
105-
}
106-
}
107-
108-
fn data_set(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
109-
match args.shift().get_attr("fset") {
110-
Some(function) => vm.invoke(function, args),
111-
None => {
112-
let attribute_error = vm.context().exceptions.attribute_error.clone();
113-
Err(vm.new_exception(attribute_error, String::from("Attribute Error")))
114-
}
115-
}
116-
}
117-
11870
// Classmethod type methods:
11971
fn classmethod_get(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
12072
trace!("classmethod.__get__ {:?}", args.args);

vm/src/obj/objobject.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::pyobject::{
88
use crate::vm::VirtualMachine;
99
use std::cell::RefCell;
1010
use std::collections::HashMap;
11+
use crate::obj::objproperty::PropertyBuilder;
1112

1213
#[derive(Clone, Debug)]
1314
pub struct PyInstance;
@@ -171,7 +172,9 @@ pub fn init(context: &PyContext) {
171172
context.set_attr(
172173
&object,
173174
"__class__",
174-
context.new_data_descriptor(object_class, object_class_setter),
175+
PropertyBuilder::new(context)
176+
.add_getter(object_class)
177+
.add_setter(object_class_setter).create(),
175178
);
176179
context.set_attr(&object, "__eq__", context.new_rustfunc(object_eq));
177180
context.set_attr(&object, "__ne__", context.new_rustfunc(object_ne));
@@ -183,7 +186,7 @@ pub fn init(context: &PyContext) {
183186
context.set_attr(
184187
&object,
185188
"__dict__",
186-
context.new_member_descriptor(object_dict),
189+
context.new_property(object_dict),
187190
);
188191
context.set_attr(&object, "__dir__", context.new_rustfunc(object_dir));
189192
context.set_attr(&object, "__hash__", context.new_rustfunc(object_hash));
@@ -202,9 +205,8 @@ fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
202205
Ok(vm.ctx.none())
203206
}
204207

205-
// TODO Use PyClassRef for owner to enforce type
206-
fn object_class(_obj: PyObjectRef, owner: PyObjectRef, _vm: &mut VirtualMachine) -> PyObjectRef {
207-
owner
208+
fn object_class(obj: PyObjectRef, _vm: &mut VirtualMachine) -> PyObjectRef {
209+
obj.typ()
208210
}
209211

210212
fn object_class_setter(

vm/src/obj/objproperty.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectRef, PyObjectPayload, PyObjectPayload2, PyResult, TypeProtocol};
66
use crate::pyobject::IntoPyNativeFunc;
7-
use crate::obj::objnone::PyNone;
87
use crate::VirtualMachine;
98
use crate::function::PyRef;
109
use std::marker::PhantomData;
10+
use crate::obj::objtype::PyClassRef;
1111

1212
/// Read-only property, doesn't have __set__ or __delete__
1313
#[derive(Debug)]
@@ -24,7 +24,7 @@ impl PyObjectPayload2 for PyReadOnlyProperty {
2424
pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>;
2525

2626
impl PyReadOnlyPropertyRef {
27-
fn get(self, obj: PyObjectRef, _owner: PyObjectRef, vm: &mut VirtualMachine) -> PyResult {
27+
fn get(self, obj: PyObjectRef, _owner: PyClassRef, vm: &mut VirtualMachine) -> PyResult {
2828
vm.invoke(self.getter.clone(), obj)
2929
}
3030
}
@@ -46,7 +46,7 @@ impl PyObjectPayload2 for PyProperty {
4646
pub type PyPropertyRef = PyRef<PyProperty>;
4747

4848
impl PyPropertyRef {
49-
fn get(self, obj: PyObjectRef, _owner: PyObjectRef, vm: &mut VirtualMachine) -> PyResult {
49+
fn get(self, obj: PyObjectRef, _owner: PyClassRef, vm: &mut VirtualMachine) -> PyResult {
5050
if let Some(getter) = self.getter.as_ref() {
5151
vm.invoke(getter.clone(), obj)
5252
} else {
@@ -71,44 +71,40 @@ impl PyPropertyRef {
7171
}
7272
}
7373

74-
pub struct PropertyBuilder<'a, I, T> {
75-
vm: &'a mut VirtualMachine,
74+
pub struct PropertyBuilder<'a, T> {
75+
ctx: &'a PyContext,
7676
getter: Option<PyObjectRef>,
7777
setter: Option<PyObjectRef>,
78-
instance: PhantomData<I>,
7978
_return: PhantomData<T>
8079
}
8180

8281

83-
impl<'a, I, T> PropertyBuilder<'a, I, T> {
84-
pub(crate) fn new(vm: &'a mut VirtualMachine) -> Self {
82+
impl<'a, T> PropertyBuilder<'a, T> {
83+
pub fn new(ctx: &'a PyContext) -> Self {
8584
Self {
86-
vm,
85+
ctx,
8786
getter: None,
8887
setter: None,
89-
instance: PhantomData,
9088
_return: PhantomData
9189
}
9290
}
9391

94-
pub fn add_getter<F:IntoPyNativeFunc<I, T>>(self, func: F) -> Self {
95-
let func = self.vm.ctx.new_rustfunc(func);
92+
pub fn add_getter<I, F:IntoPyNativeFunc<I, T>>(self, func: F) -> Self {
93+
let func = self.ctx.new_rustfunc(func);
9694
Self {
97-
vm: self.vm,
95+
ctx: self.ctx,
9896
getter: Some(func),
9997
setter: self.setter,
100-
instance: PhantomData,
10198
_return: PhantomData
10299
}
103100
}
104101

105-
pub fn add_setter<F:IntoPyNativeFunc<(I, T), PyNone>>(self, func: F) -> Self {
106-
let func = self.vm.ctx.new_rustfunc(func);
102+
pub fn add_setter<I, F:IntoPyNativeFunc<(I, T), PyResult>>(self, func: F) -> Self {
103+
let func = self.ctx.new_rustfunc(func);
107104
Self {
108-
vm: self.vm,
109-
getter: self.setter,
105+
ctx: self.ctx,
106+
getter: self.getter,
110107
setter: Some(func),
111-
instance: PhantomData,
112108
_return: PhantomData
113109
}
114110
}
@@ -125,7 +121,7 @@ impl<'a, I, T> PropertyBuilder<'a, I, T> {
125121
PyObjectPayload::AnyRustValue {
126122
value: Box::new(payload)
127123
},
128-
self.vm.ctx.property_type(),
124+
self.ctx.property_type(),
129125
)
130126
} else {
131127
let payload = PyReadOnlyProperty {
@@ -136,7 +132,7 @@ impl<'a, I, T> PropertyBuilder<'a, I, T> {
136132
PyObjectPayload::AnyRustValue {
137133
value: Box::new(payload)
138134
},
139-
self.vm.ctx.readonly_property_type(),
135+
self.ctx.readonly_property_type(),
140136
)
141137
}
142138
}

vm/src/obj/objtype.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn init(context: &PyContext) {
5353
context.set_attr(
5454
&type_type,
5555
"__mro__",
56-
context.new_member_descriptor(type_mro),
56+
context.new_property(type_mro),
5757
);
5858
context.set_attr(&type_type, "__repr__", context.new_rustfunc(type_repr));
5959
context.set_attr(
@@ -85,8 +85,7 @@ fn type_mro(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8585
vm,
8686
args,
8787
required = [
88-
(cls, Some(vm.ctx.type_type())),
89-
(_typ, Some(vm.ctx.type_type()))
88+
(cls, Some(vm.ctx.type_type()))
9089
]
9190
);
9291
match _mro(cls.clone()) {

vm/src/pyobject.rs

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ pub struct PyContext {
151151
pub readonly_property_type: PyObjectRef,
152152
pub module_type: PyObjectRef,
153153
pub bound_method_type: PyObjectRef,
154-
pub member_descriptor_type: PyObjectRef,
155-
pub data_descriptor_type: PyObjectRef,
156154
pub object: PyObjectRef,
157155
pub exceptions: exceptions::ExceptionZoo,
158156
}
@@ -198,10 +196,6 @@ impl PyContext {
198196
let super_type = create_type("super", &type_type, &object_type, &dict_type);
199197
let generator_type = create_type("generator", &type_type, &object_type, &dict_type);
200198
let bound_method_type = create_type("method", &type_type, &object_type, &dict_type);
201-
let member_descriptor_type =
202-
create_type("member_descriptor", &type_type, &object_type, &dict_type);
203-
let data_descriptor_type =
204-
create_type("data_descriptor", &type_type, &object_type, &dict_type);
205199
let str_type = create_type("str", &type_type, &object_type, &dict_type);
206200
let list_type = create_type("list", &type_type, &object_type, &dict_type);
207201
let set_type = create_type("set", &type_type, &object_type, &dict_type);
@@ -299,8 +293,6 @@ impl PyContext {
299293
generator_type,
300294
module_type,
301295
bound_method_type,
302-
member_descriptor_type,
303-
data_descriptor_type,
304296
type_type,
305297
exceptions,
306298
};
@@ -466,12 +458,6 @@ impl PyContext {
466458
pub fn bound_method_type(&self) -> PyObjectRef {
467459
self.bound_method_type.clone()
468460
}
469-
pub fn member_descriptor_type(&self) -> PyObjectRef {
470-
self.member_descriptor_type.clone()
471-
}
472-
pub fn data_descriptor_type(&self) -> PyObjectRef {
473-
self.data_descriptor_type.clone()
474-
}
475461

476462
pub fn type_type(&self) -> PyObjectRef {
477463
self.type_type.clone()
@@ -640,10 +626,7 @@ impl PyContext {
640626
where
641627
F: IntoPyNativeFunc<T, R>,
642628
{
643-
let fget = self.new_rustfunc(f);
644-
let py_obj = self.new_instance(self.property_type(), None);
645-
self.set_attr(&py_obj, "fget", fget);
646-
py_obj
629+
PropertyBuilder::new(self).add_getter(f).create()
647630
}
648631

649632
pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyObjectRef {
@@ -678,31 +661,6 @@ impl PyContext {
678661
)
679662
}
680663

681-
pub fn new_member_descriptor<F: 'static + Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult>(
682-
&self,
683-
function: F,
684-
) -> PyObjectRef {
685-
let mut dict = PyAttributes::new();
686-
dict.insert("function".to_string(), self.new_rustfunc(function));
687-
self.new_instance(self.member_descriptor_type(), Some(dict))
688-
}
689-
690-
pub fn new_data_descriptor<
691-
G: IntoPyNativeFunc<(I, PyObjectRef), T>,
692-
S: IntoPyNativeFunc<(I, T), PyResult>,
693-
T,
694-
I,
695-
>(
696-
&self,
697-
getter: G,
698-
setter: S,
699-
) -> PyObjectRef {
700-
let mut dict = PyAttributes::new();
701-
dict.insert("fget".to_string(), self.new_rustfunc(getter));
702-
dict.insert("fset".to_string(), self.new_rustfunc(setter));
703-
self.new_instance(self.data_descriptor_type(), Some(dict))
704-
}
705-
706664
pub fn new_instance(&self, class: PyObjectRef, dict: Option<PyAttributes>) -> PyObjectRef {
707665
let dict = if let Some(dict) = dict {
708666
dict
@@ -1292,6 +1250,7 @@ pub enum OptionalArg<T> {
12921250
}
12931251

12941252
use self::OptionalArg::*;
1253+
use crate::obj::objproperty::PropertyBuilder;
12951254

12961255
impl<T> OptionalArg<T> {
12971256
pub fn into_option(self) -> Option<T> {

0 commit comments

Comments
 (0)