@@ -515,8 +515,9 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing,
515
515
yield start , "%s continuation line %s" % error
516
516
517
517
# look for visual indenting
518
- if (parens [row ] and token_type not in (tokenize .NL , tokenize .COMMENT )
519
- and not indent [depth ]):
518
+ if (parens [row ] and
519
+ token_type not in (tokenize .NL , tokenize .COMMENT ) and
520
+ not indent [depth ]):
520
521
indent [depth ] = start [1 ]
521
522
indent_chances [start [1 ]] = True
522
523
if verbose >= 4 :
@@ -1000,6 +1001,45 @@ def explicit_line_join(logical_line, tokens):
1000
1001
parens -= 1
1001
1002
1002
1003
1004
+ def break_around_binary_operator (logical_line , tokens ):
1005
+ r"""
1006
+ Avoid breaks before binary operators.
1007
+
1008
+ The preferred place to break around a binary operator is after the
1009
+ operator, not before it.
1010
+
1011
+ W503: (width == 0\n + height == 0)
1012
+ W503: (width == 0\n and height == 0)
1013
+
1014
+ Okay: (width == 0 +\n height == 0)
1015
+ Okay: foo(\n -x)
1016
+ Okay: foo(x\n [])
1017
+ Okay: x = '''\n''' + ''
1018
+ Okay: foo(x,\n -y)
1019
+ Okay: foo(x, # comment\n -y)
1020
+ """
1021
+ def is_binary_operator (token_type , text ):
1022
+ # The % character is strictly speaking a binary operator, but the
1023
+ # common usage seems to be to put it next to the format parameters,
1024
+ # after a line break.
1025
+ return ((token_type == tokenize .OP or text in ['and' , 'or' ]) and
1026
+ text not in "()[]{},:.;@=%" )
1027
+
1028
+ line_break = False
1029
+ unary_context = True
1030
+ for token_type , text , start , end , line in tokens :
1031
+ if token_type == tokenize .COMMENT :
1032
+ continue
1033
+ if ('\n ' in text or '\r ' in text ) and token_type != tokenize .STRING :
1034
+ line_break = True
1035
+ else :
1036
+ if (is_binary_operator (token_type , text ) and line_break and
1037
+ not unary_context ):
1038
+ yield start , "W503 line break before binary operator"
1039
+ unary_context = text in '([{,;'
1040
+ line_break = False
1041
+
1042
+
1003
1043
def comparison_to_singleton (logical_line , noqa ):
1004
1044
r"""Comparison to singletons should use "is" or "is not".
1005
1045
@@ -1415,8 +1455,8 @@ def build_tokens_line(self):
1415
1455
(start_row , start_col ) = start
1416
1456
if prev_row != start_row : # different row
1417
1457
prev_text = self .lines [prev_row - 1 ][prev_col - 1 ]
1418
- if prev_text == ',' or (prev_text not in '{[('
1419
- and text not in '}])' ):
1458
+ if prev_text == ',' or (prev_text not in '{[(' and
1459
+ text not in '}])' ):
1420
1460
text = ' ' + text
1421
1461
elif prev_col != start_col : # different column
1422
1462
text = line [prev_col :start_col ] + text
0 commit comments