Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error at runtime if zfpy isn't present #666

Closed
wants to merge 1 commit into from
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
5 changes: 2 additions & 3 deletions numcodecs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,9 @@
register_codec(Fletcher32)

# Optional depenedencies
with suppress(ImportError):
from numcodecs.zfpy import ZFPY
from numcodecs.zfpy import ZFPY

register_codec(ZFPY)
register_codec(ZFPY)

with suppress(ImportError):
from numcodecs.msgpacks import MsgPack
Expand Down
204 changes: 102 additions & 102 deletions numcodecs/zfpy.py
Original file line number Diff line number Diff line change
@@ -1,113 +1,113 @@
import warnings
from contextlib import suppress
from importlib.metadata import PackageNotFoundError, version
import importlib.util
from importlib.metadata import version
from types import ModuleType
from typing import Optional

_zfpy: Optional[ModuleType] = None
import numpy as np

_zfpy_version: tuple = ()
with suppress(PackageNotFoundError):
_zfpy_version = tuple(map(int, version("zfpy").split(".")))
from .abc import Codec
from .compat import ensure_bytes, ensure_contiguous_ndarray, ndarray_copy

_zfpy: Optional[ModuleType]
_zfpy_spec = importlib.util.find_spec("zfpy")

if _zfpy_spec is None:
_zfpy = None

Check warning on line 15 in numcodecs/zfpy.py

View check run for this annotation

Codecov / codecov/patch

numcodecs/zfpy.py#L15

Added line #L15 was not covered by tests
else:
import zfpy as _zfpy # type: ignore[no-redef]

if _zfpy_version:
# Check NumPy version
_numpy_version: tuple = tuple(map(int, version("numpy").split('.')))

def _check_compatible_numpy() -> None:
_numpy_version = tuple(map(int, version("numpy").split('.')))
_zfpy_version = tuple(map(int, version("zfpy").split(".")))
if _numpy_version >= (2, 0, 0) and _zfpy_version <= (1, 0, 1): # pragma: no cover
_zfpy_version = ()
warnings.warn(
raise RuntimeError(
"NumPy version >= 2.0.0 detected. The zfpy library is incompatible with this version of NumPy. "
"Please downgrade to NumPy < 2.0.0 or wait for an update from zfpy.",
UserWarning,
stacklevel=2,
)
else:
with suppress(ImportError):
import zfpy as _zfpy # type: ignore[no-redef]

if _zfpy:
import numpy as np

from .abc import Codec
from .compat import ensure_bytes, ensure_contiguous_ndarray, ndarray_copy

# noinspection PyShadowingBuiltins
class ZFPY(Codec):
"""Codec providing compression using zfpy via the Python standard
library.

Parameters
----------
mode : integer
One of the zfpy mode choice, e.g., ``zfpy.mode_fixed_accuracy``.
tolerance : double, optional
A double-precision number, specifying the compression accuracy needed.
rate : double, optional
A double-precision number, specifying the compression rate needed.
precision : int, optional
A integer number, specifying the compression precision needed.

"""

codec_id = "zfpy"

def __init__(
self,
mode=_zfpy.mode_fixed_accuracy,
tolerance=-1,
rate=-1,
precision=-1,
compression_kwargs=None,
):
self.mode = mode
if mode == _zfpy.mode_fixed_accuracy:
self.compression_kwargs = {"tolerance": tolerance}
elif mode == _zfpy.mode_fixed_rate:
self.compression_kwargs = {"rate": rate}
elif mode == _zfpy.mode_fixed_precision:
self.compression_kwargs = {"precision": precision}

self.tolerance = tolerance
self.rate = rate
self.precision = precision

def encode(self, buf):
# not flatten c-order array and raise exception for f-order array
if not isinstance(buf, np.ndarray):
raise TypeError(
"The zfp codec does not support none numpy arrays."
f" Your buffers were {type(buf)}."
)
if buf.flags.c_contiguous:
flatten = False
else:
raise ValueError(
"The zfp codec does not support F order arrays. "
f"Your arrays flags were {buf.flags}."
)
buf = ensure_contiguous_ndarray(buf, flatten=flatten)

# do compression
return _zfpy.compress_numpy(buf, write_header=True, **self.compression_kwargs)

def decode(self, buf, out=None):
# normalise inputs
buf = ensure_bytes(buf)
if out is not None:
out = ensure_contiguous_ndarray(out)

# do decompression
dec = _zfpy.decompress_numpy(buf)

# handle destination
if out is not None:
return ndarray_copy(dec, out)
else:
return dec

def __repr__(self):
return (
f"{type(self).__name__}(mode={self.mode!r}, "
f"tolerance={self.tolerance}, rate={self.rate}, "
f"precision={self.precision})"


class ZFPY(Codec):
"""Codec providing compression using zfpy via the Python standard
library.

Parameters
----------
mode : integer
One of the zfpy mode choice, e.g., ``zfpy.mode_fixed_accuracy``.
tolerance : double, optional
A double-precision number, specifying the compression accuracy needed.
rate : double, optional
A double-precision number, specifying the compression rate needed.
precision : int, optional
A integer number, specifying the compression precision needed.

"""

codec_id = "zfpy"

def __init__(
self,
mode=_zfpy.mode_fixed_accuracy,
tolerance=-1,
rate=-1,
precision=-1,
compression_kwargs=None,
):
if _zfpy is None:
raise RuntimeError("The ZFPY codec requires the 'zfpy' package to be installed.")

Check warning on line 59 in numcodecs/zfpy.py

View check run for this annotation

Codecov / codecov/patch

numcodecs/zfpy.py#L59

Added line #L59 was not covered by tests
_check_compatible_numpy()

self.mode = mode
if mode == _zfpy.mode_fixed_accuracy:
self.compression_kwargs = {"tolerance": tolerance}
elif mode == _zfpy.mode_fixed_rate:
self.compression_kwargs = {"rate": rate}
elif mode == _zfpy.mode_fixed_precision:
self.compression_kwargs = {"precision": precision}

self.tolerance = tolerance
self.rate = rate
self.precision = precision

def encode(self, buf):
# not flatten c-order array and raise exception for f-order array
if not isinstance(buf, np.ndarray):
raise TypeError(
"The zfp codec does not support none numpy arrays."
f" Your buffers were {type(buf)}."
)
if buf.flags.c_contiguous:
flatten = False
else:
raise ValueError(
"The zfp codec does not support F order arrays. "
f"Your arrays flags were {buf.flags}."
)
buf = ensure_contiguous_ndarray(buf, flatten=flatten)

# do compression
return _zfpy.compress_numpy(buf, write_header=True, **self.compression_kwargs)

def decode(self, buf, out=None):
# normalise inputs
buf = ensure_bytes(buf)
if out is not None:
out = ensure_contiguous_ndarray(out)

# do decompression
dec = _zfpy.decompress_numpy(buf)

# handle destination
if out is not None:
return ndarray_copy(dec, out)
else:
return dec

def __repr__(self):
return (
f"{type(self).__name__}(mode={self.mode!r}, "
f"tolerance={self.tolerance}, rate={self.rate}, "
f"precision={self.precision})"
)
Loading