chore(compat): MAX_PY=3.14 last-supported, NEXT_MAX_PY=3.15 fail-closed (PROF-14439) - #19928
chore(compat): MAX_PY=3.14 last-supported, NEXT_MAX_PY=3.15 fail-closed (PROF-14439)#19928vlad-scherbich wants to merge 20 commits into
Conversation
Circular import analysis
|
Dependency direction analysis
|
Codeowners resolved asResolved from the full PR diff against |
dff1fad to
1d382ed
Compare
9be2db6 to
b142960
Compare
BenchmarksBenchmark execution time: 2026-08-30 03:22:39 Comparing candidate commit 57ccbdc in PR branch Found 0 performance improvements and 7 performance regressions! Performance is the same for 578 metrics, 10 unstable metrics, 3 known flaky benchmarks, 15 flaky benchmarks without significant changes.
|
cc2e9df to
f7e0135
Compare
b142960 to
a2f5c63
Compare
f7e0135 to
bd4659f
Compare
a2f5c63 to
3f0ff70
Compare
|
bd4659f to
39cfe79
Compare
Centralize the 3.15 wiring bound and the 3.16 fail-closed bound so wrap() can keep raising on 3.15 while NEXT_PY means first unsupported.
3f0ff70 to
c8b4968
Compare
inject_hook is monitoring-based on 3.15 and no longer raises.
…XT_MAX We support a range of CPythons; MAX is the upper bound we code against and NEXT_MAX is the first past that.
Fail-closed wrap/lazy sites use PY_GTE_MAX (one TODO to flip to NEXT_MAX after 3.15 GAs). SSI and WrappingContext use NEXT_MAX.
There was a problem hiding this comment.
Pull request overview
This PR standardizes Python version bound constants in ddtrace.internal.compat by introducing MAX_PY_VERSION / NEXT_MAX_PY_VERSION and derived predicates (PY_GTE_MAX, PY_GTE_NEXT_MAX), then updates internal call sites and tests to use these shared checks (including wrapping fail-closed behavior and injection runtime allow-listing).
Changes:
- Add MAX/NEXT_MAX version constants + predicates to
ddtrace.internal.compat. - Replace ad-hoc version comparisons with shared predicates in wrapping-related code paths and tests.
- Align injection bootstrap runtime allow-list upper bound with
NEXT_MAX_PY_VERSION_INFO.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
ddtrace/internal/compat.py |
Adds MAX/NEXT_MAX constants and PY_GTE_* predicates (with updated exports). |
ddtrace/internal/wrapping/__init__.py |
Switches wrap/wrap_bytecode fail-closed gate to PY_GTE_MAX. |
ddtrace/internal/wrapping/context.py |
Switches the 3.16+ fail-closed import-time gate to PY_GTE_NEXT_MAX. |
ddtrace/internal/module.py |
Updates lazy-module behavior gating to PY_GTE_MAX. |
ddtrace/internal/monitoring.py |
Replaces 3.15+ import guard with a MAX-based guard/message. |
ddtrace/internal/coverage/instrumentation_py3_12.py |
Replaces hardcoded 3.15 boundaries with MAX_PY_VERSION_INFO for PEP 810-related behavior. |
lib-injection/sources/sitecustomize.py |
Sets injection runtime exclusive upper bound to (3, 16) via NEXT_MAX_PY_VERSION_INFO. |
tests/internal/test_py315_import_degrade.py |
Adds assertions for the new constants/predicates and updates skipifs to use PY_GTE_MAX. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
MAX is a support bound; a later bump must not retie CPython API floors.
Compare to MAX/NEXT_MAX_INFO at call sites so __all__ is not a second pile of version names.
mypy only narrows sys.version_info against literals, so named aliases left sys.monitoring reachable under python_version 3.10.
Monitoring inject_hook already works. The wrap raise tests are skipif below NEXT and would demand a raise after wrap lift; they do not pin this PR error-string change. (cherry picked from commit 08c8693)
The SSI max bump does not need a bandit/mypy skip of lib-injection/. (cherry picked from commit 0cf5c73)
(cherry picked from commit cbe119a)
Lint extra bytecode==0.18.1 on 3.15 is not the runtime dep bytecode>=0.19.0. Leave both; they are different extras. (cherry picked from commit 5bd7d37)
Drop it once the testrunner 3.15 interpreter is 3.15.0rc1+, when Cython 3.3 cp315 wheels no longer SIGSEGV. (cherry picked from commit fbea5a1)
httplib, dbapi, subprocess, and detect_global_locks wrap and share GitLab --exitfirst jobs. wrap() still raises on 3.15 on this stack. (cherry picked from commit 79d6534)
NEXT_MAX_PY is 3.15 (packaging). wrap() and lazy must match merged #19910: trampoline and WrappingContext are live on 3.15, fail closed from 3.16. A rebase onto main must not re-disable wrap on 3.15.
Lint extra bytecode==0.18.1 conflicts with runtime bytecode>=0.19.0 when uv resolves extras for requires-python that includes 3.15. (cherry picked from commit cac61ca)
Description
Delta vs #19906.
MAX_PY is (3, 14) (last officially supported; matches requires-python <3.15). NEXT_MAX_PY is derived from MAX_PY as (3, 15). wrap/lazy do not raise at NEXT_MAX_PY; they match merged #19910 (trampoline / WrappingContext on 3.15) and fail-close at 3.16. PY_315_VERSION_INFO is the CPython API floor and is never aliased to MAX_PY. After 3.15 GAs, bump MAX_PY to (3, 15).
WrappingContext raises at 3.16 (monitoring already works on 3.15). SSI exclusive max is 3.16 so 3.15 injection remains (#19843).
Testing
Constants pin MAX_PY=(3, 14), NEXT_MAX_PY=(3, 15), PY_315=(3, 15) and not aliased to MAX_PY. wrap() runs on 3.15; monkeypatch pins fail-close at 3.16.
Risks
None.
Additional Notes
Does not change requires-python. SSI/WrappingContext use 3.16, not NEXT_MAX_PY.
No release note: internal constants, changelog/no-changelog.