3

セルの内容を評価しようとすると、次のエラーが発生する理由を理解しようとしています。一部の関数が返されないか、このような仕組みがわかりません。

 2012-11-08 04:30:45-0800 [HTTPPageGetter,client] handling data: None
 2012-11-08 04:30:45-0800 [HTTPPageGetter,client] Unhandled Error
 Traceback (most recent call last):
 File "path/to/python/lib/python2.7/site-packages/twisted/internet/defer.py", line 1101, in gotResult
 _inlineCallbacks(r, g, deferred)
 File "path/to/python/lib/python2.7/site-packages/twisted/internet/defer.py", line 1048, in _inlineCallbacks
 deferred.callback(None)
 File "path/ib/python2.7/site-packages/twisted/internet/defer.py", line 368, in callback
 self._startRunCallbacks(result)
 File "path/lib/python2.7/site-packages/twisted/internet/defer.py", line 464, in _startRunCallbacks
 self._runCallbacks()
 --- <exception caught here> ---
 File "path/lib/python2.7/site-packages/twisted/internet/defer.py", line 551, in _runCallbacks
 current.result = callback(current.result, *args, **kw)
 File "/path/to/lib/python2.7/site-packages/codenode/frontend/async/backend.py", line 223, in _success
 if 'cellstyle' in data and data['cellstyle'] == 'outputimage':
 exceptions.TypeError: argument of type 'NoneType' is not iterable

 2012-11-08 04:30:45-0800 [HTTPPageGetter,client] Stopping factory

ここにコードの関連部分があります(私が思うに):これが私はデータを渡しますか?

def render(self, request):
    """
    This is where we un-serialize the content sent between the frontend
    and backend engine bus.
    """
    content = request.content.read()
    if content:
        msg = json.loads(content)
        log.msg('Engine message deserialized %s' % str(msg))
    else:
        return
    cellid = msg.get('cellid', '')
    d = self.engine_bus.handleRequest(self.notebook_id, msg)
    d.addCallback(self._success, request, cellid)
    d.addErrback(self._fail, request)
    return server.NOT_DONE_YET

def _success(self, data, request, cellid):
    """
    horrible. not always eval...
    """
    log.msg('handling data: %s' % str(data))
    if 'cellstyle' in data and data['cellstyle'] == 'outputimage':
        image_data = pickle.loads(data['out']).getvalue()
        image_file_name = write_image(image_data)
        data['out'] = image_file_name

    data['cellid'] = cellid
    jsobj = json.dumps(data)
    request.write(jsobj)
    request.finish()

確かに、これは自分の仕事によるものではありません。私はそれについてほとんど理解しておらず、かなり古くなっています。ここにコードの詳細があります: github python file

[編集] ここにもう少しあります: 初期化:

class EngineSessionAdapter(resource.Resource):
    """
    There should be a better way to do this, have to figure that out.
    """

    isLeaf = True

    def __init__(self, engine_bus, notebook_id):
        resource.Resource.__init__(self)
        self.engine_bus = engine_bus
        self.notebook_id = notebook_id
        self.putChild("", self)

これがエンジン オブジェクトです。

class EngineBusAdapter(resource.Resource):

    def __init__(self, engine_bus):
        resource.Resource.__init__(self)
        self.engine_bus = engine_bus
        self.putChild("", self)

    def getChild(self, path, request):
        """XXX Can this refer back to itself?
        """
        return EngineSessionAdapter(self.engine_bus, path)

[2回目の編集] Enginebusの定義は次のとおりです。

class EngineBus(object):
"""
Common entry point for all engine requests. 
Look up engine client by access_id.

This is responsible for routing the engine message
from the browser/frontend to the engine by access_id.
This does not need to process the message (un-serialize, inspect, 
or otherwise).
"""

def __init__(self, backend):
    self.backend = backend

@defer.inlineCallbacks
def handleRequest(self, access_id, msg):
    """
    msg comes in as dictionary
    """
    log.msg('handling engine request for %s' % access_id)
    try:
        engine_client = yield self.backend.getEngine(access_id)
        log.msg('got engine Client %s' % str(engine_client))
    except InvalidAccessId:
        err = {'status':'ERR', 'response':'InvalidAccessId'}
        log.err('InvalidAccessId %s' % access_id)
        defer.returnValue(err)

    result = yield engine_client.send(msg)
    sucs = {'status':'OK', 'response':result}
    defer.returnValue(sucs)

編集:最終的に解決しました:これが差分です:

-        result = yield meth(engine_arg, cellid)
+        result = yield defer.maybeDeferred(meth,engine_arg, cellid)
         defer.returnValue(result)

-    @defer.inlineCallbacks
     def engine_start(self, args, arg):
         """dummy
         """
-        defer.returnValue({'result':'started'})
+        return {'result':'started'}

ここにコンテキストがあります:backend/engine.pyのgithubのコミット差分

4

2 に答える 2

4

このソース行を考えると:

if 'cellstyle' in data and data['cellstyle'] == 'outputimage':

あなたが得ている例外:

exceptions.TypeError: argument of type 'NoneType' is not iterable

ほぼ確実に であることを意味しdataますNonedataは にアタッチしたコールバックへの結果引数 (つまり、最初の引数) であるため、DeferredこれはDeferredNoneその結果として含まれていることを意味します。

Deferredthis コールバックがアタッチされているため、次のように作成されます。

d = self.engine_bus.handleRequest(self.notebook_id, msg)

で発火するengine_bus.handleRequestをあなたに与えているようです。おそらくこれはオブジェクトのバグですか、それともその API を誤用しているのでしょうか? 何が何だかわからないので、これ以上掘り下げることはできません。DeferredNoneengine_busengine_bus

于 2012-11-08T14:19:46.233 に答える
3
if 'cellstyle' in data and data['cellstyle'] == 'outputimage':
exceptions.TypeError: argument of type 'NoneType' is not iterable

'cellstyle' in data反復可能である必要dataがあります - 反復可能ではありませんが、None

于 2012-11-08T14:18:03.123 に答える