def run(path, code=None, params=None, ignore=None, select=None, **meta): """Check code with Radon. :return list: List of errors. """ complexity = params.get("complexity", 10) no_assert = params.get("no_assert", False) show_closures = params.get("show_closures", False) visitor = ComplexityVisitor.from_code(code, no_assert=no_assert) blocks = visitor.blocks if show_closures: blocks = add_inner_blocks(blocks) return [ { "lnum": block.lineno, "col": block.col_offset, "type": "R", "number": "R709", "text": "R701: %s is too complex %d" % (block.name, block.complexity), } for block in visitor.blocks if block.complexity > complexity ]
def run_check(self, ctx: RunContext): # noqa # noqa """Check code with Radon.""" params = ctx.get_params("radon") options = ctx.options if options: params.setdefault("complexity", options.max_complexity) params.setdefault("no_assert", options.radon_no_assert) params.setdefault("show_closures", options.radon_show_closures) complexity = params.get("complexity", 10) no_assert = params.get("no_assert", False) show_closures = params.get("show_closures", False) visitor = ComplexityVisitor.from_code(ctx.source, no_assert=no_assert) blocks = visitor.blocks if show_closures: blocks = add_inner_blocks(blocks) for block in visitor.blocks: if block.complexity > complexity: ctx.push( lnum=block.lineno, col=block.col_offset + 1, source="radon", type="R", number="R901", text=f"{block.name} is too complex {block.complexity}", )
def run(path, code=None, params=None, ignore=None, select=None, **meta): """Check code with Radon. :return list: List of errors. """ complexity = params.get('complexity', 10) no_assert = params.get('no_assert', False) show_closures = params.get('show_closures', False) visitor = ComplexityVisitor.from_code(code, no_assert=no_assert) blocks = visitor.blocks if show_closures: blocks = add_inner_blocks(blocks) return [{ 'lnum': block.lineno, 'col': block.col_offset, 'type': 'R', 'number': 'R709', 'text': 'R701: %s is too complex %d' % (block.name, block.complexity) } for block in visitor.blocks if block.complexity > complexity]
def calculate_complexity(path): try: with open(path) as file: data = file.read() v = ComplexityVisitor.from_code(data) return v.complexity except SyntaxError: return -1
def run(self): '''Run the ComplexityVisitor over the AST tree.''' if self.max_cc < 0: if not self.no_assert: return self.max_cc = 10 visitor = ComplexityVisitor.from_ast(self.tree, no_assert=self.no_assert) for block in visitor.blocks: if block.complexity > self.max_cc: text = self._error_tmpl % (block.name, block.complexity) yield block.lineno, block.col_offset, text, type(self)
def radon_test(f): filename = 'a1/a1_solution_' + f + '.py' with open(filename) as file: source = file.read() cv = ComplexityVisitor.from_code(source) res = sorted_results(cv.functions + cv.classes, order=LINES) output = {} for r in res: # print(f'Function: {r.name}, CC: {r.complexity}') output['CC'] = r.complexity res = analyze(source) # pprint(res) basic = {'loc': res[0], 'lloc': res[1], 'sloc': res[2], 'comments': res[3], 'multi': res[4], 'blank': res[5], 'single_comment': res[6]} output['Lines'] = basic config = Config(min='A', max='F', exclude=None, ignore=None, no_assert=False, show_closures=False, order=LINES) ch = CCHarvester([filename], config) res = ch.results x = json.loads(ch.as_json()) # pprint(x) res = h_visit(source) hals = {'h1': res[0], 'h2': res[1], 'N1': res[2], 'N2': res[3], 'vocabulary': res[4], 'length': res[5], 'calculated_length': res[6], 'volume': res[7], 'difficulty': res[8], 'effort': res[9], 'time': res[10], 'bugs': res[11]} output['Halstead'] = hals pprint({f: output})
def analyse_cc(iface, code): visitor = ComplexityVisitor.from_code(code) for f in visitor.functions: iface.report_metric("cyclomatic_complexity", f.complexity, line = f.lineno, function = f.name, class_ = f.classname) if f.complexity > 10: iface.report_violation("max_cyclomatic_complexity_10", "CC of " + str(f.complexity)) if f.complexity > 15: iface.report_violation("max_cyclomatic_complexity_15", "CC of " + str(f.complexity)) return visitor.total_complexity
def mi_parameters(code, count_multi=True): '''Given a source code snippet, compute the necessary parameters to compute the Maintainability Index metric. These include: * the Halstead Volume * the Cyclomatic Complexity * the number of LLOC (Logical Lines of Code) * the percent of lines of comment :param multi: If True, then count multiline strings as comment lines as well. This is not always safe because Python multiline strings are not always docstrings. ''' ast_node = ast.parse(code) raw = analyze(code) comments_lines = raw.comments + (raw.multi if count_multi else 0) comments = comments_lines / float(raw.sloc) * 100 if raw.sloc != 0 else 0 return (h_visit_ast(ast_node).volume, ComplexityVisitor.from_ast(ast_node).total_complexity, raw.lloc, comments)
def analyse(self): output = {} cv = ComplexityVisitor.from_code(self._source) res = sorted_results(cv.functions + cv.classes, order=LINES) # should be one result, since giving one function # if len(res) > 1: # raise ValueError('Complexity Analysis returned multiple results') output['cc'] = res[0].complexity res = analyze(self._source) lines_comments = dict(res._asdict()) output.update(lines_comments) res = h_visit(self._source) hals = dict(res._asdict()) output.update(hals) self._res = output
def generate_radon_metrics(code_input): radon_metrics = make_default_radon_metrics() try: # raw metrics raw_metrics = analyze(code_input) radon_metrics['loc'] = raw_metrics.loc radon_metrics['lloc'] = raw_metrics.lloc radon_metrics['sloc'] = raw_metrics.sloc radon_metrics['comments'] = raw_metrics.comments radon_metrics['multi'] = raw_metrics.multi radon_metrics['single_comments'] = raw_metrics.single_comments # cyclomatic complexity cc = ComplexityVisitor.from_code(code_input) radon_metrics['function_num'] = len(cc.functions) total_function_complexity = 0.0 for fun in cc.functions: total_function_complexity += fun.complexity radon_metrics['total_function_complexity'] = total_function_complexity radon_metrics['radon_functions_complexity'] = cc.functions_complexity # calculate based on AST tree v = h_visit_ast(h_visit(code_input)) radon_metrics['h1'] = v.h1 radon_metrics['h2'] = v.h2 radon_metrics['N1'] = v.N1 radon_metrics['N2'] = v.N2 radon_metrics['vocabulary'] = v.vocabulary radon_metrics['length'] = v.length radon_metrics['calculated_length'] = v.calculated_length radon_metrics['volume'] = v.volume radon_metrics['difficulty'] = v.difficulty radon_metrics['effort'] = v.effort radon_metrics['time'] = v.time radon_metrics['bugs'] = v.bugs # Maintainability Index (MI) based on ## the Halstead Volume, the Cyclomatic Complexity, the SLOC number and the number of comment lines mi = mi_visit(code_input, multi=True) radon_metrics['Maintainability_Index'] = mi return radon_metrics except: return radon_metrics
def analyze_complexity(code, code_metrics, is_multi): ast = visitors.code2ast(code) # Cyclomatic complexity complexity_visitor = ComplexityVisitor.from_ast(ast) res = get_wavg_complexity(complexity_visitor.blocks) # Maintainability index and rank if code_metrics['sloc'] != 0: comments_lines = (code_metrics['comments'] + (code_metrics['multi'] if is_multi else 0)) comments = utils.divide_or_zero(comments_lines, code_metrics['sloc']) * 100 else: comments = 0 res['mi'] = metrics.mi_compute(calculate_halstead_volume(ast), complexity_visitor.total_complexity, code_metrics['lloc'], comments) return res
def cc_visit_ast(ast_node, **kwargs): '''Visit the AST node with :class:`~radon.visitors.ComplexityVisitor`. All the keyword arguments are directly passed to the visitor. ''' return ComplexityVisitor.from_ast(ast_node, **kwargs).blocks
def cc_visit_ast(ast_node): '''Visit the AST node with :class:`~radon.visitors.ComplexityVisitor` and pass the resulting blocks to :func:`~radon.complexity.sorted_results`. ''' return sorted_results(ComplexityVisitor.from_ast(ast_node).blocks)
def __get_code_metrics(codigo: str): """ Recupera as métricas de um código Python. McCabe's (Complexidade) - complexity: Complexidade Total - n_classes: Quantidade de Classes - n_functions: Quantidade de Funções Métricas Brutas (Código) - loc: Número Total de Linhas - lloc: Número de Linhas Lógicas de Código - sloc: Número de Linhas de Código - comments: Número de Comentários - single_comments: Número de Comentários Simples - multilines: Número de Multi-line Strings - blank_lines: Número de Linhas em Branco Halstead (Métricas de SW) - h1: Número de Operadores Distintos - h2: Número de Operandos Distintos - N1: Número Total de Operadores - N2: Número Total de Operandos - vocabulary: Vocabulário (h = h1 + h2) - length: Tamanho (N = N1 + N2) - calculated_length: Tamanho Calculado (h1 * log2(h1) + h2 * log2(h2)) - volume: Volume (V = N * log2(h)) - difficulty: Dificuldade (D = h1/2 * N2/h2) - effort: Esforço (E = D * V) - time: Tempo (T = E / 18 segundos) - bugs: Bugs (B = V / 3000), estivativa de erros na implementação :param path: Caminho absoluto para o arquivo de código fonte (.py). :type path: str :return: As métricas que puderam ser extraídas do código. """ metricas = Metricas() try: v = ComplexityVisitor.from_code(codigo) metricas.complexity = v.complexity metricas.n_functions = len(v.functions) metricas.n_classes = len(v.functions) except Exception as e: pass try: a = analyze(codigo) metricas.loc = a.loc metricas.lloc = a.lloc metricas.sloc = a.sloc metricas.blank_lines = a.blank metricas.multilines = a.multi metricas.comments = a.comments metricas.single_comments = a.single_comments except Exception as e: pass try: h = h_visit(codigo) metricas.h1 = h.total.h1 metricas.h2 = h.total.h2 metricas.N1 = h.total.N1 metricas.N2 = h.total.N2 metricas.h = h.total.vocabulary metricas.N = h.total.length metricas.calculated_N = h.total.calculated_length metricas.volume = h.total.volume metricas.difficulty = h.total.difficulty metricas.effort = h.total.effort metricas.bugs = h.total.bugs metricas.time = h.total.time except Exception as e: pass return metricas
logging.info(config_dict["dus"]) logging.info(config_dict["critical_dus"]) du_list = [] du_dict = {} for i in config_dict["dus"].keys(): du_list.append(i) for i in range(len(du_list)): du_name = du_list[i] out_route = config_dict["output_dir"]+os.sep+du_name+".py" ##print (out_route) cadena = "" file = open(out_route,"r") for i in file: cadena = cadena + i try: v = ComplexityVisitor.from_code(cadena) except TabError: raise TabError("Error in indentation of dus, please indent source code with divisible by 4 spaces or tab size") #print(v.functions) temp_complex = 0 temp_size = 0 for i in v.functions: #print(i.fullname,i.complexity,i.endline-i.lineno) temp_complex += i.complexity temp_size += i.endline-i.lineno du_dict[du_name]={} du_dict[du_name]["cost"]=temp_complex du_dict[du_name]["size"]=temp_size #para el size resto lineas y punto ##print(du_dict)
def mi_parameters_without_comments(code): ast_node = ast.parse(code) raw = analyze(code) return (h_visit_ast(ast_node).total.volume, ComplexityVisitor.from_ast(ast_node).total_complexity, raw.lloc)
from radon.visitors import ComplexityVisitor # Import for option parsing import sys from header import dataFromFile from optparse import OptionParser # Declare options for inputting the file optparser = OptionParser() optparser.add_option('-f', '--inputFile', dest='inFile', help='file name of the source file', default=None) # Check if the file is run directly if(__name__ == '__main__') : # Parse the available options (options, args) = optparser.parse_args() # Grab the source code code = None if(options.inFile is None) : code = sys.stdin elif(options.inFile is not None) : code = dataFromFile(options.inFile) else : print("No file specified, system will exit") sys.exit("System will exit now!") # print the complexity of the program print("Cyclomatic complexity of the given source code is "+str(ComplexityVisitor.from_code(code).complexity))
''' commitComplex = {} complexities = [] commitComplex['cid'] = responobj['cid'] commitComplex['complexities'] = complexities cComplex = 0 for entry in responobj['entries']: sourceComplex = {} blob = repo[entry['id']] filename = entry['name'] sourceComplex['name'] = filename sourceComplex['complex'] = [] code = str(blob.data, 'utf-8') try: v = ComplexityVisitor.from_code(code) complexsum = 0 for func in v.functions: funcComplex = {} funcComplex['name'] = func.name funcComplex['lineno'] = func.lineno funcComplex['complexity'] = func.complexity complexsum = complexsum + func.complexity # append func complex sourceComplex['complex'].append(funcComplex) # accumulate the file complexity sourceComplex['complexval'] = complexsum # accumulate the commit complexity cComplex = cComplex + complexsum complexities.append(sourceComplex) except Exception:
def number_of_functions(input_file): with open(input_file, 'r') as file: v = ComplexityVisitor.from_code(file.read()) return len(v.functions)