What is the intuitive way of using an instance object with __await__ method in it?

After entering REPL through command “py -3.12 -m asyncio”, I define the class below and try to use its instance.

class Job2:
  def __await__(self) -> str:
    print("in job2")
    val = yield "await from job2"
    print("value received from send(): ", val)
    val2 = yield "await from job2 -2"
    print("value received from send(): ", val2)
    return "leave job2"

I try many ways but with no luck,

ag = Job2()
await ag
RuntimeError: Task got bad yield: ‘await from job2’

I can’t even figure out what this instance is. A async generator? coroutine? iterator? iterable or awaitable? Please help!

This is an awaitable object, the __await__() method is what makes something usable via await. The problem is that the specific values that get yielded from one is a private implementation detail of the specific async library - it’s how all its library functions tell the event loop how the task is paused, and when it should be woken again. For example, sleeping might pass the timestamp it should be woken up at perhaps, and reading from a socket would pass that handle over so the loop can wait for it to be readable.

You basically should always be yielding from values produced by the async library. Unless you’re writing a library yourself, in which case you get to pick what they mean.