Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8a3fb40
Implement `random` module
malkoG Oct 26, 2019
908abef
Apply code review for test snippet
malkoG Dec 14, 2019
a20b6bf
Implement _random using the MT19937 algorithm
coolreader18 Feb 1, 2020
2fd9eb9
Add random.py from CPython 3.6
coolreader18 Feb 1, 2020
b40dcb7
Use random.Random in tempfile
coolreader18 Feb 1, 2020
a762bf8
Move gen_res53 to mersenne.rs
coolreader18 Feb 4, 2020
9abb258
Fix clippy warnings
coolreader18 Feb 4, 2020
c44f04b
Fallback exit code to 0 in case of overflow
arnavb Feb 4, 2020
4c49185
Have wasm/demo's "test" npm script build the demo in release mode
coolreader18 Feb 5, 2020
60037a2
Cache WASM dependencies
coolreader18 Feb 5, 2020
3960fb8
Merge pull request #1745 from arnavb/fix-exit-code
youknowone Feb 5, 2020
c435ba0
Merge pull request #1731 from RustPython/feature/implement-random
coolreader18 Feb 5, 2020
1bac582
&str::to_string -> &str::to_owned for literals
youknowone Feb 5, 2020
7d0d313
&str::to_string -> &str::to_owned for variables
youknowone Feb 5, 2020
78180ff
Merge pull request #1734 from youknowone/to-owned
youknowone Feb 5, 2020
9f5cd17
Add getset_descriptor
youknowone Feb 2, 2020
c3d5f6c
IntoPyGetterFunc, IntoPySetterFunc
youknowone Feb 2, 2020
ca55778
`&self` support for getter/setter
youknowone Feb 3, 2020
d1f9cb4
PySetResult and IntoPySetResult
youknowone Feb 3, 2020
226a2a6
VM polymorphism for getter and setter
youknowone Feb 3, 2020
23381b9
compatiibility for CPytthon descr_check
youknowone Feb 4, 2020
0aee78d
pyproperty generates PyGetSet instead of PyProperty
youknowone Feb 3, 2020
facabfe
Remove PropertyBuilder and add new_getset
youknowone Feb 5, 2020
58744df
Revert 08e66b5002f3a3a30db72b350b18c61d367ef1fc
youknowone Feb 1, 2020
c0b235e
cleanup property and get descriptor codes
youknowone Feb 2, 2020
429a276
Bump up to python 3.8 for Azure Pipelines
youknowone Jan 25, 2020
0f12db1
Merge pull request #1705 from youknowone/azure-38
youknowone Feb 5, 2020
e7ea486
Merge pull request #1738 from youknowone/getset
coolreader18 Feb 6, 2020
844b639
Fix SyntaxError initial value
youknowone Feb 5, 2020
6ddb690
Remove `_vm` parameter when it is not required
youknowone Feb 5, 2020
92cb58b
Remove `_vm` parameter - remove unused functions
youknowone Feb 6, 2020
7312e18
Merge pull request #1748 from youknowone/syntax-error
youknowone Feb 6, 2020
67f072d
Merge pull request #1749 from youknowone/_vm
youknowone Feb 6, 2020
f873c0e
Merge pull request #1746 from RustPython/coolreader18/wasm-test-produ…
coolreader18 Feb 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove PropertyBuilder and add new_getset
  • Loading branch information
