5

Firstly, I looked at this, this and this and whilst the first has some useful information, it's not relevant here because I'm trying to iterate over values.

Here's an example of something I want to be able to do:

class BlockingIter:
    def __iter__(self):
        while True:
            yield input()

async def coroutine():
    my_iter = BlockingIter()
    #Magic thing here
    async for i in my_iter:
        await do_stuff_with(i)

How would I go about this?

(Note, BlockingIter is in reality a library I'm using (chatexchange) so there might be a few other complications.)

muddyfish
  • 3,530
  • 30
  • 37
  • Can you say more about the behavior you want here: is `do_stuff_with(i)` the only part you want done asynchronously? – Thomas Aug 27 '17 at 21:00
  • No, I'm working in a framework that uses asyncio as a base and I've got to work with it – muddyfish Aug 27 '17 at 21:01
  • Well, you could probably use `run_in_executor` to advance an iterator object. So `await`ing `loop.run_in_executor(None, next, it)` in a loop would be reasonably close to the desired behaviour. – vaultah Aug 27 '17 at 21:51
  • @vaultah that works, thanks! If you want to write an answer, the final code is `iter_messages = iter(my_iter);while 1:;i = await loop.run_in_executor(None, next, iter_messages)` – muddyfish Aug 27 '17 at 22:10
  • I think a better question is "how do I get user input asynchronously" – Eric Aug 27 '17 at 23:52
  • That's not what I wanted but it worked as a minimal example of what would cause the problem I was getting – muddyfish Aug 28 '17 at 12:25

1 Answers1

4

As @vaultah says and also explained in the docs, awaiting the executor (await loop.run_in_executor(None, next, iter_messages)) is probably what you want.

Amin Etesamian
  • 3,363
  • 5
  • 27
  • 50