From a64bb2186f94d6f9bba871628b404a4ea13a8c24 Mon Sep 17 00:00:00 2001 From: sneakers-the-rat Date: Wed, 31 Jul 2024 16:45:48 -0700 Subject: [PATCH] changelog, bump version, fill in coverage --- docs/changelog.md | 27 +++++++++++++++++++++ pyproject.toml | 2 +- src/numpydantic/schema.py | 4 ++-- tests/test_ndarray.py | 50 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 389fc07..2df9c76 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,33 @@ ## 1.* +### 1.2.3 - 24-07-31 - Vendor `nptyping` + +`nptyping` vendored into `numpydantic.vendor.nptyping` - +`nptyping` is no longer maintained, and pins `numpy<2`. +It also has many obnoxious warnings and we have to monkeypatch it +so it performs halfway decently. Since we are en-route to deprecating +usage of `nptyping` anyway, in the meantime we have just vendored it in +(it is MIT licensed, included) so that we can make those changes ourselves +and have to patch less of it. Currently the whole package is vendored with +modifications, but will be whittled away until we have replaced it with +updated type specification system :) + +Bugfix: +- [#2](https://github.com/p2p-ld/numpydantic/issues/2) - Support `numpy>=2` +- Remove deprecated numpy dtypes + +CI: +- Add windows and mac tests +- Add testing with numpy>=2 and <2 + +DevOps: +- Make a tox file for local testing, not used in CI. + +Tidying: +- Remove `monkeypatch` module! we don't need it anymore! + everything has either been upstreamed or vendored. + ### 1.2.2 - 24-07-31 Add `datetime` map to numpy's :class:`numpy.datetime64` type diff --git a/pyproject.toml b/pyproject.toml index 12a1b50..3da4cd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "numpydantic" -version = "1.2.2" +version = "1.2.3" description = "Type and shape validation and serialization for numpy arrays in pydantic models" authors = [ {name = "sneakers-the-rat", email = "sneakers-the-rat@protonmail.com"}, diff --git a/src/numpydantic/schema.py b/src/numpydantic/schema.py index bf3fd90..9636190 100644 --- a/src/numpydantic/schema.py +++ b/src/numpydantic/schema.py @@ -18,7 +18,7 @@ from numpydantic.maps import np_to_python from numpydantic.types import DtypeType, NDArrayType, ShapeType from numpydantic.vendor.nptyping.structure import StructureMeta -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: no cover from numpydantic import Shape _handler_type = Callable[[Any], core_schema.CoreSchema] @@ -143,7 +143,7 @@ def list_of_lists_schema(shape: "Shape", array_type: CoreSchema) -> ListSchema: arg = int(arg) arg_min = arg arg_max = arg - except ValueError as e: + except ValueError as e: # pragma: no cover raise ValueError( "Array shapes must be integers, wildcards, ellipses, or " diff --git a/tests/test_ndarray.py b/tests/test_ndarray.py index 62ae367..203a4f2 100644 --- a/tests/test_ndarray.py +++ b/tests/test_ndarray.py @@ -40,6 +40,56 @@ def test_ndarray_type(): instance = Model(array=np.zeros((2, 3)), array_any=np.ones((3, 4, 5))) +def test_schema_unsupported_type(): + """ + Complex numbers should just be made with an `any` schema + """ + + class Model(BaseModel): + array: NDArray[Shape["2 x, * y"], complex] + + schema = Model.model_json_schema() + assert schema["properties"]["array"]["items"] == { + "items": {}, + "type": "array", + } + + +def test_schema_tuple(): + """ + Types specified as tupled should have their schemas as a union + """ + + class Model(BaseModel): + array: NDArray[Shape["2 x, * y"], (np.uint8, np.uint16)] + + schema = Model.model_json_schema() + assert schema["properties"]["array"]["items"] == { + "items": { + "anyOf": [ + {"maximum": 255, "minimum": 0, "type": "integer"}, + {"maximum": 65535, "minimum": 0, "type": "integer"}, + ] + }, + "type": "array", + } + + +def test_schema_number(): + """ + np.numeric should just be the float schema + """ + + class Model(BaseModel): + array: NDArray[Shape["2 x, * y"], np.number] + + schema = Model.model_json_schema() + assert schema["properties"]["array"]["items"] == { + "items": {"type": "number"}, + "type": "array", + } + + def test_ndarray_union(): class Model(BaseModel): array: Optional[