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]))
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 value_in_package_can_have_same_name_as_module_if_it_is_that_module(): value_node = nodes.import_from(["."], [nodes.import_alias("x", None)]) node = nodes.module([value_node], is_executable=False) _check_module(LocalModule("root/__init__.py", node), { (".",): module({}), (".", "x"): module({}), })
def test_statements_in_module_body_are_transformed(self): module_node = nodes.module([nodes.expression_statement(nodes.ref("value"))], is_executable=True) module_type = types.module("blah", []) _assert_transform( module_node, cc.module([cc.expression_statement(cc.ref("value"))], is_executable=True, exported_names=[]), type_lookup=[(module_node, module_type)] )
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 _create_type_checker(declaration_finder=None, module_types=None, module_resolver=None, module_path=None, is_executable=False): return inference._TypeCheckerForModule( declaration_finder=declaration_finder, name_resolver=None, module_exports=modules.ModuleExports(declaration_finder), module_resolver=module_resolver, module_types=module_types, module=LocalModule(module_path, nodes.module([], is_executable=is_executable)), )
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]))
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 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 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 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, ]))
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 function_cannot_be_referenced_before_definition(): f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[]) ref_node = nodes.ref("f") try: _updated_bindings(nodes.module([ nodes.expression_statement(ref_node), f, ])) assert False, "Expected error" except errors.UnboundLocalError as error: assert_equal(ref_node, error.node)
def error_is_raised_if_value_in_package_has_same_name_as_module(): target_node = nodes.ref("x") node = nodes.module([nodes.assign([target_node], nodes.int_literal(1))], is_executable=False) try: _check_module(LocalModule("root/__init__.py", node), { (".", "x"): module({}), }) assert False, "Expected error" except errors.ImportedValueRedeclaration as error: assert_equal(target_node, error.node) assert_equal("Cannot declare value 'x' in module scope due to child module with the same name", str(error))
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 names_in_module_are_defined_and_resolved(): target_node = nodes.ref("x") ref_node = nodes.ref("x") node = nodes.module([ nodes.assign([target_node], nodes.none()), nodes.expression_statement(ref_node), ]) declarations = _create_declarations(["x"]) references = resolve(node, declarations) assert_is(references.referenced_declaration(ref_node), references.referenced_declaration(target_node))
def _update_blank_context(node, path_to_module_types): modules = {} module_types = {} for path, module_type in path_to_module_types.items(): other_module = LocalModule(path, nodes.module([])) modules[path] = other_module module_types[other_module] = module_type return update_blank_context( node, module_resolver=FakeModuleResolver(modules), module_types=FakeModuleTypes(module_types) )
def _check_module(module, path_to_module_types): modules = {} module_types = {} for path, module_type in path_to_module_types.items(): other_module = LocalModule(path, nodes.module([])) modules[path] = other_module module_types[other_module] = module_type _check( module, module_resolver=FakeModuleResolver(modules), module_types=FakeModuleTypes(module_types) )
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)
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)
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 test_module_exports_are_set_directly_on_module(self): module_node = nodes.module( [nodes.assign([nodes.ref("value")], nodes.none())], is_executable=False ) module_type = types.module("blah", [types.attr("value", types.none_type)]) _assert_transform( module_node, cc.module( [ cc.declare("value"), cc.assign(cc.ref("value"), cc.none) ], is_executable=False, exported_names=["value"], ), type_lookup=[(module_node, module_type)] )
def function_can_be_referenced_immediately_after_definition(): f = nodes.func("f", type=None, args=nodes.Arguments([]), body=[]) _updated_bindings(nodes.module([f, nodes.expression_statement(nodes.ref("f"))]))