Ejemplo n.º 1
0
def attributes_assigned_in_init_can_be_used_in_methods_when_init_method_is_defined_after_other_method():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self_init")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self_init"), "message")],
                nodes.str_literal("Hello"),
                type=nodes.ref("str"),
            )
        ],
        type=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("none")
        ),
    )
    node = nodes.class_("User", [
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[nodes.ret(nodes.attr(nodes.ref("self_g"), "message"))],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("str")
            ),
        ),
        init_func,
    ])
    _infer_class_type(node, ["__init__", "g"], [(init_func, ["self_init"])])
Ejemplo n.º 2
0
def init_method_cannot_call_other_methods():
    node = nodes.class_("User", [
        nodes.func(
            name="__init__",
            args=nodes.args([nodes.arg("self_init")]),
            body=[
                nodes.assign([nodes.ref("x")], nodes.call(nodes.attr(nodes.ref("self_init"), "g"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
    ])
    try:
        _infer_class_type(node, ["__init__", "g"])
        assert False, "Expected error"
    except errors.InitMethodCannotGetSelfAttributes as error:
        assert_equal("__init__ methods cannot get attributes of self", str(error))
Ejemplo n.º 3
0
def method_can_call_method_on_same_instance_defined_later_in_body():
    node = nodes.class_("User", [
        nodes.func(
            name="f",
            args=nodes.args([nodes.arg("self_f")]),
            body=[
                nodes.ret(nodes.call(nodes.attr(nodes.ref("self_f"), "g"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        ),
        nodes.func(
            name="g",
            args=nodes.args([nodes.arg("self_g")]),
            body=[
                nodes.ret(nodes.call(nodes.attr(nodes.ref("self_g"), "f"), []))
            ],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("none")
            ),
        )
    ])
    _infer_class_type(node, ["f", "g"])
Ejemplo n.º 4
0
def can_parse_signature_with_function_type_as_argument():
    sub_signature = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int"))],
        returns=nodes.ref("str")
    )
    expected_signature = nodes.signature(
        args=[
            nodes.signature_arg(sub_signature)
        ],
        returns=nodes.ref("none")
    )
    assert_equal(expected_signature, parse_explicit_type("(int -> str) -> none"))
Ejemplo n.º 5
0
def attributes_assigned_in_init_can_be_used_outside_of_class():
    init_func = nodes.func(
        name="__init__",
        args=nodes.args([nodes.arg("self_init")]),
        body=[
            nodes.assign(
                [nodes.attr(nodes.ref("self_init"), "message")],
                nodes.str_literal("Hello"),
                type=nodes.ref("str"),
            )
        ],
        type=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("none")
        )
    )
    class_node = nodes.class_("User", [init_func])
    
    node = [
        class_node,
        nodes.assign([nodes.ref("x")], nodes.attr(nodes.call(nodes.ref("User"), []), "message")),
    ]
    
    context = _update_context(node, declared_names_in_node=NodeDict([
        (class_node, ["Self", "__init__"]),
        (init_func, ["self_init"]),
    ]))
    
    assert_equal(types.str_type, context.lookup_name("x"))
Ejemplo n.º 6
0
def can_parse_signature_comment_with_one_formal_type_parameter():
    expected_signature = nodes.signature(
        type_params=[nodes.formal_type_parameter("T")],
        args=[nodes.signature_arg(nodes.ref("T"))],
        returns=nodes.ref("T")
    )
    assert_equal(expected_signature, parse_explicit_type("T => T -> T"))
Ejemplo n.º 7
0
def type_parameters_of_function_are_definitely_bound():
    param = nodes.formal_type_parameter("T")
    arg_ref = nodes.ref("T")
    returns_ref = nodes.ref("T")
    explicit_type = nodes.signature(type_params=[param], args=[nodes.signature_arg(arg_ref)], returns=returns_ref)
    func_node = nodes.func("f", nodes.arguments([]), [], type=explicit_type)
    
    _updated_bindings(func_node)
Ejemplo n.º 8
0
def function_adds_arguments_to_context():
    signature = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int"))],
        returns=nodes.ref("int")
    )
    args = nodes.arguments([nodes.argument("x")])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=signature)
    assert_equal(types.func([types.int_type], types.int_type), _infer_func_type(node))
Ejemplo n.º 9
0
def type_mismatch_if_return_type_is_incorrect():
    return_node = nodes.ret(nodes.str_literal("!"))
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[return_node],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    assert_type_mismatch(lambda: _infer_func_type(node), expected=types.int_type, actual=types.str_type, node=return_node)
Ejemplo n.º 10
0
def can_parse_signature_with_multiple_args():
    expected_signature = nodes.signature(
        args=[
            nodes.signature_arg(nodes.ref("int")),
            nodes.signature_arg(nodes.ref("str"))
        ],
        returns=nodes.ref("str")
    )
    assert_equal(expected_signature, parse_explicit_type("int, str -> str"))
Ejemplo n.º 11
0
def can_infer_type_of_function_with_no_args_and_return_annotation():
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[
            nodes.ret(nodes.int_literal(4))
        ],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    assert_equal(types.func([], types.int_type), _infer_func_type(node))
Ejemplo n.º 12
0
def names_in_function_signature_are_not_declared_in_outer_scope():
    explicit_type = nodes.signature(
        type_params=[nodes.formal_type_parameter("T")],
        args=[],
        returns=nodes.ref("T"),
    )
    node = nodes.func("f", nodes.arguments([]), [], type=explicit_type)
    
    declarations = find_declarations(node)
    assert not declarations.is_declared("T")
Ejemplo n.º 13
0
def init_method_is_not_present_on_instance():
    node = _create_class_with_init(
        signature=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("none")
        ),
        args=nodes.args([nodes.arg("self")]),
        body=[],
    )
    meta_type = _infer_meta_type(node, ["__init__"])
    assert not "__init__" in meta_type.type.attrs
Ejemplo n.º 14
0
def init_method_is_used_as_call_method_on_meta_type():
    node = _create_class_with_init(
        signature=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self")), nodes.signature_arg(nodes.ref("str"))],
            returns=nodes.ref("none")
        ),
        args=nodes.args([nodes.arg("self"), nodes.arg("name")]),
        body=[],
    )
    meta_type = _infer_meta_type(node, ["__init__"])
    assert_equal(types.func([types.str_type], meta_type.type), meta_type.attrs.type_of("__call__"))
Ejemplo n.º 15
0
def type_of_function_signature_is_metatype_of_function():
    type_bindings = {
        "str": types.meta_type(types.str_type),
        "int": types.meta_type(types.int_type),
    }
    node = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int"))],
        returns=nodes.ref("str")
    )
    inferred_type = infer(node, type_bindings=type_bindings)
    assert types.is_meta_type(inferred_type)
    assert_equal(types.func([types.int_type], types.str_type), inferred_type.type)
Ejemplo n.º 16
0
def error_if_type_signature_has_different_number_of_args_from_def():
    signature = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int")), nodes.signature_arg(nodes.ref("int"))],
        returns=nodes.ref("int")
    )
    args = nodes.arguments([nodes.argument("x")])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=signature)
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.ArgumentsError as error:
        assert_equal("args length mismatch: def has 1, signature has 2", str(error))
