class_docstr: A coroutine wrapped in a Future.
code: def __step(self, exc=None):
      if self.done():
          raise exceptions.InvalidStateError(
              f"_step(): already done: {self!r}, {exc!r}"
          )
      if self._must_cancel:
          if not isinstance(exc, exceptions.CancelledError):
              exc = self._make_cancelled_error()
          self._must_cancel = False
      coro = self._coro
      self._fut_waiter = None
  
      _enter_task(self._loop, self)
      # Call either coro.throw(exc) or coro.send(None).
      try:
          if exc is None:
              # We use the `send` method directly, because coroutines
              # don't have `__iter__` and `__next__` methods.
              result = coro.send(None)
          else:
              result = coro.throw(exc)
      except StopIteration as exc:
          if self._must_cancel:
              # Task is cancelled right before coro stops.
              self._must_cancel = False
              super().cancel(msg=self._cancel_message)
          else:
              super().set_result(exc.value)
      except exceptions.CancelledError as exc:
          # Save the original exception so we can chain it later.
          self._cancelled_exc = exc
          super().cancel()  # I.e., Future.cancel(self).
      except (KeyboardInterrupt, SystemExit) as exc:
          super().set_exception(exc)
          raise
      except BaseException as exc:
          super().set_exception(exc)
      else:
          blocking = getattr(result, "_asyncio_future_blocking", None)
          if blocking is not None:
              # Yielded Future must come from Future.__iter__().
              if futures._get_loop(result) is not self._loop:
                  new_exc = RuntimeError(
                      f"Task {self!r} got Future "
                      f"{result!r} attached to a different loop"
                  )
                  self._loop.call_soon(
                      self.__step, new_exc, context=self._context
                  )
              elif blocking:
                  if result is self:
                      new_exc = RuntimeError(
                          f"Task cannot await on itself: {self!r}"
                      )
                      self._loop.call_soon(
                          self.__step, new_exc, context=self._context
                      )
                  else:
                      result._asyncio_future_blocking = False
                      result.add_done_callback(
                          self.__wakeup, context=self._context
                      )
                      self._fut_waiter = result
                      if self._must_cancel:
                          if self._fut_waiter.cancel(
                              msg=self._cancel_message
                          ):
                              self._must_cancel = False
              else:
                  new_exc = RuntimeError(
                      f"yield was used instead of yield from "
                      f"in task {self!r} with {result!r}"
                  )
                  self._loop.call_soon(
                      self.__step, new_exc, context=self._context
                  )
  
          elif result is None:
              # Bare yield relinquishes control for one event loop iteration.
              self._loop.call_soon(self.__step, context=self._context)
          elif inspect.isgenerator(result):
              # Yielding a generator is just wrong.
              new_exc = RuntimeError(
                  f"yield was used instead of yield from for "
                  f"generator in task {self!r} with {result!r}"
              )
              self._loop.call_soon(
                  self.__step, new_exc, context=self._context
              )
          else:
              # Yielding something else is an error.
              new_exc = RuntimeError(f"Task got bad yield: {result!r}")
              self._loop.call_soon(
                  self.__step, new_exc, context=self._context
              )
      finally:
          _leave_task(self._loop, self)
          self = None
  
imports: import concurrent.futures
  import contextvars
  import functools
  import inspect
  import itertools
  import types
  import warnings
  import weakref
  from types import GenericAlias
  from .None import base_tasks
  from .None import coroutines
  from .None import events
  from .None import exceptions
  from .None import futures
  from .coroutines import _is_coroutine
label_desc: Use image node_id 14 for calling the Task obj's underlying member method code with example usage: obj.__step(exc) without return types