Fix store subscr list finalizer deadlock (#8956)

* Release replaced list item outside the lock in STORE_SUBSCR_LIST_INT

Assisted-by: Claude Code:claude-opus-5-5

* Add a snippet for finalizers reading a list during a specialized store

Assisted-by: Claude Code:claude-opus-5-5
This commit is contained in:
Chanho Lee authored and GitHub committed 2026-10-04 22:47:45 +09:00
1 parent f39b054b9c
commit 7536730ed6
2 files changed
+35 -1

No files matched your search

+5 -1
View File
@@ -6430,7 +6430,11 @@ impl ExecutingFrame<'_> {
{
let mut vec = list.borrow_vec_mut();
if i < vec.len() {
vec[i] = value;
// Unlock before dropping the replaced element; its
// finalizer may access this list.
let old = core::mem::replace(&mut vec[i], value);
drop(vec);
drop(old);
return Ok(None);
}
}
+30
View File
@@ -342,3 +342,33 @@ def module_attribute_custom_dict_key():
module_attribute_custom_dict_key()
## STORE_SUBSCR_LIST_INT: the replaced element's finalizer can read the list
def store_subscr_list_int_finalizer_reads_list():
target = [None]
seen = []
class Item:
def __init__(self, value):
self.value = value
def __del__(self):
seen.append((self.value, len(target), target[0] is self))
def store(value):
target[0] = value
for i in range(300):
store(Item(i))
assert any(
op.opname == "STORE_SUBSCR_LIST_INT"
for op in dis.get_instructions(store, adaptive=True)
)
store(None)
assert seen == [(i, 1, False) for i in range(300)]
store_subscr_list_int_finalizer_reads_list()