Ejemplo n.º 17
0
def type_error_if_return_is_missing():
    node = nodes.func(
        "f",
        args=nodes.arguments([]),
        body=[],
        type=nodes.signature(returns=nodes.ref("int")),
    )
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.MissingReturnError as error:
        assert_equal(node, error.node)
        assert_equal("Function must return value of type 'int'", str(error))
Ejemplo n.º 18
0
def can_parse_signature_comment_with_no_args_for_function_after_indent():
    source = """
#:: -> str
def f():
    #:: -> int
    def g():
        pass
"""
    
    module_node = parser.parse(source)
    signature = nodes.signature(returns=nodes.ref("int"))
    expected = nodes.func("g", nodes.args([]), [], type=signature)
    assert_equal(expected, module_node.body[0].body[0])
Ejemplo n.º 19
0
def can_type_check_generic_function_with_type_parameters():
    signature = nodes.signature(
        type_params=[nodes.formal_type_parameter("T")],
        args=[
            nodes.signature_arg(nodes.ref("T")),
        ],
        returns=nodes.ref("T"),
    )
    args = nodes.arguments([
        nodes.argument("value"),
    ])
    node = nodes.func("f", args=args, body=[nodes.ret(nodes.ref("value"))], type=signature)
    assert_equal(types.func([types.int_type], types.int_type), _infer_func_type(node).instantiate([types.int_type]))
Ejemplo n.º 20
0
def error_if_type_signature_argument_is_optional_but_def_argument_is_not_optional():
    signature = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int"), optional=True)],
        returns=nodes.type_union([nodes.ref("int"), nodes.ref("none")])
    )
    args = nodes.arguments([nodes.argument("x")])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=signature)
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.ArgumentsError as error:
        assert_equal("optional argument 'x' must have default value", str(error))
Ejemplo n.º 21
0
def error_if_name_of_argument_does_not_match_name_in_signature():
    signature = nodes.signature(
        args=[nodes.signature_arg("y", nodes.ref("int"))],
        returns=nodes.ref("int")
    )
    args = nodes.arguments([nodes.argument("x")])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=signature)
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.ArgumentsError as error:
        assert_equal("argument 'x' has name 'y' in signature", str(error))
