Ejemplo n.º 1
0
 def type_is_instance_of_generic_type_when_type_is_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 generic_type.is_instantiated_type(generic_type(types.int_type))
     assert not generic_type.is_instantiated_type(class_type)
Ejemplo n.º 2
0
 def common_super_type_of_types_is_passed_type_that_is_super_type_of_all_other_types(self):
     first_type = types.structural_type("first", [
         types.attr("a", types.int_type),
         types.attr("b", types.str_type),
     ])
     second_type = types.structural_type("second", [
         types.attr("a", types.int_type),
     ])
     assert_equal(second_type, types.common_super_type([first_type, second_type]))
Ejemplo n.º 3
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))
Ejemplo n.º 4
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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    def instantiated_generic_structural_type_is_sub_type_of_other_instantiated_generic_structural_type_if_it_has_matching_attributes(self):
        iterator = types.generic_structural_type("iterator", [types.covariant("T")], lambda T: [
            types.attr("__iter__", types.func([], iterator(T))),
            types.attr("__next__", types.func([], T)),
        ])

        iterable = types.generic_structural_type("iterable", [types.covariant("T")], lambda T: [
            types.attr("__iter__", types.func([], iterator(T))),
        ])
        
        assert types.is_sub_type(
            iterable(types.int_type),
            iterator(types.int_type),
        )
Ejemplo n.º 7
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))
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
def can_import_module_using_plain_import_syntax():
    node = nodes.Import([nodes.import_alias("message", None)])
    
    context = _update_blank_context(node, {
        ("message", ): module_type("message", [types.attr("value", types.str_type)])
    })
    
    assert_equal(types.str_type, context.lookup_name("message").attrs.type_of("value"))
Ejemplo n.º 10
0
 def recursive_instantiated_generic_structural_type_is_sub_type_of_same_instantiated_generic_structural_type_if_it_has_matching_attributes(self):
     recursive = types.generic_structural_type("recursive", [types.covariant("T")], lambda T: [
         types.attr("__iter__", types.func([], recursive(T))),
     ])
     
     assert types.is_sub_type(
         recursive(types.int_type),
         recursive(types.int_type),
     )
Ejemplo n.º 11
0
def can_import_value_from_relative_module_using_import_from_syntax():
    node = nodes.import_from([".", "message"], [nodes.import_alias("value", None)])
    
    context = _update_blank_context(node, {
        (".", "message"): module_type("message", [types.attr("value", types.str_type)])
    })
    
    assert_equal(types.str_type, context.lookup_name("value"))
    assert_raises(errors.UnboundLocalError, lambda: context.lookup_name("message"))
Ejemplo n.º 12
0
def can_use_aliases_with_plain_import_syntax():
    node = nodes.Import([nodes.import_alias("message", "m")])
    
    context = _update_blank_context(node, {
        ("message", ): module_type("message", [types.attr("value", types.str_type)])
    })
    
    assert_equal(types.str_type, context.lookup_name("m").attrs.type_of("value"))
    assert_raises(errors.UnboundLocalError, lambda: context.lookup_name("message"))
Ejemplo n.º 13
0
def can_import_module_using_import_from_syntax():
    node = nodes.import_from(["."], [nodes.import_alias("message", None)])
    message_module = module_type("message", [types.attr("value", types.str_type)])
    
    context = _update_blank_context(node, {
        (".", "message"): message_module,
    })
    
    assert_equal(types.str_type, context.lookup_name("message").attrs.type_of("value"))
Ejemplo n.º 14
0
def type_of_structural_type_is_as_definition():
    type_bindings = {
        "str": types.meta_type(types.str_type),
        "int": types.meta_type(types.int_type),
    }
    node = nodes.structural_type("Song", [
        ("description", nodes.ref("str")),
        ("length", nodes.ref("int")),
    ])
    
    context = update_context(node, type_bindings=type_bindings)
    declared_type = context.lookup_name("Song")
    
    assert types.is_meta_type(declared_type)
    expected_type = types.structural_type("Song", [
        types.attr("description", types.str_type),
        types.attr("length", types.int_type),
    ])
    assert types.is_equivalent_type(expected_type, declared_type.type)
