Skip to content

Commit

Permalink
feat(B032): add b032 flake8_bugbear (#3085)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosmiei committed Feb 21, 2023
1 parent d9fd78d commit 6eb014b
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 0 deletions.
29 changes: 29 additions & 0 deletions crates/ruff/resources/test/fixtures/flake8_bugbear/B032.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Should emit:
B032 - on lines 9, 10, 12, 13, 16-19
"""

# Flag these
dct = {"a": 1}

dct["b"]: 2
dct.b: 2

dct["b"]: "test"
dct.b: "test"

test = "test"
dct["b"]: test
dct["b"]: test.lower()
dct.b: test
dct.b: test.lower()

# Do not flag below
typed_dct: dict[str, int] = {"a": 1}
typed_dct["b"] = 2
typed_dct.b = 2


class TestClass:
def test_self(self):
self.test: int
12 changes: 12 additions & 0 deletions crates/ruff/src/checkers/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,18 @@ where
pycodestyle::rules::lambda_assignment(self, target, value, stmt);
}
}
if self
.settings
.rules
.enabled(&Rule::UnintentionalTypeAnnotation)
{
flake8_bugbear::rules::unintentional_type_annotation(
self,
target,
value.as_deref(),
stmt,
);
}
}
StmtKind::Delete { .. } => {}
StmtKind::Expr { value, .. } => {
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
(Flake8Bugbear, "026") => Rule::StarArgUnpackingAfterKeywordArg,
(Flake8Bugbear, "027") => Rule::EmptyMethodWithoutAbstractDecorator,
(Flake8Bugbear, "029") => Rule::ExceptWithEmptyTuple,
(Flake8Bugbear, "032") => Rule::UnintentionalTypeAnnotation,
(Flake8Bugbear, "904") => Rule::RaiseWithoutFromInsideExcept,
(Flake8Bugbear, "905") => Rule::ZipWithoutExplicitStrict,

Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ ruff_macros::register_rules!(
rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept,
rules::flake8_bugbear::rules::ZipWithoutExplicitStrict,
rules::flake8_bugbear::rules::ExceptWithEmptyTuple,
rules::flake8_bugbear::rules::UnintentionalTypeAnnotation,
// flake8-blind-except
rules::flake8_blind_except::rules::BlindExcept,
// flake8-comprehensions
Expand Down
1 change: 1 addition & 0 deletions crates/ruff/src/rules/flake8_bugbear/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mod tests {
#[test_case(Rule::EmptyMethodWithoutAbstractDecorator, Path::new("B027.py"); "B027")]
#[test_case(Rule::EmptyMethodWithoutAbstractDecorator, Path::new("B027.pyi"); "B027_pyi")]
#[test_case(Rule::ExceptWithEmptyTuple, Path::new("B029.py"); "B029")]
#[test_case(Rule::UnintentionalTypeAnnotation, Path::new("B032.py"); "B032")]
#[test_case(Rule::RaiseWithoutFromInsideExcept, Path::new("B904.py"); "B904")]
#[test_case(Rule::ZipWithoutExplicitStrict, Path::new("B905.py"); "B905")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
Expand Down
5 changes: 5 additions & 0 deletions crates/ruff/src/rules/flake8_bugbear/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub use useless_contextlib_suppress::{useless_contextlib_suppress, UselessContex
pub use useless_expression::{useless_expression, UselessExpression};
pub use zip_without_explicit_strict::{zip_without_explicit_strict, ZipWithoutExplicitStrict};

pub use unintentional_type_annotation::{
unintentional_type_annotation, UnintentionalTypeAnnotation,
};

mod abstract_base_class;
mod assert_false;
mod assert_raises_exception;
Expand All @@ -62,6 +66,7 @@ mod setattr_with_constant;
mod star_arg_unpacking_after_keyword_arg;
mod strip_with_multi_characters;
mod unary_prefix_increment;
mod unintentional_type_annotation;
mod unreliable_callable_check;
mod unused_loop_control_variable;
mod useless_comparison;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use rustpython_parser::ast::{Expr, ExprKind, Stmt};

use ruff_macros::{define_violation, derive_message_formats};

use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::Diagnostic;
use crate::violation::Violation;

define_violation!(
/// ## What it does
/// Checks for the unintentional use of type annotations.
///
/// ## Why is this bad?
/// The use of a colon (`:`) in lieu of an assignment (`=`) can be syntactically valid, but
/// is almost certainly a mistake when used in a subscript or attribute assignment.
///
/// ## Example
/// ```python
/// a["b"]: 1
/// ```
///
/// Use instead:
/// ```python
/// a["b"] = 1
/// ```
pub struct UnintentionalTypeAnnotation;
);
impl Violation for UnintentionalTypeAnnotation {
#[derive_message_formats]
fn message(&self) -> String {
format!(
"Possible unintentional type annotation (using `:`). Did you mean to assign (using `=`)?"
)
}
}

/// B032
pub fn unintentional_type_annotation(
checker: &mut Checker,
target: &Expr,
value: Option<&Expr>,
stmt: &Stmt,
) {
if value.is_some() {
return;
}
match &target.node {
ExprKind::Subscript { value, .. } => {
if matches!(&value.node, ExprKind::Name { .. }) {
checker.diagnostics.push(Diagnostic::new(
UnintentionalTypeAnnotation,
Range::from_located(stmt),
));
}
}
ExprKind::Attribute { value, .. } => {
if let ExprKind::Name { id, .. } = &value.node {
if id != "self" {
checker.diagnostics.push(Diagnostic::new(
UnintentionalTypeAnnotation,
Range::from_located(stmt),
));
}
}
}
_ => {}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
source: crates/ruff/src/rules/flake8_bugbear/mod.rs
expression: diagnostics
---
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 9
column: 0
end_location:
row: 9
column: 11
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 10
column: 0
end_location:
row: 10
column: 8
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 12
column: 0
end_location:
row: 12
column: 16
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 13
column: 0
end_location:
row: 13
column: 13
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 16
column: 0
end_location:
row: 16
column: 14
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 17
column: 0
end_location:
row: 17
column: 22
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 18
column: 0
end_location:
row: 18
column: 11
fix: ~
parent: ~
- kind:
UnintentionalTypeAnnotation: ~
location:
row: 19
column: 0
end_location:
row: 19
column: 19
fix: ~
parent: ~

2 changes: 2 additions & 0 deletions ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6eb014b

Please sign in to comment.