Ejemplo n.º 22
0
def type_of_generic_function_signature_is_metatype_of_function():
    node = nodes.signature(
        type_params=[nodes.formal_type_parameter("T")],
        args=[nodes.signature_arg(nodes.ref("T"))],
        returns=nodes.ref("T")
    )
    inferred_type = infer(node)
    assert types.is_meta_type(inferred_type)
    assert types.is_generic_func(inferred_type.type)
    formal_type_param, = inferred_type.type.formal_type_params
    assert_equal(
        types.func([formal_type_param], formal_type_param),
        inferred_type.type.instantiate([formal_type_param]),
    )
Ejemplo n.º 23
0
def init_method_must_return_none():
    node = _create_class_with_init(
        signature=nodes.signature(
            args=[nodes.signature_arg(nodes.ref("Self"))],
            returns=nodes.ref("str")
        ),
        args=nodes.args([nodes.arg("self")]),
        body=[nodes.ret(nodes.str_literal(""))],
    )
    try:
        _infer_meta_type(node, ["__init__"])
        assert False, "Expected error"
    except errors.InitMethodsMustReturnNoneError as error:
        assert_equal(node.body[0], error.node)
Ejemplo n.º 24
0
def first_argument_in_method_signature_can_be_strict_supertype_of_class():
    node = nodes.class_("User", [
        nodes.func(
            name="is_person",
            args=nodes.args([nodes.arg("self")]),
            body=[nodes.ret(nodes.bool_literal(True))],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("object"))],
                returns=nodes.ref("bool")
            ),
        )
    ])
    class_type = _infer_class_type(node, ["is_person"])
    assert_equal(types.func([], types.bool_type), class_type.attrs.type_of("is_person"))
Ejemplo n.º 25
0
def attributes_with_function_type_defined_in_class_definition_body_are_bound_to_class_type():
    node = nodes.class_("User", [
        nodes.func(
            name="is_person",
            args=nodes.args([nodes.arg("self")]),
            body=[nodes.ret(nodes.bool_literal(True))],
            type=nodes.signature(
                args=[nodes.signature_arg(nodes.ref("Self"))],
                returns=nodes.ref("bool")
            ),
        ),
    ])
    class_type = _infer_class_type(node, ["is_person"])
    assert_equal(types.func([], types.bool_type), class_type.attrs.type_of("is_person"))
Ejemplo n.º 26
0
def argument_type_in_signature_is_unioned_with_none_if_argument_is_optional():
    signature = nodes.signature(
        args=[nodes.signature_arg(nodes.ref("int"))],
        returns=nodes.ref("int")
    )
    args = nodes.arguments([nodes.argument("x", optional=True)])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=signature)
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.UnexpectedValueTypeError as error:
        assert_equal(types.int_type, error.expected)
        assert_equal(types.union(types.int_type, types.none_type), error.actual)
Ejemplo n.º 27
0
def function_definition_signature_has_names_resolved():
    int_ref = nodes.ref("int")
    str_ref = nodes.ref("str")
    
    signature = nodes.signature(
        args=[nodes.signature_arg(int_ref)],
        returns=str_ref,
    )
    node = nodes.func("f", nodes.arguments([]), [], type=signature)
    
    declarations = _create_declarations(["f", "int", "str"])
    references = resolve(node, declarations)
    assert_is(declarations.declaration("int"), references.referenced_declaration(int_ref))
    assert_is(declarations.declaration("str"), references.referenced_declaration(str_ref))
Ejemplo n.º 28
0
def can_infer_type_of_function_with_args_and_no_return():
    signature = nodes.signature(
        args=[
            nodes.signature_arg(nodes.ref("int")),
            nodes.signature_arg(nodes.ref("str")),
        ],
        returns=nodes.ref("none"),
    )
    args = nodes.arguments([
        nodes.argument("x"),
        nodes.argument("y"),
    ])
    node = nodes.func("f", args=args, body=[], type=signature)
    assert_equal(types.func([types.int_type, types.str_type], types.none_type), _infer_func_type(node))
Ejemplo n.º 29
0
def can_infer_type_of_function_with_named_arg():
    signature = nodes.signature(
        args=[
            nodes.signature_arg("message", nodes.ref("int")),
        ],
        returns=nodes.ref("none")
    )
    args = nodes.arguments([
        nodes.argument("message"),
    ])
    node = nodes.func("f", args=args, body=[], type=signature)
    assert_equal(
        types.func([types.func_arg("message", types.int_type)], types.none_type),
        _infer_func_type(node)
    )
Ejemplo n.º 30
0
def can_infer_type_of_function_with_optional_arg():
    signature = nodes.signature(
        args=[
            nodes.signature_arg(nodes.ref("int"), optional=True),
        ],
        returns=nodes.ref("none")
    )
    args = nodes.arguments([
        nodes.argument("x", optional=True),
    ])
    node = nodes.func("f", args=args, body=[], type=signature)
    assert_equal(
        types.func([types.func_arg(None, types.int_type, optional=True)], types.none_type),
        _infer_func_type(node)
    )