* address review: negative defaults, to_bytes signed, get_self, fstat
- python_default_repr renders negated int/float literals and looks
through parentheses and groups.
- int.to_bytes signed is ArgIntoBool again, so any object is accepted
by truthiness; its signature default stays False via py_default.
- PyNativeFunction::get_self falls back to the module object.
- os.fstat has its own FromArgs with a single fd parameter instead of
reusing stat's arguments.
Assisted-by: Claude:claude-opus-5-5
* address review: literal default rendering and fstat supports sets
- Literal defaults are rendered by python_literal_repr, which recurses
through negation, parentheses and groups, so `-(1)` renders `-1`.
- Float literals without a dot or exponent, such as `1f64`, render
with a trailing `.0`.
- os.fstat is removed from supports_fd, supports_dir_fd and
supports_follow_symlinks.
Assisted-by: Claude:claude-opus-5-5
* Store instance slots as atomic object pointers
PyMemberDef now carries type, offset, and flags. Slot values are
atomic PyObject pointers with try-incref reads, so a concurrent
store cannot free the memory under a reader. Objects placed in a
slot stay published until QSBR reclaims them.
Assisted-by: Grok:4.7
* Collapse nested slot load condition
Assisted-by: Grok:4.7
* Reject over-long digit strings before parsing
A pure ASCII digit string longer than the int digit limit now fails
from a wide digit check. The denial-of-service test no longer spends
the failure path scanning and parsing the whole literal.
Assisted-by: Grok:4.7
* Collapse nested digit-limit condition
Assisted-by: Grok:4.7
* Restore MemberKind for member type codes
The VM stores the member type as an enum whose discriminants match
the C type codes. The C API still reads the integer and converts it
at the boundary. Flags stay integers.
Assisted-by: Grok:4.7
* Mark MemberKind::from_i32 as must_use
Assisted-by: Grok:4.7
* Compose native text signatures at compile time from FromArgs
FromArgs gains a PARAMS const describing its Python parameters.
The derive builds the whole internal doc, `name(sig)\n--\n\ndoc`,
in a const context from those params, and `__text_signature__` /
`__doc__` parse it from the doc. The macro-time string path and the
runtime sig_parts composition are removed.
Signatures follow clinic conventions: `$module` for module functions,
Rust literal defaults rendered as Python reprs, other defaults as
`<unrepresentable>`, and a new `#[pyarg(py_default = "...")]` for the
few fields whose Rust default differs from the Python one. The
`#[pyarg]` keys are documented on the FromArgs derive.
Module functions keep their module object and return it from
`__self__`. PyNativeFunction now traverses its references.
os.stat, os.mkdir, os.listdir, os.open, dict.fromkeys, round, sorted,
int.to_bytes and bytes.hex take arguments matching their signatures.
Assisted-by: Grok:grok-4.7
Assisted-by: Claude:claude-opus-5-5
* Update builtin_signature snippet and fix mkdir on Windows
round and sum now report their FromArgs parameters, so the snippet
asserts their signatures instead of their absence. sum's start is a
PyObjectRef defaulting to int 0 with py_default "0". mkdir reads
dir_fd only on platforms that use it.
Assisted-by: Claude:claude-opus-5-5
* Remove expectedFailure from two signature tests
test_cmp_to_signature and test_autospec_on_bound_builtin_function
now pass. The TestCmpToKeyC override existed only for the marker.
Assisted-by: Claude:claude-opus-5-5
add_note, __reduce__, and __setstate__ take &Py<BaseException>.
dict.__ror__ takes &Py<PyDict>. Callers drop the clone made for add_note.
Assisted-by: Grok CLI:grok-4.7
* Pass owned iterables through; host enumerate on Py<T>
dict update, OrderedDict, defaultdict, itertools, and pickle pass an
owned object to PyIter::try_from_object.
#[pyclass(...)] impl Py<T> now emits PyClassImpl for T. enumerate's
methods live on that impl. A bare impl Py<T> stays an extension.
Assisted-by: Grok CLI:grok-4.7
* Host Self-free pyclass impls on Py<T>
filter, Ellipsis, NotImplemented, bool, Placeholder, and NoDefault
do not use Self as the payload type, so their pyclass impl can be Py<T>.
Assisted-by: Grok CLI:grok-4.7
GET_ITER, GET_YIELD_FROM_ITER, mapping keys(), and builtin iter()
already hold a PyObjectRef. get_iter() cloned it before try_from_object.
Assisted-by: Grok CLI:grok-4.7
* Borrow tp_descr_get/tp_init arguments and by-value public helpers
- DescrGetFunc and GetDescriptor::descr_get take
(&PyObject, Option<&PyObject>, Option<&PyObject>); impls call
.to_owned() where they store or return an argument.
- InitFunc takes &PyObject and Initializer::init takes &Py<Self>.
- VirtualMachine::get_attribute_opt, print_exception,
call_get_descriptor(_specific) and other helpers flagged by
clippy::needless_pass_by_value take &PyObject / &Py<T>; callers in
crates/, examples/ and tests/ drop the clones made for the call.
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Grok CLI:grok-4.7
* Pass the borrowed zelf to internal_close in WindowsConsoleIO init
Assisted-by: Claude Code:claude-opus-5-5
* Fix borrowed signatures missed by the rebase
OrderedDict.init, classmethod_descriptor.descr_get, and the warnings
get_attribute_opt callers still used owned handles.
Assisted-by: Grok CLI:grok-4.7
* Implement _collections.OrderedDict
Extracted from #6799: native OrderedDict as a dict subclass,
iterator mutation tracking, and mapping-view set operations.
* Add OrderedDict, warnings source lines, and socket sendmsg
Implement _collections.OrderedDict as a dict subclass with a
linked list of insertion-order nodes.
Pack struct F/D as native float/double complex pairs, and report
unexpected __replace__ field names as a list repr.
Register encodings.latin_1 at startup. Reject NUL in input()
prompts. Copy non-exact type dicts in mapping order.
Fetch warning source lines through _bless_my_loader and unicode
splitlines. Keep the last warnings.filters list after deletion.
Snapshot sendmsg sequences before converting buffers, parse
ancillary ints with __index__, and dispatch AF_CAN by protocol.
Store sys.trace and sys.profile on each ThreadSlot so
_settraceallthreads/_setprofileallthreads are visible to
sys.gettrace/getprofile on other threads.
Use <frozen importlib._bootstrap> as frozen importlib
co_filename. Keep HEAPTYPE socket objects GC-tracked.
Assisted-by: Grok:grok-4.6
* Load marshal via readinto and dump sets in dumps order
marshal.load fills a scratch buffer with readinto on a
contiguous writable memoryview, and rejects a returned length
other than the requested size.
set and frozenset dumps write elements in sorted(v,
key=marshal.dumps) order.
Assisted-by: Grok:grok-4.6
* Add classmethod_descriptor and ABC IS_ABSTRACT flags
Give METH_CLASS methods a distinct classmethod_descriptor type.
Store Py_TPFLAGS_IS_ABSTRACT from __abstractmethods__ and look
up that attribute only in the type's own dict.
Expose defaultdict.default_factory as a member descriptor.
Inherit bool's unused number slots from int. Mark set and
frozenset __contains__ as METH_COEXIST.
Parse classmethod, staticmethod, object.__new__, and heap type
text signatures. Register interactive source in linecache.
Assisted-by: Grok:grok-4.6
* address review: odict reuse, descr call, new wrapper
Reuse odict node slots and walk the live list in next_after.
Require both | operands to be dicts. Drop the odict iterator
on GC clear. Bind classmethod descriptors through descr_get
and update IS_ABSTRACT under the type lock. Give odict keys
and items sq_contains. Walk tp_new_wrapper past new_wrapper
so HEAPTYPE socket subclasses can call socket.__new__.
Split FreeBSD Bluetooth protocol constants from Linux values.
Assisted-by: Grok:grok-4.6
* Represent chflags bits with bitflagset
Assisted-by: Grok:grok-4.6
* Represent access and mode bits with bitflagset
Assisted-by: Grok:grok-4.6
* Continue unfinished REPL suites as incomplete input
Assisted-by: Grok:grok-4.6
* Add pickle and os.stat inspect signatures
Give _pickle.Pickler the clinic constructor text signature and
accept fix_imports and buffer_callback as positional-or-keyword.
Allow #[pyfunction(text_signature)] and use it so os.stat reports
(path, *, dir_fd=None, follow_symlinks=True). Uncomment import
_pickle and drop the pickle inspect expectedFailures.
Assisted-by: Grok:grok-4.6
* Add Unpickler, dump/load, and lstat signatures
Give _pickle Unpickler, dump, dumps, load, and loads clinic
text signatures, and os.lstat (path, *, dir_fd=None).
Assisted-by: Grok:grok-4.6
* Complete OrderedDict with insertion-order links
Move the native OrderedDict into ordered_dict.rs and track order
with a linked list of nodes, keeping mapping-view set operations.
Assisted-by: Grok:grok-4.6
* address CI: stat casts, HCI_DATA_DIR, passing xfails
Compare stat permission bits as Mode so Linux clippy does not
flag a u32-to-u32 cast. Export HCI_DATA_DIR with the Bluetooth
socket option values. Drop expectedFailure from tests that now
pass.
Assisted-by: Grok:grok-4.6
* Fix wasm teardown deadlock and bluetooth constants
Assisted-by: Grok:grok-4.6
* Clear process-wide eval breaker bits in STW test
Assisted-by: Grok:grok-4.6
* Drop exclusive-held panic that tripped wasm clippy
Assisted-by: Grok:grok-4.6
* Fix OrderedDict contains and export Windows BDADDR
Assisted-by: Grok:grok-4.6
* Add cmp_to_key and hash-once LRU cache
_functools.cmp_to_key now returns KeyWrapper. LRU lookups store the
key hash on _lru_list_elem so __hash__ is not called again on hits
or eviction.
Assisted-by: Grok:grok-4.6
* Allow subclass keywords on list, tuple, and float
list.__init__ rejects keywords only when tp_new is still list's.
tuple/float.__new__ reject them only when tp_init is still the base's.
Assisted-by: Grok:grok-4.6
* Fix CI lint, test re-export, and structseq members
Drop the duplicate clear_eval_breaker_for_test re-export.
Format structseq imports. Expose struct sequence fields as
readonly members so assignment raises "readonly attribute".
Assisted-by: Grok:grok-4.6
* Allow subclass keywords on itertools and filter
Positional-only constructors ignore extra keywords when a subclass
has replaced tp_init, matching list/tuple/float.
Assisted-by: Grok:grok-4.6
* Remove text_signature derive parameter
Drop the string override on #[pyfunction] and #[pyclass]. Signatures
are generated from the Rust parameter list only. Restore inspect
expectedFailures that depended on the override.
Assisted-by: Grok:grok-4.6
* Rename set contains_method to __contains__
Keep a borrowed contains helper for slots and C-API. The coexist
pymethod is named __contains__.
Assisted-by: Grok:grok-4.6
* Use MonitoringEvent instead of EVENT_* aliases
Drop the unused MonitoringEvents bitflags and the EVENT_PY_START
style mask constants. Call sites use the enum and .mask().
Assisted-by: Grok:grok-4.6
* Store warnings filters as PyListRef
The list already serializes its elements. Drop the extra mutex around
the cached list pointer.
Assisted-by: Grok:grok-4.6
* Re-export clear_eval_breaker_for_test after rebase
Keep the STW test helper visible without bringing back stop_bit_set.
Assisted-by: Grok:grok-4.6
* Fix groupby reentrancy and islice arguments
Give _grouper its own tgtkey and take currvalue after the key
comparison. Accept __index__ on islice bounds, reject step 0, and
drain the source up to stop.
Assisted-by: Grok:grok-4.6
* SETREF warnings filters, onceregistry, and defaultaction
Keep the last list, dict, or str after the module attributes are
deleted by swapping the interpreter cache pointer. Do not store a
None fallback for _warnings_context.
Assisted-by: Grok:grok-4.6
* Iterate OrderedDict inner dict via next_entry
&PyDict is not an iterator after the borrowed-ref signature change.
Assisted-by: Grok:grok-4.6
* Remove expectedFailure from testBluetoothConstants
Linux now exports BTPROTO_HCI and the rest of the set.
Assisted-by: Grok:grok-4.6
* Borrow get_filter arguments as PyObject
Match the warn_explicit call site that passes borrowed
handles after the internal-helper borrow change.
Assisted-by: Grok:grok-4.6
* Fix bool slots and SemHandle safety docs
Leave unused bool number slots unset so inspect reports
__add__ on int. Document SemHandle::from_raw safety.
Assisted-by: Grok:grok-4.6
* Keep sendmsg errors and drop duplicate linecache
Replace sendmsg iterable TypeError only. Register REPL
source in linecache once per compiled input.
Assisted-by: Grok:grok-4.6
* Nest REPL parse or-patterns for clippy
Assisted-by: Grok:grok-4.6
* Mark pydoc os.stat signature test expectedFailure
Assisted-by: Grok:grok-4.6
---------
Co-authored-by: Lee Dogeon <dev.moreal@gmail.com>
Internal functions that took PyObjectRef or PyRef<T> by value but only
borrowed it (reported by clippy::needless_pass_by_value) now take
&PyObject or &Py<T>. Callers pass a borrow instead of an owned handle;
61 caller-side .clone()/.to_owned() calls made only to pass the argument
are removed. Where a converted body already cloned the parameter, that
.clone() became .to_owned().
Functions with #[py*] attributes, trait methods, and functions whose
signature is fixed by a function pointer, getset or slot wrapper type are
unchanged.
PyFloat_FromString in crates/capi passes the borrowed object to
parse_float_from_string without taking an owned reference.
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Grok CLI:grok-4.7
* host_env: rebuild a unix SemHandle from its stored integer
Windows already has SemHandle::from_raw. Unix callers that keep the
semaphore integer and close it themselves need the same constructor.
Drop still closes, so that caller forgets the rebuilt handle.
Assisted-by: Grok
* Update crates/host_env/src/multiprocessing.rs
* host_env: publish remaining Windows socket constants
Windows SOMAXCONN follows winsock2.h (0x7fffffff), not the Winsock 1.1
value windows-sys still exports. The socket module takes the signed
INADDR group constants and the other Winsock names host_env already
defines.
Assisted-by: Grok
* test_socket: expect Bluetooth constants to pass on Windows
The Windows names this test reads are published now, so the blanket
expectedFailure is an unexpected success there. Other platforms still
miss BTPROTO_HCI and the rest of the non-Windows set.
Assisted-by: Grok
Parameters, return types, closure annotations, Fn and Iterator bounds,
trait methods and struct fields that borrowed an owning handle now borrow
the object: &PyObjectRef -> &PyObject, &PyRef<T> / &PyXxxRef -> &Py<T>.
Existing .clone() calls on those values became .to_owned().
- Move PyTuple::extract_tuple into impl Py<PyTuple>; FromPyTuple::from_pytuple
takes &Py<PyTuple>.
- DictIter and IntoIterator for &PyDict use &Py<PyDict>; apply_shared_ns
takes &Py<PyDict>.
- PyExactSizeIterator, calculate_suggestions, collection_repr and the cformat
tuple helpers take iterators over &PyObject; callers map with |o| &**o.
- Return types changed: TypeNamespace::as_dict, Context::cached_int,
struct_error_type, PyBoundMethod::function_obj/self_obj,
AsRef for ArgIndex. as_dict, function_obj and self_obj are no longer
const fn.
- asyncgenerator unbox, csv parse_lineterminator and _ctypes bytes
parameter take &Py<T> instead of &T.
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Grok CLI:grok-4.7
* host_env: export SIG*, sysconf, CLOCK_*, unix socket names
Re-export signal numbers, pathconf/sysconf names, clock ids,
and the unix socket integers the VM still took from libc.
Assisted-by: Claude
* stdlib: take SIG*, sysconf, CLOCK_*, socket names from host_env
signal, posix pathconf/sysconf enums, time clock ids, and the
shared socket pyattrs re-export host_env instead of libc.
Assisted-by: Claude
* host_env: export remaining socket integers and Windows SHUT_*
Alias WinSock SD_* as SHUT_* so the shared pyattr names resolve.
Re-export the rest of the libc socket integers the VM still took
from `use libc as c`.
Assisted-by: Claude
* stdlib: take remaining socket pyattrs from host_env
Module integer names come from host_env. Types and syscalls stay
on libc / WinSock.
Assisted-by: Claude
* stdlib: drop unused Windows socket constant imports
pyattrs now take those names from host_env. Keep only the syscall
names the shared body still reads as c::.
Assisted-by: Claude
The isolated test asserted a clear process-wide eval breaker, and
cleared STOP_BIT itself. Parallel STW tests flicker that word, so
Windows rust tests failed after #8786.
Assisted-by: Grok:4.6
- `try_value_with` passes `&Py<T>` to its closure instead of `&T`, and
its four callers follow.
- structseq and pyexpat getset closures take `&Py<T>`.
- `get_jit_args` takes `&Py<PyFunction>`.
- `SaturatedSlice::with_slice` takes `&Py<PySlice>`; `to_saturated`
moves from `impl PySlice` to `impl Py<PySlice>`.
- The ssl compat helpers take `&Py<PySSLSocket>`; `do_handshake`,
`read`, `write` and `shutdown` take `zelf: &Py<Self>` so they can
pass it on. An inherent `impl Py<PySSLSocket>` is not possible in
the stdlib crate.
The csv `&PyDialect` sites keep the payload reference: the dialect is
stored by value, so no `Py<PyDialect>` is available there.
Assisted-by: Claude Opus 5 (1M context)
Assisted-by: grok-4.7
* host_env: export O_* flags and wasm errno
Re-export open(2) flags from os. wasm32-unknown-unknown uses
Darwin/BSD numbers, matching the guest errno table.
Expand errno_wasm to that table plus strerror.
Assisted-by: Claude
* stdlib: take O_* open flags from host_env
os, posix, and nt re-export the host_env names instead of libc.
Assisted-by: Claude
* host_env: export remaining posix integer names
Publish wait, RTLD, SCHED, SEEK, PRIO, CLD, AT, lockf, and
statvfs flags so posix and os stop taking them from libc.
Assisted-by: Claude
* stdlib: take remaining posix names from host_env
posix and os re-export wait, RTLD, SCHED, SEEK, PRIO, and
statvfs flags from host_env.
Assisted-by: Claude
* host_env: define AT_EACCESS on Android
bionic's libc crate does not export AT_EACCESS. Use the Linux
fcntl value there.
The eval-breaker unit test now waits for STOP_BIT to be clear
instead of requiring the whole process-wide breaker word empty.
Assisted-by: Claude
* vm: gate stop_bit_set to tests
Clippy builds the lib without tests, so the helper and its
re-export were unused.
Assisted-by: Claude
* host_env: export vsock, wasm socket, Darwin flags
Publish vsock/UDPLITE/SOL fallbacks, wasm socket and errno
constants, remaining BSD chflags, and S_IFDOOR/PORT/WHT.
Assisted-by: Claude
* stdlib: take vsock, wasm socket, Darwin flags from host_env
_socket, wasm _socket/_io/errno, _stat, and openssl alerts now
re-export the host_env names.
Assisted-by: Claude
* host_env: keep wasm socket/errno off emscripten
wasm32-unknown-emscripten is unix, so the stub modules must be
unknown-unknown (and WASI) only.
Assisted-by: Claude
* stdlib: match socket module_def cfg to the module
Assisted-by: Claude
* host_env: drop duplicate Windows SOL_UDP
The IANA fallback also compiled on Windows, colliding with the
WinSock definition.
Assisted-by: Claude
* posix: add os.forkpty
pty.fork prefers forkpty so a nested spawn is a new session with its
own controlling tty. The openpty+login_tty fallback hung the
jsontests collector.
Assisted-by: Claude
* select: rebuild fd sets after EINTR
select(2) updates the sets in place. Retrying an interrupted call
with empty sets and a NULL timeout blocks forever.
Assisted-by: Claude
* http.server: keep CGI off the body-read timeout
A millisecond handler timeout races the client thread writing the
request and is inherited across CGI fork, which RSTs the client
under load.
Assisted-by: Claude
* Revert "http.server: keep CGI off the body-read timeout"
Lib edits outside a CPython copy are not allowed.
Assisted-by: Claude
* host_env: note why forkpty is libc not nix
Assisted-by: Claude
* benches: run deepcopy 10x more iterations
Assisted-by: Claude
* Show stdin traceback lines; omit StopIteration None args
Register interactive <stdin> source in linecache so REPL
tracebacks include the source line and caret. Build
StopIteration with empty args when the value is None, and
wrap monitoring STOP_ITERATION the same way.
Unskip REPL stderr flush tests and pdb Flaky doctests.
Assisted-by: Grok:4.6
* Take &Py<PyCode> in register_code_in_linecache
Assisted-by: Grok:4.6
* Count Unknown closing braces in tokenize EOF check
`$` inside an f-string interpolation is TokenKind::Unknown, so
the matching `}` is Unknown rather than Rbrace and generate_tokens
raised TokenError. Also convert &Py<PyCode> to PyObjectRef
explicitly when registering linecache.
Assisted-by: Grok:4.6
* Unskip test_pdb.PdbTestCase.test_zipimport
The test now passes, so the expectedFailure is an unexpected
success under CI.
Assisted-by: Grok:4.6
* Park STW threads; poll sockets after timeout deadline
Check per-thread stop_requested in eval_breaker_tripped so
workers still park when another interpreter clears STOP_BIT.
Start socket timeout after the fd snapshot, and poll once with
timeout 0 when the deadline has already passed, so a readable
socket is not dropped as timed out.
Assisted-by: Grok:4.6
* host_env: export ctypes, chflags, SIG_DFL
Publish ctypes FUNCFLAG/TYPEFLAG/DICTFLAG and CTYPES_MAX_ARGCOUNT,
BSD chflags bits libc does not bind, AT_FDCWD, and SIG_DFL/IGN/ERR.
Assisted-by: Claude
* stdlib: take ctypes, chflags, SIG_DFL from host_env
_ctypes, _stat, os.AT_FDCWD, and Windows SIG_DFL/IGN/ERR now re-export
the host_env names. Wasm keeps local SIG_* literals.
Assisted-by: Claude
* Unskip passing flaky CPython tests
Remove RUSTPYTHON skip overlays after Linux release repeats passed
for enum, threading, logging, subprocess, socket, int, re, strtod,
and regrtest cases.
Assisted-by: Grok:4.6
* Fix fork-child SIGSEGV and yield-from throw args
Forget JoinHandle of threads that did not survive fork instead
of dropping them. Zero-reinit the import lock and condvars in
the child rather than unlock/notify. Resume the world if
os.fork() fails.
Call a yield-from subiterator throw() without None fillers so
a 1-arg throw stays 1-arg.
Drop the stale Windows expectedFailure on logging queue config
and unskip test_reinit_tls_after_fork plus the asyncio
local_addr family test.
Assisted-by: Grok:4.6
* Restore import lock depth after fork; add WASI clock info
Zeroing IMP_LOCK in the child discarded its recursion count, so
imp.release_lock() raised and test_fork1 exited 1. Re-acquire the
saved depth, then drop the extra pre-fork hold.
Expose time.get_clock_info on WASI via clock_getres so test_int
Stopwatch can run.
Unskip lock_tests test_acquire_contended and test_thread_leak.
Assisted-by: Grok:4.6
* Honor chmod follow_symlinks=False via fchmodat
Linux chmod followed the symlink, so dangling links raised
FileNotFoundError instead of NotImplementedError. Use fchmodat
with AT_SYMLINK_NOFOLLOW and map ENOTSUP to NotImplementedError.
Unskip httpservers truncated Content-Length (CPython already
skips as root) and tempfile symlink-mode cleanup on Linux.
Assisted-by: Grok:4.6
* Unskip httplib local bad-hostname HTTPS test
The skip was leftover. With default ssl-rustls the test passes
under -W error on Linux.
Assisted-by: Grok:4.6
* Fix list cmp deadlock, wasm digit overflow, REPL prompt
Do not hold list/deque locks across item comparison callbacks.
Compute int-to-str digit bounds in u64 so the check cannot wrap
on wasm32. Snapshot set contents when list.extend copies a set.
For a non-TTY stdin, write the REPL prompt to stderr and read
lines from stdin. Flush stdout/stderr after each interactive
command. Set sys.ps1/ps2 to ">>> " and "... ".
Unskip list mutation compares, asyncio all_tasks race, importlib
deadlock/parallel/circular-import tests, and REPL stdout flush.
Assisted-by: Grok:4.6
* Avoid unnecessary u64 cast in int-to-str digit check
bits() is already u64, so `bits as u64` fails clippy
unnecessary_cast under -Dwarnings.
Assisted-by: Grok:4.6
* host_env: export winsound, spawn, and remaining SSL_OP flags
Assisted-by: Claude
* stdlib: take winsound, nt spawn, and SSL_OP names from host_env
Assisted-by: Claude
* host_env: export ssl alerts, sysexits, socket extras
Assisted-by: Claude
* stdlib: take remaining host_env and common constants
Assisted-by: Claude
* Remove unused workspace exitcode dependency
Assisted-by: Claude
* host_env: export PROTO, access, reparse, wait flags
Assisted-by: Claude
* stdlib: take PROTO, access, reparse, wait from host_env
Assisted-by: Claude
* Keep type dict keys and report current f_lasti
Snapshot the MRO during lookup so non-string keys can run __eq__,
skip subclass updates when set_bases is reentered, make module
__dict__ a readonly member, and forbid deleting exception __dict__.
f_lasti is the current opcode; line events skip NO_LOCATION units.
Assisted-by: Grok:grok-4.6
* Fire settrace call events from RESUME
PY_START/PY_RESUME become a 'call' event only at the first RESUME
of a frame activation, so lasti is the resume unit and f_trace_lines
is honored. Unskip passing TraceTestCase methods.
Assisted-by: Grok:grok-4.6
* Record what_event so f_lineno jumps match line traces
Store the current monitoring event while a trace callback
runs, reject jumps from call/return/exception, unwind tracer
errors in the traced frame, and fire call on PY_THROW.
Unskip JumpTestCase except the infinite-loop and five remaining xfails.
Assisted-by: Grok:grok-4.6
* Fire remaining settrace events from opcodes and jumps
Keep GET_ANEXT's iterator in mark_stacks, dispatch non-call
events through f_trace, fire PY_YIELD/PY_RETURN from the
opcodes, emit same-line LINE on backward jumps, and raise at
flattened call sites. Unskip the rest of test_sys_settrace.
Assisted-by: Grok:grok-4.6
* Fix trampoline raise panic and unxfail passing traces
Do not decode inline-cache units as opcodes when a flattened
call raises. Remove expectedFailure from test_trace and
test_regrtest coverage tests that now pass.
Assisted-by: Grok:grok-4.6
* Fire profile returns without a per-frame f_trace
setprofile must see PY_RETURN/PY_YIELD even when f_trace is unset.
Drop EXPECTED_FAILURE from the pdb doctest and unxfail
test_unfinished_generator.
Assisted-by: Grok:grok-4.6
* host_env: export remaining Win32 exception and file constants
Assisted-by: Claude
* _winapi: take COPY_FILE_DIRECTORY and FILE_TYPE_UNKNOWN from host_env
Assisted-by: Claude
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
* Record a module's docstring mismatches on their own
They were only kept when the module also had missing items or signature
mismatches, so annotationlib, base64, ntpath and _ctypes reported none.
Whether a module counts as implemented still depends on missing items
and signatures alone.
Assisted-by: Claude Code:claude-opus-5
* Report a builtin type method that differs as a mismatch
A method whose signature or docstring differed was listed under
"builtin items" as if it were missing, with both extra_info dicts as the
reason. That section feeds the website's builtin_items.csv. Differences
now go to mismatched_items and mismatched_doc_items, keyed by type name,
like module items. Nothing reaches this path yet because builtin
signatures are still skipped; without this change, lifting that skip
turns the one "builtin items" line into 455.
Assisted-by: Claude Code:claude-opus-5
* Compare signatures and docstrings of native callables
extra_info() skipped anything inspect treats as builtin since cc2c46b1b
(#2410), when RustPython had no __text_signature__ for builtins. It has
one now, so --signature and --doc cover functions and methods written in
Rust. Modules with a mismatched signature go from 45 to 134, and 160 of
the 710 mismatched items are ones CPython itself cannot parse, which the
--signature listing already skips.
__builtins__ is no longer compared. inspect.signature() evals defaults in
the owning module's namespace and eval() adds __builtins__ there, so
CPython's builtins module gained one after list.index was inspected and
it showed up as missing.
Assisted-by: Claude Code:claude-opus-5
* Scan the members of native classes in each module
A module was only compared one level deep, so a native class counted as
present whatever its methods were. Classes a module owns and that are
not Python-defined are now opened too, and their own members are
compared as "Class.member": 438 classes and 4,833 members, 1,033 of
which have a signature --signature reports.
A class is native when it has no __firstlineno__, which a class
statement records, and no Python functions of its own, which rules out
namedtuple-style classes made by type(). BUILTIN_TYPES moves to module
level so the builtin types are not reported twice, an alias like
array.ArrayType is skipped, and CPython's __annotations_cache__ and
__vectorcalloffset__ are left out.
RustPython follows the CPython list instead of deciding again. A member
only inherited is listed as missing with "(inherited)", as builtin type
methods are. A class missing here, or implemented as something else such
as _sha3's hash functions, is reported by its own line only.
Assisted-by: Claude Code:claude-opus-5
* Report a module that exists but cannot be imported
dir_of_mod_or_error() ran dir() on the exception import_module() returns,
so a failed import looked like a module whose every item is missing:
sqlite3 alone filled 198 of those lines, and CPython's own _ios_support
was compared as a module holding ImportError's attributes. Returning the
exception reaches the "exists but not importable" line that was already
written for it, and drops 529 lines from "stdlib items".
Assisted-by: Claude Code:claude-opus-5
* Compare a module's own docstring
extra_info() reports a docstring for callables, and a module is not one,
so the __doc__ item both sides record was None and a module docstring
never counted as a mismatch. Reading it with getdoc(), the way a
callable's is read, brings 221 module docstrings into the comparison.
sys is the one that differs; base64 and imaplib differ here only
because their Lib copies track 3.14.7 while this run used 3.14.6.
Non-callables keep reporting None. getdoc() on a plain value answers
with its type's docstring, which would turn every string constant into
a mismatch.
Assisted-by: Claude Code:claude-opus-5
* Decide a member's ownership by the class dictionary
attr_is_not_inherited() compared the attribute's value with each base's.
That took an inherited classmethod for the class's own, since a bound
method compares unequal across classes, and dropped an own attribute
whose value matched a base's default None: 394 of CPython's in all,
ast.FunctionDef.returns among them. On the RustPython side it called
AttributeError.name, a class attribute set to None, inherited.
Ownership now means the class dictionary holds the name. An inherited
member is reported only when what it resolves to differs from CPython's
own, so dict_items.__doc__, a slot CPython fills with None that
RustPython resolves to None without one, stays quiet. "(inherited)"
lines drop from 196 to 54, and ast.alias.end_lineno is among the real
gaps that appear.
Assisted-by: Claude Code:claude-fable-5-1
Return the kernel thread id (gettid / pthread_threadid_np /
GetCurrentThreadId). threading.get_native_id and Thread.native_id
follow once the function exists.
Assisted-by: Grok:4.6
malachite-bigint 0.12.0 was published while the workspace pinned 0.11.0.
pymath requires malachite-bigint = "0", so a fresh resolve picks 0.12 for
it and leaves the workspace on 0.11, putting two incompatible BigInt types
in one graph. example_projects carry no lockfile and resolve fresh.
malachite-q and malachite-base move with it. No source change is needed.
Assisted-by: Grok:grok-4.6
`char_to_decimal` carried its own sorted table of 590 decimal digit
characters, added in #5643 because `common` had no way to reach the
Unicode numeric data at the time: it lived in `stdlib`, which sits above
`common` in the dependency graph. The table's own comment said as much —
"this should probably live in a crate like unic or unicode-properties".
#8211 extracted that data into `rustpython-unicode`, below `common`, and
made `common` depend on it, so the table can now be dropped in favour of
`Ucd::decimal` — the same source `unicodedata.decimal` consults.
This fixes a CPython incompatibility. The table was last updated for
Unicode 10; the bundled UCD is Unicode 17, which has 180 more decimal
digits across 18 scripts (Hanifi Rohingya, Wancho, Tangsa, Ol Onal,
segmented digits and others). Those were rejected by `int()` and
`float()` even though `unicodedata.decimal` knew their value:
>>> int('\u{10D33}') # HANIFI ROHINGYA DIGIT THREE
ValueError # CPython: 3
>>> unicodedata.decimal('\u{10D33}')
3
All 590 characters the table covered keep their previous value, so
nothing that already worked changes, and the two lookups can no longer
drift apart on a future Unicode update.
The lookup costs about 1.5ns more per non-ASCII character, since it reads
a property trie and a value table instead of binary-searching one 2.4KB
array: `int()` over a 4000-digit non-ASCII string goes from 12.2 to
13.6 ns/char. ASCII input never reaches it — the sole caller,
`transform_decimal_and_space_to_ascii`, returns early for ASCII strings —
so ordinary numeric parsing is unaffected.
Assisted-by: Claude Code:claude-opus-5
decompress_chunks reports whether the codec signalled LZMA_STREAM_END,
and it short-circuits when the chunker has nothing left to feed. That
early return answered "the stream ended" for the case where no input was
supplied at all, so LZMADecompressor.decompress(b"") claimed a finish the
decoder had never signalled.
The caller latches that answer with `self.eof |= stream_end`, which only
ever flips eof on. A single empty call therefore finished the object for
good: needs_input went false and every later call was rejected by the
`if self.eof` guard with EOFError, before a single compressed byte had
been seen. CPython leaves eof false and needs_input true, and accepts
compressed data handed over by a later call.
d = lzma.LZMADecompressor()
d.decompress(b"") # d.eof was True, now False
d.decompress(blob) # was EOFError, now b'data'
The zlib engine returns false from the same short-circuit; lzma had
drifted away from it. bz2 was fixed incidentally by #8638 when its engine
moved into crates/common, so only lzma needed a code change.
Verified on macOS arm64 against CPython 3.14.7: the script from the issue
now prints the documented "False True" and b'data' for both
decompressors. test_decompressor_chunks_empty in Lib/test/test_lzma.py
covers exactly this and no longer needs its expectedFailure marker. The
added engine test is named after the zlib one that already existed and is
mirrored into bz2, so all three engines stay pinned to the same
behaviour. test_lzma, test_bz2, test_zlib, test_gzip, test_tarfile,
cargo test --workspace, cargo fmt --check and cargo clippy
-p rustpython-common --all-features --all-targets -D warnings are clean.
Fixes#8637
Assisted-by: Claude Code:claude-opus-5