Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 67 additions & 2 deletions pycodestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,69 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number,
top_level_lines, blank_before)


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 = []

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.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:
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 token.exact_type == tokenize.COLON:
col_count += 1
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:
Expand All @@ -442,7 +503,8 @@ def extraneous_whitespace(logical_line):
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()
Expand All @@ -451,6 +513,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, colons.index(match.end()))):
continue
code = ('E202' if char in '}])' else 'E203') # if char in ',;:'
yield found, f"{code} whitespace before '{char}'"

Expand Down
18 changes: 18 additions & 0 deletions testsuite/E20.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,28 @@
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"] :]
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]}
#:
2 changes: 2 additions & 0 deletions testsuite/python35.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ def bar(a, b)->int:
#: Okay
def baz(a, b) -> int:
pass
#: E203
a : int