PYTHON-6077 Officially support Python 3.15 - #3042
Conversation
…7-officially-support-py315 # Conflicts: # .evergreen/generated_configs/tasks.yml
This reverts commit 78b8a2e.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
| write_env("KRB5_CONFIG", krb_conf) | ||
| LOGGER.info("Writing keytab") | ||
| keytab = base64.b64decode(config["KEYTAB_BASE64"]) | ||
| keytab_b64 = config["KEYTAB_BASE64"] |
There was a problem hiding this comment.
This change was needed for Python 3.15 support
There was a problem hiding this comment.
🟡 Changes recommended
The fallback selects a 64-bit interpreter for Win32 coverage and performs avoidable rate-limited API requests.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds official Python 3.15 and free-threaded 3.15 support across packaging and CI.
Changes:
- Adds Python 3.15 metadata, changelog, tests, and wheels.
- Standardizes CI interpreter selection through
UV_PYTHON. - Adds a python-build-standalone fallback and stricter keytab decoding.
File summaries
| File | Description |
|---|---|
pyproject.toml |
Adds the Python 3.15 classifier. |
doc/changelog.rst |
Documents Python 3.15 support. |
.github/workflows/dist.yml |
Builds and verifies 3.15 wheels. |
.evergreen/scripts/setup-uv-python.sh |
Resolves toolchain interpreters. |
.evergreen/scripts/setup-dev-env.sh |
Installs or fetches missing interpreters. |
.evergreen/scripts/setup_tests.py |
Corrects keytab Base64 padding. |
.evergreen/scripts/generate_config.py |
Generates UV_PYTHON-based tasks. |
.evergreen/scripts/generate_config_utils.py |
Defines 3.15 versions and helpers. |
.evergreen/scripts/fetch-python.sh |
Fetches standalone Python builds. |
.evergreen/generated_configs/variants.yml |
Adds 3.15 compression variants. |
.evergreen/generated_configs/tasks.yml |
Adds and migrates generated tasks. |
.evergreen/generated_configs/functions.yml |
Propagates UV_PYTHON. |
Review details
Suppressed comments (1)
.evergreen/scripts/fetch-python.sh:35
- This unauthenticated GitHub API request runs before the existing-install check at line 53, so every repeated setup still consumes a request even after the large interpreter has been cached. Python 3.15 tasks source this setup more than once, making shared CI egress susceptible to GitHub's unauthenticated rate limit and causing otherwise cached jobs to fail. Resolve the cache path and return it before querying the release API, or cache the release metadata separately.
release="$(curl -fsSL --retry 3 https://api.github.com/repos/astral-sh/python-build-standalone/releases/latest)"
- Files reviewed: 11/12 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new python-build-standalone fallback currently sets UV_PYTHON to a directory (not an interpreter path), which is inconsistent with how UV_PYTHON is handled elsewhere and can break uv run interpreter selection.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
doc/changelog.rst:4
- The changelog header uses an invalid date placeholder ("2026/XX/XX"), which can be confusing and may break tooling that expects a real date. Consider using an explicit "Unreleased" marker until the release date is known.
- Files reviewed: 11/12 changed files
- Comments generated: 1
- Review effort level: Lite
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…7-officially-support-py315 # Conflicts: # doc/changelog.rst
Run async KMS SSL send/recv via loop.run_in_executor with the socket in blocking mode, mirroring the synchronous socket path. This replaces the hand-rolled add_reader/add_writer non-blocking machinery that surfaces a peer reset as a raw ConnectionResetError/BrokenPipeError (before any bytes are sent) under asyncio on Python 3.15, breaking async-only KMS-TLS tests on macOS and rhel8. Also remove the temporary [KMS-DEBUG] diagnostics.
Remove the leftover [KMS-DEBUG] block in pool_shared._async_configured_socket. In network_layer, use asyncio.shield around the executor future in _async_blocking_socket_call so wait_for cannot cancel it. On timeout, join the worker (bounded by the socket's own timeout) before propagating, so the caller never closes the SSL socket out from under the worker thread - closing an in-flight SSL socket is racy and not thread-safe. Handle CancelledError from re-awaiting the shielded future, and restore the non-blocking timeout dance for the plain (non-TLS) socket branch.
On Python 3.15 (OpenSSL 3.x), a peer that resets the connection during
async KMS send/recv surfaces as BrokenPipeError/ConnectionResetError,
where older Pythons (OpenSSL 1.1.1) surfaced a clean EOF. Map these to
OSError("connection closed") in _async_blocking_socket_call so KMS
requests treat a reset as a retryable connection failure, matching the
behavior on earlier Pythons and the sync path. Fixes the async
TestKmsTLSOptions KMIP cases on Python 3.15.
PYTHON-6077
Changes in this PR
Test Plan
Checklist
Checklist for Author
Checklist for Reviewer