-
Notifications
You must be signed in to change notification settings - Fork 270
Use compression.zstd or backports.zstd in preference to pyzstd
#1444
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
base: master
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1444 +/- ##
==========================================
- Coverage 95.45% 95.42% -0.03%
==========================================
Files 209 209
Lines 29805 29816 +11
Branches 4479 4484 +5
==========================================
+ Hits 28449 28451 +2
- Misses 924 932 +8
- Partials 432 433 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hey @pauldmccarthy, thanks for this! I think this makes a lot of sense, but it would be simplest just to drop pyzstd support altogether and only support My overall strategy would be to write things how we would want them to look with Python 3.14 plus, and then add guards in blocks labeled try:
from compression import zstd
HAVE_ZSTD = True
except ImportError: # PY313
HAVE_ZSTD = False
...
if TYPE_CHECKING:
if not HAVE_ZSTD: # PY313
from backports import zstd
HAVE_ZSTD = True
...
else:
if not HAVE_ZSTD: # PY313
zstd, HAVE_ZSTD = optional_package('backports.zstd')becomes: from compression import zstdAnd I would also aim to use def zstd_open(
filename: str,
mode: Mode = 'r',
*,
level: int | None = None,
options: dict | None = None,
zstd_dict: zstd.ZstdDict | None = None,
level_or_option: int | dict | None = None,
) -> zstd.ZstdFile:
if level_or_option is not None:
# Warn
# Set level or options (raising if duplicated)
# Let ZstdFile raise its own error if level or options shouldn't be set
return zstd.ZstdFile(filename, mode, level=level, options=options, zstd_dict=zstd_dict)uv and tox stuff looks great to me. I'm glad it wasn't too challenging! Looks like you need to run |
|
@effigies, no problem - I like your suggestions! I had wondered about dropping I was just looking through the |
rather than calling optional_package again. Use "zstd" instead of "pyzstd"
…td in that order. Use module name "zstd" instead of "pyzstd"
normalise level_or_option/level/option arguments - working around API difference between pyzstd and compression.zstd
|
This is all pretty deep API. Internally, we expect to use I would be okay with noting the removal in the changelog. If someone complains, we can put out a bug-fix release where we restore them or add a module-level |
…k to optional backports.zstd. Accept level_or_option parameter, but emit a deprecation warning
…, zstd) from openers module - now located in _compression.
a09ef97 to
44745ac
Compare
|
I found an unrelated issue while testing locally: It looks like |
Hi @effigies, I hope you're well! Also pinging @vanandrew, as this builds on the work you did in #1005.
This PR adjusts
nibabelso that it will use one ofcompression.zstd,backports.zstd, orpyzstd, in that order of preference, for handling zstandard-compressed files.I've been playing around with adding zstandard support to the core FSL tools, and noticed that
nibabelcurrently relies onpyzstd. Support for this format is now built into Python as of 3.14 viacompression.zstd, and the recommendation for older Python versions is to use thebackports.zstdpackage, as outlined in this handy migration guide:https://pyzstd.readthedocs.io/en/stable/
To handle conditional import of one of several optional modules, I've adjusted the
nibabel.optpkg.optional_packagefunction to accept either a single module name, or a sequence of names - it will try to import each in order, returning the first one that succeeds.I moved
_zstd_open,_gzip_open, andDeterministicGzipFilefromnibabel.openersintonibabel._compression, as they seem like a better fit there.The
compression.zstd.ZstdFileAPI differs very slightly from thepyzstd.ZstdFileAPI - the latter expects an overloadedlevel_or_optionparameter, whereas the former expects separatelevel/optionparameters. I've adjusted nibabel so that it will accept all three, and will pass the appropriate parameter to the underlying library.I've tried to update the metadata files (
uv.lock,tox.inietc), but am not particularly familiar with how the project is managed these days, so let me know if there's anything I ned to fix, or anything else that is needed.Thanks!