mirror of https://github.com/astral-sh/ruff
Implicit flake8-implicit-str-concat (#1463)
This commit is contained in:
parent
5f796b39b4
commit
b078050732
25
LICENSE
25
LICENSE
|
|
@ -388,6 +388,31 @@ are:
|
||||||
SOFTWARE.
|
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:
|
- flake8-import-conventions, licensed as follows:
|
||||||
"""
|
"""
|
||||||
MIT License
|
MIT License
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -95,6 +95,7 @@ of [Conda](https://docs.conda.io/en/latest/):
|
||||||
1. [flake8-comprehensions (C4)](#flake8-comprehensions-c4)
|
1. [flake8-comprehensions (C4)](#flake8-comprehensions-c4)
|
||||||
1. [flake8-debugger (T10)](#flake8-debugger-t10)
|
1. [flake8-debugger (T10)](#flake8-debugger-t10)
|
||||||
1. [flake8-errmsg (EM)](#flake8-errmsg-em)
|
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-import-conventions (ICN)](#flake8-import-conventions-icn)
|
||||||
1. [flake8-print (T20)](#flake8-print-t20)
|
1. [flake8-print (T20)](#flake8-print-t20)
|
||||||
1. [flake8-quotes (Q)](#flake8-quotes-q)
|
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 | |
|
| 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 | |
|
| 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)
|
### flake8-import-conventions (ICN)
|
||||||
|
|
||||||
| Code | Name | Message | Fix |
|
| Code | Name | Message | Fix |
|
||||||
|
|
@ -1274,6 +1285,7 @@ natively, including:
|
||||||
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/)
|
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/)
|
||||||
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
||||||
- [`flake8-errmsg`](https://pypi.org/project/flake8-errmsg/)
|
- [`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-import-conventions`](https://github.com/joaopalmeiro/flake8-import-conventions)
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
- [`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-docstrings`](https://pypi.org/project/flake8-docstrings/)
|
||||||
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
||||||
- [`flake8-errmsg`](https://pypi.org/project/flake8-errmsg/)
|
- [`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-import-conventions`](https://github.com/joaopalmeiro/flake8-import-conventions)
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,17 @@ pub enum Plugin {
|
||||||
Flake8Datetimez,
|
Flake8Datetimez,
|
||||||
Flake8Debugger,
|
Flake8Debugger,
|
||||||
Flake8Docstrings,
|
Flake8Docstrings,
|
||||||
Flake8ErrMsg,
|
|
||||||
Flake8Eradicate,
|
Flake8Eradicate,
|
||||||
|
Flake8ErrMsg,
|
||||||
|
Flake8ImplicitStrConcat,
|
||||||
Flake8Print,
|
Flake8Print,
|
||||||
Flake8Quotes,
|
Flake8Quotes,
|
||||||
Flake8Return,
|
Flake8Return,
|
||||||
Flake8Simplify,
|
Flake8Simplify,
|
||||||
Flake8TidyImports,
|
Flake8TidyImports,
|
||||||
McCabe,
|
McCabe,
|
||||||
PandasVet,
|
|
||||||
PEP8Naming,
|
PEP8Naming,
|
||||||
|
PandasVet,
|
||||||
Pyupgrade,
|
Pyupgrade,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,6 +46,7 @@ impl FromStr for Plugin {
|
||||||
"flake8-docstrings" => Ok(Plugin::Flake8Docstrings),
|
"flake8-docstrings" => Ok(Plugin::Flake8Docstrings),
|
||||||
"flake8-eradicate" => Ok(Plugin::Flake8Eradicate),
|
"flake8-eradicate" => Ok(Plugin::Flake8Eradicate),
|
||||||
"flake8-errmsg" => Ok(Plugin::Flake8ErrMsg),
|
"flake8-errmsg" => Ok(Plugin::Flake8ErrMsg),
|
||||||
|
"flake8-implicit-str-concat" => Ok(Plugin::Flake8ImplicitStrConcat),
|
||||||
"flake8-print" => Ok(Plugin::Flake8Print),
|
"flake8-print" => Ok(Plugin::Flake8Print),
|
||||||
"flake8-quotes" => Ok(Plugin::Flake8Quotes),
|
"flake8-quotes" => Ok(Plugin::Flake8Quotes),
|
||||||
"flake8-return" => Ok(Plugin::Flake8Return),
|
"flake8-return" => Ok(Plugin::Flake8Return),
|
||||||
|
|
@ -76,14 +78,15 @@ impl fmt::Debug for Plugin {
|
||||||
Plugin::Flake8Docstrings => "flake8-docstrings",
|
Plugin::Flake8Docstrings => "flake8-docstrings",
|
||||||
Plugin::Flake8Eradicate => "flake8-eradicate",
|
Plugin::Flake8Eradicate => "flake8-eradicate",
|
||||||
Plugin::Flake8ErrMsg => "flake8-errmsg",
|
Plugin::Flake8ErrMsg => "flake8-errmsg",
|
||||||
|
Plugin::Flake8ImplicitStrConcat => "flake8-implicit-str-concat",
|
||||||
Plugin::Flake8Print => "flake8-print",
|
Plugin::Flake8Print => "flake8-print",
|
||||||
Plugin::Flake8Quotes => "flake8-quotes",
|
Plugin::Flake8Quotes => "flake8-quotes",
|
||||||
Plugin::Flake8Return => "flake8-return",
|
Plugin::Flake8Return => "flake8-return",
|
||||||
Plugin::Flake8Simplify => "flake8-simplify",
|
Plugin::Flake8Simplify => "flake8-simplify",
|
||||||
Plugin::Flake8TidyImports => "flake8-tidy-imports",
|
Plugin::Flake8TidyImports => "flake8-tidy-imports",
|
||||||
Plugin::McCabe => "mccabe",
|
Plugin::McCabe => "mccabe",
|
||||||
Plugin::PandasVet => "pandas-vet",
|
|
||||||
Plugin::PEP8Naming => "pep8-naming",
|
Plugin::PEP8Naming => "pep8-naming",
|
||||||
|
Plugin::PandasVet => "pandas-vet",
|
||||||
Plugin::Pyupgrade => "pyupgrade",
|
Plugin::Pyupgrade => "pyupgrade",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -106,6 +109,7 @@ impl Plugin {
|
||||||
// TODO(charlie): Handle rename of `E` to `ERA`.
|
// TODO(charlie): Handle rename of `E` to `ERA`.
|
||||||
Plugin::Flake8Eradicate => CheckCodePrefix::ERA,
|
Plugin::Flake8Eradicate => CheckCodePrefix::ERA,
|
||||||
Plugin::Flake8ErrMsg => CheckCodePrefix::EM,
|
Plugin::Flake8ErrMsg => CheckCodePrefix::EM,
|
||||||
|
Plugin::Flake8ImplicitStrConcat => CheckCodePrefix::ISC,
|
||||||
Plugin::Flake8Print => CheckCodePrefix::T2,
|
Plugin::Flake8Print => CheckCodePrefix::T2,
|
||||||
Plugin::Flake8Quotes => CheckCodePrefix::Q,
|
Plugin::Flake8Quotes => CheckCodePrefix::Q,
|
||||||
Plugin::Flake8Return => CheckCodePrefix::RET,
|
Plugin::Flake8Return => CheckCodePrefix::RET,
|
||||||
|
|
@ -146,6 +150,7 @@ impl Plugin {
|
||||||
}
|
}
|
||||||
Plugin::Flake8Eradicate => vec![CheckCodePrefix::ERA],
|
Plugin::Flake8Eradicate => vec![CheckCodePrefix::ERA],
|
||||||
Plugin::Flake8ErrMsg => vec![CheckCodePrefix::EM],
|
Plugin::Flake8ErrMsg => vec![CheckCodePrefix::EM],
|
||||||
|
Plugin::Flake8ImplicitStrConcat => vec![CheckCodePrefix::ISC],
|
||||||
Plugin::Flake8Print => vec![CheckCodePrefix::T2],
|
Plugin::Flake8Print => vec![CheckCodePrefix::T2],
|
||||||
Plugin::Flake8Quotes => vec![CheckCodePrefix::Q],
|
Plugin::Flake8Quotes => vec![CheckCodePrefix::Q],
|
||||||
Plugin::Flake8Return => vec![CheckCodePrefix::RET],
|
Plugin::Flake8Return => vec![CheckCodePrefix::RET],
|
||||||
|
|
@ -449,6 +454,7 @@ pub fn infer_plugins_from_codes(codes: &BTreeSet<CheckCodePrefix>) -> Vec<Plugin
|
||||||
Plugin::Flake8Docstrings,
|
Plugin::Flake8Docstrings,
|
||||||
Plugin::Flake8Eradicate,
|
Plugin::Flake8Eradicate,
|
||||||
Plugin::Flake8ErrMsg,
|
Plugin::Flake8ErrMsg,
|
||||||
|
Plugin::Flake8ImplicitStrConcat,
|
||||||
Plugin::Flake8Print,
|
Plugin::Flake8Print,
|
||||||
Plugin::Flake8Quotes,
|
Plugin::Flake8Quotes,
|
||||||
Plugin::Flake8Return,
|
Plugin::Flake8Return,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
_ = "a" "b" "c"
|
||||||
|
|
||||||
|
_ = "abc" + "def"
|
||||||
|
|
||||||
|
_ = "abc" \
|
||||||
|
"def"
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
"abc" +
|
||||||
|
"def"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
f"abc" +
|
||||||
|
"def"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
b"abc" +
|
||||||
|
b"def"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
"abc"
|
||||||
|
"def"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
f"abc"
|
||||||
|
"def"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = (
|
||||||
|
b"abc"
|
||||||
|
b"def"
|
||||||
|
)
|
||||||
|
|
@ -683,6 +683,12 @@
|
||||||
"ICN0",
|
"ICN0",
|
||||||
"ICN00",
|
"ICN00",
|
||||||
"ICN001",
|
"ICN001",
|
||||||
|
"ISC",
|
||||||
|
"ISC0",
|
||||||
|
"ISC00",
|
||||||
|
"ISC001",
|
||||||
|
"ISC002",
|
||||||
|
"ISC003",
|
||||||
"M",
|
"M",
|
||||||
"M0",
|
"M0",
|
||||||
"M001",
|
"M001",
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@ use crate::visibility::{module_visibility, transition_scope, Modifier, Visibilit
|
||||||
use crate::{
|
use crate::{
|
||||||
docstrings, flake8_2020, flake8_annotations, flake8_bandit, flake8_blind_except,
|
docstrings, flake8_2020, flake8_annotations, flake8_bandit, flake8_blind_except,
|
||||||
flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_comprehensions, flake8_datetimez,
|
flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_comprehensions, flake8_datetimez,
|
||||||
flake8_debugger, flake8_errmsg, flake8_import_conventions, flake8_print, flake8_return,
|
flake8_debugger, flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions,
|
||||||
flake8_simplify, flake8_tidy_imports, flake8_unused_arguments, mccabe, noqa, pandas_vet,
|
flake8_print, flake8_return, flake8_simplify, flake8_tidy_imports, flake8_unused_arguments,
|
||||||
pep8_naming, pycodestyle, pydocstyle, pyflakes, pygrep_hooks, pylint, pyupgrade, ruff,
|
mccabe, noqa, pandas_vet, pep8_naming, pycodestyle, pydocstyle, pyflakes, pygrep_hooks, pylint,
|
||||||
visibility,
|
pyupgrade, ruff, visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
const GLOBAL_SCOPE_INDEX: usize = 0;
|
const GLOBAL_SCOPE_INDEX: usize = 0;
|
||||||
|
|
@ -2271,6 +2271,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExprKind::BinOp {
|
||||||
|
op: Operator::Add, ..
|
||||||
|
} => {
|
||||||
|
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 } => {
|
ExprKind::UnaryOp { op, operand } => {
|
||||||
let check_not_in = self.settings.enabled.contains(&CheckCode::E713);
|
let check_not_in = self.settings.enabled.contains(&CheckCode::E713);
|
||||||
let check_not_is = self.settings.enabled.contains(&CheckCode::E714);
|
let check_not_is = self.settings.enabled.contains(&CheckCode::E714);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::lex::docstring_detection::StateMachine;
|
||||||
use crate::ruff::checks::Context;
|
use crate::ruff::checks::Context;
|
||||||
use crate::settings::flags;
|
use crate::settings::flags;
|
||||||
use crate::source_code_locator::SourceCodeLocator;
|
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(
|
pub fn check_tokens(
|
||||||
locator: &SourceCodeLocator,
|
locator: &SourceCodeLocator,
|
||||||
|
|
@ -26,6 +26,8 @@ pub fn check_tokens(
|
||||||
|| settings.enabled.contains(&CheckCode::Q003);
|
|| settings.enabled.contains(&CheckCode::Q003);
|
||||||
let enforce_commented_out_code = settings.enabled.contains(&CheckCode::ERA001);
|
let enforce_commented_out_code = settings.enabled.contains(&CheckCode::ERA001);
|
||||||
let enforce_invalid_escape_sequence = settings.enabled.contains(&CheckCode::W605);
|
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();
|
let mut state_machine = StateMachine::default();
|
||||||
for &(start, ref tok, end) in tokens.iter().flatten() {
|
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
|
checks
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,10 @@ pub enum CheckCode {
|
||||||
RET506,
|
RET506,
|
||||||
RET507,
|
RET507,
|
||||||
RET508,
|
RET508,
|
||||||
|
// flake8-implicit-str-concat
|
||||||
|
ISC001,
|
||||||
|
ISC002,
|
||||||
|
ISC003,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
T201,
|
T201,
|
||||||
T203,
|
T203,
|
||||||
|
|
@ -377,6 +381,7 @@ pub enum CheckCategory {
|
||||||
Flake8Comprehensions,
|
Flake8Comprehensions,
|
||||||
Flake8Debugger,
|
Flake8Debugger,
|
||||||
Flake8ErrMsg,
|
Flake8ErrMsg,
|
||||||
|
Flake8ImplicitStrConcat,
|
||||||
Flake8ImportConventions,
|
Flake8ImportConventions,
|
||||||
Flake8Print,
|
Flake8Print,
|
||||||
Flake8Quotes,
|
Flake8Quotes,
|
||||||
|
|
@ -420,6 +425,7 @@ impl CheckCategory {
|
||||||
CheckCategory::Flake8Comprehensions => "flake8-comprehensions",
|
CheckCategory::Flake8Comprehensions => "flake8-comprehensions",
|
||||||
CheckCategory::Flake8Debugger => "flake8-debugger",
|
CheckCategory::Flake8Debugger => "flake8-debugger",
|
||||||
CheckCategory::Flake8ErrMsg => "flake8-errmsg",
|
CheckCategory::Flake8ErrMsg => "flake8-errmsg",
|
||||||
|
CheckCategory::Flake8ImplicitStrConcat => "flake8-implicit-str-concat",
|
||||||
CheckCategory::Flake8ImportConventions => "flake8-import-conventions",
|
CheckCategory::Flake8ImportConventions => "flake8-import-conventions",
|
||||||
CheckCategory::Flake8Print => "flake8-print",
|
CheckCategory::Flake8Print => "flake8-print",
|
||||||
CheckCategory::Flake8Quotes => "flake8-quotes",
|
CheckCategory::Flake8Quotes => "flake8-quotes",
|
||||||
|
|
@ -453,19 +459,21 @@ impl CheckCategory {
|
||||||
CheckCategory::Flake8Bugbear => vec![CheckCodePrefix::B],
|
CheckCategory::Flake8Bugbear => vec![CheckCodePrefix::B],
|
||||||
CheckCategory::Flake8Builtins => vec![CheckCodePrefix::A],
|
CheckCategory::Flake8Builtins => vec![CheckCodePrefix::A],
|
||||||
CheckCategory::Flake8Comprehensions => vec![CheckCodePrefix::C4],
|
CheckCategory::Flake8Comprehensions => vec![CheckCodePrefix::C4],
|
||||||
|
CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ],
|
||||||
CheckCategory::Flake8Debugger => vec![CheckCodePrefix::T10],
|
CheckCategory::Flake8Debugger => vec![CheckCodePrefix::T10],
|
||||||
CheckCategory::Flake8ErrMsg => vec![CheckCodePrefix::EM],
|
CheckCategory::Flake8ErrMsg => vec![CheckCodePrefix::EM],
|
||||||
|
CheckCategory::Flake8ImplicitStrConcat => vec![CheckCodePrefix::ISC],
|
||||||
|
CheckCategory::Flake8ImportConventions => vec![CheckCodePrefix::ICN],
|
||||||
CheckCategory::Flake8Print => vec![CheckCodePrefix::T20],
|
CheckCategory::Flake8Print => vec![CheckCodePrefix::T20],
|
||||||
CheckCategory::Flake8Quotes => vec![CheckCodePrefix::Q],
|
CheckCategory::Flake8Quotes => vec![CheckCodePrefix::Q],
|
||||||
CheckCategory::Flake8Return => vec![CheckCodePrefix::RET],
|
CheckCategory::Flake8Return => vec![CheckCodePrefix::RET],
|
||||||
CheckCategory::Flake8Simplify => vec![CheckCodePrefix::SIM],
|
CheckCategory::Flake8Simplify => vec![CheckCodePrefix::SIM],
|
||||||
CheckCategory::Flake8TidyImports => vec![CheckCodePrefix::TID],
|
CheckCategory::Flake8TidyImports => vec![CheckCodePrefix::TID],
|
||||||
CheckCategory::Flake8UnusedArguments => vec![CheckCodePrefix::ARG],
|
CheckCategory::Flake8UnusedArguments => vec![CheckCodePrefix::ARG],
|
||||||
CheckCategory::Flake8Datetimez => vec![CheckCodePrefix::DTZ],
|
|
||||||
CheckCategory::Isort => vec![CheckCodePrefix::I],
|
CheckCategory::Isort => vec![CheckCodePrefix::I],
|
||||||
CheckCategory::McCabe => vec![CheckCodePrefix::C90],
|
CheckCategory::McCabe => vec![CheckCodePrefix::C90],
|
||||||
CheckCategory::PandasVet => vec![CheckCodePrefix::PD],
|
|
||||||
CheckCategory::PEP8Naming => vec![CheckCodePrefix::N],
|
CheckCategory::PEP8Naming => vec![CheckCodePrefix::N],
|
||||||
|
CheckCategory::PandasVet => vec![CheckCodePrefix::PD],
|
||||||
CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W],
|
CheckCategory::Pycodestyle => vec![CheckCodePrefix::E, CheckCodePrefix::W],
|
||||||
CheckCategory::Pydocstyle => vec![CheckCodePrefix::D],
|
CheckCategory::Pydocstyle => vec![CheckCodePrefix::D],
|
||||||
CheckCategory::Pyflakes => vec![CheckCodePrefix::F],
|
CheckCategory::Pyflakes => vec![CheckCodePrefix::F],
|
||||||
|
|
@ -477,7 +485,6 @@ impl CheckCategory {
|
||||||
CheckCodePrefix::PLW,
|
CheckCodePrefix::PLW,
|
||||||
],
|
],
|
||||||
CheckCategory::Pyupgrade => vec![CheckCodePrefix::UP],
|
CheckCategory::Pyupgrade => vec![CheckCodePrefix::UP],
|
||||||
CheckCategory::Flake8ImportConventions => vec![CheckCodePrefix::ICN],
|
|
||||||
CheckCategory::Ruff => vec![CheckCodePrefix::RUF],
|
CheckCategory::Ruff => vec![CheckCodePrefix::RUF],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -527,6 +534,10 @@ impl CheckCategory {
|
||||||
"https://pypi.org/project/flake8-errmsg/0.4.0/",
|
"https://pypi.org/project/flake8-errmsg/0.4.0/",
|
||||||
&Platform::PyPI,
|
&Platform::PyPI,
|
||||||
)),
|
)),
|
||||||
|
CheckCategory::Flake8ImplicitStrConcat => Some((
|
||||||
|
"https://pypi.org/project/flake8-implicit-str-concat/0.3.0/",
|
||||||
|
&Platform::PyPI,
|
||||||
|
)),
|
||||||
CheckCategory::Flake8ImportConventions => None,
|
CheckCategory::Flake8ImportConventions => None,
|
||||||
CheckCategory::Flake8Print => Some((
|
CheckCategory::Flake8Print => Some((
|
||||||
"https://pypi.org/project/flake8-print/5.0.0/",
|
"https://pypi.org/project/flake8-print/5.0.0/",
|
||||||
|
|
@ -796,6 +807,10 @@ pub enum CheckKind {
|
||||||
SuperfluousElseRaise(Branch),
|
SuperfluousElseRaise(Branch),
|
||||||
SuperfluousElseContinue(Branch),
|
SuperfluousElseContinue(Branch),
|
||||||
SuperfluousElseBreak(Branch),
|
SuperfluousElseBreak(Branch),
|
||||||
|
// flake8-implicit-str-concat
|
||||||
|
SingleLineImplicitStringConcatenation,
|
||||||
|
MultiLineImplicitStringConcatenation,
|
||||||
|
ExplicitStringConcatenation,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
PrintFound,
|
PrintFound,
|
||||||
PPrintFound,
|
PPrintFound,
|
||||||
|
|
@ -992,6 +1007,8 @@ impl CheckCode {
|
||||||
| CheckCode::PGH003
|
| CheckCode::PGH003
|
||||||
| CheckCode::PGH004 => &LintSource::Lines,
|
| CheckCode::PGH004 => &LintSource::Lines,
|
||||||
CheckCode::ERA001
|
CheckCode::ERA001
|
||||||
|
| CheckCode::ISC001
|
||||||
|
| CheckCode::ISC002
|
||||||
| CheckCode::Q000
|
| CheckCode::Q000
|
||||||
| CheckCode::Q001
|
| CheckCode::Q001
|
||||||
| CheckCode::Q002
|
| CheckCode::Q002
|
||||||
|
|
@ -1180,6 +1197,10 @@ impl CheckCode {
|
||||||
CheckCode::RET506 => CheckKind::SuperfluousElseRaise(Branch::Else),
|
CheckCode::RET506 => CheckKind::SuperfluousElseRaise(Branch::Else),
|
||||||
CheckCode::RET507 => CheckKind::SuperfluousElseContinue(Branch::Else),
|
CheckCode::RET507 => CheckKind::SuperfluousElseContinue(Branch::Else),
|
||||||
CheckCode::RET508 => CheckKind::SuperfluousElseBreak(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
|
// flake8-print
|
||||||
CheckCode::T201 => CheckKind::PrintFound,
|
CheckCode::T201 => CheckKind::PrintFound,
|
||||||
CheckCode::T203 => CheckKind::PPrintFound,
|
CheckCode::T203 => CheckKind::PPrintFound,
|
||||||
|
|
@ -1576,9 +1597,10 @@ impl CheckCode {
|
||||||
CheckCode::FBT002 => CheckCategory::Flake8BooleanTrap,
|
CheckCode::FBT002 => CheckCategory::Flake8BooleanTrap,
|
||||||
CheckCode::FBT003 => CheckCategory::Flake8BooleanTrap,
|
CheckCode::FBT003 => CheckCategory::Flake8BooleanTrap,
|
||||||
CheckCode::I001 => CheckCategory::Isort,
|
CheckCode::I001 => CheckCategory::Isort,
|
||||||
CheckCode::TID251 => CheckCategory::Flake8TidyImports,
|
|
||||||
CheckCode::TID252 => CheckCategory::Flake8TidyImports,
|
|
||||||
CheckCode::ICN001 => CheckCategory::Flake8ImportConventions,
|
CheckCode::ICN001 => CheckCategory::Flake8ImportConventions,
|
||||||
|
CheckCode::ISC001 => CheckCategory::Flake8ImplicitStrConcat,
|
||||||
|
CheckCode::ISC002 => CheckCategory::Flake8ImplicitStrConcat,
|
||||||
|
CheckCode::ISC003 => CheckCategory::Flake8ImplicitStrConcat,
|
||||||
CheckCode::N801 => CheckCategory::PEP8Naming,
|
CheckCode::N801 => CheckCategory::PEP8Naming,
|
||||||
CheckCode::N802 => CheckCategory::PEP8Naming,
|
CheckCode::N802 => CheckCategory::PEP8Naming,
|
||||||
CheckCode::N803 => CheckCategory::PEP8Naming,
|
CheckCode::N803 => CheckCategory::PEP8Naming,
|
||||||
|
|
@ -1649,6 +1671,8 @@ impl CheckCode {
|
||||||
CheckCode::T100 => CheckCategory::Flake8Debugger,
|
CheckCode::T100 => CheckCategory::Flake8Debugger,
|
||||||
CheckCode::T201 => CheckCategory::Flake8Print,
|
CheckCode::T201 => CheckCategory::Flake8Print,
|
||||||
CheckCode::T203 => CheckCategory::Flake8Print,
|
CheckCode::T203 => CheckCategory::Flake8Print,
|
||||||
|
CheckCode::TID251 => CheckCategory::Flake8TidyImports,
|
||||||
|
CheckCode::TID252 => CheckCategory::Flake8TidyImports,
|
||||||
CheckCode::UP001 => CheckCategory::Pyupgrade,
|
CheckCode::UP001 => CheckCategory::Pyupgrade,
|
||||||
CheckCode::UP003 => CheckCategory::Pyupgrade,
|
CheckCode::UP003 => CheckCategory::Pyupgrade,
|
||||||
CheckCode::UP004 => CheckCategory::Pyupgrade,
|
CheckCode::UP004 => CheckCategory::Pyupgrade,
|
||||||
|
|
@ -1834,6 +1858,10 @@ impl CheckKind {
|
||||||
CheckKind::SuperfluousElseRaise(..) => &CheckCode::RET506,
|
CheckKind::SuperfluousElseRaise(..) => &CheckCode::RET506,
|
||||||
CheckKind::SuperfluousElseContinue(..) => &CheckCode::RET507,
|
CheckKind::SuperfluousElseContinue(..) => &CheckCode::RET507,
|
||||||
CheckKind::SuperfluousElseBreak(..) => &CheckCode::RET508,
|
CheckKind::SuperfluousElseBreak(..) => &CheckCode::RET508,
|
||||||
|
// flake8-implicit-str-concat
|
||||||
|
CheckKind::SingleLineImplicitStringConcatenation => &CheckCode::ISC001,
|
||||||
|
CheckKind::MultiLineImplicitStringConcatenation => &CheckCode::ISC002,
|
||||||
|
CheckKind::ExplicitStringConcatenation => &CheckCode::ISC003,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
CheckKind::PrintFound => &CheckCode::T201,
|
CheckKind::PrintFound => &CheckCode::T201,
|
||||||
CheckKind::PPrintFound => &CheckCode::T203,
|
CheckKind::PPrintFound => &CheckCode::T203,
|
||||||
|
|
@ -2484,6 +2512,16 @@ impl CheckKind {
|
||||||
CheckKind::SuperfluousElseBreak(branch) => {
|
CheckKind::SuperfluousElseBreak(branch) => {
|
||||||
format!("Unnecessary `{branch}` after `break` statement")
|
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
|
// flake8-print
|
||||||
CheckKind::PrintFound => "`print` found".to_string(),
|
CheckKind::PrintFound => "`print` found".to_string(),
|
||||||
CheckKind::PPrintFound => "`pprint` found".to_string(),
|
CheckKind::PPrintFound => "`pprint` found".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,12 @@ pub enum CheckCodePrefix {
|
||||||
ICN0,
|
ICN0,
|
||||||
ICN00,
|
ICN00,
|
||||||
ICN001,
|
ICN001,
|
||||||
|
ISC,
|
||||||
|
ISC0,
|
||||||
|
ISC00,
|
||||||
|
ISC001,
|
||||||
|
ISC002,
|
||||||
|
ISC003,
|
||||||
M,
|
M,
|
||||||
M0,
|
M0,
|
||||||
M001,
|
M001,
|
||||||
|
|
@ -717,6 +723,9 @@ impl CheckCodePrefix {
|
||||||
CheckCode::RET506,
|
CheckCode::RET506,
|
||||||
CheckCode::RET507,
|
CheckCode::RET507,
|
||||||
CheckCode::RET508,
|
CheckCode::RET508,
|
||||||
|
CheckCode::ISC001,
|
||||||
|
CheckCode::ISC002,
|
||||||
|
CheckCode::ISC003,
|
||||||
CheckCode::T201,
|
CheckCode::T201,
|
||||||
CheckCode::T203,
|
CheckCode::T203,
|
||||||
CheckCode::Q000,
|
CheckCode::Q000,
|
||||||
|
|
@ -1744,6 +1753,12 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::ICN0 => vec![CheckCode::ICN001],
|
CheckCodePrefix::ICN0 => vec![CheckCode::ICN001],
|
||||||
CheckCodePrefix::ICN00 => vec![CheckCode::ICN001],
|
CheckCodePrefix::ICN00 => vec![CheckCode::ICN001],
|
||||||
CheckCodePrefix::ICN001 => 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 => {
|
CheckCodePrefix::M => {
|
||||||
one_time_warning!(
|
one_time_warning!(
|
||||||
"{}{} {}",
|
"{}{} {}",
|
||||||
|
|
@ -3118,6 +3133,12 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::ICN0 => SuffixLength::One,
|
CheckCodePrefix::ICN0 => SuffixLength::One,
|
||||||
CheckCodePrefix::ICN00 => SuffixLength::Two,
|
CheckCodePrefix::ICN00 => SuffixLength::Two,
|
||||||
CheckCodePrefix::ICN001 => SuffixLength::Three,
|
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::M => SuffixLength::Zero,
|
||||||
CheckCodePrefix::M0 => SuffixLength::One,
|
CheckCodePrefix::M0 => SuffixLength::One,
|
||||||
CheckCodePrefix::M001 => SuffixLength::Three,
|
CheckCodePrefix::M001 => SuffixLength::Three,
|
||||||
|
|
@ -3386,6 +3407,7 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[
|
||||||
CheckCodePrefix::FBT,
|
CheckCodePrefix::FBT,
|
||||||
CheckCodePrefix::I,
|
CheckCodePrefix::I,
|
||||||
CheckCodePrefix::ICN,
|
CheckCodePrefix::ICN,
|
||||||
|
CheckCodePrefix::ISC,
|
||||||
CheckCodePrefix::N,
|
CheckCodePrefix::N,
|
||||||
CheckCodePrefix::PD,
|
CheckCodePrefix::PD,
|
||||||
CheckCodePrefix::PGH,
|
CheckCodePrefix::PGH,
|
||||||
|
|
|
||||||
|
|
@ -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<Check> {
|
||||||
|
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<Check> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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: ~
|
||||||
|
|
||||||
|
|
@ -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: ~
|
||||||
|
|
||||||
|
|
@ -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: ~
|
||||||
|
|
||||||
|
|
@ -39,6 +39,7 @@ mod flake8_comprehensions;
|
||||||
mod flake8_datetimez;
|
mod flake8_datetimez;
|
||||||
mod flake8_debugger;
|
mod flake8_debugger;
|
||||||
pub mod flake8_errmsg;
|
pub mod flake8_errmsg;
|
||||||
|
mod flake8_implicit_str_concat;
|
||||||
mod flake8_import_conventions;
|
mod flake8_import_conventions;
|
||||||
mod flake8_print;
|
mod flake8_print;
|
||||||
pub mod flake8_quotes;
|
pub mod flake8_quotes;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue