Python: fix(core): point @experimental warnings at user code, not stdlib internals#5996
Open
eavanvalkenburg wants to merge 2 commits into
Open
Conversation
…rnals Previously the wrappers installed by @experimental called warnings.warn with a fixed stacklevel=3. ABCMeta inserts an extra abc.__new__ frame when an experimental ABC is subclassed, so the warning landed inside abc.py (or <frozen abc>:106 on modern CPython) instead of the user's class Sub(...) line. Resolve the user frame by walking inspect.currentframe(), skipping frames whose module name is abc/functools/typing/contextlib (or submodules), then emit via warnings.warn_explicit so the recorded filename/lineno point at user code. Falls back to warnings.warn with stacklevel=2 if no user frame is found. Module-name matching is used because frozen stdlib modules report '<frozen abc>' as their filename. Also install a one-line warnings.formatwarning specifically for FeatureStageWarning so 'file:line: ExperimentalWarning: [ID] Name ...' prints without the secondary source-snippet line. Other categories delegate to the stdlib default formatter unchanged. Added a regression test that subclasses an @experimental ABC inside warnings.catch_warnings and asserts the recorded filename equals the test file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts Python feature-stage warning emission so @experimental warnings are attributed to the user’s callsite (not stdlib/internal frames), including the ABC subclassing case that previously surfaced as <frozen abc>:....
Changes:
- Replaces fixed
stacklevelwarning emission with a stack frame walker that resolves a “user” frame and emits viawarnings.warn_explicit. - Installs a custom
warnings.formatwarningimplementation to renderFeatureStageWarningcategories as single-line warnings. - Adds a regression test covering subclassing an
@experimentalABC and asserting the warning filename points at the test/user file.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/core/agent_framework/_feature_stage.py | Resolves user frames for warnings, switches to warn_explicit, and installs a single-line formatter for feature-stage warnings. |
| python/packages/core/tests/core/test_feature_stage.py | Adds regression coverage for ABC subclass warning attribution. |
moonbox3
approved these changes
May 21, 2026
- Make _install_feature_stage_formatter idempotent: tag the installed formatter with a marker attribute and short-circuit re-installation, so re-imports/reloads don't wrap the formatter on top of itself. Also expose the previous formatter via __wrapped__ for restoration. - Avoid leaking frame references in _resolve_user_frame: capture data into plain locals inside try and del frame/candidate in finally, per CPython's guidance on inspect.currentframe usage. - Drop redundant _WARNED_FEATURES.clear() in the new ABC subclass test (the autouse fixture already handles it). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
When an
@experimentalABC is subclassed (e.g.MemoryStore,SkillResource), the emittedExperimentalWarningwas attributed to internal stdlib frames instead of the user's code. On modern CPython this surfaced as:The cause: the wrappers installed by
@experimentalcalledwarnings.warnwith a fixedstacklevel=3, butABCMetainserts an extraabc.__new__frame for ABC-driven class creation, so the warning landed insideabc.py(or<frozen abc>:106) rather than the user'sclass Sub(...)line.Raised as a follow-up to a review comment on #5958.
Description
stacklevelwith a frame walker (_resolve_user_frame) that starts atinspect.currentframe()and skips frames belonging to this module plusabc/functools/typing/contextliband their submodules. The skip list is matched onframe.f_globals['__name__']rather than__file__, because frozen stdlib modules report<frozen abc>as the filename.warnings.warn_explicitat the resolved(filename, lineno, module)so recorded warnings point at user code; fall back towarnings.warn(stacklevel=2)only if no user frame is found.warnings.formatwarningspecifically forFeatureStageWarningso the output isfile:line: ExperimentalWarning: [FEATURE_ID] Name is experimental ...with no secondary source-snippet line (the class/function name is already in the message). Other warning categories delegate to the stdlib default formatter unchanged.@experimentalABC insidewarnings.catch_warningsand asserts the recorded filename equals the test file.Contribution Checklist