Skip to content

ENH: Enable custom compression levels in np.savez_compressed #29294

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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
STY: Improve linting error messages and formatting in _savez and re…
…lated tests
  • Loading branch information
a-sajjad72 committed Jul 17, 2025
commit ab1781a2e00b298c97962d3f9a20a08490a6f313
15 changes: 10 additions & 5 deletions numpy/lib/_npyio_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,8 @@ def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None,
key = comp.lower()
if key not in _str_to_const:
raise ValueError(
f"Unknown compression method: {comp!r}. Valid options: {list(_str_to_const)}"
f"Unknown compression method: {comp!r}. "
f"Valid options: {list(_str_to_const)}"
)
comp = _str_to_const[key]
elif isinstance(comp, int):
Expand All @@ -836,11 +837,13 @@ def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None,

if comp not in _valid_ints:
raise ValueError(
f"Unknown compression method: {comp}. Valid options: {sorted(_valid_ints)}"
f"Unknown compression method: {comp}. "
f"Valid options: {sorted(_valid_ints)}"
)
else:
raise TypeError(
"compression must be an int (zipfile constant) or a str specifying the method"
"compression must be an int (zipfile constant) or a str "
"specifying the method"
)

# Persist the (possibly normalised) compression constant back into kwargs
Expand All @@ -862,9 +865,11 @@ def _in_range(minv: int, maxv: int) -> bool:

if comp == zipfile.ZIP_DEFLATED and not _in_range(0, 9):
raise ValueError("For DEFLATED, compresslevel must be between 0 and 9.")
if hasattr(zipfile, "ZIP_BZIP2") and comp == zipfile.ZIP_BZIP2 and not _in_range(1, 9):
if (hasattr(zipfile, "ZIP_BZIP2") and comp == zipfile.ZIP_BZIP2
and not _in_range(1, 9)):
raise ValueError("For BZIP2, compresslevel must be between 1 and 9.")
if hasattr(zipfile, "ZIP_LZMA") and comp == zipfile.ZIP_LZMA and not _in_range(0, 9):
if (hasattr(zipfile, "ZIP_LZMA") and comp == zipfile.ZIP_LZMA
and not _in_range(0, 9)):
raise ValueError("For LZMA, compresslevel must be between 0 and 9.")

# Store the validated compresslevel back into kwargs
Expand Down
49 changes: 41 additions & 8 deletions numpy/lib/tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,11 @@ def test_integer_compression_constants(self, compression_const):
a = np.arange(7)
with temppath(suffix=".npz") as tmp:
try:
np.savez_compressed(tmp, a=a, zipfile_kwargs={'compression': compression_const})
np.savez_compressed(
tmp,
a=a,
zipfile_kwargs={'compression': compression_const},
)
data = np.load(tmp, allow_pickle=True)
assert_equal(data["a"], a)
data.close()
Expand All @@ -413,10 +417,18 @@ def test_compresslevel_not_allowed_for_stored(self, method, const):
with temppath(suffix=".npz") as tmp:
# String method
with pytest.raises(ValueError):
np.savez_compressed(tmp, a=a, zipfile_kwargs={'compression': method, 'compresslevel': 1})
np.savez_compressed(
tmp,
a=a,
zipfile_kwargs={'compression': method, 'compresslevel': 1},
)
# Integer constant
with pytest.raises(ValueError):
np.savez_compressed(tmp, a=a, zipfile_kwargs={'compression': const, 'compresslevel': 1})
np.savez_compressed(
tmp,
a=a,
zipfile_kwargs={'compression': const, 'compresslevel': 1},
)

def roundtrip(self, *args, **kwargs):
# Delegate to the RoundtripTest harness using savez_compressed
Expand All @@ -432,7 +444,12 @@ def test_basic_compression(self, method, level):
a = np.arange(10)
b = np.eye(3)
with temppath(suffix=".npz") as tmp:
np.savez_compressed(tmp, a=a, b=b, zipfile_kwargs={'compression': method, 'compresslevel': level})
np.savez_compressed(
tmp,
a=a,
b=b,
zipfile_kwargs={'compression': method, 'compresslevel': level},
)
data = np.load(tmp, allow_pickle=True)
assert_equal(data["a"], a)
assert_equal(data["b"], b)
Expand All @@ -446,7 +463,11 @@ def test_basic_compression(self, method, level):
def test_compression_levels(self, method, level):
a = np.arange(100)
with temppath(suffix=".npz") as tmp:
np.savez_compressed(tmp, a=a, zipfile_kwargs={'compression': method, 'compresslevel': level})
np.savez_compressed(
tmp,
a=a,
zipfile_kwargs={'compression': method, 'compresslevel': level},
)
data = np.load(tmp, allow_pickle=True)
assert_equal(data["a"], a)
data.close()
Expand All @@ -463,7 +484,11 @@ def test_mixed_data_types(self):
struct=struct,
obj=obj,
strs=strs,
zipfile_kwargs={'compression': 'bzip2', 'compresslevel': 5})
zipfile_kwargs={
'compression': 'bzip2',
'compresslevel': 5,
},
)
data = np.load(tmp, allow_pickle=True)
assert data["empty"].size == 0
assert_array_equal(data["struct"], struct)
Expand Down Expand Up @@ -495,7 +520,11 @@ def test_invalid_compression(self, method, level, exc):
with pytest.raises(exc):
np.savez_compressed(tmp,
a=a,
zipfile_kwargs={'compression': method, 'compresslevel': level})
zipfile_kwargs={
'compression': method,
'compresslevel': level,
},
)

def test_file_handle_and_pathlib(self):
a = np.arange(20)
Expand Down Expand Up @@ -537,7 +566,11 @@ def test_mixed_positional_keyword_none_level(self):
with temppath(suffix=".npz") as tmp:
# positional + keyword + None opts
np.savez_compressed(tmp, a, b=a,
zipfile_kwargs={'compression': 'lzma', 'compresslevel': None})
zipfile_kwargs={
'compression': 'lzma',
'compresslevel': None,
},
)
data = np.load(tmp, allow_pickle=True)
assert_array_equal(data["arr_0"], a)
assert_array_equal(data["b"], a)
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy