From 8905c8a74055c15b3f4b6fe5943b4a3303ce4302 Mon Sep 17 00:00:00 2001 From: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:45:48 -0700 Subject: [PATCH] fix: narrow use_dual type hints The public grid-loading APIs document and implement use_dual as a boolean, but their annotations also accepted None. Align the public and internal signatures with the actual contract and add focused regression coverage. --- test/core/test_type_hints.py | 26 ++++++++++++++++++++++++++ uxarray/core/api.py | 6 +++--- uxarray/grid/grid.py | 2 +- 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 test/core/test_type_hints.py diff --git a/test/core/test_type_hints.py b/test/core/test_type_hints.py new file mode 100644 index 000000000..24cf6438f --- /dev/null +++ b/test/core/test_type_hints.py @@ -0,0 +1,26 @@ +import ast +from pathlib import Path + +ROOT = Path(__file__).parents[2] + + +def _annotation(source: Path, function_name: str, parameter_name: str) -> str: + tree = ast.parse(source.read_text()) + function = next( + node + for node in ast.walk(tree) + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) + and node.name == function_name + ) + parameter = next(arg for arg in function.args.args if arg.arg == parameter_name) + return ast.unparse(parameter.annotation) + + +def test_use_dual_type_hints_do_not_allow_none(): + api = ROOT / "uxarray" / "core" / "api.py" + grid = ROOT / "uxarray" / "grid" / "grid.py" + + assert _annotation(api, "open_grid", "use_dual") == "bool" + assert _annotation(api, "open_dataset", "use_dual") == "bool" + assert _annotation(api, "open_mfdataset", "use_dual") == "bool" + assert _annotation(grid, "from_dataset", "use_dual") == "bool" diff --git a/uxarray/core/api.py b/uxarray/core/api.py index fbc009803..6a85be86e 100644 --- a/uxarray/core/api.py +++ b/uxarray/core/api.py @@ -35,7 +35,7 @@ def open_grid( grid_filename_or_obj: str | os.PathLike[Any] | dict | xr.Dataset, chunks=None, - use_dual: bool | None = False, + use_dual: bool = False, **kwargs: dict[str, Any], ): """Constructs and returns a ``Grid`` from a grid file. @@ -348,7 +348,7 @@ def open_dataset( filename_or_obj: str | os.PathLike[Any] | xr.Dataset | None = None, chunks=None, chunk_grid: bool = True, - use_dual: bool | None = False, + use_dual: bool = False, grid_kwargs: dict[str, Any] | None = None, **kwargs: dict[str, Any], ) -> UxDataset: @@ -475,7 +475,7 @@ def open_mfdataset( paths: str | os.PathLike, chunks=None, chunk_grid: bool = True, - use_dual: bool | None = False, + use_dual: bool = False, grid_kwargs: dict[str, Any] | None = None, **kwargs: dict[str, Any], ) -> UxDataset: diff --git a/uxarray/grid/grid.py b/uxarray/grid/grid.py index 2c753f85a..dac7b3f32 100644 --- a/uxarray/grid/grid.py +++ b/uxarray/grid/grid.py @@ -254,7 +254,7 @@ def __init__( cross_section = UncachedAccessor(GridCrossSectionAccessor) @classmethod - def from_dataset(cls, dataset, use_dual: bool | None = False, **kwargs): + def from_dataset(cls, dataset, use_dual: bool = False, **kwargs): """Constructs a ``Grid`` object from a dataset. Parameters