Skip to content

LA-62: Qualify callback-bearing native attribute mutation keys #757

Closed

Description

@ellainng

Scope

Finite follow-up under exception owner #124 and Track A #600, exposed by LA-59–LA-61 (#756).

Native attribute mutation must account for string-subtype keys whose hash/equality overrides participate in native type lookup. On pinned CPython 3.14.7, a key's hash callback can run even when mutation ultimately raises AttributeError; a lookup callback error may be suppressed before missing-name metadata is selected. Earlier missing-name cases with a raising hash and no output do not certify callback ordering or absence of callbacks.

The reflective layouts adopted by #756 explicitly refuse keys with owned hash/equality overrides before callbacks or mutation. Reconcile the corresponding behavior and claims for the other fixed native mutation layouts, including scalar/container/callable/view/generator/iterator receivers and writable native fields.

Acceptance

  • Exact CPython 3.14.7 reference matrix for hash/equality results, callback side effects, lookup failures, native data descriptors versus missing names, multiple mutation attempts, and any cache-dependent behavior.
  • Preserve original key/receiver identity, error selection, actual callback order, partial mutations and native receiver validation.
  • Owned execution through drain/step/parked Node and Chromium, collection/cancellation/close, shared resource budgets, composed modules/dynamic source and installed offline acceptance.
  • Remove a refusal only when its exact callback contract is adopted; retain separately qualified cache/host differences outside successful differential counts.

No broader formatting, source admission, library/package certification, release or deployment is implied.

Accepted — 2026-11-02

#760 is squash merged into main at 5072ae1 after complete local validation. All 678 shared PR-check IDs and 223 isolated installed-wheel offline checks pass, including the full Node/Chromium driver/profile matrix, parked collection/cancellation/close, shared limits, composed modules/dynamic source, original frames and offline Stop/Restart. Four browser worker-startup interruptions passed isolated one-worker retries; unchanged passing evidence was retained. The duplicate PR workflow was cancelled before merge.

The corpus adds 615 cases and adopts six prior reflective-key refusals. The final 2,443 cases contain 2,387 supported semantic/error comparisons and 56 explicit refusals, with 267 shared core cases and seven separate qualifications. Successful/NotImplemented equality, truth conversion and suppressed lookup errors select the actual native descriptor or dictionary storage. The first false comparison retains an explicit refusal after its effects: 16 seeded probes produced two or three comparisons for the same input. #759 owns that separately qualified path and it earns no supported differential credit.

The 140-site refusal audit and all eight revision-22 resource observations pass. The exact contract is in docs/interpreter-exceptions.md; examples/interpreter_native_keys.py runs unchanged on the pinned reference and offline console. #600/#124 record the broader remaining gates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions