セルの内容を評価しようとすると、次のエラーが発生する理由を理解しようとしています。一部の関数が返されないか、このような仕組みがわかりません。
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のコミット差分