8000 getstate · RustPython/RustPython@483537b · GitHub
[go: up one dir, main page]

Skip to content

Commit 483537b

Browse files
committed
getstate
1 parent f5c1596 commit 483537b

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

vm/src/builtins/object.rs

Lines changed: 106 additions & 0 deletions
< E30A /tr>
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::common::hash::PyHash;
33
use crate::types::PyTypeFlags;
44
use crate::{
55
class::PyClassImpl,
6+
convert::ToPyResult,
67
function::{Either, FuncArgs, PyArithmeticValue, PyComparisonValue, PySetterValue},
78
types::{Constructor, PyComparisonOp},
89
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
@@ -73,8 +74,113 @@ impl Constructor for PyBaseObject {
7374
}
7475
}
7576

77+
// object_getstate_default in CPython
78+
fn object_getstate_default(
79+
obj: &PyObject,
80+
required: bool,
81+
vm: &VirtualMachine,
82+
) -> PyResult<Option<PyObjectRef>> {
83+
// TODO: itemsize
84+
// if required && obj.class().slots.itemsize > 0 {
85+
// return vm.new_type_error(format!(
86+
// "cannot pickle {:.200} objects",
87+
// obj.class().name()
88+
// ));
89+
// }
90+
91+
let state = if obj.dict().map_or(true, |d| d.is_empty()) {
92+
vm.ctx.none()
93+
} else {
94+
// let state = object_get_dict(obj.clone(), obj.ctx()).unwrap();
95+
let Some(state) = obj.dict() else {
96+
return Ok(None);
97+
};
98+
state.into()
99+
};
100+
101+
// let slotnames = obj.class().slot_names(obj.ctx());
102+
// if slotnames.is_none() {
103+
// return PyErr::new_type_error("cannot pickle object".to_owned());
104+
// }
105+
106+
if required {
107+
let basicsize = obj.class().slots.basicsize;
108+
// if obj.class().slots.dictoffset > 0
109+
// && !obj.class().slots.flags.has_feature(PyTypeFlags::MANAGED_DICT)
110+
// {
111+
// basicsize += std::mem::size_of::<PyObjectRef>();
112+
// }
113+
// if obj.class().slots.weaklistoffset > 0 {
114+
// basicsize += std::mem::size_of::<PyObjectRef>();
115+
// }
116+
// if !slotnames.is_none() {
117+
// basicsize += std::mem::size_of::<PyObjectRef>() * slotnames.length(vm).unwrap();
118+
// }
119+
if obj.class().slots.basicsize > basicsize {
120+
return Err(
121+
vm.new_type_error(format!("cannot pickle {:.200} object", obj.class().name()))
122+
);
123+
}
124+
}
125+
126+
// if !slotnames.is_none() && slotnames.length(vm).unwrap() > 0 {
127+
// let mut slots = obj.ctx().new_dict();
128+
// let slotnames_size = slotnames.length(vm).unwrap();
129+
// for i in 0..slotnames_size {
130+
// let name = slotnames.get_item(i).unwrap();
131+
// let value = obj.getattr(&name, obj.ctx()).unwrap();
132+
// if value.is_none() {
133+
// continue;
134+
// }
135+
// slots.set_item(name, value).unwrap();
136+
// }
137+
138+
// if slots.len() > 0 {
139+
// let state2 = obj.ctx().new_tuple(vec![state, slots]).unwrap();
140+
// return state2;
141+
// }
142+
// }
143+
144+
Ok(Some(state))
145+
}
146+
147+
// object_getstate in CPython
148+
// fn object_getstate(
149+
// obj: &PyObject,
150+
// required: bool,
151+
// vm: &VirtualMachine,
152+
// ) -> PyResult<Option<PyObjectRef>> {
153+
// let getstate = obj.get_attr(identifier!(vm, __getstate__), vm)?;
154+
// if vm.is_none(&getstate) {
155+
// return Ok(None);
156+
// }
157+
158+
// let getstate = match getstate.downcast_exact::<PyNativeFunction>(vm) {
159+
// Ok(getstate)
160+
// if getstate
161+
// .get_self()
162+
// .map_or(false, |self_obj| self_obj.is(obj))
163+
// && std::ptr::addr_eq(
164+
// getstate.as_func() as *const _,
165+
// &PyBaseObject::__getstate__ as &dyn crate::function::PyNativeFn as *const _,
166+
// ) =>
167+
// {
168+
// return object_getstate_default(obj, required, vm);
169+
// }
170+
// Ok(getstate) => getstate.into_pyref().into(),
171+
// Err(getstate) => getstate,
172+
// };
173+
// getstate.call((), vm).map(Some)
174+
// }
175+
76176
#[pyclass(with(Constructor), flags(BASETYPE))]
77177
impl PyBaseObject {
178+
#[pymethod(raw)]
179+
fn __getstate__(vm: &VirtualMachine, args: FuncArgs) -> PyResult {
180+
let (zelf,): (PyObjectRef,) = args.bind(vm)?;
181+
object_getstate_default(&zelf, false, vm).to_pyresult(vm)
182+
}
183+
78184
#[pyslot]
79185
fn slot_richcompare(
80186
zelf: &PyObject,

vm/src/protocol/object.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,8 @@ impl PyObject {
564564
}
565565

566566
// int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)
567-
pub fn type_check(&self, typ: PyTypeRef) -> bool {
568-
self.fast_isinstance(&typ)
567+
pub fn type_check(&self, typ: &Py<PyType>) -> bool {
568+
self.fast_isinstance(typ)
569569
}
570570

571571
pub fn length_opt(&self, vm: &VirtualMachine) -> Option<PyResult<usize>> {

vm/src/vm/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ declare_const_name! {
130130
__getformat__,
131131
__getitem__,
132132
__getnewargs__,
133+
__getstate__,
133134
__gt__,
134135
__hash__,
135136
__iadd__,

0 commit comments

Comments
 (0)
0