Exemplo n.º 1
0
 def _get_target_directory(self):
     if self._should_install_to_site_packages():
         return normpath_with_actual_case(self._backend_proxy.get_site_packages())
     else:
         usp = self._backend_proxy.get_user_site_packages()
         os.makedirs(usp, exist_ok=True)
         return normpath_with_actual_case(usp)
Exemplo n.º 2
0
    def _create_venv(self):
        path = askdirectory(
            parent=self.winfo_toplevel(),
            initialdir=None,
            title=tr(
                "Select an existing virtual environemnt or an empty directory for new virtual environment"
            ),
        )

        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        if not os.listdir(path):
            proc = subprocess.Popen(
                [running.get_interpreter_for_subprocess(), "-m", "venv", path],
                stdin=None,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                universal_newlines=True,
            )
            dlg = SubprocessDialog(self, proc,
                                   tr("Creating virtual environment"))
            ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
        else:
            # Undefined error handling.
            pass
Exemplo n.º 3
0
 def _get_target_directory(self):
     if self._targets_virtual_environment():
         return normpath_with_actual_case(
             self._backend_proxy.get_site_packages())
     else:
         usp = self._backend_proxy.get_user_site_packages()
         os.makedirs(usp, exist_ok=True)
         return normpath_with_actual_case(usp)
Exemplo n.º 4
0
    def _create_venv(self, event=None):
        if not _check_venv_installed(self):
            return

        messagebox.showinfo(
            "Creating new virtual environment",
            "After clicking 'OK' you need to choose an empty directory, "
            "which will be the root of your new virtual environment.",
            parent=self,
        )
        path = None
        while True:
            path = askdirectory(
                parent=self.winfo_toplevel(),
                initialdir=path,
                title=tr("Select empty directory for new virtual environment"),
            )
            if not path:
                return

            if os.listdir(path):
                messagebox.showerror(
                    tr("Bad directory"),
                    tr("Selected directory is not empty.\nSelect another or cancel."
                       ),
                    master=self,
                )
            else:
                break
        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        proc = subprocess.Popen(
            [running.get_interpreter_for_subprocess(), "-m", "venv", path],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        )
        from thonny.workdlg import SubprocessDialog

        dlg = SubprocessDialog(self,
                               proc,
                               tr("Creating virtual environment"),
                               autostart=True)
        ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
Exemplo n.º 5
0
    def _get_target_directory(self):
        if self._use_user_install():
            import site

            assert hasattr(site, "getusersitepackages")
            os.makedirs(site.getusersitepackages(), exist_ok=True)
            return normpath_with_actual_case(site.getusersitepackages())
        else:
            for d in sys.path:
                if ("site-packages" in d or "dist-packages"
                        in d) and path_startswith(d, sys.prefix):
                    return normpath_with_actual_case(d)
            return None
Exemplo n.º 6
0
 def _is_read_only_package(self, name):
     dist = self._get_active_dist(name)
     if dist is None:
         return False
     else:
         return (normpath_with_actual_case(dist["location"]) !=
                 self._get_target_directory())
Exemplo n.º 7
0
    def execute_current(self, command_name: str) -> None:
        """
        This method's job is to create a command for running/debugging
        current file/script and submit it to shell
        """

        if not self.is_waiting_toplevel_command():
            self.restart_backend(False, False, 2)

        filename = get_saved_current_script_filename()

        if not filename:
            # cancel must have been pushed
            return

        # changing dir may be required
        script_dir = normpath_with_actual_case(os.path.dirname(filename))

        if get_workbench().get_option(
                "run.auto_cd") and command_name[0].isupper():
            working_directory = script_dir  # type: Optional[str]
        else:
            working_directory = None

        args = self._get_active_arguments()

        self.execute_script(filename, args, working_directory, command_name)
