From 79071d5f0bdc8c3404f19b0b96639097b5fb3e99 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Fri, 5 Apr 2024 17:35:30 +0200 Subject: [PATCH 01/10] requires >=3.8 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 33e92206..01444a43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ authors = [ ] description = "HDF5 Plugins for Windows, MacOS, and Linux" readme = "README.rst" -requires-python = ">=3.7" +requires-python = ">=3.8" license = {file = "LICENSE"} classifiers = [ "Development Status :: 5 - Production/Stable", From ee103c44c2f7b88ffe27ab030ed4ee8f73b321c0 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Fri, 5 Apr 2024 17:36:15 +0200 Subject: [PATCH 02/10] Remove python3.7 dependency code --- setup.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 2bf9f44b..67eddaec 100644 --- a/setup.py +++ b/setup.py @@ -39,10 +39,7 @@ import sysconfig import tempfile import platform -if sys.version_info[:2] >= (3, 8): - from functools import cached_property -else: - cached_property = property # Fallback for Python 3.7 +from functools import cached_property from setuptools import setup, Distribution, Extension from setuptools.command.build_ext import build_ext from setuptools.command.build_py import build_py From 5e42c0969610277aa4bfb1a29eeb7c57e2adbdc2 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 11:21:01 +0200 Subject: [PATCH 03/10] Remove debian packaging configuration and script --- build-deb.sh | 307 -------------------------------- copyright | 0 package/debian11/changelog | 5 - package/debian11/control | 39 ---- package/debian11/rules | 21 --- package/debian11/source/format | 1 - package/debian11/source/options | 1 - package/debian12/changelog | 5 - package/debian12/control | 29 --- package/debian12/rules | 21 --- package/debian12/source/format | 1 - package/debian12/source/options | 1 - 12 files changed, 431 deletions(-) delete mode 100755 build-deb.sh delete mode 100644 copyright delete mode 100644 package/debian11/changelog delete mode 100644 package/debian11/control delete mode 100755 package/debian11/rules delete mode 100644 package/debian11/source/format delete mode 100644 package/debian11/source/options delete mode 100644 package/debian12/changelog delete mode 100644 package/debian12/control delete mode 100755 package/debian12/rules delete mode 100644 package/debian12/source/format delete mode 100644 package/debian12/source/options diff --git a/build-deb.sh b/build-deb.sh deleted file mode 100755 index de699a19..00000000 --- a/build-deb.sh +++ /dev/null @@ -1,307 +0,0 @@ -#!/bin/sh -# -# Project: Silx -# https://github.com/silx-kit/silx -# -# Copyright (C) 2015-2023 European Synchrotron Radiation Facility, Grenoble, France -# -# Principal author: Jérôme Kieffer (Jerome.Kieffer@ESRF.eu) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE - -# Script that builds a debian package from this library - -project=hdf5plugin -source_project=hdf5plugin - -deb_name=$(echo "$source_project" | tr '[:upper:]' '[:lower:]') - -# target system -if [ -f /etc/debian_version ] -then - debian_version=$(cat /etc/debian_version | cut -d. -f1 | grep -o '[0-9]*') - if [ -z $debian_version ] - then - #we are probably on a ubuntu platform - debian_version=$(cat /etc/debian_version | cut -d/ -f1) - case $debian_version in - stretch) - debian_version=9 - ;; - buster) - debian_version=10 - ;; - bullseye) - debian_version=11 - ;; - bookworm) - debian_version=12 - ;; - esac - fi - -else - debian_version=0 -fi -target_system=debian${debian_version} - -project_directory="`dirname \"$0\"`" -project_directory="`( cd \"$project_directory\" && pwd )`" # absolutized -dist_directory=${project_directory}/dist/${target_system} -build_directory=${project_directory}/build/${target_system} - -cd ${project_directory} - -# Get version info -version=$(python3 -c"import sys; sys.path.insert(0, './src/${project}'); import _version; print(_version.version)") -strictversion=$(python3 -c"import sys; sys.path.insert(0, './src/${project}'); import _version; print(_version.strictversion)") -debianversion=$(python3 -c"import sys; sys.path.insert(0, './src/${project}'); import _version; print(_version.debianversion)") - -if [ -d /usr/lib/ccache ]; -then - export PATH=/usr/lib/ccache:$PATH -fi - -usage="usage: $(basename "$0") [options] - -Build the Debian ${debian_version} package of the ${project} library. - -If the build succeed the directory dist/debian${debian_version} will -contains the packages. - -optional arguments: - --help Show this help text - --install Install the packages generated at the end of - the process using 'sudo dpkg' - --stdeb-py3 Build using stdeb for python3 - --stdeb-py2.py3 Build using stdeb for python2 and python3 - --debian9 Simulate a debian 9 Stretch system - --debian10 Simulate a debian 10 Buster system - --debian11 Simulate a debian 11 Bullseye system - --debian12 Simulate a debian 12 Bookworm system -" - -install=0 -use_stdeb=0 -stdeb_all_python=0 - -while : -do - case "$1" in - -h | --help) - echo "$usage" - exit 0 - ;; - --install) - install=1 - shift - ;; - --stdeb-py2) - use_stdeb=1 - stdeb_all_python=0 - shift - ;; - --stdeb-py2.py3) - use_stdeb=1 - stdeb_all_python=1 - shift - ;; - --debian9) - debian_version=9 - target_system=debian${debian_version} - dist_directory=${project_directory}/dist/${target_system} - build_directory=${project_directory}/build/${target_system} - shift - ;; - --debian10) - debian_version=10 - target_system=debian${debian_version} - dist_directory=${project_directory}/dist/${target_system} - build_directory=${project_directory}/build/${target_system} - shift - ;; - --debian11) - debian_version=11 - target_system=debian${debian_version} - dist_directory=${project_directory}/dist/${target_system} - build_directory=${project_directory}/build/${target_system} - shift - ;; - --debian12) - debian_version=12 - target_system=debian${debian_version} - dist_directory=${project_directory}/dist/${target_system} - build_directory=${project_directory}/build/${target_system} - shift - ;; - -*) - echo "Error: Unknown option: $1" >&2 - echo "$usage" - exit 1 - ;; - *) # No more options - break - ;; - esac -done - -clean_up() -{ - echo "Clean working dir:" - # clean up previous build - rm -rf ${build_directory} - # create the build context - mkdir -p ${build_directory} -} - -build_deb() { - tarname=${project}_${debianversion}.orig.tar.gz - clean_up - python3 setup.py sdist - cp -f dist/${project}-${strictversion}.tar.gz ${build_directory}/${tarname} - if [ -f dist/${project}-testimages.tar.gz ] - then - cp -f dist/${project}-testimages.tar.gz ${build_directory} - fi - - cd ${build_directory} - tar -xzf ${tarname} - - directory=${project}-${strictversion} - newname=${deb_name}_${debianversion}.orig.tar.gz - - #echo tarname $tarname newname $newname - if [ $tarname != $newname ] - then - if [ -h $newname ] - then - rm ${newname} - fi - ln -s ${tarname} ${newname} - fi - - if [ -f ${project}-testimages.tar.gz ] - then - if [ ! -h ${deb_name}_${debianversion}.orig-testimages.tar.gz ] - then - ln -s ${project}-testimages.tar.gz ${deb_name}_${debianversion}.orig-testimages.tar.gz - fi - fi - - cd ${directory} - cp -r ${project_directory}/package/${target_system} debian - cp ${project_directory}/copyright debian - - #handle test images - if [ -f ../${deb_name}_${debianversion}.orig-testimages.tar.gz ] - then - if [ ! -d testimages ] - then - mkdir testimages - fi - cd testimages - tar -xzf ../${deb_name}_${debianversion}.orig-testimages.tar.gz - cd .. - else - # Disable to skip tests during build - echo No test data - #export PYBUILD_DISABLE_python2=test - #export PYBUILD_DISABLE_python3=test - #export DEB_BUILD_OPTIONS=nocheck - fi - - case $debian_version in - 9) - debian_name=stretch - ;; - 10) - debian_name=buster - ;; - 11) - debian_name=bullseye - ;; - esac - - dch -v ${debianversion}-1 "upstream development build of ${project} ${version}" - dch -D ${debian_name}-backports -l~bpo${debian_version}+ "${project} snapshot ${version} built for ${target_system}" - #dch --bpo "${project} snapshot ${version} built for ${target_system}" - dpkg-buildpackage -r - rc=$? - - if [ $rc -eq 0 ]; then - # move packages to dist directory - echo Build succeeded... - rm -rf ${dist_directory} - mkdir -p ${dist_directory} - mv ${build_directory}/*.deb ${dist_directory} - mv ${build_directory}/*.x* ${dist_directory} - mv ${build_directory}/*.dsc ${dist_directory} - mv ${build_directory}/*.changes ${dist_directory} - cd ../../.. - else - echo Build failed, please investigate ... - exit "$rc" - fi -} - - -build_stdeb () { - echo "Build for debian using stdeb" - tarname=${project}-${strictversion}.tar.gz - clean_up - - python setup.py sdist - cp -f dist/${tarname} ${build_directory} - cd ${build_directory} - tar -xzf ${tarname} - cd ${project}-${strictversion} - - if [ $stdeb_all_python -eq 1 ]; then - echo Using Python 2+3 - python3 setup.py --command-packages=stdeb.command sdist_dsc --with-python2=True --with-python3=True --no-python3-scripts=True build --no-cython bdist_deb - rc=$? - else - echo Using Python 3 - # bdist_deb feed /usr/bin using setup.py entry-points - python3 setup.py --command-packages=stdeb.command build --no-cython bdist_deb - rc=$? - fi - - # move packages to dist directory - rm -rf ${dist_directory} - mkdir -p ${dist_directory} - mv -f deb_dist/*.deb ${dist_directory} - - # back to the root - cd ../../.. -} - - -if [ $use_stdeb -eq 1 ]; then - build_stdeb -else - build_deb -fi - - -if [ $install -eq 1 ]; then - sudo -v su -c "dpkg -i ${dist_directory}/*.deb" -fi - -exit "$rc" diff --git a/copyright b/copyright deleted file mode 100644 index e69de29b..00000000 diff --git a/package/debian11/changelog b/package/debian11/changelog deleted file mode 100644 index 95306b62..00000000 --- a/package/debian11/changelog +++ /dev/null @@ -1,5 +0,0 @@ -hdf5plugin (2.3.1-1) unstable; urgency=low - - * source package automatically created by stdeb 0.9.0 - - -- Thomas Vincent Wed, 16 Sep 2020 13:45:10 +0200 diff --git a/package/debian11/control b/package/debian11/control deleted file mode 100644 index 2c16fbac..00000000 --- a/package/debian11/control +++ /dev/null @@ -1,39 +0,0 @@ -Source: hdf5plugin -Maintainer: Thomas Vincent -Section: python -Priority: optional -Build-Depends: debhelper-compat (= 12), - dh-python, - libgomp1, - python3-all-dev, - python3-h5py, - python3-setuptools, - python3-wheel -Standards-Version: 4.1.3 -Homepage: https://github.com/silx-kit/hdf5plugin - -Package: python3-hdf5plugin -Architecture: any -Depends: ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}, python3-h5py, libgomp1 -Description: HDF5 Plugins for windows,MacOS and linux - hdf5plugin - ========== - . - This module provides `HDF5 compression filters `_ (namely: blosc, bitshuffle, bzip2,FCIDECOMP, lz4, ZFP, zstd) and registers them to the HDF5 library used by `h5py `_. - . - * Supported operating systems: Linux, Windows, macOS. - * Supported versions of Python: >= 3.7 - . - `hdf5plugin` provides a generic way to enable the use of the provided HDF5 compression filters with `h5py` that can be installed via `pip` or `conda`. - . - Alternatives to install HDF5 compression filters are: system-wide installation on Linux or other conda packages: `blosc-hdf5-plugin `_, `hdf5-lz4 `_. - . - The HDF5 plugin sources were obtained from: - . - * LZ4 plugin (v0.1.0): https://github.com/nexusformat/HDF5-External-Filter-Plugins - * bitshuffle plugin (0.3.5): https://github.com/kiyo-masui/bitshuffle - * hdf5-blosc plugin (v1.0.0) and c-blosc (v1.17.0): https://github.com/Blosc/hdf5-blosc and https://github.com/Blosc/c-blosc - * FCIDECOMP plugin (v1.0.2) and CharLS (branch 1.x-master SHA1 ID:25160a42fb62e71e4b0ce081f5cb3f8bb73938b5): ftp://ftp.eumetsat.int/pub/OPS/out/test-data/Test-data-for-External-Users/MTG_FCI_Test-Data/FCI_Decompression_Software_V1.0.2/ and https://github.com/team-charls/charls.git - * HDF5-ZFP plugin (v1.0.1) and zfp (v0.5.5): https://github.com/LLNL/H5Z-ZFP and https://github.com/LLNL/zfp - . - diff --git a/package/debian11/rules b/package/debian11/rules deleted file mode 100755 index 153134a8..00000000 --- a/package/debian11/rules +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/make -f -# See https://wiki.debian.org/Python/Pybuild - -export PYBUILD_NAME=hdf5plugin - -# Build options -export HDF5PLUGIN_NATIVE=False -export HDF5PLUGIN_SSE2=True -export HDF5PLUGIN_SSSE3=False -export HDF5PLUGIN_AVX2=False -export HDF5PLUGIN_AVX512=False -export HDF5PLUGIN_OPENMP=True -export HDF5PLUGIN_CPP11=True - -%: - dh $@ --with python3 --buildsystem=pybuild - -override_dh_auto_test: - dh_auto_test -- -s custom --test-args="env PYTHONPATH={build_dir} {interpreter} -m hdf5plugin.test" - dh_auto_test -- -s custom --test-args="env PYTHONPATH={build_dir} {interpreter} test/test.py" - diff --git a/package/debian11/source/format b/package/debian11/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/package/debian11/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/package/debian11/source/options b/package/debian11/source/options deleted file mode 100644 index 6e88e496..00000000 --- a/package/debian11/source/options +++ /dev/null @@ -1 +0,0 @@ -extend-diff-ignore="^[^/]+\.egg-info/" \ No newline at end of file diff --git a/package/debian12/changelog b/package/debian12/changelog deleted file mode 100644 index 95306b62..00000000 --- a/package/debian12/changelog +++ /dev/null @@ -1,5 +0,0 @@ -hdf5plugin (2.3.1-1) unstable; urgency=low - - * source package automatically created by stdeb 0.9.0 - - -- Thomas Vincent Wed, 16 Sep 2020 13:45:10 +0200 diff --git a/package/debian12/control b/package/debian12/control deleted file mode 100644 index 69658ebe..00000000 --- a/package/debian12/control +++ /dev/null @@ -1,29 +0,0 @@ -Source: hdf5plugin -Maintainer: Thomas Vincent -Section: python -Priority: optional -Build-Depends: debhelper-compat (= 12), - dh-python, - libgomp1, - python3-all, - python3-h5py, - python3-setuptools, - python3-wheel -Standards-Version: 4.1.3 -Homepage: https://github.com/silx-kit/hdf5plugin - -Package: python3-hdf5plugin -Architecture: any -Depends: ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends}, python3-h5py, libgomp1 -Description: HDF5 Plugins for windows,MacOS and linux - hdf5plugin - ========== - . - *hdf5plugin* provides `HDF5 compression filters `_ (namely: Blosc, Blosc2, BitShuffle, BZip2, FciDecomp, LZ4, SZ, SZ3, Zfp, ZStd) and makes them usable from `h5py `_. - . - * Supported operating systems: Linux, Windows, macOS. - * Supported versions of Python: >= 3.7 - * Supported architectures: All. - Specific optimizations are available for *x86* family and *ppc64le*. - . - *hdf5plugin* provides a generic way to enable the use of the provided HDF5 compression filters with `h5py`. diff --git a/package/debian12/rules b/package/debian12/rules deleted file mode 100755 index 6aec2c65..00000000 --- a/package/debian12/rules +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/make -f -# See https://wiki.debian.org/Python/Pybuild - -export PYBUILD_NAME=hdf5plugin - -# Build options -export HDF5PLUGIN_NATIVE=False -export HDF5PLUGIN_SSE2=True -export HDF5PLUGIN_SSSE3=False -export HDF5PLUGIN_AVX2=False -export HDF5PLUGIN_AVX512=False -export HDF5PLUGIN_OPENMP=True -export HDF5PLUGIN_CPP11=True - -%: - dh $@ --buildsystem=pybuild - -override_dh_auto_test: - dh_auto_test -- -s custom --test-args="env PYTHONPATH={build_dir} {interpreter} -m hdf5plugin.test" - dh_auto_test -- -s custom --test-args="env PYTHONPATH={build_dir} {interpreter} test/test.py" - diff --git a/package/debian12/source/format b/package/debian12/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/package/debian12/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/package/debian12/source/options b/package/debian12/source/options deleted file mode 100644 index 6e88e496..00000000 --- a/package/debian12/source/options +++ /dev/null @@ -1 +0,0 @@ -extend-diff-ignore="^[^/]+\.egg-info/" \ No newline at end of file From c134b65683c3c483ee13e575026f1d118b830355 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 13:01:36 +0200 Subject: [PATCH 04/10] Removed deprecated variables: config, date, hexversion, strictversion; Simpler version handling --- pyproject.toml | 2 +- src/hdf5plugin/__init__.py | 19 +------ src/hdf5plugin/_version.py | 110 ++++++++----------------------------- src/hdf5plugin/test.py | 13 ----- 4 files changed, 25 insertions(+), 119 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 01444a43..9ce885c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,4 +53,4 @@ packages = ["hdf5plugin"] package-dir = {"" = "src"} [tool.setuptools.dynamic] -version = {attr = "hdf5plugin._version.strictversion"} +version = {attr = "hdf5plugin._version.version"} diff --git a/src/hdf5plugin/__init__.py b/src/hdf5plugin/__init__.py index 17005f12..d02b95b6 100644 --- a/src/hdf5plugin/__init__.py +++ b/src/hdf5plugin/__init__.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2016-2022 European Synchrotron Radiation Facility +# Copyright (c) 2016-2024 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -25,9 +25,6 @@ """This module provides compiled shared libraries for their use as HDF5 filters under windows, MacOS and linux.""" -import logging as _logging - -from . import _version from ._version import version, version_info # noqa from ._filters import FILTERS # noqa @@ -47,17 +44,3 @@ # Backward compatibility PLUGINS_PATH = PLUGIN_PATH - - -def __getattr__(name): - if name == "config": - _logging.getLogger(__name__).warning( - "hdf5plugin.config is deprecated, use get_config().build_config" - ) - return get_config().build_config - if name in ("date", "hexversion", "strictversion"): - _logging.getLogger(__name__).warning( - f"hdf5plugin.{name} is deprecated" - ) - return getattr(_version, name) - raise AttributeError(f"module {__name__} has no attribute {name}") diff --git a/src/hdf5plugin/_version.py b/src/hdf5plugin/_version.py index 4849737f..0195cfcd 100644 --- a/src/hdf5plugin/_version.py +++ b/src/hdf5plugin/_version.py @@ -1,8 +1,6 @@ -#!/usr/bin/env python -# coding: utf-8 # /*########################################################################## # -# Copyright (c) 2015-2020 European Synchrotron Radiation Facility +# Copyright (c) 2015-2024 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,97 +21,35 @@ # THE SOFTWARE. # # ###########################################################################*/ -"""Unique place where the version number is defined. -provides: -* version = "1.2.3" or "1.2.3-beta4" -* version_info = named tuple (1,2,3,"beta",4) -* hexversion: 0x010203B4 -* strictversion = "1.2.3b4 -* debianversion = "1.2.3~beta4" -* calc_hexversion: the function to transform a version_tuple into an integer -This is called hexversion since it only really looks meaningful when viewed as the -result of passing it to the built-in hex() function. -The version_info value may be used for a more human-friendly encoding of the same information. +from typing import NamedTuple +import re -The hexversion is a 32-bit number with the following layout: -Bits (big endian order) Meaning -1-8 PY_MAJOR_VERSION (the 2 in 2.1.0a3) -9-16 PY_MINOR_VERSION (the 1 in 2.1.0a3) -17-24 PY_MICRO_VERSION (the 0 in 2.1.0a3) -25-28 PY_RELEASE_LEVEL (0xA for alpha, 0xB for beta, 0xC for release candidate and 0xF for final) -29-32 PY_RELEASE_SERIAL (the 3 in 2.1.0a3, zero for final releases) +version = "5.0.0a0" -Thus 2.1.0a3 is hexversion 0x020100a3. -""" -from collections import namedtuple +class _VersionInfo(NamedTuple): + """Version information as a namedtuple""" + major: int + minor: int + micro: int + releaselevel: str = "final" + serial: int = 0 -__authors__ = ["Jérôme Kieffer"] -__license__ = "MIT" -__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France" -__date__ = "15/12/2020" -__status__ = "production" -__docformat__ = 'restructuredtext' -__all__ = ["date", "version_info", "strictversion", "hexversion", "debianversion", - "calc_hexversion"] + def __init__(self, version: str): + pattern = r"(?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc)(?P\d+))?" + match = re.fullmatch(pattern, version, re.ASCII) + fields = {k: v for k, v in match.groupdict().items() if v is not None} -RELEASE_LEVEL_VALUE = {"dev": 0, - "alpha": 10, - "beta": 11, - "candidate": 12, - "final": 15} + # Convert prerelease to releaselevel + prerelease = fields.pop("prerelease", None) + if prerelease is not None: + fields["releaselevel"] = {"a": "alpha", "b": "beta", "rc": "candidate"}[ + prerelease + ] -PRERELEASE_NORMALIZED_NAME = {"dev": "a", - "alpha": "a", - "beta": "b", - "candidate": "rc"} + super().__init__(**fields) -MAJOR = 4 -MINOR = 4 -MICRO = 1 -RELEV = "dev" # <16 -SERIAL = 0 # <16 -date = __date__ - -_version_info = namedtuple("version_info", ["major", "minor", "micro", "releaselevel", "serial"]) - -version_info = _version_info(MAJOR, MINOR, MICRO, RELEV, SERIAL) - -strictversion = version = debianversion = "%d.%d.%d" % version_info[:3] -if version_info.releaselevel != "final": - _prerelease = PRERELEASE_NORMALIZED_NAME[version_info[3]] - version += "-%s%s" % (_prerelease, version_info[-1]) - debianversion += "~adev%i" % version_info[-1] if RELEV == "dev" else "~%s%i" % (_prerelease, version_info[-1]) - strictversion += _prerelease + str(version_info[-1]) - - -def calc_hexversion(major=0, minor=0, micro=0, releaselevel="dev", serial=0): - """Calculate the hexadecimal version number from the tuple version_info: - - :param major: integer - :param minor: integer - :param micro: integer - :param relev: integer or string - :param serial: integer - :return: integer always increasing with revision numbers - """ - try: - releaselevel = int(releaselevel) - except ValueError: - releaselevel = RELEASE_LEVEL_VALUE.get(releaselevel, 0) - - hex_version = int(serial) - hex_version |= releaselevel * 1 << 4 - hex_version |= int(micro) * 1 << 8 - hex_version |= int(minor) * 1 << 16 - hex_version |= int(major) * 1 << 24 - return hex_version - - -hexversion = calc_hexversion(*version_info) - -if __name__ == "__main__": - print(version) +version_info = _VersionInfo(version) diff --git a/src/hdf5plugin/test.py b/src/hdf5plugin/test.py index 5dde2f6c..39e328d4 100644 --- a/src/hdf5plugin/test.py +++ b/src/hdf5plugin/test.py @@ -364,22 +364,9 @@ def testGetConfig(self): self.assertIsInstance(config.build_config.embedded_filters, tuple) self.assertIsInstance(config.registered_filters, dict) - def testDeprecatedConfig(self): - """Test hdf5plugin.config availability""" - config = hdf5plugin.config - self.assertIsInstance(config.openmp, bool) - self.assertIsInstance(config.native, bool) - self.assertIsInstance(config.sse2, bool) - self.assertIsInstance(config.avx2, bool) - self.assertIsInstance(config.cpp11, bool) - self.assertIsInstance(config.cpp14, bool) - self.assertIsInstance(config.embedded_filters, tuple) - def testVersion(self): """Test version information""" self.assertIsInstance(hdf5plugin.version, str) - self.assertIsInstance(hdf5plugin.strictversion, str) - self.assertIsInstance(hdf5plugin.hexversion, int) version_info = hdf5plugin.version_info self.assertIsInstance(version_info.major, int) self.assertIsInstance(version_info.minor, int) From 31cc272b1371f05f8f930a356998d549cafd2269 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 13:11:53 +0200 Subject: [PATCH 05/10] Update MANIFEST --- MANIFEST.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index c3516b32..295d36bb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,15 +1,12 @@ -include appveyor.yml -include build-deb.sh include CHANGELOG.rst -include copyright include LICENSE include MANIFEST.in +include pyproject.toml include README.rst include setup.py recursive-include doc * recursive-include src * recursive-include test *.py *.h5 -recursive-include package * global-exclude *__pycache__/* global-exclude *.ipynb_checkpoints/* global-exclude .*.swp From 2217ac313dec1cf007a5d11420b6bf7ddab6947d Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 14:08:27 +0200 Subject: [PATCH 06/10] Make flake8 pass --- .flake8 | 2 +- setup.py | 16 ++++++-------- src/hdf5plugin/_filters.py | 2 +- src/hdf5plugin/_utils.py | 2 +- src/hdf5plugin/test.py | 10 +++++---- test/test.py | 44 ++++++++++++++++++-------------------- 6 files changed, 37 insertions(+), 39 deletions(-) diff --git a/.flake8 b/.flake8 index 5ecfbf60..5e2229b1 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,3 @@ [flake8] -ignore = E203, E501 max-line-length = 88 +extend-ignore = E203,E501,E701 diff --git a/setup.py b/setup.py index 67eddaec..de1e86d0 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ from setuptools.command.build_clib import build_clib from setuptools.command.build import build from setuptools.errors import CompileError -from wheel.bdist_wheel import bdist_wheel, get_platform +from wheel.bdist_wheel import bdist_wheel logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -78,7 +78,6 @@ def get_compiler(compiler): Taken from https://github.com/pypa/setuptools/issues/2806#issuecomment-961805789 """ - d = Distribution() build_ext = Distribution().get_command_obj("build_ext") build_ext.compiler = compiler build_ext.finalize_options() @@ -108,7 +107,7 @@ def check_compile_flags(compiler, *flags, extension='.c', source=None): tmp_file = Path(tmp_dir) / f"source{extension}" tmp_file.write_text(source) try: - result = compiler.compile([str(tmp_file)], output_dir=tmp_dir, extra_postargs=list(flags)) + compiler.compile([str(tmp_file)], output_dir=tmp_dir, extra_postargs=list(flags)) except CompileError: return False else: @@ -387,9 +386,9 @@ def use_avx512(self) -> bool: return enabled USE_BMI2 = bool( - os.environ.get("HDF5PLUGIN_BMI2", 'True') == 'True' - and sys.platform in ('linux', 'darwin') - ) + os.environ.get("HDF5PLUGIN_BMI2", 'True') == 'True' + and sys.platform in ('linux', 'darwin') + ) """Whether to build with BMI2 instruction set or not (bool)""" INTEL_IPP_DIR = os.environ.get("HDF5PLUGIN_INTEL_IPP_DIR", None) @@ -985,8 +984,7 @@ def get_blosc2_plugin(): return HDF5PluginExtension( "hdf5plugin.plugins.libh5blosc2", - sources=sources + \ - prefix(hdf5_blosc2_dir, ['blosc2_filter.c', 'blosc2_plugin.c']), + sources=sources + prefix(hdf5_blosc2_dir, ['blosc2_filter.c', 'blosc2_plugin.c']), extra_objects=get_zstd_clib('extra_objects'), include_dirs=include_dirs + [hdf5_blosc2_dir], define_macros=define_macros, @@ -1027,7 +1025,7 @@ def get_bitshuffle_plugin(): extra_compile_args += ['/Ox', '/fp:fast', '/openmp'] extra_link_args = ['-fopenmp', '/openmp'] - define_macros=[("ZSTD_SUPPORT", 1)] + define_macros = [("ZSTD_SUPPORT", 1)] if platform.machine() == 'ppc64le': define_macros.append(('NO_WARN_X86_INTRINSICS', None)) # P9 way to enable SSE2 diff --git a/src/hdf5plugin/_filters.py b/src/hdf5plugin/_filters.py index ad16fa45..ce3c4a14 100644 --- a/src/hdf5plugin/_filters.py +++ b/src/hdf5plugin/_filters.py @@ -531,7 +531,7 @@ def __pack_options(cls, mode: int, quality: float, swap: bool) -> tuple[int]: if quality_log < 0: ret = int(math.ceil(abs(quality_log) * (1 << cls._FRACTIONAL_BITS))) # Store negative sign - ret |= 1 << (cls._INTEGER_BITS + cls._FRACTIONAL_BITS -1) + ret |= 1 << (cls._INTEGER_BITS + cls._FRACTIONAL_BITS - 1) else: ret = int(math.floor(quality_log * (1 << cls._FRACTIONAL_BITS))) diff --git a/src/hdf5plugin/_utils.py b/src/hdf5plugin/_utils.py index 07318ede..4d61d67b 100644 --- a/src/hdf5plugin/_utils.py +++ b/src/hdf5plugin/_utils.py @@ -161,7 +161,7 @@ def register_filter(name): if h5py.version.version_tuple[:3] > (3, 8, 0): try: h5py.h5z.register_filter(lib.H5PLget_plugin_info()) - except: + except: # noqa: E722 logger.error(f"Cannot register filter {name}: {retval}") logger.error(traceback.format_exc()) return False diff --git a/src/hdf5plugin/test.py b/src/hdf5plugin/test.py index 39e328d4..f23a3e49 100644 --- a/src/hdf5plugin/test.py +++ b/src/hdf5plugin/test.py @@ -209,9 +209,11 @@ def testBlosc2(self): self._test('blosc2') # Default options # Specify options - tested_filters = (hdf5plugin.Blosc2.NOFILTER, - hdf5plugin.Blosc2.SHUFFLE, - hdf5plugin.Blosc2.BITSHUFFLE) + tested_filters = ( + hdf5plugin.Blosc2.NOFILTER, + hdf5plugin.Blosc2.SHUFFLE, + hdf5plugin.Blosc2.BITSHUFFLE, + ) compress = 'blosclz', 'lz4', 'lz4hc', 'unused', 'zlib', 'zstd' for compression_id, cname in enumerate(compress): if cname == 'unused': @@ -488,7 +490,7 @@ def _readback_hdf5_blosc2_dataset( data: numpy.ndarray, blocks: tuple[int, ...] | None = None, **cparams - ) -> numpy.ndarray: + ) -> numpy.ndarray: """Compress data with blosc2, write it as HDF5 file with direct chunk write and read it back with h5py :param data: data array to compress diff --git a/test/test.py b/test/test.py index 53a398c1..152767c4 100644 --- a/test/test.py +++ b/test/test.py @@ -83,7 +83,6 @@ def testLZ4(self): h5 = h5py.File(fname, "r") data = h5["/entry/data"][:] h5.close() - expected_shape = (50, 2167, 2070) self.assertTrue(data.shape[0] == 50, "Incorrect shape") self.assertTrue(data.shape[1] == 2167, "Incorrect shape") self.assertTrue(data.shape[2] == 2070, "Incorrect shape") @@ -100,7 +99,6 @@ def testBitshuffle(self): h5 = h5py.File(fname, "r") data = h5["/entry/data/data"][:] h5.close() - expected_shape = (1, 2167, 2070) self.assertTrue(data.shape[0] == 1, "Incorrect shape") self.assertTrue(data.shape[1] == 2167, "Incorrect shape") self.assertTrue(data.shape[2] == 2070, "Incorrect shape") @@ -117,7 +115,6 @@ def testFcidecomp(self): h5 = h5py.File(fname, "r") data = h5["effective_radiance"][:] h5.close() - expected_shape = (60, 30) expected_data = numpy.arange(1800).astype(numpy.int16).reshape(60, 30) self.assertTrue(data.shape[0] == 60, "Incorrect shape") self.assertTrue(data.shape[1] == 30, "Incorrect shape") @@ -144,7 +141,7 @@ def testZfp(self): self.assertFalse(numpy.all(original == compressed), "Values should not be identical") self.assertTrue(numpy.allclose(original, compressed), - "Values should be close") + "Values should be close") @unittest.skipUnless(h5py.h5z.filter_avail(hdf5plugin.SPERR_ID), "Sperr filter not available") @@ -218,35 +215,35 @@ def testSZ3(self): original = h5[dname][()] # absolute 1E-3 value = 1E-3 - compressed_name = dname + "_absolute_sz3" + compressed_name = dname + "_absolute_sz3" compressed = h5[compressed_name][()] - compressed_back = h5[compressed_name+"_back"][()] + compressed_back = h5[compressed_name + "_back"][()] self.assertTrue(original.shape == compressed.shape, "Incorrect shape") self.assertFalse(numpy.all(original == compressed), "Values should not be identical") self.assertTrue(numpy.allclose(compressed, compressed_back), - "Compressed read back values should be identical to compressed data") + "Compressed read back values should be identical to compressed data") # this also tests the algorithm and not just the plugin self.assertTrue(numpy.allclose(original, compressed, atol=value), - "Values should be within tolerance") + "Values should be within tolerance") # create a compressed file output_file = os.path.join(self.tempdir, compressed_name + ".h5") with h5py.File(output_file, "w", driver="core", backing_store=False) as h5o: h5o.create_dataset("data", data=original, dtype=original.dtype, chunks=original.shape, - compression=hdf5plugin.SZ3(absolute=value)) + compression=hdf5plugin.SZ3(absolute=value)) output_data = h5o["/data"][()] self.assertFalse(numpy.all(original == output_data), "Values should not be identical") self.assertTrue(numpy.allclose(original, output_data, atol=value), - "Values should be within tolerance") + "Values should be within tolerance") # relative 1E-4 value = 1E-4 - compressed_name = dname + "_relative_sz3" + compressed_name = dname + "_relative_sz3" compressed = h5[compressed_name][()] - compressed_back = h5[compressed_name+"_back"][()] + compressed_back = h5[compressed_name + "_back"][()] self.assertTrue(original.shape == compressed.shape, "Incorrect shape") self.assertFalse(numpy.all(original == compressed), "Values should not be identical") @@ -254,13 +251,13 @@ def testSZ3(self): # under windows the results are not identical to linux # therefore we cannot check for equality of decompressed values self.assertTrue(numpy.allclose(compressed, compressed_back, rtol=0.1 * value), - "Relative read back values should be very close to compressed data") + "Relative read back values should be very close to compressed data") # create a compressed file output_file = os.path.join(self.tempdir, compressed_name + ".h5") with h5py.File(output_file, "w", driver="core", backing_store=False) as h5o: h5o.create_dataset("data", data=original, dtype=original.dtype, chunks=original.shape, - compression=hdf5plugin.SZ3(relative=value)) + compression=hdf5plugin.SZ3(relative=value)) output_data = h5o["/data"][()] self.assertFalse(numpy.all(original == output_data), "Values should not be identical") @@ -274,37 +271,38 @@ def testSZ3(self): # TODO: Check why one needs to have such large tolerance rtol = rtol * 5 self.assertTrue(numpy.allclose(original, output_data, rtol=rtol), - "Newly compressed data should match original compression quality") + "Newly compressed data should match original compression quality") self.assertTrue(numpy.allclose(compressed_back, output_data, rtol=1.5 * rtol), - "Compressed data should be close") + "Compressed data should be close") # L2 Norm value = 0.33 - compressed_name = dname + "_norm2_sz3" + compressed_name = dname + "_norm2_sz3" compressed = h5[compressed_name][()] - compressed_back = h5[compressed_name+"_back"][()] + compressed_back = h5[compressed_name + "_back"][()] self.assertTrue(original.shape == compressed.shape, "Incorrect shape") self.assertFalse(numpy.all(original == compressed), "Values should not be identical") # Absolute error from L2 norm param from: # https://github.com/szcompressor/SZ3/blob/v3.1.8/include/SZ3/utils/Statistic.hpp#L44 - abs_error = numpy.sqrt(3.0/compressed.ndim) * value + abs_error = numpy.sqrt(3.0 / compressed.ndim) * value self.assertTrue(numpy.allclose(compressed, compressed_back, atol=abs_error), - "Compressed read back values should be identical to compressed data") + "Compressed read back values should be identical to compressed data") # create a compressed file output_file = os.path.join(self.tempdir, compressed_name + ".h5") with h5py.File(output_file, "w", driver="core", backing_store=False) as h5o: h5o.create_dataset("data", data=original, dtype=original.dtype, chunks=original.shape, - compression=hdf5plugin.SZ3(norm2=value)) + compression=hdf5plugin.SZ3(norm2=value)) output_data = h5o["/data"][()] self.assertFalse(numpy.all(original == output_data), "Values should not be identical") self.assertTrue(numpy.all(compressed == output_data), - "Compressed data should be identical") + "Compressed data should be identical") self.assertTrue(numpy.allclose(compressed_back, output_data, atol=abs_error), - "Newly L2 norm read back values should be identical to compressed data") + "Newly L2 norm read back values should be identical to compressed data") h5.close() + def suite(): testSuite = unittest.TestSuite() testSuite.addTest(unittest.TestLoader().loadTestsFromTestCase( From d84688cd26ea3c0c572d591d4cef2522e9860486 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 14:33:55 +0200 Subject: [PATCH 07/10] Fix version --- src/hdf5plugin/_version.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/hdf5plugin/_version.py b/src/hdf5plugin/_version.py index 0195cfcd..4986d4fe 100644 --- a/src/hdf5plugin/_version.py +++ b/src/hdf5plugin/_version.py @@ -37,19 +37,17 @@ class _VersionInfo(NamedTuple): releaselevel: str = "final" serial: int = 0 - def __init__(self, version: str): - pattern = r"(?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc)(?P\d+))?" - match = re.fullmatch(pattern, version, re.ASCII) - fields = {k: v for k, v in match.groupdict().items() if v is not None} - # Convert prerelease to releaselevel - prerelease = fields.pop("prerelease", None) - if prerelease is not None: - fields["releaselevel"] = {"a": "alpha", "b": "beta", "rc": "candidate"}[ - prerelease - ] +def _version_info(version: str) -> _VersionInfo: + pattern = r"(?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc)(?P\d+))?" + match = re.fullmatch(pattern, version, re.ASCII) + fields = {k: v for k, v in match.groupdict().items() if v is not None} + # Remove prerelease and convert it to releaselevel + prerelease = fields.pop("prerelease", None) + releaselevel = {"a": "alpha", "b": "beta", "rc": "candidate", None: "final"}[prerelease] + version_fields = {k: int(v) for k, v in fields.items()} - super().__init__(**fields) + return _VersionInfo(releaselevel=releaselevel, **version_fields) -version_info = _VersionInfo(version) +version_info = _version_info(version) From 8a6fa52a932a8c654081d062d4a7a54c0aed0c3d Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 15:37:18 +0200 Subject: [PATCH 08/10] update doc --- doc/index.rst | 4 ++-- doc/install.rst | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index eedf659d..ea2799c2 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -5,9 +5,9 @@ hdf5plugin * Supported operating systems: Linux, Windows, macOS. -* Supported versions of Python: >= 3.7 +* Supported versions of Python: >= 3.8 * Supported architectures: All. - Specific optimizations are available for *x86* family and *ppc64le*. + Specific optimizations are available for *x86* family, *arm64* and *ppc64le*. *hdf5plugin* provides a generic way to enable the use of the provided HDF5 compression filters with `h5py` that can be installed via `pip` or `conda`. diff --git a/doc/install.rst b/doc/install.rst index a50b0b71..c63607e1 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -71,6 +71,9 @@ Available options * - ``HDF5PLUGIN_CPP14`` - Whether or not to compile C++14 code if available. Default: True if probed. + * - ``HDF5PLUGIN_CPP20`` + - Whether or not to compile C++20 code if available. + Default: True if probed. * - ``HDF5PLUGIN_INTEL_IPP_DIR`` - Experimental feature: Path to Intel `IPP`_ root directory. If provided, the LZ4 compression library and Blosc2 are set to use Intel `IPP`_. From 11a6cf73197d92945045a900c9c71777478f1113 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 8 Jul 2024 15:39:44 +0200 Subject: [PATCH 09/10] Update license --- LICENSE | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index 48bf05c0..03cd7d27 100644 --- a/LICENSE +++ b/LICENSE @@ -1,10 +1,7 @@ The hdf5plugin code itself is licensed under the MIT license (See below). The HDF5 filter plugins bundled in hdf5plugin have different copyright and licenses: - -* bitshuffle: See src/bitshuffle/LICENSE -* blosc: See src/hdf5-blosc/LICENSES/ and src/c-blosc/LICENSES/ -* lz4: See src/HDF5-External-Filter-Plugins/LZ4/COPYING +See doc/information.rst hdf5plugin copyright and license: From f7c8880ebf09e790e81a654d64cbf3b47e8a7455 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Wed, 10 Jul 2024 10:43:35 +0200 Subject: [PATCH 10/10] Update _VersionInfo --- src/hdf5plugin/_version.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hdf5plugin/_version.py b/src/hdf5plugin/_version.py index 4986d4fe..ba54e388 100644 --- a/src/hdf5plugin/_version.py +++ b/src/hdf5plugin/_version.py @@ -31,23 +31,26 @@ class _VersionInfo(NamedTuple): """Version information as a namedtuple""" + major: int minor: int micro: int releaselevel: str = "final" serial: int = 0 + @staticmethod + def from_string(version: str) -> "_VersionInfo": + pattern = r"(?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc)(?P\d+))?" + match = re.fullmatch(pattern, version, re.ASCII) + fields = {k: v for k, v in match.groupdict().items() if v is not None} + # Remove prerelease and convert it to releaselevel + prerelease = fields.pop("prerelease", None) + releaselevel = {"a": "alpha", "b": "beta", "rc": "candidate", None: "final"}[ + prerelease + ] + version_fields = {k: int(v) for k, v in fields.items()} -def _version_info(version: str) -> _VersionInfo: - pattern = r"(?P\d+)\.(?P\d+)\.(?P\d+)((?Pa|b|rc)(?P\d+))?" - match = re.fullmatch(pattern, version, re.ASCII) - fields = {k: v for k, v in match.groupdict().items() if v is not None} - # Remove prerelease and convert it to releaselevel - prerelease = fields.pop("prerelease", None) - releaselevel = {"a": "alpha", "b": "beta", "rc": "candidate", None: "final"}[prerelease] - version_fields = {k: int(v) for k, v in fields.items()} - - return _VersionInfo(releaselevel=releaselevel, **version_fields) + return _VersionInfo(releaselevel=releaselevel, **version_fields) -version_info = _version_info(version) +version_info = _VersionInfo.from_string(version)