Skip to content

Align namespace, super and dictionary controls - #9708

Merged
youknowone merged 6 commits into
RustPython:mainfrom
youknowdot:fix/namespace-controls-20261104
Nov 6, 2026
Merged

youknowone merged 6 commits into
RustPython:mainfrom
youknowdot:fix/namespace-controls-20261104

Conversation

@youknowdot

@youknowdot youknowdot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Group namespace, mapping-proxy, super lookup and dictionary lookup/iterator controls for Python 3.15 in six Rust source files (+441/-456).

SimpleNamespace

  • Convert non-exact dictionary inputs through the normal mapping protocol, validate all keys before mutation, and write instance dictionaries directly rather than invoking attribute setters/descriptors.
  • Accept any SimpleNamespace subtype returned by replacement construction, retain its fields, and apply replacement keywords directly.
  • Snapshot repr keys while looking up live values, reuse dictionary hash-error handling, and release snapshot owners backwards under the recursion guard on both success and error.
  • Remove weak-reference support from the exact base while retaining normal subclass behavior.

Mapping proxies and shared dictionary lookup

  • Route containment through fallible mapping controls, propagating hash/equality failures rather than panicking. Native namespace fallback lookups also honor dictionary key callbacks.

  • Delegate union and str to the underlying mappings, preserve arbitrary callback results, accept the named mapping constructor argument, and correct inplace-union diagnostics.

  • Keep dictionary-backed class views and iterators attached to the actual namespace; copy remains a separate operation. Preserve Align mapping boundaries with Python 3.15 final #9128's defensive exact-dict copy for unknown comparison peers and Preserve raw mappingproxy rich-comparison results #9039's raw comparison results.

  • Revalidate shared read probes after equality and temporary-key finalizers. Check the current table and candidate before using its entry, restart invalid probes, and extract values under the validated read guard. Do not retain earlier rejected keys or introduce a second per-method probe algorithm.

  • Make cached dictionary hints identity-only, avoiding unrelated key equality and stale values. Reuse the same validated lookup extraction for refreshed hints, so values are cloned before releasing the read guard.

Dictionary iterators

  • Share checked state and stepping across keys, values and items in both directions, including reduction snapshots that do not advance or poison the original iterator.
  • Track live remaining elements instead of physical slots, allowing ordinary same-used key replacement while retaining private relocation safeguards. Distinguish sticky size failures from terminal excess-key failures.
  • Clone only projected references under the dictionary/iterator guards, then allocate tuples/errors and release detached dictionary owners outside those guards. Existing set iteration checks remain unchanged.

Super namespace lookup

  • Share fallible class-namespace lookup with mapping proxies. Preserve the original query object for heap dictionaries and string-subclass keys, propagate hash/equality errors, and find fresh names inserted into live class dictionaries. Exact-string native lookups retain their map fast path.
  • Snapshot the MRO and release its read lock before dictionary callbacks, then release the owned snapshot before descriptor dispatch or generic fallback. Descriptor owner and instance arguments remain unchanged.
  • Use optional obj.__class__ lookup, correct the missing zero-argument class-cell exception, preserve native type-name prefixes and 200-byte diagnostics, and reject keywords before positional binding through a small preflight around the existing argument binder.

Validation

  • Compared against CPython d220409a13b77de7a6c30abe16ea90db01528edc namespaceobject.c, descrobject.c and dictobject.c.
  • External CPython 3.15.0 namespace oracle and independent review passed, including hash callbacks, mutations, rejected mappings, subtype replacement, and finalizer reentry on success/error.
  • Mappingproxy oracle: 94 controls passed. Shared dictionary oracle: 38 controls passed, including deletion, replacement at recycled coordinates, table resize, live value updates, finalizer-before-retry and exception traceback owners. Dedicated independent core review checked probe lifetimes and table validation separately.
  • Ten additional isolated attribute-read oracle groups passed: wrong-hash callbacks are skipped, and key/value mutation, removal, replacement, resize, errors and finalizer reentry produce the current result. Independent hinted-read ownership/lock review passed on the final patch.
  • Dictionary iterator reference coverage: 159 candidate-focused assertions plus 90 independent ownership/reentry assertions passed. Independent source review checked state snapshots, terminal transitions, dictionary ownership, lock scopes and GC traversal.
  • Super reference coverage: 43 original controls, 12 focused diagnostic checks and 48 independent checks passed pinned CPython. Independent source review covered error identity, query controls, namespace/MRO ownership, lock scopes, descriptors, subclass initializers and documented native-snapshot limitations. These are reference results, not native RustPython runtime results.
  • Final composed threaded cargo check passed (1m02s), all-targets Clippy passed (2m09s), and normal commit hooks passed. All twelve baseline diagnostics in host_env/socket, VM POSIX and ElementTree are unchanged; no suppression was added.

