Skip to content
Prev Previous commit
Next Next commit
Revert 08e66b5
which is not required anymore
  • Loading branch information
youknowone committed Feb 5, 2020
commit 58744df1d594fd06a8211b9c3c1014514b1ed230
65 changes: 1 addition & 64 deletions vm/src/obj/objnone.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use super::objproperty::PyPropertyRef;
use super::objstr::PyStringRef;
use super::objtype::PyClassRef;
use crate::pyobject::{
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;

Expand Down Expand Up @@ -52,66 +49,6 @@ impl PyNone {
Ok(false)
}

#[pymethod(name = "__getattribute__")]
fn get_attribute(zelf: PyRef<Self>, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
vm_trace!("None.__getattribute__({:?}, {:?})", self, name);
let cls = zelf.class();

// Properties use a comparision with None to determine if they are either invoked by am
// instance binding or a class binding. But if the object itself is None then this detection
// won't work. Instead we call a special function on property that bypasses this check, as
// we are invoking it as a instance binding.
//
// In CPython they instead call the slot tp_descr_get with NULL to indicates it's an
// instance binding.
// https://github.com/python/cpython/blob/master/Objects/typeobject.c#L3281
fn call_descriptor(
descriptor: PyObjectRef,
get_func: PyObjectRef,
obj: PyObjectRef,
cls: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
if let Ok(property) = PyPropertyRef::try_from_object(vm, descriptor.clone()) {
property.instance_binding_get(obj, vm)
} else {
vm.invoke(&get_func, vec![descriptor, obj, cls])
}
}

if let Some(attr) = cls.get_attr(name.as_str()) {
let attr_class = attr.class();
if attr_class.has_attr("__set__") {
if let Some(get_func) = attr_class.get_attr("__get__") {
return call_descriptor(
attr,
get_func,
zelf.into_object(),
cls.into_object(),
vm,
);
}
}
}

// None has no attributes and cannot have attributes set on it.
// if let Some(obj_attr) = zelf.as_object().get_attr(name.as_str()) {
// Ok(obj_attr)
// } else
if let Some(attr) = cls.get_attr(name.as_str()) {
let attr_class = attr.class();
if let Some(get_func) = attr_class.get_attr("__get__") {
call_descriptor(attr, get_func, zelf.into_object(), cls.into_object(), vm)
} else {
Ok(attr)
}
} else if let Some(getter) = cls.get_attr("__getattr__") {
vm.invoke(&getter, vec![zelf.into_object(), name.into_object()])
} else {
Err(vm.new_attribute_error(format!("{} has no attribute '{}'", zelf.as_object(), name)))
}
}

#[pymethod(name = "__eq__")]
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
if vm.is_none(&rhs) {
Expand Down
9 changes: 0 additions & 9 deletions vm/src/obj/objproperty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,6 @@ impl PyProperty {

// Descriptor methods

// specialised version that doesn't check for None
pub(crate) fn instance_binding_get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(ref getter) = self.getter.as_ref() {
vm.invoke(getter, obj)
} else {
Err(vm.new_attribute_error("unreadable attribute".to_owned()))
}
}

#[pymethod(name = "__set__")]
fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(ref setter) = self.setter.as_ref() {
Expand Down