summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Cimon <lucas.cimon@gmail.com>2019-01-30 15:04:55 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2019-01-31 18:24:54 +0100
commit72fd895f636f7d0c62569c39dd74227ed28c8c8b (patch)
tree760ee34ac96cc98a7d324dbfc8e6cfc9bb6f65ae
parentcee1d98c9e29c7f7cef3447cf477d1da3e0c3be2 (diff)
downloadpylint-git-72fd895f636f7d0c62569c39dd74227ed28c8c8b.tar.gz
Add a new option 'check-str-concat-over-line-jumps' to check 'implicit-str-concat-in-sequence'
-rw-r--r--ChangeLog2
-rw-r--r--pylint/checkers/strings.py40
-rwxr-xr-xpylint/test/functional/implicit_str_concat_in_sequence_multiline.py4
-rwxr-xr-xpylint/test/functional/implicit_str_concat_in_sequence_multiline.rc2
-rwxr-xr-xpylint/test/functional/implicit_str_concat_in_sequence_multiline.txt1
5 files changed, 40 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a5d268e9..2b8e64441 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -90,6 +90,8 @@ Release date: TBA
* Avoid popping __main__ when using multiple jobs
Close #2689
+
+ * Add a new option 'check-str-concat-over-line-jumps' to check 'implicit-str-concat-in-sequence'
What's New in Pylint 2.2.2?
===========================
diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py
index 92dcbbeec..eeefc6efe 100644
--- a/pylint/checkers/strings.py
+++ b/pylint/checkers/strings.py
@@ -572,6 +572,20 @@ class StringConstantChecker(BaseTokenChecker):
"maybe a comma is missing ?",
),
}
+ options = (
+ (
+ "check-str-concat-over-line-jumps",
+ {
+ "default": False,
+ "type": "yn",
+ "metavar": "<y_or_n>",
+ "help": "This flag controls whether the "
+ "implicit-str-concat-in-sequence should generate a warning "
+ "on implicit string concatenation in sequences defined over "
+ "several lines.",
+ },
+ ),
+ )
# Characters that have a special meaning after a backslash in either
# Unicode or byte strings.
@@ -601,22 +615,30 @@ class StringConstantChecker(BaseTokenChecker):
# 'token' is the whole un-parsed token; we can look at the start
# of it to see whether it's a raw or unicode string etc.
self.process_string_token(token, start[0])
- next_token = tokens[i + 1] if i + 1 < len(tokens) else None
+ # We figure the next token, ignoring comments & newlines:
+ j = i + 1
+ while j < len(tokens) and tokens[j].type in (
+ tokenize.NEWLINE,
+ tokenize.NL,
+ tokenize.COMMENT,
+ ):
+ j += 1
+ next_token = tokens[j] if j < len(tokens) else None
if encoding != "ascii":
# We convert `tokenize` character count into a byte count,
# to match with astroid `.col_offset`
start = (start[0], len(line[: start[1]].encode(encoding)))
self.string_tokens[start] = (str_eval(token), next_token)
- @check_messages(*(MSGS.keys()))
+ @check_messages(*(msgs.keys()))
def visit_list(self, node):
self.check_for_concatenated_strings(node, "list")
- @check_messages(*(MSGS.keys()))
+ @check_messages(*(msgs.keys()))
def visit_set(self, node):
self.check_for_concatenated_strings(node, "set")
- @check_messages(*(MSGS.keys()))
+ @check_messages(*(msgs.keys()))
def visit_tuple(self, node):
self.check_for_concatenated_strings(node, "tuple")
@@ -633,12 +655,12 @@ class StringConstantChecker(BaseTokenChecker):
matching_token, next_token = self.string_tokens[
(elt.lineno, elt.col_offset)
]
+ # We detect string concatenation: the AST Const is the
+ # combination of 2 string tokens
if matching_token != elt.value and next_token is not None:
- next_token_type, next_token_pos = next_token[0], next_token[2]
- # We do not warn if string concatenation happens over a newline
- if (
- next_token_type == tokenize.STRING
- and next_token_pos[0] == elt.lineno
+ if next_token.type == tokenize.STRING and (
+ next_token.start[0] == elt.lineno
+ or self.config.check_str_concat_over_line_jumps
):
self.add_message(
"implicit-str-concat-in-sequence",
diff --git a/pylint/test/functional/implicit_str_concat_in_sequence_multiline.py b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.py
new file mode 100755
index 000000000..0f8d1fcdf
--- /dev/null
+++ b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.py
@@ -0,0 +1,4 @@
+#pylint: disable=bad-continuation,missing-docstring
+
+TEST_TUPLE = ('a', 'b' # [implicit-str-concat-in-sequence]
+ 'c')
diff --git a/pylint/test/functional/implicit_str_concat_in_sequence_multiline.rc b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.rc
new file mode 100755
index 000000000..e5b344774
--- /dev/null
+++ b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.rc
@@ -0,0 +1,2 @@
+[STRING_CONSTANT]
+check-str-concat-over-line-jumps=yes
diff --git a/pylint/test/functional/implicit_str_concat_in_sequence_multiline.txt b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.txt
new file mode 100755
index 000000000..b37cf624b
--- /dev/null
+++ b/pylint/test/functional/implicit_str_concat_in_sequence_multiline.txt
@@ -0,0 +1 @@
+implicit-str-concat-in-sequence:3::Implicit string concatenation found in tuple \ No newline at end of file