Exemplo n.º 8
0
    def request_focus_into(self, path):
        if path == "":
            if running_on_windows():
                # list of drives, can't cd
                self.focus_into(path)
                return
            else:
                path = "/"

        if not os.path.isdir(path):
            return

        proxy = get_runner().get_backend_proxy()
        if (
            proxy
            and proxy.uses_local_filesystem()
            and proxy.get_cwd() != path
            and get_runner().is_waiting_toplevel_command()
        ):
            get_shell().submit_magic_command(construct_cd_command(normpath_with_actual_case(path)))
        else:
            # it's OK, if it's already focused into this directory
            # focus again to refresh
            self.focus_into(path)
            get_workbench().set_local_cwd(path)
Exemplo n.º 9
0
    def ask_new_local_path(self):
        if self._filename is None:
            initialdir = get_workbench().get_local_cwd()
            initialfile = None
        else:
            initialdir = os.path.dirname(self._filename)
            initialfile = os.path.basename(self._filename)

        # http://tkinter.unpythonic.net/wiki/tkFileDialog
        new_filename = asksaveasfilename(
            filetypes=_dialog_filetypes,
            defaultextension=".py",
            initialdir=initialdir,
            initialfile=initialfile,
        )

        # Different tkinter versions may return different values
        if new_filename in ["", (), None]:
            return None

        # Seems that in some Python versions defaultextension
        # acts funny
        if new_filename.lower().endswith(".py.py"):
            new_filename = new_filename[:-3]

        if running_on_windows():
            # may have /-s instead of \-s and wrong case
            new_filename = os.path.join(
                normpath_with_actual_case(os.path.dirname(new_filename)),
                os.path.basename(new_filename),
            )

        if new_filename.endswith(".py"):
            base = os.path.basename(new_filename)
            mod_name = base[:-3].lower()
            if running_on_windows():
                mod_name = mod_name.lower()

            if mod_name in [
                "math",
                "turtle",
                "random",
                "statistics",
                "pygame",
                "matplotlib",
                "numpy",
            ]:

                # More proper name analysis will be performed by ProgramNamingAnalyzer
                if not tk.messagebox.askyesno(
                    "Potential problem",
                    "If you name your script '%s', " % base
                    + "you won't be able to import the library module named '%s'" % mod_name
                    + ".\n\n"
                    + "Do you still want to use this name for your script?",
                ):
                    return self.ask_new_local_path()

        return new_filename
Exemplo n.º 10
0
def load_plugin() -> None:
    get_workbench().set_default(
        "file.last_browser_folder", normpath_with_actual_case(os.path.expanduser("~"))
    )

    get_workbench().set_default(HIDDEN_FILES_OPTION, False)

    get_workbench().add_view(FilesView, tr("Files"), "nw")

    for ext in [".py", ".pyw", ".pyi", ".txt", ".log", ".json", ".yml", ".yaml", ".md", ".rst"]:
        get_workbench().set_default(get_file_handler_conf_key(ext), "thonny")
Exemplo n.º 11
0
    def _create_venv(self):
        path = None
        while True:
            path = askdirectory(
                master=self,
                initialdir=path,
                title=_("Select empty directory for new virtual environment"),
            )
            if not path:
                return

            if os.listdir(path):
                messagebox.showerror(
                    _("Bad directory"),
                    _("Selected directory is not empty.\nSelect another or cancel."
                      ),
                    parent=get_workbench(),
                )
            else:
                break
        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        proc = subprocess.Popen(
            [running.get_frontend_python(), "-m", "venv", path],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        )
        dlg = SubprocessDialog(self, proc, _("Creating virtual environment"))
        ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
Exemplo n.º 12
0
    def get_editor(self, filename, open_when_necessary=False):
        if not is_remote_path(filename) and os.path.isfile(filename):
            filename = normpath_with_actual_case(os.path.abspath(filename))
        for child in self.winfo_children():
            child_filename = child.get_filename(False)
            if child_filename == filename:
                return child

        if open_when_necessary:
            return self._open_file(filename)
        else:
            return None
Exemplo n.º 13
0
    def get_editor(self, filename_or_id, open_when_necessary=False):
        if os.path.isfile(filename_or_id):
            filename_or_id = normpath_with_actual_case(os.path.abspath(filename_or_id))

        for child in self.winfo_children():
            assert isinstance(child, Editor)
            child_identifier = child.get_identifier()
            if child_identifier == filename_or_id:
                return child

        if open_when_necessary:
            return self._open_file(filename_or_id)
        else:
            return None
Exemplo n.º 14
0
    def _load_local_file(self, filename, keep_undo=False):
        with open(filename, "rb") as fp:
            source = fp.read()

        # Make sure Windows filenames have proper format
        filename = normpath_with_actual_case(filename)
        self._filename = filename
        self._last_known_mtime = os.path.getmtime(self._filename)

        get_workbench().event_generate("Open", editor=self, filename=filename)
        self._code_view.set_content_as_bytes(source, keep_undo)
        self.get_text_widget().edit_modified(False)
        self._code_view.focus_set()
        self.master.remember_recent_file(filename)
Exemplo n.º 15
0
    def _start_show_package_info(self, name):
        self.current_package_data = None
        # Fetch info from PyPI
        self._set_state("fetching")
        # Follwing fetches info about latest version.
        # This is OK even when we're looking an installed older version
        # because new version may have more relevant and complete info.
        _start_fetching_package_info(name, None, self._show_package_info)

        self.info_text.direct_delete("1.0", "end")
        self.name_label["text"] = ""
        self.name_label.grid()
        self.command_frame.grid()

        active_dist = self._get_active_dist(name)
        if active_dist is not None:
            self.name_label["text"] = active_dist["project_name"]
            self.info_text.direct_insert("end",
                                         _("Installed version:") + " ",
                                         ("caption", ))
            self.info_text.direct_insert("end", active_dist["version"] + "\n")
            self.info_text.direct_insert("end",
                                         _("Installed to:") + " ",
                                         ("caption", ))
            self.info_text.direct_insert(
                "end", normpath_with_actual_case(active_dist["location"]),
                ("url", ))
            self.info_text.direct_insert("end", "\n\n")
            self._select_list_item(name)
        else:
            self._select_list_item(0)

        # update gui
        if self._is_read_only_package(name):
            self.install_button.grid_remove()
            self.uninstall_button.grid_remove()
            self.advanced_button.grid_remove()
        else:
            self.install_button.grid(row=0, column=0)
            self.advanced_button.grid(row=0, column=2)

            if active_dist is not None:
                # existing package in target directory
                self.install_button["text"] = _("Upgrade")
                self.install_button["state"] = "disabled"
                self.uninstall_button.grid(row=0, column=1)
            else:
                # new package
                self.install_button["text"] = _("Install")
                self.uninstall_button.grid_remove()
Exemplo n.º 16
0
    def _load_local_file(self, filename, keep_undo=False):
        with tokenize.open(filename) as fp:  # TODO: support also text files
            source = fp.read()

        # get the file file format (DOS/UNIX)
        self._newlines = fp.newlines

        # Make sure Windows filenames have proper format
        filename = normpath_with_actual_case(filename)
        self._filename = filename
        self._last_known_mtime = os.path.getmtime(self._filename)

        get_workbench().event_generate("Open", editor=self, filename=filename)
        self._code_view.set_content(source, keep_undo)
        self.get_text_widget().edit_modified(False)
        self._code_view.focus_set()
        self.master.remember_recent_file(filename)
