def _infer_binary_operation(left, right, binary_opnode, context, flow_factory): """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. """ context, reverse_context = _get_binop_contexts(context, left, right) left_type = helpers.object_type(left) right_type = helpers.object_type(right) methods = flow_factory(left, left_type, binary_opnode, right, right_type, context, reverse_context) for method in methods: try: results = list(method()) except AttributeError: continue except exceptions.AttributeInferenceError: continue except exceptions.InferenceError: yield util.Uninferable return else: if any(result is util.Uninferable for result in results): yield util.Uninferable return # TODO(cpopa): since the inference engine might return # more values than are actually possible, we decide # to return util.Uninferable if we have union types. if all(map(_is_not_implemented, results)): continue not_implemented = sum(1 for result in results if _is_not_implemented(result)) if not_implemented and not_implemented != len(results): # Can't decide yet what this is, not yet though. yield util.Uninferable return for result in results: yield result return # TODO(cpopa): yield a BadBinaryOperationMessage here, # since the operation is not supported yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type)
def _infer_binary_operation(left, right, binary_opnode, context, flow_factory): """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. """ context, reverse_context = _get_binop_contexts(context, left, right) left_type = helpers.object_type(left) right_type = helpers.object_type(right) methods = flow_factory( left, left_type, binary_opnode, right, right_type, context, reverse_context ) for method in methods: try: results = list(method()) except AttributeError: continue except exceptions.AttributeInferenceError: import traceback traceback.print_exc() continue except exceptions.InferenceError: yield util.Uninferable return else: if any(result is util.Uninferable for result in results): yield util.Uninferable return if all(map(_is_not_implemented, results)): continue not_implemented = sum( 1 for result in results if _is_not_implemented(result) ) if not_implemented and not_implemented != len(results): # Can't infer yet what this is. yield util.Uninferable return yield from results return # The operation doesn't seem to be supported so let the caller know about it yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type)