If you're using Python 3.4+,
select.epoll already supports context — you're clear to just write
with epoll() as E: … and everything will be OK. The epoll descriptor will get properly closed, detached, etc.
But if you're operating on legacy 2 or ≤3.3 systems, writing bilingual code, etc., you might need to write a shim.
Thankfully, this is straightforward:
import select if hasattr(select.epoll, '__enter__'): epoll_with = select.epoll else: class epoll_with: '''contextlib wrapper for python2's epoll''' def __init__(self, *args, **kwargs): self._E = select.epoll(*args, **kwargs) def __enter__(self): return self._E def __exit__(self, exc_type, exc_value, traceback): self._E.close() with epoll_with() as E: E.register(fd, flags) …
Note that this isn't a true "polyfill" yet: the same class can't be used both directly and as a contextmanager (at least not in Python 2/≤3.3). I'll update this post with a proper polyfill at some point, but doing is non-trivial because “
TypeError: type 'select.epoll' is not an acceptable base type”.