520 Commits

Author SHA1 Message Date
Jeong, YunWon
18657330c9 Drop old PyObjectRef outside type lock to prevent deadlock
Dropping values inside with_type_lock can trigger weakref callbacks,
which may access attributes (LOAD_ATTR specialization) and re-acquire
the non-reentrant type mutex, causing deadlock.

Return old values from lock closures so they drop after lock release.
2026-03-21 00:39:45 +09:00
Jeong, YunWon
ea2d66e799 type lock 2026-03-20 22:47:55 +09:00
Jeong, YunWon
38de7462c0 Fix Constants newtype usage in init_cleanup_code 2026-03-20 22:47:55 +09:00
Jeong, YunWon
cb2db07463 Extract datastack_frame_size_bytes_for_code, skip monitoring for init_cleanup frames, guard trace dispatch
- Extract datastack_frame_size_bytes_for_code as free function, use it
  to compute init_cleanup stack bytes instead of hardcoded constant
- Add monitoring_disabled_for_code to skip instrumentation for
  synthetic init_cleanup code object in RESUME and execute_instrumented
- Add is_trace_event guard so profile-only events skip trace_func dispatch
- Reformat core.rs (rustfmt)
2026-03-20 22:47:55 +09:00
Jeong, YunWon
fb0dfa102c address review: invalidate init cache on type modification, add cspell words 2026-03-20 22:47:55 +09:00
Jeong, YunWon
9df4787aed Align call-init frame flow and spec cache atomic ordering 2026-03-20 22:47:55 +09:00
Jeong, YunWon
e19335e8f2 Tighten CALL_ALLOC_AND_ENTER_INIT stack-space guard 2026-03-20 22:47:55 +09:00
Jeong, YunWon
b3daabf169 Align type _spec_cache and latin1 singleton string paths 2026-03-20 22:47:55 +09:00
Jeong, YunWon
471fe551fa Align BINARY_OP_EXTEND with CPython descriptor cache model 2026-03-20 22:47:55 +09:00
Lee Dogeon
38f742aa8d Implement Hashable for PyBoundMethod (#7474) 2026-03-20 13:15:40 +00:00
김은빈
1b9dc4ef14 Detect list mutation during sort even when list length is unchanged (#7432)
* Detect list mutation during sort even when list length is unchanged

* Use mutation counter instead of capacity check for sort mutation detection

The capacity heuristic missed mutations when `clear()` reset capacity to
0 via `mem::take`. An AtomicU32 counter on PyList, incremented in
`borrow_vec_mut()`, reliably detects all mutations during sort.

* Hold write guard during sort mutation counter reads

* Fix list mutation counter race in `borrow_vec_mut`
2026-03-20 21:40:54 +09:00
Jeong, YunWon
8be5230a9b Fix allow_threads and EINTR handling (#7457)
* Fix allow_threads and EINTR handling

- Wrap Windows SemLock acquire wait with allow_threads
- Retry nanosleep on EINTR with remaining time instead of
  returning early
- Remove expectedFailure for test_sleep in _test_eintr.py

* Remove expectedFailureIfWindows for testHashComparisonOfMethods
2026-03-20 19:59:13 +09:00
Shahar Naveh
68cf736a9f Add cargo shear CI step (#7461)
* Add `cargo shear` CI step

* Remove some deps

* Move `ruff_python_parser` to dev deps

* Remove `thread_local` crate

* Cleanup `num-integer` usage

* Remove parser fro. wasm

* Remove windows-sys from venv launcher

* Update lock

* Resolve more

* Fix wasm

* Update lock
2026-03-20 12:42:51 +09:00
김은빈
79e17cb1cf Fix subclass right-op dispatch for Python classes (#7462)
* Fix subclass right-op dispatch for Python classes

* Separate fallback queueing from subclass priority in op dispatch
2026-03-19 09:51:56 +09:00
Copilot
2f181efed8 Preserve str subclasses in ascii() for ASCII-only __repr__ results (#7455) 2026-03-19 09:48:42 +09:00
Jeong, YunWon
62edc4722a Add per-type vectorcall for builtin constructors (#7407)
Add vectorcall fast paths for dict, list, set, int, float, str,
bool, tuple, frozenset. Clear vectorcall when __init__/__new__ is
overridden in Python. Prevent constructor vectorcall inheritance
to heap subclasses. Fix stat_result to use struct_sequence_new
with reference-copy for hidden time fields.
2026-03-18 21:44:35 +09:00
Jeong, YunWon
0768cf80d3 Merge pull request #7440 from youknowone/pycode
Upgrade test_code and fix code bugs
2026-03-17 20:53:42 +09:00
Lee Dogeon
f868f81db6 Implement complex.from_number (#7453)
Co-authored-by: CPython Developers <>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 20:50:28 +09:00
Jeong, YunWon
c57f4decd5 Fix test_code: compiler and code object improvements
- Add CO_NESTED flag (0x10) for nested function scopes
- Emit LOAD_SMALL_INT for integers 0..=255 instead of LOAD_CONST
- Eliminate dead constant expression statements (no side effects)
- Ensure None in co_consts for functions with no other constants
- Add code.__replace__() for copy.replace() support
- Mark test_co_lnotab and test_invalid_bytecode as expectedFailure
2026-03-17 10:54:12 +09:00
Lee Dogeon
5f1d5d2815 Cleanup some direct magic method definitions (#7441)
* Migrate direct __repr__ definitions to Representable trait

Move legacy #[pymethod] __repr__ to impl Representable for:
- PySSLContext, PySSLSocket (ssl.rs)
- BufferedReader, BufferedWriter, BufferedRandom (_io.rs)

Enable __repr__ guard in derive to prevent future direct definitions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Migrate direct __del__ definition to Destructor trait for PySocket

Move #[pymethod] __del__ to impl Destructor for PySocket.
Preserves ResourceWarning emission and close behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Remove redundant __iter__ pymethods from PyFuture and PyTask

Both types already have impl Iterable, so the direct #[pymethod]
__iter__ definitions were duplicates. Enable __iter__/__next__
guards in derive to prevent future direct definitions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Enable derive guards for __get__/__set__/__delete__ descriptor methods

All concrete types already use GetDescriptor/SetDescriptor traits.
Activate the compile-time guard to prevent future direct definitions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Enable derive guards for AsMapping/AsSequence slot methods

Remove redundant #[pymethod(name = "__len__")] from PyStr
(already provided via AsMapping/AsSequence trait impls).

Enable compile-time guards for __len__, __contains__, __getitem__,
__setitem__, __delitem__ to prevent future direct definitions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:49:45 +09:00
Jeong, YunWon
d2d2822bb9 Implement code object __eq__/__hash__
- Add Comparable and Hashable traits for PyCode
- Compare by name, args, flags, bytecode, consts, names, vars, linetable
- Hash by tuple of key attributes matching CPython's code_hash
- Remove unused custom_ops slice in Instruction::try_from
- Add co_lnotab intentional non-implementation comment
2026-03-16 15:25:29 +09:00
Lee Dogeon
97790a88b2 Implement missing slots for NoneType (#7437)
* Define only wrapper_descriptor

* Implement missing slots for NoneType
2026-03-16 11:58:40 +09:00
Lee Dogeon
9ddd07a656 Preserve imaginary zero signs when adding real values to complex numbers (#7421)
* Preserve imaginary zero signs when adding real values to complex numbers

* Refactor complex_add with match expression

* Correct complex real subtract op

* Remove unnecessary vm arugment
2026-03-15 17:04:23 +09:00
Shahar Naveh
9a297aad2b Newtype var_nums oparg (#7431) 2026-03-15 17:01:03 +09:00
Shahar Naveh
0c14ad195e Update ruff to 0.15.6 (#7427)
* Update ruff to `0.15.6`

* Unmark passing tests
2026-03-14 20:22:42 +09:00
Lee Dogeon
d1ea35962b Match divmod zero-division message with CPython (#7426) 2026-03-14 20:21:23 +09:00
Lee Dogeon
e7d2b57dcc Match __module__ setter behavior to CPython (#7424)
* Remove stale __firstlineno__ when updating type.__module__

* Register and use __firstlineno__ as identifier
2026-03-14 15:48:48 +09:00
Lee Dogeon
21d549caf6 Handle chr() range checks without Rust integer overflow (#7422) 2026-03-14 15:47:45 +09:00
Lee Dogeon
ed032d31fb Make singleton builtin types immutable (#7423) 2026-03-14 09:45:43 +09:00
Jeong, YunWon
be6025ab03 Adapt bitflagset to use enum (#7419) 2026-03-14 09:44:02 +09:00
Jiseok CHOI
7d63f65f21 Fix classmethod descr_get to match CPython behavior (#7420)
Simplify classmethod.__get__ to always create a PyBoundMethod binding
  the callable to the class, matching CPython's cm_descr_get which simply
  calls PyMethod_New(cm->cm_callable, type).

  The previous implementation incorrectly tried to call __get__ on the
  wrapped callable, which broke when a bound method was passed to
  classmethod() (e.g. classmethod(A().foo)).
2026-03-14 03:40:16 +09:00
Jeong, YunWon
7c0981b9ce Fix SSL handshake over-reading in STARTTLS (#7417)
During STARTTLS handshake, sock_recv(16KB) could consume
application data that arrived alongside handshake records.
The consumed data ended up in rustls's internal buffer where
select() could not detect it, causing asyncore-based servers
to miss readable events and the peer to time out.

Use MSG_PEEK to find the TLS record boundary, then recv()
only one complete record. Remaining data stays in the kernel
TCP buffer, visible to select(). This matches OpenSSL's
default no-read-ahead behaviour.

Fixes flaky test_poplib (TestPOP3_TLSClass) failures.
2026-03-13 11:46:35 +09:00
김은빈
a733c8baa7 Fix weakref proxy number protocol, right-side ops, and non-iterator error (#7410) 2026-03-13 11:36:16 +09:00
EtherealPsyche
0f61464c54 If the host_env feature is enabled, then enable the _ctypes module on the Android platform. (#7402) 2026-03-13 01:20:32 +09:00
김은빈
61b3b4f42b Add strict parameter to map() builtin (#7405)
* Add strict parameter to map() builtin

* Refactor map IterNext to match zip style
2026-03-12 15:02:53 +00:00
Shahar Naveh
bb36783206 Newtype oparg align methods (#7403)
* Align methods for newtype opargs
2026-03-12 23:41:21 +09:00
Jeong, YunWon
c578ac0b21 gc: add CollectResult, stats fields, get_referrers, and fix count reset (#7354)
* gc: add CollectResult, stats fields, get_referrers, and fix count reset

- Add CollectResult struct with collected/uncollectable/candidates/duration
- Add candidates and duration fields to GcStats and gc.get_stats()
- Pass CollectResult to gc.callbacks info dict
- Reset generation counts for all collected generations (0..=N)
- Return 0 for third value in gc.get_threshold() (3.13+)
- Implement gc.get_referrers() by scanning all tracked objects
- Add DEBUG_COLLECTABLE output for collectable objects
- Update test_gc.py to expect candidates/duration in stats

* Update test_gc from v3.14.3

* Update test_gc.py from CPython v3.15.0a5

Taken from v3.15 (not v3.14.3) because get_stats() candidates/duration
fields were added in 3.13+ and the corresponding test assertions only
exist in 3.15.

* Fix gc_state build on wasm32: skip Instant timing

* Add candidates/duration to gc callback info, mark v3.15 test failures

* Fix gc.get_referrers to exclude executing frames, fix Future cancelled exc leak

- get_referrers: skip frame objects on the execution stack, since
  they are not GC-tracked in CPython (_PyInterpreterFrame)
- _asyncio Future/Task make_cancelled_error_impl: clear the stored
  cancelled exception after returning it, matching the Python
  _make_cancelled_error behavior

* Fix gc.get_threshold to return actual gen2 threshold value

* Fix inconsistent GC count reset in early-return paths

Use the same reset_end formula in unreachable-empty early returns
as in the main collection path and collecting-empty path.

* Accept keyword arguments in socket.__init__

Use a FromArgs struct instead of a positional-only tuple so that
family, type, proto, and fileno can be passed as keyword arguments.

* Disable comp_inlined in symbol table to match compiler

The compiler does not yet implement PEP 709 inlined comprehensions
(is_inlined_comprehension_context always returns false), but the
symbol table was marking comprehensions as inlined. This mismatch
could cause comprehension-local symbols to be merged into the parent
scope while the compiler still looks them up in a separate scope.

---------

Co-authored-by: CPython Developers <>
2026-03-12 20:48:22 +09:00
Shahar Naveh
5c631e5129 Newtype var_num oparg (#7400) 2026-03-12 09:20:01 +09:00
Jeong, YunWon
85eca218af Fix atexit unraisable exception message format (#7399)
* Fix atexit unraisable exception message format

Match PyErr_FormatUnraisable behavior: use
"Exception ignored in atexit callback {func!r}" as err_msg
and pass None as object instead of the callback function.

* Fix atexit unregister deadlock with reentrant __eq__

Release the lock during equality comparison in unregister so
that __eq__ can safely call atexit.unregister or atexit._clear.
Store callbacks in LIFO order (insert at front) and use
identity-based search after comparison to handle list mutations,
matching atexitmodule.c behavior.

Also pass None as err_msg when func.repr() fails, matching
CPython's PyErr_FormatUnraisable fallback.
2026-03-11 22:20:37 +09:00
Jeong, YunWon
d248a04cae Refine specialization caches and extend binary-op coverage (#7386)
* Align BINARY_OP_EXTEND with CPython descriptor cache model

* Align type _spec_cache and latin1 singleton string paths

* Add specialization differential harness and align init error text

* Tighten CALL_ALLOC_AND_ENTER_INIT stack-space guard

* Align call-init frame flow and spec cache atomic ordering

* Refine call-init recursion guard and cache swap lifetime handling

* Align spec cache write locking with CPython contract

* Align load attr miss cooldown with CPython

* Align CALL descriptor and class-call specialization with CPython

* Extract datastack_frame_size_bytes_for_code, skip monitoring for init_cleanup frames, guard trace dispatch

- Extract datastack_frame_size_bytes_for_code as free function, use it
  to compute init_cleanup stack bytes instead of hardcoded constant
- Add monitoring_disabled_for_code to skip instrumentation for
  synthetic init_cleanup code object in RESUME and execute_instrumented
- Add is_trace_event guard so profile-only events skip trace_func dispatch
2026-03-10 15:39:55 +09:00
Jeong, YunWon
a854ef2a2b Rename stdlib files to match Python module names (#7397) 2026-03-10 15:29:17 +09:00
Jeong, YunWon
45d93f4b20 Save errno inside allow_threads in semaphore acquire (#7391)
allow_threads may call attach_thread() on return, which
can invoke syscalls that clobber errno. Capture errno
inside the closure before it is lost.
2026-03-10 14:04:28 +09:00
Jeong, YunWon
2266ba7f47 Add per-size tuple freelist (20 buckets × 2000 each) (#7361)
* Add per-size tuple freelist (20 buckets × 2000 each)

Implement PyTuple freelist matching tuples[PyTuple_MAXSAVESIZE]:
- TupleFreeList with 20 per-size buckets (sizes 1..=20, 2000 capacity each)
- freelist_push uses pre-clear size hint for correct bucket selection
- freelist_pop takes &Self payload to select bucket by size
- Type guard in new_ref handles structseq types sharing PyTuple vtable
- Add pyinner_layout<T>() helper for custom freelist Drop impls
- Update freelist_pop/push signatures across all freelist types

* freelist: exact type check at pop call-site

Move exact-type filtering from freelist_pop implementations to the
single call-site in new_ref. This prevents structseq and other subtypes
from popping tuple freelist entries entirely, rather than popping and
then deallocating on type mismatch.

Add Context::try_genesis() that returns None during bootstrap to avoid
deadlock when genesis() is called during Context initialization.

* Move exact type check from freelist_push to call-site in default_dealloc

Remove typ parameter from freelist_push trait signature. The exact type
check is now done once at the call-site alongside the heaptype check,
simplifying all freelist_push implementations.

* Remove freelist_hint; call freelist_push before tp_clear

By calling freelist_push before tp_clear, the payload is still intact
and can be read directly (e.g. tuple element count for bucket selection).
This eliminates freelist_hint and the hint parameter entirely.
2026-03-09 22:34:37 +09:00
Jeong, YunWon
6c12152aeb rustfmt (#7390) 2026-03-09 22:31:29 +09:00
Shahar Naveh
82e9b5d9e1 Newtype ConstIdx, Constants (#7358)
* Newtype ConstIdx, Constants

* Set generic
2026-03-09 11:47:24 +09:00
Jiseok CHOI
fa4f84ce3f Introduce TimeoutSeconds utility type for timeout parameters (#7271)
* Introduce TimeoutSeconds utility type for timeout parameters

Follow-up refactoring from #7237.

Python timeout parameters typically accept both float and int. Several
places in the codebase used Either<f64, i64> for this, each repeating
the same match-and-convert boilerplate. This extracts that into a
TimeoutSeconds type in vm::function::number.

Refactored sites:
- _sqlite3::ConnectArgs.timeout
- _thread::AcquireArgs.timeout
- _thread::ThreadHandle::join timeout

Either<f64, i64> in time.rs (6 sites) left unchanged: those are
timestamp values with per-branch logic (floor, range checks, etc).
Either<f64, isize> in select.rs also left unchanged (different type).

* Validate timeout in ThreadHandle::join to prevent panic

* refactor: move TimeoutSeconds from number to time module
2026-03-09 11:36:03 +09:00
Jeong, YunWon
ead2d98557 Separate WeakRefList from ObjExt as independent prefix (#7365)
- Remove weak_list from ObjExt, allocate WeakRefList as its own
  prefix slot before PyInner
- Add MANAGED_WEAKREF flag (1 << 3) to PyTypeFlags
- Normalize MANAGED_WEAKREF from HAS_WEAKREF after flag assembly
- Use Layout::extend offsets in bootstrap allocator
2026-03-09 02:09:26 +09:00
Jeong, YunWon
ce8952b1f5 Use borrowed pointers in TYPE_CACHE instead of strong references (#7384)
The method cache (TYPE_CACHE) was storing strong references (Arc
clones) to cached attribute values, which inflated sys.getrefcount().
This caused intermittent test_memoryview failures where refcount
assertions would fail depending on GC collection timing.

Store borrowed raw pointers instead. Safety is guaranteed because:
- type_cache_clear() nullifies all entries during GC collection,
  before the collector breaks cycles
- type_cache_clear_version() nullifies entries when a type is
  modified, before the source dict entry is removed
- Readers use try_to_owned_from_ptr (safe_inc) to atomically
  validate and increment the refcount on cache hit
2026-03-08 22:55:22 +09:00
Jeong, YunWon
46abff6880 Harden CALL specialization guards and cache callables (#7360)
* vm: align CALL/CALL_KW specialization core guards with CPython

* vm: keep specialization hot on misses and add heaptype getitem parity

* vm: align call-alloc/getitem cache guards and call fastpath ordering

* vm: align BINARY_OP, STORE_SUBSCR, UNPACK_SEQUENCE specialization guards

* vm: finalize unicode/subscr specialization parity and regressions

* vm: finalize specialization GC safety, tests, and cleanup
2026-03-08 21:15:30 +09:00
Jeong, YunWon
45d81296e4 More fork safety (#7380)
* apply more allow_threads

* Simplify STW thread state transitions

- Fix park_detached_threads: successful CAS no longer sets
  all_suspended=false, avoiding unnecessary polling rounds
- Replace park_timeout(50µs) with park() in wait_while_suspended
- Remove redundant self-suspension in attach_thread and detach_thread;
  the STW controller handles DETACHED→SUSPENDED via park_detached_threads
- Add double-check under mutex before condvar wait to prevent lost wakes
- Remove dead stats_detach_wait_yields field and add_detach_wait_yields

* Representable for ThreadHandle

* Set ThreadHandle state to Running in parent thread after spawn

Like CPython's ThreadHandle_start, set RUNNING state in the parent
thread immediately after spawn() succeeds, rather than in the child.
This eliminates a race where join() could see Starting state if called
before the child thread executes.

Also reverts the macOS skip for test_start_new_thread_failed since the
root cause is fixed.

* Set ThreadHandle state to Running in parent thread after spawn

* Add debug_assert for thread state in start_the_world

* Unskip now-passing test_get_event_loop_thread and test_start_new_thread_at_finalization

* Wrap IO locks and file ops in allow_threads

Add lock_wrapped to ThreadMutex for detaching thread state
while waiting on contended locks. Use it for buffered and
text IO locks. Wrap FileIO read/write in allow_threads via
crt_fd to prevent STW hangs on blocking file operations.

* Use std::sync for thread start/ready events

Replace parking_lot Mutex/Condvar with std::sync (pthread-based)
for started_event and handle_ready_event. This prevents hangs
in forked children where parking_lot's global HASHTABLE may be
corrupted.
2026-03-08 18:06:23 +09:00