jswhit / pygrib

Python interface for reading and writing GRIB data
https://jswhit.github.io/pygrib
MIT License
327 stars 97 forks source link

dir(grb) raises RunTimeError #197

Closed wgwz closed 2 years ago

wgwz commented 2 years ago

The python built-in dir returns a RunTimeError on a grb message. This is an essential function for understanding how to interact with an object. Can we make this work? I'm glad to submit a PR, with some guidance. It looks like this is the class that needs to be adjusted:

https://github.com/jswhit/pygrib/blob/master/src/pygrib/_pygrib.pyx#L721

Setup:

grbs = pygrib.open(...)
grb = next(grbs)

Example calls:

(Pdb) dir(grbs)
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '_advance', 'close', 'closed', 'has_multi_field_msgs', 'message', 'messagenumber', 'messages', 'name', 'read', 'readline', 'rewind', 'seek', 'select', 'tell']
(Pdb) dir(grb)
*** RuntimeError: b'Key/value not found'

Desired result:

(Pdb) dir(grb)
[.... list of all methods and properties for the class including but not limited to data, latlons, tostring, keys, etc, etc... ]

From the docs on dir (linked above):

If the object has a method named dir(), this method will be called and must return the list of attributes. This allows objects that implement a custom getattr() or getattribute() function to customize the way dir() reports their attributes.

If the object does not provide dir(), the function tries its best to gather information from the object’s dict attribute, if defined, and from its type object. The resulting list is not necessarily complete and may be inaccurate when the object has a custom getattr().

I believe this paragraph's may contain the solution and the problem. There is no __dir__() method on gribmessage class. So it is trying to gather the info from __dict__ and somehow I guess it is that, which raises the RunTimeError. But alas, I don't know cython well, and that could make it more complicated.

jswhit commented 2 years ago

use grb.keys() instead. I suppose I could add a dir() method that just forwards to keys().

jswhit commented 2 years ago

I just merged PR #198 which should fix this, and add all the eccodes keys to the output of dir(grb).

wgwz commented 2 years ago

Thank you @jswhit !