[fix] Python 3.14 PEP 649 annotation compatibility across inspect.signature() calls#14327
[fix] Python 3.14 PEP 649 annotation compatibility across inspect.signature() calls#14327lukasmasuch merged 8 commits intodevelopfrom
inspect.signature() calls#14327Conversation
On Python 3.14+, PEP 649 causes annotation evaluation to be deferred. When annotations reference types imported under TYPE_CHECKING, inspect.signature() raises NameError. This fix uses annotation_format=STRING to avoid evaluation since we only need parameter names and kinds. Co-Authored-By: Claude Opus 4.6 <[email protected]>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
✅ PR preview is ready!
|
There was a problem hiding this comment.
Pull request overview
Fixes a Python 3.14 (PEP 649) compatibility issue where @st.cache_data / @st.cache_resource could crash with NameError when introspecting decorated functions that use annotations referencing TYPE_CHECKING-only imports.
Changes:
- Added
_get_func_parameters()to retrieve signature parameters without forcing annotation evaluation on Python 3.14+. - Updated
_get_positional_arg_name()to use_get_func_parameters()instead of callinginspect.signature()directly. - Added unit tests for
_get_positional_arg_name()behavior and for the PEP 649 regression scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
lib/streamlit/runtime/caching/cache_utils.py |
Avoids PEP 649-triggered annotation evaluation during cache key construction by using annotation_format=Format.STRING on Python 3.14+. |
lib/tests/streamlit/runtime/caching/cache_utils_test.py |
Adds coverage for positional-arg name resolution and a Python 3.14-specific regression test for deferred annotations. |
The previous test used exec() which doesn't trigger PEP 649 deferred annotation behavior. Instead, create a function with a custom __annotate__ method that raises NameError when annotations are evaluated, which properly simulates the real PEP 649 behavior for undefined types. Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Update docstring to reference Format.STRING enum value (copilot suggestion) - Use Callable[..., Any] type annotation for func parameter instead of object, removing the need for type: ignore comment (copilot suggestion) Co-Authored-By: Claude Opus 4.6 <[email protected]>
SummaryThis PR fixes a Python 3.14 compatibility crash in The fix introduces a Changed files:
Code QualityAll three reviewers agree the implementation is clean, minimal, and well-targeted. Specific points of consensus:
Minor style note (non-blocking, all reviewers agree): Minor style note (non-blocking): Test CoverageAll reviewers agree the test coverage is strong and adequate:
Consensus: No E2E tests needed — this is a backend-only internal bug fix. Optional suggestion (from Backwards CompatibilityAll reviewers unanimously agree there are no backwards compatibility concerns:
Security & RiskAll reviewers agree: no security concerns. The change is purely about parameter introspection for cache key computation. No network, WebSocket, authentication, file serving, HTML/Markdown rendering, or external dependency changes. Risk is very low and localized to function signature introspection for cache key argument mapping. External test recommendation
AccessibilityNo frontend changes in this PR. No accessibility considerations apply. (All reviewers agree.) Recommendations
Reviewer Agreement
All three reviewers are in full agreement. No conflicts to resolve. VerdictAPPROVED: All three reviewers unanimously approve. The fix is clean, well-targeted, backwards-compatible, and includes strong test coverage for the Python 3.14 PEP 649 compatibility issue in cache decorators. No critical or blocking issues were raised. This is a consolidated AI review by 📋 Review by `gemini-3.1-pro`SummaryThis PR fixes a Code QualityThe code changes are well-structured, elegant, and adhere to the Streamlit Python guidelines. The new One minor note regarding imports: The Streamlit guidelines prefer importing entire modules instead of single functions ( Test CoverageThe changes are well-tested.
Backwards CompatibilityThe changes are fully backwards compatible. The new behavior is strictly gated behind a Security & RiskNo security concerns or regression risks identified. The changes are limited to inspecting function signatures for caching decorators and do not interact with any security-sensitive areas. External test recommendation
AccessibilityN/A - No frontend changes. RecommendationsNo changes required. The implementation and tests are solid. VerdictAPPROVED: The PR successfully fixes a Python 3.14 compatibility issue with caching decorators and includes excellent test coverage. This is an automated AI review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR fixes a Python 3.14 compatibility issue in cache decorators where deferred annotation evaluation (PEP 649) can raise Code QualityThe change is small, targeted, and maintainable.
No code-quality issues requiring changes were identified. Test CoverageCoverage for the modified behavior is good at the unit level.
Given the scope (internal caching utility behavior), unit tests are adequate. No e2e test additions are required for this change. Backwards CompatibilityNo breaking API changes were introduced.
This appears backwards compatible for existing Streamlit users. Security & RiskNo security-sensitive surfaces are modified (no auth/session transport, routing, cookie/CSRF logic, file serving, or frontend runtime execution changes). Regression risk is low and localized to function signature introspection used for cache key argument mapping. External test recommendation
AccessibilityNot applicable for this PR: no frontend UI, DOM, keyboard interaction, ARIA, or visual rendering changes. Recommendations
VerdictAPPROVED: The fix is focused, low risk, adequately unit-tested, and ready to merge. This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR fixes a Python 3.14 compatibility issue where The fix adds a Changed files:
Code QualityThe implementation is clean, minimal, and well-targeted:
Minor style note (non-blocking): In the test file, Test CoverageTest coverage is good:
One observation: There are no E2E tests for this change, which is acceptable since this is a backend-only internal bug fix that doesn't affect the frontend or any public API behavior visible in the UI. The unit tests adequately cover the fix. Backwards CompatibilityNo backwards compatibility concerns:
Security & RiskNo security concerns. This change is purely about parameter introspection for cache key computation. It does not touch:
The risk is very low. The worst case on a regression would be returning incorrect parameter names (affecting cache key uniqueness), but the implementation is straightforward and well-tested. Potential follow-up (outside scope of this PR): Other
These are separate issues and not blockers for this PR, but worth tracking. External test recommendation
AccessibilityNo frontend changes in this PR. No accessibility considerations apply. Recommendations
VerdictAPPROVED: Clean, well-targeted fix for Python 3.14 PEP 649 compatibility in cache decorators with good test coverage. The implementation is minimal, backwards-compatible, and follows project conventions. This is an automated AI review by |
On Python 3.14+, inspect.signature() can raise NameError for functions with TYPE_CHECKING-only annotations due to PEP 649 deferred evaluation. - st.help: Add NameError handling alongside ValueError - st.fragment: Add NameError to contextlib.suppress - metrics_util: Add NameError to contextlib.suppress Co-Authored-By: Claude Opus 4.6 <[email protected]>
SummaryThis PR fixes Python 3.14 compatibility issues caused by PEP 649 (deferred evaluation of annotations). When
Code QualityAll three reviewers agree: the code is clean, well-structured, targeted, and follows existing codebase patterns. The Comments explaining the PEP 649 rationale at each call site are justified — they document non-obvious intent. Unique observation (opus-4.6-thinking): Test CoverageAgreement: All reviewers agree the new tests in
Minor disagreement on test gaps:
Resolution: The gap is real but low-risk. Adding targeted tests for these paths in a follow-up would strengthen long-term regression protection, but should not block this PR. Backwards CompatibilityUnanimous agreement: No breaking changes. On Python < 3.14, all code paths remain identical. The added Security & RiskUnanimous agreement: No security concerns. Changes are limited to Python introspection and decorator metadata handling. No auth, session, routing, WebSocket, embedding, external resource, or code execution surfaces are modified. Regression risk is very low and localized. External test recommendationUnanimous agreement: No external test needed.
AccessibilityN/A — No frontend changes in this PR. Recommendations
Reviewer Consensus
All three reviewers approved unanimously. No critical or blocking issues were raised. VerdictAPPROVED: Clean, well-tested fix for Python 3.14 PEP 649 compatibility. All three reviewers approve unanimously. The changes are minimal, correctly scoped, backwards compatible, and carry no security or regression risk. Minor recommendations for follow-up test coverage are non-blocking. This is a consolidated AI review by 📋 Review by `gemini-3.1-pro`SummaryThis PR fixes compatibility issues with Python 3.14's implementation of PEP 649 (deferred evaluation of annotations). It addresses Code QualityThe code quality is excellent. The changes are targeted, well-commented, and use the correct Python 3.14+ API ( Test CoverageThe unit test coverage is comprehensive. The author added tests for Backwards CompatibilityThere are no backwards compatibility concerns. The changes only affect Python 3.14+ behavior and gracefully fall back to existing behavior on older Python versions. Security & RiskNo security concerns or regression risks identified. The changes are confined to metadata inspection and do not affect runtime execution logic, routing, or data handling. External test recommendationNo. The changes are purely related to Python 3.14 compatibility with AccessibilityN/A - No frontend changes. RecommendationsNo changes needed. The implementation is clean and well-tested. VerdictAPPROVED: The PR successfully fixes Python 3.14 compatibility issues with PEP 649 annotations in a clean and well-tested manner. This is an automated AI review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR addresses Python 3.14 PEP 649 compatibility issues at multiple Code QualityThe implementation is clean, targeted, and consistent with existing patterns:
No code quality issues were identified that should block merge. Test CoverageCoverage is directionally good for the caching path:
Potential gap (non-blocking): there is no new direct regression test for the new
Given the small and defensive nature of those changes, this is acceptable for merge, but adding targeted tests later would strengthen long-term regression protection. Backwards CompatibilityNo breaking changes found.
Security & RiskNo security concerns were identified.
External test recommendation
AccessibilityNo frontend/UI accessibility-impacting code was changed in this PR. Recommendations
VerdictAPPROVED: The patch is well-scoped, backward compatible, and addresses the Python 3.14 PEP 649 regression without introducing material security or compatibility risk. This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR fixes Python 3.14 compatibility across multiple The four affected locations are:
Code QualityThe code is clean, well-structured, and follows existing patterns in the codebase.
Exception handling additions: The Naming: Comments: The inline comments explaining the Minor observation: Test CoverageNew tests in
Test gaps: There are no dedicated unit tests for the The test file correctly follows the AGENTS.md guidelines: uses Backwards CompatibilityNo breaking changes. The code paths are fully backwards compatible:
Security & RiskNo security concerns. The changes are purely defensive error handling for a Python version compatibility issue. No network, auth, embedding, or external resource changes are involved. The Regression risk: Very low. The changes are narrow in scope and well-guarded by version checks and exception handling. External test recommendation
AccessibilityNot applicable — no frontend changes in this PR. Recommendations
VerdictAPPROVED: Clean, well-tested fix for Python 3.14 PEP 649 compatibility that addresses all This is an automated AI review by |
- Move get_func_parameters to type_util.py to avoid duplication - Add _get_arg_keywords in metrics_util.py for PEP 649-safe arg parsing - Add comprehensive tests for st.help, st.fragment, and metrics_util Co-Authored-By: Claude Opus 4.6 <[email protected]>
On Python 3.14, inspect.getfullargspec() catches NameError from
annotation evaluation and re-raises as TypeError("unsupported callable").
Update the test to accept both exception types.
Also consolidates the _get_func_parameters wrapper into type_util.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
SummaryThis PR fixes Python 3.14 compatibility across multiple Changed files:
Code QualityThe code is clean, well-structured, and follows Streamlit's established patterns. All three reviewers agreed on this.
Point of disagreement —
Resolution: Gemini is technically correct. CPython's Test placement ( Test CoverageAll reviewers agreed that test coverage is strong. Each changed call site has a corresponding test that:
Tests are appropriately gated with Minor observation (non-blocking): The Backwards CompatibilityAll reviewers agreed: no breaking changes. On Python < 3.14, code takes the existing Security & RiskAll reviewers agreed: no security concerns. Changes are purely internal Python introspection fixes with no networking, auth, WebSocket, CORS, session, or user-data handling impact. Regression risk is low. External test recommendation
AccessibilityNo frontend changes. Accessibility is not impacted. (All reviewers agreed) Recommendations
Reviewer Consensus
All expected models completed their reviews successfully. Areas of agreement (all 3 reviewers):
Areas of disagreement (resolved above):
VerdictAPPROVED: The majority of reviewers (2/3) approved, and the issue raised by gemini-3.1-pro — while technically correct — is non-blocking: it affects no current Streamlit code (no functions use positional-only syntax), is a one-line fix, and is better addressed as a follow-up nit. The PR is a well-structured, well-tested compatibility fix with low risk and no security or backwards-compatibility concerns. This is a consolidated AI review by 📋 Review by `gemini-3.1-pro`SummaryThis PR fixes compatibility issues with Python 3.14's PEP 649 deferred annotation evaluation. It introduces a centralized Code QualityThe code changes are well-structured and the centralized helper in
Test CoverageThe changes are well-tested. The author added specific tests using mocked Backwards CompatibilityThe changes are backwards compatible and only affect internal reflection and telemetry mechanisms. The use of Security & RiskNo security concerns or regression risks identified. The changes are confined to internal reflection and do not affect security-sensitive areas. External test recommendation
AccessibilityN/A Recommendations
VerdictCHANGES REQUESTED: Please fix the missing This is an automated AI review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR hardens Python 3.14 compatibility for PEP 649 deferred annotations at all current Code QualityThe changes are focused, minimal, and consistent with existing patterns:
No code-quality blockers were identified. Test CoverageCoverage is strong for the changed behavior:
Tests are appropriately gated with Backwards CompatibilityNo breaking API changes were detected:
This should be backwards compatible for existing users. Security & RiskNo security concerns were identified in this diff:
Primary risk is low and limited to metadata/signature introspection behavior in Python runtime utilities. External test recommendation
AccessibilityNo frontend/UI code was changed, so no new accessibility risks were introduced by this PR. Recommendations
VerdictAPPROVED: The PR addresses the Python 3.14 PEP 649 failure mode comprehensively across current This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR fixes Python 3.14 compatibility across multiple Changed files:
Code QualityThe code is clean, well-structured, and follows Streamlit's established patterns:
No issues identified. Test CoverageTest coverage is thorough and well-designed:
All tests use Each test verifies both the precondition (that Minor note: Local imports of Backwards CompatibilityNo breaking changes. The PR is fully backwards compatible:
Security & RiskNo security concerns. This PR:
Regression risk is low. The changes are defensive in nature (catching a new exception type) and version-gated. The fallback behavior on pre-3.14 Python is unchanged. External test recommendation
AccessibilityNo frontend changes are included in this PR. Accessibility is not impacted. RecommendationsNo blocking issues found. The implementation is clean, well-tested, and follows established patterns. A few minor observations (non-blocking):
VerdictAPPROVED: Well-structured bug fix for Python 3.14 PEP 649 compatibility with a centralized helper function, correct version gating, thorough test coverage, and no backwards compatibility or security concerns. This is an automated AI review by |
inspect.signature() calls
…docs Address PR review recommendations: - Include POSITIONAL_ONLY parameters in _get_arg_keywords() to fully match getfullargspec().args behavior (fixes potential telemetry arg mapping bug) - Update get_func_parameters() docstring to note that annotations are strings on Python 3.14+ - Move get_func_parameters PEP 649 test to type_util_test.py for better organization - Add test for positional-only parameter handling Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
|
||
| See: https://github.com/streamlit/streamlit/issues/14324 | ||
| """ | ||
| from streamlit import type_util |
There was a problem hiding this comment.
nit: Remove this redundant import statement.
|
|
||
| On Python 3.14+, inspect.signature() raises NameError for annotations | ||
| referencing types imported under TYPE_CHECKING. Our fix uses | ||
| annotation_format=STRING to avoid evaluation. |
There was a problem hiding this comment.
nit: This should be annotation_format=Format.STRING
| st.help(st, width=width) | ||
|
|
||
|
|
||
| @pytest.mark.skipif( |
There was a problem hiding this comment.
suggestion (non-blocking): All of these PEP 649 tests seem to be similar in structure, consider a shared test helper to reduce duplicative test code.
There was a problem hiding this comment.
Added a shared helper method 👍
- Move type_util import to top-level in metrics_util.py - Fix docstring to use `annotation_format=Format.STRING` - Create shared `create_pep649_function()` helper in testutil.py - Refactor all PEP 649 tests to use the shared helper Co-Authored-By: Claude Opus 4.6 <[email protected]>
6ed9102 to
a9904e6
Compare
Describe your changes
Fixes Python 3.14 PEP 649 compatibility across multiple
inspect.signature()call sites. On Python 3.14+, deferred annotation evaluation can raiseNameErrorfor functions using type annotations that reference types imported underif TYPE_CHECKING:.Implementation:
get_func_parameters()helper intype_util.pywithannotation_format=Format.STRINGon Python 3.14+_get_arg_keywords()helper inmetrics_util.pyfor PEP 649-safe argument name extractionFixed locations:
@st.cache_data/@st.cache_resource— Usestype_util.get_func_parameters()st.help()— AddedNameErrorhandling in_get_signature()@st.fragment— AddedNameErrortocontextlib.suppress()_get_arg_keywords()and addedNameErrortocontextlib.suppress()GitHub Issue Link (if applicable)
Testing Plan
lib/tests/streamlit/runtime/caching/cache_utils_test.py— Testsget_func_parameters()via_get_positional_arg_name()with PEP 649 simulationlib/tests/streamlit/elements/help_test.py— Tests_get_signature()handling of PEP 649 annotationslib/tests/streamlit/runtime/fragment_test.py— Tests fragment decorator handling of PEP 649 annotationslib/tests/streamlit/runtime/metrics_util_test.py— Tests_get_arg_keywords()andgather_metrics()decorator handlingContribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
Agent metrics