Unidata / MetPy

MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.
https://unidata.github.io/MetPy/
BSD 3-Clause "New" or "Revised" License
1.24k stars 413 forks source link

GINI Xarray backend failing with Python 3.12 #3317

Closed ktyle closed 9 months ago

ktyle commented 9 months ago

What went wrong?

In several miniconda environments that use Python 3.12, opening a GINI-formatted dataset using MetPy's GINI Xarray backend is failing. Additionally, opening non-GINI formatted datasets throw a warning message, also related to the same underlying issue.

My sense is that the underlying behavior of Python's struct library has changed in 3.12.

Operating System

Linux

Version

1.5.1

Python Version

3.12.0

Code to Reproduce

import xarray as xr
from metpy.cbook import get_test_data

ds = xr.open_dataset(get_test_data('WEST-CONUS_4km_WV_20151208_2200.gini', as_file_obj=False))

Errors, Traceback, and Logs

**(Note: I slightly modified gini.py to remove the try/except block in order to more clearly see what was casuing the error)**

File /nfs/knight/mamba_aug23/envs/dec23_12/lib/python3.12/site-packages/metpy/io/gini.py:113, in GiniFile()
     89 sectors = ['NH Composite', 'East CONUS', 'West CONUS', 'Alaska Regional',
     90            'Alaska National', 'Hawaii Regional', 'Hawaii National', 'Puerto Rico Regional',
     91            'Puerto Rico National', 'Supernational', 'NH Composite', 'Central CONUS',
     92            'East Floater', 'West Floater', 'Central Floater', 'Polar Floater']
     94 channels = ['Unknown', 'Visible', 'IR (3.9 micron)', 'WV (6.5/6.7 micron)',
     95             'IR (11 micron)', 'IR (12 micron)', 'IR (13 micron)', 'IR (1.3 micron)',
     96             'Reserved', 'Reserved', 'Reserved', 'Reserved', 'Reserved', 'LI (Imager)',
   (...)
    110             # Percent Normal TPW found empirically from Service Change Notice 20-03
    111             'Sounder (3.74 micron)', 'Sounder (Visible)', 'Percent Normal TPW']
--> 113 prod_desc_fmt = NamedStruct([('source', 'b'),
    114                              ('creating_entity', 'b', _name_lookup(crafts)),
    115                              ('sector_id', 'b', _name_lookup(sectors)),
    116                              ('channel', 'b', _name_lookup(channels)),
    117                              ('num_records', 'H'), ('record_len', 'H'),
    118                              ('datetime', '7s', _make_datetime),
    119                              ('projection', 'b', GiniProjection), ('nx', 'H'), ('ny', 'H'),
    120                              ('la1', '3s', _scaled_int), ('lo1', '3s', _scaled_int)
    121                              ], '>', 'ProdDescStart')
    123 lc_ps_fmt = NamedStruct([('reserved', 'b'), ('lov', '3s', _scaled_int),
    124                          ('dx', '3s', _scaled_int), ('dy', '3s', _scaled_int),
    125                          ('proj_center', 'b')], '>', 'LambertOrPolarProjection')
    127 mercator_fmt = NamedStruct([('resolution', 'b'), ('la2', '3s', _scaled_int),
    128                             ('lo2', '3s', _scaled_int), ('di', 'H'), ('dj', 'H')
    129                             ], '>', 'MercatorProjection')

TypeError: Struct() takes at most 1 argument (3 given)
dopplershift commented 9 months ago

Fixed by #3223 (see there for the gory details) which will be included in the "imminent" 1.6 release.