title: i'm getting 'nonetype' not iterable error in python /twisted
body: <p>I am trying to understand why I get the following error that comes about when I try to evaluate the contents of a cell, some function is either not returning or I don't understand how this stuff works.</p>
  
  <pre><code> 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()
   --- &lt;exception caught here&gt; ---
   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
  </code></pre>
  
  <p>here is the relevant part of the code (I think):
  there is a suspicious part in the addcallback(three params none of which are data) but in the _success (three apart from self one of which is data),  if this is the issue whee do I pass the data?.</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>Admittedly this is not by own work, and i have little understanding of it, and its pretty dated. 
  here is more of the code: 
  <a href="https://github.com/codenode/codenode/blob/master/codenode/frontend/async/backend.py" rel="nofollow">github python file</a></p>
  
  <p>[EDIT]
  here is a little more :
  the initialization:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>and this is the engine object:</p>
  
  <pre><code>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)
  </code></pre>
  
  <hr>
  
  <p>[2nd Edit]
  here is the Enginebus definition:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>EDIT: Finally solved it:
  here is the diff:</p>
  
  <pre><code>-        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'}
  </code></pre>
  
  <p>here it is in context: <a href="https://github.com/thebookworm101/codenode/commit/56f095dbcb6bc93e848c124c3099ca006f2f7f3a" rel="nofollow">the commit diff on github for backend/engine.py</a></p>