예제 #1
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"])
예제 #2
0
def function_definitions_in_statement_lists_can_be_mutually_recursive():
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(nodes.ref("g"), []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(nodes.ref("f"), []))
    ])
    _update_context([f, g])
예제 #3
0
def function_definitions_can_be_mutually_recursive():
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(nodes.ref("g"), []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(nodes.ref("f"), []))
    ])
    
    _updated_bindings(nodes.module([f, g]))
예제 #4
0
def call_has_child_names_resolved():
    _assert_children_resolved(
        lambda ref: nodes.call(ref, []),
    )
    _assert_children_resolved(
        lambda ref: nodes.call(nodes.none(), [ref]),
    )
    _assert_children_resolved(
        lambda ref: nodes.call(nodes.none(), [], {"blah": ref}),
    )
예제 #5
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))
예제 #6
0
def function_definitions_in_statement_lists_can_be_defined_out_of_order():
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(nodes.ref("g"), []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[])
    
    _updated_bindings(nodes.module([f, g]))
예제 #7
0
def callee_can_be_overloaded_func_type_where_choice_is_unambiguous_given_args():
    type_bindings = {"f": types.overloaded_func(
        types.func([types.str_type], types.int_type),
        types.func([types.int_type], types.str_type),
    )}
    node = nodes.call(nodes.ref("f"), [nodes.str_literal("")])
    assert_equal(types.int_type, infer(node, type_bindings=type_bindings))
예제 #8
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"))
예제 #9
0
def test_parse_call_with_keyword_arguments():
    expected = nodes.call(
        nodes.ref("f"),
        [],
        {"person": nodes.ref("bob"), "hat": nodes.ref("fedora")},
    )
    _assert_expression_parse(expected, "f(person=bob, hat=fedora)")
예제 #10
0
def type_of_keyword_arguments_must_match():
    node = nodes.call(nodes.ref("f"), [], {"name": nodes.str_literal("Bob"), "hats": nodes.int_literal(42)})
    
    type_bindings = {
        "f": types.func(
            args=[types.func_arg("name", types.str_type)],
            return_type=types.bool_type,
        )
    }
    arg_node = nodes.int_literal(4)
    node = nodes.call(nodes.ref("f"), [], {"name": arg_node})
    assert_type_mismatch(
        lambda: infer(node, type_bindings=type_bindings),
        expected=types.str_type,
        actual=types.int_type,
        node=arg_node,
    )
예제 #11
0
def can_infer_type_of_call_with_optional_argument_specified():
    type_bindings = {
        "f": types.func(
            args=[types.func_arg(None, types.str_type, optional=True)],
            return_type=types.bool_type,
        )
    }
    node = nodes.call(nodes.ref("f"), [nodes.str_literal("blah")])
    assert_equal(types.bool_type, infer(node, type_bindings=type_bindings))
예제 #12
0
def test_parse_generator_expression():
    _assert_expression_parse(
        nodes.generator_expression(
            nodes.call(nodes.ref("f"), [nodes.ref("x")]),
            nodes.ref("x"),
            nodes.ref("xs"),
        ),
        "(f(x) for x in xs)"
    )
예제 #13
0
def test_parse_single_list_comprehension():
    _assert_expression_parse(
        nodes.list_comprehension(
            nodes.call(nodes.ref("f"), [nodes.ref("x")]),
            nodes.ref("x"),
            nodes.ref("xs"),
        ),
        "[f(x) for x in xs]"
    )
예제 #14
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))
예제 #15
0
def generic_type_arguments_are_covariant():
    type_bindings = {"f": types.generic_func(["T"], lambda T:
        types.func([T, T], T),
    )}
    node = nodes.call(nodes.ref("f"), [nodes.str_literal(""), nodes.none()])
    assert_equal(
        types.common_super_type([types.str_type, types.none_type]),
        infer(node, type_bindings=type_bindings)
    )
예제 #16
0
def can_infer_type_of_call_with_keyword_arguments():
    type_bindings = {
        "f": types.func(
            args=[types.func_arg("name", types.str_type), types.func_arg("hats", types.int_type)],
            return_type=types.bool_type,
        )
    }
    node = nodes.call(nodes.ref("f"), [], {"name": nodes.str_literal("Bob"), "hats": nodes.int_literal(42)})
    assert_equal(types.bool_type, infer(node, type_bindings=type_bindings))
예제 #17
0
def return_type_is_common_super_type_of_possible_return_types_of_overloaded_function():
    type_bindings = {"f": types.overloaded_func(
        types.func([types.object_type], types.int_type),
        types.func([types.str_type], types.str_type),
    )}
    node = nodes.call(nodes.ref("f"), [nodes.str_literal("")])
    assert_equal(
        types.common_super_type([types.int_type, types.str_type]),
        infer(node, type_bindings=type_bindings)
    )
