spec 1724: Builtins/types panel re-audit to ground-truth green#95
Merged
Conversation
The string-to-int conversion limit lives in a package global, so a child interpreter spun up by _testcapi.run_in_subinterp could change it and leave the parent's value clobbered. CPython parks the limit on the interpreter state (interp->long_state.max_str_digits), so each interpreter has its own. Add a snapshot/restore hook: PushSubinterp captures the parent value and PopSubinterp restores it, registered from module/sys. Fixes test_int.test_int_max_str_digits_is_per_interpreter.
type creation was adding the managed-dict and weakref getset descriptors before copying the class body into tp_dict, so they sorted ahead of the namespace keys and a class that declared its own __dict__ lost to the synthesized one. CPython runs type_new_descriptors after type_new_set_attrs and uses PyDict_SetDefaultRef, so a user-provided slot wins. Defer the install behind an nsHasName guard to match. Also clear the thread exception in the default breakpoint hook before warning: when PYTHONBREAKPOINT names an unimportable target the hook swallows the ModuleNotFoundError in favour of a RuntimeWarning, the same as sys_breakpointhook calling PyErr_Clear, so a later handler does not observe the stale error. Fixes test_builtin test_namespace_order and test_envar_unimportable.
The 1726 bridge runs the cpython_only tests that exercise these test-only C helpers. test_bytes.test_obsolete_write_lock asks _testcapi to call PyObject_GetBuffer with a NULL Py_buffer* and expects BufferError; test_dict's CAPI test calls _testinternalcapi.dict_getitem_knownhash. Port both, plus a GetItemKnownHashOrKeyError that raises KeyError on a miss the way _PyDict_GetItem_KnownHash does. Also clear the thread exception when bytes(int) rejects a value so the swallowed error does not linger.
Re-ran the whole Builtins/types panel under the 1726 bridge for ground truth. The earlier residuals for test_int (subinterpreter leak), test_bytes (null-view helper) and test_builtin (breakpoint clear + namespace order) are fixed; only test_dict's two impl-detail divergences remain. Update the spec checklist, the residuals list, and the manifest counts to match.
Owner
Author
|
CI is green across the matrix (macOS, Linux, Windows) plus vet, lint and cfg-phase-parity. For the record, the full Builtins/types panel run from test/cpython/ this build:
The two residuals are impl-detail only and chasing either would reverse a deliberate design choice (no PEP 412 split tables; borrow-model iterator from spec 1727), so I left them documented with citations rather than shimmed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-ran the whole Builtins/types panel (spec 1724) under the 1726 bridge to get
ground truth, then fixed everything that turned out to be a real gopy bug. The
panel is now 28 of 29 files fully green; the one file with residuals (test_dict)
is down to two documented implementation-detail divergences.
What was actually broken
int_max_str_digits leaked across subinterpreters. The limit lived in a
package global, so a child interpreter from
_testcapi.run_in_subinterpcouldchange it and leave the parent clobbered. CPython keeps it on the interpreter
state. Added a snapshot/restore hook driven from PushSubinterp/PopSubinterp and
registered it from module/sys. Fixes
test_int.test_int_max_str_digits_is_per_interpreter.Type creation ordered the synthesized dict/weakref descriptors ahead
of the class body. A class that declares its own
__dict__lost to thegenerated one. CPython installs those getsets after copying the namespace in
and uses SetDefaultRef semantics so a user slot wins. Deferred the install
behind a name guard. Fixes
test_builtin.test_namespace_order.The default breakpoint hook left a stale thread exception. When
PYTHONBREAKPOINT names an unimportable target the hook swallows the
ModuleNotFoundError in favour of a RuntimeWarning, but did not clear the thread
exception the way sys_breakpointhook calls PyErr_Clear, so a later handler saw
the stale error. Fixes
test_builtin.test_envar_unimportable.Two test-only C helpers were missing.
getbuffer_with_null_view(test_bytes) and
dict_getitem_knownhash(test_dict CAPI test). Ported both,plus a KnownHash lookup that raises KeyError on a miss.
Left as documented residuals
test_dict keeps two failures, both
@cpython_only-style implementation details:test_splittable_popiteminspects the PEP 412 split-table dict layout throughsys.getsizeof. gopy uses a single combined representation, so there is nosplit-to-combined growth to observe.
test_oob_indexing_dictiter_iternextitemrelies on the items iteratorrecycling one result tuple and decreffing the previous value to zero mid-loop,
firing
__del__synchronously. gopy's IterNext returns a borrowed reference(spec 1727) and allocates a fresh tuple per advance; the in-place reuse that
would match CPython previously broke
sorted(d.items()).Both would mean reversing a deliberate gopy design choice for no Python-visible
behaviour, so they stay as residuals with citations in the spec rather than a
shim. The full reasoning is in website/docs/specs/1700/1724.
Ground truth for the whole panel (run from test/cpython/): every file OK except
the two test_dict residuals above.