Exemplo n.º 17
0
def _get_interpreters():
    result = set()

    if running_on_windows():
        # registry
        result.update(_get_interpreters_from_windows_registry())

        for minor in [6, 7, 8, 9]:
            for dir_ in [
                    "C:\\Python3%d" % minor,
                    "C:\\Python3%d-32" % minor,
                    "C:\\Python3%d-64" % minor,
                    "C:\\Program Files\\Python 3.%d" % minor,
                    "C:\\Program Files\\Python 3.%d-64" % minor,
                    "C:\\Program Files (x86)\\Python 3.%d" % minor,
                    "C:\\Program Files (x86)\\Python 3.%d-32" % minor,
                    "C:\\Program Files (x86)\\Python 3.%d-32" % minor,
                    os.path.expanduser(
                        "~\\AppData\Local\Programs\Python\Python3%d" % minor),
                    os.path.expanduser(
                        "~\\AppData\Local\Programs\Python\Python3%d-32" %
                        minor),
            ]:
                path = os.path.join(dir_, WINDOWS_EXE)
                if os.path.exists(path):
                    result.add(normpath_with_actual_case(path))

        # other locations
        for dir_ in [
                "C:\\Anaconda3",
                "C:\\ProgramData\\Anaconda3",
                os.path.expanduser("~\\Anaconda3"),
        ]:
            path = os.path.join(dir_, WINDOWS_EXE)
            if os.path.exists(path):
                result.add(normpath_with_actual_case(path))

    else:
        # Common unix locations
        dirs = [
            "/bin",
            "/usr/bin",
            "/usr/local/bin",
            os.path.expanduser("~/.local/bin"),
            os.path.expanduser("~/anaconda3/bin"),
        ]
        for dir_ in dirs:
            # if the dir_ is just a link to another dir_, skip it
            # (not to show items twice)
            # for example on Fedora /bin -> usr/bin
            if not os.path.exists(dir_):
                continue

            apath = normpath_with_actual_case(dir_)
            if apath != dir_ and apath in dirs:
                continue
            for name in [
                    "python3", "python3.5", "python3.6", "python3.7",
                    "python3.8"
            ]:
                path = os.path.join(dir_, name)
                if os.path.exists(path):
                    result.add(path)

    if running_on_mac_os():
        for version in ["3.6", "3.7", "3.8", "3.9"]:
            dir_ = os.path.join(
                "/Library/Frameworks/Python.framework/Versions", version,
                "bin")
            path = os.path.join(dir_, "python3")

            if os.path.exists(path):
                result.add(path)

    from shutil import which

    for command in [
            "python3", "python3.6", "python3.7", "python3.8", "python3.9"
    ]:
        path = which(command)
        if path is not None and os.path.isabs(path):
            result.add(path)

    for path in get_workbench().get_option("CustomInterpreter.used_paths"):
        if os.path.exists(path):
            result.add(normpath_with_actual_case(path))

    return sorted(result)
Exemplo n.º 18
0
def load_plugin() -> None:
    get_workbench().set_default(
        "file.last_browser_folder",
        normpath_with_actual_case(os.path.expanduser("~")))

    get_workbench().add_view(FilesView, _("Files"), "nw")
