Skip to content

ci: run unit tests on free-threaded Python 3.14t - #11

Draft
chipkent wants to merge 1 commit into
test/pook-mock-leakfrom
ci/free-threaded-3.14t
Draft

chipkent wants to merge 1 commit into
test/pook-mock-leakfrom
ci/free-threaded-3.14t

Conversation

@chipkent

@chipkent chipkent commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Preview only. This is a draft in the fork showing the exact text of the PR planned for massive-com/client-python. It will be closed, not merged, once the upstream PR is opened.

Fixes #<issue: CI-FREE-THREADED>

Builds on #9: without it, leaked pook mocks intercept the new test's requests. (#13 guards against the same leak inline because it cannot assume #9.)

A RESTClient is shared between threads often enough that massive-com#1040 added maxsize= for it and the README's Network Configuration section covers the case; WebSocketClient.subscribe() is likewise called from other threads while connect() runs. Free-threaded Python (PEP 703) removes the GIL, which can hide race conditions. This adds one CI job on 3.14t and a test that shares one RESTClient between threads.

  • CI job Unit test 3.14t (PYTHON_GIL=0): pip install -e . pook, fail unless sys._is_gil_enabled() is false, then run test_rest and test_websocket as make test does. pyproject.toml and poetry.lock are unchanged. The job uses actions/setup-python@v5, which understands the 3.14t version string; the existing matrix is untouched.
  • test_rest/test_concurrency.py: 16 threads make 64 calls each through one client to a local echo server. It checks that:
    • every response answers its own request (path, query, edge header);
    • per-request headers (odd calls only) never leak into c.headers, which is unchanged;
    • more than one request was in flight at once.

It calls _get, which every endpoint uses, because endpoint methods currently also copy options into the query string (#<issue: F8>).

Tests

  • The new job passes, including the GIL check.
  • make test and make lint pass on 3.10 and 3.14.
  • The test fails if _concat_headers writes into self.headers, and, on 3.14t, if per-request headers are visible to other threads even briefly.

The client is used from multi-threaded programs, and the GIL can hide
race conditions. Add one job that runs the unit tests on free-threaded
3.14t with PYTHON_GIL=0, after checking that the GIL really is off.

The job installs with pip, because the tests need only the package and
pook.

Add a test that shares one RESTClient between 16 threads against a local
server that echoes each request back. It checks that every response
answers its own request, including the per-request edge headers, that
the threads really overlapped, and that per-request headers never reach
the client's default headers.
@coderabbitai

coderabbitai Bot commented Oct 24, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant