diff --git a/eris/gut.py b/eris/gut.py deleted file mode 100755 index 4d973f7..0000000 --- a/eris/gut.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3.8 - - -"""Gut shows a python file with the bodies of functions and methods removed. - -This can be useful when initially reading a codebase. -""" - -import ast -import sys - - -USAGE = """Usage: gut.py - -# gut.py test.py""" - - -def _function_body_lines(module_contents): - ranges = [] - class FuncNodeVisitor(ast.NodeVisitor): - - def _line_range(self, body): - return body[0].lineno - 1, body[-1].end_lineno - - def visit_FunctionDef(self, node): - ranges.append(self._line_range(node.body)) - - def visit_AsyncFunctionDef(self, node): - ranges.append(self._line_range(node.body)) - visitor = FuncNodeVisitor() - tree = ast.parse(module_contents) - visitor.visit(tree) - return ranges - - -def gut_module(module_contents): - ranges = _function_body_lines(module_contents) - lines = module_contents.splitlines(keepends=True) - deleted = 0 - for start_line, end_line in ranges: - del lines[start_line-deleted:end_line-deleted] - deleted += (end_line - start_line) - return "".join(lines) - - -def main(module_path): - with open(module_path) as module_file: - print(gut_module(module_file.read())) - - -if __name__ == "__main__": - if len(sys.argv) != 2: - print(USAGE) - sys.exit(-1) - main(sys.argv[1]) diff --git a/eris/tools.py b/eris/tools.py index 272e0fc..498d5ee 100755 --- a/eris/tools.py +++ b/eris/tools.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- +import ast import contextlib import enum import functools @@ -29,7 +30,6 @@ import toml import eris import eris.fill3 as fill3 -import eris.gut as gut import eris.lscolors as lscolors import eris.termstr as termstr @@ -335,10 +335,38 @@ def python_coverage(path): return status, _colorize_coverage_report(lines) +def _function_body_lines(module_contents): + ranges = [] + class FuncNodeVisitor(ast.NodeVisitor): + + def _line_range(self, body): + return body[0].lineno - 1, body[-1].end_lineno + + def visit_FunctionDef(self, node): + ranges.append(self._line_range(node.body)) + + def visit_AsyncFunctionDef(self, node): + ranges.append(self._line_range(node.body)) + visitor = FuncNodeVisitor() + tree = ast.parse(module_contents) + visitor.visit(tree) + return ranges + + +def _gut_module(module_contents): + ranges = _function_body_lines(module_contents) + lines = module_contents.splitlines(keepends=True) + deleted = 0 + for start_line, end_line in ranges: + del lines[start_line-deleted:end_line-deleted] + deleted += (end_line - start_line) + return "".join(lines) + + @deps(url="https://github.com/ahamilton/eris") def python_gut(path): with open(path) as module_file: - output = gut.gut_module(module_file.read()) + output = _gut_module(module_file.read()) source_widget = _syntax_highlight_using_path(_fix_input(output), path) return Status.normal, source_widget diff --git a/tests/gut_test.py b/tests/gut_test.py deleted file mode 100755 index b103992..0000000 --- a/tests/gut_test.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python3.8 - - -import textwrap -import unittest - -import eris.gut as gut - - -class GutTestCase(unittest.TestCase): - - def test_import(self): - program = "import hello" - self.assertEqual(gut.gut_module(program), program) - - def test_import_and_function(self): - program = textwrap.dedent(""" - import hello - - def first(): - a = 1 - """) - expected = textwrap.dedent(""" - import hello - - def first(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_import_and_function_and_command(self): - program = textwrap.dedent(""" - import hello - - def first(): - a = 1 - - b = 1 - """) - expected = textwrap.dedent(""" - import hello - - def first(): - - b = 1 - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_import_and_class(self): - program = textwrap.dedent(""" - import hello - - class Foo: - - def bar(): - a = 1 - """) - expected = textwrap.dedent(""" - import hello - - class Foo: - - def bar(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_short_blank_line_in_def(self): - program = textwrap.dedent(""" - def bar(): - a = 1 - - b = 2 - """) - expected = textwrap.dedent(""" - def bar(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_nested_functions(self): - program = textwrap.dedent(""" - def bar(): - a = 1 - def foo(): - pass - b = 2 - """) - expected = textwrap.dedent(""" - def bar(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_multiline_signature(self): - program = textwrap.dedent(""" - def bar(a, b, - c, d): - a = 1 - """) - expected = textwrap.dedent(""" - def bar(a, b, - c, d): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_comment_in_signature_line(self): - program = textwrap.dedent(""" - def bar(): # comment - pass - """) - expected = textwrap.dedent(""" - def bar(): # comment - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_indented_comment_in_body(self): - program = textwrap.dedent(""" - def bar(): - pass - # comment - pass - """) - expected = textwrap.dedent(""" - def bar(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_non_indented_comment_in_body(self): - program = textwrap.dedent(""" - def bar(): - pass - # comment - pass - """) - expected = textwrap.dedent(""" - def bar(): - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_non_indented_comment_after_body(self): - program = textwrap.dedent(""" - def bar(): - pass - pass - - # comment - pass - """) - expected = textwrap.dedent(""" - def bar(): - - # comment - pass - """) - self.assertEqual(gut.gut_module(program), expected) - - def test_commented_out_function(self): - program = textwrap.dedent(""" - # def bar(): - # pass - """) - self.assertEqual(gut.gut_module(program), program) - - -if __name__ == "__main__": - unittest.main()