Skip to content

Commit 362f21e

Browse files
authored
Merge pull request #254 from jswhit/numpy2
numpy 2 support
2 parents 5b10ed1 + 3c8c7ff commit 362f21e

File tree

7 files changed

+40
-27
lines changed

7 files changed

+40
-27
lines changed

.github/workflows/build-conda.yml

+2-10
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,7 @@ jobs:
1111
strategy:
1212
matrix:
1313
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
14-
os: [ubuntu-latest, windows-latest, macos-latest]
15-
platform: [x64, x32]
16-
# debug on a single os/platform/python version
17-
# python-version: [ "3.9"]
18-
# os: [ubuntu-latest]
19-
# platform: [x64]
20-
exclude:
21-
- os: macos-latest
22-
platform: x32
14+
os: [ubuntu-latest, windows-latest, macos-12]
2315
steps:
2416
- uses: actions/checkout@v4
2517

@@ -47,4 +39,4 @@ jobs:
4739
#fi
4840
cd test
4941
python test.py
50-
pytest -vv test_latlons.py
42+
pytest -vv -s test_latlons.py

.github/workflows/build-windows.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ jobs:
1313
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
1414
os: [windows-latest, macos-latest]
1515
platform: [x64, x32]
16-
# debug on a single os/platform/python version
17-
# python-version: [ "3.9"]
18-
# os: [macosx-latest]
19-
# platform: [x64]
2016
exclude:
21-
- os: macos-latest
17+
- os: macos-latest
2218
platform: x32
2319
steps:
2420
- uses: actions/checkout@v4
21+
steps:
22+
- uses: actions/checkout@v4
2523

2624
- name: Setup Conda
2725
uses: s-weigand/setup-conda@v1

.github/workflows/build.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ jobs:
99
PROJ_LIB: /usr/share/proj
1010
strategy:
1111
matrix:
12-
#python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
1312
python-version: ["3.11"]
1413
steps:
1514

