[Python-ideas] Add a generic async IO poller/reactor to select module

Giampaolo Rodolà g.rodola at gmail.com
Thu May 24 03:32:42 CEST 2012

Including an established async IO framework such as Twisted, gevent or
Tornado in the Python stdlib has always been a controversial subject.
PEP-3153 (http://www.python.org/dev/peps/pep-3153/) tried to face this
problem in the most agnostic way as possible, and it's a good starting
point IMO.
Nevertheless, it's still vague about what the actual API should look
like and AFAIK it remained stagnant so far.

There's one thing in the whole async stack which is basically the same
for all implementations though: the poller/reactor.
Could it make sense to add something similar to select module?
Differently from PEP-3153, providing such a layer on top of select(),
poll() & co. is easier and could possibly be an incentive to avoid
such code duplication.

I'm coming up with this because I recently did something similar in
pyftpdlib as an hack on top of asyncore to add support for epoll() and
kqueue(), using the excellent Tornado's io loop as source of

The way I imagine it:

>>> import select
>>> dir(select)
[..., 'EpollPoller', 'PollPoller', 'SelectPoller', 'KqueuePoller']
>>> poller = select.EpollPoller()
>>> poller.register(fd, handler, poller.READ | poller.WRITE)
>>> poller.socket_map
{2 : <Handler instance at ...>}
>>> poller.modify(fd, poller.READ)
>>> poller.poll()      # will call handler.handle_read_event() if/when it's the case
>>> poller.remove(fd)
>>> poller.close()

The handler is supposed to provide 3 methods:
- handle_read_event
- handle_write_event
- handle_error_event

Users willing to support multiple event loops such as wx, gtk etc can do:

>>> while 1:
...       poller.poll(timeout=0.1, blocking=False)
...       otherpoller.poll()

Basically, this would be the whole API.


--- Giampaolo

More information about the Python-ideas mailing list