Esempio n. 1
0
 def type_is_subtype_instance_of_generic_type_when_type_is_not_direct_instantiation(self):
     generic_type = types.generic_structural_type("box", ["T"], lambda T: [
         types.attr("value", T)
     ])
     class_type = types.class_type("boxed_int", [types.attr("value", "int")])
     
     assert types.is_instantiated_sub_type(generic_type, class_type)
     assert types.is_instantiated_sub_type(generic_type, generic_type(types.int_type))
     assert not types.is_instantiated_sub_type(generic_type, types.class_type("empty"))
Esempio n. 2
0
def object_can_be_called_if_it_has_call_magic_method_that_returns_callable():
    second_cls = types.class_type("Second", [
        types.attr("__call__", types.func([types.str_type], types.int_type)),
    ])
    first_cls = types.class_type("First", [
        types.attr("__call__", second_cls),
    ])
    type_bindings = {"f": first_cls}
    assert_equal(types.int_type, infer(nodes.call(nodes.ref("f"), [nodes.str_literal("")]), type_bindings=type_bindings))
Esempio n. 3
0
 def instantiated_types_are_not_equal_if_they_have_the_same_generic_type_but_different_substitutions(self):
     first_class_type = types.class_type("Blah")
     second_class_type = types.class_type("Blah")
     
     generic_type = types.generic_class("List", ["T"])
     
     first_instantiated_type = generic_type.instantiate([first_class_type])
     second_instantiated_type = generic_type.instantiate([second_class_type])
     
     assert_not_equal(first_instantiated_type, second_instantiated_type)
Esempio n. 4
0
 def invariant_type_parameter_cannot_have_different_values_in_same_is_sub_type_relation(self):
     invariant_type_param = types.invariant("T")
     first_class_type = types.class_type("User")
     second_class_type = types.class_type("Role")
     generic_class = types.generic_class("Pair", [invariant_type_param, invariant_type_param])
     assert not types.is_sub_type(
         # TODO: need a reliable way of getting the underlying type (but as an instantiated type)
         generic_class(invariant_type_param, invariant_type_param),
         generic_class(first_class_type, second_class_type),
         unify=[invariant_type_param]
     )
Esempio n. 5
0
 def contravariant_type_parameter_is_substituted_with_common_sub_type_of_actual_type_params(self):
     contravariant_type_param = types.contravariant("T")
     first_class_type = types.class_type("User")
     second_class_type = types.class_type("Role")
     generic_class = types.generic_class("Pair", [contravariant_type_param, contravariant_type_param])
     
     type_map = types.is_sub_type(
         # TODO: need a reliable way of getting the underlying type (but as an instantiated type)
         generic_class(contravariant_type_param, contravariant_type_param),
         generic_class(first_class_type, second_class_type),
         unify=[contravariant_type_param]
     )
     assert_equal(types.bottom_type, type_map[contravariant_type_param])
Esempio n. 6
0
def type_of_add_method_argument_allows_super_type():
    cls = types.class_type("Addable", {})
    cls.attrs.add("__add__", types.func([types.object_type], cls))
    
    type_bindings = {"x": cls, "y": cls}
    addition = nodes.add(nodes.ref("x"), nodes.ref("y"))
    assert_equal(cls, infer(addition, type_bindings=type_bindings))
Esempio n. 7
0
def return_type_of_add_can_differ_from_original_type():
    cls = types.class_type("Addable", {})
    cls.attrs.add("__add__", types.func([types.object_type], types.object_type))
    
    type_bindings = {"x": cls, "y": cls}
    addition = nodes.add(nodes.ref("x"), nodes.ref("y"))
    assert_equal(types.object_type, infer(addition, type_bindings=type_bindings))
Esempio n. 8
0
def can_infer_type_of_subscript_using_getitem():
    cls = types.class_type("Blah", [
        types.attr("__getitem__", types.func([types.int_type], types.str_type)),
    ])
    type_bindings = {"x": cls}
    node = nodes.subscript(nodes.ref("x"), nodes.int_literal(4))
    assert_equal(types.str_type, infer(node, type_bindings=type_bindings))
Esempio n. 9
0
 def class_type_is_not_subtype_of_structural_type_if_it_is_missing_attrs(self):
     cls = types.class_type("Person")
     structural_type = types.structural_type("HasName", [
         types.attr("name", types.str_type),
     ])
     
     assert not types.is_sub_type(structural_type, cls)
     assert not types.is_sub_type(cls, structural_type)
