Skip to content

feat: add Python 3.14 support#250

Merged
toby-coleman merged 12 commits intomainfrom
copilot/add-python-3-14-support
Apr 22, 2026
Merged

feat: add Python 3.14 support#250
toby-coleman merged 12 commits intomainfrom
copilot/add-python-3-14-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

Summary

Adds Python 3.14 to the supported/runtime-tested versions for Plugboard and aligns dependency floors with the releases needed for working 3.14 compatibility across the project and Ray-backed tests. CI and release workflows are updated so packaging and validation run against the expanded version set, and the Ray resource integration test is updated to avoid depending on the dashboard HTTP API in CI.

Changes

  • Project metadata

    • Adds the Python 3.14 Trove classifier.
    • Keeps the existing requires-python >=3.12,<4.0 range and updates dependency floors needed for 3.14:
      • msgspec[yaml] >= 0.20
      • pydantic >= 2.13.1
      • Ray optional/test dependencies moved to ray[tune] >= 2.55.0
  • CI / release pipelines

    • Extends the main lint/test/build matrix to include Python 3.14.
    • Moves single-version workflows that build/publish artifacts to Python 3.14:
      • docs
      • docker
      • PyPI publish
    • Updates benchmarks to run on 3.14 so perf coverage tracks the newest supported interpreter.
  • Lockfile refresh

    • Regenerates uv.lock for the new dependency constraints and trims packages that were only pulled in by ray[default].
  • Python 3.14 Ray compatibility

    • Fixes the Python 3.14 Ray test failures caused by ray 2.55.0 resolving against an older pydantic.v1 compatibility layer.
    • Bumps the workspace Pydantic floor in both plugboard and plugboard-schemas so Ray state/dashboard imports and ray.init() work correctly on Python 3.14.
  • Test harness compatibility

    • Replaces the removed asyncio.events.BaseDefaultEventLoopPolicy annotation in tests/conftest.py with a Python-3.14-safe event loop policy fixture.
    • Updates tests/integration/test_component_resources.py to verify Ray actor creation and resource reservation using Ray core APIs instead of ray.util.state.list_actors(), avoiding flaky failures when the dashboard API on port 8265 is unavailable in CI.
classifiers = [
  "Programming Language :: Python :: 3.12",
  "Programming Language :: Python :: 3.13",
  "Programming Language :: Python :: 3.14",
]

dependencies = [
  "msgspec[yaml]>=0.20,<1",
  "pydantic>=2.13.1,<3",
]

[project.optional-dependencies]
ray = ["ray[tune]>=2.55.0,<3", "jsonschema<4.25.0", "optuna>=3.0,<5"]

Warning

Ray 2.55.0 Python 3.14 support depends on resolving to a new enough pydantic.v1 compatibility layer. This PR raises the Pydantic floor accordingly to avoid Ray startup and state API failures on Python 3.14.

Copilot AI linked an issue Apr 15, 2026 that may be closed by this pull request
Copilot AI and others added 3 commits April 15, 2026 20:55
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/db561b01-f70a-4723-bd46-068e4b56ae8f

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/db561b01-f70a-4723-bd46-068e4b56ae8f

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/db561b01-f70a-4723-bd46-068e4b56ae8f

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Python 3.14 support to project feat: add Python 3.14 support Apr 15, 2026
Copilot AI requested a review from toby-coleman April 15, 2026 21:30
@toby-coleman
Copy link
Copy Markdown
Contributor

@copilot The tests fail in python 3.24 with Exception: The current node timed out during startup. This could happen because some of the raylet failed to startup or the GCS has become overloaded. Investigate what is going on and fix.

Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/55438f91-bd29-47a8-8cd2-157c5e0ee709

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 19, 2026

@copilot The tests fail in python 3.24 with Exception: The current node timed out during startup. This could happen because some of the raylet failed to startup or the GCS has become overloaded. Inv...

