Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dill.load - object has no attribute in custom class #619

Open
phenolophthaleinum opened this issue Sep 11, 2023 · 2 comments
Open

dill.load - object has no attribute in custom class #619

phenolophthaleinum opened this issue Sep 11, 2023 · 2 comments

Comments

@phenolophthaleinum
Copy link

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

@AnotherSamWilson
Copy link

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'

@AnotherSamWilson
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants