uqfoundation / dill

serialize all of Python

Home Page:http://dill.rtfd.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

dill.load - object has no attribute in custom class

phenolophthaleinum opened this issue · comments

I'm trying to load a supposedly correctly dumped object of the following custom class that stores alternative names of keys from main dict as a dict where keys are aliases and values are lists of corresponding keys from main dict:

utils.py:

class AliasedDict(dict):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.aliases = {}

    def add_alias(self, alias, key):
        if alias in self.aliases:
            self.aliases[alias].append(key)
        else:
            self.aliases[alias] = [key]
    
    def show_aliases(self, key):
        return [alias for alias, value_of_key in self.aliases.items() if value_of_key == key]

    def __getitem__(self, key):
        item = self.aliases.get(key, key)
        try:
            return super().__getitem__(item)
        except:
            return [super(AliasedDict, self).__getitem__(itemkey) for itemkey in item]

    def __setitem__(self, key, value):
        return super().__setitem__(self.aliases.get(key, key), value)

table_parser.py:

def read_db(filename: str):
    with open(filename, 'rb') as f:
        return dill.load(f)

This produces an error:

Traceback (most recent call last):
  File "C:\Users\Maciej\mirna-page\page.py", line 11, in <module>
    db = read_db("mirna_table.pkl")
  File "C:\Users\Maciej\mirna-page\table_parser.py", line 39, in read_db
    return dill.load(f)
  File "C:\Users\Maciej\AppData\Local\Programs\Python\Python310\lib\site-packages\dill\_dill.py", line 287, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File "C:\Users\Maciej\AppData\Local\Programs\Python\Python310\lib\site-packages\dill\_dill.py", line 442, in load
    obj = StockUnpickler.load(self)
  File "C:\Users\Maciej\mirna-page\utils.py", line 46, in __setitem__
    return super().__setitem__(self.aliases.get(key, key), value)
AttributeError: 'AliasedDict' object has no attribute 'aliases'

Seems like dill does not serialize aliases, which is true if I try to serialize object with json - only dict is serialized, no trace of aliases. Why is that a case?
If not serialized, everything works fine.

dill version 0.3.7
Python 3.10.6
Windows 10

I also get this error when trying to deserialize instances of classes which inherit from other classes. I'm wondering if it's an issue that specifically affects inherited classes.

from pandas import CategoricalDtype
import dill

class CatDtype(CategoricalDtype):
    def __init__(self, categories, ordered, other):
        super().__init__(categories=categories, ordered=ordered)
        self.other = other

cdt = CatDtype(categories=['A', 'B'], ordered=False, other='TEMP')

dill.dump(cdt, open('temp', 'wb'))
cdt2 = dill.load(open('temp', 'rb'))

cdt2.other

Results in:
AttributeError: 'CatDtype' object has no attribute 'other'

I actually figured out above ^ it is because the inherited class had custom __getstate__ and __setstate__