New submission from Andy Maier <andreas.r.ma...@gmx.de>:

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'

----------
messages: 375909
nosy: andymaier
priority: normal
severity: normal
status: open
title: Unpickling derived class of list does not call __init__()
versions: Python 3.8

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41639>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to