Enforce keyword-only arguments for API methods with multiple options #545
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.
Keyword-Only Arguments: Improving API Clarity
What are keyword-only arguments?
Keyword-only arguments (introduced in Python 3 via PEP 3102) are function parameters that must be passed by name, not by position. They use the
*separator in function signatures:Why use keyword-only arguments?
For methods with multiple optional configuration parameters, keyword-only arguments dramatically improve code readability:
This prevents errors from parameter order confusion and makes code self-documenting.
User Experience: Deprecation Phase (v1.4)
When users pass optional parameters positionally, they'll see a helpful warning:
The code still works—users just get guidance to update their usage. Since all current test usage is already keyword-based, most users won't see any warnings.
Implementation: Two-Phase Approach (SLEP009)
Following scikit-learn's enhancement proposal SLEP009:
Phase 1 (v1.4 - this PR):
@_deprecate_positional_argsdecorator to methods with 2+ optional parametersFutureWarningwhen options passed positionallyPhase 2 (v2.0 - future):
*to function signaturesTypeErrorMethods Updated
Core Comparison API (4 methods):
Comparer.sel()- 5 optional filter parametersComparer.gridded_skill()- 5 optional configuration parametersComparerCollection.sel()- 7+ optional filter parametersComparerCollection.gridded_skill()- 5 optional configuration parametersSkill Assessment API (3 methods):
SkillTable.sel()- 2 optional parameters + kwargsSkillTable.style()- 4 optional formatting parametersSkillArrayPlotter.grid()- 7 optional display parametersPlotting API (4 methods):
ComparerPlotter.kde()- 3 optional display parametersComparerPlotter.residual_hist()- 5 optional plotting parametersComparerCollectionPlotter.spatial_overview()- 3 optional display parametersComparerCollectionPlotter.temporal_coverage()- 5 optional display parametersTotal: 12 methods updated
Why These Methods?
Methods were selected based on:
Methods with single optional parameters or semantically distinct parameters (like
skill(by, metrics)) were intentionally excluded.Migration Path
Users seeing warnings should update their code:
Related: Follows the pattern established by scikit-learn, scipy, and xgboost for gradual API improvements with clear user guidance.