Exemplo n.º 1
0
def _infer_unaryop(
    self: nodes.UnaryOp,
    context: InferenceContext | None = None
) -> Generator[InferenceResult | util.BadUnaryOperationMessage, None, None]:
    """Infer what an UnaryOp should return when evaluated."""
    for operand in self.operand.infer(context):
        try:
            yield operand.infer_unary_op(self.op)
        except TypeError as exc:
            # The operand doesn't support this operation.
            yield util.BadUnaryOperationMessage(operand, self.op, exc)
        except AttributeError as exc:
            meth = protocols.UNARY_OP_METHOD[self.op]
            if meth is None:
                # `not node`. Determine node's boolean
                # value and negate its result, unless it is
                # Uninferable, which will be returned as is.
                bool_value = operand.bool_value()
                if bool_value is not util.Uninferable:
                    yield nodes.const_factory(not bool_value)
                else:
                    yield util.Uninferable
            else:
                if not isinstance(operand, (bases.Instance, nodes.ClassDef)):
                    # The operation was used on something which
                    # doesn't support it.
                    yield util.BadUnaryOperationMessage(operand, self.op, exc)
                    continue

                try:
                    try:
                        methods = dunder_lookup.lookup(operand, meth)
                    except AttributeInferenceError:
                        yield util.BadUnaryOperationMessage(
                            operand, self.op, exc)
                        continue

                    meth = methods[0]
                    inferred = next(meth.infer(context=context), None)
                    if inferred is util.Uninferable or not inferred.callable():
                        continue

                    context = copy_context(context)
                    context.boundnode = operand
                    context.callcontext = CallContext(args=[], callee=inferred)

                    call_results = inferred.infer_call_result(self,
                                                              context=context)
                    result = next(call_results, None)
                    if result is None:
                        # Failed to infer, return the same type.
                        yield operand
                    else:
                        yield result
                except AttributeInferenceError as inner_exc:
                    # The unary operation special method was not found.
                    yield util.BadUnaryOperationMessage(
                        operand, self.op, inner_exc)
                except InferenceError:
                    yield util.Uninferable
Exemplo n.º 2
0
def _invoke_binop_inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    if context is not None:
        context.boundnode = instance
    method = methods[0]
    inferred = next(method.infer(context=context))
    return instance.infer_binary_op(opnode, op, other, context, inferred)
Exemplo n.º 3
0
def _invoke_binop_inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    method = methods[0]
    inferred = next(method.infer(context=context))
    if inferred is util.Uninferable:
        raise exceptions.InferenceError
    return instance.infer_binary_op(opnode, op, other, context, inferred)
Exemplo n.º 4
0
def _invoke_binop_Inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation Inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    context = contextmod.bind_context_to_node(context, instance)
    method = methods[0]
    queried = next(method.query(context=context))
    if queried is util.Uninferable:
        raise exceptions.InferenceError
    return instance.query_binary_op(opnode, op, other, context, queried)
Exemplo n.º 5
0
def _invoke_binop_inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    context = contextmod.bind_context_to_node(context, instance)
    method = methods[0]
    try:
        inferred = next(method.infer(context=context))
    except StopIteration as e:
        raise InferenceError(node=method, context=context) from e
    if inferred is util.Uninferable:
        raise InferenceError
    return instance.infer_binary_op(opnode, op, other, context, inferred)
Exemplo n.º 6
0
def _infer_unaryop(self, context=None):
    """Infer what an UnaryOp should return when evaluated."""
    for operand in self.operand.infer(context):
        try:
            yield operand.infer_unary_op(self.op)
        except TypeError as exc:
            # The operand doesn't support this operation.
            yield util.BadUnaryOperationMessage(operand, self.op, exc)
        except AttributeError as exc:
            meth = protocols.UNARY_OP_METHOD[self.op]
            if meth is None:
                # `not node`. Determine node's boolean
                # value and negate its result, unless it is
                # Uninferable, which will be returned as is.
                bool_value = operand.bool_value()
                if bool_value is not util.Uninferable:
                    yield nodes.const_factory(not bool_value)
                else:
                    yield util.Uninferable
            else:
                if not isinstance(operand, (bases.Instance, nodes.ClassDef)):
                    # The operation was used on something which
                    # doesn't support it.
                    yield util.BadUnaryOperationMessage(operand, self.op, exc)
                    continue

                try:
                    try:
                        methods = dunder_lookup.lookup(operand, meth)
                    except exceptions.AttributeInferenceError:
                        yield util.BadUnaryOperationMessage(operand, self.op, exc)
                        continue

                    meth = methods[0]
                    inferred = next(meth.infer(context=context))
                    if inferred is util.Uninferable or not inferred.callable():
                        continue

                    context = contextmod.copy_context(context)
                    context.callcontext = contextmod.CallContext(args=[operand])
                    call_results = inferred.infer_call_result(self, context=context)
                    result = next(call_results, None)
                    if result is None:
                        # Failed to infer, return the same type.
                        yield operand
                    else:
                        yield result
                except exceptions.AttributeInferenceError as exc:
                    # The unary operation special method was not found.
                    yield util.BadUnaryOperationMessage(operand, self.op, exc)
                except exceptions.InferenceError:
                    yield util.Uninferable
Exemplo n.º 7
0
def _invoke_binop_inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    context = bind_context_to_node(context, instance)
    method = methods[0]
    context.callcontext.callee = method

    if (isinstance(instance, nodes.Const) and isinstance(instance.value, str)
            and op == "%"):
        return iter(
            _infer_old_style_string_formatting(instance, other, context))

    try:
        inferred = next(method.infer(context=context))
    except StopIteration as e:
        raise InferenceError(node=method, context=context) from e
    if inferred is util.Uninferable:
        raise InferenceError
    return instance.infer_binary_op(opnode, op, other, context, inferred)
Exemplo n.º 8
0
def _invoke_binop_inference(instance, opnode, op, other, context, method_name):
    """Invoke binary operation inference on the given instance."""
    methods = dunder_lookup.lookup(instance, method_name)
    method = methods[0]
    inferred = next(method.infer(context=context))
    return instance.infer_binary_op(opnode, op, other, context, inferred)