def testIterFilenames(self): tmpdir = tempfile.mkdtemp() try: os.makedirs(os.path.join(tmpdir, 'd1')) f1 = os.path.join(tmpdir, 'd1', 't1.py') open(f1, 'w').close() f2 = os.path.join(tmpdir, 'd1', 't2.py') open(f2, 'w').close() os.makedirs(os.path.join(tmpdir, 'd2')) f3 = os.path.join(tmpdir, 'd2', 't3.py') open(f3, 'w').close() f4 = os.path.join(tmpdir, 'd2', 't4.py') open(f4, 'w').close() dir1 = [os.path.join(tmpdir, 'd1')] dir12 = [os.path.join(tmpdir, 'd1'), os.path.join(tmpdir, 'd2')] dirall = [tmpdir] # Test without excludes exclude = '' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1, f2, f3, f4])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1, f2, f3, f4])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1, f2])) # Test with one exclude exclude = '*/t2.py' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1, f3, f4])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1, f3, f4])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1])) # Test with two excludes exclude = '*/t2.py,*/d2/*' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1])) # Test with "-" is preserved for stdin if it's the only # parameter names = iter_filenames(['-']) self.assertEqual(set(names), set(['-'])) finally: shutil.rmtree(tmpdir)
def mi(multi=True, exclude=None, ignore=None, show=False, *paths): '''Analyze the given Python modules and compute the Maintainability Index. The maintainability index (MI) is a compound metric, with the primary aim being to determine how easy it will be to maintain a particular body of code. :param -e, --exclude <str>: Comma separated list of patterns to exclude. :param -i, --ignore <str>: Comma separated list of patterns to ignore. Radon won't even descend into those directories. :param -m, --multi: If given, multiline strings are counted as comments. :param -s, --show: If given, the actual MI value is shown in results. :param paths: The modules or packages to analyze. ''' for name in iter_filenames(paths, exclude, ignore): with open(name) as fobj: try: result = mi_visit(fobj.read(), multi) except Exception as e: log(name, indent=1) log_error(e, indent=1) continue except KeyboardInterrupt: log(name) return rank = mi_rank(result) color = MI_RANKS[rank] to_show = '' if not show else ' ({0:.2f})'.format(result) log('{0} - {1}{2}{3}{4}', name, color, rank, to_show, RESET)
def raw(exclude=None, ignore=None, summary=False, *paths): '''Analyze the given Python modules and compute raw metrics. Raw metrics include: * LOC: The number of lines of code (total) * LLOC: The number of logical lines of code * SLOC: The number of source lines of code (not necessarily corresponding to the LLOC) * comments: The number of Python comment lines * multi: The number of lines which represent multi-line strings * blank: The number of blank lines (or whitespace-only ones) The equation: sloc + blanks = loc should always hold. :param -e, --exclude <str>: Comma separated list of patterns to exclude. By default hidden directories (those starting with '.') are excluded. :param -i, --ignore <str>: Comma separated list of patterns to ignore. Radon won't even descend into those directories. :param -s, --summary: If given, at the end of the analysis display the summary of the gathered metrics. Default to False. :param paths: The modules or packages to analyze. ''' headers = ['LOC', 'LLOC', 'SLOC', 'Comments', 'Multi', 'Blank'] sum_metrics = collections.defaultdict(int, zip(headers, [0] * 6)) for path in iter_filenames(paths, exclude, ignore): with open(path) as fobj: log(path) try: mod = analyze(fobj.read()) except Exception as e: log_error(e, indent=1) continue for header, value in zip(headers, mod): log('{0}: {1}', header, value, indent=1) sum_metrics[header] = sum_metrics[header] + value if not mod.loc: continue log('- Comment Stats', indent=1) comments = mod.comments log('(C % L): {0:.0%}', comments / (float(mod.loc) or 1), indent=2) log('(C % S): {0:.0%}', comments / (float(mod.sloc) or 1), indent=2) log('(C + M % L): {0:.0%}', (comments + mod.multi) / float(mod.loc), indent=2) if summary: log('** Total **') for header in sum_metrics: log('{0}: {1}', header, sum_metrics[header], indent=1)
def testIterFilenames(self): tmpdir = tempfile.mkdtemp() try: os.makedirs(os.path.join(tmpdir, 'd1')) f1 = os.path.join(tmpdir, 'd1', 't1.py') open(f1, 'w').close() f2 = os.path.join(tmpdir, 'd1', 't2.py') open(f2, 'w').close() os.makedirs(os.path.join(tmpdir, 'd2')) f3 = os.path.join(tmpdir, 'd2', 't3.py') open(f3, 'w').close() f4 = os.path.join(tmpdir, 'd2', 't4.py') open(f4, 'w').close() dir1 = [os.path.join(tmpdir, 'd1')] dir12 = [os.path.join(tmpdir, 'd1'), os.path.join(tmpdir, 'd2')] dirall = [tmpdir] # Test without excludes exclude = '' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1, f2, f3, f4])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1, f2, f3, f4])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1, f2])) # Test with one exclude exclude = '*/t2.py' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1, f3, f4])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1, f3, f4])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1])) # Test with two excludes exclude = '*/t2.py,*/d2/*' names = iter_filenames(dirall, exclude) self.assertEqual(set(names), set([f1])) names = iter_filenames(dir12, exclude) self.assertEqual(set(names), set([f1])) names = iter_filenames(dir1, exclude) self.assertEqual(set(names), set([f1])) finally: shutil.rmtree(tmpdir)
def analyze_raw(paths, exclude, ignore): '''Analyze the files located under `paths`. :param paths: A list of paths to analyze. :param exclude: A comma-separated string of fnmatch patterns. :param ignore: A comma-separated string of patterns to ignore.''' for name in iter_filenames(paths, exclude, ignore): with open(name) as fobj: try: yield name, analyze(fobj.read()) except Exception as e: log(name) log_error(e, indent=1) continue
def analyze_cc(paths, exclude, min, max, order_function): '''Analyze the files located under `paths`. :param paths: A list of paths to analyze. :param exclude: A comma-separated string of fnmatch patterns. :param min: The minimum rank to output. :param max: The maximum rank to output. :param order_function: Can be `SCORE`, `LINES` or `ALPHA`, to sort the results respectively by CC score, line number or name.''' for name in iter_filenames(paths, exclude): with open(name) as fobj: try: results = sorted_results(cc_visit(fobj.read()), order_function) yield name, list(_filter_by_rank(results, min, max)) except Exception as e: log(name, indent=1) log_error(e, indent=1) continue
def analyze_cc(paths, exclude, ignore, order_function, no_assert): """Analyze the files located under `paths`. :param paths: A list of paths to analyze. :param exclude: A comma-separated string of fnmatch patterns. :param ignore: A comma-separated string of patterns to ignore. :param min: The minimum rank to output. :param max: The maximum rank to output. :param order_function: Can be `SCORE`, `LINES` or `ALPHA`, to sort the results respectively by CC score, line number or name. :param no_assert: If `True` assert statements will not be counted.""" for name in iter_filenames(paths, exclude, ignore): with open(name) as fobj: try: results = sorted_results(cc_visit(fobj.read(), no_assert=no_assert), order_function) yield name, results except Exception as e: log(name) log_error(e, indent=1) continue
def analyze_cc(paths, exclude, ignore, order_function, no_assert): '''Analyze the files located under `paths`. :param paths: A list of paths to analyze. :param exclude: A comma-separated string of fnmatch patterns. :param ignore: A comma-separated string of patterns to ignore. :param min: The minimum rank to output. :param max: The maximum rank to output. :param order_function: Can be `SCORE`, `LINES` or `ALPHA`, to sort the results respectively by CC score, line number or name. :param no_assert: If `True` assert statements will not be counted.''' for name in iter_filenames(paths, exclude, ignore): with open(name) as fobj: try: results = sorted_results( cc_visit(fobj.read(), no_assert=no_assert), order_function) yield name, results except Exception as e: log(name) log_error(e, indent=1) continue
def _iter_filenames(self): '''A wrapper around :func:`~radon.cli.tools.iter_filenames`.''' return iter_filenames(self.paths, self.config.exclude, self.config.ignore)
def merge_files_in_folders(folders=[]): # VERY IMPORTANT - iter_filenames folders must be an ARRAY of string, not single string filenames = [] for filename in iter_filenames(folders, [], []): filenames.append(filename) return merge_files(filenames)
def merge_files_in_folders(folders = []): # VERY IMPORTANT - iter_filenames folders must be an ARRAY of string, not single string filenames = [] for filename in iter_filenames(folders,[],[]): filenames.append(filename) return merge_files(filenames)