GitHub - Jamie-Chang/aiointerpreters: Run CPU bound code in subinterpreters using asyncio · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
Jamie-Chang
aiointerpreters
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star<br>17
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>19 Commits<br>19 Commits
.github/workflows
.github/workflows
examples
examples
src/aiointerpreters
src/aiointerpreters
tests
tests
.gitignore
.gitignore
.python-version
.python-version
LICENSE
LICENSE
README.md
README.md
pyproject.toml
pyproject.toml
runner.md
runner.md
uv.lock
uv.lock
View all files
Repository files navigation
aiointerpreters
Run CPU bound code in subinterpreters using asyncio.
Installation
Pick the tool of your choosing
uv add aiointerpreters<br>uv pip install aiointerpreters<br>pip install aiointerpreters<br>poetry add aiointerpreters<br>pdm add aiointerpreters<br>pipenv install aiointerpreters
Runner
See runner docs, initially the library only exposes a Runner class with a custom interface to schedule asyncio tasks.
Since the official release of 3.14 and the stablisation of a lot of the interpreter features, this offers no advantage to the standard library InterpreterPoolExecutor and therefore is not something that will be updated going forward.
Executor
This library implements a new InterpreterThreadPoolExecutor. This is a drop in replacement for the standard ThreadPoolExecutor with options to dynamically switch to using an Interpreter.
from aiointerpreters.executors import InterpreterThreadPoolExecutor, interpreter
with InterpreterThreadPoolExecutor() as executor:<br>executor.map(interpreter(cpu_bound), (argument for _ in range(runs)))
Any function tagged with interpreter decorator will be dispatched to an isolated interpreter in a separate thread. Otherwise this follows the original behaviour of ThreadPoolExecutor.
Additionally, InterpreterThreadPoolExecutor can be set as the default executor for asyncio and used with asyncio.to_thread:
# Shortcut<br>InterpreterThreadPoolExecutor().set_as_event_loop_default()
# or<br>asyncio.get_running_loop().set_default_executor(InterpreterThreadPoolExecutor())
async with asyncio.TaskGroup() as tg:<br>tg.create_task(asyncio.to_thread(interpreter(cpu_bound), argument))<br>tg.create_task(asyncio.to_thread(io_bound, argument))
Restrictions
The CPU bound function must be picklable. All its arguments and return value must be pickables or Shareable:
type Shareable = (<br>str | bytes | int | float | bool | None | tuple[Shareable, ...] | Queue | memoryview
Motivation
concurrent.future.InterpreterPoolExecutor is currently a great choice if you know you always need an interpreter to run your code. However it's rarely something you want to do by default since you have to always consider the restrictions mentioned above.
You can choose to run a ThreadPoolExecutor alongside an InterpreterPoolExecutor but since they both maintain a pool of threads under the hood, it'll actually save some resources to share the pool of threads. And having one good default option just makes things easier.
Using asyncio.to_thread
Note: since ContextVars are not pickleable InterpreterThreadPoolExecutor works around it by discarding the context, this is not slightly hacky and may change in the future.
Examples
See examples.
About
Run CPU bound code in subinterpreters using asyncio
Resources
Readme
License
Apache-2.0 license
Uh oh!
There was an error while loading. Please reload this page.
Activity
Stars
17<br>stars
Watchers
watching
Forks
fork
Report repository
Releases
v0.6.0
Latest
Jan 1, 2026
+ 6 releases
Packages
Uh oh!
There was an error while loading. Please reload this page.
Contributors
Uh oh!
There was an error while loading. Please reload this page.
Languages
Python<br>100.0%
You can’t perform that action at this time.