Esempio n. 10
0
def error_if_base_class_is_not_object():
    type_bindings = {"Person": types.meta_type(types.class_type("Person"))}
    node = nodes.class_("User", [], base_classes=[nodes.ref("Person")])
    try:
        _infer_class_type(node, [], type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.UnsupportedError as error:
        assert_equal("base classes other than 'object' are not supported", str(error))
Esempio n. 11
0
 def class_type_is_not_subtype_of_structural_type_if_attr_is_strict_supertype_of_attr_on_structural_type(self):
     cls = types.class_type("Person", [
         types.attr("name", types.object_type),
     ])
     structural_type = types.structural_type("HasName", [
         types.attr("name", types.str_type),
     ])
     
     assert not types.is_sub_type(structural_type, cls)
     assert not types.is_sub_type(cls, structural_type)
Esempio n. 12
0
def context_manager_of_with_statement_must_have_exit_method():
    cls = types.class_type("Manager", [types.attr("__enter__", enter_method())])
    context_manager_node = nodes.ref("x")
    node = nodes.with_(context_manager_node, None, [])

    try:
        update_context(node, type_bindings={"x": cls})
        assert False, "Expected error"
    except errors.NoSuchAttributeError as error:
        assert_equal(nodes.attr(context_manager_node, "__exit__"), error.node)
Esempio n. 13
0
def iter_method_must_return_iterator():
    cls = types.class_type("Blah")
    cls.attrs.add("__iter__", types.func([], 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.BadSignatureError as error:
        assert_equal(ref_node, error.node)
Esempio n. 14
0
def callee_must_be_function_or_have_call_magic_method():
    cls = types.class_type("Blah", {})
    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, error.node)
        assert_equal("callable object", error.expected)
        assert_equal(cls, error.actual)
Esempio n. 15
0
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)
Esempio n. 16
0
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))
Esempio n. 17
0
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))
Esempio n. 18
0
def cannot_reassign_read_only_attribute():
    cls = types.class_type("X", [types.attr("y", types.str_type, read_only=True)])
    
    attr_node = nodes.attr(nodes.ref("x"), "y")
    node = nodes.assign([attr_node], nodes.str_literal("Hello"))
    type_bindings = {"x": cls}
    try:
        update_context(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.ReadOnlyAttributeError as error:
        assert_equal(attr_node, error.node)
        assert_equal("'X' attribute 'y' is read-only", str(error))
Esempio n. 19
0
 def class_type_is_subtype_of_structural_type_if_it_has_subset_of_attrs(self):
     # TODO: how to handle sub-typing of mutable attrs
     cls = types.class_type("Person", [
         types.attr("name", types.str_type),
         types.attr("number_of_hats", types.int_type),
     ])
     structural_type = types.structural_type("HasName", [
         types.attr("name", types.str_type),
     ])
     
     assert types.is_sub_type(structural_type, cls)
     assert not types.is_sub_type(cls, structural_type)
Esempio n. 20
0
def assignment_to_attribute_does_not_allow_strict_supertype():
    cls = types.class_type("X", [types.attr("y", types.str_type, read_only=True)])
    
    attr_node = nodes.attr(nodes.ref("x"), "y")
    node = nodes.assign([attr_node], nodes.ref("obj"))
    type_bindings = {"x": cls, "obj": types.object_type}
    try:
        update_context(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.UnexpectedTargetTypeError as error:
        assert_equal(attr_node, error.node)
        assert_equal(types.object_type, error.value_type)
        assert_equal(types.str_type, error.target_type)
Esempio n. 21
0
def for_statement_accepts_iterable_with_iter_method():
    cls = types.class_type("Blah")
    cls.attrs.add("__iter__", types.func([], types.iterator(types.str_type)))
    
    node = nodes.for_(nodes.ref("x"), nodes.ref("xs"), [])
    
    type_bindings = {
        "xs": cls,
    }
    
    context = update_context(node, type_bindings=type_bindings)
    
    assert_equal(types.str_type, context.lookup_name("x"))
Esempio n. 22
0
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)
Esempio n. 23
0
 def instantiated_types_are_equal_if_they_have_the_same_substitutions_and_generic_type(self):
     class_type = types.class_type("Blah")
     generic_type = types.generic_class("List", "T")
     first_instantiated_type = generic_type.instantiate([class_type])
     second_instantiated_type = generic_type.instantiate([class_type])
     assert_equal(first_instantiated_type, second_instantiated_type)
Esempio n. 24
0
 def class_type_with_call_magic_method_is_not_func_type(self):
     class_type = types.class_type("A", [
         types.attr("__call__", types.func([], types.none_type)),
     ])
     assert not types.is_func_type(class_type)
Esempio n. 25
0
 def class_type_is_subtype_of_base_class_of_base_class(self):
     super_super_type = types.class_type("GrandParent")
     super_type = types.class_type("Parent", base_classes=[super_super_type])
     cls = types.class_type("Blah", base_classes=[super_type])
     assert types.is_sub_type(super_super_type, cls)
     assert not types.is_sub_type(cls, super_super_type)
Esempio n. 26
0
 def class_type_is_subtype_of_object_type(self):
     cls = types.class_type("Blah")
     assert types.is_sub_type(types.object_type, cls)
Esempio n. 27
0
 def class_type_is_subtype_of_itself(self):
     cls = types.class_type("Blah")
     assert types.is_sub_type(cls, cls)
Esempio n. 28
0
def object_can_be_called_if_it_has_call_magic_method():
    cls = types.class_type("Blah", [
        types.attr("__call__", types.func([types.str_type], types.int_type)),
    ])
    type_bindings = {"f": cls}
    assert_equal(types.int_type, infer(nodes.call(nodes.ref("f"), [nodes.str_literal("")]), type_bindings=type_bindings))
Esempio n. 29
0
def context_manager_class(enter_type=None, exit_type=None):
    return types.class_type("Manager", [
        types.attr("__enter__", enter_method(enter_type), read_only=True),
        types.attr("__exit__", exit_method(exit_type), read_only=True),
    ])
Esempio n. 30
0
 def class_type_is_not_func_type(self):
     class_type = types.class_type("A")
     assert not types.is_func_type(class_type)