def _infer_binary_operation(left, right, binary_opnode, context, flow_factory):
context, reverse_context = _get_binop_contexts(context, left, right)<EOL>left_type = helpers.object_type(left)<EOL>right_type = helpers.object_type(right)<EOL>methods = flow_factory(<EOL>left, left_type, binary_opnode, right, right_type, context, reverse_context<EOL>)<EOL>for method in methods:<EOL><INDENT>try:<EOL><INDENT>results = list(method())<EOL><DEDENT>except AttributeError:<EOL><INDENT>continue<EOL><DEDENT>except exceptions.AttributeInferenceError:<EOL><INDENT>continue<EOL><DEDENT>except exceptions.InferenceError:<EOL><INDENT>yield util.Uninferable<EOL>return<EOL><DEDENT>else:<EOL><INDENT>if any(result is util.Uninferable for result in results):<EOL><INDENT>yield util.Uninferable<EOL>return<EOL><DEDENT>if all(map(_is_not_implemented, results)):<EOL><INDENT>continue<EOL><DEDENT>not_implemented = sum(<EOL><NUM_LIT:1> for result in results if _is_not_implemented(result)<EOL>)<EOL>if not_implemented and not_implemented != len(results):<EOL><INDENT>yield util.Uninferable<EOL>return<EOL><DEDENT>yield from results<EOL>return<EOL><DEDENT><DEDENT>yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type)<EOL>
Infer a binary operation between a left operand and a right operand

    This is used by both normal binary operations and augmented binary
    operations, the only difference is the flow factory used.