Commit Graph
17473 Commits
Author SHA1 Message Date
Jeong, YunWon 63b80efc9f Read cached __slotnames__ and propagate slot name errors (#8895)
type_slot_names reads __slotnames__ from the type's own dict before
calling copyreg._slotnames, and rejects a cached value that is not a
list or None. object_getstate_default no longer replaces errors from
type_slot_names with TypeError("cannot pickle object"), so a
RecursionError raised there propagates.

Assisted-by: Claude:claude-opus-5-5
2026-09-29 11:04:41 +09:00
dependabot[bot] b499e70e12 build(deps): bump thiserror in the thiserror group across 1 directory (#8888)
Bumps the thiserror group with 1 update in the / directory: [thiserror](https://github.com/dtolnay/thiserror).


Updates `thiserror` from 2.0.20 to 2.0.21
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.20...2.0.21)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: thiserror
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 02:15:55 +09:00
Jeong, YunWon 8f84fea377 Fix 32-bit member layout assertions and address member descriptor review (#8882)
* Address review findings on member descriptors

Member definitions carry an internal `PY_ATOMIC` flag taken from
`MemberLayout::ATOMIC`, and loads use an atomic access only for atomic
storage; extension members never set it. `XMLParser` publishes its new
state, `entity` and `target` only after every handler lookup succeeds.
`subs_parameters` reads type names only for the error. The unraisable
hook prints `<unknown>` when `__module__` fails or is not a str. The
builtin function `__reduce__` decides on the bound object alone.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Fix member layout assertions on 32-bit targets

The tp_flags assertion compared AtomicU64 with u64 alignment, which differs
on i686. The kevent assertion required usize, isize, c_ulong and c_long to be
64-bit. Both now check only what the member cells need.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Use bitflags for member definition flags

PY_READONLY, PY_AUDIT_READ, PY_RELATIVE_OFFSET and PY_ATOMIC become the
repr(transparent) PyMemberFlags. C extension flags are read with
from_bits_retain.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5
2026-09-29 01:59:05 +09:00
dependabot[bot] a7bc8638c6 build(deps): bump taiki-e/install-action from 2.87.8 to 2.87.17 (#8883)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.87.8 to 2.87.17.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/d438492cf8a250514fa2d34b30bc3c0dc37c65ff...94c31af3204a9f15ab40b35ad084410b905bbc73)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.87.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 01:57:50 +09:00
dependabot[bot] 408842ab5b build(deps): bump github/gh-aw/actions/setup from 0.89.14 to 0.89.17 (#8887)
Bumps [github/gh-aw/actions/setup](https://github.com/github/gh-aw) from 0.89.14 to 0.89.17.
- [Release notes](https://github.com/github/gh-aw/releases)
- [Changelog](https://github.com/github/gh-aw/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw/compare/97b9a7c376bb60bd7cbcf348a5a6349b52e266ff...00457477720387bcc7d7baaf841dedb22ad06617)

---
updated-dependencies:
- dependency-name: github/gh-aw/actions/setup
  dependency-version: 0.89.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 00:35:36 +09:00
dependabot[bot] 97de0f9d24 build(deps): bump https://github.com/astral-sh/ruff-pre-commit (#8885)
Bumps [https://github.com/astral-sh/ruff-pre-commit](https://github.com/astral-sh/ruff-pre-commit) from v0.16.7 to 0.16.8.
- [Release notes](https://github.com/astral-sh/ruff-pre-commit/releases)
- [Commits](https://github.com/astral-sh/ruff-pre-commit/compare/v0.16.7...v0.16.8)

---
updated-dependencies:
- dependency-name: https://github.com/astral-sh/ruff-pre-commit
  dependency-version: 0.16.8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 00:35:13 +09:00
dependabot[bot] ab2fd0de33 build(deps): bump https://github.com/rbubley/mirrors-prettier (#8884)
Bumps [https://github.com/rbubley/mirrors-prettier](https://github.com/rbubley/mirrors-prettier) from v3.9.6 to 3.9.8.
- [Commits](https://github.com/rbubley/mirrors-prettier/compare/v3.9.6...v3.9.8)

---
updated-dependencies:
- dependency-name: https://github.com/rbubley/mirrors-prettier
  dependency-version: 3.9.8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-29 00:34:51 +09:00
Jeong, YunWon 4344a34a3c Stop Rust comments on Python items from becoming __doc__ (#8893)
Use `//` instead of `///` on Python-exposed items so their comments are not
published as `__doc__`.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7
2026-09-29 00:24:48 +09:00
1ndahous3 cc8b4d4f7e Compact sparse dictionary and set copies (#8879)
Assisted-by: Codex:GPT-6
2026-09-28 14:44:25 +00:00
1ndahous3 56eadb2997 Choose smaller difference scans and install completed intersections (#8881)
Assisted-by: Codex:GPT-6
2026-09-28 22:13:26 +09:00
1ndahous3 fd108237e4 Preallocate binary joins and preserve buffer lifetimes (#8880)
Assisted-by: Codex:GPT-6
2026-09-28 22:12:37 +09:00
1ndahous3 47eb9509b9 Reuse unchanged strings and fix mixed-representation stripping (#8878)
Assisted-by: Codex:GPT-6
2026-09-28 22:09:29 +09:00
1ndahous3 403a38cf49 Fix percent-format precision and integer conversion (#8876)
* Fix percent-format precision and integer conversion

Assisted-by: Codex:GPT-6

* Honor float subclass integer conversions in percent formatting

Assisted-by: Codex:GPT-6
2026-09-28 22:08:26 +09:00
1ndahous3 bb054f6e1b Release deque items outside locks during clear and assignment (#8875)
Assisted-by: Codex:GPT-6
2026-09-28 22:07:28 +09:00
1ndahous3 19e9b7c38a Preallocate dictionary storage in dict.fromkeys (#8874)
Assisted-by: Codex:GPT-6
2026-09-28 22:06:48 +09:00
1ndahous3 af37a76c1f Floor and ceil exact floats directly in math.floor/math.ceil (#8834)
Assisted-by: Claude Code:claude-opus-5-5
2026-09-28 21:56:46 +09:00
1ndahous3 d1327131a5 Specialize module attribute loads (#8864)
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Codex:GPT-6
2026-09-28 21:55:11 +09:00
Alessio Attilio 7329839fb5 fix(core): align hashability of dict views, namespace, and typing builtins (#8844) 2026-09-28 21:53:58 +09:00
Alessio Attilio 908368eb1c test(xml_etree): unskip passing test_deeply_nested_deepcopy (#8868) 2026-09-28 07:05:41 +09:00
Alessio Attilio 50e17bc6fc test(descr, userlist): unskip passing recursion and deallocation tests (#8871) 2026-09-28 07:04:38 +09:00
1ndahous3 afae370753 Fix array search equality and reentrant callbacks (#8870)
Assisted-by: Codex:GPT-6
2026-09-28 07:03:55 +09:00
1ndahous3 e2335f1ca9 Avoid redundant work in set difference operations (#8869)
Assisted-by: Codex:GPT-6
2026-09-28 06:53:13 +09:00
1ndahous3 456a8dc9db Match common encoding names before normalizing them (#8862)
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Codex:GPT-6
2026-09-27 16:53:42 +00:00
1ndahous3 8c928c2444 Fix recursive sequence repetition fallback (#8865)
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Codex:GPT-6
2026-09-27 16:44:38 +00:00
1ndahous3 15c99b32a6 Look up attributes without raising before calling __getattr__ (#8863)
Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Codex:GPT-6
2026-09-27 16:31:40 +00:00
Alessio Attilio b9fea9c7be fix(contextvars): isolate context stack per interpreter and thread on VirtualMachine (#8838)
* fix(contextvars): isolate context stack per interpreter and thread on VirtualMachine

* style: format and sort imports in extra_tests/snippets/stdlib_contextvars.py

Assisted-by: Antigravity:Gemini-3.8-Flash
2026-09-27 16:31:18 +00:00
1ndahous3 9fd6d76a39 Reuse stored hashes for frozenset hashing and in-place set union (#8859)
Assisted-by: Codex:GPT-6
2026-09-27 15:49:40 +00:00
1ndahous3 ad8bfdba4e Reuse stored hashes when merging dictionaries (#8858)
Assisted-by: Codex:GPT-6
2026-09-27 15:31:00 +00:00
1ndahous3 d31ccae04d Collect cycles through deque iterators and cmp_to_key wrappers (#8861)
Assisted-by: Codex:GPT-6
2026-09-27 15:14:17 +00:00
Alessio Attilio 65647e99ee fix(csv): quote non-numeric objects in writer QUOTE_NONNUMERIC mode (#8843)
* fix(csv): quote non-numeric objects in writer QUOTE_NONNUMERIC mode

* style: format extra_tests/snippets/stdlib_csv.py

Assisted-by: Antigravity:Gemini-3.8-Flash
2026-09-28 00:13:35 +09:00
1ndahous3 f24b0d896b Stream deque inputs and release evicted items outside locks (#8860)
Assisted-by: Codex:GPT-6
2026-09-28 00:05:12 +09:00
Jeong, YunWon 1bbcdad42e ci: skip cross-target check for Cargo.lock removals (#8866)
A Cargo.lock change no longer forces the cross-target cargo check by
itself. The check runs when the lock diff adds lines, or when a removed
package is still referenced from Rust sources.

Assisted-by: Claude Code:claude-opus-5-5
2026-09-28 00:03:51 +09:00
Jeong, YunWon 31963fa767 Expose more attributes as member descriptors (#8857)
* Read type.__module__ from the dict only for heap types

A static type's `__module__` is the text before the last `.` of its name,
or `builtins`. A heap type reads its dict and raises `AttributeError`
when the entry is missing; `type` and `object` reprs ignore that error.
`type()` no longer stores `__module__ = None` when the caller's globals
have no `__name__`.

`#[pyexception(module = ...)]` now reaches the type name, and static
types that relied on a dict `__module__` (ast nodes, pyexpat, ssl,
_hashlib and _interpchannels errors, ExceptionGroup) carry their module.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Expose more builtin attributes as member descriptors

`code.co_flags`, `co_nlocals`, `co_filename`, `super.__self__`,
`__self_class__`, `__thisclass__`, `traceback.tb_frame`, `tb_lasti`,
`type.__itemsize__` and `builtin_function_or_method.__module__` are now
`#[pymember]` fields instead of getsets. `super` keeps its three
references in atomic cells instead of a lock, `tb_lasti` is an `i32`,
`co_nlocals` is stored at construction, and the builtin function
`__module__` is a writable object cell.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Expose stdlib attributes as member descriptors

Decompressor `eof`/`needs_input`/`unused_data` (bz2, lzma, zlib, plus
lzma `check`), `ContextVar.name`, `functools.partial` `func`/`args`/
`keywords`, socket `family`/`type`/`proto`, `select.kevent` fields,
`SemLock` `handle`/`kind`/`maxvalue`/`name`, `Pickler.bin`/`fast`,
`xmlparser.intern`, ElementTree `XMLParser.entity`/`target`,
`UCD.unidata_version`, `_ExceptHookArgs` fields, multibytecodec
`stream`, and `_io` `Buffered*.raw` and `TextIOWrapper`
`buffer`/`encoding`/`line_buffering`/`write_through` are now
`#[pymember]` fields instead of getsets.

Values that changed under a lock move to atomic cells on the payload.
New member kinds `Short`, `Long`, `String`, `UShort`, `ULong`,
`LongLong` and `ULongLong` access exactly the width of their C type.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Match bare super and static type itemsize

`super.__new__(super)` leaves `__thisclass__`, `__self__` and
`__self_class__` empty, and a super with no type takes the
zero-argument path when bound.

Static types carry their `tp_itemsize` (`type`, `memoryview`, `code`,
`frame`, generators, `_sre` objects, `_ctypes` thunks), inherit it from
their direct base when they leave it at 0, and a variable-size base
rejects any nonempty `__slots__` and a weakref slot.
`_thread._ExceptHookArgs` is a struct sequence.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Expose SimpleNamespace.__dict__, __basicsize__ and __flags__ as members

`SimpleNamespace.__dict__` addresses the instance dict cell the same way
`module.__dict__` does. `slots.basicsize` now holds the full
`tp_basicsize` (header plus payload), so `__basicsize__` reads it
directly. Type flags are one atomic word: `__abstractmethods__` and
`_abc` set their bits in it in place, the separate `abc_tpflags` word is
gone, and `__flags__` reads the word as an unsigned long member.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5
2026-09-28 00:03:27 +09:00
Jiseok CHOI f87170772e sqlite3: restrict Row case matching to ASCII (#8856)
Assisted-by: GitHub Copilot:GPT-5.6 Terra (medium)
2026-09-27 20:53:14 +09:00
Jiseok CHOI 7897287e94 sqlite3: raise IndexError for oversized Row indices (#8855)
Assisted-by: GitHub Copilot:GPT-5.6 Terra (medium)
2026-09-27 20:52:57 +09:00
Jiseok CHOI a63a53a15f sqlite3: reject text_factory deletion (#8854)
Assisted-by: GitHub Copilot:GPT-5.6 Terra (medium)
2026-09-27 20:52:40 +09:00
1ndahous3 1a259e494f Read live list elements during repr without copying the list (#8853)
Assisted-by: Codex:GPT-6
2026-09-27 20:50:22 +09:00
1ndahous3 360803ff47 Reuse set hashes and fix stored key comparison order (#8852)
Assisted-by: Codex:GPT-6
2026-09-27 20:49:26 +09:00
1ndahous3 afe106c89c Collect functools cycles and release replaced state outside locks (#8851)
Assisted-by: Codex:GPT-6
2026-09-27 20:47:33 +09:00
Jeong, YunWon be23b2c562 Store database docstrings xz-compressed behind an optional doc feature (#8836)
* Skip Python-defined classes when collecting builtin type docs

generate.py recorded every object.__subclasses__() entry as builtins.<name>
after importing the whole stdlib, so classes written in Python (tkinter,
unittest, tarfile, ...) ended up in the doc database. Classes that are
mutable heap types without C method descriptors and whose module is not a
C extension are now skipped, and their entries are removed from
data.inc.rs.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7

* Store database docstrings xz-compressed behind an optional doc feature

- rustpython-doc's build script compresses all database docstrings into
  one xz blob with an offset index; identical texts share one offset.
- Macros emit blob references for database docs; vm decompresses the
  blob on first access.
- New `doc` cargo feature (default on) in rustpython, rustpython-vm and
  rustpython-stdlib. Without it the blob and xz are not linked and
  database-backed __doc__ is None; __text_signature__ is unaffected.
- Native types without a docstring get __doc__ = None in their dict.
- Workflows that build with --no-default-features enable `doc` where
  tests or releases need docstrings.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7
2026-09-27 20:45:45 +09:00
1ndahous3 90afe00d6c Fix dict view comparisons and avoid temporary sets (#8849)
Assisted-by: Codex:GPT-6
2026-09-27 13:40:51 +09:00
1ndahous3andJeong, YunWon 04d5e12ead Raise MemoryError on impossible allocations and reuse list/tuple buffers (#8840)
* Raise MemoryError instead of aborting on impossible allocations

Assisted-by: Claude Code:claude-opus-5-5

* use CPython 3.14's integer digit limit for left shifts

* size the pow memory check by what malachite allocates

* Make sequence allocations fallible and reuse deallocation buffers

Assisted-by: Codex:GPT-6

---------

Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
2026-09-27 13:39:29 +09:00
Jeong, YunWon bdc9246b37 Address builtin members by field offset (#8816)
* Address builtin members by field offset

`#[pymember]` now declares a field of the payload and generates a
PyMemberDef whose offset is the payload offset plus the field offset.
The getter/setter function form and `MemberAccess::Func` are removed;
builtin, slot, and C-API members share one get/set path. The macro
checks the field type against the member type.

Converted members: property fget/fset/fdel/__doc__, function
__globals__/__closure__/__builtins__/__doc__/__module__, staticmethod
and classmethod __func__/__wrapped__, complex real/imag (T_DOUBLE),
frame f_trace_lines (T_BOOL), defaultdict default_factory, getset and
member descriptor __name__/__objclass__, module __dict__.
frame.f_trace_opcodes is a getset.

Writable member fields are atomic pointer cells. The instance dict
pointer is an atomic cell at a fixed offset in front of the object,
and dict presence follows the type's HAS_DICT flag. The pickle
basicsize check no longer counts dict, weakref, and slot storage,
which live outside the payload.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Address member review findings

- `#[pymember]` keeps leading `#[cfg]` attributes on the generated
  registration, and malformed `field`/`offset` values are compile
  errors.
- The `descriptor` module and the items the expansion names are public.
- Writable double members are an `AtomicU64` cell, loaded and stored
  with relaxed atomics. Readonly double members stay plain `f64` reads.
- `LOAD_ATTR_SLOT` is not specialized for `Py_AUDIT_READ` members.
- `defaultdict.__reduce__` passes no factory argument when
  `default_factory` is None.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Declare members on payload fields

`#[pymember]` goes on a payload struct field, or on the struct with an
explicit `offset` when the storage is not a payload field. The struct
`#[pyclass]` builds `PyClassDef::MEMBERS`, a static `PyMemberSpec`
table, and `extend_class` registers one member descriptor per entry.
`path` addresses a subfield, one field may carry several members, and a
`#[cfg]` on the field gates its entry. The impl-side const form is
removed and now a compile error.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Split nullable and non-null atomic cells

The nullable cell API (`new_empty`, `load_owned`, `store`,
`compare_exchange_empty`) moves from `PyAtomicRef<PyObject>` to
`PyAtomicRef<Option<PyObject>>`, and the typed `PyAtomicRef<Option<T>>`
shares it. The non-null `PyAtomicRef<PyObject>` gets `load_owned` and
`store` that return the object directly.

Slot cells, property fget/fset/fdel/__doc__, and defaultdict
default_factory are nullable cells. staticmethod and classmethod
callable are non-null cells and are read without `unwrap`. The
instance dict cell is `PyAtomicRef<Option<PyDict>>`, so reading it no
longer downcasts.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Drop the unused cold trace_lines flag

`FrameColdData::trace_lines` had no writer after `f_trace_lines`
became a frame object member. A frame without a frame object traces
lines by default.

Assisted-by: Claude:claude-opus-5-5

* Compute payload offsets from the merged Py header

`PyInner` is now `Py`, so the payload offset and the dict member
offset are measured from `Py<T>`.

Assisted-by: Claude:claude-opus-5-5

* Expose descriptor names and owner types as members

method_descriptor, classmethod_descriptor, and wrapper_descriptor
expose `__objclass__` and `__name__` as readonly members, and
method-wrapper exposes `__self__` as a readonly member. The separate
`objclass` field of method and classmethod descriptors always equaled
`common.typ` and is removed.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Expose remaining builtin tp_members as members

Attributes stored in a payload field become readonly or writable
member descriptors: bound method __func__/__self__, code
co_argcount/co_posonlyargcount/co_kwonlyargcount/co_stacksize (Py_T_UINT),
generic alias, coroutine and async generator members, interpolation and
template, range and slice start/stop/step, type __base__, union, and the
typing TypeVar, ParamSpec, TypeVarTuple, and TypeAliasType members.
`MemberKind` gains `Int` and `Uint` with the `PyMember_GetOne`/`SetOne`
range checks.

Attributes computed on access or kept behind a lock stay getsets.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Spell a docless member as doc = false

`#[pymember(doc = false)]` stores no docstring, matching the
`doc = "..."` form, and replaces the separate `no_doc` flag.

Assisted-by: Claude:claude-opus-5-5

* Make pymember readonly by default

`#[pymember]` declares a readonly member unless `writable` is given.
The `readonly` option is removed and every declaration is converted.

Assisted-by: Claude:claude-opus-5-5

* Check the receiver of method descriptors

Binding or calling a method_descriptor with an object that is not an
instance of the owner type raises TypeError before the native function
runs. Static and class methods are exempt.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Expose exception attributes as members

BaseException.__suppress_context__, StopIteration.value, SystemExit.code,
ImportError, NameError, AttributeError, OSError, SyntaxError,
BaseExceptionGroup and the UnicodeEncode/Decode/TranslateError attributes
are member descriptors backed by payload fields. ImportError, NameError,
AttributeError and SyntaxError gain payloads for their fields, and the
methods that read those attributes read the fields. Add the Py_ssize_t
member kind for UnicodeError start and end.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Avoid same-type casts in unsigned member conversion

On targets where c_ulong is u32, casting through c_ulong was a no-op
cast that clippy rejects.

Assisted-by: Claude:claude-opus-5-5

* Prefer an explicit pymember doc over the doc table

doc = "text" is used as the docstring without consulting the stored
attribute documentation; only an omitted doc looks it up. Drop the member
doc strings that repeated the stored documentation.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Infer pymember kinds from field types

MemberLayout gives the member kind of each accepted field type, and the
macro reads it from the field or path subfield, so type = "bool" and
the other numeric spellings are gone. type only selects object_ex.
Writable doubles use a new AtomicF64 cell instead of AtomicU64 bits.
MemberLayout and MemberCell replace the per-kind marker traits.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Read nullable atomic cells only through load_owned

PyAtomicRef<Option<T>> and PyAtomicRef<Option<PyObject>> lose to_owned,
to_owned_ordering and try_to_owned; load_owned, which retries the
incref until it applies to the pointer still in the cell, is the one
owned read. Callers that kept a deref borrow across VM calls now take a
strong reference.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Inherit static type slots from the whole MRO

extend_class copied slots only from the direct bases, and tp_init is
copied only from a base that defines it, so TabError missed the
SyntaxError init that IndentationError inherits. Walk the MRO the same
way init_slots does.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Let Rust doc comments win over stored docstrings

A /// comment on a Python-exposed item is its docstring; the
rustpython-doc entry is used only when there is none. #[pymember] reads
the field's /// comment instead of doc = "...". Doc comments that were
shadowed by a stored docstring become // comments, so no docstring
changes. AGENTS.md describes the rule.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Adapt members to upstream changes

_collections._tuplegetter.__doc__ is a writable nullable member on the
payload field. The impl-side const form no longer compiles.

Assisted-by: Grok:4.7

* Drop docstring text left as comments and inline downcast_cell

Comments that only repeated an item's docstring are removed; developer
notes stay as // comments. The typed cell methods call
downcast_unchecked directly, each with its own safety note.

Assisted-by: Grok:4.7
Assisted-by: Claude:claude-opus-5-5

* Read sqlite row factories through load_owned

The nullable cell no longer has to_owned; the sqlite module is built only
with the sqlite feature, so the default build did not catch it.

Assisted-by: Claude:claude-opus-5-5
2026-09-27 13:38:11 +09:00
1ndahous3 e2ca20882f Return at once when repeating an empty sequence (#8842)
* Return at once when repeating an empty sequence

Assisted-by: Claude Code:claude-opus-5-5

* use sys.maxsize for the empty array repeat check
2026-09-27 09:55:40 +09:00
1ndahous3 eabba7c1b7 Match CPython's overflow limits in math.perm and math.comb (#8841)
Assisted-by: Claude Code:claude-opus-5-5
2026-09-27 09:54:54 +09:00
1ndahous3 373b0da216 Add native _collections._tuplegetter and _collections._count_elements (#8835)
* Add native _collections._tuplegetter and _collections._count_elements

Assisted-by: Claude Code:claude-opus-5-5

* ruff + fixed unittest

* use PySsize

* remove docstring comment

* cover "get()" overriding
2026-09-27 09:52:24 +09:00
1ndahous3 32ca8aa6f5 Track deque mutations and release removed items outside locks (#8847)
Assisted-by: Codex:GPT-6
2026-09-27 09:50:09 +09:00
Jeong, YunWon cb40e2f349 Make the hash secret process-global (#8846)
Interned strings live in the process-wide Context and cache their hash.
Each top-level interpreter built its own HashSecret from its hash_seed,
so a second interpreter with a different seed looked up cached hashes
computed with the first secret and failed bootstrap with
`KeyError: _frozen_importlib`.

The secret is now a process-wide OnceLock set by the first top-level
interpreter; later seeds are ignored. The per-interpreter hash_secret
field and the check in VirtualMachine::new are removed.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7
2026-09-27 09:49:37 +09:00
Jeong, YunWon dc3b93abfb Read tuple, bytes, int, float and complex payloads through views on Py<T> (#8819)
* Read PyTuple payloads through as_slice()

- Add Py<PyTuple<R>>::as_slice(); it is generic over R, so typed tuples use
  the same view.
- Callers reach slice methods, indexing and slice arguments through
  as_slice().
- PyTuple's own sequence and mapping slots and marshal's set_marshal_item reach
  the remaining PyTuple methods through the payload field.
- The Py<T>::payload field is pub(crate).

Assisted-by: Claude Code:claude-opus-5-5

* Read PyBytes payloads through as_bytes()

- Callers read bytes through Py<PyBytes>::as_bytes().
- bytes.rs reaches PyBytesInner and the remaining PyBytes methods through
  the payload field; fspath and os call payload.contains_nuls().
- DictKey for [u8] falls back to the PyObject key_eq; it previously resolved
  to its own key_eq through Deref.

Assisted-by: Claude Code:claude-opus-5-5

* Copy capi tuple arguments with as_slice().to_vec()

Assisted-by: Claude Code:claude-opus-5-5

* Read sqlite3 Row tuples through as_slice()

Assisted-by: Claude Code:claude-opus-5-5

* Read platform-specific tuples and bytes through as_slice() and as_bytes()

Assisted-by: Claude Code:claude-opus-5-5

* Read PyInt and PyFloat payloads through as_bigint() and to_f64()

Add `Py<PyInt>::as_bigint()`, `Py<PyInt>::try_to_primitive()` and
`Py<PyFloat>::to_f64()`, which forward to the payload methods of the same
name. Reads of the `value` field and primitive conversions go through
these views; other PyInt and PyFloat methods are called through the
`payload` field inside rustpython-vm and through payload() outside it.

Assisted-by: Claude Code:claude-opus-5-5

* Read PyComplex payloads through as_complex()

Add Py<PyComplex>::as_complex() and use it at the call sites that
read the payload directly.

Assisted-by: Claude Code:claude-opus-5-5

* Move PyInt conversion helpers to Py<PyInt>

try_to_i64_fast(), to_str_radix_10(), as_u32_mask(), as_u64_mask(),
try_to_primitive() and try_to_primitive_raw() only read the integer
value, so they are defined on Py<PyInt> and callers no longer go through
the payload. PyRange computes its protocol length from the BigInt
directly instead of building a PyInt payload.

Assisted-by: Claude Code:claude-opus-5-5

* Share one conversion between try_to_primitive() and its OverflowError variant

Py<PyInt>::try_to_primitive() and try_to_primitive_in_range(), renamed
from try_to_primitive_raw(), both call to_primitive(). They differ only
in how a negative value for an unsigned type is reported: ValueError for
try_to_primitive(), OverflowError for try_to_primitive_in_range(). The
target type is bound with `for<'a> TryFrom<&'a BigInt>`, so the methods
no longer tie a lifetime to &self.

Assisted-by: Claude Code:claude-opus-5-5

* Move PyInt bitwise operators to Py<PyInt>

__xor__, __or__, __and__ and their int_op() helper are defined on
Py<PyInt>. PyBool calls them without going through the payload.

Assisted-by: Claude Code:claude-opus-5-5

* Move PyBytes operators to Py<PyBytes>

__add__, __contains__, __getitem__ and __mod__ are defined on
Py<PyBytes>. The subscript, contains and remainder slots call them
without going through the payload.

Assisted-by: Claude Code:claude-opus-5-5

* Move PyInt general_op() and modpow() to Py<PyInt>

The power slot calls them on Py<PyInt> without going through the
payload.

Assisted-by: Claude Code:claude-opus-5-5
2026-09-27 07:59:52 +09:00
Jeong, YunWonandRoshan Ramani 5c875d322f Call __index__ in default integer argument conversion (#8828)
* Accept `__index__` objects for integer arguments

CPython converts these nine arguments with `__index__`, RustPython
required an exact `int`. Uses the existing `ArgSize`/`ArgPrimitiveIndex`
converters at each call site rather than widening the blanket `int`
conversion, so argument paths CPython keeps strict (ctypes pointers,
thread handles) are unaffected, and the range check happens while the
argument is bound rather than in the method body.

Also widens `maxsplit` before adding one. `sys.maxsize` was already
reachable there with a plain `int` and overflowed in a debug build.

Assisted-by: Claude Code:claude-opus-5

* Add snippet for `__index__` argument conversion

Expectations verified against CPython 3.14.

Assisted-by: Claude Code:claude-opus-5

* Call __index__ in primitive integer conversion; add ArgStrictInt

The TryFromObject impls for isize, usize and the fixed-width integer
types now take an int (or subclass) as-is and otherwise call __index__,
instead of accepting only int instances.

ArgStrictInt<T> keeps the old int-only conversion. The ctypes address
and handle arguments (from_address, PyObj_FromPtr, dlsym, dlclose,
call_function, call_cdeclfunction, non-Windows FreeLibrary) use it.
_thread._make_thread_handle checks for an int itself and raises
"ident must be an integer".

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7

* Accept __index__ where arguments were bound as int objects

chr, bin, math.factorial, zlib.crc32/adler32, binascii.crc32/crc_hqx,
the start/stop of sequence index(), the select event mask and a
__len__ result took an int object directly and rejected other objects
with __index__. They now go through __index__.

math.ldexp still accepts only an int for its exponent and raises
"Expected an int as second argument to ldexp." otherwise.

Extend protocol_index_argument.py with the newly accepted calls, an int
subclass whose __index__ is not called, and the sites that still
reject __index__.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7

* Replace ArgPrimitiveIndex and ArgSize with PySsize/PySize aliases

The primitive integer conversions call __index__ themselves, so
ArgPrimitiveIndex<T> and its alias ArgSize behaved the same as T. They
are removed. Arguments that used ArgSize or ArgPrimitiveIndex<isize>
now take PySsize (= isize), ArgPrimitiveIndex<usize> takes PySize
(= usize), and the other ArgPrimitiveIndex<T> take T. Those with a
literal fallback take it as a `default`; those where a missing argument
is a distinct state stay OptionalArg.

list.insert is a #[pymethod] again instead of going through a wrapper.

Assisted-by: Claude:claude-opus-5-5
Assisted-by: Grok:grok-4.7

---------

Co-authored-by: Roshan Ramani <roshanramani.dev@gmail.com>
2026-09-27 01:22:19 +09:00