MCPcopy Index your code
hub / github.com/RustPython/RustPython / object_getstate_default

Function object_getstate_default

crates/vm/src/builtins/object.rs:192–269  ·  view source on GitHub ↗

object_getstate_default

(obj: &PyObject, required: bool, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

190
191// object_getstate_default
192fn object_getstate_default(obj: &PyObject, required: bool, vm: &VirtualMachine) -> PyResult {
193 // Check itemsize
194 if required && obj.class().slots.itemsize > 0 {
195 return Err(vm.new_type_error(format!("cannot pickle {:.200} objects", obj.class().name())));
196 }
197
198 let state = if obj.dict().is_none_or(|d| d.is_empty()) {
199 vm.ctx.none()
200 } else {
201 // let state = object_get_dict(obj.clone(), obj.ctx()).unwrap();
202 let Some(state) = obj.dict() else {
203 return Ok(vm.ctx.none());
204 };
205 state.into()
206 };
207
208 let slot_names =
209 type_slot_names(obj.class(), vm).map_err(|_| vm.new_type_error("cannot pickle object"))?;
210
211 if required {
212 // Start with PyBaseObject_Type's basicsize
213 let mut basicsize = vm.ctx.types.object_type.slots.basicsize;
214
215 // Add __dict__ size if type has dict
216 if obj.class().slots.flags.has_feature(PyTypeFlags::HAS_DICT) {
217 basicsize += core::mem::size_of::<PyObjectRef>();
218 }
219
220 // Add __weakref__ size if type has weakref support
221 let has_weakref = if let Some(ref ext) = obj.class().heaptype_ext {
222 match &ext.slots {
223 None => true, // Heap type without __slots__ has automatic weakref
224 Some(slots) => slots.iter().any(|s| s.as_bytes() == b"__weakref__"),
225 }
226 } else {
227 let weakref_name = vm.ctx.intern_str("__weakref__");
228 obj.class().attributes.read().contains_key(weakref_name)
229 };
230 if has_weakref {
231 basicsize += core::mem::size_of::<PyObjectRef>();
232 }
233
234 // Add slots size
235 if let Some(ref slot_names) = slot_names {
236 basicsize += core::mem::size_of::<PyObjectRef>() * slot_names.__len__();
237 }
238
239 // Fail if actual type's basicsize > expected basicsize
240 if obj.class().slots.basicsize > basicsize {
241 return Err(vm.new_type_error(format!("cannot pickle '{}' object", obj.class().name())));
242 }
243 }
244
245 if let Some(slot_names) = slot_names {
246 let slot_names_len = slot_names.__len__();
247 if slot_names_len > 0 {
248 let slots = vm.ctx.new_dict();
249 for i in 0..slot_names_len {

Callers 2

__getstate__Method · 0.85
object_getstateFunction · 0.85

Calls 15

type_slot_namesFunction · 0.85
noneMethod · 0.80
has_featureMethod · 0.80
intern_strMethod · 0.80
contains_keyMethod · 0.80
new_dictMethod · 0.80
borrow_vecMethod · 0.80
ErrClass · 0.50
classMethod · 0.45
dictMethod · 0.45
is_emptyMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected