Example #1
0
def test_parse_if_else_statement():
    expected = nodes.if_(
        nodes.ref("b"),
        [nodes.ret(nodes.ref("x"))],
        [nodes.ret(nodes.ref("y"))],
    )
    _assert_statement_parse(expected, "if b:\n  return x\nelse:\n  return y")
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"])
Example #3
0
def has_unconditional_return_is_true_if_both_branches_of_if_statement_return():
    assert returns.has_unconditional_return([
        nodes.if_(
            nodes.int_literal(1),
            [nodes.ret(nodes.int_literal(1))],
            [nodes.ret(nodes.int_literal(2))],
        )
    ])
Example #4
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])
Example #5
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]))
Example #6
0
 def test_condition_is_transformed_using_bool_builtin(self):
     _assert_transform(
         nodes.if_(
             nodes.ref("x"),
             [nodes.ret(nodes.ref("y"))],
             [nodes.ret(nodes.ref("z"))],
         ),
         cc.if_(
             cc.call(cc.builtin("bool"), [cc.ref("x")]),
             [cc.ret(cc.ref("y"))],
             [cc.ret(cc.ref("z"))],
         )
     )
Example #7
0
 def test_statements_in_bodies_are_transformed(self):
     _assert_transform(
         nodes.try_(
             [nodes.ret(nodes.ref("x"))],
             handlers=[nodes.except_(nodes.ref("Exception"), nodes.ref("error"), [nodes.ref("y")])],
             finally_body=[nodes.ret(nodes.ref("z"))],
         ),
         cc.try_(
             [cc.ret(cc.ref("x"))],
             handlers=[cc.except_(cc.ref("Exception"), cc.ref("error"), [cc.ref("y")])],
             finally_body=[cc.ret(cc.ref("z"))],
         ),
     )
Example #8
0
def exception_handler_targets_cannot_be_accessed_from_nested_function():
    target_node = nodes.ref("error")
    ref_node = nodes.ref("error")
    body = [nodes.ret(ref_node)]
    func_node = nodes.func("f", nodes.arguments([]), body, type=None)
    try_node = nodes.try_(
        [],
        handlers=[
            nodes.except_(nodes.none(), target_node, [func_node])
        ],
    )
    
    declaration = name_declaration.ExceptionHandlerTargetNode("error")
    references = References([
        (target_node, declaration),
        (ref_node, declaration),
        (func_node, name_declaration.VariableDeclarationNode("f")),
    ])
    
    try:
        _updated_bindings(try_node, references=references)
        assert False, "Expected error"
    except errors.UnboundLocalError as error:
        assert_equal(ref_node, error.node)
        assert_is("error", error.name)
Example #9
0
def test_parse_with_statement_single_context_manager_with_target():
    expected_node = nodes.with_(
        nodes.ref("x"),
        nodes.ref("x2"),
        [nodes.ret(nodes.ref("y"))],
    )
    _assert_statement_parse(expected_node, "with x as x2:\n  return y")
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"])])
Example #11
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]))
Example #12
0
def function_definitions_in_statement_lists_are_type_checked_even_if_not_invoked():
    node = nodes.func("f", type=None, args=nodes.Arguments([]), body=[nodes.ret(nodes.int_literal(42))])
    try:
        _update_context([node])
        assert False, "Expected error"
    except errors.UnexpectedValueTypeError as error:
        assert_equal(types.int_type, error.actual)
        assert_equal(types.none_type, error.expected)
Example #13
0
def has_unconditional_return_is_false_if_only_false_branch_of_if_statement_returns():
    assert not returns.has_unconditional_return([
        nodes.if_(
            nodes.int_literal(1),
            [],
            [nodes.ret(nodes.int_literal(2))],
        )
    ])
Example #14
0
 def test_condition_is_not_transformed_using_bool_builtin_if_already_a_bool(self):
     condition_node = nodes.ref("x")
     _assert_transform(
         nodes.if_(
             condition_node,
             [nodes.ret(nodes.ref("y"))],
             [nodes.ret(nodes.ref("z"))],
         ),
         cc.if_(
             cc.ref("x"),
             [cc.ret(cc.ref("y"))],
             [cc.ret(cc.ref("z"))],
         ),
         type_lookup=[
             (condition_node, types.bool_type),
         ],
     )
