| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0aee78d commit facabfe
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -692,7 +692,8 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt | |||
| 692 | 692 | let property = quote! { | |
| 693 | 693 | class.set_str_attr( | |
| 694 | 694 | #field_name_str, | |
| 695 | - ctx.new_property( | ||
| 695 | + ctx.new_readonly_getset( | ||
| 696 | + #field_name_str, | ||
| 696 | 697 | |zelf: &::rustpython_vm::obj::objtuple::PyTuple, | |
| 697 | 698 | _vm: &::rustpython_vm::VirtualMachine| { | |
| 698 | 699 | zelf.fast_getitem(#idx) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -644,48 +644,44 @@ pub fn init(ctx: &PyContext) { | |||
| 644 | 644 | PyBaseException::extend_class(ctx, &excs.base_exception_type); | |
| 645 | 645 | ||
| 646 | 646 | extend_class!(ctx, &excs.syntax_error, { | |
| 647 | - "msg" => ctx.new_property(make_arg_getter(0)), | ||
| 648 | - "filename" => ctx.new_property(make_arg_getter(1)), | ||
| 649 | - "lineno" => ctx.new_property(make_arg_getter(2)), | ||
| 650 | - "offset" => ctx.new_property(make_arg_getter(3)), | ||
| 651 | - "text" => ctx.new_property(make_arg_getter(4)), | ||
| 647 | + "msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)), | ||
| 652 | 648 | }); | |
| 653 | 649 | ||
| 654 | 650 | extend_class!(ctx, &excs.import_error, { | |
| 655 | 651 | "__init__" => ctx.new_method(import_error_init), | |
| 656 | - "msg" => ctx.new_property(make_arg_getter(0)), | ||
| 652 | + "msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)), | ||
| 657 | 653 | }); | |
| 658 | 654 | ||
| 659 | 655 | extend_class!(ctx, &excs.stop_iteration, { | |
| 660 | - "value" => ctx.new_property(make_arg_getter(0)), | ||
| 656 | + "value" => ctx.new_readonly_getset("value", make_arg_getter(0)), | ||
| 661 | 657 | }); | |
| 662 | 658 | ||
| 663 | 659 | extend_class!(ctx, &excs.key_error, { | |
| 664 | 660 | "__str__" => ctx.new_method(key_error_str), | |
| 665 | 661 | }); | |
| 666 | 662 | ||
| 667 | 663 | extend_class!(ctx, &excs.unicode_decode_error, { | |
| 668 | - "encoding" => ctx.new_property(make_arg_getter(0)), | ||
| 669 | - "object" => ctx.new_property(make_arg_getter(1)), | ||
| 670 | - "start" => ctx.new_property(make_arg_getter(2)), | ||
| 671 | - "end" => ctx.new_property(make_arg_getter(3)), | ||
| 672 | - "reason" => ctx.new_property(make_arg_getter(4)), | ||
| 664 | + "encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)), | ||
| 665 | + "object" => ctx.new_readonly_getset("object", make_arg_getter(1)), | ||
| 666 | + "start" => ctx.new_readonly_getset("start", make_arg_getter(2)), | ||
| 667 | + "end" => ctx.new_readonly_getset("end", make_arg_getter(3)), | ||
| 668 | + "reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)), | ||
| 673 | 669 | }); | |
| 674 | 670 | ||
| 675 | 671 | extend_class!(ctx, &excs.unicode_encode_error, { | |
| 676 | - "encoding" => ctx.new_property(make_arg_getter(0)), | ||
| 677 | - "object" => ctx.new_property(make_arg_getter(1)), | ||
| 678 | - "start" => ctx.new_property(make_arg_getter(2)), | ||
| 679 | - "end" => ctx.new_property(make_arg_getter(3)), | ||
| 680 | - "reason" => ctx.new_property(make_arg_getter(4)), | ||
| 672 | + "encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)), | ||
| 673 | + "object" => ctx.new_readonly_getset("object", make_arg_getter(1)), | ||
| 674 | + "start" => ctx.new_readonly_getset("start", make_arg_getter(2)), | ||
| 675 | + "end" => ctx.new_readonly_getset("end", make_arg_getter(3)), | ||
| 676 | + "reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)), | ||
| 681 | 677 | }); | |
| 682 | 678 | ||
| 683 | 679 | extend_class!(ctx, &excs.unicode_translate_error, { | |
| 684 | - "encoding" => ctx.new_property(none_getter), | ||
| 685 | - "object" => ctx.new_property(make_arg_getter(0)), | ||
| 686 | - "start" => ctx.new_property(make_arg_getter(1)), | ||
| 687 | - "end" => ctx.new_property(make_arg_getter(2)), | ||
| 688 | - "reason" => ctx.new_property(make_arg_getter(3)), | ||
| 680 | + "encoding" => ctx.new_readonly_getset("encoding", none_getter), | ||
| 681 | + "object" => ctx.new_readonly_getset("object", make_arg_getter(0)), | ||
| 682 | + "start" => ctx.new_readonly_getset("start", make_arg_getter(1)), | ||
| 683 | + "end" => ctx.new_readonly_getset("end", make_arg_getter(2)), | ||
| 684 | + "reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)), | ||
| 689 | 685 | }); | |
| 690 | 686 | } | |
| 691 | 687 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -92,17 +92,17 @@ impl PyCodeRef { | |||
| 92 | 92 | } | |
| 93 | 93 | } | |
| 94 | 94 | ||
| 95 | - pub fn init(context: &PyContext) { | ||
| 96 | - extend_class!(context, &context.types.code_type, { | ||
| 95 | + pub fn init(ctx: &PyContext) { | ||
| 96 | + extend_class!(ctx, &ctx.types.code_type, { | ||
| 97 | 97 | (slot new) => PyCodeRef::new, | |
| 98 | - "__repr__" => context.new_method(PyCodeRef::repr), | ||
| 99 | - | ||
| 100 | - "co_argcount" => context.new_property(PyCodeRef::co_argcount), | ||
| 101 | - "co_consts" => context.new_property(PyCodeRef::co_consts), | ||
| 102 | - "co_filename" => context.new_property(PyCodeRef::co_filename), | ||
| 103 | - "co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno), | ||
| 104 | - "co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount), | ||
| 105 | - "co_name" => context.new_property(PyCodeRef::co_name), | ||
| 106 | - "co_flags" => context.new_property(PyCodeRef::co_flags), | ||
| 98 | + "__repr__" => ctx.new_method(PyCodeRef::repr), | ||
| 99 | + | ||
| 100 | + "co_argcount" => ctx.new_readonly_getset("co_argcount", PyCodeRef::co_argcount), | ||
| 101 | + "co_consts" => ctx.new_readonly_getset("co_consts", PyCodeRef::co_consts), | ||
| 102 | + "co_filename" => ctx.new_readonly_getset("co_filename", PyCodeRef::co_filename), | ||
| 103 | + "co_firstlineno" => ctx.new_readonly_getset("co_firstlineno", PyCodeRef::co_firstlineno), | ||
| 104 | + "co_kwonlyargcount" => ctx.new_readonly_getset("co_kwonlyargcount", PyCodeRef::co_kwonlyargcount), | ||
| 105 | + "co_name" => ctx.new_readonly_getset("co_name", PyCodeRef::co_name), | ||
| 106 | + "co_flags" => ctx.new_readonly_getset("co_flags", PyCodeRef::co_flags), | ||
| 107 | 107 | }); | |
| 108 | 108 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,52 +4,13 @@ | |||
| 4 | 4 | use std::cell::RefCell; | |
| 5 | 5 | ||
| 6 | 6 | use super::objtype::PyClassRef; | |
| 7 | - use crate::function::{IntoPyNativeFunc, OptionalArg}; | ||
| 7 | + use crate::function::OptionalArg; | ||
| 8 | 8 | use crate::pyobject::{ | |
| 9 | - IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, | ||
| 10 | - TypeProtocol, | ||
| 9 | + IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, | ||
| 11 | 10 | }; | |
| 12 | 11 | use crate::slots::SlotDescriptor; | |
| 13 | 12 | use crate::vm::VirtualMachine; | |
| 14 | 13 | ||
| 15 | - // Read-only property, doesn't have __set__ or __delete__ | ||
| 16 | - #[pyclass] | ||
| 17 | - #[derive(Debug)] | ||
| 18 | - pub struct PyReadOnlyProperty { | ||
| 19 | - getter: PyObjectRef, | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - impl PyValue for PyReadOnlyProperty { | ||
| 23 | - fn class(vm: &VirtualMachine) -> PyClassRef { | ||
| 24 | - vm.ctx.readonly_property_type() | ||
| 25 | - } | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>; | ||
| 29 | - | ||
| 30 | - impl SlotDescriptor for PyReadOnlyProperty { | ||
| 31 | - fn descr_get( | ||
| 32 | - vm: &VirtualMachine, | ||
| 33 | - zelf: PyObjectRef, | ||
| 34 | - obj: Option<PyObjectRef>, | ||
| 35 | - cls: OptionalArg<PyObjectRef>, | ||
| 36 | - ) -> PyResult { | ||
| 37 | - let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; | ||
| 38 | - if vm.is_none(&obj) { | ||
| 39 | - if Self::_cls_is(&cls, &vm.ctx.types.type_type) { | ||
| 40 | - vm.invoke(&zelf.getter, cls.unwrap()) | ||
| 41 | - } else { | ||
| 42 | - Ok(zelf.into_object()) | ||
| 43 | - } | ||
| 44 | - } else { | ||
| 45 | - vm.invoke(&zelf.getter, obj) | ||
| 46 | - } | ||
| 47 | - } | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - #[pyimpl(with(SlotDescriptor))] | ||
| 51 | - impl PyReadOnlyProperty {} | ||
| 52 | - | ||
| 53 | 14 | /// Property attribute. | |
| 54 | 15 | /// | |
| 55 | 16 | /// fget | |
@@ -255,81 +216,12 @@ fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option<PyObjec | |||
| 255 | 216 | } | |
| 256 | 217 | } | |
| 257 | 218 | ||
| 258 | - pub struct PropertyBuilder<'a> { | ||
| 259 | - ctx: &'a PyContext, | ||
| 260 | - getter: Option<PyObjectRef>, | ||
| 261 | - setter: Option<PyObjectRef>, | ||
| 262 | - } | ||
| 263 | - | ||
| 264 | - impl<'a> PropertyBuilder<'a> { | ||
| 265 | - pub fn new(ctx: &'a PyContext) -> Self { | ||
| 266 | - Self { | ||
| 267 | - ctx, | ||
| 268 | - getter: None, | ||
| 269 | - setter: None, | ||
| 270 | - } | ||
| 271 | - } | ||
| 272 | - | ||
| 273 | - pub fn add_getter<I, R, VM, F: IntoPyNativeFunc<I, R, VM>>(self, func: F) -> Self { | ||
| 274 | - let func = self.ctx.new_method(func); | ||
| 275 | - Self { | ||
| 276 | - ctx: self.ctx, | ||
| 277 | - getter: Some(func), | ||
| 278 | - setter: self.setter, | ||
| 279 | - } | ||
| 280 | - } | ||
| 281 | - | ||
| 282 | - pub fn add_setter< | ||
| 283 | - I, | ||
| 284 | - V, | ||
| 285 | - VM, | ||
| 286 | - F: IntoPyNativeFunc<(I, V), impl super::objgetset::IntoPyNoResult, VM>, | ||
| 287 | - >( | ||
| 288 | - self, | ||
| 289 | - func: F, | ||
| 290 | - ) -> Self { | ||
| 291 | - let func = self.ctx.new_method(func); | ||
| 292 | - Self { | ||
| 293 | - ctx: self.ctx, | ||
| 294 | - getter: self.getter, | ||
| 295 | - setter: Some(func), | ||
| 296 | - } | ||
| 297 | - } | ||
| 298 | - | ||
| 299 | - pub fn create(self) -> PyObjectRef { | ||
| 300 | - if self.setter.is_some() { | ||
| 301 | - let payload = PyProperty { | ||
| 302 | - getter: self.getter.clone(), | ||
| 303 | - setter: self.setter.clone(), | ||
| 304 | - deleter: None, | ||
| 305 | - doc: RefCell::new(None), | ||
| 306 | - }; | ||
| 307 | - | ||
| 308 | - PyObject::new(payload, self.ctx.property_type(), None) | ||
| 309 | - } else { | ||
| 310 | - let payload = PyReadOnlyProperty { | ||
| 311 | - getter: self.getter.expect( | ||
| 312 | - "One of add_getter/add_setter must be called when constructing a property", | ||
| 313 | - ), | ||
| 314 | - }; | ||
| 315 | - | ||
| 316 | - PyObject::new(payload, self.ctx.readonly_property_type(), None) | ||
| 317 | - } | ||
| 318 | - } | ||
| 319 | - } | ||
| 320 | - | ||
| 321 | - pub fn init(context: &PyContext) { | ||
| 322 | - PyReadOnlyProperty::extend_class(context, &context.types.readonly_property_type); | ||
| 323 | - | ||
| 219 | + pub(crate) fn init(context: &PyContext) { | ||
| 324 | 220 | PyProperty::extend_class(context, &context.types.property_type); | |
| 325 | 221 | ||
| 326 | 222 | // This is a bit unfortunate, but this instance attribute overlaps with the | |
| 327 | 223 | // class __doc__ string.. | |
| 328 | 224 | extend_class!(context, &context.types.property_type, { | |
| 329 | - "__doc__" => | ||
| 330 | - PropertyBuilder::new(context) | ||
| 331 | - .add_getter(PyProperty::doc_getter) | ||
| 332 | - .add_setter(PyProperty::doc_setter) | ||
| 333 | - .create(), | ||
| 225 | + "__doc__" => context.new_getset("__doc__", PyProperty::doc_getter, PyProperty::doc_setter), | ||
| 334 | 226 | }); | |
| 335 | 227 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,6 @@ use std::fmt; | |||
| 5 | 5 | use super::objdict::PyDictRef; | |
| 6 | 6 | use super::objlist::PyList; | |
| 7 | 7 | use super::objmappingproxy::PyMappingProxy; | |
| 8 | - use super::objproperty::PropertyBuilder; | ||
| 9 | 8 | use super::objstr::PyStringRef; | |
| 10 | 9 | use super::objtuple::PyTuple; | |
| 11 | 10 | use super::objweakref::PyWeak; | |
@@ -80,16 +79,13 @@ impl PyClassRef { | |||
| 80 | 79 | } | |
| 81 | 80 | } | |
| 82 | 81 | ||
| 83 | - fn _mro(self, _vm: &VirtualMachine) -> PyTuple { | ||
| 82 | + #[pyproperty(name = "__mro__")] | ||
| 83 | + fn get_mro(self, _vm: &VirtualMachine) -> PyTuple { | ||
| 84 | 84 | let elements: Vec<PyObjectRef> = | |
| 85 | 85 | _mro(&self).iter().map(|x| x.as_object().clone()).collect(); | |
| 86 | 86 | PyTuple::from(elements) | |
| 87 | 87 | } | |
| 88 | 88 | ||
| 89 | - fn _set_mro(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { | ||
| 90 | - Err(vm.new_attribute_error("read-only attribute".to_owned())) | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | 89 | #[pyproperty(magic)] | |
| 94 | 90 | fn bases(self, vm: &VirtualMachine) -> PyObjectRef { | |
| 95 | 91 | vm.ctx | |
@@ -338,6 +334,18 @@ impl PyClassRef { | |||
| 338 | 334 | } | |
| 339 | 335 | Ok(obj) | |
| 340 | 336 | } | |
| 337 | + | ||
| 338 | + #[pyproperty(magic)] | ||
| 339 | + fn dict(self) -> PyMappingProxy { | ||
| 340 | + PyMappingProxy::new(self) | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + #[pyproperty(magic, setter)] | ||
| 344 | + fn set_dict(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { | ||
| 345 | + Err(vm.new_not_implemented_error( | ||
| 346 | + "Setting __dict__ attribute on a type isn't yet implemented".to_owned(), | ||
| 347 | + )) | ||
| 348 | + } | ||
| 341 | 349 | } | |
| 342 | 350 | ||
| 343 | 351 | /* | |
@@ -346,18 +354,6 @@ impl PyClassRef { | |||
| 346 | 354 | ||
| 347 | 355 | pub(crate) fn init(ctx: &PyContext) { | |
| 348 | 356 | PyClassRef::extend_class(ctx, &ctx.types.type_type); | |
| 349 | - extend_class!(&ctx, &ctx.types.type_type, { | ||
| 350 | - "__dict__" => | ||
| 351 | - PropertyBuilder::new(ctx) | ||
| 352 | - .add_getter(type_dict) | ||
| 353 | - .add_setter(type_dict_setter) | ||
| 354 | - .create(), | ||
| 355 | - "__mro__" => | ||
| 356 | - PropertyBuilder::new(ctx) | ||
| 357 | - .add_getter(PyClassRef::_mro) | ||
| 358 | - .add_setter(PyClassRef::_set_mro) | ||
| 359 | - .create(), | ||
| 360 | - }); | ||
| 361 | 357 | } | |
| 362 | 358 | ||
| 363 | 359 | fn _mro(cls: &PyClassRef) -> Vec<PyClassRef> { | |
@@ -409,20 +405,6 @@ pub fn type_new( | |||
| 409 | 405 | new(vm, args.insert(cls.into_object())) | |
| 410 | 406 | } | |
| 411 | 407 | ||
| 412 | - fn type_dict(class: PyClassRef, _vm: &VirtualMachine) -> PyMappingProxy { | ||
| 413 | - PyMappingProxy::new(class) | ||
| 414 | - } | ||
| 415 | - | ||
| 416 | - fn type_dict_setter( | ||
| 417 | - _instance: PyClassRef, | ||
| 418 | - _value: PyObjectRef, | ||
| 419 | - vm: &VirtualMachine, | ||
| 420 | - ) -> PyResult<()> { | ||
| 421 | - Err(vm.new_not_implemented_error( | ||
| 422 | - "Setting __dict__ attribute on a type isn't yet implemented".to_owned(), | ||
| 423 | - )) | ||
| 424 | - } | ||
| 425 | - | ||
| 426 | 408 | impl PyClassRef { | |
| 427 | 409 | /// This is the internal get_attr implementation for fast lookup on a class. | |
| 428 | 410 | pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,13 +25,13 @@ use crate::obj::objcomplex::PyComplex; | |||
| 25 | 25 | use crate::obj::objdict::{PyDict, PyDictRef}; | |
| 26 | 26 | use crate::obj::objfloat::PyFloat; | |
| 27 | 27 | use crate::obj::objfunction::{PyBoundMethod, PyFunction}; | |
| 28 | + use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}; | ||
| 28 | 29 | use crate::obj::objint::{PyInt, PyIntRef}; | |
| 29 | 30 | use crate::obj::objiter; | |
| 30 | 31 | use crate::obj::objlist::PyList; | |
| 31 | 32 | use crate::obj::objnamespace::PyNamespace; | |
| 32 | 33 | use crate::obj::objnone::{PyNone, PyNoneRef}; | |
| 33 | 34 | use crate::obj::objobject; | |
| 34 | - use crate::obj::objproperty::PropertyBuilder; | ||
| 35 | 35 | use crate::obj::objset::PySet; | |
| 36 | 36 | use crate::obj::objstr; | |
| 37 | 37 | use crate::obj::objtuple::{PyTuple, PyTupleRef}; | |
@@ -503,11 +503,23 @@ impl PyContext { | |||
| 503 | 503 | ) | |
| 504 | 504 | } | |
| 505 | 505 | ||
| 506 | - pub fn new_property<F, I, V, VM>(&self, f: F) -> PyObjectRef | ||
| 506 | + pub fn new_readonly_getset<F, T>(&self, name: impl Into<String>, f: F) -> PyObjectRef | ||
| 507 | 507 | where | |
| 508 | - F: IntoPyNativeFunc<I, V, VM>, | ||
| 508 | + F: IntoPyGetterFunc<T>, | ||
| 509 | 509 | { | |
| 510 | - PropertyBuilder::new(self).add_getter(f).create() | ||
| 510 | + PyObject::new(PyGetSet::with_get(name.into(), f), self.getset_type(), None) | ||
| 511 | + } | ||
| 512 | + | ||
| 513 | + pub fn new_getset<G, S, T, U>(&self, name: impl Into<String>, g: G, s: S) -> PyObjectRef | ||
| 514 | + where | ||
| 515 | + G: IntoPyGetterFunc<T>, | ||
| 516 | + S: IntoPySetterFunc<U>, | ||
| 517 | + { | ||
| 518 | + PyObject::new( | ||
| 519 | + PyGetSet::with_get_set(name.into(), g, s), | ||
| 520 | + self.getset_type(), | ||
| 521 | + None, | ||
| 522 | + ) | ||
| 511 | 523 | } | |
| 512 | 524 | ||
| 513 | 525 | pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments