From 3dd1d6a5d3b0c99432d165d2f38fd660d0835afa Mon Sep 17 00:00:00 2001 From: caniko Date: Sat, 29 Jul 2023 11:09:49 +0200 Subject: [PATCH] Fix: Will resolve unsupported types to supported ones on NT (Windows) Test: Added tests for macos and windows Chore: Bump version, MINOR --- .github/workflows/test.yaml | 9 +- pydantic_numpy/typing/i_dimensional.py | 4 +- pydantic_numpy/typing/ii_dimensional.py | 4 +- pydantic_numpy/typing/iii_dimensional.py | 4 +- pydantic_numpy/typing/n_dimensional.py | 4 +- .../typing/strict_data_type/i_dimensional.py | 4 +- .../typing/strict_data_type/ii_dimensional.py | 6 +- .../strict_data_type/iii_dimensional.py | 6 +- .../typing/strict_data_type/n_dimensional.py | 4 +- pyproject.toml | 2 +- tests/helper/cache.py | 10 ++ tests/helper/groups.py | 54 +++++------ tests/test_np_model.py | 74 +++++++-------- tests/test_typing.py | 94 ++++++++++--------- 14 files changed, 151 insertions(+), 128 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8f2417c..368c259 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -6,13 +6,18 @@ on: pull_request: branches: [ trunk ] +defaults: + run: + shell: bash + jobs: unit_tests: - runs-on: ubuntu-latest - strategy: matrix: python-version: [ "3.9", "3.10", "3.11" ] + os: [ ubuntu-latest, windows-latest, macos-latest ] + + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 diff --git a/pydantic_numpy/typing/i_dimensional.py b/pydantic_numpy/typing/i_dimensional.py index fb724bd..21e556d 100644 --- a/pydantic_numpy/typing/i_dimensional.py +++ b/pydantic_numpy/typing/i_dimensional.py @@ -14,12 +14,12 @@ Np1DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=1) Np1DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=1) -Np1DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=1) +Np1DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble, dimensions=1) Np1DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=1) Np1DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=1) Np1DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=1) -Np1DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.complex256, dimensions=1) +Np1DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.clongdouble, dimensions=1) Np1DArrayComplex128 = np_array_pydantic_annotated_typing(data_type=np.complex128, dimensions=1) Np1DArrayComplex64 = np_array_pydantic_annotated_typing(data_type=np.complex64, dimensions=1) diff --git a/pydantic_numpy/typing/ii_dimensional.py b/pydantic_numpy/typing/ii_dimensional.py index 03f6138..4172447 100644 --- a/pydantic_numpy/typing/ii_dimensional.py +++ b/pydantic_numpy/typing/ii_dimensional.py @@ -14,12 +14,12 @@ Np2DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=2) Np2DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=2) -Np2DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=2) +Np2DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble, dimensions=2) Np2DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=2) Np2DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=2) Np2DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=2) -Np2DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.complex256, dimensions=2) +Np2DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.clongdouble, dimensions=2) Np2DArrayComplex128 = np_array_pydantic_annotated_typing(data_type=np.complex128, dimensions=2) Np2DArrayComplex64 = np_array_pydantic_annotated_typing(data_type=np.complex64, dimensions=2) diff --git a/pydantic_numpy/typing/iii_dimensional.py b/pydantic_numpy/typing/iii_dimensional.py index 0241141..9ed1308 100644 --- a/pydantic_numpy/typing/iii_dimensional.py +++ b/pydantic_numpy/typing/iii_dimensional.py @@ -14,12 +14,12 @@ Np3DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=3) Np3DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=3) -Np3DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=3) +Np3DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble, dimensions=3) Np3DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=3) Np3DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=3) Np3DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=3) -Np3DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.complex256, dimensions=3) +Np3DArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.clongdouble, dimensions=3) Np3DArrayComplex128 = np_array_pydantic_annotated_typing(data_type=np.complex128, dimensions=3) Np3DArrayComplex64 = np_array_pydantic_annotated_typing(data_type=np.complex64, dimensions=3) diff --git a/pydantic_numpy/typing/n_dimensional.py b/pydantic_numpy/typing/n_dimensional.py index 23a2fc0..26328cc 100644 --- a/pydantic_numpy/typing/n_dimensional.py +++ b/pydantic_numpy/typing/n_dimensional.py @@ -14,12 +14,12 @@ NpNDArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16) NpNDArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8) -NpNDArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128) +NpNDArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble) NpNDArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64) NpNDArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32) NpNDArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16) -NpNDArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.complex256) +NpNDArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.clongdouble) NpNDArrayComplex128 = np_array_pydantic_annotated_typing(data_type=np.complex128) NpNDArrayComplex64 = np_array_pydantic_annotated_typing(data_type=np.complex64) diff --git a/pydantic_numpy/typing/strict_data_type/i_dimensional.py b/pydantic_numpy/typing/strict_data_type/i_dimensional.py index 60ceb5f..140a360 100644 --- a/pydantic_numpy/typing/strict_data_type/i_dimensional.py +++ b/pydantic_numpy/typing/strict_data_type/i_dimensional.py @@ -12,13 +12,13 @@ NpStrict1DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=1, strict_data_typing=True) NpStrict1DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=1, strict_data_typing=True) -NpStrict1DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=1, strict_data_typing=True) +NpStrict1DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble, dimensions=1, strict_data_typing=True) NpStrict1DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=1, strict_data_typing=True) NpStrict1DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=1, strict_data_typing=True) NpStrict1DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=1, strict_data_typing=True) NpStrict1DArrayComplex256 = np_array_pydantic_annotated_typing( - data_type=np.complex256, dimensions=1, strict_data_typing=True + data_type=np.clongdouble, dimensions=1, strict_data_typing=True ) NpStrict1DArrayComplex128 = np_array_pydantic_annotated_typing( data_type=np.complex128, dimensions=1, strict_data_typing=True diff --git a/pydantic_numpy/typing/strict_data_type/ii_dimensional.py b/pydantic_numpy/typing/strict_data_type/ii_dimensional.py index 62d8fba..acc0fdd 100644 --- a/pydantic_numpy/typing/strict_data_type/ii_dimensional.py +++ b/pydantic_numpy/typing/strict_data_type/ii_dimensional.py @@ -12,13 +12,15 @@ NpStrict2DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=2, strict_data_typing=True) NpStrict2DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=2, strict_data_typing=True) -NpStrict2DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=2, strict_data_typing=True) +NpStrict2DArrayFp128 = np_array_pydantic_annotated_typing( + data_type=np.longdouble, dimensions=2, strict_data_typing=True +) NpStrict2DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=2, strict_data_typing=True) NpStrict2DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=2, strict_data_typing=True) NpStrict2DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=2, strict_data_typing=True) NpStrict2DArrayComplex256 = np_array_pydantic_annotated_typing( - data_type=np.complex256, dimensions=2, strict_data_typing=True + data_type=np.clongdouble, dimensions=2, strict_data_typing=True ) NpStrict2DArrayComplex128 = np_array_pydantic_annotated_typing( data_type=np.complex128, dimensions=2, strict_data_typing=True diff --git a/pydantic_numpy/typing/strict_data_type/iii_dimensional.py b/pydantic_numpy/typing/strict_data_type/iii_dimensional.py index e5fbac4..0cda526 100644 --- a/pydantic_numpy/typing/strict_data_type/iii_dimensional.py +++ b/pydantic_numpy/typing/strict_data_type/iii_dimensional.py @@ -12,13 +12,15 @@ NpStrict3DArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, dimensions=3, strict_data_typing=True) NpStrict3DArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, dimensions=3, strict_data_typing=True) -NpStrict3DArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, dimensions=3, strict_data_typing=True) +NpStrict3DArrayFp128 = np_array_pydantic_annotated_typing( + data_type=np.longdouble, dimensions=3, strict_data_typing=True +) NpStrict3DArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, dimensions=3, strict_data_typing=True) NpStrict3DArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, dimensions=3, strict_data_typing=True) NpStrict3DArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, dimensions=3, strict_data_typing=True) NpStrict3DArrayComplex256 = np_array_pydantic_annotated_typing( - data_type=np.complex256, dimensions=3, strict_data_typing=True + data_type=np.clongdouble, dimensions=3, strict_data_typing=True ) NpStrict3DArrayComplex128 = np_array_pydantic_annotated_typing( data_type=np.complex128, dimensions=3, strict_data_typing=True diff --git a/pydantic_numpy/typing/strict_data_type/n_dimensional.py b/pydantic_numpy/typing/strict_data_type/n_dimensional.py index 445abfe..3a73353 100644 --- a/pydantic_numpy/typing/strict_data_type/n_dimensional.py +++ b/pydantic_numpy/typing/strict_data_type/n_dimensional.py @@ -12,12 +12,12 @@ NpStrictNDArrayUint16 = np_array_pydantic_annotated_typing(data_type=np.uint16, strict_data_typing=True) NpStrictNDArrayUint8 = np_array_pydantic_annotated_typing(data_type=np.uint8, strict_data_typing=True) -NpStrictNDArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.float128, strict_data_typing=True) +NpStrictNDArrayFp128 = np_array_pydantic_annotated_typing(data_type=np.longdouble, strict_data_typing=True) NpStrictNDArrayFp64 = np_array_pydantic_annotated_typing(data_type=np.float64, strict_data_typing=True) NpStrictNDArrayFp32 = np_array_pydantic_annotated_typing(data_type=np.float32, strict_data_typing=True) NpStrictNDArrayFp16 = np_array_pydantic_annotated_typing(data_type=np.float16, strict_data_typing=True) -NpStrictNDArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.complex256, strict_data_typing=True) +NpStrictNDArrayComplex256 = np_array_pydantic_annotated_typing(data_type=np.clongdouble, strict_data_typing=True) NpStrictNDArrayComplex128 = np_array_pydantic_annotated_typing(data_type=np.complex128, strict_data_typing=True) NpStrictNDArrayComplex64 = np_array_pydantic_annotated_typing(data_type=np.complex64, strict_data_typing=True) diff --git a/pyproject.toml b/pyproject.toml index e7c24ac..c301046 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pydantic_numpy" -version = "3.1.2" +version = "3.1.3" description = "Pydantic Model integration of the NumPy array" authors = ["Can H. Tartanoglu", "Christoph Heindl"] maintainers = ["Can H. Tartanoglu "] diff --git a/tests/helper/cache.py b/tests/helper/cache.py index abb533a..f6b5e42 100644 --- a/tests/helper/cache.py +++ b/tests/helper/cache.py @@ -1,5 +1,10 @@ from functools import cache +from typing import Optional +import numpy as np +import numpy.typing as npt +from hypothesis import strategies as st +from hypothesis.extra.numpy import arrays from pydantic import BaseModel @@ -9,3 +14,8 @@ class ModelForTesting(BaseModel): array_field: array_type_hint return ModelForTesting + + +@cache +def cached_hyp_array(numpy_dtype: npt.DTypeLike, dimensions: Optional[int] = None, *, _axis_length: int = 1): + return arrays(numpy_dtype, tuple(_axis_length for _ in range(dimensions or 1))) diff --git a/tests/helper/groups.py b/tests/helper/groups.py index 2d023ab..67d105b 100644 --- a/tests/helper/groups.py +++ b/tests/helper/groups.py @@ -11,14 +11,14 @@ np.uint32, np.uint16, np.uint8, - np.float128, + np.longdouble, np.float64, np.float32, np.float16, - np.complex256, + np.clongdouble, np.complex128, np.complex64, - np.datetime64, + # np.datetime64, np.timedelta64, ) @@ -31,15 +31,15 @@ (np.uint32, Np1DArrayUint32, 1), (np.uint16, Np1DArrayUint16, 1), (np.uint8, Np1DArrayUint8, 1), - (np.float128, Np1DArrayFp128, 1), + (np.longdouble, Np1DArrayFp128, 1), (np.float64, Np1DArrayFp64, 1), (np.float32, Np1DArrayFp32, 1), (np.float16, Np1DArrayFp16, 1), - (np.complex256, Np1DArrayComplex256, 1), + (np.clongdouble, Np1DArrayComplex256, 1), (np.complex128, Np1DArrayComplex128, 1), (np.complex64, Np1DArrayComplex64, 1), (bool, Np1DArrayBool, 1), - (np.datetime64, Np1DArrayDatetime64, 1), + # (np.datetime64, Np1DArrayDatetime64, 1), (np.timedelta64, Np1DArrayTimedelta64, 1), ] data_type_2d_array_typing_dimensions = [ @@ -51,15 +51,15 @@ (np.uint32, Np2DArrayUint32, 2), (np.uint16, Np2DArrayUint16, 2), (np.uint8, Np2DArrayUint8, 2), - (np.float128, Np2DArrayFp128, 2), + (np.longdouble, Np2DArrayFp128, 2), (np.float64, Np2DArrayFp64, 2), (np.float32, Np2DArrayFp32, 2), (np.float16, Np2DArrayFp16, 2), - (np.complex256, Np2DArrayComplex256, 2), + (np.clongdouble, Np2DArrayComplex256, 2), (np.complex128, Np2DArrayComplex128, 2), (np.complex64, Np2DArrayComplex64, 2), (bool, Np2DArrayBool, 2), - (np.datetime64, Np2DArrayDatetime64, 2), + # (np.datetime64, Np2DArrayDatetime64, 2), (np.timedelta64, Np2DArrayTimedelta64, 2), ] data_type_3d_array_typing_dimensions = [ @@ -71,15 +71,15 @@ (np.uint32, Np3DArrayUint32, 3), (np.uint16, Np3DArrayUint16, 3), (np.uint8, Np3DArrayUint8, 3), - (np.float128, Np3DArrayFp128, 3), + (np.longdouble, Np3DArrayFp128, 3), (np.float64, Np3DArrayFp64, 3), (np.float32, Np3DArrayFp32, 3), (np.float16, Np3DArrayFp16, 3), - (np.complex256, Np3DArrayComplex256, 3), + (np.clongdouble, Np3DArrayComplex256, 3), (np.complex128, Np3DArrayComplex128, 3), (np.complex64, Np3DArrayComplex64, 3), (bool, Np3DArrayBool, 3), - (np.datetime64, Np3DArrayDatetime64, 3), + # (np.datetime64, Np3DArrayDatetime64, 3), (np.timedelta64, Np3DArrayTimedelta64, 3), ] data_type_nd_array_typing_dimensions = [ @@ -91,15 +91,15 @@ (np.uint32, NpNDArrayUint32, None), (np.uint16, NpNDArrayUint16, None), (np.uint8, NpNDArrayUint8, None), - (np.float128, NpNDArrayFp128, None), + (np.longdouble, NpNDArrayFp128, None), (np.float64, NpNDArrayFp64, None), (np.float32, NpNDArrayFp32, None), (np.float16, NpNDArrayFp16, None), - (np.complex256, NpNDArrayComplex256, None), + (np.clongdouble, NpNDArrayComplex256, None), (np.complex128, NpNDArrayComplex128, None), (np.complex64, NpNDArrayComplex64, None), (bool, NpNDArrayBool, None), - (np.datetime64, NpNDArrayDatetime64, None), + # (np.datetime64, NpNDArrayDatetime64, None), (np.timedelta64, NpNDArrayTimedelta64, None), ] @@ -120,15 +120,15 @@ (np.uint32, NpStrict1DArrayUint32, 1), (np.uint16, NpStrict1DArrayUint16, 1), (np.uint8, NpStrict1DArrayUint8, 1), - (np.float128, NpStrict1DArrayFp128, 1), + (np.longdouble, NpStrict1DArrayFp128, 1), (np.float64, NpStrict1DArrayFp64, 1), (np.float32, NpStrict1DArrayFp32, 1), (np.float16, NpStrict1DArrayFp16, 1), - (np.complex256, NpStrict1DArrayComplex256, 1), + (np.clongdouble, NpStrict1DArrayComplex256, 1), (np.complex128, NpStrict1DArrayComplex128, 1), (np.complex64, NpStrict1DArrayComplex64, 1), (bool, NpStrict1DArrayBool, 1), - (np.datetime64, NpStrict1DArrayDatetime64, 1), + # (np.datetime64, NpStrict1DArrayDatetime64, 1), (np.timedelta64, NpStrict1DArrayTimedelta64, 1), ] strict_data_type_2d_array_typing_dimensions = [ @@ -140,15 +140,15 @@ (np.uint32, NpStrict2DArrayUint32, 2), (np.uint16, NpStrict2DArrayUint16, 2), (np.uint8, NpStrict2DArrayUint8, 2), - (np.float128, NpStrict2DArrayFp128, 2), + (np.longdouble, NpStrict2DArrayFp128, 2), (np.float64, NpStrict2DArrayFp64, 2), (np.float32, NpStrict2DArrayFp32, 2), (np.float16, NpStrict2DArrayFp16, 2), - (np.complex256, NpStrict2DArrayComplex256, 2), + (np.clongdouble, NpStrict2DArrayComplex256, 2), (np.complex128, NpStrict2DArrayComplex128, 2), (np.complex64, NpStrict2DArrayComplex64, 2), (bool, NpStrict2DArrayBool, 2), - (np.datetime64, NpStrict2DArrayDatetime64, 2), + # (np.datetime64, NpStrict2DArrayDatetime64, 2), (np.timedelta64, NpStrict2DArrayTimedelta64, 2), ] strict_data_type_3d_array_typing_dimensions = [ @@ -160,15 +160,15 @@ (np.uint32, NpStrict3DArrayUint32, 3), (np.uint16, NpStrict3DArrayUint16, 3), (np.uint8, NpStrict3DArrayUint8, 3), - (np.float128, NpStrict3DArrayFp128, 3), + (np.longdouble, NpStrict3DArrayFp128, 3), (np.float64, NpStrict3DArrayFp64, 3), (np.float32, NpStrict3DArrayFp32, 3), (np.float16, NpStrict3DArrayFp16, 3), - (np.complex256, NpStrict3DArrayComplex256, 3), + (np.clongdouble, NpStrict3DArrayComplex256, 3), (np.complex128, NpStrict3DArrayComplex128, 3), (np.complex64, NpStrict3DArrayComplex64, 3), (bool, NpStrict3DArrayBool, 3), - (np.datetime64, NpStrict3DArrayDatetime64, 3), + # (np.datetime64, NpStrict3DArrayDatetime64, 3), (np.timedelta64, NpStrict3DArrayTimedelta64, 3), ] strict_data_type_nd_array_typing_dimensions = [ @@ -180,15 +180,15 @@ (np.uint32, NpStrictNDArrayUint32, None), (np.uint16, NpStrictNDArrayUint16, None), (np.uint8, NpStrictNDArrayUint8, None), - (np.float128, NpStrictNDArrayFp128, None), + (np.longdouble, NpStrictNDArrayFp128, None), (np.float64, NpStrictNDArrayFp64, None), (np.float32, NpStrictNDArrayFp32, None), (np.float16, NpStrictNDArrayFp16, None), - (np.complex256, NpStrictNDArrayComplex256, None), + (np.clongdouble, NpStrictNDArrayComplex256, None), (np.complex128, NpStrictNDArrayComplex128, None), (np.complex64, NpStrictNDArrayComplex64, None), (bool, NpStrictNDArrayBool, None), - (np.datetime64, NpStrictNDArrayDatetime64, None), + # (np.datetime64, NpStrictNDArrayDatetime64, None), (np.timedelta64, NpStrictNDArrayTimedelta64, None), ] diff --git a/tests/test_np_model.py b/tests/test_np_model.py index d62e79b..79d12d6 100644 --- a/tests/test_np_model.py +++ b/tests/test_np_model.py @@ -1,3 +1,4 @@ +import os import tempfile from pathlib import Path @@ -8,6 +9,7 @@ from pydantic_numpy.model import NumpyModel from pydantic_numpy.model.np_model import model_agnostic_load from pydantic_numpy.typing import NpNDArray +from tests.helper.cache import cached_hyp_array TEST_MODEL_OBJECT_ID = "test" OTHER_TEST_MODEL_OBJECT_ID = "other_test" @@ -24,7 +26,7 @@ class TestWithArbitraryForTest(NumpyModelForTest, arbitrary_types_allowed=True): def _create_example_array(): - return arrays(np.float64, (1,)).example() + return cached_hyp_array(np.float64, 1).example() def _numpy_model(): @@ -48,49 +50,47 @@ def numpy_model_with_arbitrary(request): return request.param -def test_io_yaml(numpy_model: NumpyModel) -> None: - with tempfile.TemporaryDirectory() as tmp_dirname: - numpy_model.dump(tmp_dirname, TEST_MODEL_OBJECT_ID) - assert numpy_model.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model +if os.name != "nt": + def test_io_yaml(numpy_model: NumpyModel) -> None: + with tempfile.TemporaryDirectory() as tmp_dirname: + numpy_model.dump(tmp_dirname, TEST_MODEL_OBJECT_ID) + assert numpy_model.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model -def test_io_compressed_pickle(numpy_model_with_arbitrary: NumpyModel) -> None: - with tempfile.TemporaryDirectory() as tmp_dirname: - numpy_model_with_arbitrary.dump(tmp_dirname, TEST_MODEL_OBJECT_ID, pickle=True) - assert numpy_model_with_arbitrary.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model_with_arbitrary + def test_io_compressed_pickle(numpy_model_with_arbitrary: NumpyModel) -> None: + with tempfile.TemporaryDirectory() as tmp_dirname: + numpy_model_with_arbitrary.dump(tmp_dirname, TEST_MODEL_OBJECT_ID, pickle=True) + assert numpy_model_with_arbitrary.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model_with_arbitrary + def test_io_pickle(numpy_model_with_arbitrary: NumpyModel) -> None: + with tempfile.TemporaryDirectory() as tmp_dirname: + numpy_model_with_arbitrary.dump(tmp_dirname, TEST_MODEL_OBJECT_ID, pickle=True, compress=False) + assert numpy_model_with_arbitrary.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model_with_arbitrary -def test_io_pickle(numpy_model_with_arbitrary: NumpyModel) -> None: - with tempfile.TemporaryDirectory() as tmp_dirname: - numpy_model_with_arbitrary.dump(tmp_dirname, TEST_MODEL_OBJECT_ID, pickle=True, compress=False) - assert numpy_model_with_arbitrary.load(tmp_dirname, TEST_MODEL_OBJECT_ID) == numpy_model_with_arbitrary + def test_typing_json_dump(numpy_model: NumpyModel): + assert numpy_model.model_dump_json() == '{"array":"%s","non_array":%s}' % ( + np.array2string(numpy_model.array), + NON_ARRAY_VALUE, + ), "" + def test_model_agnostic_load(): + class NumpyModelAForTest(NumpyModel): + array: NpNDArray + non_array: int -def test_typing_json_dump(numpy_model: NumpyModel): - assert numpy_model.model_dump_json() == '{"array":"%s","non_array":%s}' % ( - np.array2string(numpy_model.array), - NON_ARRAY_VALUE, - ), "" + class NumpyModelBForTest(NumpyModel): + array: NpNDArray + non_array: int + model_a = NumpyModelAForTest(array=_create_example_array(), non_array=NON_ARRAY_VALUE) + model_b = NumpyModelBForTest(array=_create_example_array(), non_array=NON_ARRAY_VALUE) -def test_model_agnostic_load(): - class NumpyModelAForTest(NumpyModel): - array: NpNDArray - non_array: int + with tempfile.TemporaryDirectory() as tmp_dirname: + tmp_dir_path = Path(tmp_dirname) - class NumpyModelBForTest(NumpyModel): - array: NpNDArray - non_array: int + model_a.dump(tmp_dir_path, TEST_MODEL_OBJECT_ID) + model_b.dump(tmp_dir_path, OTHER_TEST_MODEL_OBJECT_ID) - model_a = NumpyModelAForTest(array=_create_example_array(), non_array=NON_ARRAY_VALUE) - model_b = NumpyModelBForTest(array=_create_example_array(), non_array=NON_ARRAY_VALUE) - - with tempfile.TemporaryDirectory() as tmp_dirname: - tmp_dir_path = Path(tmp_dirname) - - model_a.dump(tmp_dir_path, TEST_MODEL_OBJECT_ID) - model_b.dump(tmp_dir_path, OTHER_TEST_MODEL_OBJECT_ID) - - models = [model_a, model_b] - assert model_a == model_agnostic_load(tmp_dir_path, TEST_MODEL_OBJECT_ID, models=models) - assert model_b == model_agnostic_load(tmp_dir_path, OTHER_TEST_MODEL_OBJECT_ID, models=models) + models = [model_a, model_b] + assert model_a == model_agnostic_load(tmp_dir_path, TEST_MODEL_OBJECT_ID, models=models) + assert model_b == model_agnostic_load(tmp_dir_path, OTHER_TEST_MODEL_OBJECT_ID, models=models) diff --git a/tests/test_typing.py b/tests/test_typing.py index 5ef3370..8900b51 100644 --- a/tests/test_typing.py +++ b/tests/test_typing.py @@ -1,3 +1,4 @@ +import os import tempfile from pathlib import Path from typing import Optional @@ -5,13 +6,15 @@ import numpy as np import numpy.typing as npt import pytest +from hypothesis.extra import numpy from hypothesis.extra.numpy import arrays +from hypothesis import strategies as st, given from pydantic import ValidationError from pydantic_numpy.helper.validation import PydanticNumpyMultiArrayNumpyFileOnFilePath from pydantic_numpy.model import MultiArrayNumpyFile from pydantic_numpy.util import np_general_all_close -from tests.helper.cache import cached_calculation +from tests.helper.cache import cached_calculation, cached_hyp_array from tests.helper.groups import ( data_type_array_typing_dimensions, dimension_testing_group, @@ -19,14 +22,10 @@ supported_data_types, ) -AXIS_LENGTH = 1 - @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) def test_correct_type(numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int]): - assert cached_calculation(pydantic_typing)( - array_field=arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(dimensions or 1))).example() - ) + assert cached_calculation(pydantic_typing)(array_field=cached_hyp_array(numpy_dtype, dimensions).example()) @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", strict_data_type_nd_array_typing_dimensions) @@ -35,7 +34,7 @@ def test_wrong_dtype_type(numpy_dtype: npt.DTypeLike, pydantic_typing, dimension if wrong_numpy_type == numpy_dtype: return True - bad_array = arrays(wrong_numpy_type, tuple(AXIS_LENGTH for _ in range(dimensions or 5))).example() + bad_array = cached_hyp_array(wrong_numpy_type, dimensions).example() with pytest.raises(ValidationError): cached_calculation(pydantic_typing)(array_field=bad_array) @@ -44,54 +43,59 @@ def test_wrong_dtype_type(numpy_dtype: npt.DTypeLike, pydantic_typing, dimension def test_wrong_dimension(numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int]): wrong_dimension = dimensions + 1 - bad_array = arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(wrong_dimension or 5))).example() + bad_array = cached_hyp_array(numpy_dtype, wrong_dimension).example() with pytest.raises(ValueError): cached_calculation(pydantic_typing)(array_field=bad_array) -@pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) -def test_file_path_passing_validation(numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int]): - hyp_array = arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(dimensions or 1))).example() - with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: - np.savez_compressed(tf.name, my_array=hyp_array) - numpy_model = cached_calculation(pydantic_typing)(array_field=Path(tf.name)) +if os.name != "nt": - assert np_general_all_close(numpy_model.array_field, hyp_array) + @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) + def test_file_path_passing_validation(numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int]): + hyp_array = cached_hyp_array(numpy_dtype, dimensions).example() + with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: + np.savez_compressed(tf.name, my_array=hyp_array) + numpy_model = cached_calculation(pydantic_typing)(array_field=Path(tf.name)) -@pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) -def test_file_path_error_on_reading_single_array_file( - numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int] -): - hyp_array = arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(dimensions or 1))).example() - with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: - np.savez_compressed(tf.name, my_array=hyp_array, my_identical_array=hyp_array) - model = cached_calculation(pydantic_typing) + assert np_general_all_close(numpy_model.array_field, hyp_array) - with pytest.raises(PydanticNumpyMultiArrayNumpyFileOnFilePath): - model(array_field=Path(tf.name)) + @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) + def test_file_path_error_on_reading_single_array_file( + numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int] + ): + hyp_array = cached_hyp_array(numpy_dtype, dimensions).example() + with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: + np.savez_compressed(tf.name, my_array=hyp_array, my_identical_array=hyp_array) + model = cached_calculation(pydantic_typing) -@pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) -def test_multi_array_numpy_passing_validation(numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int]): - hyp_array = arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(dimensions or 1))).example() - with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: - np.savez_compressed(tf.name, my_array=hyp_array) - numpy_model = cached_calculation(pydantic_typing)( - array_field=MultiArrayNumpyFile(path=Path(tf.name), key="my_array") - ) + with pytest.raises(PydanticNumpyMultiArrayNumpyFileOnFilePath): + model(array_field=Path(tf.name)) - assert np_general_all_close(numpy_model.array_field, hyp_array) + @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) + def test_multi_array_numpy_passing_validation( + numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int] + ): + hyp_array = cached_hyp_array(numpy_dtype, dimensions).example() + with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npz") as tf: + np.savez_compressed(tf.name, my_array=hyp_array) + numpy_model = cached_calculation(pydantic_typing)( + array_field=MultiArrayNumpyFile(path=Path(tf.name), key="my_array") + ) -@pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) -def test_multi_array_numpy_error_on_reading_single_array_file( - numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int] -): - hyp_array = arrays(numpy_dtype, tuple(AXIS_LENGTH for _ in range(dimensions or 1))).example() - with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npy") as tf: - np.save(tf.name, hyp_array) - model = cached_calculation(pydantic_typing) - - with pytest.raises(AttributeError): - model(array_field=MultiArrayNumpyFile(path=Path(tf.name), key="my_array")) + assert np_general_all_close(numpy_model.array_field, hyp_array) + + @pytest.mark.parametrize("numpy_dtype,pydantic_typing,dimensions", data_type_array_typing_dimensions) + def test_multi_array_numpy_error_on_reading_single_array_file( + numpy_dtype: npt.DTypeLike, pydantic_typing, dimensions: Optional[int] + ): + hyp_array = cached_hyp_array(numpy_dtype, dimensions).example() + + with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".npy") as tf: + np.save(tf.name, hyp_array) + model = cached_calculation(pydantic_typing) + + with pytest.raises(AttributeError): + model(array_field=MultiArrayNumpyFile(path=Path(tf.name), key="my_array"))