Ошибка Python jsonpickle: объект «OrderedDict» не имеет атрибута «_OrderedDict__root»

Я сталкиваюсь с этим исключением с помощью jsonpickle, когда пытаюсь замариновать довольно сложный объект, который, к сожалению, я не знаю, как здесь описать. Я знаю, что трудно говорить много, но это того стоит:

>>> frozen = jsonpickle.encode(my_complex_object_instance)
>>> thawed = jsonpickle.decode(frozen)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/jsonpickle/__init__.py",
  line 152, in decode
    return unpickler.decode(string, backend=backend, keys=keys)
      :
      :
  File "/Library/Python/2.7/site-packages/jsonpickle/unpickler.py",
  line 336, in _restore_from_dict
    instance[k] = value
  File "/Library/Python/2.7/site-packages/botocore/vendored/requests/packages/urllib3/packages/ordered_dict.py",
  line 49, in __setitem__
    root = self.__root
AttributeError: 'OrderedDict' object has no attribute '_OrderedDict__root'

Я не нахожу большой помощи при поиске ошибки в Google. Я вижу, что та же проблема была решена некоторое время назад для более простых объектов:

https://github.com/jsonpickle/jsonpickle/issues/33

Приведенный пример в этом отчете работает для меня:

>>> jsonpickle.decode(jsonpickle.encode(collections.OrderedDict()))
OrderedDict()
>>> jsonpickle.decode(jsonpickle.encode(collections.OrderedDict(a=1)))
OrderedDict([(u'a', 1)])

Кто-нибудь когда-нибудь сталкивался с этим и нашел решение? Я спрашиваю с пониманием того, что мой случай может быть «не так идиосинкразичен», как другой известный пример.


person Scott    schedule 07.02.2017    source источник


Ответы (1)


Модуль запросов для меня, кажется, сталкивается с проблемами, когда я .decode(). Немного посмотрев на код jsonpickle, я решил разветвить его и изменить следующие строки, чтобы увидеть, что происходит (и в итоге я сохранил приватную копию jsonpickle с изменениями, чтобы двигаться дальше).

В jsonpickle/unpickler.py (в моей версии это строка 368) найдите раздел оператора if в методе _restore_from_dict():

if (util.is_noncomplex(instance) or
    util.is_dictionary_subclass(instance)):
    instance[k] = value
else:
    setattr(instance, k, value)

и измените его на это (он будет регистрировать ошибки тех, которые терпят неудачу, а затем вы можете либо сохранить код на месте, либо изменить версию вашего OrderedDict с __root)

if (util.is_noncomplex(instance) or
    util.is_dictionary_subclass(instance)):
    # Currently requests.adapters.HTTPAdapter is using a non-standard
    # version of OrderedDict which doesn't have a _OrderedDict__root
    # attribute
    try:
        instance[k] = value
    except AttributeError as e:
        import logging
        import pprint
        warnmsg = 'Unable to unpickle {}[{}]={}'.format(pprint.pformat(instance), pprint.pformat(k), pprint.pformat(value))
        logging.error(warnmsg)
else:
    setattr(instance, k, value)
person davfive    schedule 16.11.2017