diff --git a/LICENSE b/LICENSE index 55b0536418..41f4d4c2c0 100644 --- a/LICENSE +++ b/LICENSE @@ -388,6 +388,31 @@ are: SOFTWARE. """ +- flake8-implicit-str-concat, licensed as follows: + """ + The MIT License (MIT) + + Copyright (c) 2019 Dylan Turner + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + """ + - flake8-import-conventions, licensed as follows: """ MIT License diff --git a/README.md b/README.md index 431191bfd5..8226cca8be 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ of [Conda](https://docs.conda.io/en/latest/): 1. [flake8-comprehensions (C4)](#flake8-comprehensions-c4) 1. [flake8-debugger (T10)](#flake8-debugger-t10) 1. [flake8-errmsg (EM)](#flake8-errmsg-em) + 1. [flake8-implicit-str-concat (ISC)](#flake8-implicit-str-concat-isc) 1. [flake8-import-conventions (ICN)](#flake8-import-conventions-icn) 1. [flake8-print (T20)](#flake8-print-t20) 1. [flake8-quotes (Q)](#flake8-quotes-q) @@ -854,6 +855,16 @@ For more, see [flake8-errmsg](https://pypi.org/project/flake8-errmsg/0.4.0/) on | EM102 | FStringInException | Exception must not use an f-string literal, assign to variable first | | | EM103 | DotFormatInException | Exception must not use a `.format()` string directly, assign to variable first | | +### flake8-implicit-str-concat (ISC) + +For more, see [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/0.3.0/) on PyPI. + +| Code | Name | Message | Fix | +| ---- | ---- | ------- | --- | +| ISC001 | SingleLineImplicitStringConcatenation | Implicitly concatenated string literals on one line | | +| ISC002 | MultiLineImplicitStringConcatenation | Implicitly concatenated string literals over continuation line | | +| ISC003 | ExplicitStringConcatenation | Explicitly concatenated string should be implicitly concatenated | | + ### flake8-import-conventions (ICN) | Code | Name | Message | Fix | @@ -1274,6 +1285,7 @@ natively, including: - [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) - [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/) - [`flake8-errmsg`](https://pypi.org/project/flake8-errmsg/) +- [`flake8-implicit-str-concat`](https://pypi.org/project/flake8-implicit-str-concat/) - [`flake8-import-conventions`](https://github.com/joaopalmeiro/flake8-import-conventions) - [`flake8-print`](https://pypi.org/project/flake8-print/) - [`flake8-quotes`](https://pypi.org/project/flake8-quotes/) @@ -1330,6 +1342,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl - [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) - [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/) - [`flake8-errmsg`](https://pypi.org/project/flake8-errmsg/) +- [`flake8-implicit-str-concat`](https://pypi.org/project/flake8-implicit-str-concat/) - [`flake8-import-conventions`](https://github.com/joaopalmeiro/flake8-import-conventions) - [`flake8-print`](https://pypi.org/project/flake8-print/) - [`flake8-quotes`](https://pypi.org/project/flake8-quotes/) diff --git a/flake8_to_ruff/src/plugin.rs b/flake8_to_ruff/src/plugin.rs index 0f8bf4b56c..71dac778f9 100644 --- a/flake8_to_ruff/src/plugin.rs +++ b/flake8_to_ruff/src/plugin.rs @@ -16,16 +16,17 @@ pub enum Plugin { Flake8Datetimez, Flake8Debugger, Flake8Docstrings, - Flake8ErrMsg, Flake8Eradicate, + Flake8ErrMsg, + Flake8ImplicitStrConcat, Flake8Print, Flake8Quotes, Flake8Return, Flake8Simplify, Flake8TidyImports, McCabe, - PandasVet, PEP8Naming, + PandasVet, Pyupgrade, } @@ -45,6 +46,7 @@ impl FromStr for Plugin { "flake8-docstrings" => Ok(Plugin::Flake8Docstrings), "flake8-eradicate" => Ok(Plugin::Flake8Eradicate), "flake8-errmsg" => Ok(Plugin::Flake8ErrMsg), + "flake8-implicit-str-concat" => Ok(Plugin::Flake8ImplicitStrConcat), "flake8-print" => Ok(Plugin::Flake8Print), "flake8-quotes" => Ok(Plugin::Flake8Quotes), "flake8-return" => Ok(Plugin::Flake8Return), @@ -76,14 +78,15 @@ impl fmt::Debug for Plugin { Plugin::Flake8Docstrings => "flake8-docstrings", Plugin::Flake8Eradicate => "flake8-eradicate", Plugin::Flake8ErrMsg => "flake8-errmsg", + Plugin::Flake8ImplicitStrConcat => "flake8-implicit-str-concat", Plugin::Flake8Print => "flake8-print", Plugin::Flake8Quotes => "flake8-quotes", Plugin::Flake8Return => "flake8-return", Plugin::Flake8Simplify => "flake8-simplify", Plugin::Flake8TidyImports => "flake8-tidy-imports", Plugin::McCabe => "mccabe", - Plugin::PandasVet => "pandas-vet", Plugin::PEP8Naming => "pep8-naming", + Plugin::PandasVet => "pandas-vet", Plugin::Pyupgrade => "pyupgrade", } ) @@ -106,6 +109,7 @@ impl Plugin { // TODO(charlie): Handle rename of `E` to `ERA`. Plugin::Flake8Eradicate => CheckCodePrefix::ERA, Plugin::Flake8ErrMsg => CheckCodePrefix::EM, + Plugin::Flake8ImplicitStrConcat => CheckCodePrefix::ISC, Plugin::Flake8Print => CheckCodePrefix::T2, Plugin::Flake8Quotes => CheckCodePrefix::Q, Plugin::Flake8Return => CheckCodePrefix::RET, @@ -146,6 +150,7 @@ impl Plugin { } Plugin::Flake8Eradicate => vec![CheckCodePrefix::ERA], Plugin::Flake8ErrMsg => vec![CheckCodePrefix::EM], + Plugin::Flake8ImplicitStrConcat => vec![CheckCodePrefix::ISC], Plugin::Flake8Print => vec![CheckCodePrefix::T2], Plugin::Flake8Quotes => vec![CheckCodePrefix::Q], Plugin::Flake8Return => vec![CheckCodePrefix::RET], @@ -449,6 +454,7 @@ pub fn infer_plugins_from_codes(codes: &BTreeSet) -> Vec { + if self.settings.enabled.contains(&CheckCode::ISC003) { + if let Some(check) = flake8_implicit_str_concat::checks::explicit(expr) { + self.add_check(check); + } + } + } ExprKind::UnaryOp { op, operand } => { let check_not_in = self.settings.enabled.contains(&CheckCode::E713); let check_not_is = self.settings.enabled.contains(&CheckCode::E714); diff --git a/src/checkers/tokens.rs b/src/checkers/tokens.rs index eacf330715..bd03f5f708 100644 --- a/src/checkers/tokens.rs +++ b/src/checkers/tokens.rs @@ -7,7 +7,7 @@ use crate::lex::docstring_detection::StateMachine; use crate::ruff::checks::Context; use crate::settings::flags; use crate::source_code_locator::SourceCodeLocator; -use crate::{eradicate, flake8_quotes, pycodestyle, ruff, Settings}; +use crate::{eradicate, flake8_implicit_str_concat, flake8_quotes, pycodestyle, ruff, Settings}; pub fn check_tokens( locator: &SourceCodeLocator, @@ -26,6 +26,8 @@ pub fn check_tokens( || settings.enabled.contains(&CheckCode::Q003); let enforce_commented_out_code = settings.enabled.contains(&CheckCode::ERA001); let enforce_invalid_escape_sequence = settings.enabled.contains(&CheckCode::W605); + let enforce_implicit_string_concatenation = settings.enabled.contains(&CheckCode::ISC001) + || settings.enabled.contains(&CheckCode::ISC002); let mut state_machine = StateMachine::default(); for &(start, ref tok, end) in tokens.iter().flatten() { @@ -99,5 +101,14 @@ pub fn check_tokens( } } + // ISC001, ISC002 + if enforce_implicit_string_concatenation { + checks.extend( + flake8_implicit_str_concat::checks::implicit(tokens, locator) + .into_iter() + .filter(|check| settings.enabled.contains(check.kind.code())), + ); + } + checks } diff --git a/src/checks.rs b/src/checks.rs index 2ccf38bcb2..3701cd2018 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -176,6 +176,10 @@ pub enum CheckCode { RET506, RET507, RET508, + // flake8-implicit-str-concat + ISC001, + ISC002, + ISC003, // flake8-print T201, T203, @@ -377,6 +381,7 @@ pub enum CheckCategory { Flake8Comprehensions, Flake8Debugger, Flake8ErrMsg, + Flake8ImplicitStrConcat, Flake8ImportConventions, Flake8Print, Flake8Quotes, @@ -420,6 +425,7 @@ impl CheckCategory { CheckCategory::Flake8Comprehensions => "flake8-comprehensions", CheckCategory::Flake8Debugger => "flake8-debugger", CheckCategory::Flake8ErrMsg => "flake8-errmsg", + CheckCategory::Flake8ImplicitStrConcat => "flake8-implicit-str-concat", CheckCategory::Flake8ImportConventions => "flake8-import-conventions", CheckCategory::Flake8Print => "flake8-print", CheckCategory::Flake8Quotes => "flake8-quotes", @@ -453,19 +459,21 @@ impl CheckCategory { CheckCategory::Flake8Bugbear => vec![CheckCodePrefix::B], CheckCategory::Flake8Builtins => vec![CheckCodePrefix::A], CheckCategory::Flake8Comprehensions => vec![CheckCodePrefix::C4], + CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ], CheckCategory::Flake8Debugger => vec![CheckCodePrefix::T10], CheckCategory::Flake8ErrMsg => vec![CheckCodePrefix::EM], + CheckCategory::Flake8ImplicitStrConcat => vec![CheckCodePrefix::ISC], + CheckCategory::Flake8ImportConventions => vec![CheckCodePrefix::ICN], CheckCategory::Flake8Print => vec![CheckCodePrefix::T20], CheckCategory::Flake8Quotes => vec![CheckCodePrefix::Q], CheckCategory::Flake8Return => vec![CheckCodePrefix::RET], CheckCategory::Flake8Simplify => vec![CheckCodePrefix::SIM], CheckCategory::Flake8TidyImports => vec![CheckCodePrefix::TID], CheckCategory::Flake8UnusedArguments => vec![CheckCodePrefix::ARG], - CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ], CheckCategory::Isort => vec![CheckCodePrefix::I], CheckCategory::McCabe => vec![CheckCodePrefix::C90], - CheckCategory::PandasVet => vec![CheckCodePrefix::PD], CheckCategory::PEP8Naming => vec![CheckCodePrefix::N], + CheckCategory::PandasVet => vec![CheckCodePrefix::PD], CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W], CheckCategory::Pydocstyle => vec![CheckCodePrefix::D], CheckCategory::Pyflakes => vec![CheckCodePrefix::F], @@ -477,7 +485,6 @@ impl CheckCategory { CheckCodePrefix::PLW, ], CheckCategory::Pyupgrade => vec![CheckCodePrefix::UP], - CheckCategory::Flake8ImportConventions => vec![CheckCodePrefix::ICN], CheckCategory::Ruff => vec![CheckCodePrefix::RUF], } } @@ -527,6 +534,10 @@ impl CheckCategory { "https://pypi.org/project/flake8-errmsg/0.4.0/", &Platform::PyPI, )), + CheckCategory::Flake8ImplicitStrConcat => Some(( + "https://pypi.org/project/flake8-implicit-str-concat/0.3.0/", + &Platform::PyPI, + )), CheckCategory::Flake8ImportConventions => None, CheckCategory::Flake8Print => Some(( "https://pypi.org/project/flake8-print/5.0.0/", @@ -796,6 +807,10 @@ pub enum CheckKind { SuperfluousElseRaise(Branch), SuperfluousElseContinue(Branch), SuperfluousElseBreak(Branch), + // flake8-implicit-str-concat + SingleLineImplicitStringConcatenation, + MultiLineImplicitStringConcatenation, + ExplicitStringConcatenation, // flake8-print PrintFound, PPrintFound, @@ -992,6 +1007,8 @@ impl CheckCode { | CheckCode::PGH003 | CheckCode::PGH004 => &LintSource::Lines, CheckCode::ERA001 + | CheckCode::ISC001 + | CheckCode::ISC002 | CheckCode::Q000 | CheckCode::Q001 | CheckCode::Q002 @@ -1180,6 +1197,10 @@ impl CheckCode { CheckCode::RET506 => CheckKind::SuperfluousElseRaise(Branch::Else), CheckCode::RET507 => CheckKind::SuperfluousElseContinue(Branch::Else), CheckCode::RET508 => CheckKind::SuperfluousElseBreak(Branch::Else), + // flake8-implicit-str-concat + CheckCode::ISC001 => CheckKind::SingleLineImplicitStringConcatenation, + CheckCode::ISC002 => CheckKind::MultiLineImplicitStringConcatenation, + CheckCode::ISC003 => CheckKind::ExplicitStringConcatenation, // flake8-print CheckCode::T201 => CheckKind::PrintFound, CheckCode::T203 => CheckKind::PPrintFound, @@ -1576,9 +1597,10 @@ impl CheckCode { CheckCode::FBT002 => CheckCategory::Flake8BooleanTrap, CheckCode::FBT003 => CheckCategory::Flake8BooleanTrap, CheckCode::I001 => CheckCategory::Isort, - CheckCode::TID251 => CheckCategory::Flake8TidyImports, - CheckCode::TID252 => CheckCategory::Flake8TidyImports, CheckCode::ICN001 => CheckCategory::Flake8ImportConventions, + CheckCode::ISC001 => CheckCategory::Flake8ImplicitStrConcat, + CheckCode::ISC002 => CheckCategory::Flake8ImplicitStrConcat, + CheckCode::ISC003 => CheckCategory::Flake8ImplicitStrConcat, CheckCode::N801 => CheckCategory::PEP8Naming, CheckCode::N802 => CheckCategory::PEP8Naming, CheckCode::N803 => CheckCategory::PEP8Naming, @@ -1649,6 +1671,8 @@ impl CheckCode { CheckCode::T100 => CheckCategory::Flake8Debugger, CheckCode::T201 => CheckCategory::Flake8Print, CheckCode::T203 => CheckCategory::Flake8Print, + CheckCode::TID251 => CheckCategory::Flake8TidyImports, + CheckCode::TID252 => CheckCategory::Flake8TidyImports, CheckCode::UP001 => CheckCategory::Pyupgrade, CheckCode::UP003 => CheckCategory::Pyupgrade, CheckCode::UP004 => CheckCategory::Pyupgrade, @@ -1834,6 +1858,10 @@ impl CheckKind { CheckKind::SuperfluousElseRaise(..) => &CheckCode::RET506, CheckKind::SuperfluousElseContinue(..) => &CheckCode::RET507, CheckKind::SuperfluousElseBreak(..) => &CheckCode::RET508, + // flake8-implicit-str-concat + CheckKind::SingleLineImplicitStringConcatenation => &CheckCode::ISC001, + CheckKind::MultiLineImplicitStringConcatenation => &CheckCode::ISC002, + CheckKind::ExplicitStringConcatenation => &CheckCode::ISC003, // flake8-print CheckKind::PrintFound => &CheckCode::T201, CheckKind::PPrintFound => &CheckCode::T203, @@ -2484,6 +2512,16 @@ impl CheckKind { CheckKind::SuperfluousElseBreak(branch) => { format!("Unnecessary `{branch}` after `break` statement") } + // flake8-implicit-str-concat + CheckKind::SingleLineImplicitStringConcatenation => { + "Implicitly concatenated string literals on one line".to_string() + } + CheckKind::MultiLineImplicitStringConcatenation => { + "Implicitly concatenated string literals over continuation line".to_string() + } + CheckKind::ExplicitStringConcatenation => { + "Explicitly concatenated string should be implicitly concatenated".to_string() + } // flake8-print CheckKind::PrintFound => "`print` found".to_string(), CheckKind::PPrintFound => "`pprint` found".to_string(), diff --git a/src/checks_gen.rs b/src/checks_gen.rs index 7cf9ef2faa..86e2d49641 100644 --- a/src/checks_gen.rs +++ b/src/checks_gen.rs @@ -314,6 +314,12 @@ pub enum CheckCodePrefix { ICN0, ICN00, ICN001, + ISC, + ISC0, + ISC00, + ISC001, + ISC002, + ISC003, M, M0, M001, @@ -717,6 +723,9 @@ impl CheckCodePrefix { CheckCode::RET506, CheckCode::RET507, CheckCode::RET508, + CheckCode::ISC001, + CheckCode::ISC002, + CheckCode::ISC003, CheckCode::T201, CheckCode::T203, CheckCode::Q000, @@ -1744,6 +1753,12 @@ impl CheckCodePrefix { CheckCodePrefix::ICN0 => vec![CheckCode::ICN001], CheckCodePrefix::ICN00 => vec![CheckCode::ICN001], CheckCodePrefix::ICN001 => vec![CheckCode::ICN001], + CheckCodePrefix::ISC => vec![CheckCode::ISC001, CheckCode::ISC002, CheckCode::ISC003], + CheckCodePrefix::ISC0 => vec![CheckCode::ISC001, CheckCode::ISC002, CheckCode::ISC003], + CheckCodePrefix::ISC00 => vec![CheckCode::ISC001, CheckCode::ISC002, CheckCode::ISC003], + CheckCodePrefix::ISC001 => vec![CheckCode::ISC001], + CheckCodePrefix::ISC002 => vec![CheckCode::ISC002], + CheckCodePrefix::ISC003 => vec![CheckCode::ISC003], CheckCodePrefix::M => { one_time_warning!( "{}{} {}", @@ -3118,6 +3133,12 @@ impl CheckCodePrefix { CheckCodePrefix::ICN0 => SuffixLength::One, CheckCodePrefix::ICN00 => SuffixLength::Two, CheckCodePrefix::ICN001 => SuffixLength::Three, + CheckCodePrefix::ISC => SuffixLength::Zero, + CheckCodePrefix::ISC0 => SuffixLength::One, + CheckCodePrefix::ISC00 => SuffixLength::Two, + CheckCodePrefix::ISC001 => SuffixLength::Three, + CheckCodePrefix::ISC002 => SuffixLength::Three, + CheckCodePrefix::ISC003 => SuffixLength::Three, CheckCodePrefix::M => SuffixLength::Zero, CheckCodePrefix::M0 => SuffixLength::One, CheckCodePrefix::M001 => SuffixLength::Three, @@ -3386,6 +3407,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[ CheckCodePrefix::FBT, CheckCodePrefix::I, CheckCodePrefix::ICN, + CheckCodePrefix::ISC, CheckCodePrefix::N, CheckCodePrefix::PD, CheckCodePrefix::PGH, diff --git a/src/flake8_implicit_str_concat/checks.rs b/src/flake8_implicit_str_concat/checks.rs new file mode 100644 index 0000000000..7e22629269 --- /dev/null +++ b/src/flake8_implicit_str_concat/checks.rs @@ -0,0 +1,73 @@ +use itertools::Itertools; +use rustpython_ast::{Constant, Expr, ExprKind, Location, Operator}; +use rustpython_parser::lexer::{LexResult, Tok}; + +use crate::ast::types::Range; +use crate::checks::{Check, CheckKind}; +use crate::source_code_locator::SourceCodeLocator; + +/// ISC001, ISC002 +pub fn implicit(tokens: &[LexResult], locator: &SourceCodeLocator) -> Vec { + let mut checks = vec![]; + for ((a_start, a_tok, a_end), (b_start, b_tok, b_end)) in + tokens.iter().flatten().tuple_windows() + { + if matches!(a_tok, Tok::String { .. }) && matches!(b_tok, Tok::String { .. }) { + if a_end.row() == b_start.row() { + checks.push(Check::new( + CheckKind::SingleLineImplicitStringConcatenation, + Range { + location: *a_start, + end_location: *b_end, + }, + )); + } else { + // TODO(charlie): The RustPython tokenization doesn't differentiate between + // continuations and newlines, so we have to detect them manually. + let contents = locator.slice_source_code_range(&Range { + location: *a_end, + end_location: Location::new(a_end.row() + 1, 0), + }); + if contents.trim().ends_with('\\') { + checks.push(Check::new( + CheckKind::MultiLineImplicitStringConcatenation, + Range { + location: *a_start, + end_location: *b_end, + }, + )); + } + } + } + } + checks +} + +/// ISC003 +pub fn explicit(expr: &Expr) -> Option { + if let ExprKind::BinOp { left, op, right } = &expr.node { + if matches!(op, Operator::Add) { + if matches!( + left.node, + ExprKind::JoinedStr { .. } + | ExprKind::Constant { + value: Constant::Str(..) | Constant::Bytes(..), + .. + } + ) && matches!( + right.node, + ExprKind::JoinedStr { .. } + | ExprKind::Constant { + value: Constant::Str(..) | Constant::Bytes(..), + .. + } + ) { + return Some(Check::new( + CheckKind::ExplicitStringConcatenation, + Range::from_located(expr), + )); + } + } + } + None +} diff --git a/src/flake8_implicit_str_concat/mod.rs b/src/flake8_implicit_str_concat/mod.rs new file mode 100644 index 0000000000..91e6073043 --- /dev/null +++ b/src/flake8_implicit_str_concat/mod.rs @@ -0,0 +1,30 @@ +pub mod checks; + +#[cfg(test)] +mod tests { + use std::convert::AsRef; + use std::path::Path; + + use anyhow::Result; + use test_case::test_case; + + use crate::checks::CheckCode; + use crate::linter::test_path; + use crate::settings; + + #[test_case(CheckCode::ISC001, Path::new("ISC.py"); "ISC001")] + #[test_case(CheckCode::ISC002, Path::new("ISC.py"); "ISC002")] + #[test_case(CheckCode::ISC003, Path::new("ISC.py"); "ISC003")] + fn checks(check_code: CheckCode, path: &Path) -> Result<()> { + let snapshot = format!("{}_{}", check_code.as_ref(), path.to_string_lossy()); + let mut checks = test_path( + Path::new("./resources/test/fixtures/flake8_implicit_str_concat") + .join(path) + .as_path(), + &settings::Settings::for_rule(check_code), + )?; + checks.sort_by_key(|check| check.location); + insta::assert_yaml_snapshot!(snapshot, checks); + Ok(()) + } +} diff --git a/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap new file mode 100644 index 0000000000..2d933a5784 --- /dev/null +++ b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC001_ISC.py.snap @@ -0,0 +1,21 @@ +--- +source: src/flake8_implicit_str_concat/mod.rs +expression: checks +--- +- kind: SingleLineImplicitStringConcatenation + location: + row: 1 + column: 4 + end_location: + row: 1 + column: 11 + fix: ~ +- kind: SingleLineImplicitStringConcatenation + location: + row: 1 + column: 8 + end_location: + row: 1 + column: 15 + fix: ~ + diff --git a/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap new file mode 100644 index 0000000000..71283cb3d0 --- /dev/null +++ b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC002_ISC.py.snap @@ -0,0 +1,13 @@ +--- +source: src/flake8_implicit_str_concat/mod.rs +expression: checks +--- +- kind: MultiLineImplicitStringConcatenation + location: + row: 5 + column: 4 + end_location: + row: 6 + column: 9 + fix: ~ + diff --git a/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap new file mode 100644 index 0000000000..95ccb7d67b --- /dev/null +++ b/src/flake8_implicit_str_concat/snapshots/ruff__flake8_implicit_str_concat__tests__ISC003_ISC.py.snap @@ -0,0 +1,37 @@ +--- +source: src/flake8_implicit_str_concat/mod.rs +expression: checks +--- +- kind: ExplicitStringConcatenation + location: + row: 3 + column: 4 + end_location: + row: 3 + column: 17 + fix: ~ +- kind: ExplicitStringConcatenation + location: + row: 9 + column: 2 + end_location: + row: 10 + column: 7 + fix: ~ +- kind: ExplicitStringConcatenation + location: + row: 14 + column: 2 + end_location: + row: 15 + column: 7 + fix: ~ +- kind: ExplicitStringConcatenation + location: + row: 19 + column: 2 + end_location: + row: 20 + column: 8 + fix: ~ + diff --git a/src/lib.rs b/src/lib.rs index fb7cc9decf..6c8292892c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,7 @@ mod flake8_comprehensions; mod flake8_datetimez; mod flake8_debugger; pub mod flake8_errmsg; +mod flake8_implicit_str_concat; mod flake8_import_conventions; mod flake8_print; pub mod flake8_quotes;