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 9b820b92f..49fbef878 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 2cc340c17..b1c35a241 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 d83cb7967..2ce59f61e 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 662d77fc5..6977d023a 100644 --- a/packages/overture-schema-codegen/docs/design.md +++ b/packages/overture-schema-codegen/docs/design.md @@ -220,7 +220,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_feature()` expands MODEL-kind fields inline with dot-notation (e.g., `sources[].dataset`), stopping at cycle boundaries. `format_type()` in `markdown/type_format.py` converts `TypeInfo` into link-aware display strings using diff --git a/packages/overture-schema-codegen/docs/walkthrough.md b/packages/overture-schema-codegen/docs/walkthrough.md index 397e082f5..0160f3d29 100644 --- a/packages/overture-schema-codegen/docs/walkthrough.md +++ b/packages/overture-schema-codegen/docs/walkthrough.md @@ -361,12 +361,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`. @@ -454,9 +455,9 @@ independent `if` statements, not `elif`. `build_placement_registry` builds the complete mapping from type names to output file paths. Three 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/geometry.md`. These are hardcoded paths since the types share a single reference page. Feature specs get individual pages. Output directories derive from @@ -538,7 +539,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 `geometry.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 @@ -580,7 +581,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 @@ -636,8 +637,8 @@ Eight steps: 1. **Expand model trees** with a shared cache across all features, so sub-models referenced by multiple features extract once. -2. **Partition primitive and geometry names** from the system primitive module's - `__all__` exports. +2. **Partition numeric and geometry names** from the system numeric and geometric + modules' `__all__` exports. 3. **Collect supplementary types** by walking expanded feature trees. @@ -650,7 +651,7 @@ Eight steps: 7. **Render each supplementary type** -- dispatching to `render_enum`, `render_newtype`, or `render_feature` (for sub-models) based on spec type. -8. **Render aggregate pages** for primitives and geometry. +8. **Render aggregate pages** for numeric types and geometry. The return value is `list[RenderedPage]` -- frozen dataclasses carrying content, output path, and a boolean `is_feature` flag. The caller decides what to do with them. @@ -713,7 +714,8 @@ two NewType layers and an `Annotated` layer, producing a `TypeInfo` with `FieldSpec.model` references. The shared cache ensures sub-models referenced by multiple features (like `Sources`) extract once. Union-kind fields skip inline expansion. -**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 expanded fields and discovers referenced enums (like `Subtype`), semantic NewTypes (like `Id`, `Sources`), and sub-models. The walk follows `FieldSpec.model` references down the tree, and for 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 0db927065..6b12d98b4 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 @@ -11,7 +11,7 @@ from annotated_types import Ge, Gt, Interval, Le, Lt, MaxLen, MinLen -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 f0d224ee4..34a931141 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,14 +18,14 @@ __all__ = [ "GEOMETRY_PAGE", - "PRIMITIVES_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") +GEOMETRY_PAGE = PurePosixPath("system/geometry.md") def build_placement_registry( @@ -86,7 +86,7 @@ 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)) 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 f7c676c06..75d8bf60d 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.model_extraction import expand_model_tree @@ -31,7 +32,7 @@ from .link_computation import LinkContext from .path_assignment import ( GEOMETRY_PAGE, - PRIMITIVES_PAGE, + NUMERIC_PAGE, build_placement_registry, resolve_output_path, ) @@ -40,7 +41,7 @@ render_feature, render_geometry_from_values, render_newtype, - render_primitives_from_specs, + render_numeric_from_specs, render_pydantic_type, ) from .reverse_references import UsedByEntry, compute_reverse_references @@ -112,22 +113,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 @@ -148,7 +151,7 @@ def generate_markdown_pages( expand_model_tree(spec, cache) numeric_names, geometry_names = partition_numeric_and_geometry_types( - _system_primitive + _system_numeric, _system_geometric ) all_specs = collect_all_supplementary_types(feature_specs) registry = build_placement_registry( @@ -172,8 +175,8 @@ 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, ) ) 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 0e829d1f4..bf16ef816 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 @@ -44,7 +44,7 @@ "render_feature", "render_geometry_from_values", "render_newtype", - "render_primitives_from_specs", + "render_numeric_from_specs", "render_pydantic_type", ] @@ -521,7 +521,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 @@ -586,9 +586,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]] = [] 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/tests/codegen_test_support.py b/packages/overture-schema-codegen/tests/codegen_test_support.py index 2a18faf13..2adcb7193 100644 --- a/packages/overture-schema-codegen/tests/codegen_test_support.py +++ b/packages/overture-schema-codegen/tests/codegen_test_support.py @@ -33,14 +33,13 @@ 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.model_constraint import require_any_of -from overture.schema.system.primitive import ( +from overture.schema.system.geometric import ( Geometry, GeometryType, GeometryTypeConstraint, - float64, - int32, ) +from overture.schema.system.model_constraint import require_any_of +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 d66cf72a3..dc4646f13 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,10 +71,12 @@ 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") diff --git a/packages/overture-schema-codegen/tests/test_constraint_description.py b/packages/overture-schema-codegen/tests/test_constraint_description.py index b205f6f73..7929a1ff1 100644 --- a/packages/overture-schema-codegen/tests/test_constraint_description.py +++ b/packages/overture-schema-codegen/tests/test_constraint_description.py @@ -10,6 +10,7 @@ ) from overture.schema.codegen.extraction.specs import TypeIdentity from overture.schema.codegen.extraction.type_analyzer import ConstraintSource +from overture.schema.system.geometric import GeometryType, GeometryTypeConstraint from overture.schema.system.model_constraint import ( FieldEqCondition, ForbidIfConstraint, @@ -22,7 +23,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 1f94bc06d..a0cb89309 100644 --- a/packages/overture-schema-codegen/tests/test_example_loader.py +++ b/packages/overture-schema-codegen/tests/test_example_loader.py @@ -889,7 +889,7 @@ class Aliased(BaseModel): def test_slots_based_field_flattened(self) -> None: """Non-BaseModel types with __slots__ and properties are flattened.""" - from overture.schema.system.primitive import BBox # noqa: PLC0415 + from overture.schema.system.geometric import BBox # noqa: PLC0415 class WithBBox(BaseModel): id: str @@ -907,7 +907,7 @@ class WithBBox(BaseModel): def test_none_slots_based_field_is_leaf(self) -> None: """A slots-based field with None value is a leaf.""" - from overture.schema.system.primitive import BBox # noqa: PLC0415 + from overture.schema.system.geometric import BBox # noqa: PLC0415 class WithBBox(BaseModel): id: str @@ -919,7 +919,7 @@ class WithBBox(BaseModel): def test_single_slot_wrapper_is_leaf(self) -> None: """Single-slot types (wrappers like Geometry) are leaf values.""" - from overture.schema.system.primitive import Geometry # noqa: PLC0415 + from overture.schema.system.geometric import Geometry # noqa: PLC0415 from shapely.geometry import Point # noqa: PLC0415 class WithGeom(BaseModel): diff --git a/packages/overture-schema-codegen/tests/test_markdown_renderer.py b/packages/overture-schema-codegen/tests/test_markdown_renderer.py index 698f9d70a..7b2c6477a 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_renderer.py +++ b/packages/overture-schema-codegen/tests/test_markdown_renderer.py @@ -47,7 +47,7 @@ render_enum, render_feature, render_newtype, - render_primitives_from_specs, + render_numeric_from_specs, render_pydantic_type, ) from overture.schema.codegen.markdown.reverse_references import UsedByEntry, UsedByKind @@ -57,7 +57,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 @@ -1122,50 +1122,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", @@ -1173,7 +1173,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 e54426f5f..7f57245c7 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_type_format.py +++ b/packages/overture-schema-codegen/tests/test_markdown_type_format.py @@ -16,7 +16,7 @@ format_type, format_underlying_type, ) -from overture.schema.system.primitive import int32 +from overture.schema.system.numeric import int32 from pydantic import BaseModel, HttpUrl @@ -222,20 +222,16 @@ 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.""" ti = analyze_type(int32) field = _make_field(ti) 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(field, ctx) assert "[`int32`]" in result - assert "system/primitive/primitives.md" in result + assert "system/numeric.md" in result class TestListOfSemanticNewtype: diff --git a/packages/overture-schema-codegen/tests/test_model_extractor.py b/packages/overture-schema-codegen/tests/test_model_extractor.py index f2b2bd257..4c3a2ecb4 100644 --- a/packages/overture-schema-codegen/tests/test_model_extractor.py +++ b/packages/overture-schema-codegen/tests/test_model_extractor.py @@ -18,17 +18,17 @@ ) from overture.schema.codegen.extraction.specs import ModelSpec 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 ee604ba75..1d07db640 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_specs.py b/packages/overture-schema-codegen/tests/test_specs.py index 0780e2fda..30356b46d 100644 --- a/packages/overture-schema-codegen/tests/test_specs.py +++ b/packages/overture-schema-codegen/tests/test_specs.py @@ -283,7 +283,7 @@ def test_enum_spec_identity(self) -> None: assert ident.name == "Color" def test_newtype_spec_identity(self) -> None: - from overture.schema.system.primitive import int32 + from overture.schema.system.numeric import int32 spec = NewTypeSpec( name="int32", description=None, type_info=STR_TYPE, source_type=int32 diff --git a/packages/overture-schema-codegen/tests/test_type_analyzer.py b/packages/overture-schema-codegen/tests/test_type_analyzer.py index bbf8373fd..f1aeafca6 100644 --- a/packages/overture-schema-codegen/tests/test_type_analyzer.py +++ b/packages/overture-schema-codegen/tests/test_type_analyzer.py @@ -12,7 +12,7 @@ analyze_type, single_literal_value, ) -from overture.schema.system.primitive import float64, int32 +from overture.schema.system.numeric import float64, 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_placement.py b/packages/overture-schema-codegen/tests/test_type_placement.py index 63e26457c..500462883 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, @@ -26,7 +27,7 @@ from overture.schema.codegen.markdown.link_computation import LinkContext, relative_link from overture.schema.codegen.markdown.path_assignment import ( GEOMETRY_PAGE, - PRIMITIVES_PAGE, + NUMERIC_PAGE, build_placement_registry, ) from overture.schema.codegen.markdown.pipeline import ( @@ -35,7 +36,7 @@ from pydantic import BaseModel _NUMERIC_NAMES, _GEOMETRY_NAMES = partition_numeric_and_geometry_types( - _system_primitive + _system_numeric, _system_geometric ) _SCHEMA_ROOT = "overture.schema" @@ -75,8 +76,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: @@ -109,18 +110,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/geometry.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 GEOMETRY_PAGE == PurePosixPath("system/geometry.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 dbb77a281..479f98b2f 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 8f89d790f..e0a928ce8 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 801d35aa3..408abcec3 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, uint8 +from overture.schema.system.numeric import float64, uint8 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-system/README.md b/packages/overture-schema-system/README.md index 9733d105f..74eb6da22 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 the domain is 0--255. The numeric 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: ```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 26ebf5085..24682f3c4 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 descrie 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 82715014f..fae33806b 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 0d2685df9..fd7709556 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,