Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions numcodecs/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import codecs

import numpy as np
import numpy.typing as npt

from .ndarray_like import NDArrayLike, is_ndarray_like
from .ndarray_like import is_ndarray_like


def ensure_ndarray_like(buf) -> NDArrayLike:
def ensure_ndarray_like(buf) -> npt.NDArray:
"""Convenience function to coerce `buf` to ndarray-like array.

Parameters
Expand Down Expand Up @@ -38,7 +39,7 @@ def ensure_ndarray_like(buf) -> NDArrayLike:
mem = memoryview(buf)
# instantiate array from memoryview, ensures no copy
buf = np.array(mem, copy=False)
return buf
return np.asanyarray(buf, copy=False)


def ensure_ndarray(buf) -> np.ndarray:
Expand All @@ -63,7 +64,7 @@ def ensure_ndarray(buf) -> np.ndarray:
return np.array(ensure_ndarray_like(buf), copy=False)


def ensure_contiguous_ndarray_like(buf, max_buffer_size=None, flatten=True) -> NDArrayLike:
def ensure_contiguous_ndarray_like(buf, max_buffer_size=None, flatten=True) -> npt.ArrayLike:
"""Convenience function to coerce `buf` to ndarray-like array.
Also ensures that the returned value exports fully contiguous memory,
and supports the new-style buffer interface. If the optional max_buffer_size is
Expand Down Expand Up @@ -174,7 +175,7 @@ def ensure_text(s, encoding="utf-8"):
return s


def ndarray_copy(src, dst) -> NDArrayLike:
def ndarray_copy(src, dst) -> npt.NDArray:
"""Copy the contents of the array from `src` to `dst`."""

if dst is None:
Expand Down
63 changes: 2 additions & 61 deletions numcodecs/ndarray_like.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,6 @@
from typing import Any, ClassVar, Protocol, runtime_checkable


class _CachedProtocolMeta(Protocol.__class__): # type: ignore[name-defined]
"""Custom implementation of @runtime_checkable

The native implementation of @runtime_checkable is slow,
see <https://github.com/zarr-developers/numcodecs/issues/379>.

This metaclass keeps an unbounded cache of the result of
isinstance checks using the object's class as the cache key.
"""

_instancecheck_cache: ClassVar[dict[tuple[type, type], bool]] = {}

def __instancecheck__(self, instance):
key = (self, instance.__class__)
ret = self._instancecheck_cache.get(key)
if ret is None:
ret = super().__instancecheck__(instance)
self._instancecheck_cache[key] = ret
return ret


@runtime_checkable
class DType(Protocol, metaclass=_CachedProtocolMeta):
itemsize: int
name: str
kind: str


@runtime_checkable
class FlagsObj(Protocol, metaclass=_CachedProtocolMeta):
c_contiguous: bool
f_contiguous: bool
owndata: bool


@runtime_checkable
class NDArrayLike(Protocol, metaclass=_CachedProtocolMeta):
dtype: DType
shape: tuple[int, ...]
strides: tuple[int, ...]
ndim: int
size: int
itemsize: int
nbytes: int
flags: FlagsObj

def __len__(self) -> int: ... # pragma: no cover

def __getitem__(self, key) -> Any: ... # pragma: no cover

def __setitem__(self, key, value): ... # pragma: no cover

def tobytes(self, order: str | None = ...) -> bytes: ... # pragma: no cover

def reshape(self, *shape: int, order: str = ...) -> "NDArrayLike": ... # pragma: no cover

def view(self, dtype: DType = ...) -> "NDArrayLike": ... # pragma: no cover
import numpy.typing as npt


def is_ndarray_like(obj: object) -> bool:
"""Return True when `obj` is ndarray-like"""
return isinstance(obj, NDArrayLike)
return isinstance(obj, npt.ArrayLike)
48 changes: 0 additions & 48 deletions numcodecs/tests/test_ndarray_like.py

This file was deleted.

Loading