docs: def run_op(self, op, sched):
          """
          Handle the operation:
  
          * if coro is in STATE_RUNNING, send or throw the given op
  
          * if coro is in STATE_NEED_INIT, call the init function and if it
            doesn't return a generator, set STATE_COMPLETED and set the result
            to whatever the function returned.
  
            * if StopIteration is raised, set STATE_COMPLETED and return self.
  
            * if any other exception is raised, set STATE_FAILED, handle error
              or send it to the caller, return self
  
          """
          if op is self:
              import warnings
              warnings.warn("Running coro %s with itself. Something is fishy."%op)
          assert self.state < self.STATE_COMPLETED, \
              "%s called with %s op %r, coroutine state (%s) should be less than %s!" % (
                  self, isinstance(op, CoroutineException) and op or
                  (hasattr(op, 'state') and {0:'RUNNING', 1:'FINALIZED', 2:'ERRORED'}[op.state] or 'NOP'), op,
                  self._state_names[self.state],
                  self._state_names[self.STATE_COMPLETED]
              )
          coroutines.ident = self
  
          try:
              if self.state == self.STATE_RUNNING:
                  if self.debug:
                      traceback.print_stack(self.coro.gr_frame)
  
                  if isinstance(op, CoroutineException):
                      rop = self.coro.throw(*op.args)
                  else:
                      rop = self.coro.switch(op and op.finalize(sched))
              elif self.state == self.STATE_NEED_INIT:
                  assert op is None
                  rop = self.coro.switch(*self.f_args, **self.f_kws)
                  self.state = self.STATE_RUNNING
  
                  del self.f_args
                  del self.f_kws
              else:
                  return None
  
          except StopIteration, e:
              self.state = self.STATE_COMPLETED
              self.result = e.args and e.args[0]
              #~ del self.coro
              rop = self
          except (KeyboardInterrupt, GeneratorExit, SystemExit):
              raise
          except:
              self.state = self.STATE_FAILED
              self.result = None
              self.exception = sys.exc_info()
              if not self.caller:
                  self.handle_error()
              rop = self
              sys.exc_clear()
              #~ del self.coro
          finally:
              coroutines.ident = None
          return rop