@@ -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+
925964def comparison_to_singleton (logical_line , noqa ):
926965 r"""Comparison to singletons should use "is" or "is not".
927966
0 commit comments