@@ -922,6 +922,45 @@ def explicit_line_join(logical_line, tokens):
922
922
parens -= 1
923
923
924
924
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
+
925
964
def comparison_to_singleton (logical_line , noqa ):
926
965
r"""Comparison to singletons should use "is" or "is not".
927
966
0 commit comments