Skip to content

Commit 79d70e3

Browse files
key262yekhbina
authored andcommitted
Enhance object dictionary handling in type and object modules
- Modify set_dict method to allow assigning dict to objects without existing dict - Update error handling in object_set_dict to provide more precise error message - Refactor type module to correctly handle dictionary assignment
1 parent c43327e commit 79d70e3

3 files changed

Lines changed: 16 additions & 6 deletions

File tree

vm/src/builtins/object.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,13 @@ pub fn object_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict
496496
.ok_or_else(|| vm.new_attribute_error("This object has no __dict__".to_owned()))
497497
}
498498

499-
pub fn object_set_dict(obj: PyObjectRef, dict: PySetterValue<PyDictRef>, vm: &VirtualMachine) -> PyResult<()> {
499+
pub fn object_set_dict(
500+
obj: PyObjectRef,
501+
dict: PySetterValue<PyDictRef>,
502+
vm: &VirtualMachine,
503+
) -> PyResult<()> {
500504
obj.set_dict(dict)
501-
.map_err(|_| vm.new_attribute_error("This object has no __dict__".to_owned()))
505+
.map_err(|_| vm.new_attribute_error("This object has no __dict__ to delete".to_owned()))
502506
}
503507

504508
pub fn init(ctx: &Context) {

vm/src/builtins/type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ fn subtype_set_dict(obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -
12881288
descr_set(&descr, obj, PySetterValue::Assign(value), vm)
12891289
}
12901290
None => {
1291-
object::object_set_dict(obj, PySetterValue::Delete, vm)?;
1291+
object::object_set_dict(obj, PySetterValue::Assign(value.try_into_value(vm)?), vm)?;
12921292
Ok(())
12931293
}
12941294
}

vm/src/object/core.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,21 +712,27 @@ impl PyObject {
712712

713713
/// Set the dict field. Returns `Err(dict)` if this object does not have a dict field
714714
/// in the first place.
715-
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Result<(), PyDictRef> {
715+
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Result<(), PySetterValue<PyDictRef>> {
716716
match (self.instance_dict(), dict) {
717717
(Some(d), PySetterValue::Assign(dict)) => {
718718
d.set(dict);
719719
Ok(())
720720
}
721-
(None, PySetterValue::Assign(dict)) => Err(dict),
721+
(None, PySetterValue::Assign(dict)) => {
722+
unsafe {
723+
let ptr = self as *const _ as *mut PyObject;
724+
(*ptr).0.dict = Some(InstanceDict::new(dict));
725+
}
726+
Ok(())
727+
}
722728
(Some(_), PySetterValue::Delete) => {
723729
unsafe {
724730
let ptr = self as *const _ as *mut PyObject;
725731
(*ptr).0.dict = None;
726732
}
727733
Ok(())
728734
}
729-
(None, PySetterValue::Delete) => Ok(()),
735+
(None, PySetterValue::Delete) => Err(PySetterValue::Delete),
730736
}
731737
}
732738

0 commit comments

Comments
 (0)