Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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
  • Loading branch information
key262yek authored and hbina committed Mar 23, 2025
commit c43327edb41e523b48d568a9a37bc1f45e206dd8
12 changes: 2 additions & 10 deletions vm/src/builtins/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,16 +497,8 @@ pub fn object_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict
}

pub fn object_set_dict(obj: PyObjectRef, dict: PySetterValue<PyDictRef>, vm: &VirtualMachine) -> PyResult<()> {
match dict {
PySetterValue::Assign(dict) => {
obj.set_dict(dict)
.map_err(|_| vm.new_attribute_error("This object has no __dict__".to_owned()))
}
PySetterValue::Delete => {
obj.delete_dict()
.map_err(|_| vm.new_attribute_error("This object has no deletable __dict__".to_owned()))
}
}
obj.set_dict(dict)
.map_err(|_| vm.new_attribute_error("This object has no __dict__".to_owned()))
}

pub fn init(ctx: &Context) {
Expand Down
36 changes: 4 additions & 32 deletions vm/src/object/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,49 +712,21 @@ impl PyObject {

/// Set the dict field. Returns `Err(dict)` if this object does not have a dict field
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc-comment doesn't fit in actual implementation anymore

/// in the first place.
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Option<()> {
// NOTE(hanif) - So far, this is the only error condition that I know of so we can use Option
// for now.
if self.payload_is::<crate::builtins::function::PyFunction>() {
return None;
}

pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Result<(), PyDictRef> {
match (self.instance_dict(), dict) {
(Some(d), PySetterValue::Assign(dict)) => {
d.set(dict);
Ok(())
}
(None, PySetterValue::Assign(dict)) => {
// self.0.dict = Some(InstanceDict::new(dict));
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = Some(InstanceDict::new(dict));
}
}
(None, PySetterValue::Assign(dict)) => Err(dict),
(Some(_), PySetterValue::Delete) => {
// self.0.dict = None;
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = None;
}
}
(None, PySetterValue::Delete) => {
// NOTE(hanif) - noop?
}
};

Some(())
}

pub fn delete_dict(&self) -> Result<(), ()> {
match self.instance_dict() {
Some(_) => {
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = None;
}
Ok(())
}
Comment on lines +733 to +739
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(Some(_), PySetterValue::Delete) => {
// self.0.dict = None;
unsafe {
let ptr = self as *const _ as *mut PyObject;
(*ptr).0.dict = None;
}
}
(Some(dict), PySetterValue::Delete) => {
dict.write().clear();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't do this because it only have &self.

None => Err(()),
(None, PySetterValue::Delete) => Ok(()),
}
}

Expand Down