blob: aba62ddf1420c2c29930bc41e2b0cf7c10ac5e8a [file] [log] [blame]
Patrick Williams705982a2024-01-12 09:51:57 -06001From 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