def test_annassign_subscript_multi_list(): program = """ l1: List l2: List l1 = [1, 2, 3] l2 = ['Hello', 'Goodbye'] """ module, inferer = cs._parse_text(program) for ann_node in module.nodes_of_class(astroid.AnnAssign): variable_type = lookup_type(inferer, ann_node, ann_node.target.name) assert issubclass(variable_type, List) assign_nodes = list(module.nodes_of_class(astroid.Assign)) assign_node_1 = assign_nodes[0] assign_type_1 = lookup_type(inferer, assign_node_1, assign_node_1.targets[0].name) eq_(assign_type_1, List[Any]) assign_node_2 = assign_nodes[1] assign_type_2 = lookup_type(inferer, assign_node_2, assign_node_2.targets[0].name) eq_(assign_type_2, List[Any])
def test_multiple_annotations(): src = """ def foo(x: int, y: int): return x + y """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), int) eq_(lookup_type(ti, func_node, 'y'), int)
def test_tuple_empty(): program = """ def f(x): a = () b = (x,) a = b """ module, ti = cs._parse_text(program) functiondef_node = next(module.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, functiondef_node, 'a'), Tuple[()]) x_type = lookup_type(ti, functiondef_node, 'x') eq_(lookup_type(ti, functiondef_node, 'b'), Tuple[x_type])
def test_attribute_reassign(): """ Test for correct type setting after a redundant assignment of an instance attribute. """ program = f'class Student:\n' \ f' def __init__(self, name1):\n' \ f' self.name = name1\n' \ f' self.name = name1\n' \ f'\n' module, inferer = cs._parse_text(program) functiondef_node = next(module.nodes_of_class(astroid.FunctionDef)) actual_type = lookup_type(inferer, functiondef_node, 'name') expected_type = lookup_type(inferer, functiondef_node, 'name1') assert inferer.type_constraints.can_unify(actual_type, expected_type)
def test_annassign_subscript_list_int(): program = """ lst: List[int] lst = [1, 2, 3] """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, List[int]) assign_node = next(module.nodes_of_class(astroid.Assign)) assign_type = lookup_type(inferer, assign_node, assign_node.targets[0].name) eq_(assign_type, List[int])
def test_for_list_tuple_multi_arg(): program = """ some_list = [('A', 1), ('B', 2)] for a, b in some_list: x = a y = b """ module, ti = cs._parse_text(program) for assign_node in module.nodes_of_class(astroid.AssignName): if assign_node.name == 'x' or assign_node.name == 'a': eq_(lookup_type(ti, assign_node, assign_node.name), str) elif assign_node.name == 'y' or assign_node.name == 'b': eq_(lookup_type(ti, assign_node, assign_node.name), int)
def test_for_zip(): program = """ some_str_list = ['A', 'B'] some_int_list = [1, 2] for a, b in zip(some_str_list, some_int_list): x = a y = b """ module, ti = cs._parse_text(program) for assign_node in module.nodes_of_class(astroid.AssignName): if assign_node.name == 'x' or assign_node.name == 'a': eq_(lookup_type(ti, assign_node, assign_node.name), str) elif assign_node.name == 'y' or assign_node.name == 'b': eq_(lookup_type(ti, assign_node, assign_node.name), int)
def test_mixed_annotation(): src = """ def foo(x: int, y): return y foo(5, 'Hello') """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), int) eq_(lookup_type(ti, func_node, 'y'), Any) call_node = next(ast_mod.nodes_of_class(astroid.Call)) eq_(call_node.inf_type.getValue(), Any)
def test_mixed_annotation_wrong(): src = """ def foo(x: int, y): return y foo('Hello', 5) """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), int) eq_(lookup_type(ti, func_node, 'y'), Any) call_node = next(ast_mod.nodes_of_class(astroid.Call)) assert isinstance(call_node.inf_type, TypeFailAnnotationUnify)
def test_annassign_subscript_tuple_int(): program = """ t: Tuple[int, int] """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Tuple[int, int])
def test_annassign_subscript_dict_int_str(): program = """ d: Dict[int, str] """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Dict[int, str])
def test_sorted_dict(): src = """ dict = {'B': 2, 'A': 1} sorted_dict = sorted(dict) """ module, ti = cs._parse_text(src) assign_node = list(module.nodes_of_class(astroid.AssignName))[1] eq_(lookup_type(ti, assign_node, assign_node.name), List[str])
def test_annassign_subscript_tuple(): program = """ t: Tuple """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Tuple[Any])
def test_annassign_subscript_set(): program = """ s: Set """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Set[Any])
def test_for_dict(): program = """ some_dict = {'A': 1, 'B': 2} for a, b in some_dict.items(): x = a y = b """ raise SkipTest( f'Return type of some_dict.items() is inferred as ItemsView[str, int],' f'which does not unify with List[Tuple[str, int]]') module, ti = cs._parse_text(program) for assign_node in module.nodes_of_class(astroid.AssignName): if assign_node.name == 'x' or assign_node.name == 'a': eq_(lookup_type(ti, assign_node, assign_node.name), str) elif assign_node.name == 'y' or assign_node.name == 'b': eq_(lookup_type(ti, assign_node, assign_node.name), int)
def test_annassign_subscript_list(): program = """ lst: List """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) assert issubclass(variable_type, List)
def test_annassign_subscript_set_int(): program = """ s: Set[int] """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Set[int])
def test_annassign_subscript_list(): program = """ lst: List """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) t = inferer.type_constraints.resolve(variable_type) assert t.getValue() == List[Any]
def test_any_dict(): src = """ dictionary = {'B': 2, 'A': 1, '': 3} any_empty = any(dictionary) """ module, ti = cs._parse_text(src) assign_node = list(module.nodes_of_class(astroid.AssignName))[1] t = lookup_type(ti, assign_node, assign_node.name) eq_(ti.type_constraints.resolve(t).getValue(), bool)
def test_for_zip(): program = """ some_str_list = ['A', 'B'] some_int_list = [1, 2] for a, b in zip(some_str_list, some_int_list): x = a y = b """ module, ti = cs._parse_text(program) raise SkipTest( f'Type signature of zip inferred incorrectly due to lookup_typevar ' f'using the first available function in type_store.functions[zip]') for assign_node in module.nodes_of_class(astroid.AssignName): if assign_node.name == 'x' or assign_node.name == 'a': eq_(lookup_type(ti, assign_node, assign_node.name), str) elif assign_node.name == 'y' or assign_node.name == 'b': eq_(lookup_type(ti, assign_node, assign_node.name), int)
def test_single_annotation_str(): src = """ def foo(x: str): return x """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), str)
def test_sorted_dict(): src = """ dictionary = {'B': 2, 'A': 1} sorted_dict = sorted(dictionary) """ module, ti = cs._parse_text(src) assign_node = list(module.nodes_of_class(astroid.AssignName))[1] t = lookup_type(ti, assign_node, assign_node.name) eq_(ti.type_constraints.resolve(t).getValue(), List[str])
def test_set_single_assign(variables_dict): """Test single-target assignment statements; verify unification of type variables.""" program = cs._parse_dictionary_to_program(variables_dict) module, inferer = cs._parse_text(program) for node in module.nodes_of_class(astroid.AssignName): target_value = node.parent.value target_type = lookup_type(inferer, node, node.name) # compare it to the type of the assigned value assert target_value.inf_type.getValue() == target_type
def test_set_name_assigned(variables_dict): """Test visitor for name nodes representing a variables with assigned values in module.""" program = cs._parse_dictionary_to_program(variables_dict) for variable_name in variables_dict: program += variable_name + "\n" module, inferer = cs._parse_text(program) for name_node in module.nodes_of_class(astroid.Name): name_type = lookup_type(inferer, name_node, name_node.name) assert name_node.inf_type.getValue() == name_type
def test_annotation_union_list(): src = """ x: Union[List, int] """ module, inferer = cs._parse_text(src, reset=True) for ann_node in module.nodes_of_class(astroid.AnnAssign): assert not isinstance(ann_node.inf_type, TypeFail) x_type = lookup_type(inferer, module, 'x') eq_(x_type, Union[List[Any], int])
def test_annassign_subscript_tuple_multi_param(): program = """ t: Tuple t = (1, 'Hello') """ raise SkipTest("Requires support for multi-parameter Tuple annotations") module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, Tuple[int, int])
def test_functiondef_method(): program = \ ''' class A: def method(self, x): return x + 1 ''' module, inferer = cs._parse_text(program) for func_def in module.nodes_of_class(astroid.FunctionDef): assert lookup_type(inferer, func_def, func_def.argnames()[0]) == ForwardRef('A')
def test_functiondef_staticmethod(): program = \ ''' class A: @staticmethod def method(x): return x + 1 ''' module, inferer = cs._parse_text(program) for func_def in module.nodes_of_class(astroid.FunctionDef): assert lookup_type(inferer, func_def, func_def.argnames()[0]) == int
def test_for_list_tuple(): program = """ some_list = [('A', 1), ('B', 2)] for elt in some_list: x = elt """ module, ti = cs._parse_text(program) for assign_node in module.nodes_of_class(astroid.AssignName): if assign_node.name == 'x' or assign_node.name == 'elt': eq_(lookup_type(ti, assign_node, assign_node.name), Tuple[str, int])
def test_annassign_subscript_list_int_wrong(): program = """ lst: List[int] lst = ['Hello', 'Goodbye'] """ module, inferer = cs._parse_text(program) ann_node = next(module.nodes_of_class(astroid.AnnAssign)) variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, List[int]) assign_node = next(module.nodes_of_class(astroid.Assign)) assert isinstance(assign_node.inf_type, TypeFailUnify)
def test_annassign(variables_annotations_dict): """Test whether types are being properly set for an AnnAssign node. """ program = f'class Student:\n' for variable in variables_annotations_dict: program += f' {variable}: {variables_annotations_dict[variable].__name__}\n' program += f' def __init__(self):\n' \ f' pass\n' module, inferer = cs._parse_text(program) for node in module.nodes_of_class(astroid.AnnAssign): variable_type = lookup_type(inferer, node, node.target.name) annotated_type = variables_annotations_dict[node.target.name] assert variable_type == annotated_type
def test_annassign_subscript_multi_list(): program = """ l1: List l2: List l1 = [1, 2, 3] l2 = ['Hello', 'Goodbye'] """ module, inferer = cs._parse_text(program) for ann_node in module.nodes_of_class(astroid.AnnAssign): variable_type = lookup_type(inferer, ann_node, ann_node.target.name) eq_(variable_type, List[Any]) assign_nodes = list(module.nodes_of_class(astroid.Assign)) assign_node_1 = assign_nodes[0] assign_type_1 = lookup_type(inferer, assign_node_1, assign_node_1.targets[0].name) eq_(assign_type_1, List[Any]) assign_node_2 = assign_nodes[1] assign_type_2 = lookup_type(inferer, assign_node_2, assign_node_2.targets[0].name) eq_(assign_type_2, List[Any])
def test_call_multiple_annotation_wrong_type(): src = """ def foo(x: int, y: str): return x foo('Hello', 'Goodbye') """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), int) call_node = next(ast_mod.nodes_of_class(astroid.Call)) assert isinstance(call_node.inf_type, TypeFailAnnotationUnify)
def test_call_wrong_type_str(): src = """ def foo(x: str): return x foo(5) """ ast_mod, ti = cs._parse_text(src) func_node = next(ast_mod.nodes_of_class(astroid.FunctionDef)) eq_(lookup_type(ti, func_node, 'x'), str) call_node = next(ast_mod.nodes_of_class(astroid.Call)) assert isinstance(call_node.inf_type, TypeFailAnnotationUnify)
def test_annassign_concrete(): """Test whether types are being properly set for an AnnAssign node. """ program = f'class Student:\n' \ f' name: str\n' \ f' age: int\n' \ f' status: bool\n' \ f' def __init__(self):\n' \ f' pass\n' \ f'' module, inferer = cs._parse_text(program) for node in module.nodes_of_class(astroid.AnnAssign): variable_type = lookup_type(inferer, node, node.target.name) annotated_type = _node_to_type(node.annotation.name) assert variable_type == annotated_type
def test_annassign(variables_annotations_dict): """Test whether types are being properly set for an AnnAssign node. """ program = f'class Student:\n' for variable in variables_annotations_dict: program += f' {variable}: {variables_annotations_dict[variable].__name__}\n' program += f' def __init__(self):\n' \ f' pass\n' module, inferer = cs._parse_text(program) for node in module.nodes_of_class(astroid.AnnAssign): variable_type = lookup_type(inferer, node, node.target.name) annotated_type = variables_annotations_dict[node.target.name] if isinstance(variable_type, _GenericAlias): assert _gorg(variable_type) == annotated_type else: assert variable_type == annotated_type