(logical_line, tokens)
r"""
    Avoid breaks before binary operators.

    The preferred place to break around a binary operator is after the
    operator, not before it.

    W503: (width == 0\n + height == 0)
    W503: (width == 0\n and height == 0)

    Okay: (width == 0 +\n height == 0)
    Okay: foo(\n    -x)
    Okay: foo(x\n    [])
    Okay: x = '''\n''' + ''
    Okay: foo(x,\n    -y)
    Okay: foo(x,  # comment\n    -y)
    Okay: var = (1 &\n       ~2)
    Okay: var = (1 /\n       -2)
    Okay: var = (1 +\n       -1 +\n       -2)
r"""
    Avoid breaks before binary operators.
r Avoid breaks before binary operators .
def break_around_binary_operator(logical_line, tokens):
    r"""
    Avoid breaks before binary operators.

    The preferred place to break around a binary operator is after the
    operator, not before it.

    W503: (width == 0\n + height == 0)
    W503: (width == 0\n and height == 0)

    Okay: (width == 0 +\n height == 0)
    Okay: foo(\n    -x)
    Okay: foo(x\n    [])
    Okay: x = '''\n''' + ''
    Okay: foo(x,\n    -y)
    Okay: foo(x,  # comment\n    -y)
    Okay: var = (1 &\n       ~2)
    Okay: var = (1 /\n       -2)
    Okay: var = (1 +\n       -1 +\n       -2)
    """
    def is_binary_operator(token_type, text):
        # The % character is strictly speaking a binary operator, but the
        # common usage seems to be to put it next to the format parameters,
        # after a line break.
        return ((token_type == tokenize.OP or text in ['and', 'or']) and
                text not in "()[]{},:.;@=%~")

    line_break = False
    unary_context = True
    # Previous non-newline token types and text
    previous_token_type = None
    previous_text = None
    for token_type, text, start, end, line in tokens:
        if token_type == tokenize.COMMENT:
            continue
        if ('\n' in text or '\r' in text) and token_type != tokenize.STRING:
            line_break = True
        else:
            if (is_binary_operator(token_type, text) and line_break and
                    not unary_context and
                    not is_binary_operator(previous_token_type,
                                           previous_text)):
                yield start, "W503 line break before binary operator"
            unary_context = text in '([{,;'
            line_break = False
            previous_token_type = token_type
            previous_text = text
def break_around_binary_operator ( logical_line , tokens ) : def is_binary_operator ( token_type , text ) : # The % character is strictly speaking a binary operator, but the # common usage seems to be to put it next to the format parameters, # after a line break. return ( ( token_type == tokenize . OP or text in [ 'and' , 'or' ] ) and text not in "()[]{},:.;@=%~" ) line_break = False unary_context = True # Previous non-newline token types and text previous_token_type = None previous_text = None for token_type , text , start , end , line in tokens : if token_type == tokenize . COMMENT : continue if ( '\n' in text or '\r' in text ) and token_type != tokenize . STRING : line_break = True else : if ( is_binary_operator ( token_type , text ) and line_break and not unary_context and not is_binary_operator ( previous_token_type , previous_text ) ) : yield start , "W503 line break before binary operator" unary_context = text in '([{,;' line_break = False previous_token_type = token_type previous_text = text