Exemplo n.º 1
0
 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
Exemplo n.º 2
0
    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()
Exemplo n.º 3
0
 def run_file(self, path, all_errors_exit=True):
     """Execute a Python file."""
     path = fixpath(path)
     with self.handling_errors(all_errors_exit):
         module_vars = run_file(path)
         self.vars.update(module_vars)
         self.store("from " + splitname(path)[1] + " import *")
Exemplo n.º 4
0
def install_custom_kernel(executable=None, logger=None):
    """Force install the custom kernel."""
    kernel_source = os.path.join(icoconut_custom_kernel_dir, "kernel.json")
    kernel_dest = fixpath(
        os.path.join(sys.exec_prefix, icoconut_custom_kernel_install_loc))
    try:
        make_custom_kernel(executable)
        if not os.path.exists(kernel_dest):
            os.makedirs(kernel_dest)
        shutil.copy(kernel_source, kernel_dest)
    except OSError:
        existing_kernel = os.path.join(kernel_dest, "kernel.json")
        if os.path.exists(existing_kernel):
            if logger is not None:
                logger.log_exc()
            errmsg = "Failed to update Coconut Jupyter kernel installation; the 'coconut' kernel might not work properly as a result"
        else:
            if logger is None:
                traceback.print_exc()
            else:
                logger.print_exc()
            errmsg = "Coconut Jupyter kernel installation failed due to above error"
        if WINDOWS:
            errmsg += " (try again from a shell that is run as administrator)"
        else:
            errmsg += " (try again with 'sudo')"
        errmsg += "."
        if logger is None:
            warn(errmsg)
        else:
            logger.warn(errmsg)
        return None
    else:
        return kernel_dest
Exemplo n.º 5
0
 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
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
 def compile_path(self, path, write=True, package=None, *args, **kwargs):
     """Compile a path and returns paths to compiled files."""
     path = fixpath(path)
     if write is not None and write is not True:
         write = fixpath(write)
     if os.path.isfile(path):
         if package is None:
             package = False
         destpath = self.compile_file(path, write, package, *args, **kwargs)
         return [destpath] if destpath is not None else []
     elif os.path.isdir(path):
         if package is None:
             package = True
         return self.compile_folder(path, write, package, *args, **kwargs)
     else:
         raise CoconutException("could not find source path", path)
Exemplo n.º 8
0
 def compile_path(self, path, write=True, package=None, *args, **kwargs):
     """Compile a path and returns paths to compiled files."""
     path = fixpath(path)
     if not isinstance(write, bool):
         write = fixpath(write)
     if os.path.isfile(path):
         if package is None:
             package = False
         destpath = self.compile_file(path, write, package, *args, **kwargs)
         return [destpath] if destpath is not None else []
     elif os.path.isdir(path):
         if package is None:
             package = True
         return self.compile_folder(path, write, package, *args, **kwargs)
     else:
         raise CoconutException("could not find source path", path)
Exemplo n.º 9
0
 def run_file(self, path, all_errors_exit=True):
     """Execute a Python file."""
     path = fixpath(path)
     with self.handling_errors(all_errors_exit):
         module_vars = run_file(path)
         self.vars.update(module_vars)
         self.store("from " + splitname(path)[1] + " import *")
Exemplo n.º 10
0
    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()
Exemplo n.º 11
0
 def compile_path(self, path, write=True, package=None, run=False, force=False):
     """Compiles a path and returns paths to compiled files."""
     path = fixpath(path)
     if write is not None and write is not True:
         write = fixpath(write)
     if os.path.isfile(path):
         if package is None:
             package = False
         destpath = self.compile_file(path, write, package, run, force)
         if destpath is None:
             return []
         else:
             return [destpath]
     elif os.path.isdir(path):
         if package is None:
             package = True
         return self.compile_folder(path, write, package, run, force)
     else:
         raise CoconutException("could not find source path", path)
Exemplo n.º 12
0
 def compile_path(self, path, write=True, package=True, *args, **kwargs):
     """Compile a path and returns paths to compiled files."""
     if not isinstance(write, bool):
         write = fixpath(write)
     if os.path.isfile(path):
         destpath = self.compile_file(path, write, package, *args, **kwargs)
         return [destpath] if destpath is not None else []
     elif os.path.isdir(path):
         return self.compile_folder(path, write, package, *args, **kwargs)
     else:
         raise CoconutException("could not find source path", path)
Exemplo n.º 13
0
 def build_vars(self, path=None):
     """Builds initial vars."""
     init_vars = {
         "__name__": "__main__",
         "__package__": None,
     }
     for var in reserved_vars:
         init_vars[var] = None
     if path is not None:
         init_vars["__file__"] = fixpath(path)
     return init_vars
