diff --git a/.flake8 b/.flake8
deleted file mode 100644
index 68e6a65b..00000000
--- a/.flake8
+++ /dev/null
@@ -1,6 +0,0 @@
-[flake8]
-max-line-length = 88
-extend-ignore = E203,E501,E701
-extend-exclude =
- build,
- lib
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8cdb3dbe..4db16665 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,11 +17,9 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
- - run: python -m pip install --upgrade pip bandit black build flake8 isort mypy numpy twine
- - run: bandit -c pyproject.toml -r .
- - run: black --check .
- - run: flake8
- - run: isort --check .
+ - run: python -m pip install --upgrade build mypy numpy pip ruff twine
+ - run: ruff format --check
+ - run: ruff check
- run: mypy
- run: python -m build --sdist
- run: python -m twine check dist/*
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 10753086..5ca23dc3 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -16,8 +16,10 @@ jobs:
with:
python-version: '3.12'
cache: 'pip'
- - run: python -m pip install --upgrade pip bandit build twine
- - run: bandit -c pyproject.toml -r .
+ - run: python -m pip install --upgrade build mypy numpy pip ruff twine
+ - run: ruff format --check
+ - run: ruff check
+ - run: mypy
- run: python -m build --sdist
- run: python -m twine check dist/*
- run: pip install --pre "$(ls dist/hdf5plugin*.tar.gz)[test]"
diff --git a/doc/contribute.rst b/doc/contribute.rst
index fbc5ebb0..6fdc822d 100644
--- a/doc/contribute.rst
+++ b/doc/contribute.rst
@@ -29,23 +29,15 @@ Formatting/Linting
From the source directory:
-* Format code with `black `_::
+* To format the code, use `ruff format `_::
- black .
+ ruff format
-* Sort imports with `isort `_::
+* To check (lint) the code, use `ruff check `_::
- isort .
+ ruff check
-* Check code with `flake8 `_::
-
- flake8
-
-* Check code with `bandit `_ security linter::
-
- bandit -c pyproject.toml -r .
-
-* Check typing with `mypy `_::
+* To check typing, use `mypy `_::
mypy
diff --git a/doc/hdf5plugin_EuropeanHUG2021.ipynb b/doc/hdf5plugin_EuropeanHUG2021.ipynb
index c5ea342c..ea76c65f 100755
--- a/doc/hdf5plugin_EuropeanHUG2021.ipynb
+++ b/doc/hdf5plugin_EuropeanHUG2021.ipynb
@@ -51,12 +51,14 @@
"%matplotlib inline\n",
"\n",
"# Creates data.h5 used for demos\n",
+ "import urllib.request\n",
+ "\n",
+ "import numpy\n",
"from matplotlib import pyplot as plt\n",
+ "from PIL import Image\n",
+ "\n",
"import h5py\n",
"import hdf5plugin\n",
- "import numpy\n",
- "from PIL import Image\n",
- "import urllib.request\n",
"\n",
"url = \"https://www.eiroforum.org/wp-content/uploads/pg-esrf-01.jpg\"\n",
"filename = urllib.request.urlretrieve(url)[0]\n",
@@ -67,7 +69,9 @@
"h5file[\"copyright\"] = \"P.Ginter/ESRF\"\n",
"h5file.attrs[\"url\"] = url\n",
"h5file.create_dataset(\"/data\", data=image)\n",
- "h5file.create_dataset(\"/compressed_data_bitshuffle_lz4\", data=image, **hdf5plugin.Bitshuffle())\n",
+ "h5file.create_dataset(\n",
+ " \"/compressed_data_bitshuffle_lz4\", data=image, **hdf5plugin.Bitshuffle()\n",
+ ")\n",
"h5file.close()\n",
"\n",
"# Restart kernel once the file is created!"
@@ -334,6 +338,7 @@
],
"source": [
"from h5glance import H5Glance # Browsing HDF5 files\n",
+ "\n",
"H5Glance(\"data.h5\")"
]
},
@@ -373,8 +378,9 @@
"import h5py # Pythonic HDF5 wrapper: https://docs.h5py.org/\n",
"\n",
"h5file = h5py.File(\"data.h5\", mode=\"r\") # Open HDF5 file in read mode\n",
- "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\"\n",
- "plt.imshow(data); plt.colorbar() # Display data"
+ "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\"\n",
+ "plt.imshow(data) # Display data\n",
+ "plt.colorbar()"
]
},
{
@@ -506,7 +512,8 @@
],
"source": [
"data = h5file[\"/compressed_data_bitshuffle_lz4\"][()] # Access datset\n",
- "plt.imshow(data); plt.colorbar() # Display data"
+ "plt.imshow(data) # Display data\n",
+ "plt.colorbar()"
]
},
{
@@ -567,7 +574,7 @@
" \"/compressed_data_bitshuffle_lz4\",\n",
" data=data,\n",
" compression=32008, # bitshuffle/lz4 HDF5 filter identifier\n",
- " compression_opts=(0, 2) # options: default number of elements/block, enable LZ4\n",
+ " compression_opts=(0, 2), # options: default number of elements/block, enable LZ4\n",
")\n",
"h5file.close()"
]
@@ -597,7 +604,7 @@
"h5file.create_dataset(\n",
" \"/compressed_data_bitshuffle_lz4\",\n",
" data=data,\n",
- " **hdf5plugin.Bitshuffle() # Or: **hdf5plugin.BitShuffle(lz4=True)\n",
+ " **hdf5plugin.Bitshuffle(), # Or: **hdf5plugin.BitShuffle(lz4=True)\n",
")\n",
"h5file.close()"
]
@@ -847,7 +854,8 @@
],
"source": [
"h5file = h5py.File(\"new_file_bitshuffle_lz4.h5\", mode=\"r\")\n",
- "plt.imshow(h5file[\"/compressed_data_bitshuffle_lz4\"][()]); plt.colorbar()\n",
+ "plt.imshow(h5file[\"/compressed_data_bitshuffle_lz4\"][()])\n",
+ "plt.colorbar()\n",
"h5file.close()"
]
},
@@ -914,7 +922,8 @@
"source": [
"h5file = h5py.File(\"new_file_shuffle_gzip.h5\", mode=\"w\")\n",
"h5file.create_dataset(\n",
- " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\")\n",
+ " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\"\n",
+ ")\n",
"h5file.close()"
]
},
@@ -947,7 +956,7 @@
"h5file.create_dataset(\n",
" \"/compressed_data_blosc\",\n",
" data=data,\n",
- " **hdf5plugin.Blosc(cname='zlib', clevel=5, shuffle=hdf5plugin.Blosc.SHUFFLE)\n",
+ " **hdf5plugin.Blosc(cname=\"zlib\", clevel=5, shuffle=hdf5plugin.Blosc.SHUFFLE),\n",
")\n",
"h5file.close()"
]
@@ -1098,7 +1107,7 @@
}
],
"source": [
- "!h5dump -d /compressed_data_bitshuffle_lz4 -s \"0,0\" -c \"5,10\" data.h5 "
+ "!h5dump -d /compressed_data_bitshuffle_lz4 -s \"0,0\" -c \"5,10\" data.h5"
]
},
{
@@ -1137,7 +1146,7 @@
"outputs": [],
"source": [
"# Retrieve hdf5plugin.PLUGINS_PATH from the command line\n",
- "!python3 -c \"import hdf5plugin; print(hdf5plugin.PLUGINS_PATH)\" "
+ "!python3 -c \"import hdf5plugin; print(hdf5plugin.PLUGINS_PATH)\""
]
},
{
diff --git a/doc/hdf5plugin_EuropeanHUG2022.ipynb b/doc/hdf5plugin_EuropeanHUG2022.ipynb
index 4c0475bb..3f45185e 100644
--- a/doc/hdf5plugin_EuropeanHUG2022.ipynb
+++ b/doc/hdf5plugin_EuropeanHUG2022.ipynb
@@ -30,7 +30,7 @@
"source": [
"# Notebook requirements\n",
"# A recent version of Pillow is required!\n",
- "#%pip install numpy h5py hdf5plugin h5glance rise jupyterlab matplotlib ipympl Pillow"
+ "# %pip install numpy h5py hdf5plugin h5glance rise jupyterlab matplotlib ipympl Pillow"
]
},
{
@@ -47,12 +47,14 @@
"%matplotlib inline\n",
"\n",
"# Creates data.h5 used for demos\n",
+ "import urllib.request\n",
+ "\n",
+ "import numpy\n",
"from matplotlib import pyplot as plt\n",
+ "from PIL import Image\n",
+ "\n",
"import h5py\n",
"import hdf5plugin\n",
- "import numpy\n",
- "from PIL import Image\n",
- "import urllib.request\n",
"\n",
"url = \"https://www.iter.org/doc/www/content/com/Lists/WebText_2014/Attachments/236/platform_view_north_1.jpg\"\n",
"filename = urllib.request.urlretrieve(url)[0]\n",
@@ -66,7 +68,7 @@
"h5file.create_dataset(\n",
" \"/compressed_data\",\n",
" data=image,\n",
- " **hdf5plugin.Blosc('lz4', shuffle=hdf5plugin.Blosc.BITSHUFFLE)\n",
+ " **hdf5plugin.Blosc(\"lz4\", shuffle=hdf5plugin.Blosc.BITSHUFFLE),\n",
")\n",
"h5file.close()"
]
@@ -93,6 +95,7 @@
"outputs": [],
"source": [
"import os\n",
+ "\n",
"os._exit(0) # Makes the kernel restart"
]
},
@@ -110,6 +113,7 @@
"%matplotlib inline\n",
"from matplotlib import pyplot as plt\n",
"\n",
+ "\n",
"def imshow(image):\n",
" plt.imshow(image)\n",
" plt.colorbar()"
@@ -360,6 +364,7 @@
],
"source": [
"from h5glance import H5Glance # Browsing HDF5 files\n",
+ "\n",
"H5Glance(\"data.h5\")"
]
},
@@ -389,8 +394,8 @@
"import h5py # Pythonic HDF5 wrapper: https://docs.h5py.org/\n",
"\n",
"h5file = h5py.File(\"data.h5\", mode=\"r\") # Open HDF5 file in read mode\n",
- "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\"\n",
- "imshow(data) # Display data"
+ "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\"\n",
+ "imshow(data) # Display data"
]
},
{
@@ -536,7 +541,7 @@
],
"source": [
"data = h5file[\"/compressed_data\"][()] # Access datset\n",
- "imshow(data) # Display data"
+ "imshow(data) # Display data"
]
},
{
@@ -598,7 +603,7 @@
" data=data,\n",
" compression=32001, # blosc HDF5 filter identifier\n",
" # options: 0, 0, 0, 0, level, shuffle, compression\n",
- " compression_opts=(0, 0, 0, 0, 5, 2, 1) \n",
+ " compression_opts=(0, 0, 0, 0, 5, 2, 1),\n",
")\n",
"h5file.close()"
]
@@ -628,10 +633,7 @@
"h5file.create_dataset(\n",
" \"/compressed_data\",\n",
" data=data,\n",
- " **hdf5plugin.Blosc(\n",
- " cname='lz4',\n",
- " clevel=5,\n",
- " shuffle=hdf5plugin.Blosc.BITSHUFFLE),\n",
+ " **hdf5plugin.Blosc(cname=\"lz4\", clevel=5, shuffle=hdf5plugin.Blosc.BITSHUFFLE),\n",
")\n",
"h5file.close()"
]
@@ -1071,7 +1073,8 @@
"source": [
"h5file = h5py.File(\"new_file_shuffle_gzip.h5\", mode=\"w\")\n",
"h5file.create_dataset(\n",
- " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\")\n",
+ " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\"\n",
+ ")\n",
"h5file.close()"
]
},
@@ -1102,9 +1105,7 @@
"source": [
"h5file = h5py.File(\"new_file_bitshuffle_lz4.h5\", mode=\"w\")\n",
"h5file.create_dataset(\n",
- " \"/compressed_data_bitshuffle_lz4\",\n",
- " data=data,\n",
- " **hdf5plugin.Bitshuffle()\n",
+ " \"/compressed_data_bitshuffle_lz4\", data=data, **hdf5plugin.Bitshuffle()\n",
")\n",
"h5file.close()"
]
diff --git a/doc/hdf5plugin_EuropeanHUG2023/benchmark.ipynb b/doc/hdf5plugin_EuropeanHUG2023/benchmark.ipynb
index a5c89922..351b7a27 100644
--- a/doc/hdf5plugin_EuropeanHUG2023/benchmark.ipynb
+++ b/doc/hdf5plugin_EuropeanHUG2023/benchmark.ipynb
@@ -116,16 +116,13 @@
"outputs": [],
"source": [
"# Initialization\n",
- "#%matplotlib inline\n",
+ "# %matplotlib inline\n",
"%matplotlib widget\n",
"\n",
+ "import numpy\n",
"from matplotlib import pyplot as plt\n",
- "from matplotlib.colors import LogNorm\n",
"\n",
- "import numpy\n",
- "import h5py\n",
- "import hdf5plugin\n",
- "from h5glance import H5Glance"
+ "import hdf5plugin"
]
},
{
@@ -141,6 +138,7 @@
"\n",
"from typing import NamedTuple\n",
"\n",
+ "\n",
"class Result(NamedTuple):\n",
" \"\"\"Store benchmark result\"\"\"\n",
"\n",
@@ -150,35 +148,38 @@
" read_duration: float\n",
" chunks: tuple[int]\n",
"\n",
- " compression_rate = property(\n",
- " lambda self: self.raw_nbytes / self.compressed_nbytes)\n",
+ " compression_rate = property(lambda self: self.raw_nbytes / self.compressed_nbytes)\n",
" write_speed = property(\n",
" lambda self: (self.raw_nbytes / 1024**2) / self.write_duration,\n",
- " doc=\"Unit: MB/sec\")\n",
+ " doc=\"Unit: MB/sec\",\n",
+ " )\n",
" read_speed = property(\n",
" lambda self: (self.raw_nbytes / 1024**2) / self.read_duration,\n",
- " doc=\"Unit: MB/sec\")\n",
+ " doc=\"Unit: MB/sec\",\n",
+ " )\n",
"\n",
- " \n",
- "def display_results(title: str='', key=None, **results):\n",
+ "\n",
+ "def display_results(title: str = \"\", key=None, **results):\n",
" \"\"\"Plot comparison of compression results.\n",
- " \n",
+ "\n",
" :param title: Additional dataset name\n",
" :param key: Key function to customize the sort\n",
- " :param **results: {compression-name: Result} mapping \n",
+ " :param **results: {compression-name: Result} mapping\n",
" \"\"\"\n",
" # Sort results by compression rate\n",
- " results = dict(sorted(\n",
- " results.items(),\n",
- " key=(lambda item: item[1].compression_rate) if key is None else key,\n",
- " ))\n",
- " \n",
+ " results = dict(\n",
+ " sorted(\n",
+ " results.items(),\n",
+ " key=(lambda item: item[1].compression_rate) if key is None else key,\n",
+ " )\n",
+ " )\n",
+ "\n",
" names = list(results.keys())\n",
" write_speed = numpy.array([r.write_speed for r in results.values()])\n",
" read_speed = numpy.array([r.read_speed for r in results.values()])\n",
" c_rate = numpy.array([r.compression_rate for r in results.values()])\n",
- " \n",
- " #print(f\"hdf5plugin_config: {results[names[0]].config}\")\n",
+ "\n",
+ " # print(f\"hdf5plugin_config: {results[names[0]].config}\")\n",
"\n",
" fig, axes = plt.subplots(1, 2)\n",
" speed_plt, c_rate_plt = axes\n",
@@ -188,23 +189,25 @@
" ticks = numpy.arange(len(names))\n",
"\n",
" # Speed\n",
- " speed_plt.barh(y=ticks, width=write_speed, height=0.4, align='edge', label=\"Write\")\n",
- " speed_plt.barh(y=ticks-.4, width=read_speed, height=0.4, align='edge', label=\"Read\")\n",
+ " speed_plt.barh(y=ticks, width=write_speed, height=0.4, align=\"edge\", label=\"Write\")\n",
+ " speed_plt.barh(\n",
+ " y=ticks - 0.4, width=read_speed, height=0.4, align=\"edge\", label=\"Read\"\n",
+ " )\n",
" speed_plt.set_xlabel(\"Speed [MB/s]\")\n",
- " speed_plt.autoscale(axis='y')\n",
+ " speed_plt.autoscale(axis=\"y\")\n",
" speed_plt.yaxis.set_ticks(ticks)\n",
" speed_plt.yaxis.set_ticklabels(names, fontsize=8)\n",
- " speed_plt.set_ylim(-0.5, len(ticks)-0.5)\n",
+ " speed_plt.set_ylim(-0.5, len(ticks) - 0.5)\n",
" speed_plt.grid(axis=\"x\")\n",
" speed_plt.legend()\n",
- " \n",
+ "\n",
" # Compression ratio\n",
" c_rate_plt.barh(y=ticks, width=c_rate)\n",
" c_rate_plt.set_xlabel(\"Compression rate\")\n",
- " c_rate_plt.autoscale(axis='y')\n",
+ " c_rate_plt.autoscale(axis=\"y\")\n",
" c_rate_plt.yaxis.set_ticks(ticks)\n",
- " c_rate_plt.yaxis.set_ticklabels([''] * len(ticks))\n",
- " c_rate_plt.set_ylim(-0.5,len(ticks)-0.5)\n",
+ " c_rate_plt.yaxis.set_ticklabels([\"\"] * len(ticks))\n",
+ " c_rate_plt.set_ylim(-0.5, len(ticks) - 0.5)\n",
" c_rate_plt.axvline(1, color=\"red\")\n",
" c_rate_plt.grid(axis=\"x\")\n",
"\n",
@@ -212,25 +215,30 @@
"\n",
" # Tooltip\n",
" tooltip = c_rate_plt.annotate(\n",
- " \"\", (0, 0), backgroundcolor=\"lightyellow\",\n",
- " verticalalignment=\"top\", xycoords='figure pixels')\n",
+ " \"\",\n",
+ " (0, 0),\n",
+ " backgroundcolor=\"lightyellow\",\n",
+ " verticalalignment=\"top\",\n",
+ " xycoords=\"figure pixels\",\n",
+ " )\n",
" tooltip.set_visible(False)\n",
"\n",
" def hover(event):\n",
" if event.inaxes in (speed_plt, c_rate_plt):\n",
- " index = numpy.clip(round(event.ydata), 0, len(names)-1)\n",
+ " index = numpy.clip(round(event.ydata), 0, len(names) - 1)\n",
" tooltip.set_text(\n",
" f\"{names[index]}\\n\"\n",
" f\"Comp. Rate: {c_rate[index]:.2f}x\\n\"\n",
" f\"Write: {write_speed[index]:.1f}MB/s\\n\"\n",
- " f\"Read: {read_speed[index]:.1f}MB/s\")\n",
+ " f\"Read: {read_speed[index]:.1f}MB/s\"\n",
+ " )\n",
" tooltip.set_x(event.x + 15)\n",
" tooltip.set_y(event.y)\n",
" tooltip.set_visible(True)\n",
" else:\n",
" tooltip.set_visible(False)\n",
" fig.canvas.draw_idle()\n",
- " \n",
+ "\n",
" def resize(event):\n",
" fig.tight_layout()\n",
"\n",
@@ -279,17 +287,18 @@
}
],
"source": [
- "import os\n",
"import sys\n",
"\n",
- "print('Python:', sys.version)\n",
+ "print(\"Python:\", sys.version)\n",
"\n",
"config = hdf5plugin.get_config()\n",
"print(f\"\"\"hdf5plugin:\n",
"* Version: {hdf5plugin.version}\n",
"* Build config:\n",
- "{'''\n",
- "'''.join(f' - {k}: {v}' for k, v in config.build_config._asdict().items())}\n",
+ "{\n",
+ " '''\n",
+ "'''.join(f\" - {k}: {v}\" for k, v in config.build_config._asdict().items())\n",
+ "}\n",
"\"\"\")"
]
},
@@ -352,10 +361,7 @@
}
],
"source": [
- "display_results(\n",
- " title=\"Filters comparison\",\n",
- " **results\n",
- ")"
+ "display_results(title=\"Filters comparison\", **results)"
]
},
{
diff --git a/doc/hdf5plugin_EuropeanHUG2023/benchmark.py b/doc/hdf5plugin_EuropeanHUG2023/benchmark.py
index 6f53a9b7..8ae60424 100644
--- a/doc/hdf5plugin_EuropeanHUG2023/benchmark.py
+++ b/doc/hdf5plugin_EuropeanHUG2023/benchmark.py
@@ -9,9 +9,10 @@
import time
from typing import NamedTuple, Optional
-import h5py
import numpy
+import h5py
+
# Set affinity and env. var. before importing hdf5plugin
if len(sys.argv) >= 2:
diff --git a/doc/hdf5plugin_EuropeanHUG2023/hdf5_compressed_chunk_direct_read.ipynb b/doc/hdf5plugin_EuropeanHUG2023/hdf5_compressed_chunk_direct_read.ipynb
index 07e30cb6..2520996b 100644
--- a/doc/hdf5plugin_EuropeanHUG2023/hdf5_compressed_chunk_direct_read.ipynb
+++ b/doc/hdf5plugin_EuropeanHUG2023/hdf5_compressed_chunk_direct_read.ipynb
@@ -40,27 +40,12 @@
"env:\n",
" OPENMP_NUM_THREADS: 1\n",
" BLOSC_NTHREADS: 1\n",
- "\n",
- "hdf5plugin:\n",
- " Version: 4.2.0\n",
- " Build config:\n",
- " openmp: True\n",
- " native: True\n",
- " bmi2: True\n",
- " sse2: True\n",
- " avx2: True\n",
- " avx512: False\n",
- " cpp11: True\n",
- " cpp14: True\n",
- " ipp: False\n",
- " filter_file_extension: .so\n",
- " embedded_filters: ('blosc', 'blosc2', 'bshuf', 'bzip2', 'fcidecomp', 'lz4', 'sz', 'sz3', 'zfp', 'zstd')\n",
"\n"
]
}
],
"source": [
- "#Set affinity and multithreading env. var. before any import\n",
+ "# Set affinity and multithreading env. var. before any import\n",
"import os\n",
"\n",
"os.sched_setaffinity(0, [0])\n",
@@ -75,8 +60,38 @@
"print(f\"\"\"env:\n",
" OPENMP_NUM_THREADS: {os.environ.get(\"OPENMP_NUM_THREADS\", \"unset\")}\n",
" BLOSC_NTHREADS: {os.environ.get(\"BLOSC_NTHREADS\", \"unset\")}\n",
- "\"\"\")\n",
- "\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "d56ca93e-9dea-4e14-bb99-c39907ab8274",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "hdf5plugin:\n",
+ " Version: 4.2.0\n",
+ " Build config:\n",
+ " openmp: True\n",
+ " native: True\n",
+ " bmi2: True\n",
+ " sse2: True\n",
+ " avx2: True\n",
+ " avx512: False\n",
+ " cpp11: True\n",
+ " cpp14: True\n",
+ " ipp: False\n",
+ " filter_file_extension: .so\n",
+ " embedded_filters: ('blosc', 'blosc2', 'bshuf', 'bzip2', 'fcidecomp', 'lz4', 'sz', 'sz3', 'zfp', 'zstd')\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
"import h5py\n",
"import hdf5plugin\n",
"\n",
@@ -85,8 +100,10 @@
"print(f\"\"\"hdf5plugin:\n",
" Version: {hdf5plugin.version}\n",
" Build config:\n",
- "{'''\n",
- "'''.join(f' {k}: {v}' for k, v in config.build_config._asdict().items())}\n",
+ "{\n",
+ " '''\n",
+ "'''.join(f\" {k}: {v}\" for k, v in config.build_config._asdict().items())\n",
+ "}\n",
"\"\"\")"
]
},
@@ -126,7 +143,6 @@
},
"outputs": [],
"source": [
- "import h5py\n",
"import hdf5plugin\n",
"\n",
"with h5py.File(\"/dev/shm/kevlar.h5\", \"r\") as h:\n",
@@ -138,7 +154,7 @@
" data=data_ref,\n",
" chunks=data_ref.shape,\n",
" compression=hdf5plugin.Blosc2(\n",
- " cname='lz4',\n",
+ " cname=\"lz4\",\n",
" clevel=5,\n",
" filters=hdf5plugin.Blosc2.BITSHUFFLE,\n",
" ),\n",
@@ -174,6 +190,7 @@
"import blosc2\n",
"import numpy\n",
"\n",
+ "\n",
"def decompress_blosc2_chunk(chunk: bytes, array: numpy.ndarray):\n",
" \"\"\"Decompress chunk data to provided array\"\"\"\n",
" blosc2.schunk_from_cframe(chunk).get_slice(out=array)"
@@ -299,13 +316,15 @@
"outputs": [],
"source": [
"import struct\n",
+ "\n",
"import bitshuffle\n",
"import numpy\n",
"\n",
+ "\n",
"def decompress_bslz4_chunk(payload, dtype, chunk_shape):\n",
- " \"\"\"This function decompresses ONE chunk with bitshuffle-LZ4. \n",
+ " \"\"\"This function decompresses ONE chunk with bitshuffle-LZ4.\n",
" The library needs to be compiled without OpenMP when using threads !\n",
- " \n",
+ "\n",
" :param payload: string with the compressed data as read by h5py.\n",
" :param dtype: data type of the stored content\n",
" :param chunk_shape: shape of one chunk\n",
@@ -426,7 +445,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.10.0"
+ "version": "3.14.4"
}
},
"nbformat": 4,
diff --git a/doc/hdf5plugin_EuropeanHUG2023/presentation.ipynb b/doc/hdf5plugin_EuropeanHUG2023/presentation.ipynb
index 2ea67c7e..4dec11d3 100644
--- a/doc/hdf5plugin_EuropeanHUG2023/presentation.ipynb
+++ b/doc/hdf5plugin_EuropeanHUG2023/presentation.ipynb
@@ -30,7 +30,7 @@
"source": [
"# Notebook requirements\n",
"# A recent version of Pillow is required!\n",
- "#%pip install numpy h5py hdf5plugin h5glance rise jupyterlab matplotlib ipympl Pillow"
+ "# %pip install numpy h5py hdf5plugin h5glance rise jupyterlab matplotlib ipympl Pillow"
]
},
{
@@ -47,12 +47,14 @@
"%matplotlib inline\n",
"\n",
"# Creates data.h5 used for demos\n",
+ "import urllib.request\n",
+ "\n",
+ "import numpy\n",
"from matplotlib import pyplot as plt\n",
+ "from PIL import Image\n",
+ "\n",
"import h5py\n",
"import hdf5plugin\n",
- "import numpy\n",
- "from PIL import Image\n",
- "import urllib.request\n",
"\n",
"url = \"https://www.desy.de/e409/e116959/e119238/media/7795/1963_Luftbild_DESY-Gelaende_1284_gf_01sw_a3.jpg\"\n",
"filename = urllib.request.urlretrieve(url)[0]\n",
@@ -67,7 +69,7 @@
" \"/compressed_data\",\n",
" data=image,\n",
" chunks=image.shape,\n",
- " **hdf5plugin.Blosc2('lz4', filters=hdf5plugin.Blosc.BITSHUFFLE)\n",
+ " **hdf5plugin.Blosc2(\"lz4\", filters=hdf5plugin.Blosc.BITSHUFFLE),\n",
")\n",
"h5file.close()"
]
@@ -94,6 +96,7 @@
"outputs": [],
"source": [
"import os\n",
+ "\n",
"os._exit(0) # Makes the kernel restart"
]
},
@@ -354,6 +357,7 @@
],
"source": [
"from h5glance import H5Glance # Browsing HDF5 files\n",
+ "\n",
"H5Glance(\"data.h5\")"
]
},
@@ -370,7 +374,7 @@
"import h5py # Pythonic HDF5 wrapper: https://docs.h5py.org/\n",
"\n",
"h5file = h5py.File(\"data.h5\", mode=\"r\") # Open HDF5 file in read mode\n",
- "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\""
+ "data = h5file[\"/data\"][()] # Access HDF5 dataset \"/data\""
]
},
{
@@ -570,7 +574,7 @@
],
"source": [
"data = h5file[\"/compressed_data\"][()] # Access datset\n",
- "plt.imshow(data, cmap=\"gray\") # Display data"
+ "plt.imshow(data, cmap=\"gray\") # Display data"
]
},
{
@@ -632,7 +636,7 @@
" data=data,\n",
" compression=32026, # Blosc2 HDF5 filter identifier\n",
" # options: 0, 0, 0, 0, level, filter, compression\n",
- " compression_opts=(0, 0, 0, 0, 5, 2, 1) \n",
+ " compression_opts=(0, 0, 0, 0, 5, 2, 1),\n",
")\n",
"h5file.close()"
]
@@ -663,9 +667,8 @@
" \"/compressed_data\",\n",
" data=data,\n",
" compression=hdf5plugin.Blosc2(\n",
- " cname='lz4',\n",
- " clevel=5,\n",
- " filters=hdf5plugin.Blosc2.BITSHUFFLE),\n",
+ " cname=\"lz4\", clevel=5, filters=hdf5plugin.Blosc2.BITSHUFFLE\n",
+ " ),\n",
")\n",
"h5file.close()"
]
@@ -982,7 +985,8 @@
"source": [
"h5file = h5py.File(\"new_file_shuffle_gzip.h5\", mode=\"w\")\n",
"h5file.create_dataset(\n",
- " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\")\n",
+ " \"/compressed_data_shuffle_gzip\", data=data, shuffle=True, compression=\"gzip\"\n",
+ ")\n",
"h5file.close()"
]
},
@@ -1015,9 +1019,7 @@
"source": [
"h5file = h5py.File(\"new_file_bitshuffle_lz4.h5\", mode=\"w\")\n",
"h5file.create_dataset(\n",
- " \"/compressed_data_bitshuffle_lz4\",\n",
- " data=data,\n",
- " compression=hdf5plugin.Bitshuffle()\n",
+ " \"/compressed_data_bitshuffle_lz4\", data=data, compression=hdf5plugin.Bitshuffle()\n",
")\n",
"h5file.close()"
]
diff --git a/pyproject.toml b/pyproject.toml
index 7e45f7e0..79084fd9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -49,10 +49,8 @@ test = [
]
dev = [
"hdf5plugin[doc,test]",
- "bandit",
- "black",
- "flake8",
- "isort",
+ "mypy",
+ "ruff",
]
[tool.setuptools]
@@ -62,27 +60,30 @@ package-dir = {"" = "src"}
[tool.setuptools.dynamic]
version = {attr = "hdf5plugin._version.version"}
-[tool.bandit]
-exclude_dirs = [
+[tool.ruff]
+exclude = [
"build",
- "doc/hdf5plugin_EuropeanHUG2023",
"lib",
]
+line-length = 88
-[tool.bandit.assert_used]
-skips = ["*test.py"]
-
-[tool.black]
-extend-exclude = '''
-(
- lib
- | .*\.ipynb
-)
-'''
+[tool.ruff.lint]
+select = [
+ "E", # pycodestyle
+ "F", # pyflakes
+ "I", # isort
+ "S", # flake8-bandit
+ "W", # pycodestyle
+]
-[tool.isort]
-profile = "black"
-skip_glob = ["lib"]
+[tool.ruff.lint.per-file-ignores]
+"*" = ["E501"] # line too long
+"test*.py" = ["S101"] # assert
+"doc/hdf5plugin_EuropeanHUG2023/*" = ["S108"] # access to /dev/shm
+# urlretrieve without url schema check
+"doc/hdf5plugin_EuropeanHUG2021.ipynb" = ["S310"]
+"doc/hdf5plugin_EuropeanHUG2022.ipynb" = ["S310"]
+"doc/hdf5plugin_EuropeanHUG2023/presentation.ipynb" = ["S310"]
[tool.mypy]
mypy_path = ["src"]
diff --git a/src/h5py.pyi b/src/h5py.pyi
index 33d5a4f3..664cdbfa 100644
--- a/src/h5py.pyi
+++ b/src/h5py.pyi
@@ -1,7 +1,7 @@
-from __future__ import annotations
-
"""mypy stubs for h5py usage in hdf5plugin"""
+from __future__ import annotations
+
import ctypes
from collections.abc import Buffer
from types import TracebackType
diff --git a/src/hdf5plugin/__init__.py b/src/hdf5plugin/__init__.py
index fab4dac6..fd7b8faf 100644
--- a/src/hdf5plugin/__init__.py
+++ b/src/hdf5plugin/__init__.py
@@ -27,13 +27,13 @@
"""
from . import _version
-from ._filters import FILTERS # noqa
from ._filters import ( # noqa
BLOSC2_ID,
BLOSC_ID,
BSHUF_ID,
BZIP2_ID,
FCIDECOMP_ID,
+ FILTERS,
LZ4,
LZ4_ID,
SPERR_ID,
diff --git a/src/hdf5plugin/test.py b/src/hdf5plugin/test.py
index bbfc0f61..fe0c6187 100644
--- a/src/hdf5plugin/test.py
+++ b/src/hdf5plugin/test.py
@@ -33,10 +33,10 @@
import unittest
from typing import Any, cast
-import h5py
import numpy
from packaging.version import parse as parse_version
+import h5py
import hdf5plugin
try:
diff --git a/test/test.py b/test/test.py
index 888a6b2a..255c3159 100644
--- a/test/test.py
+++ b/test/test.py
@@ -31,9 +31,9 @@
import tempfile
import unittest
-import h5py
import numpy
+import h5py
import hdf5plugin
from hdf5plugin import _filters
from hdf5plugin.test import suite as hdf5plugin_suite
@@ -370,9 +370,7 @@ def testReprRoundtrip(self):
with self.subTest(filter=filter_class.filter_name):
filter_instance = filter_class()
repr_string = repr(filter_instance)
- repr_instance = eval(
- repr_string, {filter_class.__name__: filter_class}
- ) # nosec
+ repr_instance = eval(repr_string, {filter_class.__name__: filter_class}) # noqa: S307
self.assertEqual(filter_instance, repr_instance)