Skip to content

refactor: switch TCbuffer regular families to the generated mixin - #90

Open
estebanzimanyi wants to merge 1 commit into
refactor/oo-codegen-meos-idlfrom
refactor/oo-codegen-tcbuffer-switch
Open

estebanzimanyi wants to merge 1 commit into
refactor/oo-codegen-meos-idlfrom
refactor/oo-codegen-tcbuffer-switch

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

The vertical-slice full working solution for the meos-idl.json-driven
OO codegen: TCbuffer's regular method families are now served by generated
code, wired into the class, with the existing test suite proving behavioural
equivalence.

What changed

  • Generator (tools/oo_codegen/codegen.py): a behaviourally-faithful
    --mixin emitter that reproduces the hand-written isinstance ladder,
    argument transforms (geo_to_gserialized, STBox border flag, distance
    arg), result post-processing (> 0 / == 1 / Temporal._factory /
    shapely / raw) and the super()/raise fallback exactly. Only
    modelled families are wired (one family per PR). The Draft _preview/
    path and the feat: meos-idl.json-driven OO method-family codegen (Draft preview) #89 coverage gate are untouched.
  • pymeos/main/_generated/tcbuffer_methods.py: generated
    TCbufferRegularMixin — 30 regular methods, each dispatching to the
    exact pymeos_cffi backing the hand-written method used.
  • pymeos/main/tcbuffer.py: inherits the mixin; the 30 now-generated
    regular methods are removed. never_* and the irregular hand-written
    core are kept.
  • Provenance: regen-from-meos-api.sh + README — the catalog is
    byte-schema-identical to MEOS-API run.py output and the generator runs
    unchanged on it (proven: a fresh run.py over local headers → 3544 fns →
    --check PASS).

Proof (the convincing artifact)

tests/main/tcbuffer_test.py is byte-identical before and after the
switch
: 26 passed, 1 failed. All 26 temporal TCbuffer* tests pass,
including every regular family the codegen serves (EverAlways, Distance,
SpatialRelationships). The single failure is TestCbuffer::test_from_as_hexwkb
— a pre-existing, unrelated pymeos_cffi cbuffer_as_hexwkb out-parameter
bug in the base Cbuffer class
(not temporal, not the codegen, not the
stubs); identical with or without this PR. Static check: 30/30 generated
methods are backing-and-fallback identical
to the hand-written oracle.

Stack / dependencies

