Skip to content

Commit 103221e

Browse files
committed
Report W503 for line breaks before binary operators; issue #197. #ep14boat
1 parent 4c5bf00 commit 103221e

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

pep8.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,45 @@ def explicit_line_join(logical_line, tokens):
922922
parens -= 1
923923

924924

925+
def break_around_binary_operator(logical_line, tokens):
926+
r"""
927+
Avoid breaks before binary operators.
928+
929+
The preferred place to break around a binary operator is after the
930+
operator, not before it.
931+
932+
W503: (width == 0\n + height == 0)
933+
W503: (width == 0\n and height == 0)
934+
935+
Okay: (width == 0 +\n height == 0)
936+
Okay: foo(\n -x)
937+
Okay: foo(x\n [])
938+
Okay: x = '''\n''' + ''
939+
Okay: foo(x,\n -y)
940+
Okay: foo(x, # comment\n -y)
941+
"""
942+
def is_binary_operator(token_type, text):
943+
# The % character is strictly speaking a binary operator, but the
944+
# common usage seems to be to put it next to the format parameters,
945+
# after a line break.
946+
return ((token_type == tokenize.OP or text == 'and' or text == 'or')
947+
and text not in "()[]{},:.;@=%")
948+
949+
line_break = False
950+
unary_context = True
951+
for token_type, text, start, end, line in tokens:
952+
if token_type == tokenize.COMMENT:
953+
continue
954+
if ('\n' in text or '\r' in text) and token_type != tokenize.STRING:
955+
line_break = True
956+
else:
957+
if (is_binary_operator(token_type, text) and line_break
958+
and not unary_context):
959+
yield start, "W503 line break before binary operator"
960+
unary_context = text in '([{,;'
961+
line_break = False
962+
963+
925964
def comparison_to_singleton(logical_line, noqa):
926965
r"""Comparison to singletons should use "is" or "is not".
927966

testsuite/E12.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,14 @@ def qualify_by_address(self, cr, uid, ids, context=None,
323323
rv.update(d=('a', 'b', 'c'),
324324
e=42)
325325
#
326-
#: E127
326+
#: E127 W503
327327
rv.update(d=('a' + 'b', 'c'),
328328
e=42, f=42
329329
+ 42)
330-
#: E127
330+
#: E127 W503
331331
input1 = {'a': {'calc': 1 + 2}, 'b': 1
332332
+ 42}
333-
#: E128
333+
#: E128 W503
334334
rv.update(d=('a' + 'b', 'c'),
335335
e=42, f=(42
336336
+ 42))

0 commit comments

Comments
 (0)