test(appsec): enable appsec_integrations_fastapi on Python 3.15 - #19853
Conversation
The fastapi==0.86.0 sub-venv was the only one still capped at 3.13. It resolves pydantic 1.10.26, which ships a pure py3 wheel, so it installs and passes on 3.14 and 3.15; lift the cap. mcp 1.20.0 imports pydantic._internal._typing_extra.eval_type_backport, removed on pydantic main, so it cannot coexist with any pydantic that supports 3.15; bump to 1.21.2 (1.24+ answers 421 to the SSE tests' Host header). pydantic ~=2.12.1 can never resolve a cp315 wheel, so widen it to ~=2.12. Lockfiles regenerated. tests/conftest.py asserted crashtracking.is_started() on Linux, but setup.py drops the Rust crashtracker on 3.15, so every test in the repo errored at setup there. Guard on crashtracking.is_available; test_crashtracker_available still asserts it loudly. APPSEC-69809 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
BenchmarksBenchmark execution time: 2026-08-25 13:59:49 Comparing candidate commit 2f9302c in PR branch Found 0 performance improvements and 8 performance regressions! Performance is the same for 575 metrics, 10 unstable metrics, 2 known flaky benchmarks, 16 flaky benchmarks without significant changes.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f9302cd01
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
6ba690d
into
main
Codeowners resolved asResolved from the full PR diff against No remaining files require a CODEOWNERS review. |
Dependency direction analysis
|
Circular import analysis
|
Description
Part of the Python 3.15 integration parity effort (parent tracker: #17809).
Closes #17844
APPSEC-69809
This PR enables the
appsec_integrations_fastapisuite on Python 3.15.There was no single upstream pin to bump. The row's own premise ("real blocker is likely IAST
runtime") was resolved by #19698, and the issue text is partly stale: it lists two capped
sub-venvs (
==0.86.0,==0.94.1), but #19620 replaced the0.94.1one with==0.141.1on["3.10", "3.14"], leaving only==0.86.0capped atmax_version="3.13". That cap turned out tobe liftable — fastapi 0.86.0 resolves
pydantic 1.10.26, which publishes a purepy3wheel, so itinstalls and passes on both 3.14 and 3.15. The remaining work was unpinning the two dependencies
that can never resolve on 3.15, and fixing a
tests/conftest.pyfixture that makes every test inthe repository error at setup on 3.15.
Changes
riotfile.pyfastapi==0.86.0venv:select_pys(min_version="3.9", max_version="3.13")→select_pys(min_version="3.9").mcp:==1.20.0→==1.21.2. mcp 1.20.0 importspydantic._internal._typing_extra.eval_type_backport, which pydantic removed onmain, so the pinned mcp cannot coexist with any pydantic that supports 3.15. 1.24+ was rejected: its transport-security middleware answers421 Misdirected Requestto the SSE tests'0.0.0.0Host header (4 failures). 1.21.2 is the first release that drops the private import while keeping the API the tests use.pydantic:~=2.12.1→~=2.12. 2.12.x has no cp315 wheels and never will, so a minor-locked pin blocks 3.15 permanently. The>=2.12floor (first release with cp314 wheels, added in ci(tests): enable Python 3.14 integration tests for IAST #15657) is preserved..riot/requirements/: regenerated — 11 added, 10 removed. The 7 unaffected venvs keep their existing lockfiles.pydanticresolves to 2.13.4 on 3.10–3.14 today.tests/conftest.py: the autouseenable_crashtrackingfixture assertedcrashtracking.is_started()on Linux, butsetup.pygates the Rust crashtracker feature onsys.version_info < (3, 15). On 3.15 the native module is absent, so the assert fired at setup for every test in the repo, not just this suite. Now gated oncrashtracking.is_available. This exact guard was already recorded as a hand-off item in the IAST 3.15 work (APPSEC-69649).No
ddtraceruntime code changed — the fastapi and IAST integration code needed nothing for 3.15.Checklist
Bumped upstream pin in— partially N/A.riotfile.pyto a version that supports Python 3.15mcpandpydanticwere unpinned/bumped as described above, but no upstream release fixes the actual 3.15 blocker yet (see Risks).max_version="3.13"cap on thefastapi==0.86.0venv..riot/requirements/*.txtlockfiles (11 added, 10 removed). Verified all 18 venvs of the suite resolve to a lockfile, and that all 1887 venvs repo-wide still do.scripts/run-tests; see the caveat there.Updated— N/A. Re-ransupported_versions.jsonscripts/integration_registry/generate_supported_versions.py: no diff, since the tested fastapi versions are unchanged.changelog/no-changelog(test/CI-only changes).Testing
Suite:
tests/appsec/integrations/fastapi_tests/. CPython 3.15.0rc1+dev (pyenv install 3.15-dev,matching
.python-versionand.gitlab/testrunner.yml), with #17849 stacked in a scratch worktree toget past the
import ddtraceblocker andrequires-pythonlocally widened sopip install -e .wouldrun. Neither local-only edit is in this PR.
main)The 3.14 legs were installed straight from the regenerated lockfiles (
13b41ca,f4ebe37,1db4c48)with the
ddtracepytest plugin active, i.e. what CI will run. 3.14 and 3.15 give identical counts onthe latest-fastapi venv.
scripts/lint fmt,style,riot, andsuitespec-checkall pass.Why raw
pytestfor these runs.AGENTS.mdsays never to invoke pytest directly, and I triedriot first. Two things block it: (a) riot cannot target 3.15 at all —
riotfile.py'sSUPPORTED_PYTHON_VERSIONSandscripts/gen_gitlab_config.py'sALL_PYTHON_VERSIONSboth stop at3.14 and there are zero 3.15 lockfiles; (b)
scripts/run-testsis currently broken on my host forthis suite regardless of version — riot builds derived venvs under
lib/python3.12(the interpreterriot itself runs on inside the testrunner image) while the
pytestshim resolves the target'ssite-packages, so every venv dies withModuleNotFoundError: No module named '_pytest'in the buildphase. That reproduces on both
13b41ca(3.14) and1f61c7b(3.13), including after deleting thederived venvs, so it is not caused by this PR. The
env=/pkgs=blocks were replicated by hand fromthe venv specs; the 3.14 legs used the committed lockfiles verbatim.
Risks
in CI:
pydantic-core 2.48.0ships cp315 wheels, but no pydanticrelease pins it — 2.13.4 pins
pydantic-core==2.46.4, whose PyO3 0.26 caps at 3.14 and whichfails to build from source (also under
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1, since abi3 modedrops the datetime APIs it needs). pydantic
mainpins 2.48.0, so the next release unblocks this.Upstream: Add support for Python 3.15 pydantic/pydantic#13173. This is why the 3.15 leg above used pydantic from git
main(2.14.0b1) — the only 3.15-capable combination that exists today.
tests/smoke_test.py,tests/lib-injection) green → flip cp315 wheel job fromallow-failto required #17816), andrequires-pythonis still capped at<3.15.pydanticmoves 2.12.x → 2.13.4 andmcp1.20.0 → 1.21.2on 3.10–3.14. Both validated on 3.14 across all three fastapi venvs; CI covers 3.10–3.13.
tests/conftest.pyguard is repo-wide, not suite-scoped. It cannot mask a crashtrackerpackaging regression:
tests/crashtracker/test_crashtracker.py::test_crashtracker_availablestillasserts
crashtracking.is_availableon Linux and fails loudly if the native module goes missing.0.86.0cap adds one new CI venv (that venv on 3.14); validated above.Additional Notes
Hand-off for the tracer-wrapping /
ci_visibility3.15 owners. Once #17849 lands, theddtracepytest plugin will fail to import on 3.15 and no suite will be runnable: that branch stops defining
INJECTION_ASSEMBLYinddtrace/internal/bytecode_injection/__init__.pyon 3.15 (it takes thesys.monitoringpath instead), butddtrace/internal/coverage/import_instrumentation_py3_12.py:9imports it unconditionally, so plugin load dies with
ImportError: cannot import name 'INJECTION_ASSEMBLY'. I worked around it locally with-p no:ddtrace. This belongs to #17849 or theci_visibilityrows (#17838–#17842), not here.Follow-up worth filing separately (not 3.15-specific). When pydantic 2.14 releases, the
fastapi ~=0.114.2venv — which has no pydantic pin — will resolve it on every Python version, andthat combination breaks
mcp==1.20.0. Themcp==1.21.2bump in this PR removes that latentbreakage from this suite, but other suites pinning old
mcpmay still be exposed.