1From 1e02dbe5533d679b9ef064078a303607a7d0542a Mon Sep 17 00:00:00 2001 2From: Alexander Kanavin <alex@linutronix.de> 3Date: Fri, 29 Dec 2023 14:33:38 +0100 4Subject: [PATCH] Fix Cython 3 compatibility 5 6Upstream-Status: Backport [https://github.com/h5py/h5py/pull/2345/commits] 7Signed-off-by: Alexander Kanavin <alex@linutronix.de> 8--- 9 benchmarks/benchmark_slicing.py | 12 ++++---- 10 docs/conf.py | 2 +- 11 docs/high/dataset.rst | 4 +-- 12 docs/high/file.rst | 6 ++-- 13 docs/requirements-rtd.txt | 5 ++-- 14 docs/vds.rst | 2 +- 15 docs/whatsnew/3.0.rst | 2 +- 16 docs/whatsnew/3.7.rst | 4 +-- 17 h5py/_errors.pxd | 10 +++---- 18 h5py/_errors.pyx | 4 +-- 19 h5py/_hl/base.py | 4 +-- 20 h5py/_hl/dataset.py | 8 ++--- 21 h5py/_hl/dims.py | 3 +- 22 h5py/_hl/files.py | 2 +- 23 h5py/_locks.pxi | 6 ++-- 24 h5py/_proxy.pyx | 4 +-- 25 h5py/_selector.pyx | 2 +- 26 h5py/api_compat.h | 13 ++++---- 27 h5py/api_types_hdf5.pxd | 48 +++++++++++++++--------------- 28 h5py/h5fd.pyx | 38 ++++++++++++++++------- 29 h5py/h5p.pyx | 4 +-- 30 h5py/h5t.pyx | 2 +- 31 h5py/tests/test_attrs_data.py | 2 +- 32 h5py/tests/test_big_endian_file.py | 4 +-- 33 h5py/tests/test_dataset.py | 4 +-- 34 h5py/tests/test_file.py | 6 ++-- 35 h5py/tests/test_file_alignment.py | 4 +-- 36 h5py/tests/test_group.py | 4 +-- 37 h5py/tests/test_selections.py | 2 +- 38 pylintrc | 2 +- 39 pyproject.toml | 2 +- 40 setup_configure.py | 2 +- 41 tox.ini | 2 +- 42 33 files changed, 116 insertions(+), 103 deletions(-) 43 44diff --git a/benchmarks/benchmark_slicing.py b/benchmarks/benchmark_slicing.py 45index e9a34dad..b833f012 100644 46--- a/benchmarks/benchmark_slicing.py 47+++ b/benchmarks/benchmark_slicing.py 48@@ -7,7 +7,7 @@ import logging 49 logger = logging.getLogger(__name__) 50 import h5py 51 52-#Needed for mutithreading: 53+#Needed for multithreading: 54 from queue import Queue 55 from threading import Thread, Event 56 import multiprocessing 57@@ -173,8 +173,8 @@ class SlicingBenchmark: 58 59 if __name__ == "__main__": 60 logging.basicConfig(level=logging.INFO) 61- benckmark = SlicingBenchmark() 62- benckmark.setup() 63- benckmark.time_sequential_reads() 64- benckmark.time_threaded_reads() 65- benckmark.teardown() 66+ benchmark = SlicingBenchmark() 67+ benchmark.setup() 68+ benchmark.time_sequential_reads() 69+ benchmark.time_threaded_reads() 70+ benchmark.teardown() 71diff --git a/docs/conf.py b/docs/conf.py 72index 93b23939..a0f6c1ac 100644 73--- a/docs/conf.py 74+++ b/docs/conf.py 75@@ -109,7 +109,7 @@ pygments_style = 'sphinx' 76 77 # The theme to use for HTML and HTML Help pages. See the documentation for 78 # a list of builtin themes. 79-html_theme = 'default' 80+html_theme = 'sphinx_rtd_theme' 81 82 # Theme options are theme-specific and customize the look and feel of a theme 83 # further. For a list of options available for each theme, see the 84diff --git a/docs/high/dataset.rst b/docs/high/dataset.rst 85index 0f27284f..cb75fffe 100644 86--- a/docs/high/dataset.rst 87+++ b/docs/high/dataset.rst 88@@ -58,7 +58,7 @@ the requested ``dtype``. 89 Reading & writing data 90 ---------------------- 91 92-HDF5 datasets re-use the NumPy slicing syntax to read and write to the file. 93+HDF5 datasets reuse the NumPy slicing syntax to read and write to the file. 94 Slice specifications are translated directly to HDF5 "hyperslab" 95 selections, and are a fast and efficient way to access data in the file. The 96 following slicing arguments are recognized: 97@@ -464,7 +464,7 @@ Reference 98 >>> dset = f["MyDS"] 99 >>> f.close() 100 >>> if dset: 101- ... print("datset accessible") 102+ ... print("dataset accessible") 103 ... else: 104 ... print("dataset inaccessible") 105 dataset inaccessible 106diff --git a/docs/high/file.rst b/docs/high/file.rst 107index 484498ce..e757fe1a 100644 108--- a/docs/high/file.rst 109+++ b/docs/high/file.rst 110@@ -392,7 +392,7 @@ Data alignment 111 When creating datasets within files, it may be advantageous to align the offset 112 within the file itself. This can help optimize read and write times if the data 113 become aligned with the underlying hardware, or may help with parallelism with 114-MPI. Unfortunately, aligning small variables to large blocks can leave alot of 115+MPI. Unfortunately, aligning small variables to large blocks can leave a lot of 116 empty space in a file. To this effect, application developers are left with two 117 options to tune the alignment of data within their file. The two variables 118 ``alignment_threshold`` and ``alignment_interval`` in the :class:`File` 119@@ -415,7 +415,7 @@ number of regions. Setting a small value can reduce the overall file size, 120 especially in combination with the ``libver`` option. This controls how the 121 overall data and metadata are laid out within the file. 122 123-For more information, see the offical HDF5 documentation `H5P_SET_META_BLOCK_SIZE 124+For more information, see the official HDF5 documentation `H5P_SET_META_BLOCK_SIZE 125 <https://portal.hdfgroup.org/display/HDF5/H5P_SET_META_BLOCK_SIZE>`_. 126 127 Reference 128@@ -497,7 +497,7 @@ Reference 129 Only available with HDF5 >= 1.12.1 or 1.10.x >= 1.10.7. 130 :param alignment_threshold: Together with ``alignment_interval``, this 131 property ensures that any file object greater than or equal 132- in size to the alignement threshold (in bytes) will be 133+ in size to the alignment threshold (in bytes) will be 134 aligned on an address which is a multiple of alignment interval. 135 :param alignment_interval: This property should be used in conjunction with 136 ``alignment_threshold``. See the description above. For more 137diff --git a/docs/requirements-rtd.txt b/docs/requirements-rtd.txt 138index e67a3eee..52096927 100644 139--- a/docs/requirements-rtd.txt 140+++ b/docs/requirements-rtd.txt 141@@ -1,3 +1,2 @@ 142-sphinx==4.3.0 143-sphinx_rtd_theme==1.0.0 144-readthedocs-sphinx-search==0.1.1 145+sphinx==7.2.6 146+sphinx_rtd_theme==1.3.0 147diff --git a/docs/vds.rst b/docs/vds.rst 148index a9a7c7f6..bd47ad1c 100644 149--- a/docs/vds.rst 150+++ b/docs/vds.rst 151@@ -124,7 +124,7 @@ Reference 152 slice it to indicate which regions should be used in the virtual dataset. 153 154 When `creating a virtual dataset <creating_vds_>`_, paths to sources present 155- in the same file are changed to a ".", refering to the current file (see 156+ in the same file are changed to a ".", referring to the current file (see 157 `H5Pset_virtual <https://portal.hdfgroup.org/display/HDF5/H5P_SET_VIRTUAL>`_). 158 This will keep such sources valid in case the file is renamed. 159 160diff --git a/docs/whatsnew/3.0.rst b/docs/whatsnew/3.0.rst 161index db30ad66..ff3c2bef 100644 162--- a/docs/whatsnew/3.0.rst 163+++ b/docs/whatsnew/3.0.rst 164@@ -44,7 +44,7 @@ New features 165 See also the deprecation related to the ``external`` argument. 166 * Support for setting file space strategy at file creation. Includes option to 167 persist empty space tracking between sessions. See :class:`.File` for details. 168-* More efficient writing when assiging a scalar to a chunked dataset, when the 169+* More efficient writing when assigning a scalar to a chunked dataset, when the 170 number of elements to write is no more than the size of one chunk. 171 * Introduced support for the split :ref:`file driver <file_driver>` 172 (:pr:`1468`). 173diff --git a/docs/whatsnew/3.7.rst b/docs/whatsnew/3.7.rst 174index 27790254..2e822d68 100644 175--- a/docs/whatsnew/3.7.rst 176+++ b/docs/whatsnew/3.7.rst 177@@ -19,7 +19,7 @@ New features 178 include it. Alternatively, you can :ref:`build h5py from source <source_install>` 179 against an HDF5 build with the direct driver enabled. 180 * The :class:`.File` constructor contains two new parameters ``alignment_threshold``, 181- and ``alignment_interval`` controling the data alignment within the HDF5 182+ and ``alignment_interval`` controlling the data alignment within the HDF5 183 file (:pr:`2040`). 184 * :meth:`~.Group.create_dataset` and :meth:`~.Group.require_dataset` now accept 185 parameters ``efile_prefix`` and ``virtual_prefix`` to set a filesystem path 186@@ -40,7 +40,7 @@ Bug fixes 187 attributes with ``track_order=True``. 188 * Fix for building with mpi4py on Python 3.10 (:pr:`2101`). 189 * Fixed fancy indexing with a boolean array for a single dimension (:pr:`2079`). 190-* Avoid returning unitialised memory when reading from a chunked dataset with 191+* Avoid returning uninitialised memory when reading from a chunked dataset with 192 missing chunks and no fill value (:pr:`2076`). 193 * Enable setting of fillvalue for datasets with variable length string dtype 194 (:pr:`2044`). 195diff --git a/h5py/_errors.pxd b/h5py/_errors.pxd 196index df9c1bbe..3cba6307 100644 197--- a/h5py/_errors.pxd 198+++ b/h5py/_errors.pxd 199@@ -23,7 +23,7 @@ cdef extern from "hdf5.h": 200 H5E_ARGS, # invalid arguments to routine 201 H5E_RESOURCE, # resource unavailable 202 H5E_INTERNAL, # Internal error (too specific to document) 203- H5E_FILE, # file Accessability 204+ H5E_FILE, # file Accessibility 205 H5E_IO, # Low-level I/O 206 H5E_FUNC, # function Entry/Exit 207 H5E_ATOM, # object Atom 208@@ -121,7 +121,7 @@ cdef extern from "hdf5.h": 209 # No error 210 H5E_NONE_MINOR # No error 211 212- # File accessability errors 213+ # File accessibility errors 214 H5E_FILEEXISTS # File already exists 215 H5E_FILEOPEN # File already open 216 H5E_CANTCREATE # Unable to create file 217@@ -207,7 +207,7 @@ cdef extern from "hdf5.h": 218 H5E_ARGS, # invalid arguments to routine 219 H5E_RESOURCE, # resource unavailable 220 H5E_INTERNAL, # Internal error (too specific to document) 221- H5E_FILE, # file Accessability 222+ H5E_FILE, # file Accessibility 223 H5E_IO, # Low-level I/O 224 H5E_FUNC, # function Entry/Exit 225 H5E_ID, # object ID 226@@ -305,7 +305,7 @@ cdef extern from "hdf5.h": 227 # No error 228 H5E_NONE_MINOR # No error 229 230- # File accessability errors 231+ # File accessibility errors 232 H5E_FILEEXISTS # File already exists 233 H5E_FILEOPEN # File already open 234 H5E_CANTCREATE # Unable to create file 235@@ -425,4 +425,4 @@ ctypedef struct err_cookie: 236 cdef err_cookie set_error_handler(err_cookie handler) 237 238 # Set the default error handler set by silence_errors/unsilence_errors 239-cdef void set_default_error_handler() nogil 240+cdef void set_default_error_handler() noexcept nogil 241diff --git a/h5py/_errors.pyx b/h5py/_errors.pyx 242index c3bd184e..2a7524b2 100644 243--- a/h5py/_errors.pyx 244+++ b/h5py/_errors.pyx 245@@ -94,7 +94,7 @@ cdef struct err_data_t: 246 H5E_error_t err 247 int n 248 249-cdef herr_t walk_cb(unsigned int n, const H5E_error_t *desc, void *e) nogil noexcept: 250+cdef herr_t walk_cb(unsigned int n, const H5E_error_t *desc, void *e) noexcept nogil: 251 252 cdef err_data_t *ee = <err_data_t*>e 253 254@@ -168,7 +168,7 @@ cdef err_cookie _error_handler # Store error handler used by h5py 255 _error_handler.func = NULL 256 _error_handler.data = NULL 257 258-cdef void set_default_error_handler() nogil: 259+cdef void set_default_error_handler() noexcept nogil: 260 """Set h5py's current default error handler""" 261 H5Eset_auto(<hid_t>H5E_DEFAULT, _error_handler.func, _error_handler.data) 262 263diff --git a/h5py/_hl/base.py b/h5py/_hl/base.py 264index cad37053..9d261c90 100644 265--- a/h5py/_hl/base.py 266+++ b/h5py/_hl/base.py 267@@ -20,7 +20,7 @@ import posixpath 268 import numpy as np 269 270 # The high-level interface is serialized; every public API function & method 271-# is wrapped in a lock. We re-use the low-level lock because (1) it's fast, 272+# is wrapped in a lock. We reuse the low-level lock because (1) it's fast, 273 # and (2) it eliminates the possibility of deadlocks due to out-of-order 274 # lock acquisition. 275 from .._objects import phil, with_phil 276@@ -524,7 +524,7 @@ def product(nums): 277 # Daniel Greenfeld, BSD license), where it is attributed to bottle (Copyright 278 # (c) 2009-2022, Marcel Hellkamp, MIT license). 279 280-class cached_property(object): 281+class cached_property: 282 def __init__(self, func): 283 self.__doc__ = getattr(func, "__doc__") 284 self.func = func 285diff --git a/h5py/_hl/dataset.py b/h5py/_hl/dataset.py 286index b69aba48..77b202d2 100644 287--- a/h5py/_hl/dataset.py 288+++ b/h5py/_hl/dataset.py 289@@ -334,10 +334,10 @@ class ChunkIterator: 290 self._layout = dset.chunks 291 if source_sel is None: 292 # select over entire dataset 293- slices = [] 294- for dim in range(rank): 295- slices.append(slice(0, self._shape[dim])) 296- self._sel = tuple(slices) 297+ self._sel = tuple( 298+ slice(0, self._shape[dim]) 299+ for dim in range(rank) 300+ ) 301 else: 302 if isinstance(source_sel, slice): 303 self._sel = (source_sel,) 304diff --git a/h5py/_hl/dims.py b/h5py/_hl/dims.py 305index d3c9206b..0cf4c9f3 100644 306--- a/h5py/_hl/dims.py 307+++ b/h5py/_hl/dims.py 308@@ -53,8 +53,7 @@ class DimensionProxy(base.CommonStateObject): 309 310 @with_phil 311 def __iter__(self): 312- for k in self.keys(): 313- yield k 314+ yield from self.keys() 315 316 @with_phil 317 def __len__(self): 318diff --git a/h5py/_hl/files.py b/h5py/_hl/files.py 319index aa4fb78d..bfcf3098 100644 320--- a/h5py/_hl/files.py 321+++ b/h5py/_hl/files.py 322@@ -480,7 +480,7 @@ class File(Group): 323 324 alignment_threshold 325 Together with ``alignment_interval``, this property ensures that 326- any file object greater than or equal in size to the alignement 327+ any file object greater than or equal in size to the alignment 328 threshold (in bytes) will be aligned on an address which is a 329 multiple of alignment interval. 330 331diff --git a/h5py/_locks.pxi b/h5py/_locks.pxi 332index bc8b2dd9..1ec4e2fc 100644 333--- a/h5py/_locks.pxi 334+++ b/h5py/_locks.pxi 335@@ -63,7 +63,7 @@ cdef class FastRLock: 336 return self._owner == pythread.PyThread_get_thread_ident() 337 338 339-cdef inline bint lock_lock(FastRLock lock, long current_thread, bint blocking) nogil: 340+cdef inline bint lock_lock(FastRLock lock, long current_thread, bint blocking) noexcept nogil: 341 # Note that this function *must* hold the GIL when being called. 342 # We just use 'nogil' in the signature to make sure that no Python 343 # code execution slips in that might free the GIL 344@@ -83,7 +83,7 @@ cdef inline bint lock_lock(FastRLock lock, long current_thread, bint blocking) n 345 lock, current_thread, 346 pythread.WAIT_LOCK if blocking else pythread.NOWAIT_LOCK) 347 348-cdef bint _acquire_lock(FastRLock lock, long current_thread, int wait) nogil: 349+cdef bint _acquire_lock(FastRLock lock, long current_thread, int wait) noexcept nogil: 350 # Note that this function *must* hold the GIL when being called. 351 # We just use 'nogil' in the signature to make sure that no Python 352 # code execution slips in that might free the GIL 353@@ -111,7 +111,7 @@ cdef bint _acquire_lock(FastRLock lock, long current_thread, int wait) nogil: 354 lock._count = 1 355 return 1 356 357-cdef inline void unlock_lock(FastRLock lock) nogil: 358+cdef inline void unlock_lock(FastRLock lock) noexcept nogil: 359 # Note that this function *must* hold the GIL when being called. 360 # We just use 'nogil' in the signature to make sure that no Python 361 # code execution slips in that might free the GIL 362diff --git a/h5py/_proxy.pyx b/h5py/_proxy.pyx 363index 46b4fe0d..e40504f5 100644 364--- a/h5py/_proxy.pyx 365+++ b/h5py/_proxy.pyx 366@@ -241,7 +241,7 @@ ctypedef struct h5py_scatter_t: 367 void* buf 368 369 cdef herr_t h5py_scatter_cb(void* elem, hid_t type_id, unsigned ndim, 370- const hsize_t *point, void *operator_data) nogil except -1: 371+ const hsize_t *point, void *operator_data) except -1 nogil: 372 cdef h5py_scatter_t* info = <h5py_scatter_t*>operator_data 373 374 memcpy(elem, (<char*>info[0].buf)+((info[0].i)*(info[0].elsize)), 375@@ -252,7 +252,7 @@ cdef herr_t h5py_scatter_cb(void* elem, hid_t type_id, unsigned ndim, 376 return 0 377 378 cdef herr_t h5py_gather_cb(void* elem, hid_t type_id, unsigned ndim, 379- const hsize_t *point, void *operator_data) nogil except -1: 380+ const hsize_t *point, void *operator_data) except -1 nogil: 381 cdef h5py_scatter_t* info = <h5py_scatter_t*>operator_data 382 383 memcpy((<char*>info[0].buf)+((info[0].i)*(info[0].elsize)), elem, 384diff --git a/h5py/_selector.pyx b/h5py/_selector.pyx 385index 8b858c82..69970176 100644 386--- a/h5py/_selector.pyx 387+++ b/h5py/_selector.pyx 388@@ -341,7 +341,7 @@ cdef class Reader: 389 390 arr = PyArray_ZEROS(arr_rank, arr_shape, self.np_typenum, 0) 391 if not self.native_byteorder: 392- arr = arr.newbyteorder() 393+ arr = arr.view(arr.dtype.newbyteorder()) 394 finally: 395 efree(arr_shape) 396 397diff --git a/h5py/api_compat.h b/h5py/api_compat.h 398index 52917f4d..a359e827 100644 399--- a/h5py/api_compat.h 400+++ b/h5py/api_compat.h 401@@ -24,7 +24,6 @@ typedef void *PyMPI_MPI_Message; 402 #include <stddef.h> 403 #include "Python.h" 404 #include "numpy/arrayobject.h" 405-#include "hdf5.h" 406 407 /* The HOFFSET macro can't be used from Cython. */ 408 409@@ -35,14 +34,14 @@ typedef void *PyMPI_MPI_Message; 410 #define h5py_size_n256 (sizeof(npy_complex256)) 411 #endif 412 413-#define h5py_offset_n64_real (HOFFSET(npy_complex64, real)) 414-#define h5py_offset_n64_imag (HOFFSET(npy_complex64, imag)) 415-#define h5py_offset_n128_real (HOFFSET(npy_complex128, real)) 416-#define h5py_offset_n128_imag (HOFFSET(npy_complex128, imag)) 417+#define h5py_offset_n64_real (0) 418+#define h5py_offset_n64_imag (sizeof(float)) 419+#define h5py_offset_n128_real (0) 420+#define h5py_offset_n128_imag (sizeof(double)) 421 422 #ifdef NPY_COMPLEX256 423-#define h5py_offset_n256_real (HOFFSET(npy_complex256, real)) 424-#define h5py_offset_n256_imag (HOFFSET(npy_complex256, imag)) 425+#define h5py_offset_n256_real (0) 426+#define h5py_offset_n256_imag (sizeof(long double)) 427 #endif 428 429 #endif 430diff --git a/h5py/api_types_hdf5.pxd b/h5py/api_types_hdf5.pxd 431index a198f105..099e0f58 100644 432--- a/h5py/api_types_hdf5.pxd 433+++ b/h5py/api_types_hdf5.pxd 434@@ -257,27 +257,27 @@ cdef extern from "hdf5.h": 435 herr_t (*sb_encode)(H5FD_t *file, char *name, unsigned char *p) 436 herr_t (*sb_decode)(H5FD_t *f, const char *name, const unsigned char *p) 437 size_t fapl_size 438- void * (*fapl_get)(H5FD_t *file) 439- void * (*fapl_copy)(const void *fapl) 440- herr_t (*fapl_free)(void *fapl) 441+ void * (*fapl_get)(H5FD_t *file) except * 442+ void * (*fapl_copy)(const void *fapl) except * 443+ herr_t (*fapl_free)(void *fapl) except -1 444 size_t dxpl_size 445 void * (*dxpl_copy)(const void *dxpl) 446 herr_t (*dxpl_free)(void *dxpl) 447- H5FD_t *(*open)(const char *name, unsigned flags, hid_t fapl, haddr_t maxaddr) 448- herr_t (*close)(H5FD_t *file) 449+ H5FD_t *(*open)(const char *name, unsigned flags, hid_t fapl, haddr_t maxaddr) except * 450+ herr_t (*close)(H5FD_t *file) except -1 451 int (*cmp)(const H5FD_t *f1, const H5FD_t *f2) 452 herr_t (*query)(const H5FD_t *f1, unsigned long *flags) 453 herr_t (*get_type_map)(const H5FD_t *file, H5FD_mem_t *type_map) 454 haddr_t (*alloc)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) 455 herr_t (*free)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size) 456- haddr_t (*get_eoa)(const H5FD_t *file, H5FD_mem_t type) 457- herr_t (*set_eoa)(H5FD_t *file, H5FD_mem_t type, haddr_t addr) 458- haddr_t (*get_eof)(const H5FD_t *file, H5FD_mem_t type) 459+ haddr_t (*get_eoa)(const H5FD_t *file, H5FD_mem_t type) noexcept 460+ herr_t (*set_eoa)(H5FD_t *file, H5FD_mem_t type, haddr_t addr) noexcept 461+ haddr_t (*get_eof)(const H5FD_t *file, H5FD_mem_t type) except -1 462 herr_t (*get_handle)(H5FD_t *file, hid_t fapl, void**file_handle) 463- herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer) 464- herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer) 465- herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) 466- herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) 467+ herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer) except * 468+ herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer) except * 469+ herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) except -1 470+ herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) except -1 471 herr_t (*lock)(H5FD_t *file, hbool_t rw) 472 herr_t (*unlock)(H5FD_t *file) 473 H5FD_mem_t fl_map[<int>H5FD_MEM_NTYPES] 474@@ -295,27 +295,27 @@ cdef extern from "hdf5.h": 475 herr_t (*sb_encode)(H5FD_t *file, char *name, unsigned char *p) 476 herr_t (*sb_decode)(H5FD_t *f, const char *name, const unsigned char *p) 477 size_t fapl_size 478- void * (*fapl_get)(H5FD_t *file) 479- void * (*fapl_copy)(const void *fapl) 480- herr_t (*fapl_free)(void *fapl) 481+ void * (*fapl_get)(H5FD_t *file) except * 482+ void * (*fapl_copy)(const void *fapl) except * 483+ herr_t (*fapl_free)(void *fapl) except -1 484 size_t dxpl_size 485 void * (*dxpl_copy)(const void *dxpl) 486 herr_t (*dxpl_free)(void *dxpl) 487- H5FD_t *(*open)(const char *name, unsigned flags, hid_t fapl, haddr_t maxaddr) 488- herr_t (*close)(H5FD_t *file) 489+ H5FD_t *(*open)(const char *name, unsigned flags, hid_t fapl, haddr_t maxaddr) except * 490+ herr_t (*close)(H5FD_t *file) except -1 491 int (*cmp)(const H5FD_t *f1, const H5FD_t *f2) 492 herr_t (*query)(const H5FD_t *f1, unsigned long *flags) 493 herr_t (*get_type_map)(const H5FD_t *file, H5FD_mem_t *type_map) 494 haddr_t (*alloc)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) 495 herr_t (*free)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size) 496- haddr_t (*get_eoa)(const H5FD_t *file, H5FD_mem_t type) 497- herr_t (*set_eoa)(H5FD_t *file, H5FD_mem_t type, haddr_t addr) 498- haddr_t (*get_eof)(const H5FD_t *file, H5FD_mem_t type) 499+ haddr_t (*get_eoa)(const H5FD_t *file, H5FD_mem_t type) noexcept 500+ herr_t (*set_eoa)(H5FD_t *file, H5FD_mem_t type, haddr_t addr) noexcept 501+ haddr_t (*get_eof)(const H5FD_t *file, H5FD_mem_t type) except -1 502 herr_t (*get_handle)(H5FD_t *file, hid_t fapl, void**file_handle) 503- herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer) 504- herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer) 505- herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) 506- herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) 507+ herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer) except * 508+ herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer) except * 509+ herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) except -1 510+ herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing) except -1 511 herr_t (*lock)(H5FD_t *file, hbool_t rw) 512 herr_t (*unlock)(H5FD_t *file) 513 H5FD_mem_t fl_map[<int>H5FD_MEM_NTYPES] 514diff --git a/h5py/h5fd.pyx b/h5py/h5fd.pyx 515index e9746057..d39cf68f 100644 516--- a/h5py/h5fd.pyx 517+++ b/h5py/h5fd.pyx 518@@ -144,10 +144,10 @@ cdef herr_t H5FD_fileobj_close(H5FD_fileobj_t *f) except -1 with gil: 519 stdlib_free(f) 520 return 0 521 522-cdef haddr_t H5FD_fileobj_get_eoa(const H5FD_fileobj_t *f, H5FD_mem_t type): 523+cdef haddr_t H5FD_fileobj_get_eoa(const H5FD_fileobj_t *f, H5FD_mem_t type) noexcept nogil: 524 return f.eoa 525 526-cdef herr_t H5FD_fileobj_set_eoa(H5FD_fileobj_t *f, H5FD_mem_t type, haddr_t addr): 527+cdef herr_t H5FD_fileobj_set_eoa(H5FD_fileobj_t *f, H5FD_mem_t type, haddr_t addr) noexcept nogil: 528 f.eoa = addr 529 return 0 530 531@@ -191,22 +191,38 @@ cdef herr_t H5FD_fileobj_flush(H5FD_fileobj_t *f, hid_t dxpl, hbool_t closing) e 532 cdef H5FD_class_t info 533 memset(&info, 0, sizeof(info)) 534 535+# Cython doesn't support "except X" in casting definition currently 536+ctypedef herr_t (*file_free_func_ptr)(void *) except -1 537+ 538+ctypedef herr_t (*file_close_func_ptr)(H5FD_t *) except -1 539+ctypedef haddr_t (*file_get_eoa_func_ptr)(const H5FD_t *, H5FD_mem_t) noexcept 540+ctypedef herr_t (*file_set_eof_func_ptr)(H5FD_t *, H5FD_mem_t, haddr_t) noexcept 541+ctypedef haddr_t (*file_get_eof_func_ptr)(const H5FD_t *, H5FD_mem_t) except -1 542+ctypedef herr_t (*file_read_func_ptr)(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, void*) except -1 543+ctypedef herr_t (*file_write_func_ptr)(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, const void*) except -1 544+ctypedef herr_t (*file_truncate_func_ptr)(H5FD_t *, hid_t, hbool_t) except -1 545+ctypedef herr_t (*file_flush_func_ptr)(H5FD_t *, hid_t, hbool_t) except -1 546+ 547+ 548 info.name = 'fileobj' 549 info.maxaddr = libc.stdint.SIZE_MAX - 1 550 info.fc_degree = H5F_CLOSE_WEAK 551 info.fapl_size = sizeof(PyObject *) 552 info.fapl_get = <void *(*)(H5FD_t *)>H5FD_fileobj_fapl_get 553 info.fapl_copy = <void *(*)(const void *)>H5FD_fileobj_fapl_copy 554-info.fapl_free = <herr_t (*)(void *)>H5FD_fileobj_fapl_free 555+ 556+info.fapl_free = <file_free_func_ptr>H5FD_fileobj_fapl_free 557+ 558 info.open = <H5FD_t *(*)(const char *name, unsigned flags, hid_t fapl, haddr_t maxaddr)>H5FD_fileobj_open 559-info.close = <herr_t (*)(H5FD_t *)>H5FD_fileobj_close 560-info.get_eoa = <haddr_t (*)(const H5FD_t *, H5FD_mem_t)>H5FD_fileobj_get_eoa 561-info.set_eoa = <herr_t (*)(H5FD_t *, H5FD_mem_t, haddr_t)>H5FD_fileobj_set_eoa 562-info.get_eof = <haddr_t (*)(const H5FD_t *, H5FD_mem_t)>H5FD_fileobj_get_eof 563-info.read = <herr_t (*)(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, void *)>H5FD_fileobj_read 564-info.write = <herr_t (*)(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, const void *)>H5FD_fileobj_write 565-info.truncate = <herr_t (*)(H5FD_t *, hid_t, hbool_t)>H5FD_fileobj_truncate 566-info.flush = <herr_t (*)(H5FD_t *, hid_t, hbool_t)>H5FD_fileobj_flush 567+ 568+info.close = <file_close_func_ptr>H5FD_fileobj_close 569+info.get_eoa = <file_get_eoa_func_ptr>H5FD_fileobj_get_eoa 570+info.set_eoa = <file_set_eof_func_ptr>H5FD_fileobj_set_eoa 571+info.get_eof = <file_get_eof_func_ptr>H5FD_fileobj_get_eof 572+info.read = <file_read_func_ptr>H5FD_fileobj_read 573+info.write = <file_write_func_ptr>H5FD_fileobj_write 574+info.truncate = <file_truncate_func_ptr>H5FD_fileobj_truncate 575+info.flush = <file_flush_func_ptr>H5FD_fileobj_flush 576 # H5FD_FLMAP_DICHOTOMY 577 info.fl_map = [H5FD_MEM_SUPER, # default 578 H5FD_MEM_SUPER, # super 579diff --git a/h5py/h5p.pyx b/h5py/h5p.pyx 580index 779ea1b5..dc8bf65a 100644 581--- a/h5py/h5p.pyx 582+++ b/h5py/h5p.pyx 583@@ -1177,7 +1177,7 @@ cdef class PropFAID(PropInstanceID): 584 size_t block_size IN: File system block size 585 size_t cbuf_size IN: Copy buffer size 586 587- Properites with value of 0 indicate that the HDF5 library should 588+ Properties with value of 0 indicate that the HDF5 library should 589 choose the value. 590 """ 591 H5Pset_fapl_direct(self.id, alignment, block_size, cbuf_size) 592@@ -1761,7 +1761,7 @@ cdef class PropOCID(PropCreateID): 593 594 max_compact -- maximum number of attributes to be stored in compact storage(default:8) 595 must be greater than or equal to min_dense 596- min_dense -- minmum number of attributes to be stored in dense storage(default:6) 597+ min_dense -- minimum number of attributes to be stored in dense storage(default:6) 598 599 """ 600 H5Pset_attr_phase_change(self.id, max_compact, min_dense) 601diff --git a/h5py/h5t.pyx b/h5py/h5t.pyx 602index e7aae14f..b9d7e74d 100644 603--- a/h5py/h5t.pyx 604+++ b/h5py/h5t.pyx 605@@ -1938,7 +1938,7 @@ def check_dtype(**kwds): 606 607 vlen = dtype 608 If the dtype represents an HDF5 vlen, returns the Python base class. 609- Currently only builting string vlens (str) are supported. Returns 610+ Currently only built-in string vlens (str) are supported. Returns 611 None if the dtype does not represent an HDF5 vlen. 612 613 enum = dtype 614diff --git a/h5py/tests/test_attrs_data.py b/h5py/tests/test_attrs_data.py 615index 56481ca0..5083a1aa 100644 616--- a/h5py/tests/test_attrs_data.py 617+++ b/h5py/tests/test_attrs_data.py 618@@ -262,7 +262,7 @@ class TestEmpty(BaseAttrs): 619 self.assertTrue(is_empty_dataspace(h5a.open(self.f.id, b'y'))) 620 621 def test_modify(self): 622- with self.assertRaises(IOError): 623+ with self.assertRaises(OSError): 624 self.f.attrs.modify('x', 1) 625 626 def test_values(self): 627diff --git a/h5py/tests/test_big_endian_file.py b/h5py/tests/test_big_endian_file.py 628index 4d81de01..170b5bcc 100644 629--- a/h5py/tests/test_big_endian_file.py 630+++ b/h5py/tests/test_big_endian_file.py 631@@ -24,14 +24,14 @@ def test_vlen_big_endian(): 632 assert dset[4] == 1.2 633 assert dset.dtype == "<f8" 634 635- # Same float values with big endianess 636+ # Same float values with big endianness 637 assert f["DSBEfloat"][0] == 3.14 638 assert f["DSBEfloat"].dtype == ">f8" 639 640 assert f["DSLEint"][0] == 1 641 assert f["DSLEint"].dtype == "<u8" 642 643- # Same int values with big endianess 644+ # Same int values with big endianness 645 assert f["DSBEint"][0] == 1 646 assert f["DSBEint"].dtype == ">i8" 647 648diff --git a/h5py/tests/test_dataset.py b/h5py/tests/test_dataset.py 649index e104dd53..0ffa5c80 100644 650--- a/h5py/tests/test_dataset.py 651+++ b/h5py/tests/test_dataset.py 652@@ -1939,9 +1939,9 @@ class TestCommutative(BaseDataset): 653 dset = self.f.create_dataset("test", shape, dtype=float, 654 data=np.random.rand(*shape)) 655 656- # grab a value from the elements, ie dset[0] 657+ # grab a value from the elements, ie dset[0, 0] 658 # check that mask arrays are commutative wrt ==, != 659- val = np.float64(dset[0]) 660+ val = np.float64(dset[0, 0]) 661 662 assert np.all((val == dset) == (dset == val)) 663 assert np.all((val != dset) == (dset != val)) 664diff --git a/h5py/tests/test_file.py b/h5py/tests/test_file.py 665index b47d408e..1aa38731 100644 666--- a/h5py/tests/test_file.py 667+++ b/h5py/tests/test_file.py 668@@ -326,7 +326,7 @@ class TestDrivers(TestCase): 669 # could be an integer multiple of 512 670 # 671 # To allow HDF5 to do the heavy lifting for different platform, 672- # We didn't provide any argumnets to the first call 673+ # We didn't provide any arguments to the first call 674 # and obtained HDF5's default values there. 675 676 # Testing creation with a few different property lists 677@@ -639,9 +639,9 @@ class TestUnicode(TestCase): 678 Modes 'r' and 'r+' do not create files even when given unicode names 679 """ 680 fname = self.mktemp(prefix=chr(0x201a)) 681- with self.assertRaises(IOError): 682+ with self.assertRaises(OSError): 683 File(fname, 'r') 684- with self.assertRaises(IOError): 685+ with self.assertRaises(OSError): 686 File(fname, 'r+') 687 688 689diff --git a/h5py/tests/test_file_alignment.py b/h5py/tests/test_file_alignment.py 690index c280bb76..da13ee04 100644 691--- a/h5py/tests/test_file_alignment.py 692+++ b/h5py/tests/test_file_alignment.py 693@@ -50,7 +50,7 @@ class TestFileAlignment(TestCase): 694 alignment_interval = 4096 695 696 for shape in [ 697- (1033,), # A prime number above the thresold 698+ (1033,), # A prime number above the threshold 699 (1000,), # Exactly equal to the threshold 700 (1001,), # one above the threshold 701 ]: 702@@ -75,7 +75,7 @@ class TestFileAlignment(TestCase): 703 alignment_interval = 1024 704 705 for shape in [ 706- (881,), # A prime number below the thresold 707+ (881,), # A prime number below the threshold 708 (999,), # Exactly one below the threshold 709 ]: 710 fname = self.mktemp() 711diff --git a/h5py/tests/test_group.py b/h5py/tests/test_group.py 712index 328c352a..4af1fb1f 100644 713--- a/h5py/tests/test_group.py 714+++ b/h5py/tests/test_group.py 715@@ -771,7 +771,7 @@ class TestExternalLinks(TestCase): 716 with self.assertRaises(KeyError): 717 self.f['ext'] 718 719- # I would prefer IOError but there's no way to fix this as the exception 720+ # I would prefer OSError but there's no way to fix this as the exception 721 # class is determined by HDF5. 722 def test_exc_missingfile(self): 723 """ KeyError raised when attempting to open missing file """ 724@@ -844,7 +844,7 @@ class TestExtLinkBugs(TestCase): 725 try: 726 if x: 727 x.close() 728- except IOError: 729+ except OSError: 730 pass 731 return w 732 orig_name = self.mktemp() 733diff --git a/h5py/tests/test_selections.py b/h5py/tests/test_selections.py 734index 0b1722d7..01f6dcb7 100644 735--- a/h5py/tests/test_selections.py 736+++ b/h5py/tests/test_selections.py 737@@ -65,7 +65,7 @@ class TestTypeGeneration(BaseSelection): 738 self.assertEqual(out, np.dtype('i')) 739 self.assertEqual(format, np.dtype( [('a','i')] )) 740 741- # Field does not apear in named typed 742+ # Field does not appear in named typed 743 with self.assertRaises(ValueError): 744 out, format = sel2.read_dtypes(dt, ('j', 'k')) 745 746diff --git a/pylintrc b/pylintrc 747index 045df2f7..2401d3b0 100644 748--- a/pylintrc 749+++ b/pylintrc 750@@ -44,7 +44,7 @@ confidence= 751 # can either give multiple identifiers separated by comma (,) or put this 752 # option multiple times (only on the command line, not in the configuration 753 # file where it should appear only once).You can also use "--disable=all" to 754-# disable everything first and then reenable specific checks. For example, if 755+# disable everything first and then re-enable specific checks. For example, if 756 # you want to run only the similarities checker, you can use "--disable=all 757 # --enable=similarities". If you want to run only the classes checker, but have 758 # no Warning level messages displayed, use"--disable=all --enable=classes 759diff --git a/pyproject.toml b/pyproject.toml 760index ee573d2f..717200ef 100644 761--- a/pyproject.toml 762+++ b/pyproject.toml 763@@ -1,6 +1,6 @@ 764 [build-system] 765 requires = [ 766- "Cython >=0.29.31,<1", 767+ "Cython >=0.29.31,<4", 768 "oldest-supported-numpy", 769 "pkgconfig", 770 "setuptools >=61", 771diff --git a/setup_configure.py b/setup_configure.py 772index 0fba53ba..c3b86a64 100644 773--- a/setup_configure.py 774+++ b/setup_configure.py 775@@ -165,7 +165,7 @@ class BuildConfig: 776 try: 777 if pkgconfig.exists(pc_name): 778 pc = pkgconfig.parse(pc_name) 779- except EnvironmentError: 780+ except OSError: 781 if os.name != 'nt': 782 print( 783 "Building h5py requires pkg-config unless the HDF5 path " 784diff --git a/tox.ini b/tox.ini 785index 0efb88a6..86a176dd 100644 786--- a/tox.ini 787+++ b/tox.ini 788@@ -65,7 +65,7 @@ skip_install=True 789 package_env = DUMMY NON-EXISTENT ENV NAME 790 changedir=docs 791 deps= 792- sphinx 793+ -r docs/requirements-rtd.txt 794 commands= 795 sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html 796 797