Example #15
0
def test_parse_for_loop_with_else_body():
    expected = nodes.for_(
        nodes.ref("x"), nodes.ref("xs"),
        [],
        [nodes.ret(nodes.ref("x"))],
    )
    
    _assert_statement_parse(expected, "for x in xs:\n  pass\nelse:\n  return x")
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))
def error_if_type_signature_is_missing_from_function_with_args():
    args = nodes.arguments([nodes.argument("x")])
    body = [nodes.ret(nodes.ref("x"))]
    node = nodes.func("f", args, body, type=None)
    try:
        _infer_func_type(node)
        assert False, "Expected error"
    except errors.ArgumentsError as error:
        assert_equal("signature is missing from function definition", str(error))
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)
Example #19
0
 def test_transform_while_loop_with_else_branch(self):
     _assert_transform(
         nodes.while_(
             nodes.ref("x"),
             [nodes.ret(nodes.ref("y"))],
             [nodes.ret(nodes.ref("z"))]
             
         ),
         """
             var __nope_u_normal_exit0 = False
             while True:
                 if not $builtins.bool(x):
                     __nope_u_normal_exit0 = True
                     break
                 return y
             if __nope_u_normal_exit0:
                 return z
         """
     )
Example #20
0
def function_definitions_bodies_can_access_variables_from_outer_scope():
    args = nodes.arguments([])
    ref = nodes.ref("x")
    body = [nodes.ret(ref)]
    node = nodes.func("f", args, body, type=None)
    
    declarations = _create_declarations(["x", "f"])
    
    references = resolve(node, declarations)
    assert_is(declarations.declaration("x"), references.referenced_declaration(ref))
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))
Example #22
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,
    ]))
Example #23
0
 def test_transform_while_loop(self):
     _assert_transform(
         nodes.while_(
             nodes.ref("x"),
             [nodes.ret(nodes.ref("y"))],
         ),
         cc.while_(
             cc.call(cc.builtin("bool"), [cc.ref("x")]),
             [cc.ret(cc.ref("y"))],
         )
     )
Example #24
0
def class_definition_functions_ignore_class_scope_when_resolving_references():
    ref = nodes.ref("x")
    node = nodes.class_("User", [
        nodes.assign([nodes.ref("x")], nodes.none()),
        nodes.func("f", nodes.args([]), [nodes.ret(ref)], type=None),
    ])
    
    declarations = _create_declarations(["x", "User"])
    
    references = resolve(node, declarations)
    assert_is(declarations.declaration("x"), references.referenced_declaration(ref))
Example #25
0
def function_definitions_adds_argument_names_to_body_context():
    arg = nodes.argument("x")
    args = nodes.arguments([arg])
    ref = nodes.ref("x")
    body = [nodes.ret(ref)]
    node = nodes.func("f", args, body, type=None)
    
    declarations = _create_declarations(["f"])
    references = resolve(node, declarations)
    assert not declarations.is_declared("x")
    assert_is(references.referenced_declaration(arg), references.referenced_declaration(ref))
Example #26
0
 def test_variables_are_declared(self):
     _assert_transform(
         nodes.func("f", nodes.args([]), [
             nodes.assign([nodes.ref("x")], nodes.ref("y")),
             nodes.ret(nodes.ref("value")),
         ], type=None),
         cc.func("f", [], [
             cc.declare("x"),
             cc.assign(cc.ref("x"), cc.ref("y")),
             cc.ret(cc.ref("value")),
         ]),
     )
Example #27
0
def function_definitions_arguments_shadow_variables_of_same_name_in_outer_scope():
    arg = nodes.argument("x")
    args = nodes.arguments([arg])
    ref = nodes.ref("x")
    body = [nodes.ret(ref)]
    node = nodes.func("f", args, body, type=None)
    
    declarations = _create_declarations(["x", "f"])
    
    references = resolve(node, declarations)
    assert_is(references.referenced_declaration(arg), references.referenced_declaration(ref))
    assert_is_not(declarations.declaration("x"), references.referenced_declaration(ref))
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))
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))
Example #30
0
def test_parse_with_statement_with_multiple_context_managers():
    expected_node = nodes.with_(
        nodes.ref("x"),
        nodes.ref("x2"),
        [
            nodes.with_(
                nodes.ref("y"),
                None,
                [nodes.ret(nodes.ref("z"))],
            )
        ]
    )
    _assert_statement_parse(expected_node, "with x as x2, y:\n    return z")