Skip to content

Deprecate blosc helper functions #619

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

Merged
merged 4 commits into from
Jan 4, 2025
Merged
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
6 changes: 0 additions & 6 deletions docs/compression/blosc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,9 @@ Blosc
Helper functions
----------------

.. autofunction:: init
.. autofunction:: destroy
.. autofunction:: compname_to_compcode
.. autofunction:: list_compressors
.. autofunction:: get_nthreads
.. autofunction:: set_nthreads
.. autofunction:: cbuffer_sizes
.. autofunction:: cbuffer_complib
.. autofunction:: cbuffer_metainfo
.. autofunction:: compress
.. autofunction:: decompress
.. autofunction:: decompress_partial
14 changes: 14 additions & 0 deletions docs/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ Breaking changes
are now keyword only, to support the updated API.
By :user:`Sam Levang <slevang>`, :issue:`623`

Deprecations
~~~~~~~~~~~~
The following ``blosc`` funcitons are deprecated, with no replacement.
This is because they are not intended to be public API.

- ``numcodecs.blosc.init``
- ``numcodecs.blosc.destroy``
- ``numcodecs.blosc.compname_to_compcode``
- ``numcodecs.blosc.cbuffer_sizes``
- ``numcodecs.blosc.cbuffer_metainfo``

In addition, ``numcodecs.blosc.decompress_partial`` is deprecated as
has always been experimental and there is no equivalent in the official
blsoc Python package.

Fixes
~~~~~
Expand Down
2 changes: 1 addition & 1 deletion numcodecs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
ncores = multiprocessing.cpu_count()
except OSError: # pragma: no cover
ncores = 1
blosc.init()
blosc._init()
blosc.set_nthreads(min(8, ncores))
atexit.register(blosc.destroy)

Expand Down
32 changes: 22 additions & 10 deletions numcodecs/blosc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import threading
import multiprocessing
import os
from deprecated import deprecated


from cpython.buffer cimport PyBUF_ANY_CONTIGUOUS, PyBUF_WRITEABLE
Expand Down Expand Up @@ -95,24 +96,31 @@ def get_mutex():
_importer_pid = os.getpid()


def init():
def _init():
"""Initialize the Blosc library environment."""
blosc_init()

init = deprecated(_init)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess decorators don't work in .pyx files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They probably do, but the idea here was to leave a non-deprecated version of the functions (starting with _) that we can call internally, and a deprecated version which has the same name as previous.


def destroy():

def _destroy():
"""Destroy the Blosc library environment."""
blosc_destroy()


def compname_to_compcode(cname):
destroy = deprecated(_destroy)


def _compname_to_compcode(cname):
"""Return the compressor code associated with the compressor name. If the compressor
name is not recognized, or there is not support for it in this build, -1 is returned
instead."""
if isinstance(cname, str):
cname = cname.encode('ascii')
return blosc_compname_to_compcode(cname)

compname_to_compcode = deprecated(_compname_to_compcode)


def list_compressors():
"""Get a list of compressors supported in the current build."""
Expand All @@ -133,7 +141,7 @@ def set_nthreads(int nthreads):
return blosc_set_nthreads(nthreads)


def cbuffer_sizes(source):
def _cbuffer_sizes(source):
"""Return information about a compressed buffer, namely the number of uncompressed
bytes (`nbytes`) and compressed (`cbytes`). It also returns the `blocksize` (which
is used internally for doing the compression by blocks).
Expand All @@ -160,6 +168,7 @@ def cbuffer_sizes(source):

return nbytes, cbytes, blocksize

cbuffer_sizes = deprecated(_cbuffer_sizes)

def cbuffer_complib(source):
"""Return the name of the compression library used to compress `source`."""
Expand All @@ -180,7 +189,7 @@ def cbuffer_complib(source):
return complib


def cbuffer_metainfo(source):
def _cbuffer_metainfo(source):
"""Return some meta-information about the compressed buffer in `source`, including
the typesize, whether the shuffle or bit-shuffle filters were used, and the
whether the buffer was memcpyed.
Expand Down Expand Up @@ -217,11 +226,13 @@ def cbuffer_metainfo(source):

return typesize, shuffle, memcpyed

cbuffer_metainfo = deprecated(_cbuffer_metainfo)

def err_bad_cname(cname):
def _err_bad_cname(cname):
raise ValueError('bad compressor or compressor not supported: %r; expected one of '
'%s' % (cname, list_compressors()))

