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.
pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option<Range> {
match &stmt.node {
@ -434,10 +459,17 @@ pub fn else_range(stmt: &Stmt, locator: &SourceCodeLocator) -> Option<Range> {
| StmtKind::While { body, orelse, .. }
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 {
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)
.flatten()

View file

@ -1171,7 +1171,9 @@ where
}
StmtKind::Try { handlers, .. } => {
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);
}
}
@ -2682,7 +2684,8 @@ where
if let Some(check) = pycodestyle::checks::do_not_use_bare_except(
type_.as_deref(),
body,
Range::from_located(excepthandler),
excepthandler,
self.locator,
) {
self.add_check(check);
}

View file

@ -1,9 +1,10 @@
use itertools::izip;
use once_cell::sync::Lazy;
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 crate::ast::helpers::except_range;
use crate::ast::types::Range;
use crate::autofix::Fix;
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(
type_: Option<&Expr>,
body: &[Stmt],
location: Range,
handler: &Excepthandler,
locator: &SourceCodeLocator,
) -> Option<Check> {
if type_.is_none()
&& !body
.iter()
.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 {
None
}

View file

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

View file

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

View file

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