Ejemplo n.º 15
0
 def instantiating_type_replaces_type_in_attributes_of_instantiated_attributes(self):
     one = types.generic_class("one", ["A"])
     two = types.generic_class("two", ["B"])
     three = types.generic_class("three", ["C"], lambda C: [
         types.attr("value", one(two(C))),
     ])
     assert_equal(
         one(two(types.int_type)),
         three(types.int_type).attrs.type_of("value"),
     )
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
 def invariant_type_parameter_can_be_unified_when_part_of_recursive_structural_type(self):
     invariant_type_param = types.invariant("T")
     recursive = types.generic_structural_type("recursive", [types.covariant("T")], lambda T: [
         types.attr("__iter__", types.func([], recursive(T))),
     ])
     
     assert types.is_sub_type(
         recursive(invariant_type_param),
         recursive(types.int_type),
         unify=[invariant_type_param]
     )
Ejemplo n.º 18
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)
Ejemplo n.º 19
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))
Ejemplo n.º 20
0
def importing_module_in_package_mutates_that_package_in_importing_module_only():
    node = nodes.Import([nodes.import_alias("messages.hello", None)])
    messages_module = module_type("messages")
    hello_module = module_type("messages.hello", [types.attr("value", types.str_type)])
    
    context = _update_blank_context(node, {
        ("messages", ): messages_module,
        ("messages", "hello"): hello_module,
    })
    
    assert_equal(types.str_type, context.lookup_name("messages").attrs.type_of("hello").attrs.type_of("value"))
    assert "hello" not in messages_module.attrs
Ejemplo n.º 21
0
def builtin_modules_are_typed():
    cgi_module = BuiltinModule("cgi", types.module("cgi", [
        types.attr("escape", types.none_type),
    ]))
    node = nodes.Import([nodes.import_alias("cgi", None)])
    
    context = update_blank_context(
        node,
        module_resolver=FakeModuleResolver({("cgi",): cgi_module}),
        module_types=FakeModuleTypes({}),
    )
    
    assert_equal(types.none_type, context.lookup_name("cgi").attrs.type_of("escape"))
Ejemplo n.º 22
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)
Ejemplo n.º 23
0
def can_import_module_after_importing_parent_package():
    messages_module = module_type("messages")
    hello_module = module_type("messages.hello", [types.attr("value", types.str_type)])
    modules = {
        ("messages", ): messages_module,
        ("messages", "hello"): hello_module,
    }
    
    context = _update_blank_context([
        nodes.Import([nodes.import_alias("messages", None)]),
        nodes.Import([nodes.import_alias("messages.hello", None)])
    ], modules)
    
    assert_equal(types.str_type, context.lookup_name("messages").attrs.type_of("hello").attrs.type_of("value"))
    assert "hello" not in messages_module.attrs
Ejemplo n.º 24
0
 def test_module_exports_are_set_directly_on_module(self):
     module_node = nodes.module(
         [nodes.assign([nodes.ref("value")], nodes.none())],
         is_executable=False
     )
     module_type = types.module("blah", [types.attr("value", types.none_type)])
     _assert_transform(
         module_node,
         cc.module(
             [
                 cc.declare("value"),
                 cc.assign(cc.ref("value"), cc.none)
             ],
             is_executable=False,
             exported_names=["value"],
         ),
         type_lookup=[(module_node, module_type)]
     )
Ejemplo n.º 25
0
 def value_in_builtin_module_can_be_resolved(self):
     # import cgi
     cgi_module = BuiltinModule(
         "cgi",
         types.module("cgi", [types.attr("escape", types.none_type)])
     )
     
     module_resolver = _module_resolver(
         _create_module("root/main.py", is_executable=True),
         builtin_modules={"cgi": cgi_module}
     )
     resolved_import = module_resolver.resolve_import_value(
         ["cgi"],
         "escape",
     )
     
     assert_is(cgi_module, resolved_import.module)
     assert_equal("escape", resolved_import.attr_name)
     assert_equal(["cgi"], resolved_import.module_name)
Ejemplo n.º 26
0
 def instantiating_type_replaces_type_in_attributes(self):
     generic_type = types.generic_structural_type("box", ["T"], lambda T: [
         types.attr("value", T)
     ])
     assert_equal(int_type, generic_type(int_type).attrs.type_of("value"))
Ejemplo n.º 27
0
def assignment_to_attribute_allows_subtype():
    cls = types.class_type("X", [types.attr("y", types.object_type, read_only=False)])
    
    node = nodes.assign([nodes.attr(nodes.ref("x"), "y")], nodes.str_literal("Hello"))
    type_bindings = {"x": cls}
    update_context(node, type_bindings=type_bindings)
Ejemplo n.º 28
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)
Ejemplo 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),
    ])
Ejemplo n.º 30
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))