From 03eade469855783d4d872038c7f26a127818b70f Mon Sep 17 00:00:00 2001 From: Evan Hubinger Date: Thu, 6 Jun 2024 01:57:21 -0700 Subject: [PATCH] Improve watching --- coconut/command/watch.py | 20 ++++++++++++++++++-- coconut/compiler/compiler.py | 2 +- coconut/compiler/util.py | 6 +++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/coconut/command/watch.py b/coconut/command/watch.py index a0852a0e..f70a15b5 100644 --- a/coconut/command/watch.py +++ b/coconut/command/watch.py @@ -21,6 +21,8 @@ import sys +from functools import partial + from coconut.terminal import logger from coconut.exceptions import CoconutException @@ -48,13 +50,27 @@ def __init__(self, recompile, *args, **kwargs): self.args = args self.kwargs = kwargs self.saw = set() + self.saw_twice = set() def on_modified(self, event): """Handle a file modified event.""" - path = event.src_path + self.handle(event.src_path) + + def handle(self, path): + """Handle a potential recompilation event for the given path.""" if path in self.saw: logger.log("Skipping watch event for: " + repr(path) + "\n\t(currently compiling: " + repr(self.saw) + ")") + self.saw_twice.add(path) else: logger.log("Handling watch event for: " + repr(path) + "\n\t(currently compiling: " + repr(self.saw) + ")") self.saw.add(path) - self.recompile(path, callback=lambda: self.saw.discard(path), *self.args, **self.kwargs) + self.saw_twice.discard(path) + self.recompile(path, callback=partial(self.callback, path), *self.args, **self.kwargs) + + def callback(self, path): + """Callback for after recompiling the given path.""" + self.saw.discard(path) + if path in self.saw_twice: + logger.log("Submitting deferred watch event for: " + repr(path) + "\n\t(currently deferred: " + repr(self.saw_twice) + ")") + self.saw_twice.discard(path) + self.handle(path) diff --git a/coconut/compiler/compiler.py b/coconut/compiler/compiler.py index 5a921e57..458d6c28 100644 --- a/coconut/compiler/compiler.py +++ b/coconut/compiler/compiler.py @@ -5209,7 +5209,7 @@ def warm_up(self, streamline=False, enable_incremental_mode=False, set_debug_nam self.streamline(self.file_parser, force=streamline) self.streamline(self.eval_parser, force=streamline) if enable_incremental_mode: - enable_incremental_parsing() + enable_incremental_parsing(reason="explicit warm_up call") # end: ENDPOINTS diff --git a/coconut/compiler/util.py b/coconut/compiler/util.py index ddf18d73..bd434b36 100644 --- a/coconut/compiler/util.py +++ b/coconut/compiler/util.py @@ -1035,7 +1035,7 @@ def get_highest_parse_loc(original): return highest_loc -def enable_incremental_parsing(): +def enable_incremental_parsing(reason="explicit enable_incremental_parsing call"): """Enable incremental parsing mode where prefix/suffix parses are reused.""" if not SUPPORTS_INCREMENTAL: return False @@ -1051,7 +1051,7 @@ def enable_incremental_parsing(): ) except ImportError as err: raise CoconutException(str(err)) - logger.log("Incremental parsing mode enabled.") + logger.log("Incremental parsing mode enabled due to {reason}.".format(reason=reason)) return True @@ -1199,7 +1199,7 @@ def load_cache_for(inputstring, codepath): incremental_enabled = True incremental_info = "using incremental parsing mode since it was already enabled" elif len(inputstring) < disable_incremental_for_len: - incremental_enabled = enable_incremental_parsing() + incremental_enabled = enable_incremental_parsing(reason="input length") if incremental_enabled: incremental_info = "incremental parsing mode enabled due to len == {input_len} < {max_len}".format( input_len=len(inputstring),