err_bad_cname = deprecated(_err_bad_cname)

def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
int blocksize=AUTOBLOCKS):
Expand Down Expand Up @@ -262,7 +273,7 @@ def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
# check valid cname early
cname_str = cname.decode('ascii')
if cname_str not in list_compressors():
err_bad_cname(cname_str)
_err_bad_cname(cname_str)

# setup source buffer
source_buffer = Buffer(source, PyBUF_ANY_CONTIGUOUS)
Expand Down Expand Up @@ -300,7 +311,7 @@ def compress(source, char* cname, int clevel, int shuffle=SHUFFLE,
if compressor_set < 0:
# shouldn't happen if we checked against list of compressors
# already, but just in case
err_bad_cname(cname_str)
_err_bad_cname(cname_str)

# set blocksize
blosc_set_blocksize(blocksize)
Expand Down Expand Up @@ -405,7 +416,7 @@ def decompress(source, dest=None):
return dest


def decompress_partial(source, start, nitems, dest=None):
def _decompress_partial(source, start, nitems, dest=None):
"""**Experimental**
Decompress data of only a part of a buffer.

Expand Down Expand Up @@ -478,6 +489,7 @@ def decompress_partial(source, start, nitems, dest=None):

return dest

decompress_partial = deprecated(_decompress_partial)

# set the value of this variable to True or False to override the
# default adaptive behaviour
Expand Down Expand Up @@ -575,7 +587,7 @@ class Blosc(Codec):
def decode_partial(self, buf, int start, int nitems, out=None):
'''**Experimental**'''
buf = ensure_contiguous_ndarray(buf, self.max_buffer_size)
return decompress_partial(buf, start, nitems, dest=out)
return _decompress_partial(buf, start, nitems, dest=out)

def __repr__(self):
r = '%s(cname=%r, clevel=%r, shuffle=%s, blocksize=%s)' % \
Expand Down
10 changes: 5 additions & 5 deletions numcodecs/tests/test_blosc.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ def test_compress_blocksize_default(use_threads):

# default blocksize
enc = blosc.compress(arr, b'lz4', 1, Blosc.NOSHUFFLE)
_, _, blocksize = blosc.cbuffer_sizes(enc)
_, _, blocksize = blosc._cbuffer_sizes(enc)
assert blocksize > 0

# explicit default blocksize
enc = blosc.compress(arr, b'lz4', 1, Blosc.NOSHUFFLE, 0)
_, _, blocksize = blosc.cbuffer_sizes(enc)
_, _, blocksize = blosc._cbuffer_sizes(enc)
assert blocksize > 0


Expand All @@ -140,7 +140,7 @@ def test_compress_blocksize(use_threads, bs):
blosc.use_threads = use_threads

enc = blosc.compress(arr, b'lz4', 1, Blosc.NOSHUFFLE, bs)
_, _, blocksize = blosc.cbuffer_sizes(enc)
_, _, blocksize = blosc._cbuffer_sizes(enc)
assert blocksize == bs


Expand Down Expand Up @@ -174,7 +174,7 @@ def test_compress_metainfo(dtype, use_threads):
blosc.use_threads = use_threads
for cname in blosc.list_compressors():
enc = blosc.compress(arr, cname.encode(), 1, shuffle)
typesize, did_shuffle, _ = blosc.cbuffer_metainfo(enc)
typesize, did_shuffle, _ = blosc._cbuffer_metainfo(enc)
assert typesize == arr.dtype.itemsize
assert did_shuffle == shuffle

Expand All @@ -186,7 +186,7 @@ def test_compress_autoshuffle(use_threads):
blosc.use_threads = use_threads
for cname in blosc.list_compressors():
enc = blosc.compress(varr, cname.encode(), 1, Blosc.AUTOSHUFFLE)
typesize, did_shuffle, _ = blosc.cbuffer_metainfo(enc)
typesize, did_shuffle, _ = blosc._cbuffer_metainfo(enc)
assert typesize == varr.dtype.itemsize
if typesize == 1:
assert did_shuffle == Blosc.BITSHUFFLE
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ for use in data storage and communication applications."""
readme = "README.rst"
dependencies = [
"numpy>=1.24",
"deprecated"
]
requires-python = ">=3.11"
dynamic = [
Expand Down
Loading