Fixed in 8b172a5. The Python 3.14 Ray failure was coming from ray 2.55.0 resolving against pydantic 2.12.x, whose bundled pydantic.v1 layer breaks Ray’s dashboard/state imports on 3.14. I bumped the workspace Pydantic floor to >=2.13.1, refreshed uv.lock, and verified the failing benchmark collection path and Ray startup regression tests on 3.14.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • metadata.google.internal
    • Triggering command: /home/REDACTED/work/plugboard/plugboard/.venv/bin/python /home/REDACTED/work/plugboard/plugboard/.venv/bin/python /home/REDACTED/work/plugboard/plugboard/.venv/lib/python3.12/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-19_20-33-08_235796_4079/logs --session-dir=/tmp/ray/session_2026-04-19_20-33-08_235796_4079 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:42175 --cluster-id-hex=f9aac9e7a83be44b0298f00b9b513725669466473475947863aeb198 --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-19_20-33-08_235796_4079/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-19_20-33-08_235796_4079/logs/dashboard.err --minimal --modules-to-load=UsageStatsHead --disable-frontend (dns block)
    • Triggering command: /home/REDACTED/.cache/uv/builds-v0/.tmpH6TJ1C/bin/python /home/REDACTED/.cache/uv/builds-v0/.tmpH6TJ1C/bin/python /home/REDACTED/.cache/uv/archive-v0/uhE3K78bc6riUp1-x7QIF/lib/python3.14/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-19_20-34-46_682489_4595/logs --session-dir=/tmp/ray/session_2026-04-19_20-34-46_682489_4595 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:43995 --cluster-id-hex=82a6117d8bbda9fa45f38eb3ccfc6aa93c34e42fd5a3287690c33bae --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-19_20-34-46_682489_4595/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-19_20-34-46_682489_4595/logs/dashboard.err --minimal --modules-to-load=UsageStatsHead --disable-frontend (dns block)
    • Triggering command: /home/REDACTED/.cache/uv/builds-v0/.tmpE5sYCb/bin/python /home/REDACTED/.cache/uv/builds-v0/.tmpE5sYCb/bin/python /home/REDACTED/.cache/uv/archive-v0/_H9FmARY8DkvPuhofnm3w/lib/python3.14/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-19_20-34-51_898061_4830/logs --session-dir=/tmp/ray/session_2026-04-19_20-34-51_898061_4830 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:43855 --cluster-id-hex=72507d85e9463ce8bcf92f35f7370e93664857b5904cd488b4d5f1dc --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-19_20-34-51_898061_4830/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-19_20-34-51_898061_4830/logs/dashboard.err --minimal --modules-to-load=UsageStatsHead --disable-frontend (dns block)
  • releases.astral.sh
    • Triggering command: /home/REDACTED/.local/bin/uv uv venv .venv --python 3.14 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Copy Markdown

Benchmark comparison for 2c24e5f0 (base) vs 3be4a9ec (PR)


---------------------------------------------------- benchmark: 1 tests ---------------------------------------------------
Name (time in ms)                   Min       Max      Mean  StdDev    Median     IQR  Outliers     OPS  Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run     461.1901  481.0947  467.2095  7.9841  463.8573  7.2334       1;1  2.1404       5           1
---------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@github-actions
Copy link
Copy Markdown

Benchmark comparison for 2c24e5f0 (base) vs 75e5ade2 (PR)


---------------------------------------------------- benchmark: 1 tests ---------------------------------------------------
Name (time in ms)                   Min       Max      Mean  StdDev    Median     IQR  Outliers     OPS  Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run     455.6769  462.8910  458.0362  3.0517  456.3163  4.1413       1;0  2.1832       5           1
---------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@github-actions
Copy link
Copy Markdown

Benchmark comparison for 2c24e5f0 (base) vs b445318a (PR)


---------------------------------------------------- benchmark: 1 tests ---------------------------------------------------
Name (time in ms)                   Min       Max      Mean  StdDev    Median     IQR  Outliers     OPS  Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run     299.5808  304.4660  301.3083  1.9359  300.5949  2.4163       1;0  3.3189       5           1
---------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@toby-coleman
Copy link
Copy Markdown
Contributor

@copilot find out why the following integration test is failing and fix

FAILED tests/integration/test_component_resources.py::test_component_resources_in_ray_process - ray.util.state.exception.ServerUnavailable: Failed to make request to http://127.0.0.1:8265/api/v0/actors. Failed to connect to API server. Please check the API server log for details. Make sure dependencies are installed with `pip install ray[default]`. Please also check dashboard is available, and included when starting ray cluster, i.e. `ray start --include-dashboard=True --head`.