Exemplo n.º 14
0
 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)
Exemplo n.º 15
0
 def build_vars(path=None):
     """Build initial vars."""
     init_vars = {
         "__name__": "__main__",
         "__package__": None,
         "reload": reload,
     }
     if path is not None:
         init_vars["__file__"] = fixpath(path)
     # put reserved_vars in for auto-completion purposes
     for var in reserved_vars:
         init_vars[var] = None
     return init_vars
Exemplo n.º 16
0
 def build_vars(path=None):
     """Build initial vars."""
     init_vars = {
         "__name__": "__main__",
         "__package__": None,
         "reload": reload,
     }
     if path is not None:
         init_vars["__file__"] = fixpath(path)
     # put reserved_vars in for auto-completion purposes
     for var in reserved_vars:
         init_vars[var] = None
     return init_vars
Exemplo n.º 17
0
    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)

        package_level = -1
        if destpath is not None:
            destpath = fixpath(destpath)
            destdir = os.path.dirname(destpath)
            if not os.path.exists(destdir):
                os.makedirs(destdir)
            if package is True:
                package_level = self.get_package_level(codepath)
                if package_level == 0:
                    self.create_package(destdir)

        foundhash = None if force else self.has_hash_of(destpath, code, package_level)
        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), "...")

            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)

            if package is True:
                self.submit_comp_job(codepath, callback, "parse_package", code, package_level=package_level)
            elif package is False:
                self.submit_comp_job(codepath, callback, "parse_file", code)
            else:
                raise CoconutInternalException("invalid value for package", package)
Exemplo n.º 18
0
 def build_vars(path=None, init=False):
     """Build initial vars."""
     init_vars = {
         "__name__": "__main__",
         "__package__": None,
         "reload": reload,
     }
     if path is not None:
         init_vars["__file__"] = fixpath(path)
     if init:
         # put reserved_vars in for auto-completion purposes only at the very beginning
         for var in reserved_vars:
             # but don't override any default Python built-ins
             if var not in dir(builtins):
                 init_vars[var] = None
     return init_vars
Exemplo n.º 19
0
 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
Exemplo n.º 20
0
    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()
Exemplo n.º 21
0
    def process_source_dest(self, source, dest, args):
        """Determine the correct source, dest, package mode to use for the given source, dest, and args."""
        # determine source
        processed_source = fixpath(source)

        # validate args
        if (args.run or args.interact) and os.path.isdir(processed_source):
            if args.run:
                raise CoconutException("source path %r must point to file not directory when --run is enabled" % (source,))
            if args.interact:
                raise CoconutException("source path %r must point to file not directory when --run (implied by --interact) is enabled" % (source,))
        if args.watch and os.path.isfile(processed_source):
            raise CoconutException("source path %r must point to directory not file when --watch is enabled" % (source,))

        # determine dest
        if dest is None:
            if args.no_write:
                processed_dest = False  # no dest
            else:
                processed_dest = True  # auto-generate dest
        elif args.no_write:
            raise CoconutException("destination path cannot be given when --no-write is enabled")
        else:
            processed_dest = dest

        # determine package mode
        if args.package or self.mypy:
            package = True
        elif args.standalone:
            package = False
        else:
            # auto-decide package
            if os.path.isfile(source):
                package = False
            elif os.path.isdir(source):
                package = True
            else:
                raise CoconutException("could not find source path", source)

        return processed_source, processed_dest, package
Exemplo n.º 22
0
    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()
Exemplo n.º 23
0
 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
Exemplo n.º 24
0
 def get_python_lib(self):
     """Get current Python lib location."""
     from distutils import sysconfig  # expensive, so should only be imported here
     return fixpath(sysconfig.get_python_lib())
Exemplo n.º 25
0
 def create_package(self, dirpath):
     """Sets up a package directory."""
     dirpath = fixpath(dirpath)
     filepath = os.path.join(dirpath, "__coconut__.py")
     with openfile(filepath, "w") as opened:
         writefile(opened, self.comp.getheader("__coconut__"))
Exemplo n.º 26
0
def subpath(path, base_path):
    """Check if path is a subpath of base_path."""
    path = fixpath(path)
    base_path = fixpath(base_path)
    return path == base_path or path.startswith(base_path + os.sep)
Exemplo n.º 27
0
 def set_history_file(self, path):
     """Set path to history file. Pass empty string for in-memory history."""
     if path:
         self.history = prompt_toolkit.history.FileHistory(fixpath(path))
     else:
         self.history = prompt_toolkit.history.InMemoryHistory()