Stacked on #89 (Draft codegen) → #88 (extended types). This relies on
#88 being instantiable: #88 was amended to add documented NotImplementedError
value-accessor stubs for TCbuffer (MEOS exposes no typed tcbuffer_* value
accessor / tcbufferinst_make; MF-JSON tracked upstream by MobilityDB#1051),
which makes the suite collectable. CI note: the bump/meos-1.4 base line does
not trigger test.yml, so these suites were never run in CI before — this PR
establishes the green proof locally.

Follow-up

Fan-out to the other five families (TNpoint also needs its NpointSet
abstract surface; TPose needs 2 ctor stubs) — each its own slice, same
pattern.

estebanzimanyi added a commit that referenced this pull request May 19, 2026
Implements the PyMEOS-side follow-up of RFC #94 §5: a consumer that
emits faithful geo/temporal mixins from the canonical
oo.<family>.<member>.dispatch blocks the parallel MEOS-API session is
adding to meta/meos-meta.json (merged into meos-idl.json).

Additive only -- the 4 shipped families' FAMILY_MODEL path
(emit_faithful_mixin) is untouched; #90/#91/#92/#93 mixins regenerate
byte-identical (regression-guarded) and #89 coverage gate stays green.

Proven correct WITHOUT waiting on the not-yet-published metadata:
_serialize_family_dispatch() expresses each of the 4 A/B-proven families
(cbuffer/pose/npoint/rgeo) in the RFC #94 §3 schema; feeding those back
through emit_from_oo_dispatch() reproduces their committed mixins
BYTE-IDENTICALLY for all 4 (the new --verify-oo-roundtrip gate +
OoDispatchConsumer test, permanently enforced). geo/temporal then plug
into this same proven consumer the instant MEOS-API emits their
oo.dispatch (via --mixin-from-dispatch), closing codegen 6/6 -- no
PyMEOS-local transcription, equivalence by construction at the catalog
level.

This is the non-wasted parallel prep: when the keystone enrichment
lands, PyMEOS converges immediately. Stacked on #94 (the RFC).
estebanzimanyi added a commit that referenced this pull request May 19, 2026
Implements the PyMEOS-side follow-up of RFC #94 §5: a consumer that
emits faithful geo/temporal mixins from the canonical
oo.<family>.<member>.dispatch blocks the parallel MEOS-API session is
adding to meta/meos-meta.json (merged into meos-idl.json).

Additive only -- the 4 shipped families' FAMILY_MODEL path
(emit_faithful_mixin) is untouched; #90/#91/#92/#93 mixins regenerate
byte-identical (regression-guarded) and #89 coverage gate stays green.

Proven correct WITHOUT waiting on the not-yet-published metadata:
_serialize_family_dispatch() expresses each of the 4 A/B-proven families
(cbuffer/pose/npoint/rgeo) in the RFC #94 §3 schema; feeding those back
through emit_from_oo_dispatch() reproduces their committed mixins
BYTE-IDENTICALLY for all 4 (the new --verify-oo-roundtrip gate +
OoDispatchConsumer test, permanently enforced). geo/temporal then plug
into this same proven consumer the instant MEOS-API emits their
oo.dispatch (via --mixin-from-dispatch), closing codegen 6/6 -- no
PyMEOS-local transcription, equivalence by construction at the catalog
level.

This is the non-wasted parallel prep: when the keystone enrichment
lands, PyMEOS converges immediately. Stacked on #94 (the RFC).
estebanzimanyi added a commit that referenced this pull request May 19, 2026
Implements the PyMEOS side of RFC #94 §5/§7: a consumer that emits
faithful geo/temporal mixins from the canonical objectModel.dispatch
metadata (MEOS-API #10 feat/object-model, merged into meos-idl.json),
closing the OO codegen to all 6 temporal type families with
equivalence by construction at the catalog level.

Additive only — the 4 derivable families' FAMILY_MODEL path
(emit_faithful_mixin) is untouched; #90/#91/#92/#93 mixins regenerate
byte-identical (--verify-oo-roundtrip + OoDispatchConsumer
.test_roundtrip_byte_identical, permanently enforced) and the #89
coverage gate stays green.

geo + the 4 temporal concretes (TFloat/TInt/TBool/TText) are not
derivable from the signature catalog (RFC #94 §1), so they are driven
by the verbatim objectModel.dispatch metadata and proven equivalent to
the hand-written oracle by dispatch-skeleton equality:

  * tools/oo_codegen/_d1-dispatch-extended-fixture.json — the verbatim
    §7 dispatch metadata (== MEOS-API #10 objectModel.dispatch).
  * tools/oo_codegen/_oracle_extended_methods.py — the byte-for-byte
    hand-written editorial methods (AST-extracted) the proof checks
    against; never executed, never imported.
  * --verify-oo-dispatch-extended + OoDispatchConsumer
    .test_extended_dispatch_matches_oracle: each of the 32 editorial
    methods (geo at/minus/distance/nearest_approach_distance + each
    concrete's always/ever/temporal eq·ne, at, minus) reduces to an
    identical ordered dispatch skeleton — isinstance type-set, backing
    symbol, arg transform, super-coerce, fallback, result wrap. 0
    divergence: same native calls, same transforms, never reimplemented.

The closed argTransform vocabulary maps to PyMEOS idioms
(scalarValue, scalarCast-per-base, geoToGserialized with
geodeticFromSelf, stboxToGeo, innerPtr, textsetMake, list[str],
coerce + via:super).

Stacked on #94 (the RFC, including the verbatim §7 SoT).
estebanzimanyi added a commit that referenced this pull request May 19, 2026
Implements the PyMEOS side of RFC #94 §5/§7: a consumer that emits
faithful geo/temporal mixins from the canonical objectModel.dispatch
metadata (MEOS-API #10 feat/object-model, merged into meos-idl.json),
closing the OO codegen to all 6 temporal type families with
equivalence by construction at the catalog level.

Additive only — the 4 derivable families' FAMILY_MODEL path
(emit_faithful_mixin) is untouched; #90/#91/#92/#93 mixins regenerate
byte-identical (--verify-oo-roundtrip + OoDispatchConsumer
.test_roundtrip_byte_identical, permanently enforced) and the #89
coverage gate stays green.

geo + the 4 temporal concretes (TFloat/TInt/TBool/TText) are not
derivable from the signature catalog (RFC #94 §1), so they are driven
by the verbatim objectModel.dispatch metadata and proven equivalent to
the hand-written oracle by dispatch-skeleton equality:

  * tools/oo_codegen/_d1-dispatch-extended-fixture.json — the verbatim
    §7 dispatch metadata (== MEOS-API #10 objectModel.dispatch).
  * tools/oo_codegen/_oracle_extended_methods.py — the byte-for-byte
    hand-written editorial methods (AST-extracted) the proof checks
    against; never executed, never imported.
  * --verify-oo-dispatch-extended + OoDispatchConsumer
    .test_extended_dispatch_matches_oracle: each of the 32 editorial
    methods (geo at/minus/distance/nearest_approach_distance + each
    concrete's always/ever/temporal eq·ne, at, minus) reduces to an
    identical ordered dispatch skeleton — isinstance type-set, backing
    symbol, arg transform, super-coerce, fallback, result wrap. 0
    divergence: same native calls, same transforms, never reimplemented.

The closed argTransform vocabulary maps to PyMEOS idioms
(scalarValue, scalarCast-per-base, geoToGserialized with
geodeticFromSelf, stboxToGeo, innerPtr, textsetMake, list[str],
coerce + via:super).

Stacked on #94 (the RFC, including the verbatim §7 SoT).
Promotes the meos-idl.json-driven OO codegen from Draft preview to a
wired-in solution for the TCbuffer vertical slice.

- Generator (tools/oo_codegen/codegen.py): adds a behaviourally-faithful
  emitter (--mixin) that reproduces the hand-written isinstance ladder,
  argument transforms, result post-processing and super()/raise fallback
  exactly; only modelled families are wired (one family per PR). The
  Draft _preview/ path and the #89 coverage gate are unchanged.
- pymeos/main/_generated/tcbuffer_methods.py: generated TCbufferRegularMixin
  (30 regular methods: comparison, spatial relationship, distance,
  restriction), each dispatching to the exact pymeos_cffi backing the
  hand-written method used.
- pymeos/main/tcbuffer.py: inherits TCbufferRegularMixin; the 30
  now-generated regular methods are removed (never_* and the irregular
  hand-written core are kept).
- Provenance: regen-from-meos-api.sh + README document that the catalog
  is byte-schema-identical to MEOS-API run.py output and the generator
  runs unchanged on it.

Behavioural equivalence is proven by the existing suite: the full
tests/main/tcbuffer_test.py is byte-identical before and after the
switch -- 26 passed, 1 failed, where the single failure is a pre-existing
unrelated pymeos_cffi cbuffer_as_hexwkb out-parameter bug in the base
Cbuffer class (not temporal, not codegen). Static check: 30/30 generated
methods are backing-and-fallback identical to the hand-written oracle.

Stacked on #89; relies on #88's TCbuffer being instantiable.
@estebanzimanyi
estebanzimanyi force-pushed the refactor/oo-codegen-meos-idl branch from 85deb9b to 6deeb71 Compare October 22, 2026 12:00
@estebanzimanyi
estebanzimanyi force-pushed the refactor/oo-codegen-tcbuffer-switch branch from 27e5965 to 43bd61e Compare October 22, 2026 12:00
estebanzimanyi added a commit that referenced this pull request Oct 22, 2026
Fans the meos-idl.json faithful codegen out to TPose (second family
after TCbuffer #90).

- codegen.py: add the `pose` FAMILY_MODEL entry (+ the `point` arg
  token — tpose distance spells its geometry overload
  `tdistance_tpose_point`). The Draft _preview path and #89 coverage
  gate are unchanged.
- pymeos/main/_generated/tpose_methods.py: generated TPoseRegularMixin
  (12 regular methods — comparison, temporal comparison, restriction,
  distance; pose has no spatial-relationship API). Each dispatches to the
  exact pymeos_cffi backing the hand-written method used.
- pymeos/main/tpose.py: inherits TPoseRegularMixin; the 12 now-generated
  regular methods removed. never_*/the irregular core and the
  already-real MEOS-backed value accessors (start_value/end_value/
  value_set/value_at_timestamp/value_n) are kept. Adds documented
  NotImplementedError stubs for from_base_time (MobilityDB#1084) and
  from_mfjson (MobilityDB#1085) so TPose/Inst/Seq/SeqSet are concrete.

Proof: tests/main/tpose_test.py is byte-identical hand-written vs wired
(A/B with the 2 stubs held constant) — 31 passed, 4 failed in BOTH; the
4 failures are pre-existing #88 defects OUTSIDE the codegen-switch domain
(TestTPoseOutputs/Pose test_str, TestTPoseAccessors test_value_at_timestamp,
TestPose test_from_as_hexwkb — hand-written accessors / base Pose, not
the regular families). Static check: 12/12 generated methods are
backing-and-fallback identical to the hand-written oracle. All
switch-domain tests (comparison/distance/restriction) pass. Stacked on
estebanzimanyi added a commit that referenced this pull request Oct 22, 2026
Third family in the codegen-switch fan-out (after TCbuffer #90, TPose

- codegen.py: add the `npoint` FAMILY_MODEL (+ `npointset` and `point`
  arg tokens; tnpoint distance spells `tdistance_tnpoint_point`). Make
  shortest_line's precision per-family (npoint: `precision: int = 15`;
  tcbuffer/tpose hardcode 10 with no param and omit the key, so #90/#91
  regenerate byte-identical -- verified). Draft _preview path and #89
  gate untouched.
- pymeos/main/_generated/tnpoint_methods.py: generated TNpointRegularMixin
  (12 regular methods -- comparison, temporal comparison, restriction,
  distance; npoint has no spatial-relationship API). Static check: 12/12
  backing-and-fallback identical to the hand-written oracle.
- pymeos/main/tnpoint.py: inherits the mixin; 12 now-generated regular
  methods removed; never_*/irregular core kept. Adds documented
  NotImplementedError stubs (value accessors -> MobilityDB#1082,
  from_base_time -> #1084, from_mfjson -> #1086) so TNpoint*/Inst/Seq/
  SeqSet are concrete.
- pymeos/collections/npoint/npointset.py: NpointSet shipped abstract in
  #88 (pre-existing base-collection defect, unrelated to the switch);
  add the 5 missing Set ops as thin super() delegations to the generic
  base Set (the established GeoSet.contains pattern), making NpointSet
  concrete.

Proof: tests/main/tnpoint_test.py is byte-identical hand-written vs
wired (A/B, stubs+NpointSet-fix held constant) -- both error IDENTICALLY
at the same pre-existing point (`tnpoint_test.py:211` TestNpointSet,
MeosTextInputError 'Missing delimiter'), so the switch delta is provably
zero. That collection error is a pre-existing #88/MEOS npointset
test-fixture/parser issue OUTSIDE the codegen-switch domain (base
NpointSet, not the temporal regular families), unrelated to and
unaffected by this change -- a separate follow-up. Static 12/12
identical is the positive proof. Stacked on #91.
estebanzimanyi added a commit that referenced this pull request Oct 22, 2026
Fourth family in the codegen-switch fan-out (after TCbuffer #90, TPose

- codegen.py: add the `rgeo` FAMILY_MODEL (temporal_token `trgeo`; geo
  token uses `geometry_to_gserialized($o)` -- single-arg, unlike the
  geo_to_gserialized(g, False) of the other spatial families; tokens
  geo/trgeo/tpoint/stbox) + `tpoint`/`trgeo` to _ORDER. Additive:
  #90/#91/#92 mixins regenerate byte-identical (regression-guarded).
- pymeos/main/_generated/trgeometry_methods.py: generated
  TRgeometryRegularMixin -- 10 methods (comparison, temporal comparison,
  distance/nad/nai/shortest_line). Static: 10/10 backing-and-fallback
  identical to the hand-written oracle.
- pymeos/main/trgeometry.py: inherits the mixin; the 10 now-generated
  regular methods removed. at/minus stay hand-written (rgeo restriction
  is the irregular `trgeo_restrict_<timetype>`+direction-bool pattern,
  not `trgeometry_at_*`, so the generator never collects them);
  never_*/irregular core kept. Adds documented NotImplementedError stubs
  for from_base_time and from_mfjson (pending upstream MEOS) so
  TRgeometry/Inst/Seq/SeqSet are concrete.

Proof: tests/main/trgeometry_test.py is byte-identical hand-written vs
wired (A/B, 2 stubs constant) -- both 6 failed / 23 passed, the SAME 6
pre-existing #88 hand-written-core defects OUTSIDE the switch domain
(TestTRgeometryConstructors/Accessors/GapMethods -- constructors,
accessors, known-gap methods; not comparison/distance), unrelated to and
unaffected by this change. Every switch-domain test passes. Static 10/10
identical is the positive proof. Stacked on #92.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant