⚡ Sangsakala Proxy 🏠 Home
Skip to content

Share exception state and callback controls - #9719

Draft
youknowdot wants to merge 2 commits into
RustPython:mainfrom
youknowdot:fix/exception-state-controls-20261104
Draft

youknowdot wants to merge 2 commits into
RustPython:mainfrom
youknowdot:fix/exception-state-controls-20261104

Conversation

@youknowdot

@youknowdot youknowdot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Group CPython 3.15 exception state, construction and callback controls in 377 changed lines across four production Rust files.

  • Keep BaseException allocation permissive while rejecting initializer keywords before mutating args. Preserve lazy exception dictionaries through the shared Constructor path, including specialized exception payloads; nonexception allocation is unchanged.

  • Make public BaseException/KeyError formatting propagate callback errors and preserve WTF-8. Snapshot the short type name before argument callbacks. Retain the forgiving internal diagnostic formatter and its buffered-I/O caller.

  • Restore every raw state entry, including dunder attributes, through setattr without stringifying keys. Preserve string-subclass identity and stop at the first setter error.

  • Use dynamic optional notes lookup and dynamic list creation. Preserve the typed Rust add_note API behind a Python validation wrapper; append to the actual list payload rather than an overridden append method.

  • Share exact-tuple identity, exact-list copying and unhinted iterable conversion between tuple construction and exception args assignment. Borrow the original setter input through replacement so temporary-source finalizers cannot run prematurely.

  • Preserve complete args and allocated-empty-dict identity in reduction. ImportError copies state only when adding native fields; AttributeError preserves ordinary dictionary entries while excluding its native obj field.

  • Share bounded type-name diagnostics with CPython's UTF-8 byte limits and None spelling.

  • Retain the originally installed args tuple through initializer callbacks. SystemExit preserves existing code on empty reinitialization and shares the exact multiargument tuple; StopIteration retains extra incoming owners until value publication.

  • Initialize AttributeError, ImportError and NameError args before rejecting keyword errors, then reuse ArgSpec for maximum-count and insertion-order validation while retaining raw keyword owners. ImportError derives msg from the original tuple even if old-args cleanup reenters initialization.

Validation

Reference source: CPython d220409a13b77de7a6c30abe16ea90db01528edc. Independent source review passed for the frozen four-file patch, including ownership, callback order, locks, dictionary allocation, typed APIs and existing-peer scope.

The reference oracle passed 32 checkpoints, including three explicitly excluded residual controls. Five implementation supplements, ten byte-boundary diagnostics and nine independent supplementary checkpoints also passed on CPython. These are reference/source checks, not execution of RustPython. Existing tests/Lib files, assertions, expected failures and workflows are unchanged.

Final threaded cargo check passed in 1m09s and all-targets Clippy in 2m27s. All 12 unchanged baseline diagnostics match exactly; no warnings were suppressed. Ordinary commit hooks passed. Native RustPython was not run because the required execution guard has not been verified. Full workspace/C-API suites, native runtime differential tests and separate platform/feature graphs remain unrun; hosted CI is pending.

The initializer follow-up is independently reviewed against an additional 49-check CPython oracle, of which 23 checkpoints cover selected controls and negative controls; the remaining checkpoints document excluded behaviors. An additional independent initializer oracle passed 83 checkpoints covering reentrant initialization, ownership survival, failure state, keyword order and metadata. Final follow-up source review, compilation, Clippy and ordinary commit hooks passed.

Limits and integration

Generic tuple conversion's allocation-boundary failure cleanup, tuple/structseq teardown, and caller-wide argument destruction are not solved by this group. ExceptionGroup conversion/repr behavior and SystemExit empty-reinitialization code retention were the three deliberately excluded controls in the original oracle; the initializer follow-up now fixes the SystemExit case. Specialized native layouts and OSError's specialized reduction are unchanged. The existing PyAtomicRef deferred reclamation remains necessary for borrow safety, so immediate CPython field-finalizer timing is not claimed. Shared ArgSpec typo suggestions/surrogate diagnostics remain outside this initializer follow-up; the unmerged #9718 parser changes are not duplicated. SyntaxError initializer changes overlap #8348 and are excluded. ExceptionGroup work remains in #9588 rather than being duplicated here.

The shared Constructor change is limited to BASE_EXC_SUBCLASS and retains the existing checked payload/type allocation path. It prevents freshly constructed specialized exceptions from acquiring an observable empty state dictionary merely as an allocation side effect.

Examined peers for reporting, native layouts, GC, SyntaxError storage and ExceptionGroup derivation do not implement these contracts. Their eventual textual composition must preserve each independent behavior. Public fallible exception formatting and the new tuple helper affect Rust integration; in-tree call sites were updated, while internal forgiving reporting remains separate.

AI-assisted contribution by OpenAI Codex; assistance is disclosed in the commit trailer.

Preserve lazy dictionaries and reduction identity, propagate public formatting errors, honor dynamic state and note protocols, and share borrowed tuple conversion while retaining internal diagnostic behavior.

Assisted-by: OpenAI Codex:model version not exposed
@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Share raw argument installation and keyword validation while retaining original owners across reentrant cleanup.

Assisted-by: OpenAI Codex:model version not exposed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant