From 9528adb1e4eaafe6b3c7d24f789cb6e0cc986e32 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 12:19:36 +0000 Subject: [PATCH] Depend on fastfields-helpers for enums and argument normalisation The Spline/Bound enums and the as_spline/as_bound/anchor_scale_shift/ infer_ndim/resolve_out_spatial normalisers have moved out of fastfields-dlpack into the new, dependency-free fastfields-helpers package (fastfields/fastfields-helpers#1 in this migration). Switch this wrapper's imports accordingly. - pyproject.toml: add "fastfields-helpers==0.*" to dependencies, same bare-wildcard-no-floor convention as fastfields-dlpack. - fastfields/numpy/__init__.py: `from fastfields.dlpack import Bound, Spline` -> `from fastfields.helpers import Bound, Spline`. - fastfields/numpy/_util.py: as_bound/as_spline re-exports now come from fastfields.helpers; comment updated. - fastfields/numpy/_resample.py: anchor_scale_shift/infer_ndim/ resolve_out_spatial now come from fastfields.helpers; docstring reference updated. `import fastfields.dlpack as _ff` (the compiled resample/ restriction/spline_coeff bindings) is untouched. - tests/test_numpy.py: the two `from fastfields.dlpack import anchor_scale_shift` imports now read from fastfields.helpers. - CLAUDE.md: "Depends only on fastfields-dlpack + numpy" corrected to name both dependencies. Every `import fastfields.dlpack as _ff` (compiled-binding usage, in _dt.py/ _sym.py/_reg.py/_pushpull.py/_resample.py) is untouched -- only the pure- Python symbol imports moved. Verified against a real build: installed fastfields-helpers, reinstalled this tree (pip install .), confirmed `fastfields.numpy.Bound.__module__ == "fastfields.helpers"` and that `fastfields.dlpack.dt_euclidean` (an actual compiled binding) is still reachable and untouched, then ran the full suite out-of-tree: 170 passed (0 failed -- the pre-existing dt_mesh failures from this migration's baseline cleared after a clean dlpack reinstall, unrelated to this change's scope). ruff check + ruff format --check clean on every changed file. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_016AjQcY78NgbagPSbPJRr6Z --- CLAUDE.md | 3 ++- fastfields/numpy/__init__.py | 2 +- fastfields/numpy/_resample.py | 4 ++-- fastfields/numpy/_util.py | 6 +++--- pyproject.toml | 5 +++++ tests/test_numpy.py | 4 ++-- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 215bf62..7b58c96 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,7 +12,8 @@ bindings. layer wraps them so every function accepts numpy arrays and **returns a fresh numpy array** (inputs untouched unless `inplace=True`). - Adds validation, zero-copy batch broadcasting, and output allocation. -- Depends only on `fastfields-dlpack` + numpy. +- Depends on `fastfields-dlpack` (compiled bindings) + `fastfields-helpers` + (the `Spline`/`Bound` enums and argument normalisers) + numpy. ## Exposed capabilities (feature level) - **Distance**: `dt_euclidean`, `dt_l1` (along diff --git a/fastfields/numpy/__init__.py b/fastfields/numpy/__init__.py index 138732d..ca2a9a8 100644 --- a/fastfields/numpy/__init__.py +++ b/fastfields/numpy/__init__.py @@ -36,7 +36,7 @@ from __future__ import annotations -from fastfields.dlpack import Bound, Spline +from fastfields.helpers import Bound, Spline from ._dt import ( dt_euclidean, diff --git a/fastfields/numpy/_resample.py b/fastfields/numpy/_resample.py index 3b352a0..eb71972 100644 --- a/fastfields/numpy/_resample.py +++ b/fastfields/numpy/_resample.py @@ -5,7 +5,7 @@ from typing import Sequence import fastfields.dlpack as _ff -from fastfields.dlpack import ( +from fastfields.helpers import ( anchor_scale_shift, infer_ndim, resolve_out_spatial, @@ -82,7 +82,7 @@ def _resize_shapes( """Return the batch, input-spatial, and output-spatial shapes. The output spatial shape is resolved via - :func:`fastfields.dlpack.resolve_out_spatial` so every backend shares one + :func:`fastfields.helpers.resolve_out_spatial` so every backend shares one implementation. Raises ``ValueError`` if ``factor``/``shape`` do not have length ``ndim``. """ diff --git a/fastfields/numpy/_util.py b/fastfields/numpy/_util.py index 0a6d2b0..2c5d9d2 100644 --- a/fastfields/numpy/_util.py +++ b/fastfields/numpy/_util.py @@ -9,11 +9,11 @@ from typing import Any -# `order`/`bound` normalisation is centralised in fastfields.dlpack so +# `order`/`bound` normalisation is centralised in fastfields.helpers so # every backend shares one implementation; re-export under the private # names the numpy modules (_dt, _resample) already import. -from fastfields.dlpack import as_bound as _as_bound # noqa: F401 -from fastfields.dlpack import as_spline as _as_spline # noqa: F401 +from fastfields.helpers import as_bound as _as_bound # noqa: F401 +from fastfields.helpers import as_spline as _as_spline # noqa: F401 import numpy as np diff --git a/pyproject.toml b/pyproject.toml index 80395f3..0eda82e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,8 +41,13 @@ classifiers = [ # (fires when `git describe` can't find a tag, e.g. a shallow-clone CI # misconfiguration) would also satisfy `==0.*` if it were ever accidentally # published. That's an accepted risk, not something this pin tries to solve. +# fastfields-helpers is the pure-Python enums/normalisation package this +# wrapper's argument handling is built on (fastfields.helpers.Bound/Spline/ +# as_bound/...) -- same bare-wildcard convention as fastfields-dlpack above, +# for the same reason: it moves on the same 0.x line. dependencies = [ "fastfields-dlpack==0.*", + "fastfields-helpers==0.*", "numpy", ] diff --git a/tests/test_numpy.py b/tests/test_numpy.py index 4dee6eb..22fb934 100644 --- a/tests/test_numpy.py +++ b/tests/test_numpy.py @@ -647,7 +647,7 @@ def test_restriction_runs_and_shapes(): def test_anchor_scale_shift_mapping(): - from fastfields.dlpack import anchor_scale_shift as _anchor_scale_shift + from fastfields.helpers import anchor_scale_shift as _anchor_scale_shift # 8 -> 4 downsample; scale/shift per torch-interpol convention. for name, abbr, exp_scale, exp_shift in [ @@ -664,7 +664,7 @@ def test_anchor_scale_shift_mapping(): def test_anchor_unknown_raises(): - from fastfields.dlpack import anchor_scale_shift as _anchor_scale_shift + from fastfields.helpers import anchor_scale_shift as _anchor_scale_shift with pytest.raises(ValueError, match="anchor"): _anchor_scale_shift("nope", (8,), (4,), 1)