Changelog

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ version 2.1.6 (not yet released)
55
gridded fields, optimize function for 50x speedup.
66
* Fix for issue #235 (`latlons` doesn't work when only a single latitude in grid).
77
* Fix for issue #241 (forecast time units in inventory wrong for 15 minute HRRR data).
8+
* Add `len` method to open instance (issue #239).
9+
* Numpy 2 compatibility (issue #251).
10+
* Fix failing doctest for eccodes >= 2.34.1 (issue #245).
11+
* use eccodes.h instead of grib_api.h, add `eccodes_version` module variable.
812

913
version 2.1.5 release
1014
=====================

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
[build-system]
22
requires = [
33
"Cython>=0.29",
4-
"oldest-supported-numpy",
54
"setuptools>=61",
5+
"oldest-supported-numpy ; python_version < '3.9'",
6+
"numpy>=2.0.0rc1,<3 ; python_version >= '3.9'",
67
]
78
build-backend = "setuptools.build_meta"
89

src/pygrib/_pygrib.pyx

+23-8
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ npc.import_array()
1818
ctypedef fused float_type:
1919
float
2020
double
21+
ctypedef fused int_type:
22+
int
23+
long
24+
long long
2125

22-
def redtoreg(float_type[:] redgrid_data, long[:] lonsperlat, missval=None):
26+
def redtoreg(float_type[:] redgrid_data, int_type[:] lonsperlat, missval=None):
2327
"""
2428
redtoreg(redgrid_data, lonsperlat, missval=None)
2529
@@ -104,7 +108,7 @@ cdef extern from "numpy/arrayobject.h":
104108
npy_intp PyArray_ISCONTIGUOUS(ndarray arr)
105109
npy_intp PyArray_ISALIGNED(ndarray arr)
106110

107-
cdef extern from "grib_api.h":
111+
cdef extern from "eccodes.h":
108112
ctypedef struct grib_handle
109113
ctypedef struct grib_index
110114
ctypedef struct grib_keys_iterator
@@ -193,6 +197,7 @@ def _get_grib_api_version():
193197
major = v
194198
return "%d.%d.%d" % (major,minor,revision)
195199
grib_api_version = _get_grib_api_version()
200+
eccodes_version = grib_api_version
196201
if grib_api_version < "2.19.1":
197202
msg="Warning: ecCodes 2.19.1 or higher is recommended. You are running"
198203
warnings.warn('%s %s.' % (msg,grib_api_version))
@@ -382,6 +387,8 @@ cdef class open(object):
382387
else:
383388
self.has_multi_field_msgs=False
384389
fseek(self._fd, self._offset, SEEK_SET)
390+
def __len__(self):
391+
return self.messages
385392
def __iter__(self):
386393
return self
387394
def __next__(self):
@@ -1103,7 +1110,7 @@ cdef class gribmessage(object):
11031110
raise RuntimeError(_get_error_message(err))
11041111
elif typ == GRIB_TYPE_LONG:
11051112
# is value an array or a scalar?
1106-
datarr = np.asarray(value, int)
1113+
datarr = np.asarray(value, np.int_)
11071114
is_array = False
11081115
if datarr.shape:
11091116
is_array = True
@@ -1189,7 +1196,12 @@ cdef class gribmessage(object):
11891196
raise RuntimeError(_get_error_message(err))
11901197
return longval
11911198
else: # array
1192-
datarr = np.zeros(size, int)
1199+
if os.name == 'nt':
1200+
# this should not be necessary since np.int_ should
1201+
# be platform-dependent long, which should map to 32-bits on windows?
1202+
datarr = np.zeros(size, np.int32)
1203+
else:
1204+
datarr = np.zeros(size, np.int_)
11931205
err = grib_get_long_array(self._gh, name, <long *>datarr.data, &size)
11941206
if err:
11951207
raise RuntimeError(_get_error_message(err))
@@ -1315,8 +1327,9 @@ cdef class gribmessage(object):
13151327
else:
13161328
missval = 1.e30
13171329
if self.expand_reduced:
1318-
nx = self['pl'].max()
1319-
datarr = redtoreg(datarr, self['pl'], missval=missval)
1330+
lonsperlat = self['pl']
1331+
nx = lonsperlat.max()
1332+
datarr = redtoreg(datarr, lonsperlat, missval=missval)
13201333
else:
13211334
nx = None
13221335
elif self.has_key('Nx') and self.has_key('Ny'):
@@ -1552,7 +1565,8 @@ cdef class gribmessage(object):
15521565
lats = self['distinctLatitudes']
15531566
if lat2 < lat1 and lats[-1] > lats[0]: lats = lats[::-1]
15541567
ny = self['Nj']
1555-
nx = self['pl'].max()
1568+
lonsperlat = self['pl']
1569+
nx = lonsperlat.max()
15561570
lon1 = self['longitudeOfFirstGridPointInDegrees']
15571571
lon2 = self['longitudeOfLastGridPointInDegrees']
15581572
lons = np.linspace(lon1,lon2,nx)
@@ -1563,7 +1577,8 @@ cdef class gribmessage(object):
15631577
elif self['gridType'] == 'reduced_ll': # reduced lat/lon grid
15641578
if self.expand_reduced:
15651579
ny = self['Nj']
1566-
nx = self['pl'].max()
1580+
lonsperlat = self['pl']
1581+
nx = lonsperlat.max()
15671582
lat1 = self['latitudeOfFirstGridPointInDegrees']
15681583
lat2 = self['latitudeOfLastGridPointInDegrees']
15691584
lon1 = self['longitudeOfFirstGridPointInDegrees']

test/test.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ def test():
1010
[1:Precipitation rate:kg m**-2 s**-1 (avg):regular_gg:surface:level 0:fcst time 108-120 hrs (avg):from 200402291200, 2:Surface pressure:Pa (instant):regular_gg:surface:level 0:fcst time 120 hrs:from 200402291200, 3:Maximum temperature:K (instant):regular_gg:heightAboveGround:level 2 m:fcst time 108-120 hrs:from 200402291200, 4:Minimum temperature:K (instant):regular_gg:heightAboveGround:level 2 m:fcst time 108-120 hrs:from 200402291200]
1111
>>> grbs = pygrib.open('../sampledata/flux.grb')
1212
13+
number of messages in file
14+
>>> len(grbs)
15+
4
16+
1317
acts like a file object
1418
>>> grbs.tell()
1519
0
@@ -234,8 +238,8 @@ def test():
234238
>>> str('min/max %5.2f %5.2f' % (data.min(), data.max()))
235239
'min/max 295.40 308.10'
236240
>>> grbs = pygrib.open('../sampledata/no-radius-shapeOfEarth-7.grb2')
237-
>>> for grb in grbs: print(grb)
238-
1:Total precipitation:kg m-2 (accum):lambert:surface:level 0:fcst time 15-30 mins (accum):from 201804100000
241+
>>> for grb in grbs: print(grb) # doctest:+ELLIPSIS
242+
1:Total precipitation:kg m-2 (accum):lambert:surface:level 0:fcst time 15...-30... mins (accum):from 201804100000
239243
>>> str(grb.packingType)
240244
'grid_simple'
241245
>>> grbs.close()

0 commit comments

Comments
 (0)