mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
* 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