Skip to content

feat: suppress implicit-any-parameter for underscore-prefixed params#3574

Open
MD-Mushfiqur123 wants to merge 3 commits into
facebook:mainfrom
MD-Mushfiqur123:fix/issue-3542-underscore-unused-vars
Open

feat: suppress implicit-any-parameter for underscore-prefixed params#3574
MD-Mushfiqur123 wants to merge 3 commits into
facebook:mainfrom
MD-Mushfiqur123:fix/issue-3542-underscore-unused-vars

Conversation

@MD-Mushfiqur123
Copy link
Copy Markdown

Summary

Parameters starting with a single underscore that do not end with underscore are conventionally used to indicate intentionally unused variables. This PR suppresses the implicit-any-parameter error for such parameters, reducing noise for a common Python pattern.

Fixes #3542

Changes

  • pyrefly/lib/alt/function.rs: Skip emitting ImplicitAnyParameter for parameters where the name starts with exactly one underscore and does not end with underscore (e.g. _, _x)
  • pyrefly/lib/test/inference.rs: Add test cases covering all underscore patterns

Underscore patterns

Pattern Behavior
_ No error (intentionally unused)
_abc No error (intentionally unused)
__abc Error (dunder prefix)
_abc_ Error (sunder, ends with underscore)
__abc__ Error (dunder)
x Error (no underscore prefix)

CLA

I will submit the CLA if needed.

🤖 This PR was created with AI assistance

Parameters starting with a single underscore that do not end with
underscore are conventionally used to indicate intentionally unused
variables (e.g. , ). Skip the implicit-any-parameter error for
these names to reduce noise, while still flagging dunders (),
sunders (), and other underscore patterns.

Fixes facebook#3542
Comment thread pyrefly/lib/alt/function.rs Outdated
// as they indicate intentionally unused variables.
// `_`, `_abc` → skip; `__abc`, `_abc_`, `__abc__` → don't skip.
let is_underscore_unused = {
let b = name.as_bytes();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name.starts_with("_") && (name.len() == 1 || !name.ends_with("_")) is easier IMO, none of the other dunder/sunder checking in Pyrefly converts to bytes so I don't think we should break that pattern

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, can we refactor this to be a helper inside

https://github.com/facebook/pyrefly/blob/main/crates/pyrefly_python/src/ast.rs#L414

with a function name like maybe_intentionally_unused that way we can reuse the check in the LSP?

Copy link
Copy Markdown
Contributor

@yangdanny97 yangdanny97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Back to you with one comment, once that's addressed we can merge

@yangdanny97
Copy link
Copy Markdown
Contributor

Oh one more thing. We should avoid emitting unused-variable and unused-parameter diagnostics for these names in the language server as well

code: Some(NumberOrString::String("unused-parameter".to_owned())),

code: Some(NumberOrString::String("unused-variable".to_owned())),

You can reuse the helper function for that

@MD-Mushfiqur123
Copy link
Copy Markdown
Author

Friendly ping — this PR is ready for review. All CI checks are passing.

@MD-Mushfiqur123
Copy link
Copy Markdown
Author

The LSP suppression has been implemented in the latest commit (suppress unused-parameter and unused-variable diagnostics for underscore-prefixed names). Could you please re-review?

@yangdanny97 yangdanny97 self-requested a review May 27, 2026 21:54
Copy link
Copy Markdown
Contributor

@yangdanny97 yangdanny97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You didn't address my comments in function.rs. The logic in server.rs is also inconsistent with function.rs - it should be the same, which is why I suggested you make a helper function.

@github-actions
Copy link
Copy Markdown

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@MD-Mushfiqur123
Copy link
Copy Markdown
Author

@yangdanny97 friendly ping — changes have been pushed addressing the LSP suppression feedback. Could you take another look?

@yangdanny97
Copy link
Copy Markdown
Contributor

@MD-Mushfiqur123 I took another look - you didn't address all the comments from my initial review

Per review feedback, the intentionally-unused check is now a
single  function in ast.rs,
used by both the type checker (function.rs) and the LSP
(server.rs). The check itself follows the reviewer's simpler
suggestion: .
@MD-Mushfiqur123
Copy link
Copy Markdown
Author

@yangdanny97 All review comments addressed:

  1. function.rs: Check simplified to Ast::is_intentionally_unused() — uses name.starts_with(_) && (name.len() == 1 || !name.ends_with(_)) as you suggested
  2. ast.rs: Added the helper function is_intentionally_unused next to is_mangled_attr
  3. server.rs: Both unused_parameters() and unused_variables() loops now use the same helper, matching function.rs logic

Could you take another look?

@github-actions github-actions Bot added size/s and removed size/s labels May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support underscore variables starting with (_) to indicate intentionally unused variables

3 participants