Skip to main content

1670. gopy objects overview

Goal

The 1670-1689 block covers the port of cpython/Objects/ (about 112k lines of C across 47 .c files). It runs alongside the rest of the 1600 series and together they form the gopy interpreter core.

This block was previously the 1700 series; the renumber keeps the whole port under one spec folder. Old references to "1700" point here.

Same rule as 1600: 100% behavioural compatibility with CPython 3.14. Same data shapes, same protocol semantics, same error messages. Only naming and surface API style move to Go conventions.

The Objects port is the most behaviour-rich part of CPython. The dict probing sequence, the unicode kind layout, the type-mro caching, the exception args slot, the descriptor protocol: each of these is observable through normal Python code, so each needs to round-trip exactly.

Sources of truth

ConcernSource
Object protocolInclude/object.h, Include/cpython/object.h
Type slotsInclude/cpython/typeobject.h
Per-type semanticsObjects/<type>object.c
Abstract protocolsObjects/abstract.c
Refcount and lifecycleObjects/object.c
Allocator (deferred)Objects/obmalloc.c

Spec files in this block

#FileFocusPhase
16701670_gopy_objects_overview.mdThis filemeta
16711671_gopy_object_protocol.mdObject interface, Header, VarHeader, refcountv0.2
16721672_gopy_type.mdType, slots, MRO, lookupv0.2
16731673_gopy_long.mdlongobject.c (PyLong, small-int cache, parsing)v0.2
16741674_gopy_float_complex.mdfloatobject.c, complexobject.cv0.2 / v0.6
16751675_gopy_bool_none.mdboolobject.c, None / NotImplemented singletonsv0.2
16761676_gopy_bytes.mdbytesobject.c, bytearrayobject.c, bytes_methods.cv0.4
16771677_gopy_unicode.mdunicodeobject.c, unicodectype.cv0.4
16781678_gopy_tuple.mdtupleobject.cv0.2
16791679_gopy_list.mdlistobject.cv0.2
16801680_gopy_dict.mddictobject.c, odictobject.cv0.2
16811681_gopy_set.mdsetobject.c (set, frozenset)v0.4
16821682_gopy_slice_range.mdsliceobject.c, rangeobject.cv0.2
16831683_gopy_abstract.mdabstract.c (PyObject_, PyNumber_, PySequence_, PyMapping_, PyIter_*)v0.2+
16841684_gopy_call.mdcall.c, vectorcallv0.6
16851685_gopy_descr_method.mddescrobject.c, methodobject.c, classobject.c, funcobject.cv0.4 / v0.7
16861686_gopy_exceptions.mdexceptions.c (BaseException + the full hierarchy)v0.3
16871687_gopy_code_frame_gen.mdcodeobject.c, frameobject.c, genobject.c, cellobject.cv0.5 / v0.6
16881688_gopy_module_misc.mdmoduleobject.c, namespaceobject.c, structseq.c, capsule.c, iterobject.c, enumobject.cv0.7
16891689_gopy_obj_misc.mdweakrefobject.c, memoryobject.c, fileobject.c, picklebufobject.c, typevarobject.c, unionobject.c, genericaliasobject.c, interpolationobject.c, templateobject.c, obmalloc.c (stub)v0.7+

Phasing

PhaseSpecs that ship
v0.21671, 1672, 1673, 1674 (float only), 1675, 1678, 1679, 1680, 1682, 1683 (subset)
v0.31686 (BaseException + KeyError + the gating hierarchy)
v0.41676, 1677, 1681, 1685 (descriptor protocol minus tp_new)
v0.51687 (code object only; frame/gen wait on v0.6)
v0.61674 (complex), 1684, 1687 (frame, gen)
v0.71685 (tp_new / tp_init / tp_alloc), 1688, 1689 (subset)
v0.101689 (weakref, memoryview, etc.) round out alongside cycle GC

Compatibility floors

Items that must match CPython exactly, gating each release:

  1. repr(obj) for every concrete type. Float repr uses shortest-roundtrip dtoa.
  2. hash(int), hash(float), hash(str), hash(bytes), hash(tuple), hash(frozenset), hash(None). SipHash-1-3 keyed from PYTHONHASHSEED.
  3. Dict iteration order: insertion order; same probing sequence as lookdict_unicode_nodummy / lookdict_split.
  4. List growth pattern: same list_resize curve.
  5. Tuple identity for empty tuple: () is () returns True.
  6. Small-int caching: -5..256 are cached singletons.
  7. None, True, False, NotImplemented, Ellipsis are singletons.
  8. Exception args slot byte-equal CPython for every constructor in the hierarchy.
  9. type.__mro__ matches CPython's C3 linearisation.
  10. Descriptor protocol order: data descriptors beat instance dict beat non-data descriptors (CPython type_getattro ordering).

