2017-02-10 3 views
0

Я активно использую twisted.internet.defer в своем пакете, я столкнулся с проблемой, которую я не могу решить, потратив на это 2 дня. Ниже приведен мой проблемный сценарий.Python Twisted Defer returnValue несовместим с dict

# all imports done and correct 
class infrastructure: # line 1 

    @inlineCallbacks 
    def dict_service(self): 
    client = MyClient() 
    services = yield client.listServices() # line 5 
    ret = (dict(service.name, [cont.container_id for cont in service.instances]) for service in dockerServices) 
    returnValue(ret) # line 7 

Я звоню своему клиенту, который возвращает мне список Услуг. listServices() возвращение type twisted.internet.defer.ReturnValue.

class myinterface: 
    # has infrastructure 

    def init: 
    data = dict(
     container_services=self._infrastructure.dict_service(), 
     ) 

При выполнении этого я становлюсь ниже ошибки, которую я не могу понять. кто-то может помочь.

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: <twisted.python.failure.Failure <type 'exceptions.NameError'>>> is not JSON serializable\n" 

Это потому, что упаковка dict с returnValue создает проблемы?

ответ

1

Там нет никаких проблем с использованием returnValue с dict например:

$ python -m twisted.conch.stdio 
>>> from __future__ import print_function 
>>> from twisted.internet.defer import inlineCallbacks, returnValue 
>>> @inlineCallbacks 
... def f(): 
...  d = yield {"foo": "bar"} # Yield *something* or it's not a generator 
...  returnValue(d) 
... 
>>> f().addCallback(print) 
{'foo': 'bar'} 
<Deferred at 0x7f84c51847a0 current result: None> 

Ошибка Вы сообщили:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: <twisted.python.failure.Failure <type 'exceptions.NameError'>>> is not JSON serializable\n" 

делает вид, как будто у вас есть код, который вызывает NameError. Это, кажется, происходит в отсроченном обратном вызове (или иным образом делает свой путь в Отложенный) и получает завернутые в Failure:

<twisted.python.failure.Failure <type 'exceptions.NameError'>> 

Остается:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: <DeferredWithContext at 0x4bfbb48 current result: ...> is not JSON serializable\n" 

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

Если это так, то ошибка говорит о DeferredWithContext, например, что имеет вышеописанный Failure как его результат:

<DeferredWithContext at 0x4bfbb48 current result: ...> 

Это оставляет:

raise TypeError(repr(o) + \" is not JSON serializable\")\nexceptions.TypeError: ... is not JSON serializable\n" 

Это, кажется, исходит из json module, либо функцию dump, либо dumps. Это утверждение о том, что было передано не сериализуемое JSON. DeferredWithContext почти наверняка не является сериализуемым JSON, поэтому это объясняет проблему.

Это в результате что-то вроде:

json.dumps(function_that_returns_deferred()) 

, который должен быть вместо этого:

function_that_returns_deferred().addCallback(json.dumps) 
+0

проверки и будет обновлять его. – chaosguru

+0

У меня нет явно json.dumps. но общая стековая таблица выглядит так. – chaosguru

+0

Что-то в вашей программе должно делать _something_ с JSON. Скрученная сама, конечно же, не пытается JSON сериализовать любые значения, которые вы получаете от встроенной функции inlineCallbacks. –