aysncio no puede leer stdin en Windows

Estoy tratando de leer stdin de forma asíncrona en Windows 7 de 64 bits y Python 3.4.3

Intenté esto inspirado por una respuesta SO :

import asyncio import sys def reader(): print('Received:', sys.stdin.readline()) loop = asyncio.get_event_loop() task = loop.add_reader(sys.stdin.fileno(), reader) loop.run_forever() loop.close() 

Sin embargo, genera un OSError: [WInError 100381] An operation was attempted on something that is not a socket .

¿Podría un objeto similar a un archivo como stdin ser envuelto en una clase para darle la API de un socket? He hecho esta pregunta por separado , pero si la solución es simple, responda aquí.

Suponiendo que no puedo envolver un objeto similar a un archivo para convertirlo en un socket, intenté usar flujos inspirados en esta esencia :

 import asyncio import sys @asyncio.coroutine def stdio(loop): reader = asyncio.StreamReader(loop=loop) reader_protocol = asyncio.StreamReaderProtocol(reader) yield from loop.connect_read_pipe(lambda: reader_protocol, sys.stdin) @asyncio.coroutine def async_input(loop): reader = yield from stdio(loop) line = yield from reader.readline() return line.decode().replace('\r', '').replace('\n', '') @asyncio.coroutine def main(loop): name = yield from async_input(loop) print('Hello ', name) loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) loop.close() 

Y eso genera un NotImplementedError en asyncio.base_events._make_read_pipe_transport

Por favor avise cómo leer stdin usando asyncio en Windows …

La excepción NotImplementedError se NotImplementedError porque las líneas de conexión de tuberías no son compatibles con SelectorEventLoop , que es el bucle de eventos predeterminado establecido en asyncio . ProactorEventLoop usar un ProactorEventLoop para admitir tuberías en Windows. Sin embargo, aún no funcionaría porque aparentemente las funciones connect_read_pipe y connect_write_pipe no admiten stdin / stdout / stderr o archivos en Windows como Python 3.5.1.

Una forma de leer desde stdin con un comportamiento asíncrono es usar un hilo con el método run_in_executor del bucle. Aquí hay un ejemplo simple para referencia:

 import asyncio import sys async def aio_readline(loop): while True: line = await loop.run_in_executor(None, sys.stdin.readline) print('Got line:', line, end='') loop = asyncio.get_event_loop() loop.run_until_complete(aio_readline(loop)) loop.close() 

En el ejemplo, la función sys.stdin.readline() es llamada dentro de otro hilo por el método loop.run_in_executor . El hilo permanece bloqueado hasta que stdin recibe un salto de línea, mientras tanto, el bucle es libre de ejecutar otras rutinas si existieran.