Title: Pickling (protocol 2) doesn't use overriden itervalues() on dict-derived classes
Type: Severity: normal
Components: Core Versions:
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: leosoto
Priority: Keywords:

Created on 2009-02-02.02:39:57 by leosoto, last changed 2009-02-04.00:52:48 by leosoto.

msg4115 (view) Author: Leonardo Soto (leosoto) Date: 2009-02-02.02:39:56
There are problems pickling instances of Django's MultiValueDict, only
when using protocol 2:

>>> from django.utils.datastructures import MultiValueDict
>>> d['a'] = 'b'
>>> pickle.loads(pickle.dumps(d, 2)) == d
>>> d
<MultiValueDict: {'a': ['b']}>
>>> pickle.loads(pickle.dumps(d, 2))
<MultiValueDict: {'a': [['b']]>

A zoom to the root of the problem:

>>> list(d.__reduce_ex__(2)[-1])
[('a', ['b'])]

Which is wrong. On CPython, it gives [('a', 'b')].

This is caused by not calling the custom itervalues() method of the
custom python class. The call which should be routed to the python
implementation is on PyObject#reduce_2(). The "routing" doesn't happen,
because PyDictDerived doesn't override itervalues(). 

Now, if we take the strategy of "routing" calls, I'm not sure how much
of the dict interface should we override on PyDictDerived to allow
forwarding java calls to the right place. All of it?

Another option would be to override __reduce__ on PyDictionaryDerived.
msg4123 (view) Author: Leonardo Soto (leosoto) Date: 2009-02-04.00:52:47
Fixed on r6010, following pjenvey's suggestion (which was way cleaner
than my idea of override iteritems() on PyDictDerived).
Date User Action Args
2009-02-04 00:52:48leosotosetstatus: open -> closed
resolution: fixed
messages: + msg4123
2009-02-02 02:39:57leosotocreate