Copilot AI and others added 4 commits April 21, 2026 21:45
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/39e4383c-94e6-453d-9964-8974046c769d

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/39e4383c-94e6-453d-9964-8974046c769d

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/39e4383c-94e6-453d-9964-8974046c769d

Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 21, 2026

@copilot find out why the following integration test is failing and fix

FAILED tests/integration/test_component_resources.py::test_component_resources_in_ray_process - ray.util.state.exception.S...

Fixed in 0b6cd56. The failure was caused by the test calling ray.util.state.list_actors(), which depends on the dashboard HTTP API on port 8265. The Ray actor itself was healthy, but the dashboard server was not reliably available in CI. I updated the test to use Ray core APIs instead: it now verifies the named actor exists and checks the expected CPU/memory reservation from Ray resource accounting, so it keeps the same intent without depending on the dashboard.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • metadata.google.internal
    • Triggering command: /home/REDACTED/work/plugboard/plugboard/.venv/bin/python /home/REDACTED/work/plugboard/plugboard/.venv/bin/python /home/REDACTED/work/plugboard/plugboard/.venv/lib/python3.12/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-21_21-42-42_789226_9811/logs --session-dir=/tmp/ray/session_2026-04-21_21-42-42_789226_9811 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:33019 --cluster-id-hex=1bb1194e2c55265592b741a2ddb6cc828fb02f807e5f207698723b6b --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-21_21-42-42_789226_9811/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-21_21-42-42_789226_9811/logs/dashboard.err --modules-to-load=UsageStatsHead --disable-frontend (dns block)
    • Triggering command: /home/REDACTED/work/plugboard/plugboard/.venv/bin/python3 /home/REDACTED/work/plugboard/plugboard/.venv/bin/python3 /home/REDACTED/work/plugboard/plugboard/.venv/lib/python3.12/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-21_21-42-41_847883_9810/logs --session-dir=/tmp/ray/session_2026-04-21_21-42-41_847883_9810 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:33621 --cluster-id-hex=236f909d713c9225cda1818ac60129d1bca1483537ad7fe9b6298069 --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-21_21-42-41_847883_9810/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-21_21-42-41_847883_9810/logs/dashboard.err ader (dns block)
    • Triggering command: /home/REDACTED/work/plugboard/plugboard/.venv/bin/python3 /home/REDACTED/work/plugboard/plugboard/.venv/bin/python3 /home/REDACTED/work/plugboard/plugboard/.venv/lib/python3.12/site-packages/ray/dashboard/dashboard.py --host=127.0.0.1 --port=8265 --port-retries=50 --temp-dir=/tmp/ray --log-dir=/tmp/ray/session_2026-04-21_21-43-13_965867_10831/logs --session-dir=/tmp/ray/session_2026-04-21_21-43-13_965867_10831 --logging-rotate-bytes=536870912 --logging-rotate-backup-count=5 --gcs-address=127.0.0.1:43735 --cluster-id-hex=f37086fe05e4b52d241ef1eadf977e00aaeaa26adb021192b646aa0e --node-ip-address=127.0.0.1 --proxy-server-url= --stdout-filepath=/tmp/ray/session_2026-04-21_21-43-13_965867_10831/logs/dashboard.out --stderr-filepath=/tmp/ray/session_2026-04-21_21-43-13_965867_10831/logs/dashboard.err (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Copy Markdown

Benchmark comparison for 2c24e5f0 (base) vs 0b6cd567 (PR)


---------------------------------------------------- benchmark: 1 tests ---------------------------------------------------
Name (time in ms)                   Min       Max      Mean  StdDev    Median     IQR  Outliers     OPS  Rounds  Iterations
---------------------------------------------------------------------------------------------------------------------------
test_benchmark_process_run     460.6314  464.3238  462.1997  1.6537  461.8537  2.9975       1;0  2.1636       5           1
---------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@toby-coleman toby-coleman marked this pull request as ready for review April 22, 2026 07:12
@toby-coleman toby-coleman merged commit 7a2c291 into main Apr 22, 2026
28 checks passed
@toby-coleman toby-coleman deleted the copilot/add-python-3-14-support branch April 22, 2026 07:13
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.

feat: Python 3.14 support

2 participants