python-stdlib/selectors: Add selectors module based on select.poll. - #1168
Open
pavelrevak wants to merge 1 commit into
Open
pavelrevak wants to merge 1 commit into
pavelrevak wants to merge 1 commit into
Conversation
This adds a CPython compatible `selectors` module implemented as a thin layer over MicroPython's `select.poll()`. It provides EVENT_READ, EVENT_WRITE, SelectorKey, BaseSelector, PollSelector and DefaultSelector with register(), unregister(), modify(), select(), close(), get_key(), get_map() and context manager support. File objects are tracked by identity rather than by file descriptor, because sockets on bare-metal ports have no fileno(). SelectorKey.fd is the fileno() when available, otherwise -1. The tests also pass against CPython's stdlib selectors module. Signed-off-by: Pavel Revak <pavelrevak@gmail.com>
Author
|
The CI failure is expected: The test registers an object that I'll re-run CI once #19741 is merged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a CPython compatible
selectorsmodule topython-stdlib, implemented as a thin layer over MicroPython's
select.poll(). It lets code written for CPython's high-level I/Omultiplexing API run unchanged on MicroPython, on the unix port as well as
on bare-metal ports. See micropython/micropython#1550 for earlier
discussion about a consistent polling API and CPython's
selectors.It provides
EVENT_READ,EVENT_WRITE,SelectorKey,BaseSelector,PollSelectorandDefaultSelectorwithregister(),unregister(),modify(),select(),close(),get_key(),get_map()and contextmanager support. Exceptions follow CPython (
ValueError,KeyError,RuntimeError).Differences from CPython (documented in the package README.md):
because sockets on bare-metal ports have no
fileno().SelectorKey.fdis thefileno()when available, otherwise-1.get_map()returns a plain dict keyed by file object.PollSelectoris provided,DefaultSelectoris an alias for it.This depends on micropython/micropython#19741. Without it, registering an
object that
select.poll()rejects leaves the poll object in a brokenstate, and a later
select()crashes. Normal use with valid objects suchas sockets is not affected.
Testing
python-stdlib/selectors/test_selectors.py(14 tests usingloopback TCP sockets) and added the package to
tools/ci.sh. One testcovers a failed registration and needs extmod/modselect: Fix crashes after a failed register() and pollfds realloc. micropython#19741.
and 20 repeated runs showed no flakiness.
selectorsmodule(CPython 3.14), which confirms the behaviour matches CPython.
manifestfile.py --compilebuilds the package.for example together with my uhttp-server or uhttp-client.
Trade-offs and Alternatives
This is a new optional package, so firmware size is unchanged. The
compiled
selectors.mpyis 1670 bytes.An alternative would be to implement
selectorsin C. Theperformance-critical part, waiting for and collecting events, is already
done in C by
ipoll(); the Python layer only maps event masks and keepsthe registered keys. As a micropython-lib package it adds no code size to
firmware for anyone who doesn't use it.
Generative AI
I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.