Skip to content

Bump PyMEOS to MEOS 1.4 - #81

Merged
estebanzimanyi merged 9 commits into
masterfrom
bump/meos-1.4
Oct 31, 2026
Merged

estebanzimanyi merged 9 commits into
masterfrom
bump/meos-1.4

Conversation

@estebanzimanyi

@estebanzimanyi estebanzimanyi commented May 14, 2026 •

Copy link
Copy Markdown
Member

Bind PyMEOS to the MEOS master surface

PyMEOS 1.4.0a1 requires pymeos-cffi 1.4.0a1 or later and calls MEOS master's
names and signatures. Text, timestamp, date and interval input and output go
through cstring_to_text, text_to_cstring, timestamptz_in, date_in and
interval_in; multiplication through the mul_* family; the conversions to an
instant, sequence or sequence set through temporal_as_; the temporal
distance of numbers through the tdistance_
family, which takes an int for a
TInt and a float for a TFloat; and the box nearest approach distance of a
temporal point through nad_tgeo_stbox.

The spatial relationships drop their restr and atvalue arguments, and the
distance, length, speed and nearest approach functions take spheroid=True,
the MobilityDB default. The tiling and split functions pass
border_inc=True, the MobilityDB default, so a value on the upper border
lands in the tile that starts there and time_split_n answers an (n+1)th
tile holding the end value when the end is inclusive. Set and span set
accessors read the array from the (array, count) pair the functions return,
and the time distances convert the returned interval to a timedelta.

Build the all-families MEOS and its catalog in the test workflow

The PyMEOS-CFFI cdef covers every optional MEOS family and is projected from
the MEOS-API catalog, so the test workflow derives the catalog once with the
shared provision-meos action, from the MobilityDB branch the package version
maps to, and each test job builds libmeos with every family: through
provision-meos on Linux and with -DALL=ON on macOS. PyMEOS-CFFI's header is
projected from that catalog and the installed library before it is built.

Align the test expectations with MEOS master

MF-JSON writes the full ISO 8601 offset (+00:00) and states the CRS of a
geography; the temporal hash values are those temporal_hash answers; the
split tests expect the tile that holds a value on the upper border; and the
min and max restrictions, which MobilityDB defines for tint, tbigint, tfloat
and ttext, raise for tbool and the temporal points.

The adjacent instant of the tint topological test takes the value 2 at the
same timestamp: two instants at different timestamps are apart in time, so
their boxes are not adjacent.

Test the space tiles and the value-time tiles

STBox.tile of a trip's box answers the 5 km space tiles of the trip, with
their space dimension, and TGeomPoint.tile answers the trip's pieces in them.
TBox.tile answers the value-time tiles in value order within each day,
covering the box's last day and no value band beyond its upper value.

Test every aggregator on two overlapping inputs

tests/aggregators runs each aggregator of pymeos.aggregators on two inputs that
overlap in time, so every result holds a stretch where both contribute and a
stretch where one does: the boolean, number and text temporal aggregates, the
three extents, the instant and period counts, the instantaneous time union, and
an incremental aggregation against the one-call form.

Witness: on PyMEOS-CFFI regenerated from MobilityDB master 1eca005aeb the 18
cases pass, and 16 of them fail on the surface of master adbb2ebad1, where each
aggregation starts from a None state the transition wrapper casts unguarded.
Measured: each expected value checks by its definition on the two inputs, the
integer sum being 1, then 1 + 2 = 3 from 2000-01-02, then 3 + 2 = 5 at
2000-01-03, then 2 to 2000-01-04. The suite passes 4471 of 4471.

Aggregate continuous time through the span union transition functions

TimeContinuousUnionAggregator aggregates as TimeInstantaneousUnionAggregator
does: span_union_transfn and spanset_union_transfn add each span or span set to
the state, which starts as None, and spanset_union_finalfn finishes it.
union_spanset_span and union_spanset_spanset are the binary unions of two
values, and MEOS refuses a NULL span set there, so they cannot start an
aggregation.

Witness: the union of [2000-01-01, 2000-01-03] and [2000-01-02, 2000-01-04]
aggregates to {[2000-01-01, 2000-01-04]}, a case added to tests/aggregators;
through union_spanset_span the first add raises TypeError: an integer is
required, from casting the None state the wrapper does not guard. The suite
passes 4472 of 4472.

