feat: add the experimental-API mark (functions, methods, properties) - #4279
Draft
TaiSakuma wants to merge 3 commits into
Draft
feat: add the experimental-API mark (functions, methods, properties)#4279TaiSakuma wants to merge 3 commits into
TaiSakuma wants to merge 3 commits into
Conversation
Implement step 1 of the API design in discussion scikit-hep#4197: an internal dual-form decorator, awkward._experimental.experimental, marking a public function, method, or property accessor as experimental, plus one new public name, awkward.errors.ExperimentalWarning. The mark derives everything user-visible from the decorated object (__qualname__, __module__), warns once per process per marked function on its first call (property: first access), and computes the warning's stacklevel by walking to the first frame outside awkward, so the warning is attributed to the caller's line even through @high_level_function() dispatch, including when a third-party array intercepts via __awkward_function__. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rename tests/test_experimental_mark.py to tests/test_4279_experimental_mark.py per the tests/test_XXXX_description.py convention. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files
|
|
The documentation preview is ready to be viewed at http://preview.awkward-array.org.s3-website.us-east-1.amazonaws.com/PR4279 |
Add two tests for awkward._experimental._find_stack_level: the currentframe()-returns-None fallback (implementations without stack-frame support) and the walk running off the top of the stack when every frame matches the package prefix. Line and branch coverage of src/awkward/_experimental.py is now 100%. Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
Implements step 1 of the implementation order proposed in discussion #4197 (design comment): the experimental mark for functions, methods, and properties — one shared wrapper.
One new public name:
awkward.errors.ExperimentalWarning, aUserWarningsubclass, because users reference it in warning filters. The decorator itself is internal (awkward._experimental.experimental).Behavior, as specified in the design comment:
@experimentaland@experimental()are equivalent; the decorator takes no arguments in the initial release (any argument raisesTypeError), and the parenthesized form is where configuration options can be added later.def, below@property/@classmethod/@staticmethod, so it always receives a plain function.__qualname__, the defining module from__module__.warningsfilter state and registry.stacklevelis computed by walking the stack to the first frame outside awkward (the pattern of pandas'find_stack_level), so the reported location stays on the user's line even through@high_level_function()dispatch; a fixed number would attribute it to_dispatch.py. The warning also fires when a third-party array intercepts the operation through__awkward_function__, because the dispatcher calls the wrapper eagerly.Example warning:
One interaction worth recording: the module-level
warnings.filterwarnings("default", module="awkward.*")inawkward._errorsmatches the frame a warning is attributed to, and this warning is attributed to user code, so that filter never governsExperimentalWarning— visibility comes fromUserWarning's default handling, and the once-per-process behavior from the wrapper's own state.No real API is marked in this PR; it is machinery and tests only. 19 tests were written first and pin the message text, the warn-once behavior (including under
simplefilter("always")and when the body raises), metadata preservation viafunctools.wraps(whichhigh_level_functiondepends on for the dispatch name), stacklevel attribution directly and through generator-style and plain-function dispatch, and the warning under interception.No docs change: sphinx-autoapi generates the class page automatically, matching the existing
awkward.errors.FieldNotFoundErrorprecedent.🤖 Generated with Claude Code