From 896a4d45161aac61f41d694f1c2579a797ecc8d2 Mon Sep 17 00:00:00 2001 From: Seth Fitzsimmons Date: Tue, 28 Jul 2026 14:51:11 -0700 Subject: [PATCH 1/4] refactor(build): migrate all packages from hatchling to uv_build Switch every workspace package's build backend to uv_build. Because the packages share the overture.schema namespace, each declares an explicit [tool.uv.build-backend] module-name (e.g. overture.schema.common); name normalization would derive the wrong module. The overture-schema aggregator uses module-name = "overture.schema" with namespace = true and ships only overture/schema/py.typed -- uv_build requires a module root, so a deps-only package still owns the namespace marker. Convert the pkgutil namespaces to PEP 420: uv_build ships shared namespaces implicitly and never packages an overture/__init__.py, so the extend_path shims are removed. Wheels and editable installs both merge the namespace natively. Deleting those __init__.py files removes the signal ruff's isort uses to detect overture as first-party (detect-same-package walks __init__ chains), so add src = ["packages/*/src"]. With overture now first-party everywhere, imports across the test suite and a few pyspark modules recanonicalize into their own group; that reformat is folded in here because it cannot land as a separately-green commit. Signed-off-by: Seth Fitzsimmons --- .../pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../test_address_json_schema_baseline.py | 1 + .../overture-schema-base-theme/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../test_bathymetry_json_schema_baseline.py | 1 + ...est_infrastructure_json_schema_baseline.py | 1 + .../test_land_cover_json_schema_baseline.py | 1 + .../tests/test_land_json_schema_baseline.py | 1 + .../test_land_use_json_schema_baseline.py | 1 + .../tests/test_water_json_schema_baseline.py | 1 + .../pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../test_building_json_schema_baseline.py | 1 + ...test_building_part_json_schema_baseline.py | 1 + packages/overture-schema-cli/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../tests/test_cli_commands.py | 1 + .../tests/test_cli_functions.py | 3 ++- .../tests/test_data_display.py | 5 ++-- .../tests/test_error_formatting.py | 5 ++-- .../tests/test_heterogeneous_collections.py | 1 + .../tests/test_resolve_types.py | 1 + .../tests/test_type_analysis.py | 3 ++- .../overture-schema-codegen/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../tests/codegen_test_support.py | 3 ++- .../overture-schema-codegen/tests/conftest.py | 7 +++--- .../overture-schema-codegen/tests/test_cli.py | 1 + .../tests/test_constraint_description.py | 1 + .../tests/test_enum_extraction.py | 1 + .../tests/test_example_loader.py | 5 ++-- .../tests/test_field_walk.py | 1 + .../tests/test_golden_markdown.py | 3 ++- .../tests/test_integration_real_models.py | 3 ++- .../tests/test_markdown_renderer.py | 3 ++- .../tests/test_markdown_type_format.py | 3 ++- .../tests/test_model_extraction.py | 3 ++- .../tests/test_model_extractor.py | 3 ++- .../tests/test_module_layout.py | 1 + .../tests/test_newtype_extraction.py | 3 ++- .../tests/test_numeric_extraction.py | 3 ++- .../tests/test_pydantic_extraction.py | 3 ++- .../tests/test_pyspark_base_row.py | 3 ++- .../tests/test_pyspark_check_builder.py | 7 +++--- .../tests/test_pyspark_constraint_dispatch.py | 3 ++- .../tests/test_pyspark_constraint_values.py | 1 + .../tests/test_pyspark_e2e.py | 3 ++- .../tests/test_pyspark_invalid_value.py | 1 + .../tests/test_pyspark_pipeline.py | 3 ++- .../tests/test_pyspark_renderer.py | 5 ++-- .../tests/test_pyspark_scaffold.py | 3 ++- .../tests/test_pyspark_schema_builder.py | 3 ++- .../tests/test_pyspark_test_renderer.py | 3 ++- .../tests/test_reverse_references.py | 3 ++- .../tests/test_specs.py | 3 ++- .../tests/test_type_analyzer.py | 5 ++-- .../tests/test_type_collection.py | 3 ++- .../tests/test_type_placement.py | 7 +++--- .../tests/test_union_extraction.py | 5 ++-- .../overture-schema-common/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../tests/scoping/test_scoped.py | 7 +++--- .../tests/test_common_tag_providers.py | 3 ++- .../tests/test_models.py | 5 ++-- .../tests/test_numeric_types.py | 3 ++- .../pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - ...test_division_area_json_schema_baseline.py | 1 + ..._division_boundary_json_schema_baseline.py | 1 + .../test_division_json_schema_baseline.py | 1 + .../pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../tests/test_place_json_schema_baseline.py | 1 + .../overture-schema-pyspark/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../src/overture/schema/pyspark/check.py | 3 +-- .../src/overture/schema/pyspark/cli.py | 4 ++-- .../expressions/constraint_expressions.py | 3 +-- .../src/overture/schema/pyspark/validate.py | 7 +++--- .../tests/_support/harness.py | 5 ++-- .../tests/_support/registry.py | 3 ++- .../tests/expressions/test_column_patterns.py | 5 ++-- .../test_constraint_expressions.py | 7 +++--- .../tests/expressions/test_schema_check.py | 9 ++++---- .../tests/test_check.py | 3 ++- .../overture-schema-pyspark/tests/test_cli.py | 9 ++++---- .../tests/test_harness.py | 3 ++- .../tests/test_validate.py | 23 ++++++++++--------- .../overture-schema-system/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../test_connector_json_schema_baseline.py | 1 + .../test_segment_json_schema_baseline.py | 1 + .../overture-schema-validation/pyproject.toml | 8 +++---- .../src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - .../tests/test_schema_validation.py | 3 ++- packages/overture-schema/pyproject.toml | 9 ++++---- .../overture-schema/src/overture/__init__.py | 1 - .../src/overture/schema/__init__.py | 1 - pyproject.toml | 4 ++++ 114 files changed, 214 insertions(+), 168 deletions(-) delete mode 100644 packages/overture-schema-addresses-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-addresses-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-base-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-base-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-buildings-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-buildings-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-cli/src/overture/__init__.py delete mode 100644 packages/overture-schema-cli/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-codegen/src/overture/__init__.py delete mode 100644 packages/overture-schema-codegen/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-common/src/overture/__init__.py delete mode 100644 packages/overture-schema-common/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-divisions-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-divisions-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-places-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-places-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-pyspark/src/overture/__init__.py delete mode 100644 packages/overture-schema-pyspark/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-system/src/overture/__init__.py delete mode 100644 packages/overture-schema-system/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-transportation-theme/src/overture/__init__.py delete mode 100644 packages/overture-schema-transportation-theme/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema-validation/src/overture/__init__.py delete mode 100644 packages/overture-schema-validation/src/overture/schema/__init__.py delete mode 100644 packages/overture-schema/src/overture/__init__.py delete mode 100644 packages/overture-schema/src/overture/schema/__init__.py diff --git a/packages/overture-schema-addresses-theme/pyproject.toml b/packages/overture-schema-addresses-theme/pyproject.toml index 7cb105b5e..6e0fa74fc 100644 --- a/packages/overture-schema-addresses-theme/pyproject.toml +++ b/packages/overture-schema-addresses-theme/pyproject.toml @@ -25,11 +25,11 @@ overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.addresses" [tool.pytest.ini_options] pythonpath = ["src"] diff --git a/packages/overture-schema-addresses-theme/src/overture/__init__.py b/packages/overture-schema-addresses-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-addresses-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-addresses-theme/src/overture/schema/__init__.py b/packages/overture-schema-addresses-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-addresses-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-addresses-theme/tests/test_address_json_schema_baseline.py b/packages/overture-schema-addresses-theme/tests/test_address_json_schema_baseline.py index a49ddc2f7..7587e6fe7 100644 --- a/packages/overture-schema-addresses-theme/tests/test_address_json_schema_baseline.py +++ b/packages/overture-schema-addresses-theme/tests/test_address_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.addresses import Address from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/pyproject.toml b/packages/overture-schema-base-theme/pyproject.toml index 38662bafa..585e429c4 100644 --- a/packages/overture-schema-base-theme/pyproject.toml +++ b/packages/overture-schema-base-theme/pyproject.toml @@ -25,11 +25,11 @@ overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.base" [project.entry-points."overture.models"] bathymetry = "overture.schema.base:Bathymetry" diff --git a/packages/overture-schema-base-theme/src/overture/__init__.py b/packages/overture-schema-base-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-base-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-base-theme/src/overture/schema/__init__.py b/packages/overture-schema-base-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-base-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-base-theme/tests/test_bathymetry_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_bathymetry_json_schema_baseline.py index c2f1347fd..9e15e6fbe 100644 --- a/packages/overture-schema-base-theme/tests/test_bathymetry_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_bathymetry_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import Bathymetry from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/tests/test_infrastructure_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_infrastructure_json_schema_baseline.py index 91c83a336..c6e821426 100644 --- a/packages/overture-schema-base-theme/tests/test_infrastructure_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_infrastructure_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import Infrastructure from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/tests/test_land_cover_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_land_cover_json_schema_baseline.py index 5ac478991..da90a858f 100644 --- a/packages/overture-schema-base-theme/tests/test_land_cover_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_land_cover_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import LandCover from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/tests/test_land_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_land_json_schema_baseline.py index b6bc8e487..d7479b058 100644 --- a/packages/overture-schema-base-theme/tests/test_land_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_land_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import Land from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/tests/test_land_use_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_land_use_json_schema_baseline.py index 2ab678cf0..0542ef06e 100644 --- a/packages/overture-schema-base-theme/tests/test_land_use_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_land_use_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import LandUse from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-base-theme/tests/test_water_json_schema_baseline.py b/packages/overture-schema-base-theme/tests/test_water_json_schema_baseline.py index aa08406fa..a91a32bdc 100644 --- a/packages/overture-schema-base-theme/tests/test_water_json_schema_baseline.py +++ b/packages/overture-schema-base-theme/tests/test_water_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.base import Water from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-buildings-theme/pyproject.toml b/packages/overture-schema-buildings-theme/pyproject.toml index 0cbb9f172..5350459af 100644 --- a/packages/overture-schema-buildings-theme/pyproject.toml +++ b/packages/overture-schema-buildings-theme/pyproject.toml @@ -25,11 +25,11 @@ overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.buildings" [project.entry-points."overture.models"] building = "overture.schema.buildings:Building" diff --git a/packages/overture-schema-buildings-theme/src/overture/__init__.py b/packages/overture-schema-buildings-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-buildings-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-buildings-theme/src/overture/schema/__init__.py b/packages/overture-schema-buildings-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-buildings-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-buildings-theme/tests/test_building_json_schema_baseline.py b/packages/overture-schema-buildings-theme/tests/test_building_json_schema_baseline.py index 8c30bfbcc..67f5a7f42 100644 --- a/packages/overture-schema-buildings-theme/tests/test_building_json_schema_baseline.py +++ b/packages/overture-schema-buildings-theme/tests/test_building_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.buildings.building import Building from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-buildings-theme/tests/test_building_part_json_schema_baseline.py b/packages/overture-schema-buildings-theme/tests/test_building_part_json_schema_baseline.py index 11b3ef530..9b5d64dad 100644 --- a/packages/overture-schema-buildings-theme/tests/test_building_part_json_schema_baseline.py +++ b/packages/overture-schema-buildings-theme/tests/test_building_part_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.buildings.building_part import BuildingPart from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-cli/pyproject.toml b/packages/overture-schema-cli/pyproject.toml index 45b16434f..c2d7e9b64 100644 --- a/packages/overture-schema-cli/pyproject.toml +++ b/packages/overture-schema-cli/pyproject.toml @@ -28,8 +28,8 @@ overture-schema-common = { workspace = true } overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [dependency-groups] dev = [ @@ -38,8 +38,8 @@ dev = [ "mypy>=1.17.0", ] -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.cli" [project.scripts] overture-schema = "overture.schema.cli:cli" diff --git a/packages/overture-schema-cli/src/overture/__init__.py b/packages/overture-schema-cli/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-cli/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-cli/src/overture/schema/__init__.py b/packages/overture-schema-cli/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-cli/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-cli/tests/test_cli_commands.py b/packages/overture-schema-cli/tests/test_cli_commands.py index 3abc8d3a0..9fb088c7d 100644 --- a/packages/overture-schema-cli/tests/test_cli_commands.py +++ b/packages/overture-schema-cli/tests/test_cli_commands.py @@ -6,6 +6,7 @@ import pytest from click.testing import CliRunner from conftest import build_feature + from overture.schema.cli.commands import cli diff --git a/packages/overture-schema-cli/tests/test_cli_functions.py b/packages/overture-schema-cli/tests/test_cli_functions.py index 601e6f3b6..59ab95d24 100644 --- a/packages/overture-schema-cli/tests/test_cli_functions.py +++ b/packages/overture-schema-cli/tests/test_cli_functions.py @@ -9,6 +9,8 @@ import yaml from click.exceptions import UsageError from conftest import build_feature +from pydantic import BaseModel, ValidationError + from overture.schema.cli.commands import ( _best_fit_model, _revalidate_undiscriminatable_items, @@ -19,7 +21,6 @@ from overture.schema.cli.type_analysis import get_item_index from overture.schema.cli.types import ValidationErrorDict from overture.schema.system.discovery import TagSelector -from pydantic import BaseModel, ValidationError class TestLoadInput: diff --git a/packages/overture-schema-cli/tests/test_data_display.py b/packages/overture-schema-cli/tests/test_data_display.py index 218872cbc..69dcbf08c 100644 --- a/packages/overture-schema-cli/tests/test_data_display.py +++ b/packages/overture-schema-cli/tests/test_data_display.py @@ -3,14 +3,15 @@ from io import StringIO from conftest import build_feature +from rich.console import Console +from rich.panel import Panel + from overture.schema.cli.data_display import ( create_feature_display, extract_feature_data, format_field_value, select_context_fields, ) -from rich.console import Console -from rich.panel import Panel class TestExtractFeatureData: diff --git a/packages/overture-schema-cli/tests/test_error_formatting.py b/packages/overture-schema-cli/tests/test_error_formatting.py index b87aa0f15..949d11305 100644 --- a/packages/overture-schema-cli/tests/test_error_formatting.py +++ b/packages/overture-schema-cli/tests/test_error_formatting.py @@ -6,6 +6,9 @@ import pytest from click.testing import CliRunner +from pydantic import BaseModel, Field, TypeAdapter, ValidationError +from rich.console import Console + from overture.schema.cli.commands import cli from overture.schema.cli.error_formatting import ( format_path, @@ -14,8 +17,6 @@ ) from overture.schema.cli.type_analysis import introspect_union from overture.schema.cli.types import ErrorLocation, ValidationErrorDict -from pydantic import BaseModel, Field, TypeAdapter, ValidationError -from rich.console import Console class TestErrorGrouping: diff --git a/packages/overture-schema-cli/tests/test_heterogeneous_collections.py b/packages/overture-schema-cli/tests/test_heterogeneous_collections.py index e3c9d93d8..9c073c25e 100644 --- a/packages/overture-schema-cli/tests/test_heterogeneous_collections.py +++ b/packages/overture-schema-cli/tests/test_heterogeneous_collections.py @@ -6,6 +6,7 @@ import pytest from click.testing import CliRunner from conftest import build_feature + from overture.schema.cli.commands import cli diff --git a/packages/overture-schema-cli/tests/test_resolve_types.py b/packages/overture-schema-cli/tests/test_resolve_types.py index 55acfd762..370d83635 100644 --- a/packages/overture-schema-cli/tests/test_resolve_types.py +++ b/packages/overture-schema-cli/tests/test_resolve_types.py @@ -9,6 +9,7 @@ from unittest.mock import patch import pytest + from overture.schema.cli.commands import resolve_types from overture.schema.system.discovery import ModelKey, TagSelector diff --git a/packages/overture-schema-cli/tests/test_type_analysis.py b/packages/overture-schema-cli/tests/test_type_analysis.py index d6e9d930b..321af8b30 100644 --- a/packages/overture-schema-cli/tests/test_type_analysis.py +++ b/packages/overture-schema-cli/tests/test_type_analysis.py @@ -3,6 +3,8 @@ from typing import Annotated, Literal import pytest +from pydantic import BaseModel, Discriminator, Field + from overture.schema.cli.type_analysis import ( StructuralTuple, create_structural_tuple, @@ -10,7 +12,6 @@ get_or_create_structural_tuple, introspect_union, ) -from pydantic import BaseModel, Discriminator, Field class TestStructuralTuples: diff --git a/packages/overture-schema-codegen/pyproject.toml b/packages/overture-schema-codegen/pyproject.toml index dc3c09445..b6a77a72a 100644 --- a/packages/overture-schema-codegen/pyproject.toml +++ b/packages/overture-schema-codegen/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [project] dependencies = [ @@ -42,5 +42,5 @@ test = [ "overture-schema-transportation-theme", ] -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.codegen" diff --git a/packages/overture-schema-codegen/src/overture/__init__.py b/packages/overture-schema-codegen/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-codegen/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-codegen/src/overture/schema/__init__.py b/packages/overture-schema-codegen/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-codegen/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-codegen/tests/codegen_test_support.py b/packages/overture-schema-codegen/tests/codegen_test_support.py index 19da210a5..d78692478 100644 --- a/packages/overture-schema-codegen/tests/codegen_test_support.py +++ b/packages/overture-schema-codegen/tests/codegen_test_support.py @@ -13,6 +13,8 @@ import pytest from annotated_types import MinLen +from pydantic import BaseModel, EmailStr, Field, HttpUrl, RootModel + from overture.schema.codegen.extraction.field import LiteralScalar, Primitive from overture.schema.codegen.extraction.field_walk import terminal_of from overture.schema.codegen.extraction.model_extraction import extract_model @@ -55,7 +57,6 @@ 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, RootModel STR_TYPE = Primitive(base_type="str") diff --git a/packages/overture-schema-codegen/tests/conftest.py b/packages/overture-schema-codegen/tests/conftest.py index db4ccde63..9f03b5c0c 100644 --- a/packages/overture-schema-codegen/tests/conftest.py +++ b/packages/overture-schema-codegen/tests/conftest.py @@ -1,10 +1,12 @@ """Shared pytest fixtures for overture-schema-codegen tests.""" -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 +from pydantic import BaseModel + +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.numeric_extraction import extract_numerics from overture.schema.codegen.extraction.specs import RecordSpec @@ -17,7 +19,6 @@ ) from overture.schema.system.discovery import discover_models from overture.schema.system.geometric import GeometryType -from pydantic import BaseModel def pytest_addoption(parser: pytest.Parser) -> None: diff --git a/packages/overture-schema-codegen/tests/test_cli.py b/packages/overture-schema-codegen/tests/test_cli.py index 07120d132..d37b6c45b 100644 --- a/packages/overture-schema-codegen/tests/test_cli.py +++ b/packages/overture-schema-codegen/tests/test_cli.py @@ -6,6 +6,7 @@ import pytest from click.testing import CliRunner + from overture.schema.codegen.cli import cli from overture.schema.codegen.extraction.specs import RecordSpec diff --git a/packages/overture-schema-codegen/tests/test_constraint_description.py b/packages/overture-schema-codegen/tests/test_constraint_description.py index a9af9fc4e..663642d72 100644 --- a/packages/overture-schema-codegen/tests/test_constraint_description.py +++ b/packages/overture-schema-codegen/tests/test_constraint_description.py @@ -3,6 +3,7 @@ import re from annotated_types import Ge, Gt, Interval, Le, Lt, MultipleOf + from overture.schema.codegen.extraction.field_constraints import ( constraint_display_text, describe_field_constraint, diff --git a/packages/overture-schema-codegen/tests/test_enum_extraction.py b/packages/overture-schema-codegen/tests/test_enum_extraction.py index 2e5367e3b..370ccccba 100644 --- a/packages/overture-schema-codegen/tests/test_enum_extraction.py +++ b/packages/overture-schema-codegen/tests/test_enum_extraction.py @@ -3,6 +3,7 @@ from enum import Enum from codegen_test_support import find_member + from overture.schema.codegen.extraction.enum_extraction import extract_enum from overture.schema.codegen.extraction.specs import EnumMemberSpec, EnumSpec from overture.schema.system.doc import DocumentedEnum diff --git a/packages/overture-schema-codegen/tests/test_example_loader.py b/packages/overture-schema-codegen/tests/test_example_loader.py index 039bead9b..9d5249f08 100644 --- a/packages/overture-schema-codegen/tests/test_example_loader.py +++ b/packages/overture-schema-codegen/tests/test_example_loader.py @@ -9,6 +9,9 @@ from typing import Annotated, Literal import pytest +from pydantic import BaseModel, ConfigDict, Field, Tag, ValidationError +from shapely.geometry import Point + from overture.schema.buildings.building import Building from overture.schema.codegen.extraction.examples import ( ExampleRecord, @@ -27,8 +30,6 @@ RoadSegment, TransportationSegment, ) -from pydantic import BaseModel, ConfigDict, Field, Tag, ValidationError -from shapely.geometry import Point class TestOrderExampleRows: diff --git a/packages/overture-schema-codegen/tests/test_field_walk.py b/packages/overture-schema-codegen/tests/test_field_walk.py index 3cdb08048..f7d68519c 100644 --- a/packages/overture-schema-codegen/tests/test_field_walk.py +++ b/packages/overture-schema-codegen/tests/test_field_walk.py @@ -3,6 +3,7 @@ import enum import pytest + from overture.schema.codegen.extraction.field import ( AnyScalar, ArrayOf, diff --git a/packages/overture-schema-codegen/tests/test_golden_markdown.py b/packages/overture-schema-codegen/tests/test_golden_markdown.py index cffdc2def..0b4d432a4 100644 --- a/packages/overture-schema-codegen/tests/test_golden_markdown.py +++ b/packages/overture-schema-codegen/tests/test_golden_markdown.py @@ -20,6 +20,8 @@ assert_golden, spec_for_model, ) +from pydantic import BaseModel + from overture.schema.codegen.extraction.enum_extraction import extract_enum from overture.schema.codegen.extraction.newtype_extraction import extract_newtype from overture.schema.codegen.extraction.specs import ModelSpec, TypeIdentity @@ -35,7 +37,6 @@ UsedByEntry, compute_reverse_references, ) -from pydantic import BaseModel GOLDEN_DIR = Path(__file__).parent / "golden" / "markdown" diff --git a/packages/overture-schema-codegen/tests/test_integration_real_models.py b/packages/overture-schema-codegen/tests/test_integration_real_models.py index a78ae6af5..a541bc899 100644 --- a/packages/overture-schema-codegen/tests/test_integration_real_models.py +++ b/packages/overture-schema-codegen/tests/test_integration_real_models.py @@ -6,6 +6,8 @@ import pytest from codegen_test_support import assert_literal_field, spec_for_model +from pydantic import BaseModel + from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.specs import ( ModelSpec, @@ -19,7 +21,6 @@ from overture.schema.codegen.spec_discovery import extract_model_spec from overture.schema.system.discovery import discover_models from overture.schema.transportation import RoadSegment, Segment -from pydantic import BaseModel class TestDiscoverModels: diff --git a/packages/overture-schema-codegen/tests/test_markdown_renderer.py b/packages/overture-schema-codegen/tests/test_markdown_renderer.py index 76f527fb8..3c929f289 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_renderer.py +++ b/packages/overture-schema-codegen/tests/test_markdown_renderer.py @@ -24,6 +24,8 @@ make_union_spec, spec_for_model, ) +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.examples import ExampleRecord from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.newtype_extraction import extract_newtype @@ -58,7 +60,6 @@ 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 _FLAT_MEMBER = EnumMemberSpec(name="FLAT", value="flat", description=None) 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 9e4597133..a5fef43ca 100644 --- a/packages/overture-schema-codegen/tests/test_markdown_type_format.py +++ b/packages/overture-schema-codegen/tests/test_markdown_type_format.py @@ -5,6 +5,8 @@ from typing import Any, Literal, NewType import pytest +from pydantic import BaseModel, HttpUrl + from overture.schema.codegen.extraction.field import ( AnyScalar, ArrayOf, @@ -27,7 +29,6 @@ ) from overture.schema.system.geometric import BBox, Geometry from overture.schema.system.numeric import int32 -from pydantic import BaseModel, HttpUrl class _ModelA(BaseModel): diff --git a/packages/overture-schema-codegen/tests/test_model_extraction.py b/packages/overture-schema-codegen/tests/test_model_extraction.py index e9b23a3ba..e8b3fd2c7 100644 --- a/packages/overture-schema-codegen/tests/test_model_extraction.py +++ b/packages/overture-schema-codegen/tests/test_model_extraction.py @@ -3,6 +3,8 @@ from typing import Annotated, Optional from codegen_test_support import FeatureWithRootModel +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.field import ( ArrayOf, MapOf, @@ -14,7 +16,6 @@ from overture.schema.codegen.extraction.length_constraints import ArrayMinLen from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.common.scoping.vehicle import VehicleSelector -from pydantic import BaseModel, Field def test_extract_model_populates_union_terminal() -> None: diff --git a/packages/overture-schema-codegen/tests/test_model_extractor.py b/packages/overture-schema-codegen/tests/test_model_extractor.py index 6356d30d3..f52d9f0ca 100644 --- a/packages/overture-schema-codegen/tests/test_model_extractor.py +++ b/packages/overture-schema-codegen/tests/test_model_extractor.py @@ -12,6 +12,8 @@ assert_literal_field, find_field, ) +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.field import ModelRef, Primitive from overture.schema.codegen.extraction.field_walk import ( all_constraints, @@ -32,7 +34,6 @@ require_if, ) from overture.schema.system.string import HexColor -from pydantic import BaseModel, Field class TestModelConstraints: diff --git a/packages/overture-schema-codegen/tests/test_module_layout.py b/packages/overture-schema-codegen/tests/test_module_layout.py index 74ff5ec54..ae2acd16b 100644 --- a/packages/overture-schema-codegen/tests/test_module_layout.py +++ b/packages/overture-schema-codegen/tests/test_module_layout.py @@ -3,6 +3,7 @@ from pathlib import PurePosixPath import pytest + from overture.schema.codegen.layout.module_layout import ( compute_output_dir, compute_schema_root, diff --git a/packages/overture-schema-codegen/tests/test_newtype_extraction.py b/packages/overture-schema-codegen/tests/test_newtype_extraction.py index 9f28dce7e..beed91a28 100644 --- a/packages/overture-schema-codegen/tests/test_newtype_extraction.py +++ b/packages/overture-schema-codegen/tests/test_newtype_extraction.py @@ -3,6 +3,8 @@ from typing import Annotated, NewType from codegen_test_support import STR_TYPE +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.field import ArrayOf, Primitive from overture.schema.codegen.extraction.field_walk import terminal_scalar from overture.schema.codegen.extraction.newtype_extraction import extract_newtype @@ -10,7 +12,6 @@ from overture.schema.system.field_constraint import UniqueItemsConstraint from overture.schema.system.ref import Id from overture.schema.system.string import HexColor -from pydantic import BaseModel, Field class TestExtractNewType: diff --git a/packages/overture-schema-codegen/tests/test_numeric_extraction.py b/packages/overture-schema-codegen/tests/test_numeric_extraction.py index b9e4f5b4e..e7ec9e99d 100644 --- a/packages/overture-schema-codegen/tests/test_numeric_extraction.py +++ b/packages/overture-schema-codegen/tests/test_numeric_extraction.py @@ -2,6 +2,8 @@ from typing import Annotated, NewType +from pydantic import Field + 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 @@ -15,7 +17,6 @@ partition_numeric_and_geometry_types, ) from overture.schema.system.numeric import float32, int32, int64, uint8 -from pydantic import Field class TestPartitionNumericAndGeometryTypes: diff --git a/packages/overture-schema-codegen/tests/test_pydantic_extraction.py b/packages/overture-schema-codegen/tests/test_pydantic_extraction.py index 1d8803d16..a1737ec71 100644 --- a/packages/overture-schema-codegen/tests/test_pydantic_extraction.py +++ b/packages/overture-schema-codegen/tests/test_pydantic_extraction.py @@ -1,8 +1,9 @@ """Tests for Pydantic type extraction.""" +from pydantic import EmailStr, HttpUrl + from overture.schema.codegen.extraction.pydantic_extraction import extract_pydantic_type from overture.schema.codegen.extraction.specs import PydanticTypeSpec -from pydantic import EmailStr, HttpUrl class TestExtractPydanticType: diff --git a/packages/overture-schema-codegen/tests/test_pyspark_base_row.py b/packages/overture-schema-codegen/tests/test_pyspark_base_row.py index 1a3eb2274..d377e36c9 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_base_row.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_base_row.py @@ -13,6 +13,8 @@ discover_feature, spec_for_model, ) +from pydantic import BaseModel, Field, HttpUrl, TypeAdapter + from overture.schema.codegen.extraction.field import ( AnyScalar, ConstraintSource, @@ -51,7 +53,6 @@ min_fields_set, require_if, ) -from pydantic import BaseModel, Field, HttpUrl, TypeAdapter @pytest.fixture(scope="module") 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 c4c9f84ef..fc7673058 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_check_builder.py @@ -16,6 +16,10 @@ spec_for_model, union_spec_for, ) +from pydantic import BaseModel, Field +from pydantic.fields import FieldInfo +from pydantic.networks import HttpUrl + from overture.schema.codegen.extraction.field import ( ConstraintSource, Primitive, @@ -62,9 +66,6 @@ ) from overture.schema.system.numeric import float64 from overture.schema.system.string import CountryCodeAlpha2 -from pydantic import BaseModel, Field -from pydantic.fields import FieldInfo -from pydantic.networks import HttpUrl _path = parse 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 c87524925..c0469bc63 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_constraint_dispatch.py @@ -4,6 +4,8 @@ import pytest from annotated_types import Ge, Gt, Interval, Le, Lt, MultipleOf +from pydantic import Field, Strict + from overture.schema.codegen.extraction.field import Primitive from overture.schema.codegen.extraction.length_constraints import ( ArrayMaxLen, @@ -50,7 +52,6 @@ RequireIfConstraint, ) from overture.schema.system.ref import Identified, Reference, Relationship -from pydantic import Field, Strict class _Stub(Identified): diff --git a/packages/overture-schema-codegen/tests/test_pyspark_constraint_values.py b/packages/overture-schema-codegen/tests/test_pyspark_constraint_values.py index 419e2866e..2a44e7f71 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_constraint_values.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_constraint_values.py @@ -1,6 +1,7 @@ """Tests for the paired constraint value table.""" import pytest + from overture.schema.codegen.pyspark.constraint_dispatch import ExpressionDescriptor from overture.schema.codegen.pyspark.test_data.constraint_values import ( CONSTRAINT_VALUES, diff --git a/packages/overture-schema-codegen/tests/test_pyspark_e2e.py b/packages/overture-schema-codegen/tests/test_pyspark_e2e.py index 6ec7f663b..b61292976 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_e2e.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_e2e.py @@ -7,13 +7,14 @@ import pytest from annotated_types import Ge from codegen_test_support import discover_feature +from pydantic import BaseModel + from overture.schema.codegen.cli import _generate_pyspark from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.pyspark.pipeline import ( GeneratedModule, generate_pyspark_module, ) -from pydantic import BaseModel class SimpleModel(BaseModel): 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 0db68c8e4..0a99238dd 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_invalid_value.py @@ -1,6 +1,7 @@ """Tests for constraint-violating value generation.""" import pytest + from overture.schema.codegen.pyspark.constraint_dispatch import ExpressionDescriptor from overture.schema.codegen.pyspark.test_data.invalid_value import invalid_value from overture.schema.system.field_constraint.string import ( diff --git a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py index c0b512fbf..98b7e5289 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py @@ -7,6 +7,8 @@ import pytest from annotated_types import Ge from codegen_test_support import find_theme +from pydantic import BaseModel + from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.specs import ( ModelSpec, @@ -23,7 +25,6 @@ from overture.schema.codegen.spec_discovery import extract_model_spec from overture.schema.system.field_path import Direct from overture.schema.system.geometric import GeometryType -from pydantic import BaseModel class SimpleModel(BaseModel): diff --git a/packages/overture-schema-codegen/tests/test_pyspark_renderer.py b/packages/overture-schema-codegen/tests/test_pyspark_renderer.py index 56ac887b0..54a843f17 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_renderer.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_renderer.py @@ -17,6 +17,9 @@ flat_specs_from_discovery, spec_for_model, ) +from pydantic import BaseModel, Field, HttpUrl +from pydantic.fields import FieldInfo + from overture.schema.codegen.extraction.specs import ModelSpec from overture.schema.codegen.pyspark._render_common import ( field_check_rows, @@ -65,8 +68,6 @@ ) from overture.schema.system.numeric import int32 from overture.schema.system.string import CountryCodeAlpha2 -from pydantic import BaseModel, Field, HttpUrl -from pydantic.fields import FieldInfo _path = parse diff --git a/packages/overture-schema-codegen/tests/test_pyspark_scaffold.py b/packages/overture-schema-codegen/tests/test_pyspark_scaffold.py index 84cdace4f..8a5a2a416 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_scaffold.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_scaffold.py @@ -10,6 +10,8 @@ discover_feature, spec_for_model, ) +from pydantic import TypeAdapter + from overture.schema.codegen.extraction.specs import ModelSpec, UnionSpec from overture.schema.codegen.pyspark.check_builder import build_checks from overture.schema.codegen.pyspark.check_ir import ( @@ -29,7 +31,6 @@ leaf_list_depth, ) from overture.schema.system.field_path import ArraySegment, Iterated, parse -from pydantic import TypeAdapter _path = parse diff --git a/packages/overture-schema-codegen/tests/test_pyspark_schema_builder.py b/packages/overture-schema-codegen/tests/test_pyspark_schema_builder.py index 58c96c897..0a7253daa 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_schema_builder.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_schema_builder.py @@ -4,6 +4,8 @@ import pytest from codegen_test_support import FeatureWithRootModel, spec_for_model +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.field import Primitive from overture.schema.codegen.extraction.specs import ( AnnotatedField, @@ -12,7 +14,6 @@ ) from overture.schema.codegen.pyspark.schema_builder import SchemaField, build_schema from overture.schema.divisions import DivisionArea -from pydantic import BaseModel, Field class SimpleModel(BaseModel): 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 82da0d6de..9a8e33d86 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py @@ -6,6 +6,8 @@ from typing import Annotated import pytest +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.field import ArrayOf, ModelRef, Primitive from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.specs import RecordSpec @@ -50,7 +52,6 @@ Not, require_any_of, ) -from pydantic import BaseModel, Field _path = parse diff --git a/packages/overture-schema-codegen/tests/test_reverse_references.py b/packages/overture-schema-codegen/tests/test_reverse_references.py index 02d7ffcc2..6e6fefa87 100644 --- a/packages/overture-schema-codegen/tests/test_reverse_references.py +++ b/packages/overture-schema-codegen/tests/test_reverse_references.py @@ -16,6 +16,8 @@ make_union_spec, spec_for_model, ) +from pydantic import BaseModel + from overture.schema.codegen.extraction.enum_extraction import extract_enum from overture.schema.codegen.extraction.field import ( ArrayOf, @@ -38,7 +40,6 @@ ) from overture.schema.system.ref import Id from overture.schema.system.string import NoWhitespaceString -from pydantic import BaseModel @pytest.mark.parametrize( diff --git a/packages/overture-schema-codegen/tests/test_specs.py b/packages/overture-schema-codegen/tests/test_specs.py index 99cbe2780..1688e05c0 100644 --- a/packages/overture-schema-codegen/tests/test_specs.py +++ b/packages/overture-schema-codegen/tests/test_specs.py @@ -9,6 +9,8 @@ SimpleModel, make_union_spec, ) +from pydantic import BaseModel, Field + from overture.schema.codegen.extraction.model_extraction import extract_model from overture.schema.codegen.extraction.specs import ( AnnotatedField, @@ -21,7 +23,6 @@ is_union_alias, ) from overture.schema.system.numeric import int32 -from pydantic import BaseModel, Field class TestModelSpec: diff --git a/packages/overture-schema-codegen/tests/test_type_analyzer.py b/packages/overture-schema-codegen/tests/test_type_analyzer.py index 1fecc4c6c..08863f064 100644 --- a/packages/overture-schema-codegen/tests/test_type_analyzer.py +++ b/packages/overture-schema-codegen/tests/test_type_analyzer.py @@ -6,6 +6,9 @@ import pytest from annotated_types import Ge, MaxLen, MinLen from codegen_test_support import TollChargesByVehicleType +from pydantic import BaseModel, Field, RootModel, Tag +from typing_extensions import Sentinel + from overture.schema.codegen.extraction.field import ( AnyScalar, ArrayOf, @@ -48,8 +51,6 @@ NoWhitespaceString, SnakeCaseString, ) -from pydantic import BaseModel, Field, RootModel, Tag -from typing_extensions import Sentinel def _shape(annotation: object) -> FieldShape: diff --git a/packages/overture-schema-codegen/tests/test_type_collection.py b/packages/overture-schema-codegen/tests/test_type_collection.py index 71907e719..35119aba2 100644 --- a/packages/overture-schema-codegen/tests/test_type_collection.py +++ b/packages/overture-schema-codegen/tests/test_type_collection.py @@ -10,6 +10,8 @@ lookup_by_name, spec_for_model, ) +from pydantic import BaseModel + from overture.schema.codegen.extraction.specs import ( EnumSpec, NewTypeSpec, @@ -23,7 +25,6 @@ ) from overture.schema.system.numeric import uint8 from overture.schema.system.string import HexColor -from pydantic import BaseModel def _make_feature_with_sub_model(sub_model: type) -> type[BaseModel]: diff --git a/packages/overture-schema-codegen/tests/test_type_placement.py b/packages/overture-schema-codegen/tests/test_type_placement.py index bf3d5528a..3b67da9e4 100644 --- a/packages/overture-schema-codegen/tests/test_type_placement.py +++ b/packages/overture-schema-codegen/tests/test_type_placement.py @@ -2,8 +2,6 @@ from pathlib import PurePosixPath -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, @@ -12,6 +10,10 @@ lookup_by_name, make_union_spec, ) +from pydantic import BaseModel + +import overture.schema.system.geometric as _system_geometric +import overture.schema.system.numeric as _system_numeric from overture.schema.codegen.extraction.specs import ( AnnotatedField, FieldSpec, @@ -32,7 +34,6 @@ from overture.schema.codegen.markdown.pipeline import ( partition_numeric_and_geometry_types, ) -from pydantic import BaseModel _NUMERIC_NAMES, _GEOMETRY_NAMES = partition_numeric_and_geometry_types( _system_numeric, _system_geometric diff --git a/packages/overture-schema-codegen/tests/test_union_extraction.py b/packages/overture-schema-codegen/tests/test_union_extraction.py index a543c63c4..623fbe2e4 100644 --- a/packages/overture-schema-codegen/tests/test_union_extraction.py +++ b/packages/overture-schema-codegen/tests/test_union_extraction.py @@ -17,6 +17,9 @@ TestSegmentEqualConstraints, WaterSegment, ) +from pydantic import Field, GetCoreSchemaHandler +from pydantic_core import core_schema + from overture.schema.codegen.extraction.field import ( ArrayOf, ConstraintSource, @@ -38,8 +41,6 @@ JsonPointerConstraint, PatternConstraint, ) -from pydantic import Field, GetCoreSchemaHandler -from pydantic_core import core_schema class TestExtractUnion: diff --git a/packages/overture-schema-common/pyproject.toml b/packages/overture-schema-common/pyproject.toml index d652ccb74..91f3d7ba2 100644 --- a/packages/overture-schema-common/pyproject.toml +++ b/packages/overture-schema-common/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [project] name = "overture-schema-common" @@ -25,8 +25,8 @@ Issues = "https://github.com/OvertureMaps/schema/issues" [tool.uv.sources] overture-schema-system = { workspace = true } -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.common" [dependency-groups] dev = [ diff --git a/packages/overture-schema-common/src/overture/__init__.py b/packages/overture-schema-common/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-common/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-common/src/overture/schema/__init__.py b/packages/overture-schema-common/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-common/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-common/tests/scoping/test_scoped.py b/packages/overture-schema-common/tests/scoping/test_scoped.py index 9f27d293e..c33b2391a 100644 --- a/packages/overture-schema-common/tests/scoping/test_scoped.py +++ b/packages/overture-schema-common/tests/scoping/test_scoped.py @@ -3,6 +3,10 @@ from typing import Annotated, cast, get_args, get_origin import pytest +from pydantic import BaseModel +from pydantic.fields import FieldInfo +from pydantic_core import PydanticUndefined + from overture.schema.common.scoping import ( Heading, LinearlyReferencedPosition, @@ -17,9 +21,6 @@ ModelConstraint, RequireAnyOfConstraint, ) -from pydantic import BaseModel -from pydantic.fields import FieldInfo -from pydantic_core import PydanticUndefined class TestScope: diff --git a/packages/overture-schema-common/tests/test_common_tag_providers.py b/packages/overture-schema-common/tests/test_common_tag_providers.py index 4f1755332..feaa0064b 100644 --- a/packages/overture-schema-common/tests/test_common_tag_providers.py +++ b/packages/overture-schema-common/tests/test_common_tag_providers.py @@ -3,6 +3,8 @@ from typing import Annotated, Literal import pytest +from pydantic import BaseModel, Field, Tag + from overture.schema.common import OvertureFeature from overture.schema.common.tag_providers import ( theme_provider, @@ -10,7 +12,6 @@ from overture.schema.system.discovery import ModelKey from overture.schema.system.discovery.discovery import _generate_tags from overture.schema.system.discovery.types import TagProviderDict, TagProviderKey -from pydantic import BaseModel, Field, Tag @pytest.fixture diff --git a/packages/overture-schema-common/tests/test_models.py b/packages/overture-schema-common/tests/test_models.py index d29d00df7..df1dc1edf 100644 --- a/packages/overture-schema-common/tests/test_models.py +++ b/packages/overture-schema-common/tests/test_models.py @@ -4,6 +4,9 @@ import pytest from deepdiff import DeepDiff +from pydantic import ValidationError +from shapely.geometry import LineString, Point + from overture.schema.common.feature import OvertureFeature from overture.schema.common.sources import SourceItem from overture.schema.system.geometric import ( @@ -11,8 +14,6 @@ Geometry, ) from overture.schema.system.json_schema import GenerateOmitNullableOptionalJsonSchema -from pydantic import ValidationError -from shapely.geometry import LineString, Point def prune_dict( diff --git a/packages/overture-schema-common/tests/test_numeric_types.py b/packages/overture-schema-common/tests/test_numeric_types.py index 698ed2082..25a1d684a 100644 --- a/packages/overture-schema-common/tests/test_numeric_types.py +++ b/packages/overture-schema-common/tests/test_numeric_types.py @@ -3,6 +3,8 @@ from typing import Annotated import pytest +from pydantic import BaseModel, Field, ValidationError + from overture.schema.system.numeric import ( float32, float64, @@ -10,7 +12,6 @@ uint8, uint16, ) -from pydantic import BaseModel, Field, ValidationError class TestValidation: diff --git a/packages/overture-schema-divisions-theme/pyproject.toml b/packages/overture-schema-divisions-theme/pyproject.toml index e1ac36d2e..c2ab8a8af 100644 --- a/packages/overture-schema-divisions-theme/pyproject.toml +++ b/packages/overture-schema-divisions-theme/pyproject.toml @@ -24,11 +24,11 @@ overture-schema-common = { workspace = true } overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.divisions" [project.entry-points."overture.models"] division = "overture.schema.divisions:Division" diff --git a/packages/overture-schema-divisions-theme/src/overture/__init__.py b/packages/overture-schema-divisions-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-divisions-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-divisions-theme/src/overture/schema/__init__.py b/packages/overture-schema-divisions-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-divisions-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-divisions-theme/tests/test_division_area_json_schema_baseline.py b/packages/overture-schema-divisions-theme/tests/test_division_area_json_schema_baseline.py index 53a5d3821..3fa2be335 100644 --- a/packages/overture-schema-divisions-theme/tests/test_division_area_json_schema_baseline.py +++ b/packages/overture-schema-divisions-theme/tests/test_division_area_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.divisions import DivisionArea from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-divisions-theme/tests/test_division_boundary_json_schema_baseline.py b/packages/overture-schema-divisions-theme/tests/test_division_boundary_json_schema_baseline.py index 66733892e..d753a9666 100644 --- a/packages/overture-schema-divisions-theme/tests/test_division_boundary_json_schema_baseline.py +++ b/packages/overture-schema-divisions-theme/tests/test_division_boundary_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.divisions import DivisionBoundary from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-divisions-theme/tests/test_division_json_schema_baseline.py b/packages/overture-schema-divisions-theme/tests/test_division_json_schema_baseline.py index cf91ce8f8..83f531831 100644 --- a/packages/overture-schema-divisions-theme/tests/test_division_json_schema_baseline.py +++ b/packages/overture-schema-divisions-theme/tests/test_division_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.divisions import Division from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-places-theme/pyproject.toml b/packages/overture-schema-places-theme/pyproject.toml index 811a3d92a..518ee6938 100644 --- a/packages/overture-schema-places-theme/pyproject.toml +++ b/packages/overture-schema-places-theme/pyproject.toml @@ -24,11 +24,11 @@ overture-schema-common = { workspace = true } overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.places" [project.entry-points."overture.models"] place = "overture.schema.places:Place" diff --git a/packages/overture-schema-places-theme/src/overture/__init__.py b/packages/overture-schema-places-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-places-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-places-theme/src/overture/schema/__init__.py b/packages/overture-schema-places-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-places-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-places-theme/tests/test_place_json_schema_baseline.py b/packages/overture-schema-places-theme/tests/test_place_json_schema_baseline.py index 6360911d3..c75dbe0d5 100644 --- a/packages/overture-schema-places-theme/tests/test_place_json_schema_baseline.py +++ b/packages/overture-schema-places-theme/tests/test_place_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.places import Place from overture.schema.system.testing import assert_json_schema_golden diff --git a/packages/overture-schema-pyspark/pyproject.toml b/packages/overture-schema-pyspark/pyproject.toml index 027a5ae60..6e72bc93c 100644 --- a/packages/overture-schema-pyspark/pyproject.toml +++ b/packages/overture-schema-pyspark/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [project] dependencies = [ @@ -17,8 +17,8 @@ version = "0.1.1" [project.scripts] overture-validate = "overture.schema.pyspark.cli:validate_cli" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.pyspark" [tool.uv.sources] overture-schema-system = { workspace = true } diff --git a/packages/overture-schema-pyspark/src/overture/__init__.py b/packages/overture-schema-pyspark/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-pyspark/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-pyspark/src/overture/schema/__init__.py b/packages/overture-schema-pyspark/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-pyspark/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) 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 71e09ad2f..3ece5b671 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/check.py @@ -6,11 +6,10 @@ from dataclasses import dataclass from enum import Enum +from overture.schema.system.geometric import GeometryType from pyspark.sql import Column from pyspark.sql.types import StructType -from overture.schema.system.geometric import GeometryType - class CheckShape(Enum): """How the composition layer handles a check expression.""" 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 14fb70833..7bae68f51 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/cli.py @@ -7,11 +7,11 @@ from dataclasses import dataclass import click -from pyspark.errors import AnalysisException -from pyspark.sql import DataFrame, SparkSession from overture.schema.system.discovery import resolve_entry_point_key from overture.schema.system.geometric import GeometryType +from pyspark.errors import AnalysisException +from pyspark.sql import DataFrame, SparkSession 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 9540c52bc..e75722396 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 @@ -18,11 +18,10 @@ from functools import reduce from typing import Literal +from overture.schema.system.geometric import GeometryType from pyspark.sql import Column from pyspark.sql import functions as F -from overture.schema.system.geometric import GeometryType - from .column_patterns import error_msg _WKB_TYPE_CODE: dict[GeometryType, int] = { diff --git a/packages/overture-schema-pyspark/src/overture/schema/pyspark/validate.py b/packages/overture-schema-pyspark/src/overture/schema/pyspark/validate.py index f6161b4b0..7aa9aab8d 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/validate.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/validate.py @@ -16,14 +16,13 @@ from collections.abc import Iterable from dataclasses import dataclass -from pyspark.sql import DataFrame -from pyspark.sql import functions as F -from pyspark.sql.types import StringType, StructField, StructType - from overture.schema.system.discovery import ( entry_point_class_alias, resolve_entry_point_key, ) +from pyspark.sql import DataFrame +from pyspark.sql import functions as F +from pyspark.sql.types import StringType, StructField, StructType from ._registry import REGISTRY from .check import Check, CheckShape diff --git a/packages/overture-schema-pyspark/tests/_support/harness.py b/packages/overture-schema-pyspark/tests/_support/harness.py index 99681807d..6d4a6961a 100644 --- a/packages/overture-schema-pyspark/tests/_support/harness.py +++ b/packages/overture-schema-pyspark/tests/_support/harness.py @@ -12,8 +12,6 @@ from dataclasses import dataclass from typing import Any -from overture.schema.pyspark.check import Check -from overture.schema.pyspark.validate import evaluate_checks, explain_errors from pyspark.sql import SparkSession from pyspark.sql.types import ( ArrayType, @@ -27,6 +25,9 @@ ) from shapely import wkb, wkt +from overture.schema.pyspark.check import Check +from overture.schema.pyspark.validate import evaluate_checks, explain_errors + from .helpers import PathTraversalError, deep_merge from .scenarios import Scenario diff --git a/packages/overture-schema-pyspark/tests/_support/registry.py b/packages/overture-schema-pyspark/tests/_support/registry.py index 5108bd4b9..ec285e00b 100644 --- a/packages/overture-schema-pyspark/tests/_support/registry.py +++ b/packages/overture-schema-pyspark/tests/_support/registry.py @@ -7,9 +7,10 @@ from collections.abc import Callable, Iterator from contextlib import contextmanager +from pyspark.sql.types import StructType + from overture.schema.pyspark._registry import REGISTRY from overture.schema.pyspark.check import Check, ModelValidation -from pyspark.sql.types import StructType @contextmanager diff --git a/packages/overture-schema-pyspark/tests/expressions/test_column_patterns.py b/packages/overture-schema-pyspark/tests/expressions/test_column_patterns.py index a43be04a6..9ac4c715b 100644 --- a/packages/overture-schema-pyspark/tests/expressions/test_column_patterns.py +++ b/packages/overture-schema-pyspark/tests/expressions/test_column_patterns.py @@ -15,6 +15,9 @@ from typing import Any import pytest +from pyspark.sql import Column, SparkSession +from pyspark.sql import functions as F + from overture.schema.pyspark.expressions.column_patterns import ( array_check, check_struct_unique, @@ -31,8 +34,6 @@ check_require_any_of, check_string_min_length, ) -from pyspark.sql import Column, SparkSession -from pyspark.sql import functions as F # PySpark 3.4's collect() leaves its result socket for the GC to finalize; under # -W error that ResourceWarning fails the batched `results` fixture. conftest's 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 26a29663b..aa7f09f1b 100644 --- a/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py +++ b/packages/overture-schema-pyspark/tests/expressions/test_constraint_expressions.py @@ -20,6 +20,10 @@ from typing import Any import pytest +from pyspark.sql import Column, SparkSession +from pyspark.sql import functions as F +from shapely.geometry import LineString, MultiPolygon, Point, Polygon + from overture.schema.pyspark.expressions.constraint_expressions import ( check_array_max_length, check_array_min_length, @@ -49,9 +53,6 @@ except_literals, ) from overture.schema.system.geometric import GeometryType -from pyspark.sql import Column, SparkSession -from pyspark.sql import functions as F -from shapely.geometry import LineString, MultiPolygon, Point, Polygon # PySpark 3.4's collect() leaves its result socket for the GC to finalize; under # -W error that ResourceWarning fails the batched `results` fixture. conftest's diff --git a/packages/overture-schema-pyspark/tests/expressions/test_schema_check.py b/packages/overture-schema-pyspark/tests/expressions/test_schema_check.py index ddd756a00..8ec084798 100644 --- a/packages/overture-schema-pyspark/tests/expressions/test_schema_check.py +++ b/packages/overture-schema-pyspark/tests/expressions/test_schema_check.py @@ -1,9 +1,5 @@ """Tests for schema comparison.""" -from overture.schema.pyspark.schema_check import ( - SchemaMismatch, - compare_schemas, -) from pyspark.sql.types import ( ArrayType, DoubleType, @@ -14,6 +10,11 @@ StructType, ) +from overture.schema.pyspark.schema_check import ( + SchemaMismatch, + compare_schemas, +) + class TestIdenticalSchemas: def test_empty_schemas(self) -> None: diff --git a/packages/overture-schema-pyspark/tests/test_check.py b/packages/overture-schema-pyspark/tests/test_check.py index 0993411c2..b51539a4f 100644 --- a/packages/overture-schema-pyspark/tests/test_check.py +++ b/packages/overture-schema-pyspark/tests/test_check.py @@ -3,10 +3,11 @@ import dataclasses import pytest -from overture.schema.pyspark.check import Check, CheckShape from pyspark.sql import SparkSession from pyspark.sql import functions as F +from overture.schema.pyspark.check import Check, CheckShape + def test_check_is_frozen(spark: SparkSession) -> None: check = Check( diff --git a/packages/overture-schema-pyspark/tests/test_cli.py b/packages/overture-schema-pyspark/tests/test_cli.py index 7dd9af9a0..6a331b6ee 100644 --- a/packages/overture-schema-pyspark/tests/test_cli.py +++ b/packages/overture-schema-pyspark/tests/test_cli.py @@ -5,6 +5,11 @@ import pytest from click.testing import CliRunner +from pyspark.errors import AnalysisException +from pyspark.sql import Row, SparkSession +from pyspark.sql import functions as F +from pyspark.sql.types import StringType, StructField, StructType + from overture.schema.pyspark._registry import REGISTRY from overture.schema.pyspark.check import Check, CheckShape from overture.schema.pyspark.cli import ( @@ -15,10 +20,6 @@ resolve_read, validate_cli, ) -from pyspark.errors import AnalysisException -from pyspark.sql import Row, SparkSession -from pyspark.sql import functions as F -from pyspark.sql.types import StringType, StructField, StructType from ._support.registry import register_model diff --git a/packages/overture-schema-pyspark/tests/test_harness.py b/packages/overture-schema-pyspark/tests/test_harness.py index 3fa07d628..e03cf0d83 100644 --- a/packages/overture-schema-pyspark/tests/test_harness.py +++ b/packages/overture-schema-pyspark/tests/test_harness.py @@ -5,7 +5,6 @@ import re import pytest -from overture.schema.pyspark.check import Check, CheckShape from pyspark.sql import Row, SparkSession from pyspark.sql import functions as F from pyspark.sql.types import ( @@ -18,6 +17,8 @@ StructType, ) +from overture.schema.pyspark.check import Check, CheckShape + from ._support.harness import ( assert_schema_covers_checks, build_scenario_map, diff --git a/packages/overture-schema-pyspark/tests/test_validate.py b/packages/overture-schema-pyspark/tests/test_validate.py index 9539b8977..fdf4070cb 100644 --- a/packages/overture-schema-pyspark/tests/test_validate.py +++ b/packages/overture-schema-pyspark/tests/test_validate.py @@ -4,6 +4,18 @@ from collections.abc import Iterator import pytest +from pyspark.sql import DataFrame, Row, SparkSession +from pyspark.sql import functions as F +from pyspark.sql.types import ( + ArrayType, + DoubleType, + IntegerType, + MapType, + StringType, + StructField, + StructType, +) + from overture.schema.pyspark._registry import REGISTRY from overture.schema.pyspark.check import Check, CheckShape from overture.schema.pyspark.expressions.column_patterns import map_values_check @@ -17,17 +29,6 @@ model_names, validate_model, ) -from pyspark.sql import DataFrame, Row, SparkSession -from pyspark.sql import functions as F -from pyspark.sql.types import ( - ArrayType, - DoubleType, - IntegerType, - MapType, - StringType, - StructField, - StructType, -) from ._support.registry import register_model diff --git a/packages/overture-schema-system/pyproject.toml b/packages/overture-schema-system/pyproject.toml index 761a3011c..52d32b464 100644 --- a/packages/overture-schema-system/pyproject.toml +++ b/packages/overture-schema-system/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [project] name = "overture-schema-system" @@ -30,8 +30,8 @@ dev = [ "mypy>=1.17.0", ] -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.system" [tool.ruff] target-version = "py310" diff --git a/packages/overture-schema-system/src/overture/__init__.py b/packages/overture-schema-system/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-system/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-system/src/overture/schema/__init__.py b/packages/overture-schema-system/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-system/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-transportation-theme/pyproject.toml b/packages/overture-schema-transportation-theme/pyproject.toml index 5fa8df617..270cc14bb 100644 --- a/packages/overture-schema-transportation-theme/pyproject.toml +++ b/packages/overture-schema-transportation-theme/pyproject.toml @@ -25,11 +25,11 @@ overture-schema-system = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.transportation" [project.entry-points."overture.models"] connector = "overture.schema.transportation:Connector" diff --git a/packages/overture-schema-transportation-theme/src/overture/__init__.py b/packages/overture-schema-transportation-theme/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-transportation-theme/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-transportation-theme/src/overture/schema/__init__.py b/packages/overture-schema-transportation-theme/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-transportation-theme/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-transportation-theme/tests/test_connector_json_schema_baseline.py b/packages/overture-schema-transportation-theme/tests/test_connector_json_schema_baseline.py index da6a43280..8fbc8ab2a 100644 --- a/packages/overture-schema-transportation-theme/tests/test_connector_json_schema_baseline.py +++ b/packages/overture-schema-transportation-theme/tests/test_connector_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.system.testing import assert_json_schema_golden from overture.schema.transportation import Connector diff --git a/packages/overture-schema-transportation-theme/tests/test_segment_json_schema_baseline.py b/packages/overture-schema-transportation-theme/tests/test_segment_json_schema_baseline.py index 0952851c1..c3db70507 100644 --- a/packages/overture-schema-transportation-theme/tests/test_segment_json_schema_baseline.py +++ b/packages/overture-schema-transportation-theme/tests/test_segment_json_schema_baseline.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest + from overture.schema.system.testing import assert_json_schema_golden from overture.schema.transportation import Segment diff --git a/packages/overture-schema-validation/pyproject.toml b/packages/overture-schema-validation/pyproject.toml index abc30a0c5..a9fb73727 100644 --- a/packages/overture-schema-validation/pyproject.toml +++ b/packages/overture-schema-validation/pyproject.toml @@ -1,6 +1,6 @@ [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" [project] maintainers = [ @@ -33,5 +33,5 @@ dev = [ "yamlcore>=0.0.4", ] -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema.validation" diff --git a/packages/overture-schema-validation/src/overture/__init__.py b/packages/overture-schema-validation/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-validation/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-validation/src/overture/schema/__init__.py b/packages/overture-schema-validation/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema-validation/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema-validation/tests/test_schema_validation.py b/packages/overture-schema-validation/tests/test_schema_validation.py index 13702a5a9..9b59083c0 100644 --- a/packages/overture-schema-validation/tests/test_schema_validation.py +++ b/packages/overture-schema-validation/tests/test_schema_validation.py @@ -5,10 +5,11 @@ import pytest import yaml -from overture.schema.validation import validate, validate_json from pydantic import ValidationError from yamlcore import CoreLoader # type: ignore +from overture.schema.validation import validate, validate_json + # Top-level constants for paths PROJECT_ROOT = Path(__file__).parent.parent.parent.parent EXAMPLES_DIR = PROJECT_ROOT / "reference" / "examples" diff --git a/packages/overture-schema/pyproject.toml b/packages/overture-schema/pyproject.toml index 435979b93..e55b53d1b 100644 --- a/packages/overture-schema/pyproject.toml +++ b/packages/overture-schema/pyproject.toml @@ -35,8 +35,9 @@ overture-schema-places-theme = { workspace = true } overture-schema-transportation-theme = { workspace = true } [build-system] -build-backend = "hatchling.build" -requires = ["hatchling"] +requires = ["uv_build>=0.11.32,<0.13"] +build-backend = "uv_build" -[tool.hatch.build.targets.wheel] -packages = ["src/overture"] +[tool.uv.build-backend] +module-name = "overture.schema" +namespace = true diff --git a/packages/overture-schema/src/overture/__init__.py b/packages/overture-schema/src/overture/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema/src/overture/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/packages/overture-schema/src/overture/schema/__init__.py b/packages/overture-schema/src/overture/schema/__init__.py deleted file mode 100644 index 8db66d3d0..000000000 --- a/packages/overture-schema/src/overture/schema/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__("pkgutil").extend_path(__path__, __name__) diff --git a/pyproject.toml b/pyproject.toml index 7a98c855e..cb8e803d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,10 @@ members = ["packages/*"] [tool.ruff] line-length = 88 target-version = "py310" +# PEP 420 namespace packages carry no `overture/__init__.py`, so isort can no +# longer walk up to the package root; name the src roots so it still classifies +# `overture` as first-party (in source) without over-forcing it in tests. +src = ["packages/*/src"] [tool.ruff.lint] ignore = [ From 29a6af38c74e733d7e2d03326999b25d4599b973 Mon Sep 17 00:00:00 2001 From: Seth Fitzsimmons Date: Thu, 30 Jul 2026 11:46:08 -0700 Subject: [PATCH 2/4] refactor(build): emit PEP 420 generated pyspark tree Stop the pyspark codegen from emitting empty `__init__.py` files so the generated expression and test trees are PEP 420 namespace packages, matching the rest of the workspace after the hatchling->uv_build migration. The mirrored layout (generated/overture/schema//) is kept -- only the init emission is dropped. Removing the inits broke three things the bead's plan assumed would keep working; each needed a real fix: - pytest collection: generated conformance tests reached `_support` via deep relative imports whose depth `_support_prefix` computed. Under PEP 420 the module resolves as `generated.*` (tests/ is on pythonpath), not `tests.generated.*`, so those relative imports overshoot the top level. Emit absolute `from _support.X import ...` instead and delete the `_support_prefix` machinery. To keep one import style across the test tree, the hand-written tests move to the same absolute form. Set `--import-mode=importlib` (via addopts; it has no ini form) and `consider_namespace_packages = true` so collection walks the namespace. - type checking: mypy resolves `_support` as top-level only when its parent is a base, so add the pyspark tests dir to `mypy_path`. The hand-written `tests/__init__.py` stays: dropping it would make pyspark's `test_cli` a top-level module colliding with codegen's under importlib. - runtime registry: `pkgutil.walk_packages` skips subdirectories without `__init__.py`, finding zero generated modules under the PEP 420 tree. Walk the namespace roots as files instead. test_registry.py covers this -- no existing test exercised the on-disk walk, so an empty registry would have passed the suite silently. Signed-off-by: Seth Fitzsimmons --- .../schema/codegen/pyspark/pipeline.py | 50 ++----------- .../pyspark/templates/test_module.py.jinja2 | 8 +-- .../schema/codegen/pyspark/test_renderer.py | 2 - .../tests/test_pyspark_e2e.py | 7 +- .../tests/test_pyspark_pipeline.py | 70 +++++-------------- .../tests/test_pyspark_test_renderer.py | 20 +++--- .../src/overture/schema/pyspark/_registry.py | 29 ++++++-- .../overture-schema-pyspark/tests/test_cli.py | 3 +- .../tests/test_harness.py | 23 +++--- .../tests/test_helpers.py | 3 +- .../tests/test_mutations.py | 5 +- .../tests/test_registry.py | 48 +++++++++++++ .../tests/test_validate.py | 3 +- pyproject.toml | 10 +++ 14 files changed, 137 insertions(+), 144 deletions(-) create mode 100644 packages/overture-schema-pyspark/tests/test_registry.py 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 d375a097f..3b83f5448 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 @@ -7,7 +7,7 @@ from __future__ import annotations -from collections.abc import Iterable, Sequence +from collections.abc import Sequence from dataclasses import dataclass from pathlib import PurePosixPath @@ -48,12 +48,10 @@ class GeneratedModule: class PipelineOutput: """PySpark modules emitted by the pipeline, split by output tree. - The source and test trees are written to separate directories and - mirror the same relative layout, so a path is meaningful only - relative to its tree. Splitting at the boundary keeps each tree - self-contained -- in practice the overlap today is just - `__init__.py`, but any path duplicated between trees would be - ambiguous in a single flat list. + Source and test modules write to separate directories + (`--output-dir` and `--test-output-dir`), so they travel as two + lists rather than one. Both trees mirror the same relative layout, + so a path is meaningful only relative to its own tree. """ source: list[GeneratedModule] @@ -62,21 +60,6 @@ class PipelineOutput: _OUTPUT_PACKAGE = "overture.schema.pyspark.expressions.generated" -# Dots in `from ...x import y` from a generated test module to reach -# `tests/`: one to leave the file's package, one to leave `generated/`. -# Each additional directory component under `generated/` adds another. -_DOTS_FROM_TEST_TO_TESTS_ROOT = 2 - - -def _support_prefix(directory: PurePosixPath) -> str: - """Relative-import prefix used by generated test modules to reach `_support`. - - Each leading dot climbs one package level; the first two dots step - out of `tests/generated/` to `tests/`, and an extra dot is appended - for every component of *directory* under `generated/`. - """ - return "." * (len(directory.parts) + _DOTS_FROM_TEST_TO_TESTS_ROOT) - def _require_entry_point(spec: ModelSpec) -> str: """Return *spec*'s entry point or raise if it's missing.""" @@ -117,21 +100,6 @@ def _extract_geometry_types( return tuple(sorted(seen, key=lambda g: g.name)) -def _init_modules(paths: Iterable[PurePosixPath]) -> list[GeneratedModule]: - """Emit empty `__init__.py` for every directory of `paths`. - - Includes the output root so the top-level package exists after a - full `rm -rf` of the generated tree. - """ - paths = list(paths) - if not paths: - return [] - dirs: set[PurePosixPath] = set() - for path in paths: - dirs.update(path.parents) - return [GeneratedModule(content="", path=d / "__init__.py") for d in sorted(dirs)] - - def generate_pyspark_module(spec: ModelSpec) -> GeneratedModule: """Generate a PySpark validation module from a model spec. @@ -162,16 +130,14 @@ def generate_pyspark_modules( Returns ------- PipelineOutput - Source-tree model modules and test-tree modules. Each tree - includes the `__init__.py` files needed for its package layout. + Source-tree model modules and test-tree modules. The generated + tree is PEP 420, so no `__init__.py` files are emitted. """ items = [(spec, build_checks(spec)) for spec in model_specs] source = [_render_module(spec, checks) for spec, checks in items] test: list[GeneratedModule] = [] for spec, checks in items: test.extend(_render_test_modules(spec, checks)) - source.extend(_init_modules(m.path for m in source)) - test.extend(_init_modules(m.path for m in test)) return PipelineOutput(source=source, test=test) @@ -232,7 +198,6 @@ def _render_test_modules( field_checks, model_checks = checks directory, model_name = _directory_and_model_name(spec) expression_import = ".".join([_OUTPUT_PACKAGE, *directory.parts, model_name]) - support_prefix = _support_prefix(directory) modules: list[GeneratedModule] = [] for arm, (base_row_sparse, base_row_populated) in _select_arm_rows(spec).items(): @@ -248,7 +213,6 @@ def _render_test_modules( arm=arm, spec=spec, expression_import=expression_import, - support_prefix=support_prefix, ), path=directory / f"test_{model_name}{suffix}.py", ) diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/test_module.py.jinja2 b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/test_module.py.jinja2 index 466103cf2..eb56f4fb2 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/test_module.py.jinja2 +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/templates/test_module.py.jinja2 @@ -11,17 +11,17 @@ from {{ expression_import }} import ( ) from pyspark.sql import SparkSession -from {{ support_prefix }}_support.harness import ( +from _support.harness import ( ValidationResults, run_validation_pipeline, ) {% if mutation_imports %} -from {{ support_prefix }}_support.mutations import {{ mutation_imports | join(", ") }} +from _support.mutations import {{ mutation_imports | join(", ") }} {% endif %} {% if needs_set_at_path %} -from {{ support_prefix }}_support.helpers import set_at_path +from _support.helpers import set_at_path {% endif %} -from {{ support_prefix }}_support.scenarios import Scenario +from _support.scenarios import Scenario BASE_ROW_SPARSE: dict = {{ base_row_sparse }} diff --git a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_renderer.py b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_renderer.py index a3e94bfdf..15a28e411 100644 --- a/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_renderer.py +++ b/packages/overture-schema-codegen/src/overture/schema/codegen/pyspark/test_renderer.py @@ -141,7 +141,6 @@ def render_test_module( model_checks: list[ModelCheck], *, expression_import: str, - support_prefix: str, base_row_sparse: dict[str, Any] | None = None, base_row_populated: dict[str, Any] | None = None, arm: str | None = None, @@ -187,7 +186,6 @@ def render_test_module( base_row_populated=populated_repr, scenarios=all_scenarios, expression_import=expression_import, - support_prefix=support_prefix, ) diff --git a/packages/overture-schema-codegen/tests/test_pyspark_e2e.py b/packages/overture-schema-codegen/tests/test_pyspark_e2e.py index b61292976..46f3fb8bd 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_e2e.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_e2e.py @@ -198,14 +198,15 @@ def test_array_discriminator_outside_lambda( assert 'F.col("subtype")' in generated.content -def test_cli_writes_init_modules(tmp_path: Path) -> None: +def test_cli_writes_pep420_tree(tmp_path: Path) -> None: + """The CLI writes model and test modules but no `__init__.py` (PEP 420).""" spec = extract_model(SimpleModel, entry_point="overture.schema.simple:SimpleModel") out = tmp_path / "src" test_out = tmp_path / "tests" _generate_pyspark([spec], out, test_out) - assert (out / "overture" / "schema" / "simple" / "__init__.py").exists() assert (out / "overture" / "schema" / "simple" / "simple_model.py").exists() - assert (test_out / "overture" / "schema" / "simple" / "__init__.py").exists() assert ( test_out / "overture" / "schema" / "simple" / "test_simple_model.py" ).exists() + assert not list(out.rglob("__init__.py")) + assert not list(test_out.rglob("__init__.py")) diff --git a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py index 98b7e5289..1c04c94a4 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_pipeline.py @@ -83,10 +83,6 @@ def _two_specs() -> list[ModelSpec]: ] -def _features(modules: list[GeneratedModule]) -> list[GeneratedModule]: - return [m for m in modules if m.path.name != "__init__.py"] - - class TestGeneratePysparkModules: @pytest.fixture def two_spec_modules(self) -> PipelineOutput: @@ -98,7 +94,7 @@ def test_empty_specs_returns_no_modules(self) -> None: assert result.test == [] def test_one_module_per_spec(self, two_spec_modules: PipelineOutput) -> None: - assert len(_features(two_spec_modules.source)) == 2 + assert len(two_spec_modules.source) == 2 def test_paths_unique_per_tree(self, two_spec_modules: PipelineOutput) -> None: # source and test trees mirror the same dirs; uniqueness is @@ -136,10 +132,10 @@ def all_modules(self) -> PipelineOutput: return generate_pyspark_modules(_two_specs()) def test_generates_test_modules(self, all_modules: PipelineOutput) -> None: - assert len(_features(all_modules.test)) == 2 # one per feature spec + assert len(all_modules.test) == 2 # one per feature spec def test_test_module_paths(self, all_modules: PipelineOutput) -> None: - paths = {m.path.name for m in _features(all_modules.test)} + paths = {m.path.name for m in all_modules.test} assert "test_simple_model.py" in paths assert "test_bounds_model.py" in paths @@ -148,7 +144,7 @@ def test_test_modules_are_valid_python(self, all_modules: PipelineOutput) -> Non ast.parse(mod.content) def test_test_module_contains_imports(self, all_modules: PipelineOutput) -> None: - for mod in _features(all_modules.test): + for mod in all_modules.test: assert "_support.harness import" in mod.content assert "_support.scenarios import" in mod.content @@ -175,13 +171,13 @@ def segment_modules(self, all_discovered_models: dict) -> PipelineOutput: return generate_pyspark_modules(specs) def test_produces_per_arm_test_files(self, segment_modules: PipelineOutput) -> None: - paths = {m.path.name for m in _features(segment_modules.test)} + paths = {m.path.name for m in segment_modules.test} assert "test_segment_road.py" in paths assert "test_segment_rail.py" in paths def test_no_monolithic_test_file(self, segment_modules: PipelineOutput) -> None: """When per-arm tests exist, no undifferentiated test_segment.py.""" - paths = {m.path.name for m in _features(segment_modules.test)} + paths = {m.path.name for m in segment_modules.test} assert "test_segment.py" not in paths def test_per_arm_modules_are_valid_python( @@ -229,7 +225,7 @@ def test_non_union_still_gets_single_test(self) -> None: ) ] ) - tests = _features(modules.test) + tests = modules.test assert len(tests) == 1 assert tests[0].path.name == "test_simple_model.py" @@ -240,7 +236,7 @@ def test_module_path_mirrors_entry_point(self) -> None: SimpleModel, entry_point="overture.schema.simple:SimpleModel" ) modules = generate_pyspark_modules([spec]) - features = _features(modules.source) + features = modules.source assert len(features) == 1 assert features[0].path == PurePosixPath( "overture/schema/simple/simple_model.py" @@ -250,45 +246,20 @@ def test_two_packages_no_collision(self) -> None: a = extract_model(SimpleModel, entry_point="overture.schema.places:Place") b = extract_model(SimpleModel, entry_point="annex.schema.places:Place") modules = generate_pyspark_modules([a, b]) - paths = {m.path for m in _features(modules.source)} + paths = {m.path for m in modules.source} assert PurePosixPath("overture/schema/places/place.py") in paths assert PurePosixPath("annex/schema/places/place.py") in paths -_EXPECTED_INIT_PATHS = { - PurePosixPath("__init__.py"), - PurePosixPath("overture/__init__.py"), - PurePosixPath("overture/schema/__init__.py"), - PurePosixPath("overture/schema/simple/__init__.py"), -} - - -def _init_paths(modules: list[GeneratedModule]) -> set[PurePosixPath]: - return {m.path for m in modules if m.path.name == "__init__.py"} - - -class TestInitModuleEmission: - def test_intermediate_dirs_get_init_modules(self) -> None: - spec = extract_model( - SimpleModel, entry_point="overture.schema.simple:SimpleModel" - ) - modules = generate_pyspark_modules([spec]) - assert _init_paths(modules.source) == _EXPECTED_INIT_PATHS - - def test_init_modules_are_empty(self) -> None: +class TestNoInitModulesEmitted: + def test_neither_tree_has_init_modules(self) -> None: + # The generated tree is PEP 420; codegen emits no `__init__.py`. spec = extract_model( SimpleModel, entry_point="overture.schema.simple:SimpleModel" ) modules = generate_pyspark_modules([spec]) - init = next(m for m in modules.source if m.path.name == "__init__.py") - assert init.content == "" - - def test_shared_dirs_emitted_once(self) -> None: - a = extract_model(SimpleModel, entry_point="overture.schema.simple:SimpleModel") - b = extract_model(BoundsModel, entry_point="overture.schema.simple:BoundsModel") - modules = generate_pyspark_modules([a, b]) - init_paths = [m.path for m in modules.source if m.path.name == "__init__.py"] - assert len(init_paths) == len(set(init_paths)) + for tree in (modules.source, modules.test): + assert all(m.path.name != "__init__.py" for m in tree) class TestNoRegistryEmitted: @@ -309,7 +280,7 @@ def test_test_module_path_mirrors_source(self) -> None: SimpleModel, entry_point="overture.schema.simple:SimpleModel" ) modules = generate_pyspark_modules([spec]) - tests = _features(modules.test) + tests = modules.test assert len(tests) == 1 assert tests[0].path == PurePosixPath( "overture/schema/simple/test_simple_model.py" @@ -320,21 +291,12 @@ def test_test_module_imports_nested_expression(self) -> None: SimpleModel, entry_point="overture.schema.simple:SimpleModel" ) modules = generate_pyspark_modules([spec]) - test_mod = next(iter(_features(modules.test))) + test_mod = next(iter(modules.test)) assert ( "from overture.schema.pyspark.expressions.generated.overture.schema.simple.simple_model import" in test_mod.content ) - def test_test_dirs_get_init_modules(self) -> None: - spec = extract_model( - SimpleModel, entry_point="overture.schema.simple:SimpleModel" - ) - modules = generate_pyspark_modules([spec]) - # Source-tree init modules already covered in TestInitModuleEmission. - # The test tree must mirror the same package layout. - assert _init_paths(modules.test) == _EXPECTED_INIT_PATHS - class TestExtractGeometryTypes: """`_extract_geometry_types` aggregates across descriptors and checks.""" 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 9a8e33d86..e828ba163 100644 --- a/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py +++ b/packages/overture-schema-codegen/tests/test_pyspark_test_renderer.py @@ -68,15 +68,13 @@ def render_test_module(*args: object, **kwargs: object) -> str: - """Invoke the renderer with placeholder `expression_import`/`support_prefix`. + """Invoke the renderer with a placeholder `expression_import`. - Tests parse the rendered source rather than executing it, so neither - the expression import target nor the relative `_support` package depth - needs to match a real layout. Defining this as a free function (rather - than a fixture) keeps test bodies terse. + Tests parse the rendered source rather than executing it, so the + expression import target need not match a real layout. Defining this + as a free function (rather than a fixture) keeps test bodies terse. """ kwargs.setdefault("expression_import", _TEST_EXPRESSION_IMPORT) - kwargs.setdefault("support_prefix", "..") return _real_render_test_module(*args, **kwargs) # type: ignore[arg-type] @@ -935,7 +933,7 @@ def test_min_fields_set_renders_mutation_call(self) -> None: source = render_test_module("test", [], model_nodes) assert "mutate_min_fields_set(row, ['x', 'y'])" in source import_match = re.search( - r"from \.\._support\.mutations\s+import\s+(.+?)(?:\n\n|\Z)", + r"from _support\.mutations\s+import\s+(.+?)(?:\n\n|\Z)", source, re.DOTALL, ) @@ -1093,12 +1091,12 @@ def test_imports_scenario(self, empty_source: str) -> None: assert "Scenario" in empty_source def test_uses_harness_imports(self, empty_source: str) -> None: - assert "from .._support.harness import" in empty_source + assert "from _support.harness import" in empty_source def test_imports_set_at_path_only_when_field_scenarios_present(self) -> None: # No field checks -> no set_at_path scenarios -> no import empty = render_test_module("test", [], []) - assert "from .._support.helpers import set_at_path" not in empty + assert "from _support.helpers import set_at_path" not in empty # Field check -> set_at_path used -> import emitted with_field = render_test_module( @@ -1106,7 +1104,7 @@ def test_imports_set_at_path_only_when_field_scenarios_present(self) -> None: [make_check("check_required", _path("country"))], [], ) - assert "from .._support.helpers import set_at_path" in with_field + assert "from _support.helpers import set_at_path" in with_field def test_scenario_checks_valid_and_invalid(self, empty_source: str) -> None: assert "::valid" in empty_source @@ -1135,7 +1133,7 @@ def test_struct_unique_imports_mutate_unique_items( self, sources_unique_output: str ) -> None: assert ( - "from .._support.mutations import mutate_unique_items" + "from _support.mutations import mutate_unique_items" in sources_unique_output ) diff --git a/packages/overture-schema-pyspark/src/overture/schema/pyspark/_registry.py b/packages/overture-schema-pyspark/src/overture/schema/pyspark/_registry.py index dd40f92af..d5c20ad5d 100644 --- a/packages/overture-schema-pyspark/src/overture/schema/pyspark/_registry.py +++ b/packages/overture-schema-pyspark/src/overture/schema/pyspark/_registry.py @@ -15,7 +15,7 @@ import importlib import logging -import pkgutil +from pathlib import Path from .check import ModelValidation @@ -24,6 +24,25 @@ _GENERATED_ROOT = "overture.schema.pyspark.expressions.generated" +def _iter_generated_module_names(root_paths: list[str]) -> list[str]: + """Return the dotted names of every generated module on disk. + + The generated tree is PEP 420 (no `__init__.py`), so its subdirectories + are namespace packages. `pkgutil.walk_packages` skips those, so the tree + is walked as files instead: every `.py` under the namespace roots, keyed + to a dotted name relative to `_GENERATED_ROOT`. + """ + names: list[str] = [] + for root_path in root_paths: + base = Path(root_path) + for path in sorted(base.rglob("*.py")): + if path.name == "__init__.py": + continue + relative = path.relative_to(base).with_suffix("") + names.append(".".join([_GENERATED_ROOT, *relative.parts])) + return names + + def _walk() -> tuple[dict[str, ModelValidation], dict[str, dict[str, str]]]: """Walk the generated tree and collect registry + partition map. @@ -47,10 +66,8 @@ def _walk() -> tuple[dict[str, ModelValidation], dict[str, dict[str, str]]]: except ImportError: return registry, partition_map - for info in pkgutil.walk_packages(root.__path__, prefix=root.__name__ + "."): - if info.ispkg: - continue - module = importlib.import_module(info.name) + for name in _iter_generated_module_names(list(root.__path__)): + module = importlib.import_module(name) entry_point = getattr(module, "ENTRY_POINT", None) validation = getattr(module, "MODEL_VALIDATION", None) if entry_point is None or validation is None: @@ -58,7 +75,7 @@ def _walk() -> tuple[dict[str, ModelValidation], dict[str, dict[str, str]]]: registry[entry_point] = validation partitions = getattr(module, "PARTITIONS", None) or {} if partitions: - feature_type = info.name.rsplit(".", 1)[-1] + feature_type = name.rsplit(".", 1)[-1] partition_map[entry_point] = {**partitions, "type": feature_type} return registry, partition_map diff --git a/packages/overture-schema-pyspark/tests/test_cli.py b/packages/overture-schema-pyspark/tests/test_cli.py index 6a331b6ee..5ddc0b3a7 100644 --- a/packages/overture-schema-pyspark/tests/test_cli.py +++ b/packages/overture-schema-pyspark/tests/test_cli.py @@ -4,6 +4,7 @@ from pathlib import Path import pytest +from _support.registry import register_model from click.testing import CliRunner from pyspark.errors import AnalysisException from pyspark.sql import Row, SparkSession @@ -21,8 +22,6 @@ validate_cli, ) -from ._support.registry import register_model - _TEST_TYPE = "_test_cli" # Shared schema for all test registrations that need the four base columns. diff --git a/packages/overture-schema-pyspark/tests/test_harness.py b/packages/overture-schema-pyspark/tests/test_harness.py index e03cf0d83..94f2b3939 100644 --- a/packages/overture-schema-pyspark/tests/test_harness.py +++ b/packages/overture-schema-pyspark/tests/test_harness.py @@ -5,6 +5,17 @@ import re import pytest +from _support.harness import ( + assert_schema_covers_checks, + build_scenario_map, + build_scenario_rows, + coerce_to_schema, + index_violations, + sanitize_row, + scenario_uuid, +) +from _support.helpers import PathTraversalError, set_at_path +from _support.scenarios import Scenario from pyspark.sql import Row, SparkSession from pyspark.sql import functions as F from pyspark.sql.types import ( @@ -19,18 +30,6 @@ from overture.schema.pyspark.check import Check, CheckShape -from ._support.harness import ( - assert_schema_covers_checks, - build_scenario_map, - build_scenario_rows, - coerce_to_schema, - index_violations, - sanitize_row, - scenario_uuid, -) -from ._support.helpers import PathTraversalError, set_at_path -from ._support.scenarios import Scenario - class TestScenarioUuid: def test_deterministic(self) -> None: diff --git a/packages/overture-schema-pyspark/tests/test_helpers.py b/packages/overture-schema-pyspark/tests/test_helpers.py index ad2937745..e016b4a0d 100644 --- a/packages/overture-schema-pyspark/tests/test_helpers.py +++ b/packages/overture-schema-pyspark/tests/test_helpers.py @@ -5,8 +5,7 @@ from typing import Any import pytest - -from ._support.helpers import PathTraversalError, deep_merge, set_at_path +from _support.helpers import PathTraversalError, deep_merge, set_at_path class TestSetAtPath: diff --git a/packages/overture-schema-pyspark/tests/test_mutations.py b/packages/overture-schema-pyspark/tests/test_mutations.py index 9a3430b0c..ef8d8d35a 100644 --- a/packages/overture-schema-pyspark/tests/test_mutations.py +++ b/packages/overture-schema-pyspark/tests/test_mutations.py @@ -3,9 +3,8 @@ from typing import Any import pytest - -from ._support.helpers import PathTraversalError -from ._support.mutations import ( +from _support.helpers import PathTraversalError +from _support.mutations import ( _get_nested, _set_nested, _walk_strict, diff --git a/packages/overture-schema-pyspark/tests/test_registry.py b/packages/overture-schema-pyspark/tests/test_registry.py new file mode 100644 index 000000000..fcf261207 --- /dev/null +++ b/packages/overture-schema-pyspark/tests/test_registry.py @@ -0,0 +1,48 @@ +"""Tests for the runtime registry's discovery of the generated tree. + +The generated expression tree is PEP 420 (no `__init__.py`), so the +registry must walk it as a namespace package. No other test exercises the +real on-disk walk -- conformance tests import expression modules directly +and `test_validate.py` registers models through a test shim -- so an empty +registry would otherwise pass the suite unnoticed. +""" + +from __future__ import annotations + +import importlib +from pathlib import Path + +import pytest + +from overture.schema.pyspark._registry import REGISTRY + +_GENERATED_ROOT = "overture.schema.pyspark.expressions.generated" + + +def _generated_leaf_count() -> int: + """Count generated model modules on disk (excludes namespace dirs). + + Returns 0 when the generated tree is absent -- mirroring the registry's + own `ImportError` handling -- so the test skips rather than errors. + """ + try: + root = importlib.import_module(_GENERATED_ROOT) + except ImportError: + return 0 + return sum( + 1 + for base in root.__path__ + for path in Path(base).rglob("*.py") + if path.name != "__init__.py" + ) + + +def test_registry_discovers_generated_models() -> None: + """The registry finds generated modules under the PEP 420 namespace tree.""" + if _generated_leaf_count() == 0: + pytest.skip("generated tree not present; run `make generate-pyspark`") + + generated_entries = [ + key for key in REGISTRY if ":" in key and key.startswith("overture.schema.") + ] + assert generated_entries, "registry found no generated feature modules on disk" diff --git a/packages/overture-schema-pyspark/tests/test_validate.py b/packages/overture-schema-pyspark/tests/test_validate.py index fdf4070cb..5b0f86c62 100644 --- a/packages/overture-schema-pyspark/tests/test_validate.py +++ b/packages/overture-schema-pyspark/tests/test_validate.py @@ -4,6 +4,7 @@ from collections.abc import Iterator import pytest +from _support.registry import register_model from pyspark.sql import DataFrame, Row, SparkSession from pyspark.sql import functions as F from pyspark.sql.types import ( @@ -30,8 +31,6 @@ validate_model, ) -from ._support.registry import register_model - def _scalar_check( field: str, name: str, expr: F.Column, *, read_columns: frozenset[str] | None = None diff --git a/pyproject.toml b/pyproject.toml index cb8e803d4..a778311e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,10 @@ select = [ disallow_untyped_defs = true explicit_package_bases = true files = "packages/**/*.py" +# The pyspark test tree is PEP 420 and its tests import `_support` as a +# top-level package (mirroring pytest's pythonpath). Put that tests dir on +# the mypy path so `_support` resolves the same way for the type checker. +mypy_path = "packages/overture-schema-pyspark/tests" namespace_packages = true plugins = ["pydantic.mypy"] python_version = "3.10" @@ -65,6 +69,12 @@ dev = [ ] [tool.pytest.ini_options] +# The generated pyspark conformance tree is PEP 420 (no `__init__.py`), so its +# subdirectories are namespace packages. The default `prepend` import mode +# mishandles them during collection; `importlib` mode (no ini form -- only +# `addopts`) plus `consider_namespace_packages` collects them correctly. +addopts = ["--import-mode=importlib"] +consider_namespace_packages = true markers = [ "baseline: golden file baseline tests", ] From 892ebe9c5e689d65ed9529d774abea21600907aa Mon Sep 17 00:00:00 2001 From: Seth Fitzsimmons Date: Fri, 31 Jul 2026 11:28:29 -0700 Subject: [PATCH 3/4] chore(build): guard PEP 420 namespace roots against __init__.py check-namespace fails if overture/ or overture/schema/ gains an __init__.py, which would turn a namespace root into a regular package and shadow other workspace packages' contributions at import. Wired into the check gate. Signed-off-by: Seth Fitzsimmons --- Makefile | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 33ce34306..1923f46cd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: default uv-sync clean-pyspark generate-pyspark check test-all test test-only docformat docformat-only doctest doctest-only mypy mypy-only lint-only update-baselines +.PHONY: default uv-sync clean-pyspark generate-pyspark check check-namespace test-all test test-only docformat docformat-only doctest doctest-only mypy mypy-only lint-only update-baselines TESTMON ?= --testmon @@ -23,7 +23,23 @@ generate-pyspark: uv-sync clean-pyspark @uv run ruff format --quiet $(PYSPARK_EXPRESSIONS) $(PYSPARK_GENERATED_TESTS) check: uv-sync generate-pyspark - @$(MAKE) -j test-only docformat-only doctest-only lint-only mypy-only + @$(MAKE) -j test-only docformat-only doctest-only lint-only mypy-only check-namespace + +# Guard the PEP 420 namespace roots. overture/ and overture/schema/ are +# implicit namespace packages -- no __init__.py -- so every workspace package +# contributes its own leaf under the shared namespace. An __init__.py at either +# root turns that package into a regular package that shadows every other +# distribution's contribution at import time. -path patterns (not shell globs) +# keep this shell-independent and match only the two roots, never the leaves. +check-namespace: + @found=$$(find packages -type f -path '*/src/overture/__init__.py' \ + -o -type f -path '*/src/overture/schema/__init__.py'); \ + if [ -n "$$found" ]; then \ + echo "ERROR: __init__.py at PEP 420 namespace root(s) -- delete these:" >&2; \ + echo "$$found" >&2; \ + echo "overture/ and overture/schema/ must stay implicit namespace packages." >&2; \ + exit 1; \ + fi # test-all is the unconditional full run -- testmon-independent, unlike the # incremental test/test-only targets -- so data-only changes (golden JSON, From 985b838626348ff0d072bab4c41dfb7a95c3e3e1 Mon Sep 17 00:00:00 2001 From: Seth Fitzsimmons Date: Wed, 5 Aug 2026 10:28:09 -0700 Subject: [PATCH 4/4] chore(build): add changelog fragments for uv_build/PEP 420 migration Signed-off-by: Seth Fitzsimmons --- packages/overture-schema-addresses-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-base-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-buildings-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-cli/changelog.d/618.misc.md | 1 + packages/overture-schema-codegen/changelog.d/618.misc.md | 1 + packages/overture-schema-common/changelog.d/618.misc.md | 1 + packages/overture-schema-divisions-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-places-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-pyspark/changelog.d/618.misc.md | 1 + packages/overture-schema-system/changelog.d/618.misc.md | 1 + .../overture-schema-transportation-theme/changelog.d/618.misc.md | 1 + packages/overture-schema-validation/changelog.d/618.misc.md | 1 + packages/overture-schema/changelog.d/618.misc.md | 1 + 13 files changed, 13 insertions(+) create mode 100644 packages/overture-schema-addresses-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-base-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-buildings-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-cli/changelog.d/618.misc.md create mode 100644 packages/overture-schema-codegen/changelog.d/618.misc.md create mode 100644 packages/overture-schema-common/changelog.d/618.misc.md create mode 100644 packages/overture-schema-divisions-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-places-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-pyspark/changelog.d/618.misc.md create mode 100644 packages/overture-schema-system/changelog.d/618.misc.md create mode 100644 packages/overture-schema-transportation-theme/changelog.d/618.misc.md create mode 100644 packages/overture-schema-validation/changelog.d/618.misc.md create mode 100644 packages/overture-schema/changelog.d/618.misc.md diff --git a/packages/overture-schema-addresses-theme/changelog.d/618.misc.md b/packages/overture-schema-addresses-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-addresses-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-base-theme/changelog.d/618.misc.md b/packages/overture-schema-base-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-base-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-buildings-theme/changelog.d/618.misc.md b/packages/overture-schema-buildings-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-buildings-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-cli/changelog.d/618.misc.md b/packages/overture-schema-cli/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-cli/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-codegen/changelog.d/618.misc.md b/packages/overture-schema-codegen/changelog.d/618.misc.md new file mode 100644 index 000000000..252629b21 --- /dev/null +++ b/packages/overture-schema-codegen/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend to uv_build and stopped emitting `__init__.py` in the generated PySpark trees, making them PEP 420 namespace packages. diff --git a/packages/overture-schema-common/changelog.d/618.misc.md b/packages/overture-schema-common/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-common/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-divisions-theme/changelog.d/618.misc.md b/packages/overture-schema-divisions-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-divisions-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-places-theme/changelog.d/618.misc.md b/packages/overture-schema-places-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-places-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-pyspark/changelog.d/618.misc.md b/packages/overture-schema-pyspark/changelog.d/618.misc.md new file mode 100644 index 000000000..3540365f6 --- /dev/null +++ b/packages/overture-schema-pyspark/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend to uv_build and PEP 420; the runtime registry now walks the namespace roots as files so it discovers generated modules that no longer ship `__init__.py`. diff --git a/packages/overture-schema-system/changelog.d/618.misc.md b/packages/overture-schema-system/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-system/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-transportation-theme/changelog.d/618.misc.md b/packages/overture-schema-transportation-theme/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-transportation-theme/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema-validation/changelog.d/618.misc.md b/packages/overture-schema-validation/changelog.d/618.misc.md new file mode 100644 index 000000000..d82dab3bd --- /dev/null +++ b/packages/overture-schema-validation/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend from hatchling to uv_build and made `overture.schema` a PEP 420 namespace package. diff --git a/packages/overture-schema/changelog.d/618.misc.md b/packages/overture-schema/changelog.d/618.misc.md new file mode 100644 index 000000000..116ce6b04 --- /dev/null +++ b/packages/overture-schema/changelog.d/618.misc.md @@ -0,0 +1 @@ +Migrated the build backend to uv_build with an explicit `overture.schema` namespace module root shipping only `py.typed`.