Compare commits

..

3 Commits

Author SHA1 Message Date
Charlie Marsh
e00bcd19f5 Bump version to 0.0.97 2022-11-02 22:38:43 -04:00
Charlie Marsh
4550581be2 Relax lowercase condition in N806 (#562) 2022-11-02 22:38:29 -04:00
Charlie Marsh
b42d77a4c6 Avoid autofixes for errors in f-strings (#561) 2022-11-02 22:31:57 -04:00
16 changed files with 112 additions and 83 deletions

View File

@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.96
rev: v0.0.97
hooks:
- id: ruff

4
Cargo.lock generated
View File

@@ -920,7 +920,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flake8-to-ruff"
version = "0.0.96-dev.0"
version = "0.0.97-dev.0"
dependencies = [
"anyhow",
"clap 4.0.15",
@@ -2211,7 +2211,7 @@ dependencies = [
[[package]]
name = "ruff"
version = "0.0.96"
version = "0.0.97"
dependencies = [
"anyhow",
"assert_cmd",

View File

@@ -5,7 +5,7 @@ members = [
[package]
name = "ruff"
version = "0.0.96"
version = "0.0.97"
edition = "2021"
[lib]

View File

@@ -89,7 +89,7 @@ Ruff also works with [pre-commit](https://pre-commit.com):
```yaml
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.96
rev: v0.0.97
hooks:
- id: ruff
```

View File

@@ -771,7 +771,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flake8_to_ruff"
version = "0.0.96"
version = "0.0.97"
dependencies = [
"anyhow",
"clap",
@@ -1975,7 +1975,7 @@ dependencies = [
[[package]]
name = "ruff"
version = "0.0.96"
version = "0.0.97"
dependencies = [
"anyhow",
"bincode",

View File

@@ -1,6 +1,6 @@
[package]
name = "flake8-to-ruff"
version = "0.0.96-dev.0"
version = "0.0.97-dev.0"
edition = "2021"
[lib]

View File

@@ -2,3 +2,4 @@ def f():
lower = 0
Camel = 0
CONSTANT = 0
_ = 0

View File

@@ -129,7 +129,9 @@ impl<'a> Checker<'a> {
/// Return `true` if a patch should be generated under the given autofix
/// `Mode`.
pub fn patch(&self) -> bool {
self.autofix.patch()
// TODO(charlie): We can't fix errors in f-strings until RustPython adds
// location data.
self.autofix.patch() && self.in_f_string.is_none()
}
/// Return `true` if the `Expr` is a reference to `typing.${target}`.
@@ -995,6 +997,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1008,6 +1011,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1021,6 +1025,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1035,6 +1040,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1044,7 +1050,10 @@ where
if self.settings.enabled.contains(&CheckCode::C404) {
if let Some(check) =
flake8_comprehensions::checks::unnecessary_list_comprehension_dict(
expr, func, args, keywords,
func,
args,
keywords,
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1059,6 +1068,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1066,7 +1076,10 @@ where
if self.settings.enabled.contains(&CheckCode::C406) {
if let Some(check) = flake8_comprehensions::checks::unnecessary_literal_dict(
expr, func, args, keywords,
func,
args,
keywords,
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1080,6 +1093,7 @@ where
keywords,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1093,6 +1107,7 @@ where
args,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1107,6 +1122,7 @@ where
args,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1120,6 +1136,7 @@ where
args,
self.locator,
self.patch(),
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
@@ -1128,7 +1145,9 @@ where
if self.settings.enabled.contains(&CheckCode::C413) {
if let Some(check) =
flake8_comprehensions::checks::unnecessary_call_around_sorted(
expr, func, args,
func,
args,
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1138,7 +1157,9 @@ where
if self.settings.enabled.contains(&CheckCode::C414) {
if let Some(check) =
flake8_comprehensions::checks::unnecessary_double_cast_or_process(
expr, func, args,
func,
args,
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1148,7 +1169,9 @@ where
if self.settings.enabled.contains(&CheckCode::C415) {
if let Some(check) =
flake8_comprehensions::checks::unnecessary_subscript_reversal(
expr, func, args,
func,
args,
self.locate_check(Range::from_located(expr)),
)
{
self.checks.push(check);
@@ -1156,9 +1179,11 @@ where
}
if self.settings.enabled.contains(&CheckCode::C417) {
if let Some(check) =
flake8_comprehensions::checks::unnecessary_map(expr, func, args)
{
if let Some(check) = flake8_comprehensions::checks::unnecessary_map(
func,
args,
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};
}
@@ -1335,7 +1360,10 @@ where
ExprKind::ListComp { elt, generators } | ExprKind::SetComp { elt, generators } => {
if self.settings.enabled.contains(&CheckCode::C416) {
if let Some(check) = flake8_comprehensions::checks::unnecessary_comprehension(
expr, elt, generators,
expr,
elt,
generators,
self.locate_check(Range::from_located(expr)),
) {
self.checks.push(check);
};

View File

@@ -1,6 +1,6 @@
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
use crate::ast::types::Range;
use crate::ast::types::{CheckLocator, Range};
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind};
@@ -42,7 +42,10 @@ pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: &Optio
..
} = &test.node
{
let mut check = Check::new(CheckKind::DoNotAssertFalse, Range::from_located(test));
let mut check = Check::new(
CheckKind::DoNotAssertFalse,
checker.locate_check(Range::from_located(test)),
);
if checker.patch() {
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_stmt(&assertion_error(msg)) {

View File

@@ -1,7 +1,7 @@
use rustpython_ast::{ExprKind, Stmt, Withitem};
use crate::ast::helpers::match_name_or_attr;
use crate::ast::types::Range;
use crate::ast::types::{CheckLocator, Range};
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind};
@@ -17,7 +17,7 @@ pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[With
{
checker.add_check(Check::new(
CheckKind::NoAssertRaisesException,
Range::from_located(stmt),
checker.locate_check(Range::from_located(stmt)),
));
}
}

View File

@@ -1,6 +1,6 @@
use rustpython_ast::{Expr, ExprKind, Unaryop};
use crate::ast::types::Range;
use crate::ast::types::{CheckLocator, Range};
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind};
@@ -11,7 +11,7 @@ pub fn unary_prefix_increment(checker: &mut Checker, expr: &Expr, op: &Unaryop,
if matches!(op, Unaryop::UAdd) {
checker.add_check(Check::new(
CheckKind::UnaryPrefixIncrement,
Range::from_located(expr),
checker.locate_check(Range::from_located(expr)),
))
}
}

View File

@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use rustpython_ast::{Expr, ExprKind, Stmt};
use crate::ast::types::Range;
use crate::ast::types::{CheckLocator, Range};
use crate::ast::visitor;
use crate::ast::visitor::Visitor;
use crate::autofix::Fix;
@@ -64,7 +64,7 @@ pub fn unused_loop_control_variable(checker: &mut Checker, target: &Expr, body:
let mut check = Check::new(
CheckKind::UnusedLoopControlVariable(name.to_string()),
Range::from_located(expr),
checker.locate_check(Range::from_located(expr)),
);
if checker.patch() {
// Prefix the variable name with an underscore.

View File

@@ -54,13 +54,11 @@ pub fn unnecessary_generator_list(
keywords: &[Keyword],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("list", func, args, keywords)?;
if let ExprKind::GeneratorExp { .. } = argument {
let mut check = Check::new(
CheckKind::UnnecessaryGeneratorList,
Range::from_located(expr),
);
let mut check = Check::new(CheckKind::UnnecessaryGeneratorList, location);
if fix {
match fixes::fix_unnecessary_generator_list(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -80,13 +78,11 @@ pub fn unnecessary_generator_set(
keywords: &[Keyword],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("set", func, args, keywords)?;
if let ExprKind::GeneratorExp { .. } = argument {
let mut check = Check::new(
CheckKind::UnnecessaryGeneratorSet,
Range::from_located(expr),
);
let mut check = Check::new(CheckKind::UnnecessaryGeneratorSet, location);
if fix {
match fixes::fix_unnecessary_generator_set(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -106,15 +102,13 @@ pub fn unnecessary_generator_dict(
keywords: &[Keyword],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("dict", func, args, keywords)?;
if let ExprKind::GeneratorExp { elt, .. } = argument {
match &elt.node {
ExprKind::Tuple { elts, .. } if elts.len() == 2 => {
let mut check = Check::new(
CheckKind::UnnecessaryGeneratorDict,
Range::from_located(expr),
);
let mut check = Check::new(CheckKind::UnnecessaryGeneratorDict, location);
if fix {
match fixes::fix_unnecessary_generator_dict(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -137,13 +131,11 @@ pub fn unnecessary_list_comprehension_set(
keywords: &[Keyword],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("set", func, args, keywords)?;
if let ExprKind::ListComp { .. } = &argument {
let mut check = Check::new(
CheckKind::UnnecessaryListComprehensionSet,
Range::from_located(expr),
);
let mut check = Check::new(CheckKind::UnnecessaryListComprehensionSet, location);
if fix {
match fixes::fix_unnecessary_list_comprehension_set(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -157,10 +149,10 @@ pub fn unnecessary_list_comprehension_set(
/// C404 (`dict([...])`)
pub fn unnecessary_list_comprehension_dict(
expr: &Expr,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("dict", func, args, keywords)?;
if let ExprKind::ListComp { elt, .. } = &argument {
@@ -168,7 +160,7 @@ pub fn unnecessary_list_comprehension_dict(
ExprKind::Tuple { elts, .. } if elts.len() == 2 => {
return Some(Check::new(
CheckKind::UnnecessaryListComprehensionDict,
Range::from_located(expr),
location,
));
}
_ => {}
@@ -185,6 +177,7 @@ pub fn unnecessary_literal_set(
keywords: &[Keyword],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("set", func, args, keywords)?;
let kind = match argument {
@@ -192,10 +185,7 @@ pub fn unnecessary_literal_set(
ExprKind::Tuple { .. } => "tuple",
_ => return None,
};
let mut check = Check::new(
CheckKind::UnnecessaryLiteralSet(kind.to_string()),
Range::from_located(expr),
);
let mut check = Check::new(CheckKind::UnnecessaryLiteralSet(kind.to_string()), location);
if fix {
match fixes::fix_unnecessary_literal_set(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -207,10 +197,10 @@ pub fn unnecessary_literal_set(
/// C406 (`dict([(1, 2)])`)
pub fn unnecessary_literal_dict(
expr: &Expr,
func: &Expr,
args: &[Expr],
keywords: &[Keyword],
location: Range,
) -> Option<Check> {
let argument = exactly_one_argument_with_matching_function("dict", func, args, keywords)?;
let (kind, elts) = match argument {
@@ -228,7 +218,7 @@ pub fn unnecessary_literal_dict(
Some(Check::new(
CheckKind::UnnecessaryLiteralDict(kind.to_string()),
Range::from_located(expr),
location,
))
}
@@ -240,6 +230,7 @@ pub fn unnecessary_collection_call(
keywords: &[Located<KeywordData>],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
if !args.is_empty() {
return None;
@@ -256,7 +247,7 @@ pub fn unnecessary_collection_call(
};
let mut check = Check::new(
CheckKind::UnnecessaryCollectionCall(id.to_string()),
Range::from_located(expr),
location,
);
if fix {
// TODO(charlie): Support fixing `dict(a=1)`.
@@ -277,6 +268,7 @@ pub fn unnecessary_literal_within_tuple_call(
args: &[Expr],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = first_argument_with_matching_function("tuple", func, args)?;
let argument_kind = match argument {
@@ -286,7 +278,7 @@ pub fn unnecessary_literal_within_tuple_call(
};
let mut check = Check::new(
CheckKind::UnnecessaryLiteralWithinTupleCall(argument_kind.to_string()),
Range::from_located(expr),
location,
);
if fix {
match fixes::fix_unnecessary_literal_within_tuple_call(locator, expr) {
@@ -304,6 +296,7 @@ pub fn unnecessary_literal_within_list_call(
args: &[Expr],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = first_argument_with_matching_function("list", func, args)?;
let argument_kind = match argument {
@@ -313,7 +306,7 @@ pub fn unnecessary_literal_within_list_call(
};
let mut check = Check::new(
CheckKind::UnnecessaryLiteralWithinListCall(argument_kind.to_string()),
Range::from_located(expr),
location,
);
if fix {
match fixes::fix_unnecessary_literal_within_list_call(locator, expr) {
@@ -331,10 +324,11 @@ pub fn unnecessary_list_call(
args: &[Expr],
locator: &SourceCodeLocator,
fix: bool,
location: Range,
) -> Option<Check> {
let argument = first_argument_with_matching_function("list", func, args)?;
if let ExprKind::ListComp { .. } = argument {
let mut check = Check::new(CheckKind::UnnecessaryListCall, Range::from_located(expr));
let mut check = Check::new(CheckKind::UnnecessaryListCall, location);
if fix {
match fixes::fix_unnecessary_list_call(locator, expr) {
Ok(fix) => check.amend(fix),
@@ -347,7 +341,11 @@ pub fn unnecessary_list_call(
}
/// C413
pub fn unnecessary_call_around_sorted(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check> {
pub fn unnecessary_call_around_sorted(
func: &Expr,
args: &[Expr],
location: Range,
) -> Option<Check> {
let outer = function_name(func)?;
if !(outer == "list" || outer == "reversed") {
return None;
@@ -356,7 +354,7 @@ pub fn unnecessary_call_around_sorted(expr: &Expr, func: &Expr, args: &[Expr]) -
if function_name(func)? == "sorted" {
return Some(Check::new(
CheckKind::UnnecessaryCallAroundSorted(outer.to_string()),
Range::from_located(expr),
location,
));
}
}
@@ -365,19 +363,19 @@ pub fn unnecessary_call_around_sorted(expr: &Expr, func: &Expr, args: &[Expr]) -
/// C414
pub fn unnecessary_double_cast_or_process(
expr: &Expr,
func: &Expr,
args: &[Expr],
location: Range,
) -> Option<Check> {
let outer = function_name(func)?;
if !["list", "tuple", "set", "reversed", "sorted"].contains(&outer) {
return None;
}
fn new_check(inner: &str, outer: &str, expr: &Expr) -> Check {
fn new_check(inner: &str, outer: &str, location: Range) -> Check {
Check::new(
CheckKind::UnnecessaryDoubleCastOrProcess(inner.to_string(), outer.to_string()),
Range::from_located(expr),
location,
)
}
@@ -387,24 +385,28 @@ pub fn unnecessary_double_cast_or_process(
if (outer == "set" || outer == "sorted")
&& (inner == "list" || inner == "tuple" || inner == "reversed" || inner == "sorted")
{
return Some(new_check(inner, outer, expr));
return Some(new_check(inner, outer, location));
}
// Ex) list(tuple(...))
if (outer == "list" || outer == "tuple") && (inner == "list" || inner == "tuple") {
return Some(new_check(inner, outer, expr));
return Some(new_check(inner, outer, location));
}
// Ex) set(set(...))
if outer == "set" && inner == "set" {
return Some(new_check(inner, outer, expr));
return Some(new_check(inner, outer, location));
}
}
None
}
/// C415
pub fn unnecessary_subscript_reversal(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check> {
pub fn unnecessary_subscript_reversal(
func: &Expr,
args: &[Expr],
location: Range,
) -> Option<Check> {
let first_arg = args.first()?;
let id = function_name(func)?;
if !["set", "sorted", "reversed"].contains(&id) {
@@ -427,7 +429,7 @@ pub fn unnecessary_subscript_reversal(expr: &Expr, func: &Expr, args: &[Expr]) -
if *val == BigInt::from(1) {
return Some(Check::new(
CheckKind::UnnecessarySubscriptReversal(id.to_string()),
Range::from_located(expr),
location,
));
}
}
@@ -444,6 +446,7 @@ pub fn unnecessary_comprehension(
expr: &Expr,
elt: &Expr,
generators: &[Comprehension],
location: Range,
) -> Option<Check> {
if generators.len() != 1 {
return None;
@@ -464,30 +467,27 @@ pub fn unnecessary_comprehension(
};
Some(Check::new(
CheckKind::UnnecessaryComprehension(expr_kind.to_string()),
Range::from_located(expr),
location,
))
}
/// C417
pub fn unnecessary_map(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check> {
fn new_check(kind: &str, expr: &Expr) -> Check {
Check::new(
CheckKind::UnnecessaryMap(kind.to_string()),
Range::from_located(expr),
)
pub fn unnecessary_map(func: &Expr, args: &[Expr], location: Range) -> Option<Check> {
fn new_check(kind: &str, location: Range) -> Check {
Check::new(CheckKind::UnnecessaryMap(kind.to_string()), location)
}
let id = function_name(func)?;
match id {
"map" => {
if args.len() == 2 && matches!(&args[0].node, ExprKind::Lambda { .. }) {
return Some(new_check("generator", expr));
return Some(new_check("generator", location));
}
}
"list" | "set" => {
if let ExprKind::Call { func, args, .. } = &args.first()?.node {
let argument = first_argument_with_matching_function("map", func, args)?;
if let ExprKind::Lambda { .. } = argument {
return Some(new_check(id, expr));
return Some(new_check(id, location));
}
}
}
@@ -498,7 +498,7 @@ pub fn unnecessary_map(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check>
if let ExprKind::Lambda { body, .. } = &argument {
if matches!(&body.node, ExprKind::Tuple { elts, .. } | ExprKind::List { elts, .. } if elts.len() == 2)
{
return Some(new_check(id, expr));
return Some(new_check(id, location));
}
}
}

View File

@@ -9,25 +9,20 @@ pub fn print_call(
func: &Expr,
check_print: bool,
check_pprint: bool,
location: Range,
) -> Option<Check> {
if let ExprKind::Name { id, .. } = &func.node {
if check_print && id == "print" {
return Some(Check::new(CheckKind::PrintFound, Range::from_located(expr)));
} else if check_pprint && id == "pprint" {
return Some(Check::new(
CheckKind::PPrintFound,
Range::from_located(expr),
));
return Some(Check::new(CheckKind::PPrintFound, location));
}
}
if let ExprKind::Attribute { value, attr, .. } = &func.node {
if let ExprKind::Name { id, .. } = &value.node {
if check_pprint && id == "pprint" && attr == "pprint" {
return Some(Check::new(
CheckKind::PPrintFound,
Range::from_located(expr),
));
return Some(Check::new(CheckKind::PPrintFound, location));
}
}
}

View File

@@ -1,6 +1,7 @@
use log::error;
use rustpython_ast::{Expr, Stmt, StmtKind};
use crate::ast::types::{CheckLocator, Range};
use crate::autofix::helpers;
use crate::check_ast::Checker;
use crate::checks::CheckCode;
@@ -12,6 +13,7 @@ pub fn print_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
func,
checker.settings.enabled.contains(&CheckCode::T201),
checker.settings.enabled.contains(&CheckCode::T203),
checker.locate_check(Range::from_located(expr)),
) {
if checker.patch() {
let context = checker.binding_context();

View File

@@ -118,7 +118,7 @@ pub fn non_lowercase_variable_in_function(scope: &Scope, expr: &Expr, name: &str
if !matches!(scope.kind, ScopeKind::Function(FunctionScope { .. })) {
return None;
}
if !is_lower(name) {
if name.to_lowercase() != name {
return Some(Check::new(
CheckKind::NonLowercaseVariableInFunction(name.to_string()),
Range::from_located(expr),