Skip to content

Commit

Permalink
Improve watching
Browse files Browse the repository at this point in the history
  • Loading branch information
evhub committed May 24, 2024
1 parent 0196d71 commit 570c918
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 28 deletions.
63 changes: 41 additions & 22 deletions coconut/command/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ def compile_file(self, filepath, write=True, package=False, force=False, **kwarg
self.compile(filepath, destpath, package, force=force, **kwargs)
return destpath

def compile(self, codepath, destpath=None, package=False, run=False, force=False, show_unchanged=True):
def compile(self, codepath, destpath=None, package=False, run=False, force=False, show_unchanged=True, callback=None):
"""Compile a source Coconut file to a destination Python file."""
with univ_open(codepath, "r") as opened:
code = readfile(opened)
Expand All @@ -603,29 +603,39 @@ def compile(self, codepath, destpath=None, package=False, run=False, force=False
else:
logger.show_tabulated("Compiling", showpath(codepath), "...")

def callback(compiled):
if destpath is None:
logger.show_tabulated("Compiled", showpath(codepath), "without writing to file.")
else:
with univ_open(destpath, "w") as opened:
writefile(opened, compiled)
logger.show_tabulated("Compiled to", showpath(destpath), ".")
if self.display:
logger.print(compiled)
if run:
def inner_callback(compiled):
try:
if destpath is None:
self.execute(compiled, path=codepath, allow_show=False)
logger.show_tabulated("Compiled", showpath(codepath), "without writing to file.")
else:
self.execute_file(destpath, argv_source_path=codepath)
with univ_open(destpath, "w") as opened:
writefile(opened, compiled)
logger.show_tabulated("Compiled to", showpath(destpath), ".")
if self.display:
logger.print(compiled)
if run:
if destpath is None:
self.execute(compiled, path=codepath, allow_show=False)
else:
self.execute_file(destpath, argv_source_path=codepath)
except BaseException as err:
if callback is not None:
callback(False, err)
raise
else:
if callback is not None:
callback(True, destpath)

parse_kwargs = dict(
codepath=codepath,
use_cache=self.use_cache,
)
if callback is not None:
parse_kwargs["error_callback"] = lambda err: callback(False, err)
if package is True:
self.submit_comp_job(codepath, callback, "parse_package", code, package_level=package_level, **parse_kwargs)
self.submit_comp_job(codepath, inner_callback, "parse_package", code, package_level=package_level, **parse_kwargs)
elif package is False:
self.submit_comp_job(codepath, callback, "parse_file", code, **parse_kwargs)
self.submit_comp_job(codepath, inner_callback, "parse_file", code, **parse_kwargs)
else:
raise CoconutInternalException("invalid value for package", package)

Expand Down Expand Up @@ -669,6 +679,7 @@ def create_package(self, dirpath, retries_left=create_package_retries):

def submit_comp_job(self, path, callback, method, *args, **kwargs):
"""Submits a job on self.comp to be run in parallel."""
error_callback = kwargs.pop("error_callback", None)
if self.executor is None:
with self.handling_exceptions():
callback(getattr(self.comp, method)(*args, **kwargs))
Expand All @@ -681,8 +692,14 @@ def callback_wrapper(completed_future):
"""Ensures that all errors are always caught, since errors raised in a callback won't be propagated."""
with logger.in_path(path): # handle errors in the path context
with self.handling_exceptions():
result = completed_future.result()
callback(result)
try:
result = completed_future.result()
except BaseException as err:
if error_callback is not None:
error_callback(err)
raise
else:
callback(result)
future.add_done_callback(callback_wrapper)

def register_exit_code(self, code=1, errmsg=None, err=None):
Expand Down Expand Up @@ -1138,7 +1155,11 @@ def watch(self, all_compile_path_kwargs):
def interrupt():
interrupted[0] = True

def recompile(path, **kwargs):
def recompile(path, callback, **kwargs):
def inner_callback(ok, path):
if ok:
self.run_mypy(path)
callback()
path = fixpath(path)
src = kwargs.pop("source")
dest = kwargs.pop("dest")
Expand All @@ -1150,14 +1171,14 @@ def recompile(path, **kwargs):
# correct the compilation path based on the relative position of path to src
dirpath = os.path.dirname(path)
writedir = os.path.join(dest, os.path.relpath(dirpath, src))
filepaths = self.compile_path(
self.compile_path(
path,
writedir,
show_unchanged=False,
handling_exceptions_kwargs=dict(on_keyboard_interrupt=interrupt),
callback=inner_callback,
**kwargs # no comma for py2
)
self.run_mypy(filepaths)

observer = Observer()
watchers = []
Expand All @@ -1171,8 +1192,6 @@ def recompile(path, **kwargs):
try:
while not interrupted[0]:
time.sleep(watch_interval)
for wcher in watchers:
wcher.keep_watching()
except KeyboardInterrupt:
interrupt()
finally:
Expand Down
6 changes: 1 addition & 5 deletions coconut/command/watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,11 @@ def __init__(self, recompile, *args, **kwargs):
self.recompile = recompile
self.args = args
self.kwargs = kwargs
self.keep_watching()

def keep_watching(self):
"""Allows recompiling previously-compiled files."""
self.saw = set()

def on_modified(self, event):
"""Handle a file modified event."""
path = event.src_path
if path not in self.saw:
self.saw.add(path)
self.recompile(path, *self.args, **self.kwargs)
self.recompile(path, callback=lambda: self.saw.remove(path), *self.args, **self.kwargs)
2 changes: 1 addition & 1 deletion coconut/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def message(self, message, source, point, ln, extra=None, endpoint=None, filenam
message_parts += ["|"]
else:
message_parts += ["/", "~" * (len(lines[0]) - point_ind - 1)]
message_parts += ["~" * (max_line_len - len(lines[0])), "\n"]
message_parts += ["~" * (max_line_len - len(lines[0]) + 1), "\n"]

# add code, highlighting all of it together
code_parts = []
Expand Down

0 comments on commit 570c918

Please sign in to comment.