Fixed
- **A record's docs now reach the runtime type on `apply`, not only the
`.pyi` (gh-1267).** gh-646 made `_record.descriptor_c` emit the record
type's own doc and each field's doc into the two `PyStructSequence`
tables, from the same `_record.fields` / `_record.type_doc` calls the
`.pyi` writer uses -- but nothing refreshed an *existing* fragment. A
module object's `native/src/<mod>/<mod>_ext_<obj>.c` is sacred: it is
spliced, never re-rendered, so hand-written bindings survive, and
`_docsync` carries derived prose into it instead -- for `PyMethodDef`,
`PyGetSetDef` and `tp_doc`, but not for the structseq descriptor. That
descriptor was therefore frozen at the moment the method was first
declared, so documenting the record afterwards (`/**< … */` on the struct
members in the sacred header, or `record_doc` / a `--result-field` doc in
the manifest) reached the `.pyi` and stopped: the stub grew a full
`Attributes` table while `help()` on the built type showed
`{"n", NULL}` and the `Sum(n, mean)` synopsis. Measured in doppler on
0.75.3, where gh-1264 made these types real module attributes and so made
the gap visible. The standalone path never had it -- it re-renders
`<comp>_ext.c` wholesale. Fixed by teaching the transplant the two
tables; those slots have no hand-written variant to protect, since the
whole descriptor is generated from the manifest and the header.
- **One extension module now publishes exactly one type object per record
name, so a view and its parent sharing a `single = true` method no
longer segfault (gh-1268).** gh-1264 deduplicated the list of records to
register in `_record.registrations`, which sees one *component*, while
the name being deduplicated is an attribute of the whole *module*. A view
and its parent each passed their own "first occurrence" test, so the
aggregator emitted `PyModule_AddObject(m, "FrameLayout", ...)` twice with
two different type objects. That call *steals* the reference it is given:
the second dropped the module's only reference to the first type, which
survived on its own `tp_mro`/descriptor self-references as an unreachable
cycle and was freed at the next GC pass -- while the first wrapper's
`static PyTypeObject *` still pointed at it. The next call through that
wrapper read freed memory. Nothing failed at import, and on a fresh
interpreter the first call still returned a correct-looking record, which
is why it shipped; doppler caught it as `make test-stubs` exiting 139.
The rule now lives in `_record.resolve`, over a namespace the module
aggregator keeps for all of its components: a repeat of a name already
claimed by an identical shape **aliases** the first type object
(`SeededAcc_summary_type = Acc_summary_type;`) instead of registering a
second, so both classes return instances of the one class the `.pyi`
declares and `isinstance` holds for both. A repeat claiming one name with
a **different** shape is refused instead -- aliasing would fill a
descriptor of one arity from a kernel of another -- and `jm method`
refuses it before writing anything, naming both claimants, both field
lists, and `--record-name` as the way out.