Fix E722 and F707 ranges (#1508)

This commit is contained in:
Harutaka Kawamura 2022-12-31 21:58:46 +09:00 committed by GitHub
parent 62c273cd22
commit f73dfbbfd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 21 deletions

View file

@ -426,6 +426,31 @@ pub fn excepthandler_name_range(
} }
} }
/// Return the `Range` of `except` in `Excepthandler`.
pub fn except_range(handler: &Excepthandler, locator: &SourceCodeLocator) -> Range {
let ExcepthandlerKind::ExceptHandler { body, type_, .. } = &handler.node;
let end = if let Some(type_) = type_ {
type_.location
} else {
body.first()
.expect("Expected body to be non-empty")
.location
};
let contents = locator.slice_source_code_range(&Range {
location: handler.location,
end_location: end,
});
let range = lexer::make_tokenizer_located(&contents, handler.location)
.flatten()
.find(|(_, kind, _)| matches!(kind, Tok::Except { .. }))
.map(|(location, _, end_location)| Range {
location,
end_location,
})
.expect("Failed to find `except` range");
range
}
/// Return the `Range` of `else` in `For`, `AsyncFor`, and `While` statements. /// Return the `Range` of `else` in `For`, `AsyncFor`, and `While` statements.
pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option<Range> { pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option<Range> {
match &stmt.node { match &stmt.node {
@ -434,10 +459,17 @@ pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option<Range> {
| StmtKind::While { body, orelse, .. } | StmtKind::While { body, orelse, .. }
if !orelse.is_empty() => if !orelse.is_empty() =>
{ {
let body_end = body.last().unwrap().end_location.unwrap(); let body_end = body
.last()
.expect("Expected body to be non-empty")
.end_location
.unwrap();
let contents = locator.slice_source_code_range(&Range { let contents = locator.slice_source_code_range(&Range {
location: body_end, location: body_end,
end_location: orelse[0].location, end_location: orelse
.first()
.expect("Expected orelse to be non-empty")
.location,
}); });
let range = lexer::make_tokenizer_located(&contents, body_end) let range = lexer::make_tokenizer_located(&contents, body_end)
.flatten() .flatten()

View file

@ -1171,7 +1171,9 @@ where
} }
StmtKind::Try { handlers, .. } => { StmtKind::Try { handlers, .. } => {
if self.settings.enabled.contains(&CheckCode::F707) { if self.settings.enabled.contains(&CheckCode::F707) {
if let Some(check) = pyflakes::checks::default_except_not_last(handlers) { if let Some(check) =
pyflakes::checks::default_except_not_last(handlers, self.locator)
{
self.add_check(check); self.add_check(check);
} }
} }
@ -2682,7 +2684,8 @@ where
if let Some(check) = pycodestyle::checks::do_not_use_bare_except( if let Some(check) = pycodestyle::checks::do_not_use_bare_except(
type_.as_deref(), type_.as_deref(),
body, body,
Range::from_located(excepthandler), excepthandler,
self.locator,
) { ) {
self.add_check(check); self.add_check(check);
} }

View file

@ -1,9 +1,10 @@
use itertools::izip; use itertools::izip;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
use rustpython_ast::{Constant, Located, Location, Stmt, StmtKind}; use rustpython_ast::{Constant, Excepthandler, Located, Location, Stmt, StmtKind};
use rustpython_parser::ast::{Cmpop, Expr, ExprKind}; use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
use crate::ast::helpers::except_range;
use crate::ast::types::Range; use crate::ast::types::Range;
use crate::autofix::Fix; use crate::autofix::Fix;
use crate::checks::{Check, CheckKind}; use crate::checks::{Check, CheckKind};
@ -88,14 +89,18 @@ pub fn type_comparison(ops: &[Cmpop], comparators: &[Expr], location: Range) ->
pub fn do_not_use_bare_except( pub fn do_not_use_bare_except(
type_: Option<&Expr>, type_: Option<&Expr>,
body: &[Stmt], body: &[Stmt],
location: Range, handler: &Excepthandler,
locator: &SourceCodeLocator,
) -> Option<Check> { ) -> Option<Check> {
if type_.is_none() if type_.is_none()
&& !body && !body
.iter() .iter()
.any(|stmt| matches!(stmt.node, StmtKind::Raise { exc: None, .. })) .any(|stmt| matches!(stmt.node, StmtKind::Raise { exc: None, .. }))
{ {
Some(Check::new(CheckKind::DoNotUseBareExcept, location)) Some(Check::new(
CheckKind::DoNotUseBareExcept,
except_range(handler, locator),
))
} else { } else {
None None
} }

View file

@ -7,8 +7,8 @@ expression: checks
row: 4 row: 4
column: 0 column: 0
end_location: end_location:
row: 5 row: 4
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~
- kind: DoNotUseBareExcept - kind: DoNotUseBareExcept
@ -16,8 +16,8 @@ expression: checks
row: 11 row: 11
column: 0 column: 0
end_location: end_location:
row: 12 row: 11
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~
- kind: DoNotUseBareExcept - kind: DoNotUseBareExcept
@ -25,8 +25,8 @@ expression: checks
row: 16 row: 16
column: 0 column: 0
end_location: end_location:
row: 17 row: 16
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~

View file

@ -5,8 +5,10 @@ use rustpython_parser::ast::{
Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt, StmtKind, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt, StmtKind,
}; };
use crate::ast::helpers::except_range;
use crate::ast::types::{Binding, BindingKind, Range, Scope, ScopeKind}; use crate::ast::types::{Binding, BindingKind, Range, Scope, ScopeKind};
use crate::checks::{Check, CheckKind}; use crate::checks::{Check, CheckKind};
use crate::source_code_locator::SourceCodeLocator;
/// F631 /// F631
pub fn assert_tuple(test: &Expr, location: Range) -> Option<Check> { pub fn assert_tuple(test: &Expr, location: Range) -> Option<Check> {
@ -110,13 +112,16 @@ pub fn unused_annotation(
} }
/// F707 /// F707
pub fn default_except_not_last(handlers: &[Excepthandler]) -> Option<Check> { pub fn default_except_not_last(
handlers: &[Excepthandler],
locator: &SourceCodeLocator,
) -> Option<Check> {
for (idx, handler) in handlers.iter().enumerate() { for (idx, handler) in handlers.iter().enumerate() {
let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node; let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node;
if type_.is_none() && idx < handlers.len() - 1 { if type_.is_none() && idx < handlers.len() - 1 {
return Some(Check::new( return Some(Check::new(
CheckKind::DefaultExceptNotLast, CheckKind::DefaultExceptNotLast,
Range::from_located(handler), except_range(handler, locator),
)); ));
} }
} }

View file

@ -7,8 +7,8 @@ expression: checks
row: 3 row: 3
column: 0 column: 0
end_location: end_location:
row: 4 row: 3
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~
- kind: DefaultExceptNotLast - kind: DefaultExceptNotLast
@ -16,8 +16,8 @@ expression: checks
row: 10 row: 10
column: 0 column: 0
end_location: end_location:
row: 11 row: 10
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~
- kind: DefaultExceptNotLast - kind: DefaultExceptNotLast
@ -25,8 +25,8 @@ expression: checks
row: 19 row: 19
column: 0 column: 0
end_location: end_location:
row: 20 row: 19
column: 8 column: 6
fix: ~ fix: ~
parent: ~ parent: ~