def binary_operation_has_child_names_resolved(): _assert_children_resolved( lambda ref: nodes.add(ref, nodes.none()), ) _assert_children_resolved( lambda ref: nodes.add(nodes.none(), ref), )
def subscript_has_child_names_resolved(): _assert_children_resolved( lambda ref: nodes.subscript(ref, nodes.none()), ) _assert_children_resolved( lambda ref: nodes.subscript(nodes.none(), ref), )
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}), )
def except_handler_targets_in_same_try_statement_can_share_their_name(): _assert_name_is_not_definitely_bound(lambda generate: nodes.try_( [], handlers=[ nodes.except_(nodes.none(), generate.target(), []), nodes.except_(nodes.none(), generate.target(), []), ], ) )
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 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)
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 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 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 _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 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) )
def except_handler_target_is_defined_but_not_definitely_bound(): _assert_name_is_not_definitely_bound(lambda generate: nodes.try_( [], handlers=[ nodes.except_(nodes.none(), generate.target(), []) ], ) )
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 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 list_comprehension_adds_target_names_to_body_context(): target = nodes.ref("target") ref = nodes.ref("target") node = nodes.list_comprehension(target, ref, nodes.none()) declarations = _create_declarations([]) references = resolve(node, declarations) assert not declarations.is_declared("target") assert_is(references.referenced_declaration(target), references.referenced_declaration(ref))
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 except_handler_target_is_declared(): node = nodes.try_( [], handlers=[ nodes.except_(nodes.none(), nodes.ref("error"), []) ], ) declarations = find_declarations(node) assert_equal("error", declarations.declaration("error").name) assert isinstance(declarations.declaration("error"), name_declaration.VariableDeclarationNode)
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 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 declarations_in_list_comprehension_are_variable_reference_targets(): node = nodes.list_comprehension( nodes.none(), nodes.tuple_literal([nodes.ref("target"), nodes.attr(nodes.ref("other"), "name")]), nodes.ref("iterable") ) declarations = _declarations_in(node) assert isinstance(declarations.declaration("target"), name_declaration.VariableDeclarationNode) assert not declarations.is_declared("other") assert not declarations.is_declared("iterable")
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 target_of_exception_handler_is_removed_from_scope_after_exception_handler(): target_node = nodes.ref("error") node = nodes.try_( [], handlers=[ nodes.except_(nodes.none(), target_node, []) ], ) bindings = _updated_bindings(node, is_definitely_bound={"error": True}) assert not bindings.is_definitely_bound(target_node)
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 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))
def test_assignments_in_body_are_transformed(self): _assert_transform( nodes.class_("Blah", [nodes.assign([nodes.ref("value")], nodes.none())]), cc.class_( "Blah", methods=[], body=[ cc.declare("value"), cc.assign(cc.ref("value"), cc.none), ], ), )
def children_of_list_comprehension_are_checked(): _assert_child_expression_is_checked(lambda generate: nodes.list_comprehension( generate.unbound_ref(), generate.bound_ref("x", types.int_type), nodes.list_literal([]), ) ) _assert_child_expression_is_checked(lambda generate: nodes.list_comprehension( nodes.none(), nodes.attr(generate.unbound_ref(), "x"), nodes.list_literal([]), ) ) _assert_child_expression_is_checked(lambda generate: nodes.list_comprehension( nodes.none(), generate.bound_ref("x", types.int_type), generate.unbound_ref(), ) )
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 list_comprehension_has_child_names_resolved(): _assert_children_resolved( lambda ref: nodes.list_comprehension(ref, nodes.none(), nodes.none()), ) _assert_children_resolved( lambda ref: nodes.list_comprehension(nodes.none(), nodes.attr(ref, "name"), nodes.none()), ) _assert_children_resolved( lambda ref: nodes.list_comprehension(nodes.none(), nodes.none(), ref), )
def given_explicit_type_when_value_does_not_have_that_type_an_error_is_raised(): value_node = nodes.none() node = nodes.assign( [nodes.ref("x")], value_node, type=nodes.ref("int") ) try: update_context(node, type_bindings={ "int": types.meta_type(types.int_type), }) assert False, "Expected error" except errors.UnexpectedValueTypeError as error: assert_equal(value_node, error.node) assert_equal(types.none_type, error.actual) assert_equal(types.int_type, error.expected)