From ccb9deb8bedf0c14b74ca086f750bd8f3913305c Mon Sep 17 00:00:00 2001 From: Seth Fitzsimmons Date: Mon, 20 Jul 2026 10:17:48 -0700 Subject: [PATCH] refactor(schema): split system.primitive into numeric and geometric modules overture.schema.system.primitive mixed two unrelated concerns: portable numeric NewTypes (int8, uint32, float64, etc.) and geometric types (BBox, Geometry, GeometryType, GeometryTypeConstraint). The generated reference page this produced was titled "Primitive Types" at system/primitive/primitives even though it only covered numeric types. Numeric types move to a new numeric.py module; BBox and Geometry move to a new geometric package. The primitive package is removed and every import across the workspace (themes, common, codegen, and their tests, including several doctest examples) is updated to the correct module. Remaining "primitive" wording in system-package docstrings, the package READMEs, and the Pydantic guide is retired with it. The aggregate docs pages move with their source: system/numeric.md (title "Numeric Types") and system/geometry.md, both flat under system/ like the existing scalar type pages rather than nested under primitive/. Closes #464. Signed-off-by: Seth Fitzsimmons --- PYDANTIC_GUIDE.md | 26 +++---- README.pydantic.md | 6 +- .../src/overture/schema/addresses/address.py | 4 +- .../src/overture/schema/base/_common.py | 2 +- .../src/overture/schema/base/bathymetry.py | 2 +- .../overture/schema/base/infrastructure.py | 2 +- .../src/overture/schema/base/land.py | 2 +- .../src/overture/schema/base/land_cover.py | 2 +- .../src/overture/schema/base/land_use.py | 2 +- .../src/overture/schema/base/water.py | 2 +- .../src/overture/schema/buildings/_common.py | 2 +- .../src/overture/schema/buildings/building.py | 2 +- .../schema/buildings/building_part.py | 2 +- packages/overture-schema-codegen/README.md | 2 +- .../overture-schema-codegen/docs/design.md | 2 +- .../docs/walkthrough.md | 28 ++++---- .../codegen/extraction/field_constraints.py | 2 +- .../codegen/markdown/path_assignment.py | 12 ++-- .../schema/codegen/markdown/pipeline.py | 41 ++++++----- .../schema/codegen/markdown/renderer.py | 14 ++-- ...geometry.md.jinja2 => geometric.md.jinja2} | 0 ...primitives.md.jinja2 => numeric.md.jinja2} | 2 +- .../codegen/pyspark/constraint_dispatch.py | 2 +- .../schema/codegen/pyspark/pipeline.py | 2 +- .../schema/codegen/pyspark/renderer.py | 2 +- .../pyspark/templates/model_module.py.jinja2 | 2 +- .../codegen/pyspark/test_data/base_row.py | 10 +-- .../pyspark/test_data/invalid_value.py | 2 +- .../tests/codegen_test_support.py | 13 ++-- .../overture-schema-codegen/tests/conftest.py | 19 ++--- .../tests/test_constraint_description.py | 2 +- .../tests/test_example_loader.py | 2 +- .../tests/test_markdown_renderer.py | 72 +++++++++---------- .../tests/test_markdown_type_format.py | 40 ++++------- .../tests/test_model_extractor.py | 10 +-- .../tests/test_numeric_extraction.py | 23 ++++-- .../tests/test_pyspark_check_builder.py | 2 +- .../tests/test_pyspark_constraint_dispatch.py | 2 +- .../tests/test_pyspark_invalid_value.py | 2 +- .../tests/test_pyspark_pipeline.py | 2 +- .../tests/test_pyspark_renderer.py | 16 ++--- .../tests/test_pyspark_test_renderer.py | 2 +- .../tests/test_specs.py | 2 +- .../tests/test_type_analyzer.py | 2 +- .../tests/test_type_collection.py | 2 +- .../tests/test_type_placement.py | 25 +++---- packages/overture-schema-common/README.md | 4 +- .../src/overture/schema/common/cartography.py | 2 +- .../src/overture/schema/common/models.py | 4 +- .../src/overture/schema/common/names.py | 2 +- .../schema/common/scoping/__init__.py | 20 +++--- .../src/overture/schema/common/scoping/lr.py | 2 +- .../overture/schema/common/scoping/vehicle.py | 2 +- .../src/overture/schema/common/types.py | 2 +- .../tests/test_models.py | 4 +- ...imitive_types.py => test_numeric_types.py} | 16 ++--- .../src/overture/schema/divisions/_common.py | 2 +- .../src/overture/schema/divisions/division.py | 12 ++-- .../schema/divisions/division_area.py | 10 +-- .../schema/divisions/division_boundary.py | 10 +-- .../src/overture/schema/places/place.py | 4 +- .../src/overture/schema/pyspark/check.py | 2 +- .../src/overture/schema/pyspark/cli.py | 2 +- .../expressions/constraint_expressions.py | 2 +- .../test_constraint_expressions.py | 2 +- packages/overture-schema-system/README.md | 23 ++++-- .../src/overture/schema/system/__init__.py | 22 +++--- .../src/overture/schema/system/feature.py | 9 +-- .../schema/system/geometric/__init__.py | 25 +++++++ .../system/{primitive => geometric}/bbox.py | 10 +-- .../system/{primitive => geometric}/geom.py | 14 ++-- .../{primitive/__init__.py => numeric.py} | 38 ++++------ .../src/overture/schema/system/string.py | 6 +- .../{primitive => geometric}/test_bbox.py | 2 +- .../{primitive => geometric}/test_geom.py | 2 +- .../tests/test_feature.py | 12 ++-- .../schema/transportation/connector/models.py | 2 +- .../overture/schema/transportation/models.py | 2 +- .../schema/transportation/segment/models.py | 2 +- 79 files changed, 362 insertions(+), 328 deletions(-) rename packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/{geometry.md.jinja2 => geometric.md.jinja2} (100%) rename packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/{primitives.md.jinja2 => numeric.md.jinja2} (97%) rename packages/overture-schema-common/tests/{test_primitive_types.py => test_numeric_types.py} (94%) create mode 100644 packages/overture-schema-system/src/overture/schema/system/geometric/__init__.py rename packages/overture-schema-system/src/overture/schema/system/{primitive => geometric}/bbox.py (96%) rename packages/overture-schema-system/src/overture/schema/system/{primitive => geometric}/geom.py (97%) rename packages/overture-schema-system/src/overture/schema/system/{primitive/__init__.py => numeric.py} (77%) rename packages/overture-schema-system/tests/{primitive => geometric}/test_bbox.py (99%) rename packages/overture-schema-system/tests/{primitive => geometric}/test_geom.py (99%) diff --git a/PYDANTIC_GUIDE.md b/PYDANTIC_GUIDE.md index 98dbf5005..e7b4e8dbc 100644 --- a/PYDANTIC_GUIDE.md +++ b/PYDANTIC_GUIDE.md @@ -42,7 +42,7 @@ from pydantic import BaseModel, Field # Overture common models from overture.schema.common import OvertureFeature -from overture.schema.system.primitive import Geometry, GeometryType, GeometryTypeConstraint +from overture.schema.system.geometric import Geometry, GeometryType, GeometryTypeConstraint # Validation system from overture.schema.system.field_constraint import UniqueItemsConstraint @@ -57,8 +57,8 @@ from overture.schema.system.string import ( from overture.schema.common.types import ConfidenceScore from overture.schema.system.string import LanguageTag -# Numeric primitives (use these instead of int/float) -from overture.schema.system.primitive import ( +# Numeric types (use these instead of int/float) +from overture.schema.system.numeric import ( int8, int32, int64, uint8, uint16, uint32, float32, float64 @@ -71,7 +71,7 @@ from overture.schema.system.primitive import ( from typing import Annotated from pydantic import BaseModel, Field from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import int8, float64 +from overture.schema.system.numeric import int8, float64 @no_extra_fields class MyCustomType(BaseModel): @@ -101,7 +101,7 @@ class MyCustomType(BaseModel): from typing import Annotated, Literal from pydantic import Field from overture.schema.common import OvertureFeature -from overture.schema.system.primitive import Geometry, GeometryType, GeometryTypeConstraint +from overture.schema.system.geometric import Geometry, GeometryType, GeometryTypeConstraint class MyFeature(OvertureFeature[Literal["my_theme"], Literal["my_type"]]): """Description of what this feature represents.""" @@ -152,7 +152,7 @@ class Address(BaseModel): ```python from typing import Literal from overture.schema.common import OvertureFeature -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 class Building(OvertureFeature[Literal["buildings"], Literal["building"]]): """A building feature with strongly-typed theme and type.""" @@ -180,7 +180,7 @@ from typing import Literal from overture.schema.common import OvertureFeature from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 class Building(OvertureFeature[Literal["buildings"], Literal["building"]], Named, Stacked): # Gets fields from Feature: id, theme, type, geometry, etc. @@ -259,13 +259,13 @@ class Building(OvertureFeature): Keep the schema separate from business logic. The schema describes the shape of data, not the business rules about what missing values mean. -#### Numeric Primitives +#### Numeric Types **Always use specific numeric types instead of Python's generic `int`/`float`:** ```python from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import ( +from overture.schema.system.numeric import ( int8, int32, int64, # Signed integers uint8, uint16, uint32, # Unsigned integers float32, float64 # Floating point @@ -1174,7 +1174,7 @@ JSON Schema containers become **mixin classes** in Pydantic that you inherit fro from typing import Annotated from pydantic import BaseModel, Field from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import int8, float64 +from overture.schema.system.numeric import int8, float64 @no_extra_fields class MyCustomType(BaseModel): @@ -1204,7 +1204,7 @@ class MyCustomType(BaseModel): from typing import Annotated, Literal from pydantic import Field from overture.schema.common import OvertureFeature -from overture.schema.system.primitive import Geometry, GeometryType, GeometryTypeConstraint +from overture.schema.system.geometric import Geometry, GeometryType, GeometryTypeConstraint class MyFeature(OvertureFeature[Literal["my_theme"], Literal["my_type"]]): """Description of what this feature represents.""" @@ -1263,7 +1263,7 @@ class Contact(BaseModel): from typing import Annotated, Literal from pydantic import Field from overture.schema.common import OvertureFeature -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 from overture.schema.system.ref import Id, Reference, Relationship class MyAssociation(OvertureFeature[Literal["associations"], Literal["my_association"]]): @@ -1349,7 +1349,7 @@ from pydantic import Field from overture.schema.common import OvertureFeature from overture.schema.system.field_constraint import UniqueItemsConstraint from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import int32, float64 +from overture.schema.system.numeric import int32, float64 # For associations and references from overture.schema.system.ref import Id, Reference, Relationship diff --git a/README.pydantic.md b/README.pydantic.md index 76bd78e1f..e03afba56 100644 --- a/README.pydantic.md +++ b/README.pydantic.md @@ -90,9 +90,9 @@ This workspace contains the following packages: convenient usage - **`overture-schema-common`** - Overture-specific models shared across themes: base feature class, scoping framework, names, sources, and cartographic hints -- **`overture-schema-system`** - Portable primitive types, constraints, and a - GeoJSON-aware base model for building Pydantic schemas that serialize to - JSON, Parquet, and Spark +- **`overture-schema-system`** - Portable numeric, geometric, and string types, + constraints, and a GeoJSON-aware base model for building Pydantic schemas that + serialize to JSON, Parquet, and Spark ### Theme Packages diff --git a/packages/overture-schema-addresses-theme/src/overture/schema/addresses/address.py b/packages/overture-schema-addresses-theme/src/overture/schema/addresses/address.py index baf93f839..a6565dad5 100644 --- a/packages/overture-schema-addresses-theme/src/overture/schema/addresses/address.py +++ b/packages/overture-schema-addresses-theme/src/overture/schema/addresses/address.py @@ -10,12 +10,12 @@ from overture.schema.common import ( OvertureFeature, ) -from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, ) +from overture.schema.system.model_constraint import no_extra_fields from overture.schema.system.string import CountryCodeAlpha2, StrippedString diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/_common.py b/packages/overture-schema-base-theme/src/overture/schema/base/_common.py index e0b777947..2d0523a1d 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/_common.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/_common.py @@ -4,7 +4,7 @@ from pydantic import BaseModel, Field -from overture.schema.system.primitive import float64, int32 +from overture.schema.system.numeric import float64, int32 from overture.schema.system.string import WikidataId Depth = NewType( diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/bathymetry.py b/packages/overture-schema-base-theme/src/overture/schema/base/bathymetry.py index 9f525728a..d8f3ec8f7 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/bathymetry.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/bathymetry.py @@ -10,7 +10,7 @@ OvertureFeature, ) from overture.schema.common.cartography import CartographicallyHinted -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/infrastructure.py b/packages/overture-schema-base-theme/src/overture/schema/base/infrastructure.py index fee9d67c4..f9639657d 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/infrastructure.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/infrastructure.py @@ -14,7 +14,7 @@ ) from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/land.py b/packages/overture-schema-base-theme/src/overture/schema/base/land.py index 6775842b7..6bc908ef2 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/land.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/land.py @@ -14,7 +14,7 @@ ) from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/land_cover.py b/packages/overture-schema-base-theme/src/overture/schema/base/land_cover.py index 29eeb5e19..4ea176e14 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/land_cover.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/land_cover.py @@ -11,7 +11,7 @@ OvertureFeature, ) from overture.schema.common.cartography import CartographicallyHinted -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/land_use.py b/packages/overture-schema-base-theme/src/overture/schema/base/land_use.py index 20a99c06a..0bbf55617 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/land_use.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/land_use.py @@ -14,7 +14,7 @@ ) from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-base-theme/src/overture/schema/base/water.py b/packages/overture-schema-base-theme/src/overture/schema/base/water.py index d90971bb4..ca831c655 100644 --- a/packages/overture-schema-base-theme/src/overture/schema/base/water.py +++ b/packages/overture-schema-base-theme/src/overture/schema/base/water.py @@ -12,7 +12,7 @@ ) from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/_common.py b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/_common.py index b2b558718..9f02c1bb0 100644 --- a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/_common.py +++ b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/_common.py @@ -5,7 +5,7 @@ from pydantic import BaseModel, Field from overture.schema.system.doc import DocumentedEnum -from overture.schema.system.primitive import float64, int32 +from overture.schema.system.numeric import float64, int32 from overture.schema.system.string import HexColor diff --git a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building.py b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building.py index d40d3e296..43ed4883c 100644 --- a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building.py +++ b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building.py @@ -12,7 +12,7 @@ from overture.schema.common import OvertureFeature from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building_part.py b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building_part.py index ce0ed2c46..9d83d01a2 100644 --- a/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building_part.py +++ b/packages/overture-schema-buildings-theme/src/overture/schema/buildings/building_part.py @@ -11,7 +11,7 @@ from overture.schema.common import OvertureFeature from overture.schema.common.models import Stacked from overture.schema.common.names import Named -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-codegen/README.md b/packages/overture-schema-codegen/README.md index 61c029505..67c35002e 100644 --- a/packages/overture-schema-codegen/README.md +++ b/packages/overture-schema-codegen/README.md @@ -65,7 +65,7 @@ module structure. Link computation and reverse references enable cross-page navi **Rendering** consumes specs and owns all presentation decisions. Markdown output uses Jinja2 templates for feature pages (with field tables, constraint sections, and -examples), enum pages, NewType pages, and aggregate primitive/geometry reference pages. +examples), enum pages, NewType pages, and aggregate numeric/geometry reference pages. `markdown/pipeline.py` orchestrates the full pipeline without I/O, returning `list[RenderedPage]`. The CLI writes files to disk with Docusaurus frontmatter. diff --git a/packages/overture-schema-codegen/docs/design.md b/packages/overture-schema-codegen/docs/design.md index f7387c96e..b58dad1b7 100644 --- a/packages/overture-schema-codegen/docs/design.md +++ b/packages/overture-schema-codegen/docs/design.md @@ -258,7 +258,7 @@ to registered primitives. ### Markdown renderer -Jinja2 templates for feature, enum, NewType, primitives, and geometry pages. +Jinja2 templates for feature, enum, NewType, numeric, and geometry pages. `render_model()` walks each field's `FieldShape` tree and expands `ModelRef` terminals inline with dot-notation (e.g., `sources[].dataset`), stopping at `ModelRef.starts_cycle`. `format_type()` in `markdown/type_format.py` converts a diff --git a/packages/overture-schema-codegen/docs/walkthrough.md b/packages/overture-schema-codegen/docs/walkthrough.md index 7cfabf84e..4c13e0d8a 100644 --- a/packages/overture-schema-codegen/docs/walkthrough.md +++ b/packages/overture-schema-codegen/docs/walkthrough.md @@ -351,12 +351,13 @@ discriminator attribute. For Segment, it finds `subtype` and builds the mapping: `{"road": RoadSegment, "rail": RailSegment, "water": WaterSegment}` by checking each member for single-value `Literal` fields on the discriminator. -### Primitive extraction +### Numeric and geometry extraction -`partition_numeric_and_geometry_types` reads a module's `__all__` exports. NewType -exports are numeric primitives; non-constraint class exports are geometry types. +`partition_numeric_and_geometry_types` reads the numeric and geometric modules' +`__all__` exports. NewType exports of the numeric module are numeric types; +non-constraint class exports of the geometric module are geometry types. -`extract_numerics` builds `NumericSpec` objects. For each primitive name it resolves +`extract_numerics` builds `NumericSpec` objects. For each numeric type name it resolves the object from the module, calls `extract_newtype` for the type analysis, then extracts numeric bounds from constraints. `extract_numeric_bounds` scans constraint objects for `ge`/`gt`/`le`/`lt` attributes and packs them into an `Interval`. @@ -443,9 +444,9 @@ independent `if` statements, not `elif`. `build_placement_registry` builds the complete `dict[TypeIdentity, PurePosixPath]` mapping each type to its output file path. Four tiers: -Aggregate pages come first. All numeric primitives point to -`system/primitive/primitives.md`. All geometry types point to -`system/primitive/geometry.md`. These are hardcoded paths since the types share a single +Aggregate pages come first. All numeric types point to +`system/numeric.md`. All geometry types point to +`system/geometric.md`. These are hardcoded paths since the types share a single reference page. Feature specs get individual pages. Output directories derive from @@ -533,7 +534,7 @@ Six Jinja2 templates in `markdown/templates/`. `feature.md.jinja2` renders a fie with Name, Type, and Description columns, an optional Constraints section, an optional Examples section, and a "Used By" partial. `enum.md.jinja2` renders a bullet list of values. `newtype.md.jinja2` shows underlying type and constraints with provenance links. -`primitives.md.jinja2` and `geometry.md.jinja2` render aggregate reference pages. +`numeric.md.jinja2` and `geometric.md.jinja2` render aggregate reference pages. `_used_by.md.jinja2` is an included partial. The Jinja2 environment registers `linkify_urls` as a filter, which wraps bare URLs in @@ -575,7 +576,7 @@ truncate at 100 characters. Lists and dicts use compact bracket/brace notation. ### Aggregate pages -`render_primitives_from_specs` sorts primitives by bit-width key (prefix then numeric +`render_numeric_from_specs` sorts numeric types by bit-width key (prefix then numeric width), groups into signed integers, unsigned integers, and floats, and formats ranges. Integer ranges show both bounds as a compact "lower to upper" form; `int64`-scale bounds use `2^63` notation for readability. `render_geometry_from_values` produces a @@ -628,8 +629,8 @@ pipeline. feature specs and a schema root, returns rendered pages without touching the filesystem. Seven steps (tree expansion happens inside `extract_model`): -1. **Partition primitive and geometry names** from the system primitive module's - `__all__` exports. +1. **Partition numeric and geometry names** from the system numeric and geometric + modules' `__all__` exports. 2. **Collect supplementary types** by walking feature trees. @@ -642,7 +643,7 @@ Seven steps (tree expansion happens inside `extract_model`): 6. **Render each supplementary type** -- dispatching to `render_enum`, `render_newtype`, `render_model` (for sub-models), or `render_pydantic_type` based on spec type. -7. **Render aggregate pages** for primitives and geometry. +7. **Render aggregate pages** for numeric types and geometry. The return value is `list[RenderedPage]` -- frozen dataclasses carrying content, output path, and a boolean `is_model` flag. The caller decides what to do with them. @@ -703,7 +704,8 @@ values. Sub-model `FieldShape` trees are fully resolved -- `ModelRef` nodes already carry their `RecordSpec` from recursive `extract_model` calls. No separate expansion pass is needed. -**Layout.** `partition_numeric_and_geometry_types` reads the system module's exports. +**Layout.** `partition_numeric_and_geometry_types` reads the system numeric and +geometric modules' exports. `collect_all_supplementary_types` walks Segment's field shapes and discovers referenced enums (like `Subtype`), semantic NewTypes (like `Id`, `Sources`), and sub-models. The walk follows `ModelRef.model` references down the tree, and for `UnionRef` shapes, diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/extraction/field_constraints.py b/packages/overture-schema-codegen/src/overture/schema/codegen/extraction/field_constraints.py index 1cf1f2f15..cf77e5274 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/extraction/field_constraints.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/extraction/field_constraints.py @@ -13,7 +13,7 @@ from annotated_types import Ge, Gt, Interval, Le, Lt, MultipleOf -from overture.schema.system.primitive import GeometryTypeConstraint +from overture.schema.system.geometric import GeometryTypeConstraint from overture.schema.system.ref import Reference from .docstring import first_docstring_line diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/path_assignment.py b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/path_assignment.py index 7113ab8ca..e4d2f61a1 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/path_assignment.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/path_assignment.py @@ -18,15 +18,15 @@ from ..layout.module_layout import compute_output_dir, output_dir_for_entry_point __all__ = [ - "GEOMETRY_PAGE", - "PRIMITIVES_PAGE", + "GEOMETRIC_PAGE", + "NUMERIC_PAGE", "build_placement_registry", "resolve_output_path", ] # Aggregate page paths. -PRIMITIVES_PAGE = PurePosixPath("system/primitive/primitives.md") -GEOMETRY_PAGE = PurePosixPath("system/primitive/geometry.md") +NUMERIC_PAGE = PurePosixPath("system/numeric.md") +GEOMETRIC_PAGE = PurePosixPath("system/geometric.md") def build_placement_registry( @@ -85,9 +85,9 @@ def _aggregate_page_entries( ) -> dict[TypeIdentity, PurePosixPath]: """Pre-populate registry entries for types documented on aggregate pages.""" entries: dict[TypeIdentity, PurePosixPath] = dict.fromkeys( - numeric_names, PRIMITIVES_PAGE + numeric_names, NUMERIC_PAGE ) - entries.update(dict.fromkeys(geometry_names, GEOMETRY_PAGE)) + entries.update(dict.fromkeys(geometry_names, GEOMETRIC_PAGE)) return entries diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/pipeline.py b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/pipeline.py index 262782609..d159060de 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/pipeline.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/pipeline.py @@ -10,8 +10,9 @@ from dataclasses import dataclass from pathlib import PurePosixPath -import overture.schema.system.primitive as _system_primitive -from overture.schema.system.primitive import GeometryType +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric +from overture.schema.system.geometric import GeometryType from ..extraction.examples import ExampleRecord, load_examples from ..extraction.numeric_extraction import extract_numerics @@ -29,8 +30,8 @@ from ..layout.type_collection import collect_all_supplementary_types from .link_computation import LinkContext from .path_assignment import ( - GEOMETRY_PAGE, - PRIMITIVES_PAGE, + GEOMETRIC_PAGE, + NUMERIC_PAGE, build_placement_registry, resolve_output_path, ) @@ -39,7 +40,7 @@ render_geometry_from_values, render_model, render_newtype, - render_primitives_from_specs, + render_numeric_from_specs, render_pydantic_type, ) from .reverse_references import UsedByEntry, compute_reverse_references @@ -114,22 +115,24 @@ def _render_supplement( def partition_numeric_and_geometry_types( - types_module: object, + numeric_module: object, + geometric_module: object, ) -> tuple[list[TypeIdentity], list[TypeIdentity]]: - """Discover numeric and geometry types from a module's exports. + """Discover numeric and geometry types from their source modules' exports. - NewType exports are numeric types. - Non-constraint class/enum exports are geometry types. + NewType exports of *numeric_module* are numeric types. + Non-constraint class/enum exports of *geometric_module* are geometry types. """ - module_all: list[str] = getattr(types_module, "__all__", []) numerics: list[TypeIdentity] = [] - geometries: list[TypeIdentity] = [] - - for name in module_all: - obj = getattr(types_module, name) + for name in getattr(numeric_module, "__all__", []): + obj = getattr(numeric_module, name) if is_newtype(obj): numerics.append(TypeIdentity(obj, name)) - elif isinstance(obj, type) and not name.endswith("Constraint"): + + geometries: list[TypeIdentity] = [] + for name in getattr(geometric_module, "__all__", []): + obj = getattr(geometric_module, name) + if isinstance(obj, type) and not name.endswith("Constraint"): geometries.append(TypeIdentity(obj, name)) return numerics, geometries @@ -146,7 +149,7 @@ def generate_markdown_pages( (like Docusaurus category files). """ numeric_names, geometry_names = partition_numeric_and_geometry_types( - _system_primitive + _system_numeric, _system_geometric ) all_specs = collect_all_supplementary_types(model_specs) registry = build_placement_registry( @@ -170,15 +173,15 @@ def generate_markdown_pages( pages.append( RenderedPage( - content=render_primitives_from_specs(extract_numerics(numeric_names)), - path=PRIMITIVES_PAGE, + content=render_numeric_from_specs(extract_numerics(numeric_names)), + path=NUMERIC_PAGE, ) ) pages.append( RenderedPage( content=render_geometry_from_values([m.value for m in GeometryType]), - path=GEOMETRY_PAGE, + path=GEOMETRIC_PAGE, ) ) diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/renderer.py b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/renderer.py index 10c96a803..8f0911ab8 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/renderer.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/renderer.py @@ -48,7 +48,7 @@ "render_model", "render_geometry_from_values", "render_newtype", - "render_primitives_from_specs", + "render_numeric_from_specs", "render_pydantic_type", ] @@ -532,7 +532,7 @@ def render_pydantic_type( ) -# Matches the ge/le bounds of the int64 NewType in overture.schema.system.primitive. +# Matches the ge/le bounds of the int64 NewType in overture.schema.system.numeric. _INT64_MIN = -(2**63) _INT64_MAX = 2**63 - 1 @@ -597,9 +597,9 @@ def _bit_width_key(name: str) -> tuple[str, int]: return (prefix, int(digits) if digits else 0) -def render_primitives_from_specs(specs: list[NumericSpec]) -> str: - """Render the primitives.md page from pre-extracted NumericSpecs.""" - template = _get_jinja_env().get_template("primitives.md.jinja2") +def render_numeric_from_specs(specs: list[NumericSpec]) -> str: + """Render the numeric.md page from pre-extracted NumericSpecs.""" + template = _get_jinja_env().get_template("numeric.md.jinja2") signed_ints: list[dict[str, str | None]] = [] unsigned_ints: list[dict[str, str | None]] = [] @@ -635,7 +635,7 @@ def render_primitives_from_specs(specs: list[NumericSpec]) -> str: def render_geometry_from_values(geometry_type_values: list[str]) -> str: - """Render the geometry.md page from pre-extracted geometry type values.""" - template = _get_jinja_env().get_template("geometry.md.jinja2") + """Render the geometric.md page from pre-extracted geometry type values.""" + template = _get_jinja_env().get_template("geometric.md.jinja2") geometry_types = ", ".join(f"`{v}`" for v in geometry_type_values) return template.render(geometry_types=geometry_types) diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/geometry.md.jinja2 b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/geometric.md.jinja2 similarity index 100% rename from packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/geometry.md.jinja2 rename to packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/geometric.md.jinja2 diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/primitives.md.jinja2 b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/numeric.md.jinja2 similarity index 97% rename from packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/primitives.md.jinja2 rename to packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/numeric.md.jinja2 index fd87a1ec0..947256bf4 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/primitives.md.jinja2 +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/markdown/templates/numeric.md.jinja2 @@ -1,4 +1,4 @@ -# Primitive Types +# Numeric Types Numeric types used for schema field definitions. diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/constraint_dispatch.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/constraint_dispatch.py index 72baa5b88..e346f1082 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/constraint_dispatch.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/constraint_dispatch.py @@ -24,6 +24,7 @@ StrippedConstraint, ) from overture.schema.system.field_path import FieldPath +from overture.schema.system.geometric import GeometryTypeConstraint from overture.schema.system.model_constraint import ( Condition, FieldEqCondition, @@ -36,7 +37,6 @@ RequireAnyTrueConstraint, RequireIfConstraint, ) -from overture.schema.system.primitive import GeometryTypeConstraint from overture.schema.system.ref import Reference from ..extraction.docstring import first_docstring_line diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/pipeline.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/pipeline.py index 9bb2a9daa..d375a097f 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/pipeline.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/pipeline.py @@ -13,7 +13,7 @@ from overture.schema.system.case import to_snake_case from overture.schema.system.discovery import entry_point_to_path -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from ..extraction.specs import ModelSpec, UnionSpec from .check_builder import build_checks diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/renderer.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/renderer.py index 6fb48f3e1..44c5d85d2 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/renderer.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/renderer.py @@ -13,7 +13,7 @@ MapProjection, ScalarPath, ) -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from ._render_common import ( FieldCheckRow, diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/model_module.py.jinja2 b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/model_module.py.jinja2 index 8c91646c4..101b1abfd 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/model_module.py.jinja2 +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/model_module.py.jinja2 @@ -14,7 +14,7 @@ from pyspark.sql.types import ( ) {% endif %} {% if geometry_type %} -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType {% endif %} from overture.schema.pyspark.check import Check, CheckShape, ModelValidation diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/base_row.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/base_row.py index a9c56a359..2fb3db912 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/base_row.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/base_row.py @@ -15,6 +15,11 @@ from typing import Any from overture.schema.common.scoping.lr import LinearReferenceRangeConstraint +from overture.schema.system.geometric.geom import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( ForbidIfConstraint, MinFieldsSetConstraint, @@ -23,11 +28,6 @@ RequireAnyTrueConstraint, RequireIfConstraint, ) -from overture.schema.system.primitive.geom import ( - Geometry, - GeometryType, - GeometryTypeConstraint, -) from ...extraction.field import ( AnyScalar, diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/invalid_value.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/invalid_value.py index e54081a6c..078a1763f 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/invalid_value.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_data/invalid_value.py @@ -7,7 +7,7 @@ from __future__ import annotations -from overture.schema.system.primitive.geom import GeometryType +from overture.schema.system.geometric.geom import GeometryType from ..constraint_dispatch import ExpressionDescriptor from .constraint_values import ( diff --git a/packages/overture-schema-codegen/tests/codegen_test_support.py b/packages/overture-schema-codegen/tests/codegen_test_support.py index c30bffebb..0ded56a3c 100644 --- a/packages/overture-schema-codegen/tests/codegen_test_support.py +++ b/packages/overture-schema-codegen/tests/codegen_test_support.py @@ -41,19 +41,18 @@ from overture.schema.system.discovery.tag import get_values_for_key from overture.schema.system.doc import DocumentedEnum from overture.schema.system.field_constraint import UniqueItemsConstraint +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, radio_group, require_any_of, require_any_true, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, - float64, - int32, -) +from overture.schema.system.numeric import float64, int32 from overture.schema.system.ref import Id, Identified, Reference, Relationship from overture.schema.system.string import HexColor, LanguageTag, StrippedString from pydantic import BaseModel, EmailStr, Field, HttpUrl diff --git a/packages/overture-schema-codegen/tests/conftest.py b/packages/overture-schema-codegen/tests/conftest.py index fbd1f0f1e..db4ccde63 100644 --- a/packages/overture-schema-codegen/tests/conftest.py +++ b/packages/overture-schema-codegen/tests/conftest.py @@ -1,6 +1,7 @@ """Shared pytest fixtures for overture-schema-codegen tests.""" -import overture.schema.system.primitive as _system_primitive +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric import pytest from click.testing import CliRunner from codegen_test_support import find_model_class @@ -12,10 +13,10 @@ ) from overture.schema.codegen.markdown.renderer import ( render_geometry_from_values, - render_primitives_from_specs, + render_numeric_from_specs, ) from overture.schema.system.discovery import discover_models -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from pydantic import BaseModel @@ -70,13 +71,15 @@ def division_class(all_discovered_models: dict) -> type[BaseModel]: @pytest.fixture(scope="module") -def primitives_markdown() -> str: - """Render the primitives.md page from the system primitive module.""" - numeric_names, _ = partition_numeric_and_geometry_types(_system_primitive) - return render_primitives_from_specs(extract_numerics(numeric_names)) +def numeric_markdown() -> str: + """Render the numeric.md page from the system numeric module.""" + numeric_names, _ = partition_numeric_and_geometry_types( + _system_numeric, _system_geometric + ) + return render_numeric_from_specs(extract_numerics(numeric_names)) @pytest.fixture(scope="module") def geometry_markdown() -> str: - """Render the geometry.md page from system GeometryType values.""" + """Render the geometric.md page from system GeometryType values.""" return render_geometry_from_values([m.value for m in GeometryType]) diff --git a/packages/overture-schema-codegen/tests/test_constraint_description.py b/packages/overture-schema-codegen/tests/test_constraint_description.py index ff693960c..a9af9fc4e 100644 --- a/packages/overture-schema-codegen/tests/test_constraint_description.py +++ b/packages/overture-schema-codegen/tests/test_constraint_description.py @@ -25,6 +25,7 @@ CountryCodeAlpha2Constraint, PatternConstraint, ) +from overture.schema.system.geometric import GeometryType, GeometryTypeConstraint from overture.schema.system.model_constraint import ( FieldEqCondition, ForbidIfConstraint, @@ -37,7 +38,6 @@ RequireAnyTrueConstraint, RequireIfConstraint, ) -from overture.schema.system.primitive import GeometryType, GeometryTypeConstraint from overture.schema.system.ref import Reference, Relationship from overture.schema.system.ref.id import Identified diff --git a/packages/overture-schema-codegen/tests/test_example_loader.py b/packages/overture-schema-codegen/tests/test_example_loader.py index 541b81282..6db506b0b 100644 --- a/packages/overture-schema-codegen/tests/test_example_loader.py +++ b/packages/overture-schema-codegen/tests/test_example_loader.py @@ -21,7 +21,7 @@ resolve_pyproject_path, validate_example, ) -from overture.schema.system.primitive import BBox, Geometry +from overture.schema.system.geometric import BBox, Geometry from overture.schema.transportation import Segment from overture.schema.transportation.segment.models import ( RoadSegment, diff --git a/packages/overture-schema-codegen/tests/test_markdown_renderer.py b/packages/overture-schema-codegen/tests/test_markdown_renderer.py index 271347ca2..76f527fb8 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_renderer.py +++ b/packages/overture-schema-codegen/tests/test_markdown_renderer.py @@ -45,7 +45,7 @@ render_enum, render_model, render_newtype, - render_primitives_from_specs, + render_numeric_from_specs, render_pydantic_type, ) from overture.schema.codegen.markdown.reverse_references import UsedByEntry, UsedByKind @@ -55,7 +55,7 @@ UniqueItemsConstraint, ) from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 from overture.schema.system.ref import Id from overture.schema.system.string import HexColor, NoWhitespaceString from pydantic import BaseModel, Field @@ -1162,50 +1162,50 @@ def test_empty_examples_list_omits_section(self) -> None: assert "## Examples" not in result -class TestRenderPrimitivesPage: - """Tests for the aggregate primitives page.""" +class TestRenderNumericPage: + """Tests for the aggregate numeric types page.""" - def test_contains_title(self, primitives_markdown: str) -> None: - assert "# Primitive Types" in primitives_markdown + def test_contains_title(self, numeric_markdown: str) -> None: + assert "# Numeric Types" in numeric_markdown - def test_contains_signed_integers(self, primitives_markdown: str) -> None: - assert "| `int8` |" in primitives_markdown - assert "| `int16` |" in primitives_markdown - assert "| `int32` |" in primitives_markdown - assert "| `int64` |" in primitives_markdown + def test_contains_signed_integers(self, numeric_markdown: str) -> None: + assert "| `int8` |" in numeric_markdown + assert "| `int16` |" in numeric_markdown + assert "| `int32` |" in numeric_markdown + assert "| `int64` |" in numeric_markdown - def test_contains_unsigned_integers(self, primitives_markdown: str) -> None: - assert "| `uint8` |" in primitives_markdown - assert "| `uint16` |" in primitives_markdown - assert "| `uint32` |" in primitives_markdown + def test_contains_unsigned_integers(self, numeric_markdown: str) -> None: + assert "| `uint8` |" in numeric_markdown + assert "| `uint16` |" in numeric_markdown + assert "| `uint32` |" in numeric_markdown - def test_contains_floats(self, primitives_markdown: str) -> None: - assert "| `float32` |" in primitives_markdown - assert "| `float64` |" in primitives_markdown + def test_contains_floats(self, numeric_markdown: str) -> None: + assert "| `float32` |" in numeric_markdown + assert "| `float64` |" in numeric_markdown - def test_ranges_match_schema_constraints(self, primitives_markdown: str) -> None: + def test_ranges_match_schema_constraints(self, numeric_markdown: str) -> None: """Range strings derive from ge/le constraints in the schema.""" - assert "-128 to 127" in primitives_markdown - assert "-32,768 to 32,767" in primitives_markdown - assert "-2,147,483,648 to 2,147,483,647" in primitives_markdown - assert "-2^63 to 2^63-1" in primitives_markdown - assert "0 to 255" in primitives_markdown - assert "0 to 65,535" in primitives_markdown - assert "0 to 4,294,967,295" in primitives_markdown - - def test_descriptions_from_docstrings(self, primitives_markdown: str) -> None: + assert "-128 to 127" in numeric_markdown + assert "-32,768 to 32,767" in numeric_markdown + assert "-2,147,483,648 to 2,147,483,647" in numeric_markdown + assert "-2^63 to 2^63-1" in numeric_markdown + assert "0 to 255" in numeric_markdown + assert "0 to 65,535" in numeric_markdown + assert "0 to 4,294,967,295" in numeric_markdown + + def test_descriptions_from_docstrings(self, numeric_markdown: str) -> None: """Descriptions derive from first line of NewType docstrings.""" - assert "Portable 8-bit signed integer." in primitives_markdown - assert "Portable 16-bit unsigned integer." in primitives_markdown - assert "Portable IEEE 32-bit floating point number." in primitives_markdown + assert "Portable 8-bit signed integer." in numeric_markdown + assert "Portable 16-bit unsigned integer." in numeric_markdown + assert "Portable IEEE 32-bit floating point number." in numeric_markdown - def test_float_precision(self, primitives_markdown: str) -> None: + def test_float_precision(self, numeric_markdown: str) -> None: """Float entries show IEEE 754 precision.""" - assert "~7 decimal digits" in primitives_markdown - assert "~15 decimal digits" in primitives_markdown + assert "~7 decimal digits" in numeric_markdown + assert "~15 decimal digits" in numeric_markdown def test_pipe_in_description_escaped(self) -> None: - """Pipe characters in primitive descriptions are escaped.""" + """Pipe characters in numeric type descriptions are escaped.""" specs = [ NumericSpec( name="int8", @@ -1213,7 +1213,7 @@ def test_pipe_in_description_escaped(self) -> None: bounds=Interval(ge=-128, le=127), ), ] - result = render_primitives_from_specs(specs) + result = render_numeric_from_specs(specs) assert "Range: -128 \\| 127" in result diff --git a/packages/overture-schema-codegen/tests/test_markdown_type_format.py b/packages/overture-schema-codegen/tests/test_markdown_type_format.py index b10a69451..9e4597133 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_type_format.py +++ b/packages/overture-schema-codegen/tests/test_markdown_type_format.py @@ -25,7 +25,8 @@ format_type, format_underlying_type, ) -from overture.schema.system.primitive import BBox, Geometry, int32 +from overture.schema.system.geometric import BBox, Geometry +from overture.schema.system.numeric import int32 from pydantic import BaseModel, HttpUrl @@ -101,27 +102,18 @@ def test_geometry_links_to_aggregate_page(self) -> None: ctx = LinkContext( page_path=PurePosixPath("buildings/building/building.md"), registry={ - TypeIdentity(Geometry, "Geometry"): PurePosixPath( - "system/primitive/geometry.md" - ) + TypeIdentity(Geometry, "Geometry"): PurePosixPath("system/geometric.md") }, ) - assert ( - format_type(field, ctx) - == "[`geometry`](../../system/primitive/geometry.md)" - ) + assert format_type(field, ctx) == "[`geometry`](../../system/geometric.md)" def test_bbox_links_to_aggregate_page(self) -> None: field = _make_field(BBox) ctx = LinkContext( page_path=PurePosixPath("base/feature/feature.md"), - registry={ - TypeIdentity(BBox, "BBox"): PurePosixPath( - "system/primitive/geometry.md" - ) - }, + registry={TypeIdentity(BBox, "BBox"): PurePosixPath("system/geometric.md")}, ) - assert format_type(field, ctx) == "[`bbox`](../../system/primitive/geometry.md)" + assert format_type(field, ctx) == "[`bbox`](../../system/geometric.md)" def test_geometry_without_context_renders_plain_code(self) -> None: assert format_type(_make_field(Geometry)) == "`geometry`" @@ -298,18 +290,14 @@ def test_list_of_pydantic_type_linked(self) -> None: assert "pydantic/networks/http_url.md" in result def test_registered_primitive_links_to_aggregate_page(self) -> None: - """int32 links to the primitives aggregate page when in registry.""" + """int32 links to the numeric types aggregate page when in registry.""" ctx = LinkContext( page_path=PurePosixPath("places/place/place.md"), - registry={ - TypeIdentity(int32, "int32"): PurePosixPath( - "system/primitive/primitives.md" - ) - }, + registry={TypeIdentity(int32, "int32"): PurePosixPath("system/numeric.md")}, ) result = format_type(_make_field(int32), ctx) assert "[`int32`]" in result - assert "system/primitive/primitives.md" in result + assert "system/numeric.md" in result class TestListOfSemanticNewtype: @@ -491,10 +479,10 @@ def test_map_value_geometry_links_in_field_cell(self) -> None: The map-side link decision shares `_scalar_identity`'s coverage, so a Geometry value links rather than rendering bare. """ - ctx = _link_ctx((Geometry, "geometry", "system/primitive/geometry.md")) + ctx = _link_ctx((Geometry, "geometry", "system/geometric.md")) result = format_type(_make_field(dict[str, Geometry]), ctx) assert "[`geometry`]" in result - assert "system/primitive/geometry.md" in result + assert "system/geometric.md" in result assert "``" not in result def test_map_value_pydantic_type_links_in_field_cell(self) -> None: @@ -520,13 +508,11 @@ def test_geometry_underlying_type_links(self) -> None: ctx = LinkContext( page_path=PurePosixPath("system/types/geom_alias.md"), registry={ - TypeIdentity(Geometry, "geometry"): PurePosixPath( - "system/primitive/geometry.md" - ) + TypeIdentity(Geometry, "geometry"): PurePosixPath("system/geometric.md") }, ) result = format_underlying_type(shape, ctx) - assert "[`geometry`](../primitive/geometry.md)" in result + assert "[`geometry`](../geometric.md)" in result def test_numeric_underlying_type_stays_bare(self) -> None: """A NewType over a numeric primitive renders bare, not over-linked. diff --git a/packages/overture-schema-codegen/tests/test_model_extractor.py b/packages/overture-schema-codegen/tests/test_model_extractor.py index 981d7bf78..6356d30d3 100644 --- a/packages/overture-schema-codegen/tests/test_model_extractor.py +++ b/packages/overture-schema-codegen/tests/test_model_extractor.py @@ -20,17 +20,17 @@ ) from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.system.field_constraint import UniqueItemsConstraint +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, FieldGroupConstraint, require_any_of, require_if, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, -) from overture.schema.system.string import HexColor from pydantic import BaseModel, Field diff --git a/packages/overture-schema-codegen/tests/test_numeric_extraction.py b/packages/overture-schema-codegen/tests/test_numeric_extraction.py index 6f3a5767f..b9e4f5b4e 100644 --- a/packages/overture-schema-codegen/tests/test_numeric_extraction.py +++ b/packages/overture-schema-codegen/tests/test_numeric_extraction.py @@ -2,7 +2,8 @@ from typing import Annotated, NewType -import overture.schema.system.primitive as _system_primitive +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric from overture.schema.codegen.extraction.newtype_extraction import extract_newtype from overture.schema.codegen.extraction.numeric_extraction import ( extract_numeric_bounds, @@ -13,7 +14,7 @@ from overture.schema.codegen.markdown.pipeline import ( partition_numeric_and_geometry_types, ) -from overture.schema.system.primitive import float32, int32, int64, uint8 +from overture.schema.system.numeric import float32, int32, int64, uint8 from pydantic import Field @@ -21,28 +22,36 @@ class TestPartitionNumericAndGeometryTypes: """Tests for partition_numeric_and_geometry_types function.""" def test_returns_type_identities(self) -> None: - nums, geoms = partition_numeric_and_geometry_types(_system_primitive) + nums, geoms = partition_numeric_and_geometry_types( + _system_numeric, _system_geometric + ) assert all(isinstance(p, TypeIdentity) for p in nums) assert all(isinstance(g, TypeIdentity) for g in geoms) def test_identity_obj_is_actual_callable(self) -> None: - nums, _ = partition_numeric_and_geometry_types(_system_primitive) + nums, _ = partition_numeric_and_geometry_types( + _system_numeric, _system_geometric + ) int32_id = next(p for p in nums if p.name == "int32") - assert int32_id.obj is _system_primitive.int32 + assert int32_id.obj is _system_numeric.int32 class TestExtractNumerics: """Tests for extract_numerics function.""" def test_accepts_type_identities(self) -> None: - nums, _ = partition_numeric_and_geometry_types(_system_primitive) + nums, _ = partition_numeric_and_geometry_types( + _system_numeric, _system_geometric + ) specs = extract_numerics(nums) assert len(specs) > 0 names = [s.name for s in specs] assert "int32" in names def test_extracts_bounds(self) -> None: - nums, _ = partition_numeric_and_geometry_types(_system_primitive) + nums, _ = partition_numeric_and_geometry_types( + _system_numeric, _system_geometric + ) specs = extract_numerics(nums) int32_spec = next(s for s in specs if s.name == "int32") assert int32_spec.bounds.ge == -(2**31) diff --git a/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py b/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py index 77b2acd62..88d8dc5da 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py @@ -64,7 +64,7 @@ forbid_if, require_any_of, ) -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 from overture.schema.system.string import CountryCodeAlpha2 from pydantic import BaseModel, Field from pydantic.fields import FieldInfo diff --git a/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py b/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py index 1e3d2275e..c87524925 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py @@ -37,6 +37,7 @@ SnakeCaseConstraint, StrippedConstraint, ) +from overture.schema.system.geometric import GeometryType, GeometryTypeConstraint from overture.schema.system.model_constraint import ( FieldEqCondition, ForbidIfConstraint, @@ -48,7 +49,6 @@ RequireAnyTrueConstraint, RequireIfConstraint, ) -from overture.schema.system.primitive import GeometryType, GeometryTypeConstraint from overture.schema.system.ref import Identified, Reference, Relationship from pydantic import Field, Strict diff --git a/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py b/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py index 77a4a3ef2..0db68c8e4 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py @@ -10,7 +10,7 @@ RegionCodeConstraint, StrippedConstraint, ) -from overture.schema.system.primitive.geom import GeometryType +from overture.schema.system.geometric.geom import GeometryType class TestInvalidValueRequired: diff --git a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py index d84fe7199..74ba280b2 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py @@ -22,7 +22,7 @@ ) from overture.schema.codegen.spec_discovery import extract_model_spec from overture.schema.system.field_path import ScalarPath -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from pydantic import BaseModel diff --git a/packages/overture-schema-codegen/tests/test_pyspark_renderer.py b/packages/overture-schema-codegen/tests/test_pyspark_renderer.py index 54d865d21..a7f2c9497 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_renderer.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_renderer.py @@ -51,6 +51,11 @@ ScalarPath, parse, ) +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, Not, @@ -58,12 +63,7 @@ require_any_of, require_if, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, - int32, -) +from overture.schema.system.numeric import int32 from overture.schema.system.string import CountryCodeAlpha2 from pydantic import BaseModel, HttpUrl from pydantic.fields import FieldInfo @@ -574,7 +574,7 @@ def test_geometry_type_imported_when_only_constant_needs_it(self) -> None: schema_fields, geometry_types=(GeometryType.POINT,), ) - assert "from overture.schema.system.primitive import GeometryType" in source + assert "from overture.schema.system.geometric import GeometryType" in source class TestImports: @@ -776,7 +776,7 @@ def test_geometry_type_uses_qualified_name(self) -> None: def test_geometry_type_import_present(self) -> None: source = _render(GeomModel, "geom") - assert "from overture.schema.system.primitive import GeometryType" in source + assert "from overture.schema.system.geometric import GeometryType" in source def test_no_geometry_type_import_without_geometry_field( self, literal_subtype_source: str diff --git a/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py b/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py index 485684d96..54a27291e 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py @@ -41,8 +41,8 @@ StrippedConstraint, ) from overture.schema.system.field_path import ArrayPath, ScalarPath, parse +from overture.schema.system.geometric.geom import GeometryType from overture.schema.system.model_constraint import FieldEqCondition, Not -from overture.schema.system.primitive.geom import GeometryType _path = parse diff --git a/packages/overture-schema-codegen/tests/test_specs.py b/packages/overture-schema-codegen/tests/test_specs.py index 51da3a20a..99cbe2780 100644 --- a/packages/overture-schema-codegen/tests/test_specs.py +++ b/packages/overture-schema-codegen/tests/test_specs.py @@ -20,7 +20,7 @@ TypeIdentity, is_union_alias, ) -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 from pydantic import BaseModel, Field diff --git a/packages/overture-schema-codegen/tests/test_type_analyzer.py b/packages/overture-schema-codegen/tests/test_type_analyzer.py index 144214b75..b3a81cb8c 100644 --- a/packages/overture-schema-codegen/tests/test_type_analyzer.py +++ b/packages/overture-schema-codegen/tests/test_type_analyzer.py @@ -38,7 +38,7 @@ unwrap_list, ) from overture.schema.common.scoping.vehicle import VehicleSelector -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 from overture.schema.system.ref import Id from overture.schema.system.string import ( HexColor, diff --git a/packages/overture-schema-codegen/tests/test_type_collection.py b/packages/overture-schema-codegen/tests/test_type_collection.py index 66cbbcbd5..71907e719 100644 --- a/packages/overture-schema-codegen/tests/test_type_collection.py +++ b/packages/overture-schema-codegen/tests/test_type_collection.py @@ -21,7 +21,7 @@ from overture.schema.codegen.layout.type_collection import ( collect_all_supplementary_types, ) -from overture.schema.system.primitive import uint8 +from overture.schema.system.numeric import uint8 from overture.schema.system.string import HexColor from pydantic import BaseModel diff --git a/packages/overture-schema-codegen/tests/test_type_placement.py b/packages/overture-schema-codegen/tests/test_type_placement.py index 5ae07dbbd..bf3d5528a 100644 --- a/packages/overture-schema-codegen/tests/test_type_placement.py +++ b/packages/overture-schema-codegen/tests/test_type_placement.py @@ -2,7 +2,8 @@ from pathlib import PurePosixPath -import overture.schema.system.primitive as _system_primitive +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric from codegen_test_support import ( EMAIL_STR_SPEC, HTTP_URL_SPEC, @@ -24,8 +25,8 @@ ) from overture.schema.codegen.markdown.link_computation import LinkContext, relative_link from overture.schema.codegen.markdown.path_assignment import ( - GEOMETRY_PAGE, - PRIMITIVES_PAGE, + GEOMETRIC_PAGE, + NUMERIC_PAGE, build_placement_registry, ) from overture.schema.codegen.markdown.pipeline import ( @@ -34,7 +35,7 @@ from pydantic import BaseModel _NUMERIC_NAMES, _GEOMETRY_NAMES = partition_numeric_and_geometry_types( - _system_primitive + _system_numeric, _system_geometric ) _SCHEMA_ROOT = "overture.schema" @@ -71,8 +72,8 @@ def test_within_common(self) -> None: def test_to_aggregate_page(self) -> None: source = PurePosixPath("common/names/names.md") - target = PurePosixPath("system/primitive/primitives.md") - assert relative_link(source, target) == "../../system/primitive/primitives.md" + target = PurePosixPath("system/numeric.md") + assert relative_link(source, target) == "../../system/numeric.md" class TestBuildPlacementRegistry: @@ -105,18 +106,18 @@ def test_no_duplicate_paths(self) -> None: registry, _ = _build_registry(specs) aggregate_pages = { - PurePosixPath("system/primitive/primitives.md"), - PurePosixPath("system/primitive/geometry.md"), + PurePosixPath("system/numeric.md"), + PurePosixPath("system/geometric.md"), } individual = [p for p in registry.values() if p not in aggregate_pages] assert len(individual) == len(set(individual)), ( "Duplicate output paths detected" ) - def test_aggregate_pages_at_system_primitive(self) -> None: - """Primitive and geometry aggregate pages under system/primitive/.""" - assert PRIMITIVES_PAGE == PurePosixPath("system/primitive/primitives.md") - assert GEOMETRY_PAGE == PurePosixPath("system/primitive/geometry.md") + def test_aggregate_pages_under_system(self) -> None: + """Numeric and geometry aggregate pages sit directly under system/.""" + assert NUMERIC_PAGE == PurePosixPath("system/numeric.md") + assert GEOMETRIC_PAGE == PurePosixPath("system/geometric.md") def test_supplementary_types_nested_under_types(self) -> None: """Supplementary types in a feature directory go under types/.""" diff --git a/packages/overture-schema-common/README.md b/packages/overture-schema-common/README.md index ebb4a4534..177aaf834 100644 --- a/packages/overture-schema-common/README.md +++ b/packages/overture-schema-common/README.md @@ -27,7 +27,7 @@ Many Overture values only apply under specific conditions -- a speed limit that ```python from pydantic import BaseModel from overture.schema.common.scoping import Scope, scoped -from overture.schema.system.primitive import float32 +from overture.schema.system.numeric import float32 @scoped(Scope.GEOMETRIC_RANGE, Scope.TEMPORAL) class SpeedLimit(BaseModel): @@ -92,6 +92,6 @@ Rendering hints for map-making: `prominence` (1--100 significance scale), `min_z ## Also Included -- **Types** -- domain-specific aliases built on system primitives: `ConfidenceScore` (0.0--1.0), `Level` (z-order), `FeatureVersion`. +- **Types** -- domain-specific aliases built on system numeric types: `ConfidenceScore` (0.0--1.0), `Level` (z-order), `FeatureVersion`. - **Units** -- measurement enumerations: `SpeedUnit`, `LengthUnit`, `WeightUnit`. - **Tag providers** -- `theme` provider for the discovery system in `overture-schema-system`. Tags `OvertureFeature`-derived models with `overture:theme={theme}`. diff --git a/packages/overture-schema-common/src/overture/schema/common/cartography.py b/packages/overture-schema-common/src/overture/schema/common/cartography.py index 71cd60dbf..f0a52e870 100644 --- a/packages/overture-schema-common/src/overture/schema/common/cartography.py +++ b/packages/overture-schema-common/src/overture/schema/common/cartography.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, Field from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 Prominence = NewType( "Prominence", diff --git a/packages/overture-schema-common/src/overture/schema/common/models.py b/packages/overture-schema-common/src/overture/schema/common/models.py index 9a364f639..64fabc546 100644 --- a/packages/overture-schema-common/src/overture/schema/common/models.py +++ b/packages/overture-schema-common/src/overture/schema/common/models.py @@ -14,10 +14,10 @@ from overture.schema.system.feature import Feature from overture.schema.system.field_constraint import UniqueItemsConstraint -from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, ) +from overture.schema.system.model_constraint import no_extra_fields from overture.schema.system.ref import Id, Identified from overture.schema.system.string import ( CountryCodeAlpha2, diff --git a/packages/overture-schema-common/src/overture/schema/common/names.py b/packages/overture-schema-common/src/overture/schema/common/names.py index 75c0decf3..80b5aa4e8 100644 --- a/packages/overture-schema-common/src/overture/schema/common/names.py +++ b/packages/overture-schema-common/src/overture/schema/common/names.py @@ -10,7 +10,7 @@ >>> from typing import Literal >>> from overture.schema.common import OvertureFeature ->>> from overture.schema.system.primitive import Geometry +>>> from overture.schema.system.geometric import Geometry >>> class MyFeature(OvertureFeature[Literal["mytheme"], Literal["mytype"]], Named): ... pass ... diff --git a/packages/overture-schema-common/src/overture/schema/common/scoping/__init__.py b/packages/overture-schema-common/src/overture/schema/common/scoping/__init__.py index b7e703b5d..bed8ef3f2 100644 --- a/packages/overture-schema-common/src/overture/schema/common/scoping/__init__.py +++ b/packages/overture-schema-common/src/overture/schema/common/scoping/__init__.py @@ -18,12 +18,12 @@ >>> from typing import Annotated, Literal >>> from pydantic import BaseModel >>> from overture.schema.common.models import OvertureFeature ->>> from overture.schema.system.primitive import ( -... float32, +>>> from overture.schema.system.geometric import ( ... Geometry, ... GeometryType, -... GeometryTypeConstraint +... GeometryTypeConstraint, ... ) +>>> from overture.schema.system.numeric import float32 ... >>> @scoped(Scope.GEOMETRIC_RANGE) ... class Depth(BaseModel): @@ -72,12 +72,12 @@ >>> from typing import Annotated, Literal >>> from pydantic import BaseModel >>> from overture.schema.common.models import OvertureFeature ->>> from overture.schema.system.primitive import ( +>>> from overture.schema.system.geometric import ( ... Geometry, ... GeometryType, ... GeometryTypeConstraint, -... uint32, ... ) +>>> from overture.schema.system.numeric import uint32 ... >>> @scoped(required=Scope.GEOMETRIC_POSITION) ... class Transformer(BaseModel): @@ -120,12 +120,12 @@ >>> from typing import Annotated, Literal >>> from pydantic import BaseModel, Field >>> from overture.schema.common.models import OvertureFeature ->>> from overture.schema.system.primitive import ( +>>> from overture.schema.system.geometric import ( ... Geometry, ... GeometryType, ... GeometryTypeConstraint, -... uint32, ... ) +>>> from overture.schema.system.numeric import uint32 >>> from overture.schema.system.string import StrippedString ... >>> @scoped(required=Scope.HEADING) @@ -213,7 +213,7 @@ >>> from typing import Annotated, Literal >>> from pydantic import BaseModel >>> from overture.schema.common.models import OvertureFeature ->>> from overture.schema.system.primitive import ( +>>> from overture.schema.system.geometric import ( ... Geometry, ... GeometryType, ... GeometryTypeConstraint, @@ -255,7 +255,7 @@ added to the model. >>> from overture.schema.common.unit import LengthUnit ->>> from overture.schema.system.primitive import float32 +>>> from overture.schema.system.numeric import float32 ... >>> @scoped(Scope.VEHICLE) ... class Fare(BaseModel): @@ -341,7 +341,7 @@ If a `when` field is added to the model, the model is also decorated with a nested `When` class to simplify instantiating values for the `when` field, for example: ->>> from overture.schema.system.primitive import uint8 +>>> from overture.schema.system.numeric import uint8 ... >>> @scoped(Scope.HEADING) ... class MyModel(BaseModel): diff --git a/packages/overture-schema-common/src/overture/schema/common/scoping/lr.py b/packages/overture-schema-common/src/overture/schema/common/scoping/lr.py index d1bc03b00..eb39b197c 100644 --- a/packages/overture-schema-common/src/overture/schema/common/scoping/lr.py +++ b/packages/overture-schema-common/src/overture/schema/common/scoping/lr.py @@ -8,7 +8,7 @@ from pydantic_core import InitErrorDetails, core_schema from overture.schema.system.field_constraint import CollectionConstraint -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 LinearlyReferencedPosition = NewType( "LinearlyReferencedPosition", diff --git a/packages/overture-schema-common/src/overture/schema/common/scoping/vehicle.py b/packages/overture-schema-common/src/overture/schema/common/scoping/vehicle.py index 82330ecb1..fb791126f 100644 --- a/packages/overture-schema-common/src/overture/schema/common/scoping/vehicle.py +++ b/packages/overture-schema-common/src/overture/schema/common/scoping/vehicle.py @@ -9,7 +9,7 @@ from overture.schema.common.unit import LengthUnit, WeightUnit from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import float64 +from overture.schema.system.numeric import float64 class VehicleDimension(str, Enum): diff --git a/packages/overture-schema-common/src/overture/schema/common/types.py b/packages/overture-schema-common/src/overture/schema/common/types.py index 8cbc8673f..4639d342c 100644 --- a/packages/overture-schema-common/src/overture/schema/common/types.py +++ b/packages/overture-schema-common/src/overture/schema/common/types.py @@ -4,7 +4,7 @@ Field, ) -from overture.schema.system.primitive import float64, int32 +from overture.schema.system.numeric import float64, int32 ConfidenceScore = NewType( "ConfidenceScore", diff --git a/packages/overture-schema-common/tests/test_models.py b/packages/overture-schema-common/tests/test_models.py index cc8003ae5..9d819de4e 100644 --- a/packages/overture-schema-common/tests/test_models.py +++ b/packages/overture-schema-common/tests/test_models.py @@ -6,11 +6,11 @@ from deepdiff import DeepDiff from overture.schema.common.models import OvertureFeature from overture.schema.common.sources import SourceItem -from overture.schema.system.json_schema import GenerateOmitNullableOptionalJsonSchema -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( BBox, Geometry, ) +from overture.schema.system.json_schema import GenerateOmitNullableOptionalJsonSchema from pydantic import ValidationError from shapely.geometry import LineString, Point diff --git a/packages/overture-schema-common/tests/test_primitive_types.py b/packages/overture-schema-common/tests/test_numeric_types.py similarity index 94% rename from packages/overture-schema-common/tests/test_primitive_types.py rename to packages/overture-schema-common/tests/test_numeric_types.py index e35dc8ddd..698ed2082 100644 --- a/packages/overture-schema-common/tests/test_primitive_types.py +++ b/packages/overture-schema-common/tests/test_numeric_types.py @@ -1,9 +1,9 @@ -"""Tests for primitive data types functionality.""" +"""Tests for numeric data types functionality.""" from typing import Annotated import pytest -from overture.schema.system.primitive import ( +from overture.schema.system.numeric import ( float32, float64, int32, @@ -14,7 +14,7 @@ class TestValidation: - """Test validation behavior of primitive types.""" + """Test validation behavior of numeric types.""" def test_uint8_validation(self) -> None: """Test UInt8 validation constraints.""" @@ -51,7 +51,7 @@ class TestModel(BaseModel): TestModel(value=2**31) def test_optional_fields(self) -> None: - """Test optional primitive type fields.""" + """Test optional numeric type fields.""" class TestModel(BaseModel): required_value: uint8 @@ -68,7 +68,7 @@ class TestModel(BaseModel): assert model.optional_value is None def test_float_types(self) -> None: - """Test float primitive types.""" + """Test float numeric types.""" class TestModel(BaseModel): f32: float32 @@ -79,7 +79,7 @@ class TestModel(BaseModel): assert model.f64 == 2.71828 def test_conflicting_validation_criteria(self) -> None: - """Test that Field constraints closest to use take precedence over primitive + """Test that Field constraints closest to use take precedence over numeric type constraints.""" # Int32 has built-in constraints: ge=-(2**31), le=2**31-1 @@ -93,7 +93,7 @@ class TestModelRestrictive(BaseModel): assert TestModelRestrictive(value=5).value == 5 assert TestModelRestrictive(value=-5).value == -5 - # Should fail with the more restrictive constraint (le=5), not the primitive type constraint + # Should fail with the more restrictive constraint (le=5), not the numeric type constraint with pytest.raises(ValidationError) as exc_info: TestModelRestrictive(value=6) @@ -110,7 +110,7 @@ class TestModelPermissive(BaseModel): assert TestModelPermissive(value=-10).value == -10 assert TestModelPermissive(value=0).value == 0 - # Should fail with the closer constraint (ge=-10), not the primitive type constraint + # Should fail with the closer constraint (ge=-10), not the numeric type constraint with pytest.raises(ValidationError) as exc_info: TestModelPermissive(value=-11) diff --git a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/_common.py b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/_common.py index a2aaa9da0..69ddacc5d 100644 --- a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/_common.py +++ b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/_common.py @@ -5,7 +5,7 @@ from overture.schema.system.doc import DocumentedEnum from overture.schema.system.model_constraint import FieldEqCondition -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 AdminLevel = NewType( "AdminLevel", diff --git a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division.py b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division.py index f0b00b246..3af64df23 100644 --- a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division.py +++ b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division.py @@ -22,18 +22,18 @@ from overture.schema.system.field_constraint import ( UniqueItemsConstraint, ) +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, forbid_if, no_extra_fields, require_if, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, - int32, -) +from overture.schema.system.numeric import int32 from overture.schema.system.ref import Id, Reference, Relationship from overture.schema.system.string import ( CountryCodeAlpha2, diff --git a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_area.py b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_area.py index e1a92a94d..e910e3e4a 100644 --- a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_area.py +++ b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_area.py @@ -13,16 +13,16 @@ Names, ) from overture.schema.system.doc import DocumentedEnum +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, require_any_true, require_if, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, -) from overture.schema.system.ref import Id, Reference, Relationship from overture.schema.system.string import CountryCodeAlpha2, RegionCode diff --git a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_boundary.py b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_boundary.py index 974a928f4..60597cf29 100644 --- a/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_boundary.py +++ b/packages/overture-schema-divisions-theme/src/overture/schema/divisions/division_boundary.py @@ -11,17 +11,17 @@ from overture.schema.common.models import Perspectives from overture.schema.system.doc import DocumentedEnum from overture.schema.system.field_constraint import UniqueItemsConstraint +from overture.schema.system.geometric import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, forbid_if, require_any_true, require_if, ) -from overture.schema.system.primitive import ( - Geometry, - GeometryType, - GeometryTypeConstraint, -) from overture.schema.system.ref import Id, Reference, Relationship from overture.schema.system.string import CountryCodeAlpha2, RegionCode diff --git a/packages/overture-schema-places-theme/src/overture/schema/places/place.py b/packages/overture-schema-places-theme/src/overture/schema/places/place.py index f83e54e0b..3682e8f8a 100644 --- a/packages/overture-schema-places-theme/src/overture/schema/places/place.py +++ b/packages/overture-schema-places-theme/src/overture/schema/places/place.py @@ -20,12 +20,12 @@ from overture.schema.system.field_constraint import ( UniqueItemsConstraint, ) -from overture.schema.system.model_constraint import no_extra_fields -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, ) +from overture.schema.system.model_constraint import no_extra_fields from overture.schema.system.string import ( CountryCodeAlpha2, PhoneNumber, diff --git a/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py b/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py index ac6d993b2..71e09ad2f 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py @@ -9,7 +9,7 @@ from pyspark.sql import Column from pyspark.sql.types import StructType -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType class CheckShape(Enum): diff --git a/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py b/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py index ed8dae2b8..14fb70833 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py @@ -11,7 +11,7 @@ from pyspark.sql import DataFrame, SparkSession from overture.schema.system.discovery import resolve_entry_point_key -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from ._registry import PARTITION_MAP, REGISTRY from .validate import ( diff --git a/packages/overture-schema-pyspark/src/overture/schema/pyspark/expressions/constraint_expressions.py b/packages/overture-schema-pyspark/src/overture/schema/pyspark/expressions/constraint_expressions.py index abc459b28..9540c52bc 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/expressions/constraint_expressions.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/expressions/constraint_expressions.py @@ -21,7 +21,7 @@ from pyspark.sql import Column from pyspark.sql import functions as F -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from .column_patterns import error_msg diff --git a/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py b/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py index b5565a4d7..d62936c30 100644 --- a/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py +++ b/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py @@ -31,7 +31,7 @@ check_url_length, except_literals, ) -from overture.schema.system.primitive import GeometryType +from overture.schema.system.geometric import GeometryType from pyspark.sql import Row, SparkSession from pyspark.sql import functions as F from pyspark.sql.types import DoubleType, StringType, StructField, StructType diff --git a/packages/overture-schema-system/README.md b/packages/overture-schema-system/README.md index 9733d105f..6dddfc8cc 100644 --- a/packages/overture-schema-system/README.md +++ b/packages/overture-schema-system/README.md @@ -1,6 +1,6 @@ # Overture Schema System -Write Pydantic models once, get validated data that serializes correctly to JSON, Parquet, and Spark. This package provides the primitive types, constraint decorators, and GeoJSON-aware base class that make Pydantic models portable across serialization targets. +Write Pydantic models once, get validated data that serializes correctly to JSON, Parquet, and Spark. This package provides the numeric and geometric types, constraint decorators, and GeoJSON-aware base class that make Pydantic models portable across serialization targets. ## Installation @@ -14,7 +14,8 @@ GeoJSON-compatible Pydantic base model. Subclasses serialize to the GeoJSON form ```python from overture.schema.system.feature import Feature -from overture.schema.system.primitive import Geometry, float32 +from overture.schema.system.geometric import Geometry +from overture.schema.system.numeric import float32 class Mountain(Feature): name: str @@ -27,20 +28,30 @@ m = Mountain( ) ``` -## Primitive Types +## Numeric Types -Using `int` and `float` in a Pydantic model produces valid Python but loses information downstream -- an `int` field becomes a 64-bit integer in Parquet, Arrow, and Spark StructTypes, even when the domain is 0--255. The primitive types (`uint8`, `int32`, `float32`, etc.) carry range constraints and map to the correct wire type so data round-trips cleanly between Python, Parquet files, PostgreSQL, and JSON Schema: +Using `int` and `float` in a Pydantic model produces valid Python but loses information downstream -- an `int` field becomes a 64-bit integer in Parquet, Arrow, and Spark StructTypes, even when a single byte would hold every value. How wide a field needs to be is the schema author's choice, but `int` and `float` give Pydantic no way to record it. The numeric types (`uint8`, `int32`, `float32`, etc.) do: each declares a width that maps to the correct wire type in every serialization target, so a single portable declaration round-trips cleanly between Python, Parquet, Spark, and JSON Schema: ```python from pydantic import BaseModel -from overture.schema.system.primitive import uint8, float32 +from overture.schema.system.numeric import uint8, float32 class Building(BaseModel): height: float32 | None = None num_floors: uint8 | None = None ``` -Integer types: `uint8`, `uint16`, `uint32`, `int8`, `int16`, `int32`, `int64`. Float types: `float32`, `float64`. Geometry types: `Geometry`, `BBox`, `GeometryType`, `GeometryTypeConstraint`. +Integer types: `uint8`, `uint16`, `uint32`, `int8`, `int16`, `int32`, `int64`. Float types: `float32`, `float64`. + +## Geometric Types + +`Geometry` and `BBox` wrap Shapely and GeoJSON-compatible geometry and bounding box values so they can participate in a Pydantic model as fields, with `GeometryType` and `GeometryTypeConstraint` available to restrict a `Geometry` field to specific geometry types: + +```python +from overture.schema.system.geometric import Geometry, GeometryType, GeometryTypeConstraint +``` + +Types: `Geometry`, `BBox`, `GeometryType`, `GeometryTypeConstraint`. ## String Types diff --git a/packages/overture-schema-system/src/overture/schema/system/__init__.py b/packages/overture-schema-system/src/overture/schema/system/__init__.py index a491d860f..1a8c6e1dd 100644 --- a/packages/overture-schema-system/src/overture/schema/system/__init__.py +++ b/packages/overture-schema-system/src/overture/schema/system/__init__.py @@ -1,8 +1,8 @@ r""" Foundational types at the base of the Overture schema system. -A set of primitive types, constraint rules, and Pydantic model classes, and annotations that can be -used to create strongly-typed, predictably validated, data. +A set of numeric and geometric types, constraint rules, and Pydantic model classes, and annotations +that can be used to create strongly-typed, predictably validated, data. Subpackages ----------- @@ -13,15 +13,17 @@ - :mod:`field_constraint ` Constraints that can be annotated onto Pydantic model fields to force them to conform to well-known rules, for example "a collection that contains unique items" or "a string that is a valid country code". +- :mod:`geometric ` Geometric types, including `Geometry` and + `BBox`. - :mod:`json_schema ` Overture-flavored JSON Schema generation for Pydantic models. - :mod:`model_constraint ` Constraints that can be decorated onto Pydantic model classes to add cross-field validation rules, for example "these two fields are mutually-exclusive" or "if this field is set, then that field must also be set". +- :mod:`numeric ` Portable numeric types with specific bit widths, + for example `int32` and `float64`. - :mod:`optionality` ` The `Omitable` type hint, syntax sugar to help a Pydantic model's optional fields behave closer to JSON Schema semantics. -- :mod:`primitive ` Primitive data types, including numeric and - geometry types. - :mod:`ref ` Unique IDs and annotations to describe relationships between models based on unique IDs. (*i.e.*, foreign key relationships). - :mod:`string ` String types with built-in validation to conform to @@ -36,7 +38,7 @@ Parquet.) - Tightly integrated with Pydantic's JSON Schema system, providing rich JSON Schemas and maximum parity between Pydantic, generated JSON Schemas, and Overture's code generation tools. -- First-class support for geospatial data using the geometry primitives and the +- First-class support for geospatial data using the geometry types and the `overture.schema.system.feature.Feature` class. - Conditional fields and validation on relationships between fields (*e.g.*, if the type field contains "region", then region code field must also be set). @@ -49,7 +51,7 @@ rejects invalid input: >>> from pydantic import BaseModel, ValidationError ->>> from overture.schema.system.primitive import uint32; +>>> from overture.schema.system.numeric import uint32; >>> from overture.schema.system.string import SnakeCaseString; >>> class MyModel(BaseModel): ... index: uint32 @@ -63,7 +65,7 @@ Valid inputs to the same model are accepted: >>> from pydantic import BaseModel, ValidationError ->>> from overture.schema.system.primitive import uint32; +>>> from overture.schema.system.numeric import uint32; >>> from overture.schema.system.string import SnakeCaseString; >>> class MyModel(BaseModel): ... index: uint32 @@ -151,11 +153,12 @@ doc, feature, field_constraint, + geometric, json_schema, metadata, model_constraint, + numeric, optionality, - primitive, ref, string, ) @@ -166,11 +169,12 @@ "doc", "feature", "field_constraint", + "geometric", "json_schema", "metadata", "model_constraint", + "numeric", "optionality", - "primitive", "ref", "string", ] diff --git a/packages/overture-schema-system/src/overture/schema/system/feature.py b/packages/overture-schema-system/src/overture/schema/system/feature.py index 429582535..b3b2211ca 100644 --- a/packages/overture-schema-system/src/overture/schema/system/feature.py +++ b/packages/overture-schema-system/src/overture/schema/system/feature.py @@ -25,8 +25,8 @@ from typing_extensions import Self from overture.schema.system import _json_schema +from overture.schema.system.geometric import BBox, Geometry from overture.schema.system.optionality import Omitable -from overture.schema.system.primitive import BBox, Geometry from overture.schema.system.ref import Id @@ -70,7 +70,8 @@ class Feature(BaseModel): >>> from typing import Annotated >>> from pydantic import Field - >>> from overture.schema.system.primitive import Geometry, float32 + >>> from overture.schema.system.geometric import Geometry + >>> from overture.schema.system.numeric import float32 ... >>> class Mountain(Feature): ... name: str @@ -108,7 +109,7 @@ class Feature(BaseModel): This can help maximize validation and data integrity by preventing geometries that do not make sense from being stored. - >>> from overture.schema.system.primitive import GeometryType, GeometryTypeConstraint + >>> from overture.schema.system.geometric import GeometryType, GeometryTypeConstraint ... >>> class River(Feature): ... geometry: Annotated[ @@ -124,7 +125,7 @@ class Feature(BaseModel): union, use the `field_discriminator` method: >>> from typing import Annotated, Literal - >>> from overture.schema.system.primitive import float32 + >>> from overture.schema.system.numeric import float32 >>> import pydantic >>> >>> class Field(Feature): diff --git a/packages/overture-schema-system/src/overture/schema/system/geometric/__init__.py b/packages/overture-schema-system/src/overture/schema/system/geometric/__init__.py new file mode 100644 index 000000000..fd1ea6518 --- /dev/null +++ b/packages/overture-schema-system/src/overture/schema/system/geometric/__init__.py @@ -0,0 +1,25 @@ +""" +Geometric types. + +This module provides geometric types that can be used as fields in Pydantic models but are +not themselves models: `Geometry` for GeoJSON-compatible vector geometry, and `BBox` for bounding +boxes. + +These types have representations that can differ significantly between different serialization +targets, so they do not derive from the Pydantic `BaseModel` although they can participate in a +`BaseModel` as a field. +""" + +from .bbox import BBox +from .geom import ( + Geometry, + GeometryType, + GeometryTypeConstraint, +) + +__all__ = [ + "BBox", + "Geometry", + "GeometryType", + "GeometryTypeConstraint", +] diff --git a/packages/overture-schema-system/src/overture/schema/system/primitive/bbox.py b/packages/overture-schema-system/src/overture/schema/system/geometric/bbox.py similarity index 96% rename from packages/overture-schema-system/src/overture/schema/system/primitive/bbox.py rename to packages/overture-schema-system/src/overture/schema/system/geometric/bbox.py index c078290c5..5af086be9 100644 --- a/packages/overture-schema-system/src/overture/schema/system/primitive/bbox.py +++ b/packages/overture-schema-system/src/overture/schema/system/geometric/bbox.py @@ -1,5 +1,5 @@ """ -Bounding box primitive. +Bounding box type. """ from typing import Any @@ -15,11 +15,11 @@ class BBox: """ - Immutable 2D bounding box primitive. + Immutable 2D bounding box type. - This type is a geometric primitive with representations that can differ significantly between - different data formats. Consequently, does not derive from the Pydantic `BaseModel` although it - can participate in a `BaseModel` as a field. + Representations of this type can differ significantly between different data formats. + Consequently, it does not derive from the Pydantic `BaseModel` although it can participate in a + `BaseModel` as a field. Parameters ---------- diff --git a/packages/overture-schema-system/src/overture/schema/system/primitive/geom.py b/packages/overture-schema-system/src/overture/schema/system/geometric/geom.py similarity index 97% rename from packages/overture-schema-system/src/overture/schema/system/primitive/geom.py rename to packages/overture-schema-system/src/overture/schema/system/geometric/geom.py index 281abe59e..b543cbb6f 100644 --- a/packages/overture-schema-system/src/overture/schema/system/primitive/geom.py +++ b/packages/overture-schema-system/src/overture/schema/system/geometric/geom.py @@ -1,5 +1,5 @@ """ -Geometry primitive and geometry type constraint. +The `Geometry` value type and its geometry type constraint. Use `Geometry` as the type for fields containing geometry values. Use `GeometryTypeConstraint` if you need to constrain allowed types of geometries. @@ -10,7 +10,7 @@ >>> from typing import Annotated >>> from pydantic import BaseModel ->>> from overture.schema.system.primitive import float32 +>>> from overture.schema.system.numeric import float32 >>> class Peak(BaseModel): ... position: Annotated[ ... Geometry, @@ -210,11 +210,11 @@ def __get_pydantic_json_schema__( class Geometry: """ - Immutable vector geometry primitive. + Immutable vector geometry type. - This type is a geometric primitive with representations that can differ significantly between - different data formats. Consequently, does not derive from the Pydantic `BaseModel` although it - can participate in a `BaseModel` as a field. + Representations of this type can differ significantly between different data formats. + Consequently, it does not derive from the Pydantic `BaseModel` although it can participate in a + `BaseModel` as a field. Parameters ---------- @@ -407,7 +407,7 @@ def __get_pydantic_json_schema__( ######################################################################## -# JSON Schema primitives for GeoJSON geometry +# Base JSON Schema for GeoJSON geometry ######################################################################## # This is the `bbox` schema for a GeoJSON *geometry* object, not for a diff --git a/packages/overture-schema-system/src/overture/schema/system/primitive/__init__.py b/packages/overture-schema-system/src/overture/schema/system/numeric.py similarity index 77% rename from packages/overture-schema-system/src/overture/schema/system/primitive/__init__.py rename to packages/overture-schema-system/src/overture/schema/system/numeric.py index 2b27ef89e..ae53de77f 100644 --- a/packages/overture-schema-system/src/overture/schema/system/primitive/__init__.py +++ b/packages/overture-schema-system/src/overture/schema/system/numeric.py @@ -1,28 +1,22 @@ """ -Primitive data types. - -This module provides a set of primitive types that can be used as fields in Pydantic models but are -not themselves models. The primitive types include specific numeric types such as `int16` and -`float64`; and geometric types including `Geometry` and `BBox`. - -Primitives are intended to provide specific, well-defined behavior for a wide range of serialization -targets including not just Pydantic models and JSON, but also a range of other serialization -targets, for example, the Parquet format or Spark dataframes. They come with built-in Pydantic -constraints, but also specific documented behavior expectations so they can be supported by other -serialization targets. +Numeric types. + +This module provides a set of portable numeric types that can be used as fields in Pydantic models +but are not themselves models: unsigned and signed integers of specific bit widths, and 32- and +64-bit floating point numbers. + +These types are `int` or `float` at runtime, but using them for Pydantic model fields instead of the +bare Python types makes them portable across different serialization and validation targets, +including not just Pydantic models and JSON, but also a range of other serialization targets, for +example, the Parquet format or Spark dataframes. They come with built-in Pydantic constraints, but +also specific documented behavior expectations so they can be supported by other serialization +targets. """ from typing import Annotated, NewType from pydantic import Field -from .bbox import BBox -from .geom import ( - Geometry, - GeometryType, - GeometryTypeConstraint, -) - uint8 = NewType("uint8", Annotated[int, Field(ge=0, le=255)]) # type: ignore [type-arg] uint8.__doc__ = """ Portable 8-bit unsigned integer. @@ -97,16 +91,12 @@ __all__ = [ - "BBox", - "Geometry", - "GeometryType", - "GeometryTypeConstraint", + "float32", + "float64", "int8", "int16", "int32", "int64", - "float32", - "float64", "uint8", "uint16", "uint32", diff --git a/packages/overture-schema-system/src/overture/schema/system/string.py b/packages/overture-schema-system/src/overture/schema/system/string.py index 6533a192a..2de609445 100644 --- a/packages/overture-schema-system/src/overture/schema/system/string.py +++ b/packages/overture-schema-system/src/overture/schema/system/string.py @@ -5,9 +5,9 @@ Pydantic models to ensure the field values conform to well-known patterns, for example country codes, language tags, and color codes. -While not considered "primitives", the fundamental string types are intended to provide specific, -well-defined behavior for a wide range of serialization targets including not just Pydantic models -and JSON, but also including targets such as the Parquet data formats and Spark dataframes. +The fundamental string types are intended to provide specific, well-defined behavior for a wide +range of serialization targets including not just Pydantic models and JSON, but also including +targets such as the Parquet data formats and Spark dataframes. """ from typing import Annotated, NewType diff --git a/packages/overture-schema-system/tests/primitive/test_bbox.py b/packages/overture-schema-system/tests/geometric/test_bbox.py similarity index 99% rename from packages/overture-schema-system/tests/primitive/test_bbox.py rename to packages/overture-schema-system/tests/geometric/test_bbox.py index 31146720a..22e5d025a 100644 --- a/packages/overture-schema-system/tests/primitive/test_bbox.py +++ b/packages/overture-schema-system/tests/geometric/test_bbox.py @@ -4,7 +4,7 @@ import pytest from pydantic import BaseModel, ValidationError -from overture.schema.system.primitive.bbox import BBox +from overture.schema.system.geometric.bbox import BBox @pytest.mark.parametrize( diff --git a/packages/overture-schema-system/tests/primitive/test_geom.py b/packages/overture-schema-system/tests/geometric/test_geom.py similarity index 99% rename from packages/overture-schema-system/tests/primitive/test_geom.py rename to packages/overture-schema-system/tests/geometric/test_geom.py index 68dc5dd5b..b24c2de6c 100644 --- a/packages/overture-schema-system/tests/primitive/test_geom.py +++ b/packages/overture-schema-system/tests/geometric/test_geom.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, ValidationError from shapely import wkt -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-system/tests/test_feature.py b/packages/overture-schema-system/tests/test_feature.py index fc4a31751..008eedb5f 100644 --- a/packages/overture-schema-system/tests/test_feature.py +++ b/packages/overture-schema-system/tests/test_feature.py @@ -19,6 +19,12 @@ from util import assert_subset from overture.schema.system.feature import Feature, _FieldLevel, _maybe_refactor_schema +from overture.schema.system.geometric import ( + BBox, + Geometry, + GeometryType, + GeometryTypeConstraint, +) from overture.schema.system.model_constraint import ( FieldEqCondition, forbid_if, @@ -27,12 +33,6 @@ require_if, ) from overture.schema.system.optionality import Omitable -from overture.schema.system.primitive import ( - BBox, - Geometry, - GeometryType, - GeometryTypeConstraint, -) class TestFieldDiscriminator: diff --git a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/connector/models.py b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/connector/models.py index cb7d4e482..58964b628 100644 --- a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/connector/models.py +++ b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/connector/models.py @@ -7,7 +7,7 @@ from overture.schema.common import ( OvertureFeature, ) -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, diff --git a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/models.py b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/models.py index 260fd4574..fc7554930 100644 --- a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/models.py +++ b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/models.py @@ -15,7 +15,7 @@ no_extra_fields, require_any_of, ) -from overture.schema.system.primitive import float64, int32 +from overture.schema.system.numeric import float64, int32 from overture.schema.system.ref import Id, Reference, Relationship from overture.schema.system.string import StrippedString, WikidataId diff --git a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/segment/models.py b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/segment/models.py index 3643fd572..6a7ad9b5f 100644 --- a/packages/overture-schema-transportation-theme/src/overture/schema/transportation/segment/models.py +++ b/packages/overture-schema-transportation-theme/src/overture/schema/transportation/segment/models.py @@ -12,7 +12,7 @@ ) from overture.schema.system.feature import Feature from overture.schema.system.field_constraint import UniqueItemsConstraint -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint,