Skip to main content

pytest-freethreaded

A Pytest plugin for helping verify that your tests and libraries are thread-safe with the Python 3.13 experimental freethreaded mode.

Why do I need this plugin?

Python 3.13 introduces a new mode called freethreaded that allows you to run Python code with the GIL disabled. This can be useful for running CPU-bound code in parallel, but it also means that your code must be thread-safe.

Some packages and libraries with good, mature test bases have marked their libraries as "compatible" with freethreaded, but they have only run the tests once and in a single-thread!

Pytest-xdist won't help you here, because it uses multiprocessing to parallelize tests, and the GIL is still enabled.

So we made this plugin to help you run your tests in a thread-pool with the GIL disabled, to help you identify if your tests are thread-safe.

And the first library we tested it on (which was marked as compatible) caused a segmentation fault in CPython! So you should give this a go if you're a package maintainer.

Installation

pip install pytest-freethreaded

Usage

We recommend using this plugin in a phased approach to identify if your tests can be run in a thread-pool with the GIL disabled, before disabling the GIL.

Phase 1: Your tests should pass without this plugin

First, your tests should be running, and you should have tests.

Phase 2: Run your tests with the GIL enabled, but with concurrency

This plugin will run each multiple times, in parallel. By default, it will execute each test 10 times, then repeat that 20 times. This means each test will run 200 times. This is a lot, so we recommend only running this cycle once, or on a subset of tests.

If a test fails on any of the runs, we will raise a special error called a ConcurrencyError that indicates the test partially failed, most likely due to a lack of thread-safety and/or a race condition.

Selecting specific tests

If, during this phase you decide to only run a subset of tests, you can use the -k flag to select tests by name.

Alternatively, you can set the number of threads and the executions using a marker:

import pytest

@pytest.mark.freethreaded(threads=10, executions=10)
def test_my_threaded_code():
    pass

Then on the command-line set the threads and executions to 1:

pytest --threads 1 --executions 1

Phase 3: Run your tests with the GIL disabled

If you passed phase 3; congratulations! You can now run your tests with the GIL disabled.

We recommend using the --require-gil-disabled flag in Pytest for this phase so that if you accidentally run Python 3.13 with the GIL on, it will fail the tests.

pytest --require-gil-disabled

During this final phase, if you see any new Concurrency Errors or even worse you see a crash in Python 3.13, you will need to debug it.

Development

Setup:

python3.13t -m venv .venv
source .venv/bin/activate
python -m pip install flit
python -m flit install -s

Testing

To run the tests

pytest -vvvv --log-level=DEBUG

Credits

This extension was created at PyCon JP sprints with the following team members:

  • Anthony Shaw @tonybaloney
  • Mike Hommey @glandium
  • Oliver Basset @obassett
  • Maryanne Wachter @m-clare
  • Toshihiko Yanase @toshihikoyanase
  • Heejun Shin @abel9851
  • Otake Katsuaki
  • Rei Suyama @rhoboro

Metadata

Release files for pytest-freethreaded 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-freethreaded 0.1.0
File Size Uploaded
pytest_freethreaded-0.1.0.tar.gz 6.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-freethreaded 0.1.0
File Interpreter ABI Platform
pytest_freethreaded-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.7 kB

Release files / pytest_freethreaded-0.1.0.tar.gz

Download URL pytest_freethreaded-0.1.0.tar.gz
Size 6.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9cb4f412db3abb5a8ffdcb29a2d42e058c41f16437c0a1815101651b485dcf45
BLAKE2b-256 checksum
How to use checksums
20093bf5fb5321463551787c41bd1af128c1eff018a55e1bb91af0501df54773
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.3

Release files / pytest_freethreaded-0.1.0-py3-none-any.whl

Download URL pytest_freethreaded-0.1.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5f2beb6026857f274162d0aa131fe605b8c6d2a3b0c2d35a2af14721959398f1
BLAKE2b-256 checksum
How to use checksums
a6e0f379af92804357ac186d2d90ec73a1534183477de1e32e1a4f0bb86b85da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page