Merge pull request #403 from Alexander-N/__dict__
Complete __dict__ support
This commit is contained in:
commit
d8dc3a17bd
|
@ -47,6 +47,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
### Fixed
|
||||
|
||||
* A soudness hole where every instances of a `#[pyclass]` struct was considered to be part of a python object, even though you can create instances that are not part of the python heap. This was fixed through `PyRef` and `PyRefMut`.
|
||||
* Fix kwargs support in [#328].
|
||||
* Add full support for `__dict__` in [#403].
|
||||
|
||||
## [0.5.3] - 2019-01-04
|
||||
|
||||
|
|
|
@ -104,8 +104,7 @@ python object that can be collected, the `PyGCProtocol` trait has to be implemen
|
|||
* `weakref` - adds support for python weak references
|
||||
* `extends=BaseType` - use a custom base class. The base BaseType must implement `PyTypeInfo`.
|
||||
* `subclass` - Allows Python classes to inherit from this class
|
||||
* `dict` - adds `__dict__` support, the instances of this type have a dictionary containing instance variables. (Incomplete, see [#123](https://github.com/PyO3/pyo3/issues/123))
|
||||
|
||||
* `dict` - adds `__dict__` support, the instances of this type have a dictionary containing instance variables.
|
||||
|
||||
## Constructor
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef {
|
|||
closure: ptr::null_mut(),
|
||||
};
|
||||
|
||||
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef_INIT;
|
||||
|
||||
impl Clone for PyGetSetDef {
|
||||
#[inline]
|
||||
fn clone(&self) -> PyGetSetDef {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::ffi3::methodobject::PyMethodDef;
|
||||
use crate::ffi3::object::{PyObject, PyTypeObject};
|
||||
use crate::ffi3::object::{
|
||||
PyObject, PyObject_GenericGetDict, PyObject_GenericSetDict, PyTypeObject,
|
||||
};
|
||||
use crate::ffi3::structmember::PyMemberDef;
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::ptr;
|
||||
|
@ -27,6 +29,14 @@ pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef {
|
|||
closure: ptr::null_mut(),
|
||||
};
|
||||
|
||||
pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef {
|
||||
name: "__dict__\0".as_ptr() as *mut c_char,
|
||||
get: Some(PyObject_GenericGetDict),
|
||||
set: Some(PyObject_GenericSetDict),
|
||||
doc: ptr::null_mut(),
|
||||
closure: ptr::null_mut(),
|
||||
};
|
||||
|
||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||
extern "C" {
|
||||
pub static mut PyClassMethodDescr_Type: PyTypeObject;
|
||||
|
|
|
@ -702,6 +702,7 @@ extern "C" {
|
|||
arg2: *mut PyObject,
|
||||
arg3: *mut PyObject,
|
||||
) -> c_int;
|
||||
pub fn PyObject_GenericGetDict(arg1: *mut PyObject, arg2: *mut c_void) -> *mut PyObject;
|
||||
pub fn PyObject_GenericSetDict(
|
||||
arg1: *mut PyObject,
|
||||
arg2: *mut PyObject,
|
||||
|
|
|
@ -321,7 +321,8 @@ where
|
|||
}
|
||||
|
||||
// __dict__ support
|
||||
if T::FLAGS & PY_TYPE_FLAG_DICT != 0 {
|
||||
let has_dict = T::FLAGS & PY_TYPE_FLAG_DICT != 0;
|
||||
if has_dict {
|
||||
offset -= std::mem::size_of::<*const ffi::PyObject>();
|
||||
type_object.tp_dictoffset = offset as isize;
|
||||
}
|
||||
|
@ -392,6 +393,10 @@ where
|
|||
|
||||
// properties
|
||||
let mut props = py_class_properties::<T>();
|
||||
|
||||
if cfg!(Py_3) && has_dict {
|
||||
props.push(ffi::PyGetSetDef_DICT);
|
||||
}
|
||||
if !props.is_empty() {
|
||||
props.push(ffi::PyGetSetDef_INIT);
|
||||
type_object.tp_getset = Box::into_raw(props.into_boxed_slice()) as *mut _;
|
||||
|
|
|
@ -453,6 +453,22 @@ fn dunder_dict_support() {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(Py_3)]
|
||||
#[test]
|
||||
fn access_dunder_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = PyRef::new(py, DunderDictSupport {}).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
r#"
|
||||
inst.a = 1
|
||||
assert inst.__dict__ == {'a': 1}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass(weakref, dict)]
|
||||
struct WeakRefDunderDictSupport {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue