Skip to main content

1688. gopy module and misc

What we are porting

Six small files, ~3500 lines combined:

  • Objects/moduleobject.c: module type. Holds __dict__, __name__, __doc__, __loader__, __spec__, __file__, __path__. The dual-storage pattern: most attributes live in __dict__, but the type also tracks md_dict, md_def, md_state for C-defined modules.
  • Objects/namespaceobject.c: types.SimpleNamespace. Tiny: attribute access through __dict__, repr lists fields sorted.
  • Objects/structseq.c: tuple-with-named-fields used by os.stat_result, sys.version_info, time.struct_time. Fixed-size, named fields, optional unnamed extras.
  • Objects/capsule.c: PyCapsule. Opaque pointer container used by C extensions to expose internal pointers across module boundaries. gopy's port stores an interface{}; the C-pointer ABI is irrelevant since gopy does not link C extensions.
  • Objects/iterobject.c: iter (sequence iterator) and callable_iterator (the two-argument iter() form). Generic wrappers used when a type has __getitem__ but no __iter__.
  • Objects/enumobject.c: enumerate and reversed builtins.

Go shape

// Module mirrors PyModuleObject.
type Module struct {
Header
Dict *Dict
Name *Str
State interface{} // for "C-defined" modules; gopy uses Go struct
}

// Namespace mirrors _PyNamespaceObject.
type Namespace struct {
Header
Dict *Dict
}

// StructSeq is the per-type base. Each named struct-sequence
// (e.g. os.stat_result) is a Type whose instances are *StructSeq.
type StructSeq struct {
VarHeader
items []Object
}

// Capsule mirrors PyCapsule.
type Capsule struct {
Header
Pointer interface{}
Name string
Context interface{}
Destruct func()
}

// SeqIter is the sequence iterator wrapper.
type SeqIter struct {
Header
Index int
Seq Object
}

// CallableIter is the two-arg iter() form.
type CallableIter struct {
Header
Callable Object
Sentinel Object
Done bool
}

// Enumerate mirrors enumobject.c:enumobject.
type Enumerate struct {
Header
Index *Long
Seq Object // an iterator
Result *Tuple // recycled 2-tuple when refcount allows
}

// Reversed mirrors enumobject.c:reversedobject.
type Reversed struct {
Header
Index int
Seq Object // sequence with __len__ and __getitem__
}

File mapping

C sourceGo target
Objects/moduleobject.cobjects/module.go
Objects/namespaceobject.cobjects/namespace.go
Objects/structseq.cobjects/structseq.go
Objects/capsule.cobjects/capsule.go
Objects/iterobject.cobjects/seqiter.go
Objects/enumobject.cobjects/enum.go

Checklist

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

Files

  • objects/module.go: Module struct, getattr through dict with __getattr__ fallback (PEP 562), repr (<module 'name' from 'path'>), __dir__.
  • objects/namespace.go: SimpleNamespace, equality (compares __dict__), repr (sorted fields).
  • objects/structseq.go: StructSeq base type, factory (NewType(name, fields, n_unnamed_fields)), getattr by name, positional access, repr (name(field1=v1, field2=v2)), pickling support.
  • objects/capsule.go: opaque-pointer container; in gopy used only for stdlib bridge.
  • objects/seqiter.go: SeqIter + CallableIter.
  • objects/enum.go: Enumerate (with start arg), Reversed (handles __reversed__ callback if defined).
  • objects/module_test.go, enum_test.go, seqiter_test.go: per-file panels.

Surface guarantees

  • module.__getattr__ (PEP 562) is honoured before raising AttributeError.
  • repr(module) matches CPython for the four cases (filesystem path, builtin, frozen, namespace package).
  • SimpleNamespace(a=1, b=2) == SimpleNamespace(b=2, a=1).
  • structseq n_sequence_fields vs n_fields distinction: named-but-not-sequence fields don't count in tuple length.
  • os.stat_result(...) round-trips through pickle.
  • iter(obj) with only __getitem__ falls through to SeqIter; raises TypeError if neither.
  • iter(callable, sentinel) stops on sentinel equality.
  • enumerate(['a', 'b'], start=10) yields (10, 'a'), (11, 'b').
  • reversed(range(3)) returns a range_iterator (specialised), not a Reversed wrapper.
  • reversed(d) where d is a dict iterates keys in reverse insertion order.

Cross-references

  • Module / __getattr__ (PEP 562): import system (v0.8).
  • Capsule / stdlib bridge: any future stdlib module that needs cross-module C handles.

Out of scope

  • The frozen-module loader. Lands in v0.8 import system.
  • Multi-phase module init (PEP 489). v0.8.