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"))
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))
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"))
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"))
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"])])
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))
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"))
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")
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")
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")
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) """ )
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))
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"))
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
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")
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))
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)
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({}), })
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) )
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")), ]), )
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))
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)
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))
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)
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"))
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)
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))
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))
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))
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"))