From ace7b01d5193d78f8396e765a5be708a2bf40a32 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 13 May 2019 08:31:40 +0200 Subject: [PATCH] Improve check for logical continuation in comprehension. Excludes ``` sorted(obj for obj in iterator if some_long_cond() and some_other_cond()) ``` from E127. It is true that this also lets through some "bad" indents e.g. ``` (1 if a and 2 else b) ``` but at the tokenization level it is quite difficult to distinguish between the "if" in `a for b in c if d` and the "if" in `a if b else c`, which play quite different roles. --- pycodestyle.py | 6 +++++- testsuite/E12not.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pycodestyle.py b/pycodestyle.py index 705ba25a..95c38b14 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -608,7 +608,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, if verbose >= 3: print(">>> " + tokens[0][4].rstrip()) - for token_type, text, start, end, line in tokens: + for idx, (token_type, text, start, end, line) in enumerate(tokens): newline = row < start[0] - first_row if newline: @@ -695,6 +695,10 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, elif (token_type in (tokenize.STRING, tokenize.COMMENT) or text in ('u', 'ur', 'b', 'br')): indent_chances[start[1]] = str + # hanging indents in comprehensions + elif (token_type == tokenize.NAME and text == "if" and + tokens[idx + 1][0] != tokenize.LPAR): # [0] == .type + indent_chances[tokens[idx + 1][2][1]] = True # [2] == .start # special case for the "if" statement because len("if (") == 4 elif not indent_chances and not row and not depth and text == 'if': indent_chances[end[1] + 1] = True diff --git a/testsuite/E12not.py b/testsuite/E12not.py index ebaa078f..f04f3e86 100644 --- a/testsuite/E12not.py +++ b/testsuite/E12not.py @@ -639,3 +639,7 @@ def other_example(): # more stuff ) ) +#: W503 +sorted(obj for obj in [] + if True + and False)