Skip to content
Merged
Prev Previous commit
Next Next commit
compatiibility for CPytthon descr_check
  • Loading branch information
youknowone committed Feb 5, 2020
commit 23381b9937e6ce241eb17d7ce056483562293340
7 changes: 6 additions & 1 deletion derive/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,13 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
slot_ident,
item_ident,
} => {
let transform = if vec!["new", "call"].contains(&slot_ident.to_string().as_str()) {
quote! { ::rustpython_vm::function::IntoPyNativeFunc::into_func }
} else {
quote! { Box::new }
};
let into_func = quote_spanned! {item_ident.span()=>
::rustpython_vm::function::IntoPyNativeFunc::into_func(Self::#item_ident)
#transform(Self::#item_ident)
};
Some(quote! {
(*class.slots.borrow_mut()).#slot_ident = Some(#into_func);
Expand Down
4 changes: 4 additions & 0 deletions tests/snippets/types_snippet.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ class C(B, BB):
pass

assert C.mro() == [C, B, A, BB, AA, object]


assert type(Exception.args).__name__ == 'getset_descriptor'
assert type(None).__bool__(None) is False
26 changes: 15 additions & 11 deletions vm/src/obj/objbuiltinfunc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::fmt;
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::{PyBuiltinCallable, PyBuiltinDescriptor};
use crate::slots::{SlotCall, SlotDescriptor};
use crate::vm::VirtualMachine;

#[pyclass]
Expand Down Expand Up @@ -35,13 +35,13 @@ impl PyBuiltinFunction {
}
}

impl PyBuiltinCallable for PyBuiltinFunction {
impl SlotCall for PyBuiltinFunction {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
(self.value)(vm, args)
}
}

#[pyimpl(with(PyBuiltinCallable))]
#[pyimpl(with(SlotCall))]
impl PyBuiltinFunction {}

#[pyclass]
Expand Down Expand Up @@ -73,13 +73,17 @@ impl PyBuiltinMethod {
}
}

impl PyBuiltinDescriptor for PyBuiltinMethod {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyBuiltinMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
};
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
Ok(zelf.into_object())
} else {
Expand All @@ -88,13 +92,13 @@ impl PyBuiltinDescriptor for PyBuiltinMethod {
}
}

impl PyBuiltinCallable for PyBuiltinMethod {
impl SlotCall for PyBuiltinMethod {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
(self.function.value)(vm, args)
}
}

#[pyimpl(with(PyBuiltinDescriptor, PyBuiltinCallable))]
#[pyimpl(with(SlotDescriptor, SlotCall))]
impl PyBuiltinMethod {}

pub fn init(context: &PyContext) {
Expand Down
15 changes: 8 additions & 7 deletions vm/src/obj/objclassmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::function::OptionalArg;
use crate::pyobject::{
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;

/// classmethod(function) -> method
Expand Down Expand Up @@ -47,19 +47,20 @@ impl PyValue for PyClassMethod {
}
}

impl PyBuiltinDescriptor for PyClassMethod {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyClassMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
let cls = cls.unwrap_or_else(|| obj.class().into_object());
Ok(vm.ctx.new_bound_method(zelf.callable.clone(), cls))
}
}

#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyClassMethod {
#[pyslot]
fn tp_new(
Expand Down
19 changes: 10 additions & 9 deletions vm/src/obj/objfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::pyobject::{
TypeProtocol,
};
use crate::scope::Scope;
use crate::slots::{PyBuiltinCallable, PyBuiltinDescriptor};
use crate::slots::{SlotCall, SlotDescriptor};
use crate::vm::VirtualMachine;

pub type PyFunctionRef = PyRef<PyFunction>;
Expand All @@ -27,13 +27,14 @@ pub struct PyFunction {
kw_only_defaults: Option<PyDictRef>,
}

impl PyBuiltinDescriptor for PyFunction {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyFunction {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
Ok(zelf.into_object())
} else {
Expand Down Expand Up @@ -240,7 +241,7 @@ impl PyValue for PyFunction {
}
}

#[pyimpl(with(PyBuiltinDescriptor))]
#[pyimpl(with(SlotDescriptor))]
impl PyFunction {
#[pyslot]
#[pymethod(magic)]
Expand Down Expand Up @@ -272,7 +273,7 @@ pub struct PyBoundMethod {
pub function: PyObjectRef,
}

impl PyBuiltinCallable for PyBoundMethod {
impl SlotCall for PyBoundMethod {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
let args = args.insert(self.object.clone());
vm.invoke(&self.function, args)
Expand All @@ -285,7 +286,7 @@ impl PyBoundMethod {
}
}

#[pyimpl(with(PyBuiltinCallable))]
#[pyimpl(with(SlotCall))]
impl PyBoundMethod {
#[pymethod(magic)]
fn getattribute(&self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
Expand Down
18 changes: 11 additions & 7 deletions vm/src/obj/objgetset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::function::{OptionalArg, OwnedParam, RefParam};
use crate::pyobject::{
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;

pub type PyGetterFunc = Box<dyn Fn(&VirtualMachine, PyObjectRef) -> PyResult>;
Expand Down Expand Up @@ -178,13 +178,17 @@ impl PyValue for PyGetSet {

pub type PyGetSetRef = PyRef<PyGetSet>;

impl PyBuiltinDescriptor for PyGetSet {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
_cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyGetSet {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
};
if let Some(ref f) = zelf.getter {
f(vm, obj)
} else {
Expand Down Expand Up @@ -222,7 +226,7 @@ impl PyGetSet {
}
}

#[pyimpl(with(PyBuiltinDescriptor))]
#[pyimpl(with(SlotDescriptor))]
impl PyGetSet {
// Descriptor methods

Expand Down
28 changes: 15 additions & 13 deletions vm/src/obj/objproperty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
TypeProtocol,
};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;

// Read-only property, doesn't have __set__ or __delete__
Expand All @@ -27,13 +27,14 @@ impl PyValue for PyReadOnlyProperty {

pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>;

impl PyBuiltinDescriptor for PyReadOnlyProperty {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyReadOnlyProperty {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
if vm.is_none(&obj) {
if Self::_cls_is(&cls, &vm.ctx.types.type_type) {
vm.invoke(&zelf.getter, cls.unwrap())
Expand All @@ -46,7 +47,7 @@ impl PyBuiltinDescriptor for PyReadOnlyProperty {
}
}

#[pyimpl(with(PyBuiltinDescriptor))]
#[pyimpl(with(SlotDescriptor))]
impl PyReadOnlyProperty {}

/// Property attribute.
Expand Down Expand Up @@ -110,13 +111,14 @@ struct PropertyArgs {
doc: Option<PyObjectRef>,
}

impl PyBuiltinDescriptor for PyProperty {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
_cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyProperty {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
if let Some(getter) = zelf.getter.as_ref() {
if obj.is(vm.ctx.none.as_object()) {
Ok(zelf.into_object())
Expand All @@ -129,7 +131,7 @@ impl PyBuiltinDescriptor for PyProperty {
}
}

#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyProperty {
#[pyslot]
fn tp_new(cls: PyClassRef, args: PropertyArgs, vm: &VirtualMachine) -> PyResult<PyPropertyRef> {
Expand Down
15 changes: 8 additions & 7 deletions vm/src/obj/objstaticmethod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;

#[pyclass(name = "staticmethod")]
Expand All @@ -17,18 +17,19 @@ impl PyValue for PyStaticMethod {
}
}

impl PyBuiltinDescriptor for PyStaticMethod {
fn get(
zelf: PyRef<Self>,
_obj: PyObjectRef,
impl SlotDescriptor for PyStaticMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
_obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
_vm: &VirtualMachine,
) -> PyResult {
let zelf = Self::_zelf(zelf, vm)?;
Ok(zelf.callable.clone())
}
}

#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyStaticMethod {
#[pyslot]
fn tp_new(
Expand Down
8 changes: 6 additions & 2 deletions vm/src/obj/objtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::objproperty::PropertyBuilder;
use super::objstr::PyStringRef;
use super::objtuple::PyTuple;
use super::objweakref::PyWeak;
use crate::function::PyFuncArgs;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyObject, PyObjectRef, PyRef,
PyResult, PyValue, TypeProtocol,
Expand Down Expand Up @@ -170,7 +170,11 @@ impl PyClassRef {

if let Some(attr) = self.get_attr(&name) {
let attr_class = attr.class();
if let Some(ref descriptor) = attr_class.get_attr("__get__") {
let slots = attr_class.slots.borrow();
if let Some(ref descr_get) = slots.descr_get {
return descr_get(vm, attr, None, OptionalArg::Present(self.into_object()));
} else if let Some(ref descriptor) = attr_class.get_attr("__get__") {
// TODO: is this nessessary?
return vm.invoke(descriptor, vec![attr, vm.get_none(), self.into_object()]);
}
}
Expand Down
6 changes: 3 additions & 3 deletions vm/src/obj/objweakref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
PyClassImpl, PyContext, PyObject, PyObjectPayload, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::slots::PyBuiltinCallable;
use crate::slots::SlotCall;
use crate::vm::VirtualMachine;

use std::rc::{Rc, Weak};
Expand Down Expand Up @@ -34,14 +34,14 @@ impl PyValue for PyWeak {

pub type PyWeakRef = PyRef<PyWeak>;

impl PyBuiltinCallable for PyWeak {
impl SlotCall for PyWeak {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
args.bind::<()>(vm)?;
Ok(self.referent.upgrade().unwrap_or_else(|| vm.get_none()))
}
}

#[pyimpl(with(PyBuiltinCallable), flags(BASETYPE))]
#[pyimpl(with(SlotCall), flags(BASETYPE))]
impl PyWeak {
// TODO callbacks
#[pyslot]
Expand Down
Loading