Build GDAL without GEOS and install neither GEOS nor GSL on macOS

MEOS 1.4 calls neither GEOS nor GSL, so the macOS jobs install neither
from Homebrew, and they build GDAL 3.12.0, the version MEOS-API's
provision-meos builds for the Linux jobs, with -DGDAL_USE_GEOS=OFF beside
the Arrow and Parquet switches. The GDAL cache key carries the version,
so the first run builds the new GDAL. Its source and build directories
lie in the runner's temporary directory, outside the checkout, so pytest
collects neither GDAL's Python bindings nor its tests.

State the geodetic crossing MEOS misses on arm64 as an expected failure

The temporal equality of a geodetic sequence and of a geodetic sequence
set against a sequence they meet at 12:00 is a strict expected failure
on arm64 and an ordinary test elsewhere. MEOS dates the meeting with the
Cartesian fraction of tgeogpointsegm_distance_turnpt and compares the
two great-circle points it interpolates there with exact equality, so it
finds the meeting where the two roundings agree, on x86, and misses it
where they do not, on arm64. The mark is strict, so the run fails once
MEOS dates the meeting exactly on every platform and the mark is due to
leave.

Shift or scale a time value or a box through its own MEOS function

MEOS states the time shift and the time scale of a timestamptz set, span
and span set and of a temporal box and a spatiotemporal box as their own
functions, tstzset_shift and tstzset_scale, tstzspan_shift and
tstzspan_scale, tstzspanset_shift and tstzspanset_scale, tbox_shift_time
and tbox_scale_time, and stbox_shift_time and stbox_scale_time, and the
shift and scale function of each takes both intervals. TsTzSet,
TsTzSpan, TsTzSpanSet, TBox and STBox answer shift and scale through
them, as Temporal answers shift_time and scale_time, and shift_scale,
whose two arguments stay optional, calls the shift alone, the scale
alone or both by the intervals it is given.

