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
Address CodeRabbit concerns: fix GC clearing and improve thread safet…
…y of lazy __dict__ recreation
  • Loading branch information
alok-108 committed Apr 6, 2026
commit 28c5fe2c2b7a57550326a75afcb44614524d6979
6 changes: 1 addition & 5 deletions crates/vm/src/builtins/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,11 +558,7 @@ pub fn object_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDict
Ok(dict)
} else {
match obj.instance_dict() {
Some(d) => {
let dict = vm.ctx.new_dict();
d.set(Some(dict.clone()));
Ok(dict)
}
Some(d) => Ok(d.get_or_insert(vm)),
None => Err(vm.new_attribute_error("This object has no __dict__")),
}
}
Expand Down
20 changes: 16 additions & 4 deletions crates/vm/src/object/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,8 +909,8 @@ impl Py<PyWeak> {
}

#[derive(Debug)]
pub(super) struct InstanceDict {
pub(super) d: PyRwLock<Option<PyDictRef>>,
pub(crate) struct InstanceDict {
pub(crate) d: PyRwLock<Option<PyDictRef>>,
}

impl From<PyDictRef> for InstanceDict {
Expand Down Expand Up @@ -948,6 +948,17 @@ impl InstanceDict {
pub fn into_inner(self) -> Option<PyDictRef> {
self.d.into_inner()
}

pub(crate) fn get_or_insert(&self, vm: &VirtualMachine) -> PyDictRef {
let mut d = self.d.write();
if let Some(existing) = d.as_ref() {
existing.clone()
} else {
let dict = vm.ctx.new_dict();
*d = Some(dict.clone());
dict
}
}
}

impl<T: PyPayload> PyInner<T> {
Expand Down Expand Up @@ -1776,8 +1787,9 @@ impl PyObject {
let ext = unsafe { &mut *ext_ptr };
if let Some(old_dict) = ext.dict.take() {
// Get the dict ref before dropping InstanceDict
let dict_ref = old_dict.into_inner();
result.push(dict_ref.into());
if let Some(dict_ref) = old_dict.into_inner() {
result.push(dict_ref.into());
}
}
for slot in ext.slots.iter() {
if let Some(val) = slot.write().take() {
Expand Down
Loading