Repository navigation
Fix object.__getstate__ deadlock and panic on __slotnames__ - #8981
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
📦 Library DependenciesThe following Lib/ modules were modified. Here are their dependencies: :4: SyntaxWarning: invalid decimal literal dependencies: dependent tests: (no tests depend on descr) Legend:
|
Merging this PR will improve performance by 10.98%
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
|
@luantaraschi thank you for the patch! windows test hang looks like regression of this patch. could you take a look? |
object_getstate_default kept the __slotnames__ list read-locked while it looked up each slot attribute. A getter or __getattr__ that changed the list (as in test_descr.test_issue24097) then waited forever for the write lock. A non-str entry in a cached __slotnames__ hit an unwrap and panicked. Take a reference to each name and drop the lock before the lookup, raise TypeError for a non-str name, let errors other than AttributeError propagate, and check the list size after each item, as CPython does. Assisted-by: Claude Code:claude-opus-5-5
0026fce to
e66a99c
Compare
|
I looked into it, and I don't think it's this patch. The same four I rebased onto main. The only conflict was in |
youknowone
left a comment
There was a problem hiding this comment.
Thank you for confirming! and sorry to ask you to check a fake issue.
Probably it was flaky and I was not lucky enough to pass it on second run.
Summary
object_getstate_defaultheld the__slotnames__read lock while it looked up each slot attribute. If a getter or__getattr__mutates the list during that lookup, which is exactly whattest_descr.test_issue24097does, it blocks on the write lock forever. On main that test hangs until the runner's 30 s timeout, so it was skipped.A non-str entry in a cached
__slotnames__hitdowncast_ref::<PyStr>().unwrap()instead:The loop now clones each name out of the list and drops the lock before the lookup, and raises
TypeError: attribute name must be string, not 'int'for a non-str name. OnlyAttributeErroris ignored now (throughget_attribute_opt): before, any exception from the lookup was swallowed, so a__getattr__raisingValueErrorgave a state ofNonewhere CPython raises. The size check runs after each item, as CPython does.Compared with CPython 3.14.7: the non-str and
ValueErrorcases now raise the same exception and message. The mutating case raisesRuntimeErrorlike CPython does, with our existing message (CPython spells it__slotsname__). A missing attribute is still skipped.test_issue24097intest_descr.pyis unskipped and passes. Fulltest_descr: OK.extra_tests/snippets/builtin_object.py.test_copy,test_copyreg,test_pickle,test_collections,test_dataclasses,test_enum,test_xml_etree,test_functools,test_dequeandtest_iopass as on main.cargo testfor the workspace (with the AGENTS.md exclusions),clippy -Dwarnings,cargo fmt --checkandcheck_redundant_patches.pyare clean. Linux only.Written with Claude Code (claude-opus-5-5) as a tool. I reviewed the diff and reproduced the hang and the panic before and after the change myself.
Summary by CodeRabbit
object.__getstate__handling of slot names: invalid entries and changes to the list during lookup now raise clear errors, and errors reading slot values are no longer suppressed.