Skip to content

ci: run each job on the Python version it names - #160

Merged
MarketDataDev02 merged 1 commit into
mainfrom
ci/test-matrix-python-version
Oct 2, 2026
Merged

MarketDataDev02 merged 1 commit into
mainfrom
ci/test-matrix-python-version

Conversation

@MarketDataDev02

Copy link
Copy Markdown
Collaborator

What happened

test (3.11), test (3.12) and Integration Tests (live) installed their Python with actions/setup-python, and then uv sync --group dev built .venv on the 3.10 that .python-version names, downloading a managed 3.10.21 because the runner had none on PATH. pytest ran on 3.10.21 in all four jobs, so the matrix tested one version three times. The release gate of tag-and-release and publish.yml calls this workflow, so it had the same gap. From 3.11 on the lock installs numpy 2.3.5 instead of 2.2.6, and CI had never run it.

Lint, and build.yml, which both release workflows call, set up 3.12 and ran uv on 3.10 by the same rule. Nothing they produce changed: ruff is a standalone binary that targets py310 from pyproject.toml, and the wheel is py3-none-any.

The change

python-version on astral-sh/setup-uv in every job that builds a uv environment: the matrix version in test, and "3.12" in the live job, in Lint and in build.yml, the version each one already sets up. The input exports UV_PYTHON for the later steps, and uv sync, uv pip and uv run all take it over .python-version.

Of the three ways to do it, this is the smallest: one line per job, and it covers every uv command in the job. uv sync --python X alone would not hold, because the bare uv run pytest that follows recreates .venv on the version .python-version names. Measured locally, on an environment that uv sync --python 3.11 had just built:

$ uv run python -V
Using CPython 3.10.18
Removed virtual environment at: .../venv311
Creating virtual environment at: .../venv311
Installed 46 packages in 7.54s
Python 3.10.18

A job-level UV_PYTHON env does the same as the input, with one more line in the matrix job.

actions/setup-python stays: uv now uses the interpreter it installs instead of downloading one, and build.yml runs python from it.

.python-version stays 3.10. The job names and the Tests passed gate do not change. One CHANGELOG entry under Fixed.

Proof

Before: main run 36139219264 (bc0619c) for the matrix. A push to main does not run the live suite, so its before is job 108175285786 of run 36166436477, on the branch of #159, whose test.yml is main's. After: run 36484944941, a workflow_dispatch of Tests on this branch (b057347).

job setup-python uv pytest numpy tests coverage
test (3.10) before 3.10.21 uses it Python 3.10.21 2.2.6 1954 passed 100%
after 3.10.21 Set UV_PYTHON to 3.10, uses it Python 3.10.21 2.2.6 1954 passed 100%
test (3.11) before 3.11.16 downloads 3.10.21 Python 3.10.21 2.2.6 1 failed ¹, 1953 passed 100%
after 3.11.16 Set UV_PYTHON to 3.11, uses it Python 3.11.16 2.3.5 1952 passed, 2 skipped 100%
test (3.12) before 3.12.14 downloads 3.10.21 Python 3.10.21 2.2.6 1954 passed 100%
after 3.12.14 Set UV_PYTHON to 3.12, uses it Python 3.12.14 2.3.5 1952 passed, 2 skipped 100%
Integration Tests (live) before 3.12.14 downloads 3.10.21 Python 3.10.21 2.2.6 1 failed ², 17 passed not measured
after 3.12.14 Set UV_PYTHON to 3.12, uses it Python 3.12.14 2.3.5 18 passed not measured

"uses it" is the log line Using CPython 3.1x.y interpreter at: /opt/hostedtoolcache/Python/3.1x.y/x64/bin/python3.1x, the interpreter setup-python installed. "downloads" is Downloading cpython-3.10.21-linux-x86_64-gnu followed by Using CPython 3.10.21. No job of the after run downloads a Python or recreates .venv, and its uv pip install -e . step runs with UV_PYTHON set to the job's version.

The 2 skipped on 3.11 and 3.12 are the nul-byte cases of test_merge_csv_responses_turns_a_body_the_csv_module_cannot_read_into_a_parse_error, which skip from 3.11 on because the csv module reads NUL as data there. 3.10 skips none, so the count follows the interpreter as well.

¹ The intermittent FloatingPointError of #155 (test_a_null_date_keeps_its_row_on_the_other_decoded_formats[stocks.news-pandas]), raised from .venv/lib/python3.10/site-packages/numpy: a 3.11 job running 3.10.
² test_status_lists_every_service: the live /status/ answered a 500 HTML page at 12:04 UTC on 2026-09-28. It has nothing to do with the interpreter, and the after run passes it.

Lint: main run 36139219342 sets up 3.12.14, then logs Downloading cpython-3.10.21 and Using CPython 3.10.21. The dispatch on this branch, 36484949723, logs Set UV_PYTHON to 3.12 and Using CPython 3.12.14 interpreter at: /opt/hostedtoolcache/Python/3.12.14/x64/bin/python3.12, and passes.

build.yml runs only from a release, so it was checked locally: uv build reads .python-version and builds on 3.10.18, and with UV_PYTHON=3.12 it looks for 3.12 and builds on 3.12.12. From the same tree both give the same wheel and sdist, byte for byte (sha256 a8601ee2… and cf857c69…).

Before the change, the unit suite ran locally (Windows) on 3.11.13 and 3.12.12 with numpy 2.3.5: 1952 passed, 2 skipped on each. Nothing on 3.11 or 3.12 needed fixing.

Closes #156

setup-python installed the matrix interpreter, but uv takes its version
from .python-version (3.10), not from the interpreter on PATH, so
test (3.11), test (3.12) and the live suite, set up on 3.12, all ran on
3.10. The release gate calls this workflow, so it had the same gap
(#156).

setup-uv's python-version input exports UV_PYTHON, which uv sync, uv pip
and uv run all prefer to .python-version. Passing --python to uv sync
alone would not hold: the bare uv run that follows recreates the
environment on the version .python-version names.

Lint and the release build set up 3.12 and ran on 3.10 the same way, so
they get the same input. .python-version stays 3.10.
@codecov

codecov Bot commented Sep 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (bc0619c) to head (b057347).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #160   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           62        62           
  Lines         3196      3196           
=========================================
  Hits          3196      3196           
Flag Coverage Δ
unittests 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marketdata-code-review

Copy link
Copy Markdown

✅ Ready — Code review

This CI-only change makes uv use each job's declared Python version in test, lint, integration, and build workflows. Version impact: none; no public SDK symbols or runtime package behavior change.

Rating patch 6/6 (exemplary) · proof 6/6 (comprehensive) · overall 6/6


Reviewed b057347 · revision 1 · codex (gpt-5.6-sol) · claude unavailable · rules: default, sdk

@MarketDataDev02
MarketDataDev02 merged commit 83fa829 into main Oct 2, 2026
19 checks passed
@MarketDataDev02
MarketDataDev02 deleted the ci/test-matrix-python-version branch October 2, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI runs every matrix job on Python 3.10: uv sync ignores the matrix interpreter

2 participants