mirror of
https://github.com/p2p-ld/numpydantic.git
synced 2024-11-12 17:54:29 +00:00
linting for tests
This commit is contained in:
parent
f291afbbe2
commit
8f1eb6e5b4
20 changed files with 93 additions and 99 deletions
|
@ -127,8 +127,7 @@ markers = [
|
|||
|
||||
[tool.ruff]
|
||||
target-version = "py39"
|
||||
include = ["src/numpydantic/**/*.py", "pyproject.toml"]
|
||||
exclude = ["tests"]
|
||||
include = ["src/numpydantic/**/*.py", "tests/**/*.py", "pyproject.toml"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
|
@ -177,6 +176,10 @@ ignore = [
|
|||
|
||||
fixable = ["ALL"]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"src/numpydantic/testing/*" = ["D", "F722"]
|
||||
"tests/*" = ["D", "F403", "F722", "ANN", ]
|
||||
|
||||
[tool.mypy]
|
||||
plugins = [
|
||||
"pydantic.mypy"
|
||||
|
|
|
@ -18,7 +18,6 @@ else:
|
|||
YES_PIPE = False
|
||||
|
||||
|
||||
|
||||
class BasicModel(BaseModel):
|
||||
x: int
|
||||
|
||||
|
@ -129,4 +128,3 @@ if YES_PIPE:
|
|||
"union-pipe-str",
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from typing import Any, Tuple, Type, Union
|
||||
|
||||
import numpy as np
|
||||
from pydantic import BaseModel, ConfigDict, computed_field
|
||||
|
||||
from numpydantic import NDArray, Shape
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import sys
|
||||
|
||||
from numpydantic.testing.cases import YES_PIPE, RGB_UNION, UNION_PIPE, DTYPE_CASES, DTYPE_IDS
|
||||
import pytest
|
||||
|
||||
from numpydantic.testing.cases import (
|
||||
DTYPE_CASES,
|
||||
DTYPE_IDS,
|
||||
RGB_UNION,
|
||||
)
|
||||
from numpydantic.testing.helpers import ValidationCase
|
||||
from tests.fixtures import *
|
||||
|
||||
|
@ -14,9 +17,6 @@ def pytest_addoption(parser):
|
|||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
scope="module",
|
||||
params=[
|
||||
|
|
4
tests/fixtures/__init__.py
vendored
4
tests/fixtures/__init__.py
vendored
|
@ -1,3 +1,3 @@
|
|||
from .paths import *
|
||||
from .generation import *
|
||||
from .models import *
|
||||
from .models import *
|
||||
from .paths import *
|
||||
|
|
9
tests/fixtures/generation.py
vendored
9
tests/fixtures/generation.py
vendored
|
@ -24,15 +24,16 @@ def hdf5_array(
|
|||
compound: bool = False,
|
||||
) -> H5ArrayPath:
|
||||
array_path = "/" + "_".join([str(s) for s in shape]) + "__" + dtype.__name__
|
||||
|
||||
generator = np.random.default_rng()
|
||||
|
||||
if not compound:
|
||||
if dtype is str:
|
||||
data = np.random.random(shape).astype(bytes)
|
||||
data = generator.random(shape).astype(bytes)
|
||||
elif dtype is datetime:
|
||||
data = np.empty(shape, dtype="S32")
|
||||
data.fill(datetime.now(timezone.utc).isoformat().encode("utf-8"))
|
||||
else:
|
||||
data = np.random.random(shape).astype(dtype)
|
||||
data = generator.random(shape).astype(dtype)
|
||||
|
||||
h5path = H5ArrayPath(hdf5_file, array_path)
|
||||
else:
|
||||
|
@ -64,7 +65,7 @@ def zarr_nested_array(tmp_output_dir_func) -> ZarrArrayPath:
|
|||
file = tmp_output_dir_func / "nested.zarr"
|
||||
path = "a/b/c"
|
||||
root = zarr.open(str(file), mode="w")
|
||||
array = root.zeros(path, shape=(100, 100), chunks=(10, 10))
|
||||
_ = root.zeros(path, shape=(100, 100), chunks=(10, 10))
|
||||
return ZarrArrayPath(file=file, path=path)
|
||||
|
||||
|
||||
|
|
2
tests/fixtures/models.py
vendored
2
tests/fixtures/models.py
vendored
|
@ -1,4 +1,4 @@
|
|||
from typing import Callable, Tuple, Union, Type, Optional, Any
|
||||
from typing import Any, Callable, Optional, Tuple, Type, Union
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
|
3
tests/fixtures/paths.py
vendored
3
tests/fixtures/paths.py
vendored
|
@ -20,7 +20,8 @@ def tmp_output_dir(request: pytest.FixtureRequest) -> Path:
|
|||
except PermissionError as e:
|
||||
# sporadic error on windows machines...
|
||||
warn(
|
||||
f"Temporary directory could not be removed due to a permissions error: \n{str(e)}"
|
||||
"Temporary directory could not be removed due to a permissions error: "
|
||||
f"\n{str(e)}"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import pytest
|
||||
|
||||
from typing import Callable, Tuple, Type
|
||||
import numpy as np
|
||||
|
||||
import dask.array as da
|
||||
import numpy as np
|
||||
import pytest
|
||||
import zarr
|
||||
from pydantic import BaseModel
|
||||
|
||||
from numpydantic import interface, NDArray
|
||||
from numpydantic import NDArray, interface
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import pytest
|
||||
import json
|
||||
|
||||
import dask.array as da
|
||||
import pytest
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
from numpydantic.interface import DaskInterface
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
|
||||
from numpydantic.interface import DaskInterface
|
||||
from numpydantic.testing.helpers import ValidationCase
|
||||
|
||||
pytestmark = pytest.mark.dask
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import json
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import h5py
|
||||
import numpy as np
|
||||
import pytest
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
import numpy as np
|
||||
from numpydantic import NDArray, Shape
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
from numpydantic.interface import H5Interface
|
||||
from numpydantic.interface.hdf5 import H5ArrayPath, H5Proxy
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
|
||||
from numpydantic.testing.helpers import ValidationCase
|
||||
|
||||
pytestmark = pytest.mark.hdf5
|
||||
|
@ -221,10 +220,7 @@ def test_empty_dataset(dtype, tmp_path):
|
|||
Empty datasets shouldn't choke us during validation
|
||||
"""
|
||||
array_path = tmp_path / "test.h5"
|
||||
if dtype in (str, datetime):
|
||||
np_dtype = "S32"
|
||||
else:
|
||||
np_dtype = dtype
|
||||
np_dtype = "S32" if dtype in (str, datetime) else dtype
|
||||
|
||||
with h5py.File(array_path, "w") as h5f:
|
||||
_ = h5f.create_dataset(name="/data", dtype=np_dtype)
|
||||
|
|
|
@ -6,18 +6,17 @@ for tests that should apply to all interfaces, use ``test_interfaces.py``
|
|||
import gc
|
||||
from typing import Literal
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from numpydantic.interface import (
|
||||
Interface,
|
||||
JsonDict,
|
||||
InterfaceMark,
|
||||
NumpyInterface,
|
||||
JsonDict,
|
||||
MarkedJson,
|
||||
NumpyInterface,
|
||||
)
|
||||
from pydantic import ValidationError
|
||||
|
||||
from numpydantic.interface.interface import V
|
||||
|
||||
|
||||
|
@ -46,9 +45,7 @@ def interfaces():
|
|||
@classmethod
|
||||
def check(cls, array):
|
||||
cls.checked = True
|
||||
if isinstance(array, list):
|
||||
return True
|
||||
return False
|
||||
return isinstance(array, list)
|
||||
|
||||
@classmethod
|
||||
def enabled(cls) -> bool:
|
||||
|
@ -94,7 +91,8 @@ def interfaces():
|
|||
|
||||
def test_interface_match_error(interfaces):
|
||||
"""
|
||||
Test that `match` and `match_output` raises errors when no or multiple matches are found
|
||||
Test that `match` and `match_output` raises errors when no or multiple matches
|
||||
are found
|
||||
"""
|
||||
with pytest.raises(ValueError) as e:
|
||||
Interface.match([1, 2, 3])
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
Tests that should be applied to all interfaces
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from typing import Callable
|
||||
from importlib.metadata import version
|
||||
import json
|
||||
from importlib.metadata import version
|
||||
from typing import Callable
|
||||
|
||||
import numpy as np
|
||||
import dask.array as da
|
||||
from zarr.core import Array as ZarrArray
|
||||
import numpy as np
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
from zarr.core import Array as ZarrArray
|
||||
|
||||
from numpydantic.interface import Interface, InterfaceMark, MarkedJson
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import numpy as np
|
||||
import pytest
|
||||
from pydantic import ValidationError, BaseModel
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
from numpydantic.testing.helpers import ValidationCase
|
||||
|
||||
pytestmark = pytest.mark.numpy
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
Needs to be refactored to DRY, but works for now
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
import cv2
|
||||
|
||||
import cv2
|
||||
import pytest
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
from numpydantic import NDArray, Shape
|
||||
|
@ -65,7 +63,7 @@ def test_video_wrong_shape(avi_video):
|
|||
|
||||
# should correctly validate :)
|
||||
with pytest.raises(ValidationError):
|
||||
instance = MyModel(array=vid)
|
||||
_ = MyModel(array=vid)
|
||||
|
||||
|
||||
@pytest.mark.proxy
|
||||
|
|
|
@ -2,14 +2,11 @@ import json
|
|||
|
||||
import pytest
|
||||
import zarr
|
||||
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from numcodecs import Pickle
|
||||
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
from numpydantic.interface import ZarrInterface
|
||||
from numpydantic.interface.zarr import ZarrArrayPath
|
||||
from numpydantic.exceptions import DtypeError, ShapeError
|
||||
|
||||
from numpydantic.testing.helpers import ValidationCase
|
||||
|
||||
pytestmark = pytest.mark.zarr
|
||||
|
@ -36,7 +33,7 @@ def nested_dir_array(tmp_output_dir_func) -> zarr.NestedDirectoryStore:
|
|||
def _zarr_array(case: ValidationCase, store) -> zarr.core.Array:
|
||||
if issubclass(case.dtype, BaseModel):
|
||||
pytest.skip(
|
||||
f"Zarr can't handle objects properly at the moment, "
|
||||
"Zarr can't handle objects properly at the moment, "
|
||||
"see https://github.com/zarr-developers/zarr-python/issues/2081"
|
||||
)
|
||||
# return zarr.full(
|
||||
|
@ -103,14 +100,14 @@ def test_zarr_from_tuple(array, model_blank, request):
|
|||
"""Should be able to do the same validation logic from tuples as an input"""
|
||||
array = request.getfixturevalue(array)
|
||||
if isinstance(array, ZarrArrayPath):
|
||||
instance = model_blank(array=(array.file, array.path))
|
||||
_ = model_blank(array=(array.file, array.path))
|
||||
else:
|
||||
instance = model_blank(array=(array,))
|
||||
_ = model_blank(array=(array,))
|
||||
|
||||
|
||||
def test_zarr_from_path(zarr_array, model_blank):
|
||||
"""Should be able to just pass a path"""
|
||||
instance = model_blank(array=zarr_array)
|
||||
_ = model_blank(array=zarr_array)
|
||||
|
||||
|
||||
def test_zarr_array_path_from_iterable(zarr_array):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from numpydantic import NDArray
|
||||
|
@ -40,4 +41,4 @@ def test_stub_revealed_type():
|
|||
"""
|
||||
Check that the revealed type matches the stub
|
||||
"""
|
||||
type = reveal_type(NDArray)
|
||||
_ = reveal_type(NDArray)
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import pytest
|
||||
|
||||
from typing import Union, Optional, Any
|
||||
import json
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
import numpy as np
|
||||
from pydantic import BaseModel, ValidationError, Field
|
||||
import pytest
|
||||
from pydantic import BaseModel, Field, ValidationError
|
||||
|
||||
|
||||
from numpydantic import NDArray, Shape
|
||||
from numpydantic.exceptions import ShapeError, DtypeError
|
||||
from numpydantic import dtype
|
||||
from numpydantic import NDArray, Shape, dtype
|
||||
from numpydantic.dtype import Number
|
||||
from numpydantic.exceptions import DtypeError
|
||||
|
||||
|
||||
@pytest.mark.json_schema
|
||||
|
@ -28,15 +25,15 @@ def test_ndarray_type():
|
|||
assert schema["properties"]["array"]["minItems"] == 2
|
||||
|
||||
# models should instantiate correctly!
|
||||
instance = Model(array=np.zeros((2, 3)))
|
||||
_ = Model(array=np.zeros((2, 3)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.zeros((4, 6)))
|
||||
_ = Model(array=np.zeros((4, 6)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.ones((2, 3), dtype=bool))
|
||||
_ = Model(array=np.ones((2, 3), dtype=bool))
|
||||
|
||||
instance = Model(array=np.zeros((2, 3)), array_any=np.ones((3, 4, 5)))
|
||||
_ = Model(array=np.zeros((2, 3)), array_any=np.ones((3, 4, 5)))
|
||||
|
||||
|
||||
@pytest.mark.dtype
|
||||
|
@ -93,6 +90,7 @@ def test_schema_number():
|
|||
|
||||
|
||||
def test_ndarray_union():
|
||||
generator = np.random.default_rng()
|
||||
class Model(BaseModel):
|
||||
array: Optional[
|
||||
Union[
|
||||
|
@ -102,22 +100,22 @@ def test_ndarray_union():
|
|||
]
|
||||
] = Field(None)
|
||||
|
||||
instance = Model()
|
||||
instance = Model(array=np.random.random((5, 10)))
|
||||
instance = Model(array=np.random.random((5, 10, 3)))
|
||||
instance = Model(array=np.random.random((5, 10, 3, 4)))
|
||||
_ = Model()
|
||||
_ = Model(array=generator.random((5, 10)))
|
||||
_ = Model(array=generator.random((5, 10, 3)))
|
||||
_ = Model(array=generator.random((5, 10, 3, 4)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.random.random((5,)))
|
||||
_ = Model(array=generator.random((5,)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.random.random((5, 10, 4)))
|
||||
_ = Model(array=generator.random((5, 10, 4)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.random.random((5, 10, 3, 6)))
|
||||
_ = Model(array=generator.random((5, 10, 3, 6)))
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
instance = Model(array=np.random.random((5, 10, 4, 6)))
|
||||
_ = Model(array=generator.random((5, 10, 4, 6)))
|
||||
|
||||
|
||||
@pytest.mark.shape
|
||||
|
@ -127,15 +125,16 @@ def test_ndarray_unparameterized(dtype):
|
|||
"""
|
||||
NDArray without any parameters is any shape, any type
|
||||
"""
|
||||
generator = np.random.default_rng()
|
||||
|
||||
class Model(BaseModel):
|
||||
array: NDArray
|
||||
|
||||
# not very sophisticated fuzzing of "any shape"
|
||||
test_cases = 10
|
||||
for i in range(test_cases):
|
||||
n_dimensions = np.random.randint(1, 8)
|
||||
dim_sizes = np.random.randint(1, 7, size=n_dimensions)
|
||||
for _ in range(test_cases):
|
||||
n_dimensions = generator.integers(1, 8)
|
||||
dim_sizes = generator.integers(1, 7, size=n_dimensions)
|
||||
_ = Model(array=np.zeros(dim_sizes, dtype=dtype))
|
||||
|
||||
|
||||
|
@ -144,15 +143,16 @@ def test_ndarray_any():
|
|||
"""
|
||||
using :class:`typing.Any` in for the shape means any shape
|
||||
"""
|
||||
generator = np.random.default_rng()
|
||||
|
||||
class Model(BaseModel):
|
||||
array: NDArray[Any, np.uint8]
|
||||
|
||||
# not very sophisticated fuzzing of "any shape"
|
||||
test_cases = 100
|
||||
for i in range(test_cases):
|
||||
n_dimensions = np.random.randint(1, 8)
|
||||
dim_sizes = np.random.randint(1, 16, size=n_dimensions)
|
||||
for _ in range(test_cases):
|
||||
n_dimensions = generator.integers(1, 8)
|
||||
dim_sizes = generator.integers(1, 16, size=n_dimensions)
|
||||
_ = Model(array=np.zeros(dim_sizes, dtype=np.uint8))
|
||||
|
||||
|
||||
|
@ -191,7 +191,7 @@ def test_ndarray_serialize():
|
|||
class Model(BaseModel):
|
||||
array: NDArray[Any, Number]
|
||||
|
||||
mod = Model(array=np.random.random((3, 3)))
|
||||
mod = Model(array=np.random.default_rng().random((3, 3)))
|
||||
mod_str = mod.model_dump_json()
|
||||
mod_json = json.loads(mod_str)
|
||||
assert isinstance(mod_json["array"], list)
|
||||
|
|
|
@ -3,14 +3,15 @@ Test serialization-specific functionality that doesn't need to be
|
|||
applied across every interface (use test_interface/test_interfaces for that
|
||||
"""
|
||||
|
||||
import h5py
|
||||
import pytest
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
import numpy as np
|
||||
import json
|
||||
|
||||
from numpydantic.serialization import _walk_and_apply, _relativize_paths, relative_path
|
||||
import h5py
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from numpydantic.serialization import _relativize_paths, _walk_and_apply, relative_path
|
||||
|
||||
pytestmark = pytest.mark.serialization
|
||||
|
||||
|
@ -115,7 +116,8 @@ def test_absolute_path(hdf5_at_path, tmp_output_dir, model_blank):
|
|||
|
||||
def test_walk_and_apply():
|
||||
"""
|
||||
Walk and apply should recursively apply a function to everything in a nesty structure
|
||||
Walk and apply should recursively apply a function to everything in a
|
||||
nesty structure
|
||||
"""
|
||||
test = {
|
||||
"a": 1,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import pytest
|
||||
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, ValidationError
|
||||
import numpy as np
|
||||
import pytest
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
from numpydantic import NDArray, Shape
|
||||
|
||||
|
|
Loading…
Reference in a new issue