Exemplo n.º 28
0
 def set_history_file(self, path):
     """Set path to history file. "" produces no file."""
     if path:
         self.history = prompt_toolkit.history.FileHistory(fixpath(path))
     else:
         self.history = prompt_toolkit.history.InMemoryHistory()
Exemplo n.º 29
0
    def use_args(self, args, interact=True, original_args=None):
        """Handle command-line arguments."""
        logger.quiet, logger.verbose = args.quiet, args.verbose
        if DEVELOP:
            logger.tracing = args.trace

        logger.log("Using " + PYPARSING_INFO + ".")
        if original_args is not None:
            logger.log("Directly passed args:", original_args)
        logger.log("Parsed args:", args)

        if args.recursion_limit is not None:
            set_recursion_limit(args.recursion_limit)
        if args.jobs is not None:
            self.set_jobs(args.jobs)
        if args.display:
            self.show = True
        if args.style is not None:
            self.prompt.set_style(args.style)
        if args.history_file is not None:
            self.prompt.set_history_file(args.history_file)
        if args.documentation:
            launch_documentation()
        if args.tutorial:
            launch_tutorial()

        self.setup(
            target=args.target,
            strict=args.strict,
            minify=args.minify,
            line_numbers=args.line_numbers,
            keep_lines=args.keep_lines,
            no_tco=args.no_tco,
        )

        if args.mypy is not None:
            self.set_mypy_args(args.mypy)

        if args.argv is not None:
            sys.argv = [args.source if args.source is not None else ""]
            sys.argv.extend(args.argv)

        if args.source is not None:
            if args.interact and args.run:
                logger.warn(
                    "extraneous --run argument passed; --interact implies --run"
                )
            if args.package and self.mypy:
                logger.warn(
                    "extraneous --package argument passed; --mypy implies --package"
                )

            if args.standalone and args.package:
                raise CoconutException(
                    "cannot compile as both --package and --standalone")
            if args.standalone and self.mypy:
                raise CoconutException(
                    "cannot compile as both --package (implied by --mypy) and --standalone"
                )
            if args.no_write and self.mypy:
                raise CoconutException(
                    "cannot compile with --no-write when using --mypy")
            if (args.run or args.interact) and os.path.isdir(args.source):
                if args.run:
                    raise CoconutException(
                        "source path must point to file not directory when --run is enabled"
                    )
                if args.interact:
                    raise CoconutException(
                        "source path must point to file not directory when --run (implied by --interact) is enabled"
                    )
            if args.watch and os.path.isfile(args.source):
                raise CoconutException(
                    "source path must point to directory not file when --watch is enabled"
                )

            if args.dest is None:
                if args.no_write:
                    dest = False  # no dest
                else:
                    dest = True  # auto-generate dest
            elif args.no_write:
                raise CoconutException(
                    "destination path cannot be given when --no-write is enabled"
                )
            else:
                dest = args.dest

            source = fixpath(args.source)

            if args.package or self.mypy:
                package = True
            elif args.standalone:
                package = False
            else:
                # auto-decide package
                if os.path.isfile(source):
                    package = False
                elif os.path.isdir(source):
                    package = True
                else:
                    raise CoconutException("could not find source path",
                                           source)

            with self.running_jobs(exit_on_error=not args.watch):
                filepaths = self.compile_path(source, dest, package, args.run
                                              or args.interact, args.force)
            self.run_mypy(filepaths)

        elif (args.run or args.no_write or args.force or args.package
              or args.standalone or args.watch):
            raise CoconutException(
                "a source file/folder must be specified when options that depend on the source are enabled"
            )

        if args.code is not None:
            self.execute(self.comp.parse_block(args.code))
        got_stdin = False
        if args.jupyter is not None:
            self.start_jupyter(args.jupyter)
        elif stdin_readable():
            logger.log("Reading piped input from stdin...")
            self.execute(self.comp.parse_block(sys.stdin.read()))
            got_stdin = True
        if args.interact or (interact
                             and not (got_stdin or args.source or args.code
                                      or args.tutorial or args.documentation or
                                      args.watch or args.jupyter is not None)):
            self.start_prompt()
        if args.watch:
            self.watch(source, dest, package, args.run, args.force)
Exemplo n.º 30
0
 def create_package(self, dirpath):
     """Set up a package directory."""
     dirpath = fixpath(dirpath)
     filepath = os.path.join(dirpath, "__coconut__.py")
     with openfile(filepath, "w") as opened:
         writefile(opened, self.comp.getheader("__coconut__"))
Exemplo n.º 31
0
 def set_history_file(self, path):
     """Set path to history file. "" produces no file."""
     if path:
         self.history = prompt_toolkit.history.FileHistory(fixpath(path))
     else:
         self.history = prompt_toolkit.history.InMemoryHistory()