Skip to content

Commit

Permalink
Disable E741 in stub files (#13119)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Waygood <[email protected]>
  • Loading branch information
calumy and AlexWaygood authored Aug 27, 2024
1 parent a5ef124 commit 4e1b289
Show file tree
Hide file tree
Showing 9 changed files with 326 additions and 26 deletions.
75 changes: 75 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pycodestyle/E741.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from contextlib import contextmanager

l = 0
I = 0
O = 0
l: int = 0

a, l = 0, 1
[a, l] = 0, 1
a, *l = 0, 1, 2
a = l = 0

o = 0
i = 0

for l in range(3):
pass


for a, l in zip(range(3), range(3)):
pass


def f1():
global l
l = 0


def f2():
l = 0

def f3():
nonlocal l
l = 1

f3()
return l


def f4(l, /, I):
return l, I, O


def f5(l=0, *, I=1):
return l, I


def f6(*l, **I):
return l, I


@contextmanager
def ctx1():
yield 0


with ctx1() as l:
pass


@contextmanager
def ctx2():
yield 0, 1


with ctx2() as (a, l):
pass

try:
pass
except ValueError as l:
pass

if (l := 5) > 0:
pass
10 changes: 5 additions & 5 deletions crates/ruff_linter/src/checkers/ast/analyze/except_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ pub(crate) fn except_handler(except_handler: &ExceptHandler, checker: &mut Check
}
if let Some(name) = name {
if checker.enabled(Rule::AmbiguousVariableName) {
if let Some(diagnostic) =
pycodestyle::rules::ambiguous_variable_name(name.as_str(), name.range())
{
checker.diagnostics.push(diagnostic);
}
pycodestyle::rules::ambiguous_variable_name(
checker,
name.as_str(),
name.range(),
);
}
if checker.enabled(Rule::BuiltinVariableShadowing) {
flake8_builtins::rules::builtin_variable_shadowing(checker, name, name.range());
Expand Down
6 changes: 1 addition & 5 deletions crates/ruff_linter/src/checkers/ast/analyze/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
}
}
if checker.enabled(Rule::AmbiguousVariableName) {
if let Some(diagnostic) =
pycodestyle::rules::ambiguous_variable_name(id, expr.range())
{
checker.diagnostics.push(diagnostic);
}
pycodestyle::rules::ambiguous_variable_name(checker, id, expr.range());
}
if !checker.semantic.current_scope().kind.is_class() {
if checker.enabled(Rule::BuiltinVariableShadowing) {
Expand Down
10 changes: 5 additions & 5 deletions crates/ruff_linter/src/checkers/ast/analyze/parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::rules::{flake8_builtins, pep8_naming, pycodestyle};
/// Run lint rules over a [`Parameter`] syntax node.
pub(crate) fn parameter(parameter: &Parameter, checker: &mut Checker) {
if checker.enabled(Rule::AmbiguousVariableName) {
if let Some(diagnostic) =
pycodestyle::rules::ambiguous_variable_name(&parameter.name, parameter.name.range())
{
checker.diagnostics.push(diagnostic);
}
pycodestyle::rules::ambiguous_variable_name(
checker,
&parameter.name,
parameter.name.range(),
);
}
if checker.enabled(Rule::InvalidArgumentName) {
if let Some(diagnostic) = pep8_naming::rules::invalid_argument_name(
Expand Down
12 changes: 6 additions & 6 deletions crates/ruff_linter/src/checkers/ast/analyze/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
pylint::rules::global_at_module_level(checker, stmt);
}
if checker.enabled(Rule::AmbiguousVariableName) {
checker.diagnostics.extend(names.iter().filter_map(|name| {
pycodestyle::rules::ambiguous_variable_name(name, name.range())
}));
for name in names {
pycodestyle::rules::ambiguous_variable_name(checker, name, name.range());
}
}
}
Stmt::Nonlocal(nonlocal @ ast::StmtNonlocal { names, range: _ }) => {
if checker.enabled(Rule::AmbiguousVariableName) {
checker.diagnostics.extend(names.iter().filter_map(|name| {
pycodestyle::rules::ambiguous_variable_name(name, name.range())
}));
for name in names {
pycodestyle::rules::ambiguous_variable_name(checker, name, name.range());
}
}
if checker.enabled(Rule::NonlocalWithoutBinding) {
if !checker.semantic.scope_id.is_global() {
Expand Down
5 changes: 5 additions & 0 deletions crates/ruff_linter/src/rules/pycodestyle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ mod tests {
#[test_case(Rule::AmbiguousClassName, Path::new("E742.py"))]
#[test_case(Rule::AmbiguousFunctionName, Path::new("E743.py"))]
#[test_case(Rule::AmbiguousVariableName, Path::new("E741.py"))]
// E741 has different behaviour for `.pyi` files in preview mode;
// this test case checks it still has the old behaviour in stable mode
#[test_case(Rule::AmbiguousVariableName, Path::new("E741.pyi"))]
#[test_case(Rule::LambdaAssignment, Path::new("E731.py"))]
#[test_case(Rule::BareExcept, Path::new("E722.py"))]
#[test_case(Rule::BlankLineWithWhitespace, Path::new("W29.py"))]
Expand Down Expand Up @@ -75,6 +78,8 @@ mod tests {
#[test_case(Rule::TooManyNewlinesAtEndOfFile, Path::new("W391_2.py"))]
#[test_case(Rule::TooManyNewlinesAtEndOfFile, Path::new("W391_3.py"))]
#[test_case(Rule::TooManyNewlinesAtEndOfFile, Path::new("W391_4.py"))]
// E741 has different behaviour for `.pyi` files in preview mode
#[test_case(Rule::AmbiguousVariableName, Path::new("E741.pyi"))]
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!(
"preview__{}_{}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ruff_text_size::TextRange;
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

use crate::checkers::ast::Checker;
use crate::rules::pycodestyle::helpers::is_ambiguous_name;

/// ## What it does
Expand All @@ -25,6 +26,13 @@ use crate::rules::pycodestyle::helpers::is_ambiguous_name;
/// o = 123
/// i = 42
/// ```
///
/// ## Preview mode behavior for stub files
/// In [preview] mode, this rule is automatically disabled for all stub files
/// (files with `.pyi` extensions). The rule has little relevance for authors
/// of stubs: a well-written stub should aim to faithfully represent the
/// interface of the equivalent .py file as it exists at runtime, including any
/// ambiguously named variables in the runtime module.

#[violation]
pub struct AmbiguousVariableName(pub String);
Expand All @@ -38,13 +46,14 @@ impl Violation for AmbiguousVariableName {
}

/// E741
pub(crate) fn ambiguous_variable_name(name: &str, range: TextRange) -> Option<Diagnostic> {
pub(crate) fn ambiguous_variable_name(checker: &mut Checker, name: &str, range: TextRange) {
if checker.settings.preview.is_enabled() && checker.source_type.is_stub() {
return;
}
if is_ambiguous_name(name) {
Some(Diagnostic::new(
checker.diagnostics.push(Diagnostic::new(
AmbiguousVariableName(name.to_string()),
range,
))
} else {
None
));
}
}
Loading

0 comments on commit 4e1b289

Please sign in to comment.