def operands_of_add_operation_must_support_add(): type_bindings = {"x": types.none_type, "y": types.none_type} addition = nodes.add(nodes.ref("x"), nodes.ref("y")) try: infer(addition, type_bindings=type_bindings) assert False, "Expected error" except errors.NoSuchAttributeError as error: assert_equal(nodes.attr(addition.left, "__add__"), error.node) assert_equal(addition.left, ephemeral.root_node(error.node))
def call_attribute_must_be_function(): cls = types.class_type("Blah", [types.attr("__call__", types.int_type)]) type_bindings = {"f": cls} callee_node = nodes.ref("f") try: infer(nodes.call(callee_node, []), type_bindings=type_bindings) assert False, "Expected error" except errors.UnexpectedValueTypeError as error: assert_equal(callee_node, ephemeral.root_node(error.node)) assert_equal("callable object", error.expected) assert_equal(types.int_type, error.actual)
def add_method_should_only_accept_one_argument(): cls = types.class_type("NotAddable", {}) cls.attrs.add("__add__", types.func([types.object_type, types.object_type], cls)) type_bindings = {"x": cls, "y": cls} addition = nodes.add(nodes.ref("x"), nodes.ref("y")) try: infer(addition, type_bindings=type_bindings) assert False, "Expected error" except errors.TypeCheckError as error: assert_equal(addition, ephemeral.root_node(error.node))
def iter_method_must_take_no_arguments(): cls = types.class_type("Blah") cls.attrs.add("__iter__", types.func([types.str_type], types.iterable(types.str_type))) ref_node = nodes.ref("xs") node = nodes.for_(nodes.ref("x"), ref_node, []) try: update_context(node, type_bindings={"x": None, "xs": cls}) assert False, "Expected error" except errors.TypeCheckError as error: assert_equal(ref_node, ephemeral.root_node(error.node))
def _print_error(error): if isinstance(error, SyntaxError): _print_location(error) print() print("{}: {}".format(type(error).__name__, error.msg)) elif hasattr(error, "node"): node = ephemeral.root_node(error.node) location = getattr(node, "location", None) if location is not None: _print_location(location) print(error) else: print(error)
def assignment_to_list_does_not_allow_supertype(): target_sequence_node = nodes.ref("x") value_node = nodes.ref("y") node = nodes.assign([nodes.subscript(target_sequence_node, nodes.int_literal(0))], value_node) type_bindings = { "x": types.list_type(types.str_type), "y": types.object_type, } try: update_context(node, type_bindings=type_bindings) assert False, "Expected error" except errors.UnexpectedTargetTypeError as error: assert_equal(target_sequence_node, ephemeral.root_node(error.node)) assert_equal( ephemeral.FormalArg(ephemeral.attr(target_sequence_node, "__setitem__"), 1), ephemeral.underlying_node(error.node) ) assert_equal(types.object_type, error.value_type) assert_equal(types.str_type, error.target_type)
def for_statement_target_cannot_be_strict_subtype_of_iterable_element_type(): target_sequence_node = nodes.ref("ys") target_node = nodes.subscript(target_sequence_node, nodes.int_literal(0)) iterable_node = nodes.ref("xs") node = nodes.for_(target_node, iterable_node, []) try: update_context(node, type_bindings={ "xs": types.list_type(types.object_type), "ys": types.list_type(types.int_type), }) assert False, "Expected error" except errors.UnexpectedTargetTypeError as error: assert_equal(target_sequence_node, ephemeral.root_node(error.node)) assert_equal( ephemeral.FormalArg(ephemeral.attr(target_sequence_node, "__setitem__"), 1), ephemeral.underlying_node(error.node) ) assert_equal(types.object_type, error.value_type) assert_equal(types.int_type, error.target_type)
def for_statement_requires_iterable_getitem_method_to_accept_integers(): cls = types.class_type("Blah") cls.attrs.add("__getitem__", types.func([types.str_type], types.str_type)) ref_node = nodes.ref("xs") node = nodes.for_(nodes.ref("x"), ref_node, []) type_bindings = { "xs": cls, } try: update_context(node, type_bindings=type_bindings) assert False, "Expected error" except errors.UnexpectedTargetTypeError as error: assert_equal(ref_node, ephemeral.root_node(error.node)) assert_equal( ephemeral.FormalArg(ephemeral.attr(ref_node, "__getitem__"), 0), ephemeral.underlying_node(error.node) ) assert_equal(types.int_type, error.value_type) assert_equal(types.str_type, error.target_type)
def test_root_node_of_ephemeral_attr_is_left_value_if_left_value_is_not_ephemeral(): ref_node = nodes.ref("x") assert_is(ref_node, ephemeral.root_node(ephemeral.attr(ref_node, "__len__")))
def test_root_node_of_ephemeral_node_recurses_up_tree_until_non_ephemeral_node(): ref_node = nodes.ref("x") node = ephemeral.attr(ephemeral.attr(ref_node, "__call__"), "__call__") assert_is(ref_node, ephemeral.root_node(node))