This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author andymaier
Recipients andymaier
Date 2020-08-26.06:50:59
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1598424659.93.0.553984904692.issue41639@roundup.psfhosted.org>
In-reply-to
Content
Unpickling an object of a user class that derives from list seems to miss calling the user class's __init__() method:

Consider this script, which defines a derived class of the built-in list for the purpose of creating a case insensitive list. The real example has all methods of list implemented, but this subset example also shows the issue:

-----------------
import pickle

def _lc_list(lst):
    result = list()
    for value in lst:
        result.append(value.lower())
    return result

class NocaseList(list):

    #def __new__(cls, iterable=()):
    #    self = super(NocaseList, cls).__new__(cls, iterable)
    #    print("Debug: __new__()  for self={}".format(id(self)))
    #    return self

    def __init__(self, iterable=()):
        print("Debug: __init__() for self={}".format(id(self)))
        super(NocaseList, self).__init__(iterable)
        self.lc_list = _lc_list(self)

    def append(self, value):
        super(NocaseList, self).append(value)
        self.lc_list.append(value.lower())

    def extend(self, iterable):
        super(NocaseList, self).extend(iterable)
        for value in iterable:
            self.lc_list.append(value.lower())

ncl = NocaseList(['A', 'b'])
pkl = pickle.dumps(ncl)
nclx = pickle.loads(pkl)
-----------------

$ python ./pickle_extend.py 
Debug: __init__() for self=4498704880
Traceback (most recent call last):
  File "./pickle_extend.py", line 32, in <module>
    nclx = pickle.loads(pkl)
  File "./pickle_extend.py", line 28, in extend
    self.lc_list.append(value.lower())
AttributeError: 'NocaseList' object has no attribute 'lc_list'

Uncommenting the __new__() method in the script shows that __new__() is called but not __init__():

$ python ./pickle_extend.py 
Debug: __new__()  for self=4359683024
Debug: __init__() for self=4359683024
Debug: __new__()  for self=4360134304
Traceback (most recent call last):
  File "./pickle_extend.py", line 32, in <module>
    nclx = pickle.loads(pkl)
  File "./pickle_extend.py", line 28, in extend
    self.lc_list.append(value.lower())
AttributeError: 'NocaseList' object has no attribute 'lc_list'
History
Date User Action Args
2020-08-26 06:51:00andymaiersetrecipients: + andymaier
2020-08-26 06:50:59andymaiersetmessageid: <1598424659.93.0.553984904692.issue41639@roundup.psfhosted.org>
2020-08-26 06:50:59andymaierlinkissue41639 messages
2020-08-26 06:50:59andymaiercreate