Compare commits

...

3 Commits

Author SHA1 Message Date
b8d6f7b594 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
2025-02-15 00:56:39 +09:00
dc0a75e903 Refactor object dictionary setter to handle delete and assign operations
- Simplify object_set_dict method in object.rs
- Update set_dict method in core.rs to handle both assignment and deletion
- Consolidate dictionary modification logic
2025-02-15 00:12:19 +09:00
c40d24ed68 Implement delete object dictionary
- Add support for deleting object dictionaries
- Modify object_set_dict to handle dictionary deletion
- Update setter value handling to support delete operations
2025-02-10 10:30:17 +09:00
4 changed files with 31 additions and 9 deletions

View File

@@ -495,9 +495,14 @@ pub fn object_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict
obj.dict()
.ok_or_else(|| vm.new_attribute_error("This object has no __dict__".to_owned()))
}
pub fn object_set_dict(obj: PyObjectRef, dict: PyDictRef, vm: &VirtualMachine) -> PyResult<()> {
pub fn object_set_dict(
obj: PyObjectRef,
dict: PySetterValue<PyDictRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
obj.set_dict(dict)
.map_err(|_| vm.new_attribute_error("This object has no __dict__".to_owned()))
.map_err(|_| vm.new_attribute_error("This object has no __dict__ to delete".to_owned()))
}
pub fn init(ctx: &Context) {

View File

@@ -1288,7 +1288,7 @@ fn subtype_set_dict(obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -
descr_set(&descr, obj, PySetterValue::Assign(value), vm)
}
None => {
object::object_set_dict(obj, value.try_into_value(vm)?, vm)?;
object::object_set_dict(obj, PySetterValue::Assign(value.try_into_value(vm)?), vm)?;
Ok(())
}
}

View File

@@ -36,8 +36,10 @@ where
{
#[inline]
fn from_setter_value(vm: &VirtualMachine, obj: PySetterValue) -> PyResult<Self> {
let obj = obj.ok_or_else(|| vm.new_type_error("can't delete attribute".to_owned()))?;
T::try_from_object(vm, obj)
match obj {
PySetterValue::Assign(obj) => T::try_from_object(vm, obj),
PySetterValue::Delete => T::try_from_object(vm, vm.ctx.none()),
}
}
}

View File

@@ -25,6 +25,7 @@ use crate::{
lock::{PyMutex, PyMutexGuard, PyRwLock},
refcount::RefCount,
},
function::PySetterValue,
vm::VirtualMachine,
};
use itertools::Itertools;
@@ -707,13 +708,27 @@ impl PyObject {
/// Set the dict field. Returns `Err(dict)` if this object does not have a dict field
/// in the first place.
pub fn set_dict(&self, dict: PyDictRef) -> Result<(), PyDictRef> {
match self.instance_dict() {
Some(d) => {
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Result<(), PySetterValue<PyDictRef>> {
match (self.instance_dict(), dict) {
(Some(d), PySetterValue::Assign(dict)) => {
d.set(dict);
Ok(())
}
None => Err(dict),
(None, PySetterValue::Assign(dict)) => {
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = Some(InstanceDict::new(dict));
}
Ok(())
}
(Some(_), PySetterValue::Delete) => {
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = None;
}
Ok(())
}
(None, PySetterValue::Delete) => Err(PySetterValue::Delete),
}
}