我试图理解为什么当我尝试评估单元格的内容时会出现以下错误,某些函数要么没有返回,要么我不明白这些东西是如何工作的。
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
这是代码的相关部分(我认为): addcallback 中有一个可疑部分(三个参数都不是数据)但在 _success 中(三个除了 self 一个是数据),如果这是问题何时我传递数据?
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文件
[编辑] 这里还有一点:初始化:
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'}
这里是上下文:github上后端/engine.py的提交差异