def compile(self, codepath, destpath=None, package=False, run=False, force=False, show_unchanged=True): """Compile a source Coconut file to a destination Python file.""" with openfile(codepath, "r") as opened: code = readfile(opened) if destpath is not None: destdir = os.path.dirname(destpath) if not os.path.exists(destdir): os.makedirs(destdir) if package is True: self.create_package(destdir) foundhash = None if force else self.has_hash_of( destpath, code, package) if foundhash: if show_unchanged: logger.show_tabulated("Left unchanged", showpath(destpath), "(pass --force to override).") if self.show: print(foundhash) if run: self.execute_file(destpath) else: logger.show_tabulated("Compiling", showpath(codepath), "...") if package is True: compile_method = "parse_package" elif package is False: compile_method = "parse_file" else: raise CoconutInternalException("invalid value for package", package) def callback(compiled): if destpath is None: logger.show_tabulated("Compiled", showpath(codepath), "without writing to file.") else: with openfile(destpath, "w") as opened: writefile(opened, compiled) logger.show_tabulated("Compiled to", showpath(destpath), ".") if self.show: print(compiled) if run: if destpath is None: self.execute(compiled, path=codepath, allow_show=False) else: self.execute_file(destpath) self.submit_comp_job(codepath, callback, compile_method, code)
def callback(compiled): if destpath is None: logger.show_tabulated("Finished", showpath(codepath), "without writing to file.") else: with openfile(destpath, "w") as opened: writefile(opened, compiled) logger.show_tabulated("Compiled to", showpath(destpath), ".") if self.show: print(compiled) if run: if destpath is None: self.execute(compiled, path=codepath, allow_show=False) else: self.execute_file(destpath)
def callback(compiled): if destpath is None: logger.show_tabulated("Compiled", showpath(codepath), "without writing to file.") else: with openfile(destpath, "w") as opened: writefile(opened, compiled) logger.show_tabulated("Compiled to", showpath(destpath), ".") if self.show: print(compiled) if run: if destpath is None: self.execute(compiled, path=codepath, allow_show=False) else: self.execute_file(destpath)
def callback(compiled): if destpath is None: logger.show_tabulated("Finished", showpath(codepath), "without writing to file.") else: with openfile(destpath, "w") as opened: writefile(opened, compiled) logger.show_tabulated("Compiled to", showpath(destpath), ".") if run: runpath = destpath if destpath is not None else codepath self.execute(compiled, path=runpath, isolate=True) elif self.show: print(compiled)
def compile_file(self, filepath, write=True, package=False, *args, **kwargs): """Compile a file and returns the compiled file's path.""" set_ext = False if write is False: destpath = None elif write is True: destpath = filepath set_ext = True elif os.path.splitext(write)[1]: # write is a file; it is the destination filepath destpath = write else: # write is a dir; make the destination filepath by adding the filename destpath = os.path.join(write, os.path.basename(filepath)) set_ext = True if set_ext: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = fixpath(base + ext) if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself", extra="incorrect file extension") self.compile(filepath, destpath, package, *args, **kwargs) return destpath
def watch(self, source, write=True, package=None, run=False, force=False): """Watches a source and recompiles on change.""" from coconut.command.watch import Observer, RecompilationWatcher source = fixpath(source) logger.print() logger.show_tabulated("Watching", showpath(source), "(press Ctrl-C to end)...") def recompile(path): if os.path.isfile(path) and os.path.splitext(path)[1] in code_exts: with self.handling_exceptions(): self.compile_path(path, write, package, run, force) observer = Observer() observer.schedule(RecompilationWatcher(recompile), source, recursive=True) with self.running_jobs(): observer.start() try: while True: time.sleep(watch_interval) except KeyboardInterrupt: logger.show("Got KeyboardInterrupt; stopping watcher.") finally: observer.stop() observer.join()
def watch(self, source, write=True, package=None, run=False, force=False): """Watches a source and recompiles on change.""" from coconut.command.watch import Observer, RecompilationWatcher source = fixpath(source) print() logger.show_tabulated("Watching", showpath(source), "(press Ctrl-C to end)...") def recompile(path): if os.path.isfile(path) and os.path.splitext(path)[1] in code_exts: with self.handling_exceptions(): self.run_mypy(self.compile_path(path, write, package, run, force)) observer = Observer() observer.schedule(RecompilationWatcher(recompile), source, recursive=True) with self.running_jobs(): observer.start() try: while True: time.sleep(watch_interval) except KeyboardInterrupt: logger.show("Got KeyboardInterrupt; stopping watcher.") finally: observer.stop() observer.join()
def compile_file(self, filepath, write=True, package=False, force=False, **kwargs): """Compile a file and returns the compiled file's path.""" set_ext = False if write is False: destpath = None elif write is True: destpath = filepath set_ext = True elif os.path.splitext(write)[1]: # write is a file; it is the destination filepath destpath = write else: # write is a dir; make the destination filepath by adding the filename destpath = os.path.join(write, os.path.basename(filepath)) set_ext = True if set_ext: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = fixpath(base + ext) if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself", extra="incorrect file extension") if destpath is not None: dest_ext = os.path.splitext(destpath)[1] if dest_ext in code_exts: if force: logger.warn("found destination path with " + dest_ext + " extension; compiling anyway due to --force") else: raise CoconutException( "found destination path with " + dest_ext + " extension; aborting compilation", extra="pass --force to override", ) self.compile(filepath, destpath, package, force=force, **kwargs) return destpath
def compile_file(self, filepath, write=True, package=False, *args, **kwargs): """Compile a file and returns the compiled file's path.""" if write is None: destpath = None elif write is True: destpath = filepath else: # add the name of file to the destination path destpath = os.path.join(write, os.path.basename(filepath)) if destpath is not None: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = fixpath(base + ext) if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself", extra="incorrect file extension") self.compile(filepath, destpath, package, *args, **kwargs) return destpath
def compile(self, codepath, destpath=None, package=False, run=False, force=False): """Compiles a source Coconut file to a destination Python file.""" logger.show_tabulated("Compiling", showpath(codepath), "...") with openfile(codepath, "r") as opened: code = readfile(opened) if destpath is not None: destdir = os.path.dirname(destpath) if not os.path.exists(destdir): os.makedirs(destdir) if package is True: self.create_package(destdir) foundhash = None if force else self.hashashof(destpath, code, package) if foundhash: logger.show_tabulated("Left unchanged", showpath(destpath), "(pass --force to override).") if self.show: print(foundhash) if run: self.execute_file(destpath) else: if package is True: compile_method = "parse_package" elif package is False: compile_method = "parse_file" else: raise CoconutInternalException("invalid value for package", package) def callback(compiled): if destpath is None: logger.show_tabulated("Finished", showpath(codepath), "without writing to file.") else: with openfile(destpath, "w") as opened: writefile(opened, compiled) logger.show_tabulated("Compiled to", showpath(destpath), ".") if self.show: print(compiled) if run: if destpath is None: self.execute(compiled, path=codepath, allow_show=False) else: self.execute_file(destpath) self.submit_comp_job(codepath, callback, compile_method, code)
def submit_comp_job(self, path, callback, method, *args, **kwargs): """Submits a job on self.comp to be run in parallel.""" if self.executor is None: with self.handling_exceptions(): callback(getattr(self.comp, method)(*args, **kwargs)) else: path = showpath(path) with logger.in_path(path): # pickle the compiler in the path context future = self.executor.submit(multiprocess_wrapper(self.comp, method), *args, **kwargs) 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) future.add_done_callback(callback_wrapper)
def submit_comp_job(self, path, callback, method, *args, **kwargs): """Submits a job on self.comp to be run in parallel.""" if self.executor is None: with self.handling_exceptions(): callback(getattr(self.comp, method)(*args, **kwargs)) else: path = showpath(path) with logger.in_path(path): # pickle the compiler in the path context future = self.executor.submit(multiprocess_wrapper(self.comp, method), *args, **kwargs) 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) future.add_done_callback(callback_wrapper)
def compile_file(self, filepath, write=True, package=False, run=False, force=False): """Compiles a file and returns the compiled file's path.""" if write is None: destpath = None elif write is True: destpath = filepath else: destpath = os.path.join(write, os.path.basename(filepath)) if destpath is not None: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = fixpath(base + ext) if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself", extra="incorrect file extension") self.compile(filepath, destpath, package, run, force) return destpath
def watch(self, source, write=True, package=None, run=False, force=False): """Watch a source and recompiles on change.""" from coconut.command.watch import Observer, RecompilationWatcher source = fixpath(source) logger.show() logger.show_tabulated("Watching", showpath(source), "(press Ctrl-C to end)...") def recompile(path): path = fixpath(path) if os.path.isfile(path) and os.path.splitext(path)[1] in code_exts: with self.handling_exceptions(): if write is True or write is None: writedir = write else: # correct the compilation path based on the relative position of path to source dirpath = os.path.dirname(path) writedir = os.path.join( write, os.path.relpath(dirpath, source)) filepaths = self.compile_path(path, writedir, package, run, force, show_unchanged=False) self.run_mypy(filepaths) watcher = RecompilationWatcher(recompile) observer = Observer() observer.schedule(watcher, source, recursive=True) with self.running_jobs(): observer.start() try: while True: time.sleep(watch_interval) watcher.keep_watching() except KeyboardInterrupt: logger.show_sig("Got KeyboardInterrupt; stopping watcher.") finally: observer.stop() observer.join()
def compile_file(self, filepath, write=True, package=False, run=False, force=False): """Compiles a file.""" if write is None: destpath = None elif write is True: destpath = filepath else: destpath = os.path.join(write, os.path.basename(filepath)) if destpath is not None: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = base + ext if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself (incorrect file extension)") else: self.compile(filepath, destpath, package, run, force)
def watch(self, source, write=True, package=None, run=False, force=False): """Watch a source and recompiles on change.""" from coconut.command.watch import Observer, RecompilationWatcher source = fixpath(source) logger.show() logger.show_tabulated("Watching", showpath(source), "(press Ctrl-C to end)...") def recompile(path): path = fixpath(path) if os.path.isfile(path) and os.path.splitext(path)[1] in code_exts: with self.handling_exceptions(): if write is True or write is None: writedir = write else: # correct the compilation path based on the relative position of path to source dirpath = os.path.dirname(path) writedir = os.path.join(write, os.path.relpath(dirpath, source)) filepaths = self.compile_path(path, writedir, package, run, force, show_unchanged=False) self.run_mypy(filepaths) watcher = RecompilationWatcher(recompile) observer = Observer() observer.schedule(watcher, source, recursive=True) with self.running_jobs(): observer.start() try: while True: time.sleep(watch_interval) watcher.keep_watching() except KeyboardInterrupt: logger.show_sig("Got KeyboardInterrupt; stopping watcher.") finally: observer.stop() observer.join()
def compile_file(self, filepath, write=True, package=False, *args, **kwargs): """Compile a file and returns the compiled file's path.""" set_ext = False if write is False: destpath = None elif write is True: destpath = filepath set_ext = True elif os.path.splitext(write)[1]: # write is a file; it is the destination filepath destpath = write else: # write is a dir; make the destination filepath by adding the filename destpath = os.path.join(write, os.path.basename(filepath)) set_ext = True if set_ext: base, ext = os.path.splitext(os.path.splitext(destpath)[0]) if not ext: ext = comp_ext destpath = fixpath(base + ext) if filepath == destpath: raise CoconutException("cannot compile " + showpath(filepath) + " to itself", extra="incorrect file extension") self.compile(filepath, destpath, package, *args, **kwargs) return destpath