From a2ce4c8045cfa22b6db005e893ea083bcdd8321e Mon Sep 17 00:00:00 2001 From: Adam Kelly Date: Sun, 4 Nov 2018 20:11:07 +0000 Subject: [PATCH] Add special case handling for __get__(None, NoneType) --- vm/src/obj/objfunction.rs | 18 ++++++++++++++---- vm/src/obj/objproperty.rs | 2 +- vm/src/vm.rs | 12 ++---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index d4e4dafce2..955f2643e5 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -1,6 +1,6 @@ use super::super::pyobject::{ - AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult, - TypeProtocol, + AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, + PyResult, TypeProtocol, }; use super::super::vm::VirtualMachine; use super::objtype; @@ -22,7 +22,17 @@ pub fn init(context: &PyContext) { } fn bind_method(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - Ok(vm.new_bound_method(args.args[0].clone(), args.args[1].clone())) + arg_check!( + vm, + args, + required = [(function, None), (obj, None), (cls, None)] + ); + + if obj.is(&vm.get_none()) && !cls.is(&obj.typ()) { + Ok(function.clone()) + } else { + Ok(vm.ctx.new_bound_method(function.clone(), obj.clone())) + } } fn member_get(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult { @@ -50,7 +60,7 @@ fn classmethod_get(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { match cls.get_attr("function") { Some(function) => { let py_obj = owner.clone(); - let py_method = vm.new_bound_method(function, py_obj); + let py_method = vm.ctx.new_bound_method(function, py_obj); Ok(py_method) } None => { diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index d2972a2686..1876915cb0 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -31,7 +31,7 @@ fn property_get(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { match cls.get_attr("fget") { Some(getter) => { - let py_method = vm.new_bound_method(getter, inst.clone()); + let py_method = vm.ctx.new_bound_method(getter, inst.clone()); vm.invoke(py_method, PyFuncArgs::default()) } None => { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 5f73ffe4cb..17c89ba0b6 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -17,8 +17,8 @@ use super::obj::objsequence; use super::obj::objstr; use super::obj::objtype; use super::pyobject::{ - AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, - PyResult, TypeProtocol, + AttributeProtocol, DictProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, + TypeProtocol, }; use super::stdlib; use super::sysmodule; @@ -92,14 +92,6 @@ impl VirtualMachine { self.ctx.none() } - pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef { - if object.is(&self.get_none()) { - function - } else { - self.ctx.new_bound_method(function, object) - } - } - pub fn get_type(&self) -> PyObjectRef { self.ctx.type_type() }