uchicago-cs / deepdish

Flexible HDF5 saving/loading and other data science tools from the University of Chicago
http://deepdish.io
BSD 3-Clause "New" or "Revised" License
270 stars 59 forks source link

Saving Class instances not working when registry is not called #43

Open jorenretel opened 4 years ago

jorenretel commented 4 years ago

Hi, thanks for this cool library. The following example I took from your readthedocs (https://deepdish.readthedocs.io/en/latest/io.html#class-instances):

import deepdish as dd

class Foo(dd.util.SaveableRegistry):
    def __init__(self, x):
        self.x = x

    @classmethod
    def load_from_dict(self, d):
        obj = Foo(d['x'])
        return obj

    def save_to_dict(self):
        return {'x': self.x}

if __name__ == '__main__':
    f = Foo(10)
    f.save('foo.h5')
    f = Foo.load('foo.h5')

This is a more minimal example because there is no class 'Bar' that inherits from Foo and therefore the @Foo.register('bar') decorator) is never called. When doing this. This leads to the following traceback:

/Users/jorenretel/bin/miniconda3/envs/abstract_classifier/bin/python /Users/jorenretel/Library/Preferences/PyCharm2019.3/scratches/scratch_3.py
/Users/jorenretel/bin/miniconda3/envs/abstract_classifier/lib/python3.8/site-packages/deepdish/io/hdf5io.py:246: FutureWarning: The Panel class is removed from pandas. Accessing it from the top-level namespace will also be removed in the next version
  elif _pandas and isinstance(level, (pd.DataFrame, pd.Series, pd.Panel)):
Traceback (most recent call last):
  File "/Users/jorenretel/Library/Preferences/PyCharm2019.3/scratches/scratch_3.py", line 20, in <module>
    f = Foo.load('foo.h5')
  File "/Users/jorenretel/bin/miniconda3/envs/abstract_classifier/lib/python3.8/site-packages/deepdish/util/saveable.py", line 162, in load
    return cls.getclass(class_name).load_from_dict(d)
  File "/Users/jorenretel/bin/miniconda3/envs/abstract_classifier/lib/python3.8/site-packages/deepdish/util/saveable.py", line 121, in getclass
    return cls.REGISTRY[name]
KeyError: 'noname'

Process finished with exit code 1

The problem is that this function in deepdish/util/saveable.py never gets overloaded when registry is not called:

    @property
    def name(self):
        """Returns the name of the registry entry."""
        # Automatically overloaded by 'register'
        return "noname"

Possible solution: return None, instead of 'noname'? I am not sure whether this does not have some side effect that I am not aware of.