Migrate ten canonical production modules and fifteen complete canonical test files, retaining existing RustPython guards. Nine modules change behavior; heap removes duplicated allocation checks.
Assisted-by: OpenAI Codex:model version unavailable
Multiprocessing fork/spawn/forkserver now run in the main -j $CORES
CPython test job. Remove expectedFailureIf for os.killpg now that
killpg exists.
Assisted-by: Grok:4.6
accept/recv/send kept the socket RwLock during the syscall. After
fork, the child copied that held lock, so _ResourceSharer._afterfork
hung in listener.close().
Unskip fork connection pickling, pool task ref release, and spawn
thread-pool terminate. Add extra_tests for fork+accept close and
fork after DupFd.
Assisted-by: Grok:4.6
* Fix ctypes from_buffer writes and unskip passing MP tests
Write char-array .value/.raw through borrowed buffers instead of
Cow::to_mut(), which copied shared memory into a private buffer.
Unskip connection pickling, sharedctypes, Condition notify, and
concurrent.futures interpreter-shutdown tests. Cover forkserver
Condition notify and shared ctypes char arrays in extra_tests.
Assisted-by: Grok:4.6
* Unskip linux RLock repr; keep fork pickling hang skip
test_repr_rlock passed on Linux spawn/fork/forkserver. Connection
pickling hangs under the fork start method, so skip it only there.
Build the apple-container image from rust:bookworm; rust:bullseye
apt indexes 404.
Assisted-by: Grok:4.6
* Unskip multiprocessing RLock repr test
Assisted-by: Grok:4.6
* Drop stable modules from the flaky MP CI list
Assisted-by: Grok:4.6
* Keep only multiprocessing fork on the flaky MP list
Assisted-by: Grok:4.6
* Drop gc_collect bench and unbreak two CI jobs
Remove benches/benchmarks/gc_collect.py so CodSpeed no longer
includes that execution benchmark.
On Windows, run test_multiprocessing_spawn serially; the
parallel snippets job hit a regrtest worker temp-dir error
while that suite was still running.
Install cargo-shear from a pinned prebuilt binary so the job
does not fall back to compiling 1.13.4 from source.
Assisted-by: Grok:4.6
* Unskip hang tests that now pass under -m test
Drop the RustPython hang skips on interpreter shutdown,
submit-after-shutdown, and connection pickling after they
passed with rustpython -m test.
Remove the unused expectedFailureIf around killpg on the
resource tracker deadlock test; os.killpg is present.
Pass matrix flaky-MP extras through the job environment
instead of interpolating them into the run script.
Assisted-by: Grok:4.6
* Restore hang skips and isolate spawn on CI
Put test_multiprocessing_spawn and
test_multiprocessing_forkserver back on the serial flaky MP
list. Ubuntu timed out in spawn test_notify_all under -j, and
forkserver.test_processes needed a rerun.
Restore the hang skips on interpreter shutdown, submit-after
shutdown, and connection pickling.
Assisted-by: Grok:4.6
* Fix dict iterator __reduce__ to resume from current position
Pickling a partially-consumed dict / dict-view iterator restarted from the
beginning because __reduce__ materialized every entry and ignored the
iterator's position. Walk from the current position (mirroring next) so
only the not-yet-yielded entries are captured, matching CPython, which
reduces both directions to iter(remaining).
Fixing the reverse iterator also uncovered two pre-existing bugs in
reverse iteration itself, both from prev_entry saturating at 0: a hole
just above index 0 made the entry at 0 yield twice, and deleting the
first-inserted key made reversed() loop forever. prev_entry now returns
the found entry's actual index and stops cleanly at index 0, and the
reverse iterator/reduce detect exhaustion from that index.
Verified against CPython 3.14 across all pickle protocols, dict states
(including deletions), iterator kinds, and consumption counts. No
regressions in test_dict, test_dictviews, test_ordered_dict,
test_collections, test_userdict, test_iter, or test_copy.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Apply cargo fmt to dict.rs imports
Collapse the builtins import block left multi-line after removing the
now-unused builtins_reversed import.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Unmark TestSyncManagerTypes.test_dict as expectedFailure
The dict iterator __reduce__ fix makes SyncManager dict proxies pickle
correctly, so this test now passes under spawn and forkserver. Remove the
stale expectedFailure marker that was causing an UNEXPECTED SUCCESS CI
failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Bytecode parity phase 3
Compiler changes:
- Emit TO_BOOL in and/or short-circuit evaluation (COPY+TO_BOOL+JUMP)
- Add module-level __conditional_annotations__ cell (PEP 649)
- Only set conditional annotations for AnnAssign, not function params
- Skip __classdict__ cell when future annotations are active
- Convert list literals to tuples in for-loop iterables
- Fix cell variable ordering: parameters first, then alphabetical
- Fix RESUME DEPTH1 flag for yield-from/await
- Don't propagate __classdict__/__conditional_annotations__ freevar
through regular functions — only annotation/type-param scopes
- Inline string compilation path
* Skip test_thread_safety in _test_multiprocessing
SIGSEGV in _finalizer_registry dict access under aggressive GC
and thread switching. Root cause is dict thread-safety in VM.
* Skip list→tuple optimization for async for; propagate future_annotations to nested scopes
* Handle EINTR retry in os.write() (PEP 475)
Add EINTR retry loop to os.write(), matching the existing
pattern in os.read() and os.readinto(). Remove the
expectedFailure marker from test_write in _test_eintr.py.
* Add atomic snapshot for dict/dict_keys in extract_elements
Add fast paths for dict and dict_keys types in
extract_elements_with, matching _list_extend() in CPython
Objects/listobject.c. Each branch takes an atomic snapshot
under a single read lock, preventing race conditions from
concurrent dict mutation without the GIL.
Remove expectedFailure from test_thread_safety.
When -O flag removes assert statements, any nested scopes
(generators, comprehensions, lambdas) inside the assert
expression still have symbol tables in the sub_tables list.
Without consuming them, the next_sub_table index gets
misaligned, causing later scopes to use wrong symbol tables.
Walk the skipped assert expression with an AST visitor to
find and consume nested scope symbol tables, keeping the
index aligned with AST traversal order.
* Use patched parking_lot_core with fork-safe HASHTABLE reset
parking_lot_core's global HASHTABLE retains stale ThreadData after
fork(), causing segfaults when contended locks enter park(). Use the
patched version from youknowone/parking_lot (rustpython branch) which
registers a pthread_atfork handler to reset the hash table.
Unskip test_asyncio TestFork. Add Manager+fork integration test.
* Unskip fork-related flaky tests after parking_lot fix
With parking_lot_core's HASHTABLE now properly reset via
pthread_atfork, fork-related segfaults and connection errors
in multiprocessing tests should be resolved.
Remove skip/expectedFailure markers from:
- test_concurrent_futures/test_wait.py (6 tests)
- test_concurrent_futures/test_process_pool.py (1 test)
- test_multiprocessing_fork/test_manager.py (all WithManagerTest*)
- test_multiprocessing_fork/test_misc.py (5 tests)
- test_multiprocessing_fork/test_threads.py (2 tests)
- _test_multiprocessing.py (2 shared_memory tests)
Keep test_repr_rlock skipped (flaky thread start latency,
not fork-related).
* Fix thread-safety in GC, type cache, and instruction cache
GC / refcount:
- Add safe_inc() check for strong()==0 in RefCount
- Add try_to_owned() to PyObject for atomic refcount acquire
- Replace strong_count()+to_owned() with try_to_owned() in GC
collection and weakref callback paths to prevent TOCTOU races
Type cache:
- Add proper SeqLock (sequence counter) to TypeCacheEntry
- Readers spin-wait on odd sequence, validate after read
- Writers bracket updates with begin_write/end_write
- Use try_to_owned + pointer revalidation on read path
- Call modified() BEFORE attribute modification in set_attr
Instruction cache:
- Add pointer_cache (AtomicUsize array) to CodeUnits for
single atomic pointer load/store (prevents torn reads)
- Add try_read_cached_descriptor with try_to_owned + pointer
and version revalidation after increment
- Add write_cached_descriptor with version-bracketed writes
RLock:
- Fix release() to check is_owned_by_current_thread
- Add _release_save/_acquire_restore methods
* Fix RLock _acquire_restore tuple handling and unxfail threading test
* Align type cache seqlock writer protocol with CPython
* RLock: use single parking_lot level, track recursion manually
Instead of calling lock()/unlock() N times for recursion depth N,
keep parking_lot at 1 level and manage the count ourselves.
This makes acquire/release O(1) and matches CPython's
_PyRecursiveMutex approach (lock once + set level directly).
* Add try_to_owned_from_ptr to avoid &PyObject on stale ptrs
Use addr_of! to access ref_count directly from a raw pointer
without forming &PyObject first. Applied in type cache and
instruction cache hit paths where the pointer may be stale.
* Fix CI: spelling typo and xfail flaky test_thread_safety
- Fix "minimising" -> "minimizing" for cspell
- xfail test_thread_safety: dict iteration races with
concurrent GC mutations in _finalizer_registry
* gc module internal structure and API
Add gc_state module with GcState, GcGeneration, GcDebugFlags, GcStats.
Replace gc module stubs with working API backed by gc_state.
Add gc_callbacks and gc_garbage to Context.
Add is_gc_tracked, gc_finalized, gc_get_referents to PyObject.
Collection is stubbed (returns 0) — actual algorithm to follow.
* fix dict/weakref/generators
* unmark test_asyncio
* apply review