4

I'm currently working on the current toy code to try and understand the asyncio module.

import asyncio
import os, sys, traceback
from time import time

os.environ['PYTHONASYNCIODEBUG'] = '1'
print(sys.version)

def timed_fib(n):
    def fib(n):
        return fib(n - 1) + fib(n - 2) if n > 1 else n
    a = time()
    return fib(n), time() - a

def process_input():
    text = sys.stdin.readline()
    n = int(text.strip())
    print('fib({}) = {}'.format(n, timed_fib(n)))


@asyncio.coroutine
def print_hello():
    while True:
        print("{} - Hello world!".format(int(time())))
        yield from asyncio.sleep(3)

def main():
    loop = asyncio.get_event_loop()
    loop.add_reader(sys.stdin, process_input)
    loop.run_until_complete(print_hello())


if __name__ == '__main__':
    main()

However, trying to run this yields the incredibly cryptic traceback below. As you can see, the debug environment variable is set in the fifth line of the code above, however, the traceback remains incredibly unhelpful, as below:

3.4.3rc1 (v3.4.3rc1:69dd528ca625+, Feb  8 2015, 11:01:19) [MSC v.1600 32 bit (In
tel)]
Traceback (most recent call last):
  File "test.py", line 33, in <module>
    main()
  File "test.py", line 29, in main
    loop.run_until_complete(print_hello())
  File "C:\Python34\lib\asyncio\base_events.py", line 304, in run_until_complete

    self.run_forever()
  File "C:\Python34\lib\asyncio\base_events.py", line 276, in run_forever
    self._run_once()
  File "C:\Python34\lib\asyncio\base_events.py", line 1136, in _run_once
    event_list = self._selector.select(timeout)
  File "C:\Python34\lib\selectors.py", line 314, in select
    r, w, _ = self._select(self._readers, self._writers, [], timeout)
  File "C:\Python34\lib\selectors.py", line 305, in _select
    r, w, x = select.select(r, w, w, timeout)
OSError: [WinError 10038] An operation was attempted on something that is not a
socket

How can I access a more useful traceback, and what might be the problem? I am on Windows 7, if it matters.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
Firnagzen
  • 1,212
  • 3
  • 13
  • 29

1 Answers1

6

select() works only with sockets on Windows.

To work with file descriptors, you could try non-select-based event loop, code example:

if os.name == 'nt':
    loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()

Though I doubt that it would help with sys.stdin and asyncio, code example.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Interesting, thanks! Unfortunately, I just tried your latter code example - it gives me `File "C:\Python34\lib\asyncio\base_events.py", line 241, in _make_write_pipe_transport raise NotImplementedError NotImplementedError`, any idea what's wrong there? – Firnagzen Feb 21 '15 at 07:12
  • the second code example is about stdio and asyncio. You have to add `Proactor` bit yourself. – jfs Feb 21 '15 at 07:16
  • I get `OSError: [WinError 6] The handle is invalid` after adding Proactor – Eric Jan 04 '17 at 17:04