From d1e538f5f34ab5a645a4f742bf6e4bad05908af3 Mon Sep 17 00:00:00 2001 From: Andrew Hamilton Date: Mon, 22 Nov 2021 19:53:37 +1000 Subject: [PATCH] Coding style. - More import tidying. - Fix line lengths. - Dead code in tests. - lambdas. - Tests pass regardless of term type. --- eris/eris/__main__.py | 37 +++++++----- eris/eris/tools.py | 17 ++++-- eris/eris/webserver.py | 3 +- eris/eris/worker.py | 4 +- eris/tests/__main___test.py | 20 +++---- eris/tests/golden-files/log-original | 60 +++++++++++++++++++ .../golden-files/window-orientation-original | 60 +++++++++++++++++++ eris/tests/paged_list_test.py | 2 +- eris/tests/tools_test.py | 3 +- lscolors/lscolors.py | 1 - termstr/tests/termstr_test.py | 13 ++-- 11 files changed, 177 insertions(+), 43 deletions(-) create mode 100644 eris/tests/golden-files/log-original create mode 100644 eris/tests/golden-files/window-orientation-original diff --git a/eris/eris/__main__.py b/eris/eris/__main__.py index d1c14bf..db7d29f 100755 --- a/eris/eris/__main__.py +++ b/eris/eris/__main__.py @@ -32,17 +32,17 @@ import sys import time import docopt +import fill3 +import fill3.terminal as terminal import pygments.styles import pyinotify +import termstr import eris import eris.tools as tools import eris.worker as worker import eris.paged_list as paged_list -import fill3 -import fill3.terminal as terminal import sorted_collection -import termstr USAGE = """ @@ -316,8 +316,8 @@ class Summary: Entry.MAX_WIDTH = max((len(entry) for entry in self._entries), default=0) if (len(path) - 2) == self._max_path_length: - self._max_path_length = max(((len(entry.path) - 2) - for entry in self._entries), default=0) + self._max_path_length = max( + ((len(entry.path) - 2) for entry in self._entries), default=0) x, y = self._cursor_position if y == len(self._entries): self._cursor_position = x, y - 1 @@ -370,7 +370,8 @@ class Summary: log.log_message("Started sync with filesystem…") start_time = time.time() all_paths = set() - for path in fix_paths(self._root_path, codebase_files(self._root_path)): + for path in fix_paths(self._root_path, + codebase_files(self._root_path)): await asyncio.sleep(0) all_paths.add(path) if path in cache: @@ -387,7 +388,8 @@ class Summary: await asyncio.sleep(0) self.on_file_deleted(path) duration = time.time() - start_time - log.log_message(f"Finished sync with filesystem. {round(duration, 2)} secs") + log.log_message(f"Finished sync with filesystem. " + f"{round(duration, 2)} secs") def _sweep_up(self, x, y): yield from reversed(self._entries[y][:x]) @@ -641,11 +643,12 @@ class Help: self.view = fill3.View.from_widget(fill3.Text(help_text)) self.widget = fill3.Border(self.view, title="Help") portal = self.view.portal - self.key_map = {"h": self._exit_help, terminal.UP_KEY: portal.scroll_up, - terminal.DOWN_KEY: portal.scroll_down, - terminal.LEFT_KEY: portal.scroll_left, - terminal.RIGHT_KEY: portal.scroll_right, - "q": self._exit_help, terminal.ESC: self._exit_help} + self.key_map = { + "h": self._exit_help, terminal.UP_KEY: portal.scroll_up, + terminal.DOWN_KEY: portal.scroll_down, + terminal.LEFT_KEY: portal.scroll_left, + terminal.RIGHT_KEY: portal.scroll_right, "q": self._exit_help, + terminal.ESC: self._exit_help} def _exit_help(self): self.screen._is_help_visible = False @@ -1122,8 +1125,10 @@ def main(root_path, loop, worker_count=None, editor_command=None, theme=None, screen.editor_command = editor_command log.log_message("Program started.") jobs_added_event.set() - callback = lambda event: on_filesystem_event(event, summary, root_path, - appearance_changed_event) + + def callback(event): + on_filesystem_event(event, summary, root_path, + appearance_changed_event) notifier = setup_inotify(root_path, loop, callback, is_path_excluded) try: log.log_message(f"Starting workers ({worker_count}) …") @@ -1136,8 +1141,8 @@ def main(root_path, loop, worker_count=None, editor_command=None, theme=None, loop.stop() loop.create_task(summary.sync_with_filesystem( appearance_changed_event, log)) - for worker in screen.workers: - loop.create_task(worker.future) + for worker_ in screen.workers: + loop.create_task(worker_.future) if sys.stdout.isatty(): with fill3.context(loop, appearance_changed_event, screen, exit_loop=exit_loop): diff --git a/eris/eris/tools.py b/eris/eris/tools.py index fe05061..66694c9 100755 --- a/eris/eris/tools.py +++ b/eris/eris/tools.py @@ -69,7 +69,8 @@ STATUS_MEANINGS = [ STATUS_TO_TERMSTR = { status: termstr.TermStr(" ", termstr.CharStyle(bg_color=color)) for status, color in _STATUS_COLORS.items()} -STATUS_TO_TERMSTR[Status.pending] = termstr.TermStr(".").fg_color(termstr.Color.grey_100) +STATUS_TO_TERMSTR[Status.pending] = termstr.TermStr(".").fg_color( + termstr.Color.grey_100) def get_ls_color_codes(): @@ -334,9 +335,12 @@ def python_coverage(path): def _function_body_lines(python_source): 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)) visit_AsyncFunctionDef = visit_FunctionDef @@ -467,7 +471,8 @@ def godoc(path): with tempfile.TemporaryDirectory() as temp_dir: symlink_path = os.path.join(temp_dir, "file.go") os.symlink(os.path.abspath(path), symlink_path) - stdout, stderr, returncode = _do_command(["go", "doc", "."], cwd=temp_dir) + stdout, stderr, returncode = _do_command(["go", "doc", "."], + cwd=temp_dir) os.remove(symlink_path) status = (Status.not_applicable if stdout.strip() == "" or returncode != 0 else Status.ok) @@ -493,6 +498,7 @@ def make_tool_function(dependencies, command, url=None, error_status=None, command_parts = command.split() executables = set([command_parts[0]]) error_status = None if error_status is None else Status[error_status] + @deps(deps=set(dependencies), url=url, executables=executables) def func(path): return _run_command(command_parts + [path], error_status, has_color, @@ -710,8 +716,8 @@ def splitext(path): @functools.lru_cache() def is_tool_available(tool): - if (hasattr(tool, "command") and - tool.command.startswith(f"{PYTHON_EXECUTABLE} -m ")): + if (hasattr(tool, "command") and tool.command.startswith( + f"{PYTHON_EXECUTABLE} -m ")): return importlib.util.find_spec(tool.command.split()[2]) is not None try: return all(shutil.which(executable) for executable in tool.executables) @@ -720,7 +726,8 @@ def is_tool_available(tool): def tools_for_path(path): - git_tools = [git_diff, git_blame, git_log] if os.path.exists(".git") else [] + git_tools = ([git_diff, git_blame, git_log] + if os.path.exists(".git") else []) root, ext = splitext(path) extra_tools = [] if ext == "" else _tools_for_extension().get(ext[1:], []) tools = generic_tools() + git_tools + extra_tools diff --git a/eris/eris/webserver.py b/eris/eris/webserver.py index a0e65dd..3ba7b60 100755 --- a/eris/eris/webserver.py +++ b/eris/eris/webserver.py @@ -99,7 +99,8 @@ def make_summary_page(project_name, summary): return make_page(body_html, "Summary of " + project_name) -def run(server_class=http.server.HTTPServer, handler_class=Webserver, port=8080): +def run(server_class=http.server.HTTPServer, handler_class=Webserver, + port=8080): server_address = ("", port) httpd = server_class(server_address, handler_class) print("Starting httpd…") diff --git a/eris/eris/worker.py b/eris/eris/worker.py index c11018e..a5bd771 100755 --- a/eris/eris/worker.py +++ b/eris/eris/worker.py @@ -37,8 +37,8 @@ class Worker: async def run_tool(self, path, tool): while True: - self.process.stdin.write( - f"{tool.__qualname__}\n{path}\n".encode("utf-8", "surrogatepass")) + self.process.stdin.write(f"{tool.__qualname__}\n{path}\n" + .encode("utf-8", "surrogatepass")) data = await self.process.stdout.readline() if data == b"": await self.create_process() diff --git a/eris/tests/__main___test.py b/eris/tests/__main___test.py index 2cf475c..5f6b70c 100755 --- a/eris/tests/__main___test.py +++ b/eris/tests/__main___test.py @@ -9,14 +9,13 @@ import shutil import tempfile import unittest -os.environ["TERM"] = "xterm-256color" - import fill3 import golden import eris.__main__ as __main__ +os.environ["TERM"] = "xterm-256color" _DIMENSIONS = (100, 60) @@ -68,18 +67,15 @@ class ScreenWidgetTestCase(unittest.TestCase): _assert_widget_appearance(self.main_widget, "golden-files/help") def test_log_appearance(self): - log_shown = _widget_to_string(self.main_widget) + _assert_widget_appearance(self.main_widget, + "golden-files/log-original") self.main_widget.toggle_log() - log_hidden = _widget_to_string(self.main_widget) - actual = "shown:\n%s\nhidden:\n%s" % (log_shown, log_hidden) _assert_widget_appearance(self.main_widget, "golden-files/log") def test_window_orientation(self): - window_left_right = _widget_to_string(self.main_widget) + _assert_widget_appearance(self.main_widget, + "golden-files/window-orientation-original") self.main_widget.toggle_window_orientation() - window_top_bottom = _widget_to_string(self.main_widget) - actual = ("left-right:\n%s\ntop-bottom:\n%s" % - (window_left_right, window_top_bottom)) _assert_widget_appearance(self.main_widget, "golden-files/window-orientation") @@ -130,8 +126,10 @@ class SummarySyncWithFilesystemTestCase(unittest.TestCase): self.appearance_changed_event = asyncio.Event() self.summary = __main__.Summary(self.temp_dir, self.jobs_added_event) self.loop = asyncio.new_event_loop() - callback = lambda event: __main__.on_filesystem_event( - event, self.summary, self.temp_dir, self.appearance_changed_event) + + def callback(event): + __main__.on_filesystem_event(event, self.summary, self.temp_dir, + self.appearance_changed_event) __main__.setup_inotify(self.temp_dir, self.loop, callback, __main__.is_path_excluded) _touch(self.foo_path) diff --git a/eris/tests/golden-files/log-original b/eris/tests/golden-files/log-original new file mode 100644 index 0000000..6695766 --- /dev/null +++ b/eris/tests/golden-files/log-original @@ -0,0 +1,60 @@ +┏━━━━━━━━ Summary of project ━━━━━━━━┓┌────────────────────────────────────────────────────────────┐ +┃ ┃│Nothing selected │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛│ │ +┌─────────────── Log ────────────────┐│ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└────────────────────────────────────┘└────────────────────────────────────────────────────────────┘ + help quit tab:focus turn log edit next sort refresh fullscreen open  \ No newline at end of file diff --git a/eris/tests/golden-files/window-orientation-original b/eris/tests/golden-files/window-orientation-original new file mode 100644 index 0000000..6695766 --- /dev/null +++ b/eris/tests/golden-files/window-orientation-original @@ -0,0 +1,60 @@ +┏━━━━━━━━ Summary of project ━━━━━━━━┓┌────────────────────────────────────────────────────────────┐ +┃ ┃│Nothing selected │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┃ ┃│ │ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛│ │ +┌─────────────── Log ────────────────┐│ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +└────────────────────────────────────┘└────────────────────────────────────────────────────────────┘ + help quit tab:focus turn log edit next sort refresh fullscreen open  \ No newline at end of file diff --git a/eris/tests/paged_list_test.py b/eris/tests/paged_list_test.py index 179bbe9..64c3625 100755 --- a/eris/tests/paged_list_test.py +++ b/eris/tests/paged_list_test.py @@ -11,7 +11,7 @@ import eris.paged_list as paged_list class PagedListTestCase(unittest.TestCase): def test_batch(self): - self.assertEqual(list(paged_list.batch(iter([3,4,5,6,7]), 2)), + self.assertEqual(list(paged_list.batch(iter([3, 4, 5, 6, 7]), 2)), [[3, 4], [5, 6], [7]]) def test_getitem(self): diff --git a/eris/tests/tools_test.py b/eris/tests/tools_test.py index bc0dda2..7260644 100755 --- a/eris/tests/tools_test.py +++ b/eris/tests/tools_test.py @@ -7,14 +7,13 @@ import shutil import unittest import unittest.mock -os.environ["TERM"] = "xterm-256color" - import fill3 import golden import eris.tools as tools +os.environ["TERM"] = "xterm-256color" os.environ["TZ"] = "GMT" ERIS_ROOT = os.path.dirname(__file__) diff --git a/lscolors/lscolors.py b/lscolors/lscolors.py index 4c73d9e..9d70344 100644 --- a/lscolors/lscolors.py +++ b/lscolors/lscolors.py @@ -1,6 +1,5 @@ - """Give coloring for file types as in the ls command.""" diff --git a/termstr/tests/termstr_test.py b/termstr/tests/termstr_test.py index 6bfa00d..d1790cb 100755 --- a/termstr/tests/termstr_test.py +++ b/termstr/tests/termstr_test.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3.9 +import os import pickle import unittest @@ -8,6 +9,7 @@ import unittest import termstr +os.environ["TERM"] = "xterm-256color" ESC = "\x1b" @@ -105,14 +107,16 @@ class TermStrTests(unittest.TestCase): self.assertEqual(termstr.TermStr("FOO").lower(), foo) self.assertEqual(termstr.TermStr("FOO", bold_style).lower(), foo_bold) self.assertEqual(termstr.TermStr("FOO").swapcase(), foo) - self.assertEqual(termstr.TermStr("FOO", bold_style).swapcase(), foo_bold) + self.assertEqual(termstr.TermStr("FOO", bold_style).swapcase(), + foo_bold) phrase = termstr.TermStr("foo bar") self.assertEqual(phrase.title(), termstr.TermStr("Foo Bar")) self.assertEqual(phrase.capitalize(), termstr.TermStr("Foo bar")) self.assertEqual(foo.upper(), termstr.TermStr("FOO")) self.assertEqual(foo_bold.center(0), foo_bold) self.assertEqual(foo_bold.center(7), - termstr.TermStr(" ") + foo_bold + termstr.TermStr(" ")) + termstr.TermStr(" ") + foo_bold + + termstr.TermStr(" ")) self.assertEqual(foo_bold.ljust(0), foo_bold) self.assertEqual(foo_bold.ljust(5), foo_bold + termstr.TermStr(" ")) self.assertEqual(foo_bold.rjust(0), foo_bold) @@ -125,14 +129,15 @@ class TermStrTests(unittest.TestCase): def test_from_term(self): def test_round_trip(term_str): - self.assertEqual(termstr.TermStr.from_term(str(term_str)), term_str) + self.assertEqual(termstr.TermStr.from_term(str(term_str)), + term_str) test_round_trip(termstr.TermStr("foo")) test_round_trip(termstr.TermStr("foo").bold()) test_round_trip(termstr.TermStr("foo").underline()) test_round_trip(termstr.TermStr("foo").italic()) test_round_trip(termstr.TermStr("foo").fg_color(termstr.Color.red)) - test_round_trip(termstr.TermStr("foo").fg_color(termstr.Color.red).\ + test_round_trip(termstr.TermStr("foo").fg_color(termstr.Color.red). bg_color(termstr.Color.green)) test_round_trip(termstr.TermStr("foo").fg_color(1)) test_round_trip(termstr.TermStr("foo").bg_color(10))