예제 #18
0
 def test_transform_call_with_positional_arguments(self):
     func_node = nodes.ref("f")
     type_lookup = [
         (func_node, types.func([types.str_type], types.none_type))
     ]
     _assert_transform(
         nodes.call(func_node, [nodes.ref("x")]),
         cc.call(cc.ref("f"), [cc.ref("x")]),
         type_lookup=type_lookup,
     )
예제 #19
0
def type_of_positional_arguments_must_match():
    type_bindings = {"f": types.func([types.str_type], types.int_type)}
    arg_node = nodes.int_literal(4)
    node = nodes.call(nodes.ref("f"), [arg_node])
    assert_type_mismatch(
        lambda: infer(node, type_bindings=type_bindings),
        expected=types.str_type,
        actual=types.int_type,
        node=arg_node,
    )
예제 #20
0
 def test_transform_call_magic_method(self):
     func_node = nodes.ref("str")
     type_lookup = [
         (func_node, types.str_meta_type)
     ]
     
     _assert_transform(
         nodes.call(func_node, [nodes.ref("x")]),
         """str.__call__(x)""",
         type_lookup=type_lookup,
     )
예제 #21
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)
예제 #22
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)
예제 #23
0
def error_if_generic_func_is_passed_wrong_arguments():
    type_bindings = {"f": types.generic_func(["T"], lambda T:
        types.func([T, types.int_type], T),
    )}
    node = nodes.call(nodes.ref("f"), [nodes.str_literal(""), nodes.none()])
    try:
        infer(node, type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.ArgumentsError as error:
        assert_is(node, error.node)
        assert_equal("cannot call function of type: T => T, int -> T\nwith arguments: str, NoneType", str(error))
예제 #24
0
def method_can_reference_later_function_if_class_is_not_used_in_the_interim():
    g_ref = nodes.ref("g")
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(g_ref, []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[])
    
    _updated_bindings(nodes.module([
        nodes.class_("a", [f]),
        g,
    ]))
예제 #25
0
def can_infer_type_of_call_with_specified_optional_argument_after_unspecified_optional_argument():
    type_bindings = {
        "f": types.func(
            args=[
                types.func_arg("x", types.str_type, optional=True),
                types.func_arg("y", types.int_type, optional=True),
            ],
            return_type=types.bool_type,
        )
    }
    node = nodes.call(nodes.ref("f"), [], {"y": nodes.int_literal(42)})
    assert_equal(types.bool_type, infer(node, type_bindings=type_bindings))
예제 #26
0
def error_in_inferring_actual_argument_to_overloaded_function_is_not_failure_to_find_matching_overload():
    type_bindings = {"f": types.overloaded_func(
        types.func([types.object_type], types.any_type),
        types.func([types.str_type], types.any_type),
    )}
    
    ref = nodes.ref("x")
    
    try:
        infer(nodes.call(nodes.ref("f"), [ref]), type_bindings=type_bindings)
        assert False, "Expected error"
    except errors.TypeCheckError as error:
        assert_equal(ref, error.node)
예제 #27
0
def function_cannot_be_referenced_before_definition_of_dependencies():
    g_ref = nodes.ref("g")
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(g_ref, []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[])
    
    try:
        _updated_bindings(nodes.module([
            f,
            nodes.expression_statement(nodes.ref("f")),
            g,
        ]))
        assert False, "Expected error"
    except errors.UnboundLocalError as error:
        assert_equal(g_ref, error.node)
예제 #28
0
def class_cannot_be_referenced_if_method_dependencies_are_not_bound():
    g_ref = nodes.ref("g")
    f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[
        nodes.ret(nodes.call(g_ref, []))
    ])
    g = nodes.func("g", type=None, args=nodes.Arguments([]), body=[])
    
    try:
        _updated_bindings(nodes.module([
            nodes.class_("a", [f]),
            nodes.expression_statement(nodes.ref("a")),
            g,
        ]))
        assert False, "Expected error"
    except errors.UnboundLocalError as error:
        assert_equal(g_ref, error.node)
예제 #29
0
 def test_transform_call_with_keyword_arguments(self):
     func_node = nodes.ref("f")
     type_lookup = [
         (func_node, types.func(
             [
                 types.func_arg("first", types.str_type),
                 types.func_arg("second", types.str_type),
             ],
             types.none_type
         ))
     ]
     
     _assert_transform(
         nodes.call(func_node, [], {"first": nodes.ref("x"), "second": nodes.ref("y")}),
         cc.call(cc.ref("f"), [cc.ref("x"), cc.ref("y")]),
         type_lookup=type_lookup,
     )
예제 #30
0
def formal_type_of_argument_is_used_as_type_hint_for_actual_argument():
    type_bindings = {"f": types.func([types.list_type(types.str_type)], types.int_type)}
    node = nodes.call(nodes.ref("f"), [nodes.list_literal([])])
    assert_equal(types.int_type, infer(node, type_bindings=type_bindings))