youknowone committed Feb 5, 2020
commit facabfee1ac0ca5f5e2337a2e2aff253ce3810ee
3 changes: 2 additions & 1 deletion derive/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,8 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
let property = quote! {
class.set_str_attr(
#field_name_str,
ctx.new_property(
ctx.new_readonly_getset(
#field_name_str,
|zelf: &::rustpython_vm::obj::objtuple::PyTuple,
_vm: &::rustpython_vm::VirtualMachine| {
zelf.fast_getitem(#idx)
Expand Down
40 changes: 18 additions & 22 deletions vm/src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,48 +644,44 @@ pub fn init(ctx: &PyContext) {
PyBaseException::extend_class(ctx, &excs.base_exception_type);

extend_class!(ctx, &excs.syntax_error, {
"msg" => ctx.new_property(make_arg_getter(0)),
"filename" => ctx.new_property(make_arg_getter(1)),
"lineno" => ctx.new_property(make_arg_getter(2)),
"offset" => ctx.new_property(make_arg_getter(3)),
"text" => ctx.new_property(make_arg_getter(4)),
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
});

extend_class!(ctx, &excs.import_error, {
"__init__" => ctx.new_method(import_error_init),
"msg" => ctx.new_property(make_arg_getter(0)),
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
});

extend_class!(ctx, &excs.stop_iteration, {
"value" => ctx.new_property(make_arg_getter(0)),
"value" => ctx.new_readonly_getset("value", make_arg_getter(0)),
});

extend_class!(ctx, &excs.key_error, {
"__str__" => ctx.new_method(key_error_str),
});

extend_class!(ctx, &excs.unicode_decode_error, {
"encoding" => ctx.new_property(make_arg_getter(0)),
"object" => ctx.new_property(make_arg_getter(1)),
"start" => ctx.new_property(make_arg_getter(2)),
"end" => ctx.new_property(make_arg_getter(3)),
"reason" => ctx.new_property(make_arg_getter(4)),
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
});

extend_class!(ctx, &excs.unicode_encode_error, {
"encoding" => ctx.new_property(make_arg_getter(0)),
"object" => ctx.new_property(make_arg_getter(1)),
"start" => ctx.new_property(make_arg_getter(2)),
"end" => ctx.new_property(make_arg_getter(3)),
"reason" => ctx.new_property(make_arg_getter(4)),
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
});

extend_class!(ctx, &excs.unicode_translate_error, {
"encoding" => ctx.new_property(none_getter),
"object" => ctx.new_property(make_arg_getter(0)),
"start" => ctx.new_property(make_arg_getter(1)),
"end" => ctx.new_property(make_arg_getter(2)),
"reason" => ctx.new_property(make_arg_getter(3)),
"encoding" => ctx.new_readonly_getset("encoding", none_getter),
"object" => ctx.new_readonly_getset("object", make_arg_getter(0)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(1)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(2)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)),
});
}

Expand Down
22 changes: 11 additions & 11 deletions vm/src/obj/objcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,17 @@ impl PyCodeRef {
}
}

pub fn init(context: &PyContext) {
extend_class!(context, &context.types.code_type, {
pub fn init(ctx: &PyContext) {
extend_class!(ctx, &ctx.types.code_type, {
(slot new) => PyCodeRef::new,
"__repr__" => context.new_method(PyCodeRef::repr),

"co_argcount" => context.new_property(PyCodeRef::co_argcount),
"co_consts" => context.new_property(PyCodeRef::co_consts),
"co_filename" => context.new_property(PyCodeRef::co_filename),
"co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno),
"co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount),
"co_name" => context.new_property(PyCodeRef::co_name),
"co_flags" => context.new_property(PyCodeRef::co_flags),
"__repr__" => ctx.new_method(PyCodeRef::repr),

"co_argcount" => ctx.new_readonly_getset("co_argcount", PyCodeRef::co_argcount),
"co_consts" => ctx.new_readonly_getset("co_consts", PyCodeRef::co_consts),
"co_filename" => ctx.new_readonly_getset("co_filename", PyCodeRef::co_filename),
"co_firstlineno" => ctx.new_readonly_getset("co_firstlineno", PyCodeRef::co_firstlineno),
"co_kwonlyargcount" => ctx.new_readonly_getset("co_kwonlyargcount", PyCodeRef::co_kwonlyargcount),
"co_name" => ctx.new_readonly_getset("co_name", PyCodeRef::co_name),
"co_flags" => ctx.new_readonly_getset("co_flags", PyCodeRef::co_flags),
});
}
116 changes: 4 additions & 112 deletions vm/src/obj/objproperty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,13 @@
use std::cell::RefCell;

use super::objtype::PyClassRef;
use crate::function::{IntoPyNativeFunc, OptionalArg};
use crate::function::OptionalArg;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
TypeProtocol,
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;

// Read-only property, doesn't have __set__ or __delete__
#[pyclass]
#[derive(Debug)]
pub struct PyReadOnlyProperty {
getter: PyObjectRef,
}

impl PyValue for PyReadOnlyProperty {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.readonly_property_type()
}
}

pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>;

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())
} else {
Ok(zelf.into_object())
}
} else {
vm.invoke(&zelf.getter, obj)
}
}
}

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

/// Property attribute.
///
/// fget
Expand Down Expand Up @@ -255,81 +216,12 @@ fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option<PyObjec
}
}

pub struct PropertyBuilder<'a> {
ctx: &'a PyContext,
getter: Option<PyObjectRef>,
setter: Option<PyObjectRef>,
}

impl<'a> PropertyBuilder<'a> {
pub fn new(ctx: &'a PyContext) -> Self {
Self {
ctx,
getter: None,
setter: None,
}
}

pub fn add_getter<I, R, VM, F: IntoPyNativeFunc<I, R, VM>>(self, func: F) -> Self {
let func = self.ctx.new_method(func);
Self {
ctx: self.ctx,
getter: Some(func),
setter: self.setter,
}
}

pub fn add_setter<
I,
V,
VM,
F: IntoPyNativeFunc<(I, V), impl super::objgetset::IntoPyNoResult, VM>,
>(
self,
func: F,
) -> Self {
let func = self.ctx.new_method(func);
Self {
ctx: self.ctx,
getter: self.getter,
setter: Some(func),
}
}

pub fn create(self) -> PyObjectRef {
if self.setter.is_some() {
let payload = PyProperty {
getter: self.getter.clone(),
setter: self.setter.clone(),
deleter: None,
doc: RefCell::new(None),
};

PyObject::new(payload, self.ctx.property_type(), None)
} else {
let payload = PyReadOnlyProperty {
getter: self.getter.expect(
"One of add_getter/add_setter must be called when constructing a property",
),
};

PyObject::new(payload, self.ctx.readonly_property_type(), None)
}
}
}

