Example #1
0
    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
        ]
Example #2
0
    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}",
                )
Example #3
0
    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]
Example #4
0
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)
Example #6
0
 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)
Example #7
0
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})
Example #8
0
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
Example #9
0
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)
Example #10
0
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 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
Example #14
0
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
Example #15
0
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
Example #16
0
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)
Example #17
0
    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 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
Example #20
0
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)
Example #21
0
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)
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:
Example #24
0
def number_of_functions(input_file):
    with open(input_file, 'r') as file:
        v = ComplexityVisitor.from_code(file.read())
    return len(v.functions)