Skip to content

Commit 00d0bbe

Browse files
committed
type.__getattribute__ should be bound to type!
1 parent 6746784 commit 00d0bbe

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

tests/snippets/class.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,9 @@ def kungfu(x):
2727

2828

2929
bar = Bar()
30-
bar.fubar(2)
3130

32-
# TODO: make below work:
33-
# Bar.fubar(2)
31+
bar.fubar(2)
32+
Bar.fubar(2)
3433

3534
bar.kungfu(3)
36-
# TODO: make below work:
37-
# Bar.kungfu(3)
38-
35+
Bar.kungfu(3)

vm/src/obj/objtype.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn init(context: &PyContext) {
2929
type_type.set_attr("__class__", context.new_member_descriptor(type_new));
3030
type_type.set_attr("__repr__", context.new_rustfunc(type_repr));
3131
type_type.set_attr("__prepare__", context.new_rustfunc(type_prepare));
32+
type_type.set_attr("__getattribute__", context.new_rustfunc(type_getattribute));
3233
}
3334

3435
fn type_mro(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -85,7 +86,7 @@ pub fn get_type_name(typ: &PyObjectRef) -> String {
8586
}
8687

8788
pub fn type_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
88-
debug!("type.__new__{:?}", args);
89+
debug!("type.__new__ {:?}", args);
8990
if args.args.len() == 2 {
9091
arg_check!(
9192
vm,

vm/src/vm.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use super::obj::objsequence;
1717
use super::obj::objstr;
1818
use super::obj::objtype;
1919
use super::pyobject::{
20-
AttributeProtocol, DictProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult,
21-
TypeProtocol,
20+
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef,
21+
PyResult, TypeProtocol,
2222
};
2323
use super::stdlib;
2424
use super::sysmodule;
@@ -93,7 +93,11 @@ impl VirtualMachine {
9393
}
9494

9595
pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef {
96-
self.ctx.new_bound_method(function, object)
96+
if object.is(&self.get_none()) {
97+
function
98+
} else {
99+
self.ctx.new_bound_method(function, object)
100+
}
97101
}
98102

99103
pub fn get_type(&self) -> PyObjectRef {
@@ -202,7 +206,13 @@ impl VirtualMachine {
202206
let cls = obj.typ();
203207
match cls.get_attr(method_name) {
204208
Some(func) => {
205-
trace!("vm.call_method {:?} {:?} -> {:?}", obj, method_name, func);
209+
trace!(
210+
"vm.call_method {:?} {:?} {:?} -> {:?}",
211+
obj,
212+
cls,
213+
method_name,
214+
func
215+
);
206216
let wrapped = self.call_get_descriptor(func, obj.clone())?;
207217
self.invoke(wrapped, args)
208218
}
@@ -423,6 +433,7 @@ impl VirtualMachine {
423433

424434
// get_attribute should be used for full attribute access (usually from user code).
425435
pub fn get_attribute(&mut self, obj: PyObjectRef, attr_name: PyObjectRef) -> PyResult {
436+
trace!("vm.__getattribute__: {:?} {:?}", obj, attr_name);
426437
self.call_method(&obj, "__getattribute__", vec![attr_name])
427438
}
428439

0 commit comments

Comments
 (0)