feat(enrichment): add missing-deprecation rule#351
feat(enrichment): add missing-deprecation rule#351Alberto-Codes wants to merge 3 commits intomainfrom
Conversation
Adds a new enrichment rule that detects deprecated functions whose docstrings omit a deprecation notice. Fires when a function calls warnings.warn(..., DeprecationWarning/PendingDeprecationWarning/FutureWarning) at its top scope or carries a @deprecated decorator (any form), and the docstring does not contain the word "deprecated" (case-insensitive). Scope-aware AST walk prevents false positives from nested defs/classes.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds a new enrichment rule (missing-deprecation) to detect deprecated functions that don’t mention deprecation in their docstring, along with a config toggle, tests, and documentation updates.
Changes:
- Implement
missing-deprecationrule in enrichment (AST-based detection forwarnings.warn(..., DeprecationWarning|PendingDeprecationWarning|FutureWarning)and@deprecateddecorator forms). - Add
require-deprecation-noticetoggle toEnrichmentConfig, including TOML formatting + docs. - Add comprehensive unit tests and register the rule in the rules catalog + docs site.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/docvet/checks/enrichment.py |
Implements the missing-deprecation rule + wires it into enrichment dispatch. |
src/docvet/config.py |
Adds require_deprecation_notice config field, valid key, and TOML rendering support. |
tests/unit/checks/test_missing_deprecation.py |
New unit tests covering warning/decorator variants, nesting behavior, and config gating. |
docs/rules.yml |
Registers the new rule in the canonical rules registry. |
tests/unit/test_docs_infrastructure.py |
Updates expected rules count to reflect the new rule. |
docs/site/rules/missing-deprecation.md |
New rule reference page. |
docs/site/configuration.md |
Documents the new require-deprecation-notice option and updates the full example. |
_bmad-output/implementation-artifacts/sprint-status.yaml |
Updates sprint/story status metadata. |
_bmad-output/implementation-artifacts/35-2-missing-deprecation-enrichment-rule.md |
Adds story implementation artifact detailing ACs, tasks, and verification. |
.claude/rules/gh-discussions.md |
Adds internal reference notes for GitHub Discussions GraphQL workflows. |
- Add import warnings to fix example in docs/rules.yml (Copilot) - Add missing-deprecation entry to _RULE_CATALOG in mcp.py; update unit and integration test counts 22→23 (Copilot) - Add tests for chained-attribute and non-warnings-module warn calls to cover lines 1971/1973 in _is_warnings_warn_call (Codecov)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
tests/unit/test_mcp.py:555
- The MCP rule catalog tests are now updated to 23 rules, but the repo defines 25 rule ids in docs/rules.yml and there are implemented checks for additional rules (notably
missing-returnsandoverload-has-docstring). Ifdocvet_rulesis intended to be comprehensive, these assertions should be updated to include the missing rule names and the expected count adjusted accordingly.
def test_rule_catalog_has_expected_count(self):
assert len(_RULE_CATALOG) == 23
def test_rule_catalog_entries_have_required_keys(self):
expected_keys = {
"name",
"check",
"description",
"category",
"guidance",
"fix_example",
}
for entry in _RULE_CATALOG:
assert set(entry.keys()) == expected_keys
def test_rule_catalog_names_match_emitted_rules(self):
expected_rules = {
# presence (1)
"missing-docstring",
# enrichment (13)
"missing-raises",
"missing-yields",
"missing-receives",
"missing-warns",
"missing-other-parameters",
"missing-attributes",
"missing-typed-attributes",
"missing-examples",
"missing-cross-references",
"prefer-fenced-code-blocks",
"missing-param-in-docstring",
"extra-param-in-docstring",
"missing-deprecation",
# freshness (5)
"stale-signature",
"stale-body",
"stale-import",
"stale-drift",
"stale-age",
# coverage (1)
"missing-init",
# griffe (3)
"griffe-unknown-param",
"griffe-missing-type",
"griffe-format-warning",
}
catalog_names = {entry["name"] for entry in _RULE_CATALOG}
assert catalog_names == expected_rules
- Update docs/rules.yml header comment 24→25 rules (Copilot) - Simplify missing-deprecation fix_example in _RULE_CATALOG to docstring-only fragment for consistency with other enrichment entries; removes incomplete warnings.warn call (Copilot) - Start _has_deprecation_warning_call traversal from node.body instead of ast.iter_child_nodes(node) so decorators/annotations are not walked; add explicit list[ast.AST] annotation for type safety (Copilot)
| @@ -0,0 +1,214 @@ | |||
| # GitHub Discussions API Reference | |||
|
|
|||
| Working patterns for GitHub Discussions via `gh api graphql`. The REST API and `gh discussion` CLI command do NOT support discussions — GraphQL is the only path. | |||
There was a problem hiding this comment.
This file says “The REST API … do NOT support discussions — GraphQL is the only path.”, but later claims a REST endpoint works for reading discussions. Please reconcile these statements (either remove the REST claim or clarify what is/িসn’t supported and under which conditions).
| Working patterns for GitHub Discussions via `gh api graphql`. The REST API and `gh discussion` CLI command do NOT support discussions — GraphQL is the only path. | |
| Working patterns for GitHub Discussions via `gh api graphql`. For creating or updating discussions, the REST API and `gh discussion` CLI command do NOT support the required operations — GraphQL is the only path for write actions. Limited read-only access to discussions may be available via specific REST endpoints, as documented below. |
| # GitHub Discussions API Reference | ||
|
|
||
| Working patterns for GitHub Discussions via `gh api graphql`. The REST API and `gh discussion` CLI command do NOT support discussions — GraphQL is the only path. | ||
|
|
There was a problem hiding this comment.
The PR metadata focuses on adding the missing-deprecation enrichment rule, but this PR also adds an internal GitHub Discussions API reference under .claude/rules/. If this is intentional, please mention it in the PR description; otherwise, consider moving it to a separate PR to keep the change focused and easier to review/revert.
| ## Key IDs | ||
|
|
||
| These are stable — no need to look them up each session: | ||
|
|
||
| - **Repository ID**: `R_kgDORLG_EQ` | ||
| - **Announcements category ID**: `DIC_kwDORLG_Ec4C3lBx` | ||
| - **General category ID**: `DIC_kwDORLG_Ec4C3lBy` | ||
| - **Ideas category ID**: `DIC_kwDORLG_Ec4C3lB0` | ||
| - **Polls category ID**: `DIC_kwDORLG_Ec4C3lB2` | ||
| - **Q&A category ID**: `DIC_kwDORLG_Ec4C3lBz` | ||
| - **Show and tell category ID**: `DIC_kwDORLG_Ec4C3lB1` | ||
|
|
There was a problem hiding this comment.
These hard-coded repository/category/discussion node IDs are specific to this repository and will be wrong in forks or if categories are reorganized. Consider adding an explicit note that they are docvet-repo-specific (and/or include a short “how to look them up” snippet) so readers don’t treat them as universally stable.
|
Closing in favor of #353 which covers the same feature with additional improvements: 34 tests (vs 25), CC refactoring via |
docvet had no way to detect deprecated functions whose docstrings omit a deprecation notice, leaving callers unaware they should migrate. This adds the
missing-deprecationenrichment rule to close that gap._check_missing_deprecationwith scope-aware AST walk detectingwarnings.warn(..., DeprecationWarning/PendingDeprecationWarning/FutureWarning)and all@deprecateddecorator forms (bare, dotted, call)require_deprecation_notice: bool = TruetoEnrichmentConfig, wirerequire-deprecation-noticeconfig key through_VALID_ENRICHMENT_KEYSandformat_config_toml@pytest.mark.parametrizeacross all warning categories and decorator forms; cross-rule interaction test verifies no dispatch conflictsdocs/site/rules/missing-deprecation.mdrule reference page, register indocs/rules.yml, addrequire-deprecation-noticeto enrichment options table and complete example indocs/site/configuration.mdTest:
uv run pytest tests/unit/checks/test_missing_deprecation.py -vPR Review
Checklist
uv run pytest)uv run ruff check .)uv run ty check)!in title andBREAKING CHANGE:in bodyReview Focus
_has_deprecation_warning_call(AC6 — stops at nestedFunctionDef/AsyncFunctionDef/ClassDef)_has_deprecated_decoratorcovering all 4 forms including PEP 702 call forms_SPHINX_AUTO_DISABLE_RULES— detection is code-AST-based, style-agnosticRelated
missing-param-in-docstring/extra-param-in-docstring) established the_RULE_DISPATCHtwo-entry convention and parametrize mandate followed here