Test strategy

objtest/ carries the cross-cut gates per phase:

  • v0.2: TestGateBuildDict, TestGateHashTuple, TestGateIterList.
  • v0.3: exception construction + str round-trip panel.
  • v0.4: unicode kind round-trip; bytes hash parity.
  • v0.5: code-object equality panel against compile.Compile.
  • v0.6: frame creation + generator close.

Each per-type spec carries its own per-type tests; this overview only lists the cross-cut gates.

v0.5 status checklist

This block did not gate v0.5 (compile pipeline); it gates v0.2. Tracking v0.5-relevant Objects work here for visibility:

  • Object header + refcount placeholder shipped via objects/ (per project memory; replaced by the full v0.2 port).
  • Code object stub used by compile.Compile (compile/code.go).
  • Code object port to Objects/code.go proper. Lands in v0.5.5 alongside the parser handover.
  • Frame object + generator object. Lands in v0.6.

Block-level checklist

Status: [x] shipped, [ ] pending, [~] partial / scaffold, [n] deferred / not in scope this phase.

Cross-cut artefacts

  • objects/ package skeleton (header, type, placeholder hash).
  • objtest/ v0.2 gate harness scaffold.
  • compat/ golden tests for repr / hash / dict-iter parity.

Per-spec progress (one row per sub-spec)

SpecStatusNotes (audited 2026-05-06)
1671[~]Header + refcount + Object interface shipped; repr.go / hash.go (SipHash key) / identity.go pending
1672[~]Type + v0.2 slot subset + trivial-base MRO shipped; method-bundle split, type_repr, descriptor-aware getattro pending
1673[~]Int struct on math/big shipped; arithmetic, bitwise, parse, cache, hash/repr/format pending
1674[~]Float struct + basic arithmetic shipped; pystrtod repr, float_parse, complex (v0.6) pending
1675[~]bool + None shipped; NotImplemented and Ellipsis singletons pending
1676[ ]bytes / bytearray / bytes_methods all pending (v0.4)
1677[~]strstub.go placeholder shipped; PEP 393 str, methods, format, codecs/intern pending (v0.4)
1678[~]Tuple struct + empty-tuple singleton shipped; hash, repr, count/index, richcompare pending
1679[~]List struct + Append/Pop shipped; CPython resize curve, Timsort, methods, richcompare pending
1680[~]Dict struct + probing shipped; four lookdict variants, mutate, views, split-table, odict pending
1681[x]Set + frozenset shipped (#233); set_ops algebra and frozenset XOR hash pending
1682[~]Slice + Range structs shipped; slice_indices, range_iter, Ellipsis pending
1683[~]abstract subset (Length/GetItem/RichCmp/Hash/Repr/Add/Sub/Mul/Iter) shipped; bitwise/MatMul/Index, mapping protocol, slice ops pending
1684[~]call.go minimal (Call/CallNoArgs/CallOneArg) shipped; full vectorcall, *args/**kwargs unpacking pending (v0.6)
1685[~]Function/Cell minimal shipped; descr.go, property, cfunction (METH_*), bound method, full Function pending (v0.4 + v0.7)
1686[~]BaseException + LookupError/KeyError/IndexError + ImportError shipped (#232); Simple/Arithmetic/OS/Syntax/Unicode/Warning/Group pending
1687[~]Code (scaffold) + Cell + Generator (minimal) shipped; full code repr/hash, frame, frame_locals, gen full, coroutine, async_gen pending (v0.6)
1688[~]Module shipped (#231); namespace, structseq, seqiter/enum, capsule pending (v0.7)
1689[ ]weakref / memoryview / file / typevar / union / templates all pending (v0.7+ / v0.10)

Out of scope

  • obmalloc.c small-block pool: Go's allocator handles this. We ship a stub in 1689 that records the public API surface but delegates to make / new.
  • C extension ABI (PyObject* layout exposed to .so files). gopy does not load C extensions; see 1600 §Compatibility floors.
  • Free-threaded reader paths (ob_tid, ob_mutex, etc.). Land in v0.14 alongside gc/freethreading.go.