From f529ae52e4ccfa5b09a1b4151ca0813f7920ac23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9ni=20Gauffier=7E?= Date: Tue, 28 Dec 2021 01:35:38 +0100 Subject: [PATCH 1/3] fix E203 false positive in list slices --- pycodestyle.py | 63 ++++++++++++++++++++++++++++++++++++++++++- testsuite/E20.py | 14 ++++++++++ testsuite/python35.py | 2 ++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/pycodestyle.py b/pycodestyle.py index 83069c509..d904f7345 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -422,8 +422,66 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number, top_level_lines, blank_before) +def _E203(tokens, pos): + """Additional check for E203 to allow whitespace in slices""" + + sqbrackets = 0 + last = 0 + + in_lambda = False + delim_history = [] + + for token in tokens: + if token.exact_type == tokenize.LSQB: + sqbrackets += 1 + elif token.exact_type == tokenize.RSQB: + sqbrackets -= 1 + if token.exact_type in ( + tokenize.LBRACE, tokenize.RBRACE, tokenize.RSQB, tokenize.LSQB + ): + delim_history.append(token.exact_type) + + if token.exact_type == tokenize.NAME and token[1] == "lambda": + in_lambda = True + + if token[3][1] == pos: + # Colon not inside brackets or + # following another colon or in lambda expression + if sqbrackets <= 0 or last == tokenize.COLON or in_lambda: + return True + + # Colon in dict + if tokenize.LBRACE not in delim_history: + break + needs = 0 + count = 0 + for d in delim_history[::-1]: + if needs == 0: + if d == tokenize.LBRACE: + return True + if d == tokenize.LSQB: + return False + needs = d - 1 + else: + if d == needs: + if count == 0: + needs = 0 + else: + count -= 1 + if d == needs + 1: + count += 1 + break + + if in_lambda and token.exact_type == tokenize.COLON: + in_lambda = False + + last = token.exact_type + + return False + + @register_check -def extraneous_whitespace(logical_line): +def extraneous_whitespace(logical_line, tokens): r"""Avoid extraneous whitespace. Avoid extraneous whitespace in these situations: @@ -451,6 +509,9 @@ def extraneous_whitespace(logical_line): # assert char in '([{' yield found + 1, "E201 whitespace after '%s'" % char elif line[found - 1] != ',': + if (char == ":" and line[found - 1] != " " and + not _E203(tokens, match.end())): + continue code = ('E202' if char in '}])' else 'E203') # if char in ',;:' yield found, f"{code} whitespace before '{char}'" diff --git a/testsuite/E20.py b/testsuite/E20.py index 20c6dfd80..08ef6660b 100644 --- a/testsuite/E20.py +++ b/testsuite/E20.py @@ -69,10 +69,24 @@ if x == 4: print x, y x, y = y , x +#: E203:1:20 +ham[lower + offset : upper + offset] +#: E203:1:12 +ham[lower : : upper] +#: E203:1:14 +ham[(lambda x : x)(5) :] +#: E203:1:9 +ham[{"a" : 6}["a"] :] +#: E203:1:38 +ham[{"a": [1, {}, {"a": [{}, []], "b" :[3]}, 3][1 : 3]}["a"] :] #: Okay if x == 4: print x, y x, y = y, x a[b1, :] == a[b1, ...] b = a[:, b1] +ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:] +ham[lower:upper], ham[lower:upper:], ham[lower::step] +ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] +ham[{"a": [1, {}, {"a": [{}, []], "b": [3]}, 3][1 : 3]}["a"] :] #: diff --git a/testsuite/python35.py b/testsuite/python35.py index 1bedee5d9..d653fc850 100644 --- a/testsuite/python35.py +++ b/testsuite/python35.py @@ -4,3 +4,5 @@ def bar(a, b)->int: #: Okay def baz(a, b) -> int: pass +#: E203 +a : int From f7618bdb4363bc5df82ef7345b8922d792c534c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 28 Dec 2021 00:43:42 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pycodestyle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycodestyle.py b/pycodestyle.py index d904f7345..67eeede75 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -424,7 +424,7 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number, def _E203(tokens, pos): """Additional check for E203 to allow whitespace in slices""" - + sqbrackets = 0 last = 0 From 24b22d70ad560e2e6bbaf0dd3875dd3ae03fc17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9ni=20Gauffier=7E?= Date: Tue, 28 Dec 2021 02:37:17 +0100 Subject: [PATCH 3/3] multi line fix --- pycodestyle.py | 18 +++++++++++------- testsuite/E20.py | 4 ++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/pycodestyle.py b/pycodestyle.py index d904f7345..cbbcf4a56 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -422,12 +422,14 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number, top_level_lines, blank_before) -def _E203(tokens, pos): +def _E203(tokens, count): """Additional check for E203 to allow whitespace in slices""" - + sqbrackets = 0 last = 0 + col_count = 0 + in_lambda = False delim_history = [] @@ -444,7 +446,8 @@ def _E203(tokens, pos): if token.exact_type == tokenize.NAME and token[1] == "lambda": in_lambda = True - if token[3][1] == pos: + if token.exact_type == tokenize.COLON and col_count == count: + # Colon not inside brackets or # following another colon or in lambda expression if sqbrackets <= 0 or last == tokenize.COLON or in_lambda: @@ -472,9 +475,9 @@ def _E203(tokens, pos): count += 1 break - if in_lambda and token.exact_type == tokenize.COLON: + if token.exact_type == tokenize.COLON: + col_count += 1 in_lambda = False - last = token.exact_type return False @@ -500,7 +503,8 @@ def extraneous_whitespace(logical_line, tokens): E203: if x == 4: print x, y ; x, y = y, x E203: if x == 4 : print x, y; x, y = y, x """ - line = logical_line + line: str = logical_line + colons = [m.end() for m in re.compile(r":").finditer(line)] for match in EXTRANEOUS_WHITESPACE_REGEX.finditer(line): text = match.group() char = text.strip() @@ -510,7 +514,7 @@ def extraneous_whitespace(logical_line, tokens): yield found + 1, "E201 whitespace after '%s'" % char elif line[found - 1] != ',': if (char == ":" and line[found - 1] != " " and - not _E203(tokens, match.end())): + not _E203(tokens, colons.index(match.end()))): continue code = ('E202' if char in '}])' else 'E203') # if char in ',;:' yield found, f"{code} whitespace before '{char}'" diff --git a/testsuite/E20.py b/testsuite/E20.py index 08ef6660b..bd20ebe05 100644 --- a/testsuite/E20.py +++ b/testsuite/E20.py @@ -89,4 +89,8 @@ ham[lower:upper], ham[lower:upper:], ham[lower::step] ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] ham[{"a": [1, {}, {"a": [{}, []], "b": [3]}, 3][1 : 3]}["a"] :] +append_leaves( + new_line, line, LL[string_idx + 1 : rpar_idx] + LL[rpar_idx + 1 :] +) +if token.PERCENT in {leaf.type for leaf in LL[idx - 1 : next_idx]} #: