On Sun, Mar 10, 2013 at 12:13 PM, Tres Seaver <tsea...@palladion.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 03/10/2013 11:55 AM, Jim Fulton wrote:
>> On Sun, Mar 10, 2013 at 11:25 AM, Tres Seaver <tsea...@palladion.com>
>> wrote:
>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
>>>
>>> On 03/10/2013 09:19 AM, Jim Fulton wrote:
>> ...
>>>> I think the fix is pretty straightforward.
>>>>
>>>> In the default __setstate__ provided by Persistent, and when
>>>> loading non-persistent instances:
>>>>
>>>> - On Python 2, ASCII encode unicode attribute names.
>>>>
>>>> - On Python 3, ASCII decode byte attribute names.
>>>>
>>>> The same transformation is necessary when looking up global
>>>> names.
>>>
>>> Hmm, if zodbpickle has to handle the issue for non-persistent
>>> instances and global names, wouldn't it be simpler to make it handle
>>> persistent instances too?
>>
>> No.  It can't know when a key is going to be used for a persistent
>> attribute name.
>>
>>> It can examine the stack inside 'load_dict' to figure out that the
>>> context is an instance, right?
>>
>> Ugh.  What stack?
>
> The one where the unpickler keeps its work-in-progress?
>
>  static int
>  load_none(UnpicklerObject *self)
>  {
>      PDATA_APPEND(self->stack, Py_None, -1);
>      return 0;
>  }
>
>  static int
>  load_dict(UnpicklerObject *self)
>  {
>      PyObject *dict, *key, *value;
>      Py_ssize_t i, j, k;
>
>      if ((i = marker(self)) < 0)
>          return -1;
>      j = Py_SIZE(self->stack);
>
>      if ((dict = PyDict_New()) == NULL)
>          return -1;
>
>      for (k = i + 1; k < j; k += 2) {
>          key = self->stack->data[k - 1];
>          value = self->stack->data[k];
>          if (PyDict_SetItem(dict, key, value) < 0) {
>              Py_DECREF(dict);
>              return -1;
>          }
>      }
>      Pdata_clear(self->stack, i);
>      PDATA_PUSH(self->stack, dict, -1);
>      return 0;
>  }

That won't work for persistent objects.

Persistent state is set by the deserializer, not by the unpickler.

The deserializer calls the unpickler to load the state.  It then calls
__setstate__ on the persistent object to set the state.  The
serializer doesn't know how to interpret the state, only __setstate__
does.

Jim

--
Jim Fulton
http://www.linkedin.com/in/jimfulton
Jerky is better than bacon! http://zo.pe/Kqm
_______________________________________________
For more information about ZODB, see http://zodb.org/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zodb-dev

Reply via email to