def _process_function(self, symbol, parent=None): """Process an ast.FunctionDef object to extract data.""" function = model.Function(symbol.name) #TODO: Decorators #We are not going to collect data from decorators yet. # for decorator in symbol.decorator_list: #Decorators can be: Name, Call, Attributes # function.decorators.append(decorator.id) if symbol.args.vararg is not None: assign = model.Assign(symbol.args.vararg) assign.add_data(symbol.lineno, '__builtin__.list', None, None) function.args[assign.name] = assign if symbol.args.kwarg is not None: assign = model.Assign(symbol.args.kwarg) assign.add_data(symbol.lineno, '__builtin__.dict', None, None) function.args[assign.name] = assign #We store the arguments to compare with default backwards defaults = [] for value in symbol.args.defaults: #TODO: In some cases we can have something like: a=os.path type_value = value.__class__ data_type = self.__mapping.get(type_value, None) defaults.append((data_type, type_value)) for arg in reversed(symbol.args.args): try: if arg.id == 'self': continue except Exception as reason: logger.error('_process_function, error: %r' % reason) logger.error('line number: %d' % symbol.lineno) logger.error('line: %s' % self.content[symbol.lineno]) raise assign = model.Assign(arg.id) data_type = (model.late_resolution, None) if defaults: data_type = defaults.pop() assign.add_data(symbol.lineno, data_type[0], None, data_type[1]) function.args[assign.name] = assign for sym in symbol.body: if sym.__class__ is ast.Assign: result = self._process_assign(sym) function.add_attributes(result[0]) if parent is not None: parent.add_attributes(result[1]) elif sym.__class__ is ast.FunctionDef: function.add_function(self._process_function(sym)) if sym.__class__ is not ast.Assign: self._search_recursive_for_types(function, sym, parent) return function
def _parse_tuple_in_func_arg(self, symbol_tuple, function, lineno=0): """Parse the tuple inside a function argument call.""" for item in symbol_tuple.elts: assign = model.Assign(item.id) data_type = (model.late_resolution, None) assign.add_data(lineno, data_type[0], None, data_type[1]) function.args[assign.name] = assign
def test_attrs_in_class_func(self): module = self.analyzer.analyze(SOURCE_ANALYZER_NATIVE) clazz = module.classes['Test'] func = clazz.functions['my_function'] self.assertEqual(func.args, {}) self.assertEqual(func.decorators, []) self.assertEqual(func.return_type, []) self.assertEqual(func.name, 'my_function') self.assertEqual(func.functions, {}) #Assign result_a = func.attributes.keys() result_a.sort() expected = ['code', 'my_var'] self.assertEqual(result_a, expected) #Assing: code assign = func.attributes['code'] self.assertEqual(assign.name, 'code') assign_test1 = model.Assign('code') assign_test1.add_data(0, '__builtin__.str', " code = 'string'", None) expected_data = assign_test1.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertTrue(result_data.is_native) self.assertFalse(result_data.from_import) #Assing: my_var assign = func.attributes['my_var'] self.assertEqual(assign.name, 'my_var') assign_test1 = model.Assign('my_var') assign_test1.add_data(0, '__builtin__.str', " my_var = 'inside if'", None) expected_data = assign_test1.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertTrue(result_data.is_native) self.assertFalse(result_data.from_import)
def test_var_attribute_assign(self): module = self.analyzer.analyze(SOURCE_LATE_RESOLUTION) type1 = model._TypeData(None, 'os', 'import os', None) type2 = model.Assign('p') type2.add_data(4, model.late_resolution, 'p = os.path', _ast.Attribute) expected = {'os': type1} for imp in module.imports: data = expected[imp] impo = module.imports[imp] self.assertEqual(data.data_type, impo.data_type) self.assertEqual(data.line_content, impo.line_content) self.assertEqual(module.attributes['p'].data[0].lineno, type2.data[0].lineno) self.assertEqual(module.attributes['p'].data[0].data_type, type2.data[0].data_type) self.assertEqual(module.attributes['p'].data[0].operation, type2.data[0].operation) self.assertEqual(module.attributes['p'].data[0].line_content, type2.data[0].line_content)
def test_attrs_in_module_func(self): module = self.analyzer.analyze(SOURCE_ANALYZER_NATIVE) func = module.functions['global_func'] self.assertEqual(func.args, {}) self.assertEqual(func.decorators, []) self.assertEqual(func.return_type, []) self.assertEqual(func.name, 'global_func') self.assertEqual(func.functions, {}) #Assign: 1 result_a = func.attributes.keys() result_a.sort() expected = ['another', 'bo', 'di', 'obj'] self.assertEqual(result_a, expected) assign = func.attributes['bo'] self.assertEqual(assign.name, 'bo') assign_test1 = model.Assign('bo') assign_test1.add_data(0, '__builtin__.bool', ' bo = True', None) expected_data = assign_test1.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertTrue(result_data.is_native) self.assertFalse(result_data.from_import) #Assign: 2 assign = func.attributes['obj'] self.assertEqual(assign.name, 'obj') assign_test2 = model.Assign('obj') assign_test2.add_data(0, model.late_resolution, ' obj = os.path', _ast.Attribute) expected_data = assign_test2.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertFalse(result_data.is_native) #Assign: 3 assign = func.attributes['di'] self.assertEqual(assign.name, 'di') assign_test2 = model.Assign('di') assign_test2.add_data(0, model.late_resolution, ' di = Test()', _ast.Call) expected_data = assign_test2.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertFalse(result_data.is_native) self.assertFalse(result_data.from_import) #Assign: 4 assign = func.attributes['another'] self.assertEqual(assign.name, 'another') assign_test2 = model.Assign('another') assign_test2.add_data(0, model.late_resolution, ' another = obj', _ast.Name) expected_data = assign_test2.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertFalse(result_data.is_native)
def test_attrs_in_class_func_extended(self): module = self.analyzer.analyze(SOURCE_ANALYZER_NATIVE) clazz = module.classes['Test'] func = clazz.functions['func_args'] #Args args_names = ['var', 'inte', 'num', 'li', 'arggg', 'kwarggg'] args_names.sort() func_args = func.args.keys() func_args.sort() self.assertEqual(func_args, args_names) #For: var type_var = model._TypeData(0, model.late_resolution, None, None) func_arg_obj = func.args['var'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'var') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertFalse(type_arg_func.is_native) #For: inte type_var = model._TypeData(0, model.late_resolution, None, None) func_arg_obj = func.args['inte'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'inte') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertFalse(type_arg_func.is_native) #For: num type_var = model._TypeData(0, '__builtin__.int', None, None) func_arg_obj = func.args['num'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'num') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertTrue(type_arg_func.is_native) #For: li type_var = model._TypeData(0, '__builtin__.str', None, None) func_arg_obj = func.args['li'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'li') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertTrue(type_arg_func.is_native) #For: arggg type_var = model._TypeData(0, '__builtin__.list', None, None) func_arg_obj = func.args['arggg'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'arggg') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertTrue(type_arg_func.is_native) #For: kwarggg type_var = model._TypeData(0, '__builtin__.dict', None, None) func_arg_obj = func.args['kwarggg'] type_arg_func = func_arg_obj.data[0] self.assertEqual(func_arg_obj.name, 'kwarggg') self.assertEqual(type_arg_func.data_type, type_var.data_type) self.assertEqual(type_arg_func.line_content, type_var.line_content) self.assertEqual(type_arg_func.operation, type_var.operation) self.assertTrue(type_arg_func.is_native) #Decorators self.assertEqual(func.decorators, []) #Return Type self.assertEqual(func.return_type, []) #Attributes self.assertEqual(func.name, 'func_args') self.assertEqual(func.functions, {}) #Assign result_a = func.attributes.keys() expected = ['nothing'] self.assertEqual(result_a, expected) assign = func.attributes['nothing'] self.assertEqual(assign.name, 'nothing') assign_test1 = model.Assign('nothing') assign_test1.add_data(0, '__builtin__.bool', " nothing = False", None) expected_data = assign_test1.data[0] result_data = assign.data[0] self.assertEqual(result_data.data_type, expected_data.data_type) self.assertEqual(result_data.line_content, expected_data.line_content) self.assertEqual(result_data.operation, expected_data.operation) self.assertTrue(result_data.is_native) self.assertFalse(result_data.from_import)