code: def _infer_binop(self, context):
      
      left = self.left
      right = self.right
  
      # we use two separate contexts for evaluating lhs and rhs because
      # 1. evaluating lhs may leave some undesired entries in context.path
      #    which may not let us infer right value of rhs
      context = context or contextmod.InferenceContext()
      lhs_context = contextmod.copy_context(context)
      rhs_context = contextmod.copy_context(context)
      lhs_iter = left.infer(context=lhs_context)
      rhs_iter = right.infer(context=rhs_context)
      for lhs, rhs in itertools.product(lhs_iter, rhs_iter):
          if any(value is util.Uninferable for value in (rhs, lhs)):
              # Don't know how to process this.
              yield util.Uninferable
              return
  
          try:
              yield from _infer_binary_operation(lhs, rhs, self, context, _get_binop_flow)
          except exceptions._NonDeducibleTypeHierarchy:
              yield util.Uninferable
docs: Binary operation inference logic.