Limits

Native RustPython execution remains unperformed because the required safety guard is not verified. One existing Rust unit-test invocation is mechanically adjusted for the now-infallible hint API; its assertion and expected value are unchanged. No Python tests, test markers, or workflows were modified. Hosted runtime CI remains necessary.

Attributes-backed native namespaces still require materialized snapshots. This includes mutable AST namespace views, callbacks changing those namespaces, and union-exposed backing-dictionary identity. Only actual dictionary-backed class namespaces become live; no type-storage redesign is included. For super lookups with callback-bearing queries, a native AST namespace mutation can still leave the materialized snapshot stale and postpone destruction of replaced values. The native exact-string fast path has no Python key callbacks.

The read-probe correction uses allocation identity like CPython, not a new mutation-history counter. Same-key clear/reinsert callback counts can depend on allocator reuse; no universal count claim is made for that case. Hinted reads are included; concurrent races after separate mutation lookup/commit phases, including pop/remove_if, remain outside this patch. No broad operation-atomicity or native stress-test claim is made. Existing module-qualification differences in SimpleNamespace replacement rejection diagnostics are also unchanged.

Integration: #9681's separate reentrant LRU mutation helpers are unchanged and must remain on composition. Older #6215 instead raises on changed dictionary size; this patch follows CPython restart semantics rather than adopting that behavior. Broad ownership work in #8944/#8939 may require textual reconciliation. Those PRs already include an owned super MRO snapshot; preserve that change when composing. They do not supply the fallible raw namespace/query controls added here.

Dictionary iterator limitations: private relocation guards remain conservative for internal compaction. Cached item-result tuple ownership/identity and view-intersection error cleanup remain separately identified follow-ups; this patch does not mutate published tuples or claim those fixes. No concurrent stress/benchmark pass is claimed.

Ownership integration detail: #8939/#8944 create AST classes as interpreter-local heap types with real dictionaries. That should remove the specific AST snapshot gap when combined with this lookup helper, but this conclusion is source-only. The new owned dictionary accessor must resolve their interpreter-local namespace before returning it; shared native runtime namespaces should use a real interpreter-owned dictionary. Preserve bootstrap Attributes, stable native identities and registry initialization/GC ordering. Do not attach a runtime dictionary to a process-global native definition or keep a second value-owning Attributes mirror. This integration has not been implemented or compiled in this PR.

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

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

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

Propagate key callback errors, retain live dictionary-backed class views, and revalidate shared read probes after equality and finalizer callbacks.

Assisted-by: OpenAI Codex:model version not exposed
@youknowdot youknowdot changed the title Align SimpleNamespace dictionary and callback controls Align namespace and mapping proxy dictionary controls Nov 4, 2026
Assisted-by: OpenAI Codex:model version not exposed
Assisted-by: OpenAI Codex:model version not exposed
Assisted-by: OpenAI Codex:model version not exposed
@youknowdot youknowdot changed the title Align namespace and mapping proxy dictionary controls Align namespace and dictionary controls Nov 4, 2026
Share fallible namespace reads with mapping proxies and retain original query behavior without holding the MRO lock across callbacks.

Assisted-by: OpenAI Codex:model version not exposed
@youknowdot youknowdot changed the title Align namespace and dictionary controls Align namespace, super and dictionary controls Nov 4, 2026
@youknowone
youknowone marked this pull request as ready for review November 6, 2026 12:48
@youknowone
youknowone merged commit 23b661c into RustPython:main Nov 6, 2026
18 of 20 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ❌ Failed 2026-11-06T12:48:43.320020Z
We couldn’t complete this review. Comment @codex review to try again.
a9b7067 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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.

2 participants