Add special case handling for __get__(None, NoneType)

This commit is contained in:
Adam Kelly
2018-11-04 20:11:07 +00:00
parent 7bf8378a18
commit a2ce4c8045
3 changed files with 17 additions and 15 deletions

View File

@@ -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 => {

View File

@@ -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 => {

View File

@@ -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()
}