estebanzimanyi added a commit that referenced this pull request May 14, 2026
The 1.4 surface (PR #81) cdef's meos_cbuffer.h / meos_pose.h /
meos_rgeo.h, which only land in /usr/local/include when the build
enables those features. Without them the cffi step bails on
FileNotFoundError. Mirrors the PyMEOS-CFFI pr_build.yml flags.
@estebanzimanyi
estebanzimanyi force-pushed the bump/meos-1.4 branch 3 times, most recently from 6c7b804 to ecca684 Compare May 23, 2026 07:17
@estebanzimanyi
estebanzimanyi force-pushed the bump/meos-1.4 branch 7 times, most recently from 3429b49 to d600b5c Compare October 22, 2026 21:35
PyMEOS 1.4.0a1 requires pymeos-cffi 1.4.0a1 or later and calls MEOS master's
names and signatures. Text, timestamp, date and interval input and output go
through cstring_to_text, text_to_cstring, timestamptz_in, date_in and
interval_in; multiplication through the mul_* family; the conversions to an
instant, sequence or sequence set through temporal_as_*; the temporal
distance of numbers through the tdistance_* family, which takes an int for a
TInt and a float for a TFloat; and the box nearest approach distance of a
temporal point through nad_tgeo_stbox.

The spatial relationships drop their restr and atvalue arguments, and the
distance, length, speed and nearest approach functions take spheroid=True,
the MobilityDB default. The tiling and split functions pass
border_inc=True, the MobilityDB default, so a value on the upper border
lands in the tile that starts there and time_split_n answers an (n+1)th
tile holding the end value when the end is inclusive. Set and span set
accessors read the array from the (array, count) pair the functions return,
and the time distances convert the returned interval to a timedelta.
The PyMEOS-CFFI cdef covers every optional MEOS family and is projected from
the MEOS-API catalog, so the test workflow derives the catalog once with the
shared provision-meos action, from the MobilityDB branch the package version
maps to, and each test job builds libmeos with every family: through
provision-meos on Linux and with -DALL=ON on macOS. PyMEOS-CFFI's header is
projected from that catalog and the installed library before it is built.
MF-JSON writes the full ISO 8601 offset (+00:00) and states the CRS of a
geography; the temporal hash values are those temporal_hash answers; the
split tests expect the tile that holds a value on the upper border; and the
min and max restrictions, which MobilityDB defines for tint, tbigint, tfloat
and ttext, raise for tbool and the temporal points.

The adjacent instant of the tint topological test takes the value 2 at the
same timestamp: two instants at different timestamps are apart in time, so
their boxes are not adjacent.
STBox.tile of a trip's box answers the 5 km space tiles of the trip, with
their space dimension, and TGeomPoint.tile answers the trip's pieces in them.
TBox.tile answers the value-time tiles in value order within each day,
covering the box's last day and no value band beyond its upper value.
tests/aggregators runs each aggregator of pymeos.aggregators on two inputs that
overlap in time, so every result holds a stretch where both contribute and a
stretch where one does: the boolean, number and text temporal aggregates, the
three extents, the instant and period counts, the instantaneous time union, and
an incremental aggregation against the one-call form.

Witness: on PyMEOS-CFFI regenerated from MobilityDB master 1eca005aeb the 18
cases pass, and 16 of them fail on the surface of master adbb2ebad1, where each
aggregation starts from a None state the transition wrapper casts unguarded.
Measured: each expected value checks by its definition on the two inputs, the
integer sum being 1, then 1 + 2 = 3 from 2000-01-02, then 3 + 2 = 5 at
2000-01-03, then 2 to 2000-01-04. The suite passes 4471 of 4471.
TimeContinuousUnionAggregator aggregates as TimeInstantaneousUnionAggregator
does: span_union_transfn and spanset_union_transfn add each span or span set to
the state, which starts as None, and spanset_union_finalfn finishes it.
union_spanset_span and union_spanset_spanset are the binary unions of two
values, and MEOS refuses a NULL span set there, so they cannot start an
aggregation.

Witness: the union of [2000-01-01, 2000-01-03] and [2000-01-02, 2000-01-04]
aggregates to {[2000-01-01, 2000-01-04]}, a case added to tests/aggregators;
through union_spanset_span the first add raises TypeError: an integer is
required, from casting the None state the wrapper does not guard. The suite
passes 4472 of 4472.
MEOS 1.4 calls neither GEOS nor GSL, so the macOS jobs install neither
from Homebrew, and they build GDAL 3.12.0, the version MEOS-API's
provision-meos builds for the Linux jobs, with -DGDAL_USE_GEOS=OFF beside
the Arrow and Parquet switches. The GDAL cache key carries the version,
so the first run builds the new GDAL. Its source and build directories
lie in the runner's temporary directory, outside the checkout, so pytest
collects neither GDAL's Python bindings nor its tests.
The temporal equality of a geodetic sequence and of a geodetic sequence
set against a sequence they meet at 12:00 is a strict expected failure
on arm64 and an ordinary test elsewhere. MEOS dates the meeting with the
Cartesian fraction of tgeogpointsegm_distance_turnpt and compares the
two great-circle points it interpolates there with exact equality, so it
finds the meeting where the two roundings agree, on x86, and misses it
where they do not, on arm64. The mark is strict, so the run fails once
MEOS dates the meeting exactly on every platform and the mark is due to
leave.
MEOS states the time shift and the time scale of a timestamptz set, span
and span set and of a temporal box and a spatiotemporal box as their own
functions, tstzset_shift and tstzset_scale, tstzspan_shift and
tstzspan_scale, tstzspanset_shift and tstzspanset_scale, tbox_shift_time
and tbox_scale_time, and stbox_shift_time and stbox_scale_time, and the
shift and scale function of each takes both intervals. TsTzSet,
TsTzSpan, TsTzSpanSet, TBox and STBox answer shift and scale through
them, as Temporal answers shift_time and scale_time, and shift_scale,
whose two arguments stay optional, calls the shift alone, the scale
alone or both by the intervals it is given.
@estebanzimanyi estebanzimanyi changed the title Bump PyMEOS to MEOS 1.4 (work in progress) Bump PyMEOS to MEOS 1.4 Oct 31, 2026
@estebanzimanyi
estebanzimanyi marked this pull request as ready for review October 31, 2026 12:14
@estebanzimanyi
estebanzimanyi merged commit 9aaf928 into master Oct 31, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant