예제 #1
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"))
예제 #2
0
def error_is_raised_if_all_is_redeclared():
    try:
        all_node = nodes.assign(["__all__"], nodes.list_literal([]))
        second_all_node = nodes.assign(["__all__"], nodes.list_literal([]))
        _exported_names(nodes.module([all_node, second_all_node]))
        assert False, "Expected error"
    except errors.AllAssignmentError as error:
        assert_equal(second_all_node, error.node)
        assert_equal("__all__ cannot be redeclared", str(error))
예제 #3
0
def module_exports_default_to_values_without_leading_underscore_if_all_is_not_specified():
    module_node = nodes.module([
        nodes.assign(["x"], nodes.str_literal("one")),
        nodes.assign(["_y"], nodes.str_literal("two")),
        nodes.assign(["z"], nodes.int_literal(3)),
    ])
    
    module, type_lookup = _check(LocalModule(None, module_node))
    assert_equal(types.str_type, module.attrs.type_of("x"))
    assert_equal(None, module.attrs.get("_y"))
    assert_equal(types.int_type, module.attrs.type_of("z"))
예제 #4
0
def module_exports_are_specified_using_all():
    module_node = nodes.module([
        nodes.assign(["__all__"], nodes.list_literal([nodes.str_literal("x"), nodes.str_literal("z")])),
        nodes.assign(["x"], nodes.str_literal("one")),
        nodes.assign(["y"], nodes.str_literal("two")),
        nodes.assign(["z"], nodes.int_literal(3)),
    ])
    
    module, type_lookup = _check(LocalModule(None, module_node))
    assert_equal(types.str_type, module.attrs.type_of("x"))
    assert_equal(None, module.attrs.get("y"))
    assert_equal(types.int_type, module.attrs.type_of("z"))
예제 #5
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"])])
예제 #6
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))
예제 #7
0
def can_assign_value_of_subtype_to_variable():
    target_node = nodes.ref("x")
    node = nodes.assign([target_node], nodes.int_literal(1))
    type_bindings = {"x": types.object_type}
    
    context = update_context(node, type_bindings=type_bindings)
    assert_equal(types.object_type, context.lookup_name("x"))
예제 #8
0
def names_in_class_are_not_declared_in_outer_scope():
    node = nodes.class_("User", [
        nodes.assign([nodes.ref("x")], nodes.none())
    ])
    
    declarations = find_declarations(node)
    assert not declarations.is_declared("x")
예제 #9
0
def names_in_function_are_not_declared_in_outer_scope():
    node = nodes.func("f", nodes.arguments([]), [
        nodes.assign([nodes.ref("x")], nodes.none())
    ], type=None)
    
    declarations = find_declarations(node)
    assert not declarations.is_declared("x")
예제 #10
0
def declarations_in_function_include_declarations_in_body():
    node = nodes.func("f", nodes.arguments([]), [
        nodes.assign([nodes.ref("x")], nodes.none())
    ], type=None)
    
    declarations = _declarations_in(node)
    assert isinstance(declarations.declaration("x"), name_declaration.VariableDeclarationNode)
    assert not declarations.is_declared("f")
예제 #11
0
 def test_transform_setitem_subscript(self):
     _assert_transform(
         nodes.assign([nodes.subscript(nodes.ref("x"), nodes.ref("y"))], nodes.ref("z")),
         """
             var __nope_u_tmp0 = z
             x.__setitem__(y, __nope_u_tmp0)
         """
     )
예제 #12
0
def check_generates_type_lookup_for_all_expressions():
    int_ref_node = nodes.ref("a")
    int_node = nodes.int_literal(3)
    str_node = nodes.str_literal("Hello")
    
    module_node = nodes.module([
        nodes.assign(["a"], int_node),
        nodes.func("f", nodes.args([]), [
            nodes.assign("b", int_ref_node),
            nodes.assign("c", str_node),
        ], type=None),
    ])
    
    module, type_lookup = _check(LocalModule(None, module_node))
    assert_equal(types.int_type, type_lookup.type_of(int_node))
    assert_equal(types.int_type, type_lookup.type_of(int_ref_node))
    assert_equal(types.str_type, type_lookup.type_of(str_node))
예제 #13
0
def only_values_that_are_definitely_bound_are_exported():
    module_node = nodes.module([
        nodes.if_(
            nodes.bool_literal(True),
            [
                nodes.assign(["x"], nodes.str_literal("one")),
                nodes.assign(["y"], nodes.str_literal("two")),
            ],
            [
                nodes.assign(["y"], nodes.str_literal("three")),
            ]
        )
    ])
    
    module, type_lookup = _check(LocalModule(None, module_node))
    assert_equal(None, module.attrs.get("x"))
    assert_equal(types.str_type, module.attrs.type_of("y"))
예제 #14
0
def attributes_with_function_type_defined_in_class_definition_body_are_not_present_on_meta_type():
    node = nodes.class_("User", [
        nodes.assign([nodes.ref("is_person")], nodes.ref("true_func")),
    ])
    meta_type = _infer_meta_type(node, ["is_person"], type_bindings={
        "true_func": types.func([types.object_type], types.none_type)
    })
    assert "is_person" not in meta_type.attrs
예제 #15
0
def declarations_in_class_include_declarations_in_body():
    node = nodes.class_("User", [
        nodes.assign([nodes.ref("x")], nodes.none())
    ])
    
    declarations = _declarations_in(node)
    assert isinstance(declarations.declaration("x"), name_declaration.VariableDeclarationNode)
    assert not declarations.is_declared("User")
예제 #16
0
def error_is_raised_if_all_is_not_a_list():
    try:
        all_node = nodes.assign(["__all__"], nodes.none())
        _exported_names(nodes.module([all_node]))
        assert False, "Expected error"
    except errors.AllAssignmentError as error:
        assert_equal(all_node, error.node)
        assert_equal("__all__ must be a list of string literals", str(error))
예제 #17
0
def assignment_to_tuple_declares_variables_in_tuple():
    first_definition_node = nodes.ref("x")
    second_definition_node = nodes.ref("y")
    node = nodes.assign([nodes.tuple_literal([first_definition_node, second_definition_node])], nodes.none())
    declarations = find_declarations(node)
    assert_equal("x", declarations.declaration("x").name)
    assert_equal("y", declarations.declaration("y").name)
    assert isinstance(declarations.declaration("x"), name_declaration.VariableDeclarationNode)
    assert isinstance(declarations.declaration("y"), name_declaration.VariableDeclarationNode)
예제 #18
0
def values_can_have_same_name_as_child_module_if_they_are_not_in_module_scope():
    value_node = nodes.assign([nodes.ref("x")], nodes.int_literal(1))
    node = nodes.module([
        nodes.func("f", nodes.args([]), [value_node], type=None)
    ], is_executable=False)
    
    _check_module(LocalModule("root/__init__.py", node), {
        (".", "x"): module({}),
    })
예제 #19
0
def _create_module(path, is_executable=False, declares=[]):
    declarations = [
        nodes.assign([nodes.ref(name)], nodes.none())
        for name in declares
    ]
    return LocalModule(
        path=path,
        node=nodes.module(declarations, is_executable=is_executable)
    )
예제 #20
0
 def test_transform_compound_assignments(self):
     _assert_transform(
         nodes.assign(["x", "y"], nodes.ref("z")),
         cc.statements([
             cc.declare("__nope_u_tmp0", cc.ref("z")),
             cc.assign(cc.ref("x"), cc.ref("__nope_u_tmp0")),
             cc.assign(cc.ref("y"), cc.ref("__nope_u_tmp0")),
         ]),
     )
예제 #21
0
def class_definitions_assignments_shadow_variables_of_same_name_in_outer_scope():
    ref = nodes.ref("x")
    body = [nodes.assign([ref], nodes.none())]
    node = nodes.class_("User", body)
    
    declarations = _create_declarations(["x", "User"])
    
    references = resolve(node, declarations)
    assert_is_not(declarations.declaration("x"), references.referenced_declaration(ref))
