Implement autofix for more docstring-related rules (#448)

This commit is contained in:
Charlie Marsh 2022-10-17 16:56:47 -04:00 committed by GitHub
parent 118a9feec8
commit 206e6463be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 1378 additions and 919 deletions

View file

@ -294,7 +294,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
| D202 | NoBlankLineAfterFunction | No blank lines allowed after function docstring (found 1) | 🛠 |
| D203 | OneBlankLineBeforeClass | 1 blank line required before class docstring | 🛠 |
| D204 | OneBlankLineAfterClass | 1 blank line required after class docstring | 🛠 |
| D205 | NoBlankLineAfterSummary | 1 blank line required between summary line and description | 🛠 |
| D205 | BlankLineAfterSummary | 1 blank line required between summary line and description | 🛠 |
| D206 | IndentWithSpaces | Docstring should be indented with spaces, not tabs | |
| D207 | NoUnderIndentation | Docstring is under-indented | |
| D208 | NoOverIndentation | Docstring is over-indented | |
@ -304,7 +304,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
| D212 | MultiLineSummaryFirstLine | Multi-line docstring summary should start at the first line | |
| D213 | MultiLineSummarySecondLine | Multi-line docstring summary should start at the second line | |
| D214 | SectionNotOverIndented | Section is over-indented ("Returns") | |
| D215 | SectionUnderlineNotOverIndented | Section underline is over-indented ("Returns") | |
| D215 | SectionUnderlineNotOverIndented | Section underline is over-indented ("Returns") | 🛠 |
| D300 | UsesTripleQuotes | Use """triple double quotes""" | |
| D400 | EndsInPeriod | First line should end with a period | |
| D402 | NoSignature | First line should not be the function's 'signature' | |
@ -312,12 +312,12 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
| D404 | NoThisPrefix | First word of the docstring should not be `This` | |
| D405 | CapitalizeSectionName | Section name should be properly capitalized ("returns") | |
| D406 | NewLineAfterSectionName | Section name should end with a newline ("Returns") | |
| D407 | DashedUnderlineAfterSection | Missing dashed underline after section ("Returns") | |
| D407 | DashedUnderlineAfterSection | Missing dashed underline after section ("Returns") | 🛠 |
| D408 | SectionUnderlineAfterName | Section underline should be in the line following the section's name ("Returns") | |
| D409 | SectionUnderlineMatchesSectionLength | Section underline should match the length of its name ("Returns") | |
| D409 | SectionUnderlineMatchesSectionLength | Section underline should match the length of its name ("Returns") | 🛠 |
| D410 | BlankLineAfterSection | Missing blank line after section ("Returns") | 🛠 |
| D411 | BlankLineBeforeSection | Missing blank line before section ("Returns") | |
| D412 | NoBlankLinesBetweenHeaderAndContent | No blank lines allowed between a section header and its content ("Returns") | |
| D411 | BlankLineBeforeSection | Missing blank line before section ("Returns") | 🛠 |
| D412 | NoBlankLinesBetweenHeaderAndContent | No blank lines allowed between a section header and its content ("Returns") | 🛠 |
| D413 | BlankLineAfterLastSection | Missing blank line after last section ("Returns") | 🛠 |
| D414 | NonEmptySection | Section has no content ("Returns") | |
| D415 | EndsInPunctuation | First line should end with a period, question mark, or exclamation point | |

View file

@ -1,7 +1,10 @@
use crate::autofix::Fix;
use crate::autofix::Patch;
use itertools::Itertools;
use rustpython_parser::ast::Location;
use std::collections::BTreeSet;
use crate::checks::{Check, Fix};
use crate::checks::Check;
#[derive(Hash)]
pub enum Mode {
@ -35,34 +38,44 @@ pub fn fix_file(checks: &mut [Check], contents: &str) -> Option<String> {
fn apply_fixes<'a>(fixes: impl Iterator<Item = &'a mut Fix>, contents: &str) -> String {
let lines: Vec<&str> = contents.lines().collect();
let mut output = "".to_string();
let mut last_pos: Location = Location::new(0, 0);
let mut output: String = Default::default();
let mut last_pos: Location = Default::default();
let mut applied: BTreeSet<&Patch> = Default::default();
for fix in fixes.sorted_by_key(|fix| fix.location) {
// Best-effort approach: if this fix overlaps with a fix we've already applied, skip it.
if last_pos > fix.location {
for fix in fixes.sorted_by_key(|fix| fix.patch.location) {
// If we already applied an identical fix as part of another correction, skip any
// re-application.
if applied.contains(&fix.patch) {
fix.applied = true;
continue;
}
if fix.location.row() > last_pos.row() {
// Best-effort approach: if this fix overlaps with a fix we've already applied, skip it.
if last_pos > fix.patch.location {
continue;
}
if fix.patch.location.row() > last_pos.row() {
if last_pos.row() > 0 || last_pos.column() > 0 {
output.push_str(&lines[last_pos.row() - 1][last_pos.column() - 1..]);
output.push('\n');
}
for line in &lines[last_pos.row()..fix.location.row() - 1] {
for line in &lines[last_pos.row()..fix.patch.location.row() - 1] {
output.push_str(line);
output.push('\n');
}
output.push_str(&lines[fix.location.row() - 1][..fix.location.column() - 1]);
output.push_str(&fix.content);
output
.push_str(&lines[fix.patch.location.row() - 1][..fix.patch.location.column() - 1]);
output.push_str(&fix.patch.content);
} else {
output.push_str(
&lines[last_pos.row() - 1][last_pos.column() - 1..fix.location.column() - 1],
&lines[last_pos.row() - 1][last_pos.column() - 1..fix.patch.location.column() - 1],
);
output.push_str(&fix.content);
output.push_str(&fix.patch.content);
}
last_pos = fix.patch.end_location;
last_pos = fix.end_location;
applied.insert(&fix.patch);
fix.applied = true;
}
@ -89,7 +102,8 @@ mod tests {
use rustpython_parser::ast::Location;
use crate::autofix::fixer::apply_fixes;
use crate::checks::Fix;
use crate::autofix::Fix;
use crate::autofix::Patch;
#[test]
fn empty_file() -> Result<()> {
@ -105,9 +119,11 @@ mod tests {
#[test]
fn apply_single_replacement() -> Result<()> {
let mut fixes = vec![Fix {
patch: Patch {
content: "Bar".to_string(),
location: Location::new(1, 9),
end_location: Location::new(1, 15),
},
applied: false,
}];
let actual = apply_fixes(
@ -129,9 +145,11 @@ mod tests {
#[test]
fn apply_single_removal() -> Result<()> {
let mut fixes = vec![Fix {
patch: Patch {
content: "".to_string(),
location: Location::new(1, 8),
end_location: Location::new(1, 16),
},
applied: false,
}];
let actual = apply_fixes(
@ -154,15 +172,19 @@ mod tests {
fn apply_double_removal() -> Result<()> {
let mut fixes = vec![
Fix {
patch: Patch {
content: "".to_string(),
location: Location::new(1, 8),
end_location: Location::new(1, 17),
},
applied: false,
},
Fix {
patch: Patch {
content: "".to_string(),
location: Location::new(1, 17),
end_location: Location::new(1, 24),
},
applied: false,
},
];
@ -186,15 +208,19 @@ mod tests {
fn ignore_overlapping_fixes() -> Result<()> {
let mut fixes = vec![
Fix {
patch: Patch {
content: "".to_string(),
location: Location::new(1, 8),
end_location: Location::new(1, 16),
},
applied: false,
},
Fix {
patch: Patch {
content: "ignored".to_string(),
location: Location::new(1, 10),
end_location: Location::new(1, 12),
},
applied: false,
},
];

View file

@ -9,7 +9,7 @@ use rustpython_parser::token::Tok;
use crate::ast::operations::SourceCodeLocator;
use crate::ast::types::Range;
use crate::checks::Fix;
use crate::autofix::Fix;
/// Convert a location within a file (relative to `base`) to an absolute position.
fn to_absolute(relative: &Location, base: &Location) -> Location {
@ -56,12 +56,7 @@ pub fn remove_class_def_base(
}
return match (fix_start, fix_end) {
(Some(start), Some(end)) => Some(Fix {
content: "".to_string(),
location: start,
end_location: end,
applied: false,
}),
(Some(start), Some(end)) => Some(Fix::replacement("".to_string(), start, end)),
_ => None,
};
}
@ -95,12 +90,7 @@ pub fn remove_class_def_base(
}
match (fix_start, fix_end) {
(Some(start), Some(end)) => Some(Fix {
content: "".to_string(),
location: start,
end_location: end,
applied: false,
}),
(Some(start), Some(end)) => Some(Fix::replacement("".to_string(), start, end)),
_ => None,
}
} else {
@ -120,12 +110,7 @@ pub fn remove_class_def_base(
}
match (fix_start, fix_end) {
(Some(start), Some(end)) => Some(Fix {
content: "".to_string(),
location: start,
end_location: end,
applied: false,
}),
(Some(start), Some(end)) => Some(Fix::replacement("".to_string(), start, end)),
_ => None,
}
}
@ -150,12 +135,11 @@ pub fn remove_super_arguments(locator: &mut SourceCodeLocator, expr: &Expr) -> O
let mut state = Default::default();
tree.codegen(&mut state);
return Some(Fix {
content: state.to_string(),
location: range.location,
end_location: range.end_location,
applied: false,
});
return Some(Fix::replacement(
state.to_string(),
range.location,
range.end_location,
));
}
}
}
@ -232,21 +216,18 @@ pub fn remove_stmt(stmt: &Stmt, parent: Option<&Stmt>, deleted: &[&Stmt]) -> Res
{
// If removing this node would lead to an invalid syntax tree, replace
// it with a `pass`.
Ok(Fix {
location: stmt.location,
end_location: stmt.end_location.unwrap(),
content: "pass".to_string(),
applied: false,
})
Ok(Fix::replacement(
"pass".to_string(),
stmt.location,
stmt.end_location.unwrap(),
))
} else {
// Otherwise, nuke the entire line.
// TODO(charlie): This logic assumes that there are no multi-statement physical lines.
Ok(Fix {
location: Location::new(stmt.location.row(), 1),
end_location: Location::new(stmt.end_location.unwrap().row() + 1, 1),
content: "".to_string(),
applied: false,
})
Ok(Fix::deletion(
Location::new(stmt.location.row(), 1),
Location::new(stmt.end_location.unwrap().row() + 1, 1),
))
}
}
@ -307,12 +288,11 @@ pub fn remove_unused_imports(
let mut state = Default::default();
tree.codegen(&mut state);
Ok(Fix {
content: state.to_string(),
location: stmt.location,
end_location: stmt.end_location.unwrap(),
applied: false,
})
Ok(Fix::replacement(
state.to_string(),
stmt.location,
stmt.end_location.unwrap(),
))
}
}
@ -382,11 +362,10 @@ pub fn remove_unused_import_froms(
let mut state = Default::default();
tree.codegen(&mut state);
Ok(Fix {
content: state.to_string(),
location: stmt.location,
end_location: stmt.end_location.unwrap(),
applied: false,
})
Ok(Fix::replacement(
state.to_string(),
stmt.location,
stmt.end_location.unwrap(),
))
}
}

View file

@ -1,2 +1,53 @@
use rustpython_ast::Location;
use serde::{Deserialize, Serialize};
pub mod fixer;
pub mod fixes;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Patch {
pub content: String,
pub location: Location,
pub end_location: Location,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Fix {
pub patch: Patch,
pub applied: bool,
}
impl Fix {
pub fn deletion(start: Location, end: Location) -> Self {
Self {
patch: Patch {
content: "".to_string(),
location: start,
end_location: end,
},
applied: false,
}
}
pub fn replacement(content: String, start: Location, end: Location) -> Self {
Self {
patch: Patch {
content,
location: start,
end_location: end,
},
applied: false,
}
}
pub fn insertion(content: String, at: Location) -> Self {
Self {
patch: Patch {
content,
location: at,
end_location: at,
},
applied: false,
}
}
}

View file

@ -4,7 +4,8 @@ use rustpython_parser::ast::Location;
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::checks::{Check, CheckCode, CheckKind, Fix};
use crate::autofix::Fix;
use crate::checks::{Check, CheckCode, CheckKind};
use crate::noqa;
use crate::noqa::Directive;
use crate::settings::Settings;
@ -166,15 +167,10 @@ pub fn check_lines(
},
);
if matches!(autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
check.amend(Fix {
content: "".to_string(),
location: Location::new(row + 1, start + 1),
end_location: Location::new(
row + 1,
lines[row].chars().count() + 1,
),
applied: false,
});
check.amend(Fix::deletion(
Location::new(row + 1, start + 1),
Location::new(row + 1, lines[row].chars().count() + 1),
));
}
line_checks.push(check);
}
@ -200,25 +196,16 @@ pub fn check_lines(
);
if matches!(autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
if valid_codes.is_empty() {
check.amend(Fix {
content: "".to_string(),
location: Location::new(row + 1, start + 1),
end_location: Location::new(
row + 1,
lines[row].chars().count() + 1,
),
applied: false,
});
check.amend(Fix::deletion(
Location::new(row + 1, start + 1),
Location::new(row + 1, lines[row].chars().count() + 1),
));
} else {
check.amend(Fix {
content: format!(" # noqa: {}", valid_codes.join(", ")),
location: Location::new(row + 1, start + 1),
end_location: Location::new(
row + 1,
lines[row].chars().count() + 1,
),
applied: false,
});
check.amend(Fix::replacement(
format!(" # noqa: {}", valid_codes.join(", ")),
Location::new(row + 1, start + 1),
Location::new(row + 1, lines[row].chars().count() + 1),
));
}
}
line_checks.push(check);

View file

@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumIter, EnumString};
use crate::ast::types::Range;
use crate::autofix::Fix;
use crate::pyupgrade::types::Primitive;
#[derive(
@ -293,6 +294,7 @@ pub enum CheckKind {
// pydocstyle
BlankLineAfterLastSection(String),
BlankLineAfterSection(String),
BlankLineAfterSummary,
BlankLineBeforeSection(String),
CapitalizeSectionName(String),
DashedUnderlineAfterSection(String),
@ -308,7 +310,6 @@ pub enum CheckKind {
NewLineAfterLastParagraph,
NewLineAfterSectionName(String),
NoBlankLineAfterFunction(usize),
NoBlankLineAfterSummary,
NoBlankLineBeforeClass(usize),
NoBlankLineBeforeFunction(usize),
NoBlankLinesBetweenHeaderAndContent(String),
@ -473,7 +474,7 @@ impl CheckCode {
CheckCode::D202 => CheckKind::NoBlankLineAfterFunction(1),
CheckCode::D203 => CheckKind::OneBlankLineBeforeClass(0),
CheckCode::D204 => CheckKind::OneBlankLineAfterClass(0),
CheckCode::D205 => CheckKind::NoBlankLineAfterSummary,
CheckCode::D205 => CheckKind::BlankLineAfterSummary,
CheckCode::D206 => CheckKind::IndentWithSpaces,
CheckCode::D207 => CheckKind::NoUnderIndentation,
CheckCode::D208 => CheckKind::NoOverIndentation,
@ -756,7 +757,7 @@ impl CheckKind {
CheckKind::NewLineAfterLastParagraph => &CheckCode::D209,
CheckKind::NewLineAfterSectionName(_) => &CheckCode::D406,
CheckKind::NoBlankLineAfterFunction(_) => &CheckCode::D202,
CheckKind::NoBlankLineAfterSummary => &CheckCode::D205,
CheckKind::BlankLineAfterSummary => &CheckCode::D205,
CheckKind::NoBlankLineBeforeClass(_) => &CheckCode::D211,
CheckKind::NoBlankLineBeforeFunction(_) => &CheckCode::D201,
CheckKind::NoBlankLinesBetweenHeaderAndContent(_) => &CheckCode::D412,
@ -1053,7 +1054,7 @@ impl CheckKind {
}
// pydocstyle
CheckKind::FitsOnOneLine => "One-line docstring should fit on one line".to_string(),
CheckKind::NoBlankLineAfterSummary => {
CheckKind::BlankLineAfterSummary => {
"1 blank line required between summary line and description".to_string()
}
CheckKind::NewLineAfterLastParagraph => {
@ -1205,19 +1206,24 @@ impl CheckKind {
self,
CheckKind::BlankLineAfterLastSection(_)
| CheckKind::BlankLineAfterSection(_)
| CheckKind::BlankLineAfterSummary
| CheckKind::BlankLineBeforeSection(_)
| CheckKind::DashedUnderlineAfterSection(_)
| CheckKind::DeprecatedUnittestAlias(_, _)
| CheckKind::DoNotAssertFalse
| CheckKind::DuplicateHandlerException(_)
| CheckKind::NewLineAfterLastParagraph
| CheckKind::NoBlankLineAfterFunction(_)
| CheckKind::NoBlankLineAfterSummary
| CheckKind::NoBlankLineBeforeClass(_)
| CheckKind::NoBlankLineBeforeFunction(_)
| CheckKind::NoBlankLinesBetweenHeaderAndContent(_)
| CheckKind::NoSurroundingWhitespace
| CheckKind::OneBlankLineAfterClass(_)
| CheckKind::OneBlankLineBeforeClass(_)
| CheckKind::PPrintFound
| CheckKind::PrintFound
| CheckKind::SectionUnderlineMatchesSectionLength(_)
| CheckKind::SectionUnderlineNotOverIndented(_)
| CheckKind::SuperCallWithParameters
| CheckKind::TypeOfPrimitive(_)
| CheckKind::UnnecessaryAbspath
@ -1231,43 +1237,6 @@ impl CheckKind {
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Fix {
pub content: String,
pub location: Location,
pub end_location: Location,
pub applied: bool,
}
impl Fix {
pub fn deletion(start: Location, end: Location) -> Self {
Self {
content: "".to_string(),
location: start,
end_location: end,
applied: false,
}
}
pub fn replacement(content: String, start: Location, end: Location) -> Self {
Self {
content,
location: start,
end_location: end,
applied: false,
}
}
pub fn insertion(content: String, at: Location) -> Self {
Self {
content,
location: at,
end_location: at,
applied: false,
}
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Check {
pub kind: CheckKind,
@ -1277,11 +1246,11 @@ pub struct Check {
}
impl Check {
pub fn new(kind: CheckKind, rage: Range) -> Self {
pub fn new(kind: CheckKind, range: Range) -> Self {
Self {
kind,
location: rage.location,
end_location: rage.end_location,
location: range.location,
end_location: range.end_location,
fix: None,
}
}

View file

@ -2,8 +2,9 @@ use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind, Fix};
use crate::checks::{Check, CheckKind};
use crate::code_gen::SourceGenerator;
fn assertion_error(msg: &Option<Box<Expr>>) -> Stmt {
@ -47,12 +48,11 @@ pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: &Optio
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_stmt(&assertion_error(msg)) {
if let Ok(content) = generator.generate() {
check.amend(Fix {
check.amend(Fix::replacement(
content,
location: stmt.location,
end_location: stmt.end_location.unwrap(),
applied: false,
})
stmt.location,
stmt.end_location.unwrap(),
));
}
}
}

View file

@ -6,8 +6,9 @@ use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKi
use crate::ast::helpers;
use crate::ast::types::{CheckLocator, Range};
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckCode, CheckKind, Fix};
use crate::checks::{Check, CheckCode, CheckKind};
use crate::code_gen::SourceGenerator;
fn type_pattern(elts: Vec<&Expr>) -> Expr {
@ -54,12 +55,11 @@ pub fn duplicate_handler_exceptions(
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_expr(&type_pattern(unique_elts), 0) {
if let Ok(content) = generator.generate() {
check.amend(Fix {
check.amend(Fix::replacement(
content,
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
})
expr.location,
expr.end_location.unwrap(),
))
}
}
}

View file

@ -31,7 +31,7 @@ pub fn print_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
&deleted,
) {
Ok(fix) => {
if fix.content.is_empty() || fix.content == "pass" {
if fix.patch.content.is_empty() || fix.patch.content == "pass" {
checker.deletions.insert(context.defined_by);
}
check.amend(fix)

View file

@ -8,8 +8,9 @@ use titlecase::titlecase;
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckCode, CheckKind, Fix};
use crate::checks::{Check, CheckCode, CheckKind};
use crate::docstrings::definition::{Definition, DefinitionKind};
use crate::docstrings::helpers;
use crate::docstrings::sections::{section_contexts, SectionContext};
@ -180,6 +181,7 @@ pub fn blank_before_after_function(checker: &mut Checker, definition: &Definitio
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Delete the blank line before the docstring.
check.amend(Fix::deletion(
Location::new(docstring.location.row() - blank_lines_before, 1),
Location::new(docstring.location.row(), 1),
@ -217,6 +219,7 @@ pub fn blank_before_after_function(checker: &mut Checker, definition: &Definitio
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Delete the blank line after the docstring.
check.amend(Fix::deletion(
Location::new(
docstring.location.row() + 1 + expected_blank_lines_after,
@ -266,6 +269,7 @@ pub fn blank_before_after_class(checker: &mut Checker, definition: &Definition)
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply)
{
// Delete the blank line before the class.
check.amend(Fix::deletion(
Location::new(docstring.location.row() - blank_lines_before, 1),
Location::new(docstring.location.row(), 1),
@ -282,6 +286,7 @@ pub fn blank_before_after_class(checker: &mut Checker, definition: &Definition)
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply)
{
// Insert one blank line before the class.
check.amend(Fix::replacement(
"\n".to_string(),
Location::new(docstring.location.row() - blank_lines_before, 1),
@ -313,6 +318,7 @@ pub fn blank_before_after_class(checker: &mut Checker, definition: &Definition)
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Insert a blank line before the class (replacing any existing lines).
check.amend(Fix::replacement(
"\n".to_string(),
Location::new(docstring.end_location.unwrap().row() + 1, 1),
@ -350,10 +356,11 @@ pub fn blank_after_summary(checker: &mut Checker, definition: &Definition) {
}
if lines_count > 1 && blanks_count != 1 {
let mut check = Check::new(
CheckKind::NoBlankLineAfterSummary,
CheckKind::BlankLineAfterSummary,
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Insert one blank line after the summary (replacing any existing lines).
check.amend(Fix::replacement(
"\n".to_string(),
Location::new(docstring.location.row() + 1, 1),
@ -845,11 +852,23 @@ fn blanks_and_section_underline(
// Nothing but blank lines after the section header.
if blank_lines_after_header == context.following_lines.len() {
if checker.settings.enabled.contains(&CheckCode::D407) {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::DashedUnderlineAfterSection(context.section_name.to_string()),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Add a dashed line (of the appropriate length) under the section header.
let mut content = "".to_string();
content.push_str(helpers::indentation(checker, docstring));
content.push_str(&"-".repeat(context.section_name.len()));
content.push('\n');
check.amend(Fix::insertion(
content,
Location::new(docstring.location.row() + context.original_index + 1, 1),
));
}
checker.add_check(check);
}
if checker.settings.enabled.contains(&CheckCode::D414) {
checker.add_check(Check::new(
CheckKind::NonEmptySection(context.section_name.to_string()),
@ -866,29 +885,69 @@ fn blanks_and_section_underline(
if !dash_line_found {
if checker.settings.enabled.contains(&CheckCode::D407) {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::DashedUnderlineAfterSection(context.section_name.to_string()),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Add a dashed line (of the appropriate length) under the section header.
let mut content = "".to_string();
content.push_str(helpers::indentation(checker, docstring));
content.push_str(&"-".repeat(context.section_name.len()));
content.push('\n');
check.amend(Fix::insertion(
content,
Location::new(docstring.location.row() + context.original_index + 1, 1),
));
}
checker.add_check(check);
}
if blank_lines_after_header > 0 {
if checker.settings.enabled.contains(&CheckCode::D212) {
checker.add_check(Check::new(
if checker.settings.enabled.contains(&CheckCode::D412) {
let mut check = Check::new(
CheckKind::NoBlankLinesBetweenHeaderAndContent(
context.section_name.to_string(),
),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Delete any blank lines between the header and content.
check.amend(Fix::deletion(
Location::new(docstring.location.row() + context.original_index + 1, 1),
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header,
1,
),
));
}
checker.add_check(check);
}
}
} else {
if blank_lines_after_header > 0 {
if checker.settings.enabled.contains(&CheckCode::D408) {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::SectionUnderlineAfterName(context.section_name.to_string()),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Delete any blank lines between the header and the underline.
check.amend(Fix::deletion(
Location::new(docstring.location.row() + context.original_index + 1, 1),
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header,
1,
),
));
}
checker.add_check(check);
}
}
if non_empty_line
@ -899,23 +958,70 @@ fn blanks_and_section_underline(
!= context.section_name.len()
{
if checker.settings.enabled.contains(&CheckCode::D409) {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::SectionUnderlineMatchesSectionLength(
context.section_name.to_string(),
),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Replace the existing underline with a line of the appropriate length.
let mut content = "".to_string();
content.push_str(helpers::indentation(checker, docstring));
content.push_str(&"-".repeat(context.section_name.len()));
content.push('\n');
check.amend(Fix::replacement(
content,
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header,
1,
),
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header
+ 1,
1,
),
));
};
checker.add_check(check);
}
}
if checker.settings.enabled.contains(&CheckCode::D215) {
if helpers::leading_space(non_empty_line).len()
> helpers::indentation(checker, docstring).len()
{
checker.add_check(Check::new(
let leading_space = helpers::leading_space(non_empty_line);
let indentation = helpers::indentation(checker, docstring).to_string();
if leading_space.len() > indentation.len() {
let mut check = Check::new(
CheckKind::SectionUnderlineNotOverIndented(context.section_name.to_string()),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Replace the existing indentation with whitespace of the appropriate length.
check.amend(Fix::replacement(
indentation,
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header,
1,
),
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ blank_lines_after_header,
1 + leading_space.len(),
),
));
};
checker.add_check(check);
}
}
@ -925,7 +1031,11 @@ fn blanks_and_section_underline(
let line_after_dashes = context.following_lines[line_after_dashes_index];
if line_after_dashes.trim().is_empty() {
let rest_of_lines = &context.following_lines[line_after_dashes_index..];
if rest_of_lines.iter().all(|line| line.trim().is_empty()) {
let blank_lines_after_dashes = rest_of_lines
.iter()
.take_while(|line| line.trim().is_empty())
.count();
if blank_lines_after_dashes == rest_of_lines.len() {
if checker.settings.enabled.contains(&CheckCode::D414) {
checker.add_check(Check::new(
CheckKind::NonEmptySection(context.section_name.to_string()),
@ -934,13 +1044,34 @@ fn blanks_and_section_underline(
}
} else {
if checker.settings.enabled.contains(&CheckCode::D412) {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::NoBlankLinesBetweenHeaderAndContent(
context.section_name.to_string(),
),
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Delete any blank lines between the header and content.
check.amend(Fix::deletion(
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ line_after_dashes_index,
1,
),
Location::new(
docstring.location.row()
+ context.original_index
+ 1
+ line_after_dashes_index
+ blank_lines_after_dashes,
1,
),
));
}
checker.add_check(check);
}
}
}
} else {
@ -1003,6 +1134,7 @@ fn common_section(
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Add a newline after the section.
check.amend(Fix::insertion(
"\n".to_string(),
Location::new(
@ -1023,6 +1155,7 @@ fn common_section(
Range::from_located(docstring),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Add a newline after the section.
check.amend(Fix::insertion(
"\n".to_string(),
Location::new(
@ -1032,7 +1165,7 @@ fn common_section(
+ context.following_lines.len(),
1,
),
))
));
}
checker.add_check(check);
}
@ -1041,10 +1174,18 @@ fn common_section(
if checker.settings.enabled.contains(&CheckCode::D411) {
if !context.previous_line.is_empty() {
checker.add_check(Check::new(
let mut check = Check::new(
CheckKind::BlankLineBeforeSection(context.section_name.to_string()),
Range::from_located(docstring),
))
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
// Add a blank line before the section.
check.amend(Fix::insertion(
"\n".to_string(),
Location::new(docstring.location.row() + context.original_index, 1),
));
}
checker.add_check(check)
}
}

View file

@ -5,8 +5,9 @@ use rustpython_ast::{Expr, ExprKind};
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind, Fix};
use crate::checks::{Check, CheckKind};
static DEPRECATED_ALIASES: Lazy<BTreeMap<&'static str, &'static str>> = Lazy::new(|| {
BTreeMap::from([
@ -38,12 +39,11 @@ pub fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) {
Range::from_located(expr),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
check.amend(Fix {
content: format!("self.{}", target),
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
});
check.amend(Fix::replacement(
format!("self.{}", target),
expr.location,
expr.end_location.unwrap(),
));
}
checker.add_check(check);
}

View file

@ -2,8 +2,9 @@ use rustpython_ast::Expr;
use crate::ast::types::{CheckLocator, Range};
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{CheckKind, Fix};
use crate::checks::CheckKind;
use crate::pyupgrade::checks;
pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
@ -12,12 +13,11 @@ pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args:
{
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
if let CheckKind::TypeOfPrimitive(primitive) = &check.kind {
check.amend(Fix {
content: primitive.builtin(),
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
});
check.amend(Fix::replacement(
primitive.builtin(),
expr.location,
expr.end_location.unwrap(),
));
}
}
checker.add_check(check);

View file

@ -2,8 +2,8 @@ use rustpython_ast::Expr;
use crate::ast::types::{CheckLocator, Range};
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::Fix;
use crate::pyupgrade::checks;
pub fn unnecessary_abspath(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
@ -11,12 +11,11 @@ pub fn unnecessary_abspath(checker: &mut Checker, expr: &Expr, func: &Expr, args
checks::unnecessary_abspath(func, args, checker.locate_check(Range::from_located(expr)))
{
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
check.amend(Fix {
content: "__file__".to_string(),
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
});
check.amend(Fix::replacement(
"__file__".to_string(),
expr.location,
expr.end_location.unwrap(),
));
}
checker.add_check(check);
}

View file

@ -2,8 +2,9 @@ use rustpython_ast::Expr;
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind, Fix};
use crate::checks::{Check, CheckKind};
use crate::python::typing;
pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr, id: &str) {
@ -14,12 +15,11 @@ pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr, id: &str) {
Range::from_located(expr),
);
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
check.amend(Fix {
content: id.to_lowercase(),
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
})
check.amend(Fix::replacement(
id.to_lowercase(),
expr.location,
expr.end_location.unwrap(),
));
}
checker.add_check(check);
}

View file

@ -3,8 +3,9 @@ use rustpython_ast::{Constant, Expr, ExprKind, Operator};
use crate::ast::helpers::match_name_or_attr;
use crate::ast::types::Range;
use crate::autofix::fixer;
use crate::autofix::Fix;
use crate::check_ast::Checker;
use crate::checks::{Check, CheckKind, Fix};
use crate::checks::{Check, CheckKind};
use crate::code_gen::SourceGenerator;
fn optional(expr: &Expr) -> Expr {
@ -49,12 +50,11 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_expr(&optional(slice), 0) {
if let Ok(content) = generator.generate() {
check.amend(Fix {
check.amend(Fix::replacement(
content,
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
})
expr.location,
expr.end_location.unwrap(),
))
}
}
}
@ -70,12 +70,11 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_expr(&union(elts), 0) {
if let Ok(content) = generator.generate() {
check.amend(Fix {
check.amend(Fix::replacement(
content,
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
})
expr.location,
expr.end_location.unwrap(),
))
}
}
}
@ -84,12 +83,11 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
let mut generator = SourceGenerator::new();
if let Ok(()) = generator.unparse_expr(slice, 0) {
if let Ok(content) = generator.generate() {
check.amend(Fix {
check.amend(Fix::replacement(
content,
location: expr.location,
end_location: expr.end_location.unwrap(),
applied: false,
});
expr.location,
expr.end_location.unwrap(),
));
}
}
}

View file

@ -26,7 +26,7 @@ pub fn useless_metaclass_type(checker: &mut Checker, stmt: &Stmt, value: &Expr,
&deleted,
) {
Ok(fix) => {
if fix.content.is_empty() || fix.content == "pass" {
if fix.patch.content.is_empty() || fix.patch.content == "pass" {
checker.deletions.insert(context.defined_by);
}
check.amend(fix)

View file

@ -10,6 +10,7 @@ expression: checks
row: 8
column: 13
fix:
patch:
content: raise AssertionError()
location:
row: 8
@ -26,6 +27,7 @@ expression: checks
row: 10
column: 13
fix:
patch:
content: "raise AssertionError('message')"
location:
row: 10

View file

@ -12,6 +12,7 @@ expression: checks
row: 17
column: 25
fix:
patch:
content: "OSError,"
location:
row: 17
@ -30,6 +31,7 @@ expression: checks
row: 28
column: 25
fix:
patch:
content: "MyError,"
location:
row: 28
@ -48,6 +50,7 @@ expression: checks
row: 49
column: 27
fix:
patch:
content: "re.error,"
location:
row: 49

View file

@ -11,6 +11,7 @@ expression: checks
row: 132
column: 25
fix:
patch:
content: ""
location:
row: 131
@ -28,6 +29,7 @@ expression: checks
row: 146
column: 38
fix:
patch:
content: ""
location:
row: 145

View file

@ -11,6 +11,7 @@ expression: checks
row: 79
column: 33
fix:
patch:
content: ""
location:
row: 81
@ -28,6 +29,7 @@ expression: checks
row: 137
column: 25
fix:
patch:
content: ""
location:
row: 138
@ -45,6 +47,7 @@ expression: checks
row: 146
column: 38
fix:
patch:
content: ""
location:
row: 147
@ -62,6 +65,7 @@ expression: checks
row: 453
column: 24
fix:
patch:
content: ""
location:
row: 455

View file

@ -11,6 +11,7 @@ expression: checks
row: 156
column: 33
fix:
patch:
content: "\n"
location:
row: 156
@ -28,6 +29,7 @@ expression: checks
row: 187
column: 46
fix:
patch:
content: "\n"
location:
row: 187
@ -45,6 +47,7 @@ expression: checks
row: 527
column: 8
fix:
patch:
content: "\n"
location:
row: 521

View file

@ -11,6 +11,7 @@ expression: checks
row: 176
column: 25
fix:
patch:
content: "\n"
location:
row: 177
@ -28,6 +29,7 @@ expression: checks
row: 187
column: 46
fix:
patch:
content: "\n"
location:
row: 188

View file

@ -2,7 +2,7 @@
source: src/linter.rs
expression: checks
---
- kind: NoBlankLineAfterSummary
- kind: BlankLineAfterSummary
location:
row: 195
column: 5
@ -10,6 +10,7 @@ expression: checks
row: 198
column: 8
fix:
patch:
content: "\n"
location:
row: 196
@ -18,7 +19,7 @@ expression: checks
row: 196
column: 1
applied: false
- kind: NoBlankLineAfterSummary
- kind: BlankLineAfterSummary
location:
row: 205
column: 5
@ -26,6 +27,7 @@ expression: checks
row: 210
column: 8
fix:
patch:
content: "\n"
location:
row: 206

View file

@ -10,6 +10,7 @@ expression: checks
row: 278
column: 20
fix:
patch:
content: "\n "
location:
row: 278

View file

@ -10,6 +10,7 @@ expression: checks
row: 283
column: 34
fix:
patch:
content: Whitespace at the end.
location:
row: 283
@ -26,6 +27,7 @@ expression: checks
row: 288
column: 38
fix:
patch:
content: Whitespace at everywhere.
location:
row: 288
@ -42,6 +44,7 @@ expression: checks
row: 297
column: 8
fix:
patch:
content: Whitespace at the beginning.
location:
row: 294

View file

@ -11,6 +11,7 @@ expression: checks
row: 165
column: 30
fix:
patch:
content: ""
location:
row: 164
@ -28,6 +29,7 @@ expression: checks
row: 176
column: 25
fix:
patch:
content: ""
location:
row: 175

View file

@ -10,7 +10,16 @@ expression: checks
end_location:
row: 153
column: 8
fix: ~
fix:
patch:
content: " "
location:
row: 150
column: 1
end_location:
row: 150
column: 9
applied: false
- kind:
SectionUnderlineNotOverIndented: Returns
location:
@ -19,5 +28,14 @@ expression: checks
end_location:
row: 165
column: 8
fix: ~
fix:
patch:
content: " "
location:
row: 164
column: 1
end_location:
row: 164
column: 9
applied: false

View file

@ -10,7 +10,16 @@ expression: checks
end_location:
row: 47
column: 8
fix: ~
fix:
patch:
content: " -------\n"
location:
row: 45
column: 1
end_location:
row: 45
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Returns
location:
@ -19,7 +28,16 @@ expression: checks
end_location:
row: 58
column: 8
fix: ~
fix:
patch:
content: " -------\n"
location:
row: 57
column: 1
end_location:
row: 57
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Raises
location:
@ -28,7 +46,16 @@ expression: checks
end_location:
row: 221
column: 8
fix: ~
fix:
patch:
content: " ------\n"
location:
row: 219
column: 1
end_location:
row: 219
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Returns
location:
@ -37,7 +64,16 @@ expression: checks
end_location:
row: 262
column: 8
fix: ~
fix:
patch:
content: " -------\n"
location:
row: 258
column: 1
end_location:
row: 258
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Raises
location:
@ -46,7 +82,16 @@ expression: checks
end_location:
row: 262
column: 8
fix: ~
fix:
patch:
content: " ------\n"
location:
row: 260
column: 1
end_location:
row: 260
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -55,7 +100,16 @@ expression: checks
end_location:
row: 274
column: 8
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 272
column: 1
end_location:
row: 272
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -64,7 +118,16 @@ expression: checks
end_location:
row: 292
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 289
column: 1
end_location:
row: 289
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -73,7 +136,16 @@ expression: checks
end_location:
row: 306
column: 8
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 304
column: 1
end_location:
row: 304
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -82,7 +154,16 @@ expression: checks
end_location:
row: 319
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 316
column: 1
end_location:
row: 316
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -91,7 +172,16 @@ expression: checks
end_location:
row: 330
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 328
column: 1
end_location:
row: 328
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -100,7 +190,16 @@ expression: checks
end_location:
row: 343
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 340
column: 1
end_location:
row: 340
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -109,7 +208,16 @@ expression: checks
end_location:
row: 355
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 353
column: 1
end_location:
row: 353
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -118,7 +226,16 @@ expression: checks
end_location:
row: 367
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 365
column: 1
end_location:
row: 365
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -127,7 +244,16 @@ expression: checks
end_location:
row: 382
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 374
column: 1
end_location:
row: 374
column: 1
applied: false
- kind:
DashedUnderlineAfterSection: Args
location:
@ -136,5 +262,14 @@ expression: checks
end_location:
row: 497
column: 12
fix: ~
fix:
patch:
content: " ----\n"
location:
row: 495
column: 1
end_location:
row: 495
column: 1
applied: false

View file

@ -10,5 +10,14 @@ expression: checks
end_location:
row: 92
column: 8
fix: ~
fix:
patch:
content: ""
location:
row: 88
column: 1
end_location:
row: 89
column: 1
applied: false

View file

@ -10,7 +10,16 @@ expression: checks
end_location:
row: 105
column: 8
fix: ~
fix:
patch:
content: " -------\n"
location:
row: 102
column: 1
end_location:
row: 103
column: 1
applied: false
- kind:
SectionUnderlineMatchesSectionLength: Returns
location:
@ -19,5 +28,14 @@ expression: checks
end_location:
row: 221
column: 8
fix: ~
fix:
patch:
content: " -------\n"
location:
row: 216
column: 1
end_location:
row: 217
column: 1
applied: false

View file

@ -11,6 +11,7 @@ expression: checks
row: 78
column: 8
fix:
patch:
content: "\n"
location:
row: 71
@ -28,6 +29,7 @@ expression: checks
row: 221
column: 8
fix:
patch:
content: "\n"
location:
row: 218

View file

@ -10,7 +10,16 @@ expression: checks
end_location:
row: 78
column: 8
fix: ~
fix:
patch:
content: "\n"
location:
row: 71
column: 1
end_location:
row: 71
column: 1
applied: false
- kind:
BlankLineBeforeSection: Returns
location:
@ -19,7 +28,16 @@ expression: checks
end_location:
row: 129
column: 8
fix: ~
fix:
patch:
content: "\n"
location:
row: 125
column: 1
end_location:
row: 125
column: 1
applied: false
- kind:
BlankLineBeforeSection: Raises
location:
@ -28,5 +46,14 @@ expression: checks
end_location:
row: 221
column: 8
fix: ~
fix:
patch:
content: "\n"
location:
row: 218
column: 1
end_location:
row: 218
column: 1
applied: false

View file

@ -10,5 +10,14 @@ expression: checks
end_location:
row: 221
column: 8
fix: ~
fix:
patch:
content: ""
location:
row: 211
column: 1
end_location:
row: 212
column: 1
applied: false

View file

@ -12,6 +12,7 @@ expression: checks
row: 2
column: 21
fix:
patch:
content: import os
location:
row: 2
@ -30,6 +31,7 @@ expression: checks
row: 8
column: 2
fix:
patch:
content: "from collections import (\n Counter,\n namedtuple,\n)"
location:
row: 4
@ -48,6 +50,7 @@ expression: checks
row: 12
column: 24
fix:
patch:
content: import logging.handlers
location:
row: 12
@ -66,6 +69,7 @@ expression: checks
row: 33
column: 18
fix:
patch:
content: ""
location:
row: 33
@ -84,6 +88,7 @@ expression: checks
row: 34
column: 21
fix:
patch:
content: ""
location:
row: 34
@ -102,6 +107,7 @@ expression: checks
row: 38
column: 19
fix:
patch:
content: ""
location:
row: 38
@ -120,6 +126,7 @@ expression: checks
row: 53
column: 22
fix:
patch:
content: pass
location:
row: 53

View file

@ -10,6 +10,7 @@ expression: checks
row: 1
column: 23
fix:
patch:
content: ""
location:
row: 1

View file

@ -10,6 +10,7 @@ expression: checks
row: 3
column: 24
fix:
patch:
content: ""
location:
row: 3
@ -26,6 +27,7 @@ expression: checks
row: 8
column: 31
fix:
patch:
content: ""
location:
row: 8

View file

@ -10,6 +10,7 @@ expression: checks
row: 2
column: 25
fix:
patch:
content: pass
location:
row: 2
@ -26,6 +27,7 @@ expression: checks
row: 6
column: 25
fix:
patch:
content: ""
location:
row: 6

View file

@ -10,6 +10,7 @@ expression: checks
row: 3
column: 22
fix:
patch:
content: __file__
location:
row: 3
@ -26,6 +27,7 @@ expression: checks
row: 9
column: 30
fix:
patch:
content: __file__
location:
row: 9
@ -42,6 +44,7 @@ expression: checks
row: 15
column: 27
fix:
patch:
content: __file__
location:
row: 15

View file

@ -11,6 +11,7 @@ expression: checks
row: 1
column: 9
fix:
patch:
content: str
location:
row: 1
@ -28,6 +29,7 @@ expression: checks
row: 2
column: 10
fix:
patch:
content: bytes
location:
row: 2
@ -45,6 +47,7 @@ expression: checks
row: 3
column: 8
fix:
patch:
content: int
location:
row: 3
@ -62,6 +65,7 @@ expression: checks
row: 4
column: 9
fix:
patch:
content: float
location:
row: 4
@ -79,6 +83,7 @@ expression: checks
row: 5
column: 9
fix:
patch:
content: complex
location:
row: 5

View file

@ -11,6 +11,7 @@ expression: checks
row: 5
column: 15
fix:
patch:
content: ""
location:
row: 5
@ -28,6 +29,7 @@ expression: checks
row: 10
column: 11
fix:
patch:
content: ""
location:
row: 9
@ -45,6 +47,7 @@ expression: checks
row: 16
column: 11
fix:
patch:
content: ""
location:
row: 15
@ -62,6 +65,7 @@ expression: checks
row: 24
column: 11
fix:
patch:
content: ""
location:
row: 22
@ -79,6 +83,7 @@ expression: checks
row: 31
column: 11
fix:
patch:
content: ""
location:
row: 29
@ -96,6 +101,7 @@ expression: checks
row: 37
column: 11
fix:
patch:
content: ""
location:
row: 36
@ -113,6 +119,7 @@ expression: checks
row: 45
column: 11
fix:
patch:
content: ""
location:
row: 43
@ -130,6 +137,7 @@ expression: checks
row: 53
column: 11
fix:
patch:
content: ""
location:
row: 51
@ -147,6 +155,7 @@ expression: checks
row: 61
column: 11
fix:
patch:
content: ""
location:
row: 59
@ -164,6 +173,7 @@ expression: checks
row: 69
column: 11
fix:
patch:
content: ""
location:
row: 67
@ -181,6 +191,7 @@ expression: checks
row: 75
column: 18
fix:
patch:
content: ""
location:
row: 75
@ -198,6 +209,7 @@ expression: checks
row: 79
column: 15
fix:
patch:
content: ""
location:
row: 79
@ -215,6 +227,7 @@ expression: checks
row: 84
column: 11
fix:
patch:
content: ""
location:
row: 84
@ -232,6 +245,7 @@ expression: checks
row: 92
column: 11
fix:
patch:
content: ""
location:
row: 91
@ -249,6 +263,7 @@ expression: checks
row: 98
column: 11
fix:
patch:
content: ""
location:
row: 98
@ -266,6 +281,7 @@ expression: checks
row: 108
column: 11
fix:
patch:
content: ""
location:
row: 107
@ -283,6 +299,7 @@ expression: checks
row: 114
column: 19
fix:
patch:
content: ""
location:
row: 114
@ -300,6 +317,7 @@ expression: checks
row: 119
column: 11
fix:
patch:
content: ""
location:
row: 118
@ -317,6 +335,7 @@ expression: checks
row: 125
column: 11
fix:
patch:
content: ""
location:
row: 124
@ -334,6 +353,7 @@ expression: checks
row: 131
column: 11
fix:
patch:
content: ""
location:
row: 130

View file

@ -13,6 +13,7 @@ expression: checks
row: 6
column: 26
fix:
patch:
content: self.assertEqual
location:
row: 6
@ -32,6 +33,7 @@ expression: checks
row: 7
column: 26
fix:
patch:
content: self.assertEqual
location:
row: 7
@ -51,6 +53,7 @@ expression: checks
row: 9
column: 35
fix:
patch:
content: self.assertAlmostEqual
location:
row: 9
@ -70,6 +73,7 @@ expression: checks
row: 10
column: 36
fix:
patch:
content: self.assertNotRegex
location:
row: 10

View file

@ -11,6 +11,7 @@ expression: checks
row: 4
column: 14
fix:
patch:
content: list
location:
row: 4
@ -28,6 +29,7 @@ expression: checks
row: 11
column: 21
fix:
patch:
content: list
location:
row: 11

View file

@ -10,6 +10,7 @@ expression: checks
row: 4
column: 23
fix:
patch:
content: str | None
location:
row: 4
@ -26,6 +27,7 @@ expression: checks
row: 11
column: 30
fix:
patch:
content: str | None
location:
row: 11
@ -42,6 +44,7 @@ expression: checks
row: 18
column: 46
fix:
patch:
content: "str | int | Union[float, bytes]"
location:
row: 18
@ -58,6 +61,7 @@ expression: checks
row: 18
column: 45
fix:
patch:
content: float | bytes
location:
row: 18
@ -74,6 +78,7 @@ expression: checks
row: 25
column: 32
fix:
patch:
content: str | int
location:
row: 25
@ -90,6 +95,7 @@ expression: checks
row: 32
column: 48
fix:
patch:
content: "str | int | Union[float, bytes]"
location:
row: 32
@ -106,6 +112,7 @@ expression: checks
row: 32
column: 48
fix:
patch:
content: float | bytes
location:
row: 32
@ -122,6 +129,7 @@ expression: checks
row: 39
column: 34
fix:
patch:
content: str | int
location:
row: 39

View file

@ -10,6 +10,7 @@ expression: checks
row: 17
column: 36
fix:
patch:
content: super()
location:
row: 17
@ -26,6 +27,7 @@ expression: checks
row: 18
column: 27
fix:
patch:
content: super()
location:
row: 18
@ -42,6 +44,7 @@ expression: checks
row: 22
column: 10
fix:
patch:
content: super()
location:
row: 19
@ -58,6 +61,7 @@ expression: checks
row: 36
column: 29
fix:
patch:
content: super()
location:
row: 36
@ -74,6 +78,7 @@ expression: checks
row: 50
column: 33
fix:
patch:
content: super()
location:
row: 50

View file

@ -12,6 +12,7 @@ expression: checks
row: 8
column: 2
fix:
patch:
content: "from models import (\n Fruit,\n)"
location:
row: 5

View file

@ -11,6 +11,7 @@ expression: checks
row: 9
column: 18
fix:
patch:
content: ""
location:
row: 9
@ -29,6 +30,7 @@ expression: checks
row: 13
column: 24
fix:
patch:
content: ""
location:
row: 13
@ -48,6 +50,7 @@ expression: checks
row: 16
column: 30
fix:
patch:
content: ""
location:
row: 16
@ -66,6 +69,7 @@ expression: checks
row: 19
column: 30
fix:
patch:
content: " # noqa: F841"
location:
row: 19
@ -84,6 +88,7 @@ expression: checks
row: 44
column: 24
fix:
patch:
content: " # noqa: E501"
location:
row: 44
@ -102,6 +107,7 @@ expression: checks
row: 52
column: 18
fix:
patch:
content: ""
location:
row: 52
@ -119,6 +125,7 @@ expression: checks
row: 60
column: 12
fix:
patch:
content: ""
location:
row: 60