pub fn init(context: &PyContext) {
PyReadOnlyProperty::extend_class(context, &context.types.readonly_property_type);

pub(crate) fn init(context: &PyContext) {
PyProperty::extend_class(context, &context.types.property_type);

// This is a bit unfortunate, but this instance attribute overlaps with the
// class __doc__ string..
extend_class!(context, &context.types.property_type, {
"__doc__" =>
PropertyBuilder::new(context)
.add_getter(PyProperty::doc_getter)
.add_setter(PyProperty::doc_setter)
.create(),
"__doc__" => context.new_getset("__doc__", PyProperty::doc_getter, PyProperty::doc_setter),
});
}
46 changes: 14 additions & 32 deletions vm/src/obj/objtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::fmt;
use super::objdict::PyDictRef;
use super::objlist::PyList;
use super::objmappingproxy::PyMappingProxy;
use super::objproperty::PropertyBuilder;
use super::objstr::PyStringRef;
use super::objtuple::PyTuple;
use super::objweakref::PyWeak;
Expand Down Expand Up @@ -80,16 +79,13 @@ impl PyClassRef {
}
}

fn _mro(self, _vm: &VirtualMachine) -> PyTuple {
#[pyproperty(name = "__mro__")]
fn get_mro(self, _vm: &VirtualMachine) -> PyTuple {
let elements: Vec<PyObjectRef> =
_mro(&self).iter().map(|x| x.as_object().clone()).collect();
PyTuple::from(elements)
}

fn _set_mro(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_attribute_error("read-only attribute".to_owned()))
}

#[pyproperty(magic)]
fn bases(self, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx
Expand Down Expand Up @@ -338,6 +334,18 @@ impl PyClassRef {
}
Ok(obj)
}

#[pyproperty(magic)]
fn dict(self) -> PyMappingProxy {
PyMappingProxy::new(self)
}

#[pyproperty(magic, setter)]
fn set_dict(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_not_implemented_error(
"Setting __dict__ attribute on a type isn't yet implemented".to_owned(),
))
}
}

/*
Expand All @@ -346,18 +354,6 @@ impl PyClassRef {

pub(crate) fn init(ctx: &PyContext) {
PyClassRef::extend_class(ctx, &ctx.types.type_type);
extend_class!(&ctx, &ctx.types.type_type, {
"__dict__" =>
PropertyBuilder::new(ctx)
.add_getter(type_dict)
.add_setter(type_dict_setter)
.create(),
"__mro__" =>
PropertyBuilder::new(ctx)
.add_getter(PyClassRef::_mro)
.add_setter(PyClassRef::_set_mro)
.create(),
});
}

fn _mro(cls: &PyClassRef) -> Vec<PyClassRef> {
Expand Down Expand Up @@ -409,20 +405,6 @@ pub fn type_new(
new(vm, args.insert(cls.into_object()))
}

fn type_dict(class: PyClassRef, _vm: &VirtualMachine) -> PyMappingProxy {
PyMappingProxy::new(class)
}

fn type_dict_setter(
_instance: PyClassRef,
_value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Err(vm.new_not_implemented_error(
"Setting __dict__ attribute on a type isn't yet implemented".to_owned(),
))
}

impl PyClassRef {
/// This is the internal get_attr implementation for fast lookup on a class.
pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
Expand Down
20 changes: 16 additions & 4 deletions vm/src/pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ use crate::obj::objcomplex::PyComplex;
use crate::obj::objdict::{PyDict, PyDictRef};
use crate::obj::objfloat::PyFloat;
use crate::obj::objfunction::{PyBoundMethod, PyFunction};
use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet};
use crate::obj::objint::{PyInt, PyIntRef};
use crate::obj::objiter;
use crate::obj::objlist::PyList;
use crate::obj::objnamespace::PyNamespace;
use crate::obj::objnone::{PyNone, PyNoneRef};
use crate::obj::objobject;
use crate::obj::objproperty::PropertyBuilder;
use crate::obj::objset::PySet;
use crate::obj::objstr;
use crate::obj::objtuple::{PyTuple, PyTupleRef};
Expand Down Expand Up @@ -503,11 +503,23 @@ impl PyContext {
)
}

pub fn new_property<F, I, V, VM>(&self, f: F) -> PyObjectRef
pub fn new_readonly_getset<F, T>(&self, name: impl Into<String>, f: F) -> PyObjectRef
where
F: IntoPyNativeFunc<I, V, VM>,
F: IntoPyGetterFunc<T>,
{
PropertyBuilder::new(self).add_getter(f).create()
PyObject::new(PyGetSet::with_get(name.into(), f), self.getset_type(), None)
}

pub fn new_getset<G, S, T, U>(&self, name: impl Into<String>, g: G, s: S) -> PyObjectRef
where
G: IntoPyGetterFunc<T>,
S: IntoPySetterFunc<U>,
{
PyObject::new(
PyGetSet::with_get_set(name.into(), g, s),
self.getset_type(),
None,
)
}

pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef {
Expand Down
Loading