Aiointerpreters – Run CPU bound code in subinterpreters using asyncio

rzk2 pts0 comments

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.

aiointerpreters asyncio interpreter interpreterthreadpoolexecutor code using

Related Articles