예제 #22
0
def potentially_bound_variable_becomes_definitely_bound_after_being_assigned_in_both_branches_of_if_else():
    target_node = nodes.ref("x")
    node = nodes.if_(
        nodes.bool_literal(True),
        [nodes.assign([target_node], nodes.none())],
        []
    )
    
    bindings = _updated_bindings(node)
    assert not bindings.is_definitely_bound(target_node)
    
    node = nodes.if_(
        nodes.bool_literal(True),
        [nodes.assign([target_node], nodes.none())],
        [nodes.assign([target_node], nodes.none())]
    )
    bindings = _updated_bindings(node)
    assert bindings.is_definitely_bound(target_node)
예제 #23
0
def function_definitions_assignments_shadow_variables_of_same_name_in_outer_scope():
    args = nodes.arguments([])
    ref = nodes.ref("x")
    body = [nodes.assign([ref], nodes.none())]
    node = nodes.func("f", args, body, type=None)
    
    declarations = _create_declarations(["x", "f"])
    
    references = resolve(node, declarations)
    assert_is_not(declarations.declaration("x"), references.referenced_declaration(ref))
예제 #24
0
def init_must_be_function_definition():
    func_node = nodes.assign([nodes.ref("__init__")], nodes.ref("f"))
    node = nodes.class_("User", [func_node])
    try:
        _infer_class_type(node, ["__init__"], type_bindings={
            "f": types.func([types.object_type], types.str_type)
        })
        assert False, "Expected error"
    except errors.InitAttributeMustBeFunctionDefinitionError as error:
        assert_equal(func_node, error.node)
예제 #25
0
def assignment_to_tuple_unpacks_tuple_type():
    node = nodes.assign(
        [nodes.tuple_literal([nodes.ref("x"), nodes.ref("y")])],
        nodes.ref("value")
    )
    context = update_context(node, type_bindings={
        "value": types.tuple_type(types.int_type, types.str_type),
    })
    assert_equal(types.int_type, context.lookup_name("x"))
    assert_equal(types.str_type, context.lookup_name("y"))
예제 #26
0
def variable_remains_definitely_bound_after_being_reassigned_in_one_branch_of_if_else():
    target_node = nodes.ref("x")
    node = nodes.if_(
        nodes.bool_literal(True),
        [nodes.assign([target_node], nodes.none())],
        []
    )
    
    bindings = _updated_bindings(node, is_definitely_bound={"x": True})
    assert bindings.is_definitely_bound(target_node)
예제 #27
0
def cannot_declare_name_with_two_different_declaration_types():
    try:
        declarations = _declarations_in(nodes.module([
            nodes.assign([nodes.ref("f")], nodes.none()),
            nodes.func("f", nodes.arguments([]), [], type=None)
        ]))
        declarations = find_declarations(node)
        assert False, "Expected error"
    except errors.InvalidReassignmentError as error:
        assert_equal("function declaration and variable assignment cannot share the same name", str(error))
예제 #28
0
def error_if_imported_name_is_already_bound_to_non_module_value():
    modules = {
        ("messages", ): module_type("messages"),
    }
    
    statements = [
        nodes.assign([nodes.ref("messages")], nodes.none()),
        nodes.Import([nodes.import_alias("messages", None)])
    ]
    
    assert_raises(errors.UnexpectedTargetTypeError, lambda: _update_blank_context(statements, modules))
예제 #29
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))
예제 #30
0
def when_target_has_explicit_type_that_type_is_used_as_type_hint():
    node = nodes.assign(
        [nodes.ref("x")],
        nodes.list_literal([nodes.str_literal("Hello")]),
        type=nodes.type_apply(nodes.ref("list"), [nodes.ref("object")])
    )
    context = update_context(node, type_bindings={
        "list": types.meta_type(types.list_type),
        "object": types.meta_type(types.object_type),
    })
    assert_equal(types.list_type(types.object_type), context.lookup_name("x"))