Exemplo n.º 19
0
    def ask_new_local_path(self):
        if self._filename is None:
            initialdir = get_workbench().get_local_cwd()
            initialfile = None
        else:
            initialdir = os.path.dirname(self._filename)
            initialfile = os.path.basename(self._filename)

        # https://tcl.tk/man/tcl8.6/TkCmd/getOpenFile.htm
        type_var = tk.StringVar(value="")
        new_filename = asksaveasfilename(
            filetypes=_dialog_filetypes,
            defaultextension=None,
            initialdir=initialdir,
            initialfile=initialfile,
            parent=get_workbench(),
            typevariable=type_var,
        )
        logger.info("Save dialog returned %r with typevariable %r", new_filename, type_var.get())

        # Different tkinter versions may return different values
        if new_filename in ["", (), None]:
            return None

        if running_on_windows():
            # may have /-s instead of \-s and wrong case
            new_filename = os.path.join(
                normpath_with_actual_case(os.path.dirname(new_filename)),
                os.path.basename(new_filename),
            )

        if type_var.get() == PYTHON_FILES_STR or type_var.get() == "":
            new_filename = self._check_add_py_extension(
                new_filename, without_asking=type_var.get() == PYTHON_FILES_STR
            )

        if new_filename.endswith(".py"):
            base = os.path.basename(new_filename)
            mod_name = base[:-3].lower()
            if running_on_windows():
                mod_name = mod_name.lower()

            if mod_name in [
                "math",
                "turtle",
                "random",
                "statistics",
                "pygame",
                "matplotlib",
                "numpy",
            ]:

                # More proper name analysis will be performed by ProgramNamingAnalyzer
                if not tk.messagebox.askyesno(
                    "Potential problem",
                    "If you name your script '%s', " % base
                    + "you won't be able to import the library module named '%s'" % mod_name
                    + ".\n\n"
                    + "Do you still want to use this name for your script?",
                    master=self,
                ):
                    return self.ask_new_local_path()

        return new_filename
Exemplo n.º 20
0
    def save_file(self, ask_filename=False):
        if self._filename is not None and not ask_filename:
            get_workbench().event_generate("Save",
                                           editor=self,
                                           filename=self._filename)
        else:
            # http://tkinter.unpythonic.net/wiki/tkFileDialog
            new_filename = asksaveasfilename(
                master=get_workbench(),
                filetypes=_dialog_filetypes,
                defaultextension=".py",
                initialdir=get_workbench().get_cwd(),
            )

            # Different tkinter versions may return different values
            if new_filename in [
                    "",
                (),
                    None,
            ]:
                return None

            # Seems that in some Python versions defaultextension
            # acts funny
            if new_filename.lower().endswith(".py.py"):
                new_filename = new_filename[:-3]

            if running_on_windows():
                # may have /-s instead of \-s and wrong case
                new_filename = os.path.join(
                    normpath_with_actual_case(os.path.dirname(new_filename)),
                    os.path.basename(new_filename))

            if new_filename.endswith(".py"):
                base = os.path.basename(new_filename)
                mod_name = base[:-3].lower()
                if running_on_windows():
                    mod_name = mod_name.lower()

                if mod_name in [
                        "math",
                        "turtle",
                        "random",
                        "statistics",
                        "pygame",
                        "matplotlib",
                        "numpy",
                ]:

                    # More proper name analysis will be performed by ProgramNamingAnalyzer
                    if not tk.messagebox.askyesno(
                            "Potential problem",
                            "If you name your script '%s', " % base +
                            "you won't be able to import the library module named '%s'"
                            % mod_name + ".\n\n" +
                            "Do you still want to use this name for your script?",
                            parent=get_workbench(),
                    ):
                        return self.save_file(ask_filename)

            self._filename = new_filename
            get_workbench().event_generate("SaveAs",
                                           editor=self,
                                           filename=new_filename)

        content = self._code_view.get_content_as_bytes()
        try:
            f = open(self._filename, mode="wb")
            f.write(content)
            f.flush()
            # Force writes on disk, see https://learn.adafruit.com/adafruit-circuit-playground-express/creating-and-editing-code#1-use-an-editor-that-writes-out-the-file-completely-when-you-save-it
            os.fsync(f)
            f.close()
            self._last_known_mtime = os.path.getmtime(self._filename)
        except PermissionError:
            if askyesno(
                    "Permission Error",
                    "Looks like this file or folder is not writable.\n\n" +
                    "Do you want to save under another folder and/or filename?",
                    parent=get_workbench(),
            ):
                return self.save_file(True)
            else:
                return None

        self.master.remember_recent_file(self._filename)

        self._code_view.text.edit_modified(False)

        return self._filename
Exemplo n.º 21
0
def construct_cd_command(path):
    return construct_cmd_line(["%cd", normpath_with_actual_case(path)])