Coding style.

- Update asyncio code to latest style using asyncio.run().
This commit is contained in:
Andrew Hamilton 2021-12-08 15:43:34 +10:00
parent 2bb586c862
commit 0679cb14b5
4 changed files with 46 additions and 65 deletions

View file

@ -645,10 +645,9 @@ class Listing:
class Screen:
def __init__(self, summary, log, main_loop):
def __init__(self, summary, log):
self._summary = summary
self._log = log
self._main_loop = main_loop
self._is_summary_focused = True
self.workers = None
self._is_listing_portrait = True
@ -660,7 +659,6 @@ class Screen:
def __getstate__(self):
state = self.__dict__.copy()
state["_main_loop"] = None
state["workers"] = None
return state
@ -798,7 +796,7 @@ class Screen:
self._summary.sort_entries()
def quit_(self):
os.kill(os.getpid(), signal.SIGINT)
fill3.SHUTDOWN_EVENT.set()
def refresh(self):
selection = self._summary.get_selection()
@ -977,7 +975,7 @@ def setup_inotify(root_path, loop, on_filesystem_event, exclude_filter):
return pyinotify.AsyncioNotifier(watch_manager, loop, callback=lambda notifier: None)
def load_state(pickle_path, jobs_added_event, root_path, loop):
def load_state(pickle_path, jobs_added_event, root_path):
is_first_run = True
try:
with gzip.open(pickle_path, "rb") as file_:
@ -985,10 +983,9 @@ def load_state(pickle_path, jobs_added_event, root_path, loop):
except (FileNotFoundError, AttributeError):
summary = Summary(root_path, jobs_added_event)
log = Log()
screen = Screen(summary, log, loop)
screen = Screen(summary, log)
else:
is_first_run = False
screen._main_loop = loop
summary = screen._summary
summary._jobs_added_event = jobs_added_event
summary._root_path = root_path
@ -1017,8 +1014,9 @@ def on_filesystem_event(event, summary, root_path):
fill3.APPEARANCE_CHANGED_EVENT.set()
def main(root_path, loop, worker_count=None, editor_command=None, theme=None,
compression=None, is_being_tested=False):
async def main(root_path, worker_count=None, editor_command=None, theme=None, compression=None,
is_being_tested=False):
loop = asyncio.get_running_loop()
if worker_count is None:
worker_count = max(multiprocessing.cpu_count() - 1, 1)
if theme is None:
@ -1028,8 +1026,9 @@ def main(root_path, loop, worker_count=None, editor_command=None, theme=None,
os.environ["PYGMENT_STYLE"] = theme
pickle_path = os.path.join(tools.CACHE_PATH, "summary.pickle")
jobs_added_event = asyncio.Event()
summary, screen, log, is_first_run = load_state(pickle_path, jobs_added_event, root_path, loop)
summary, screen, log, is_first_run = load_state(pickle_path, jobs_added_event, root_path)
screen.editor_command = editor_command
fill3.APPEARANCE_CHANGED_EVENT = asyncio.Event()
log.log_message("Program started.")
jobs_added_event.set()
@ -1039,25 +1038,20 @@ def main(root_path, loop, worker_count=None, editor_command=None, theme=None,
try:
log.log_message(f"Starting workers ({worker_count}) …")
screen.make_workers(worker_count, is_being_tested, compression)
def exit_loop():
log.log_command("Exiting…")
time.sleep(0.05)
screen.stop_workers()
loop.stop()
loop.create_task(summary.sync_with_filesystem(log))
for worker_ in screen.workers:
loop.create_task(worker_.future)
if sys.stdout.isatty():
with fill3.context(loop, screen, exit_loop=exit_loop):
loop.run_forever()
log.log_message("Program stopped.")
else:
try:
loop.run_forever()
except KeyboardInterrupt:
screen.stop_workers()
loop.stop()
try:
if sys.stdout.isatty() or is_being_tested:
await fill3.tui(screen)
log.log_message("Program stopped.")
else:
shutdown_event = asyncio.Event()
with (fill3.signal_handler(loop, signal.SIGINT, shutdown_event.set),
fill3.signal_handler(loop, signal.SIGTERM, shutdown_event.set)):
await shutdown_event.wait()
finally:
screen.stop_workers()
finally:
notifier.stop()
if summary.is_loaded:
@ -1163,9 +1157,8 @@ def entry_point():
manage_cache(root_path)
with terminal.terminal_title("eris: " + os.path.basename(root_path)):
with chdir(root_path): # FIX: Don't change directory if possible.
loop = asyncio.get_event_loop()
try:
main(root_path, loop, worker_count, editor_command, theme, compression)
asyncio.run(main(root_path, worker_count, editor_command, theme, compression))
except pyinotify.WatchManagerError:
inotify_watches_exceeded()

View file

@ -68,7 +68,7 @@ class Worker:
log.log_message(Worker.AUTOSAVE_MESSAGE)
screen.save()
if self.is_being_tested:
os.kill(os.getpid(), signal.SIGINT)
fill3.SHUTDOWN_EVENT.set()
jobs_added_event.clear()
def kill(self):

View file

@ -33,12 +33,6 @@ def _assert_widget_appearance(widget, golden_path, dimensions=_DIMENSIONS):
golden.assertGolden(_widget_to_string(widget, dimensions), golden_path_absolute)
class _MockMainLoop:
def add_reader(self, foo, bar):
pass
class ScreenWidgetTestCase(unittest.TestCase):
def setUp(self):
@ -50,7 +44,7 @@ class ScreenWidgetTestCase(unittest.TestCase):
jobs_added_event = asyncio.Event()
summary = __main__.Summary(project_dir, jobs_added_event)
log = __main__.Log()
self.main_widget = __main__.Screen(summary, log, _MockMainLoop())
self.main_widget = __main__.Screen(summary, log)
def tearDown(self):
shutil.rmtree(self.temp_dir)
@ -111,6 +105,7 @@ class SummaryCursorTest(unittest.TestCase):
class SummarySyncWithFilesystemTestCase(unittest.TestCase):
def setUp(self):
fill3.APPEARANCE_CHANGED_EVENT = asyncio.Event()
self.temp_dir = tempfile.mkdtemp()
self.foo_path = os.path.join(self.temp_dir, "foo")
self.bar_path = os.path.join(self.temp_dir, "bar.md")
@ -198,31 +193,31 @@ def _tmp_total():
class MainTestCase(unittest.TestCase):
def test_main_and_restart_and_no_leaks_and_is_relocatable(self):
def test_run(root_path, loop):
def test_run(root_path):
mount_total = _mount_total()
tmp_total = _tmp_total()
foo_path = os.path.join(root_path, "foo")
open(foo_path, "w").close()
__main__.manage_cache(root_path)
with __main__.chdir(root_path):
loop = asyncio.get_event_loop()
with contextlib.redirect_stdout(io.StringIO()):
__main__.main(root_path, loop, worker_count=2, is_being_tested=True)
loop.run_until_complete(__main__.main(
root_path, worker_count=2, is_being_tested=True))
for file_name in ["summary.pickle", "creation_time",
"foo-metadata", "foo-contents"]:
self.assertTrue(os.path.exists(".eris/" + file_name))
self.assertEqual(_mount_total(), mount_total)
self.assertEqual(_tmp_total(), tmp_total)
temp_dir = tempfile.mkdtemp()
try:
loop = asyncio.get_event_loop()
first_dir = os.path.join(temp_dir, "first")
os.mkdir(first_dir)
test_run(first_dir, loop)
test_run(first_dir)
second_dir = os.path.join(temp_dir, "second")
os.rename(first_dir, second_dir)
test_run(second_dir, loop)
loop.close()
loop.stop()
test_run(second_dir)
finally:
shutil.rmtree(temp_dir)

View file

@ -406,7 +406,6 @@ class Fixed:
##########################
APPEARANCE_CHANGED_EVENT = asyncio.Event()
_LAST_APPEARANCE = []
@ -429,10 +428,10 @@ def patch_screen(widget):
async def update_screen(screen_widget):
while True:
patch_screen(screen_widget)
await asyncio.sleep(0.01) # Limit the update rate
await APPEARANCE_CHANGED_EVENT.wait()
APPEARANCE_CHANGED_EVENT.clear()
patch_screen(screen_widget)
await asyncio.sleep(0.01)
def on_terminal_input(screen_widget):
@ -453,21 +452,21 @@ def signal_handler(loop, signal_, func):
loop.remove_signal_handler(signal_)
@contextlib.contextmanager
def context(loop, screen_widget, exit_loop=None):
APPEARANCE_CHANGED_EVENT.set()
if exit_loop is None:
exit_loop = loop.stop
async def tui(screen_widget):
global APPEARANCE_CHANGED_EVENT
global SHUTDOWN_EVENT
APPEARANCE_CHANGED_EVENT = asyncio.Event()
SHUTDOWN_EVENT = asyncio.Event()
loop = asyncio.get_running_loop()
with (signal_handler(loop, signal.SIGWINCH, lambda: draw_screen(screen_widget)),
signal_handler(loop, signal.SIGINT, exit_loop),
signal_handler(loop, signal.SIGTERM, exit_loop), terminal.alternate_buffer(),
terminal.interactive(), terminal.mouse_tracking()):
update_task = loop.create_task(
update_screen(screen_widget))
signal_handler(loop, signal.SIGINT, SHUTDOWN_EVENT.set),
signal_handler(loop, signal.SIGTERM, SHUTDOWN_EVENT.set),
terminal.alternate_buffer(), terminal.interactive(), terminal.mouse_tracking()):
update_task = asyncio.create_task(update_screen(screen_widget))
try:
loop.add_reader(sys.stdin, on_terminal_input, screen_widget)
try:
yield
await SHUTDOWN_EVENT.wait()
finally:
loop.remove_reader(sys.stdin)
finally:
@ -487,7 +486,7 @@ class _Screen:
def on_keyboard_input(self, term_code):
if term_code in ["q", terminal.ESC]:
asyncio.get_event_loop().stop()
SHUTDOWN_EVENT.set()
else:
self.content = Filler(Text(repr(term_code)))
APPEARANCE_CHANGED_EVENT.set()
@ -498,11 +497,5 @@ class _Screen:
APPEARANCE_CHANGED_EVENT.set()
def _main():
loop = asyncio.get_event_loop()
with context(loop, _Screen()):
loop.run_forever()
if __name__ == "__main__":
_main()
asyncio.run(tui(_Screen()))