src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py

Tue, 18 Oct 2022 16:06:21 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 18 Oct 2022 16:06:21 +0200
branch
eric7
changeset 9413
80c06d472826
parent 9221
bf71ee032bb4
child 9473
3f23dbf37dbe
permissions
-rw-r--r--

Changed the eric7 import statements to include the package name (i.e. eric7) in order to not fiddle with sys.path.

# -*- coding: utf-8 -*-

# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a dialog to enter the virtual environment upgrade
parameters.
"""

import re

from PyQt6.QtCore import pyqtSlot, QProcess, QTimer
from PyQt6.QtWidgets import QDialog, QDialogButtonBox

from eric7.EricWidgets.EricPathPicker import EricPathPickerModes

from .Ui_VirtualenvUpgradeConfigurationDialog import (
    Ui_VirtualenvUpgradeConfigurationDialog,
)

from eric7 import Globals, Preferences, Utilities


class VirtualenvUpgradeConfigurationDialog(
    QDialog, Ui_VirtualenvUpgradeConfigurationDialog
):
    """
    Class implementing a dialog to enter the virtual environment upgrade
    parameters.
    """

    def __init__(self, envName, envPath, parent=None):
        """
        Constructor

        @param envName name of the environment to be upgraded
        @type str
        @param envPath directory of the environment to be upgraded
        @type str
        @param parent reference to the parent widget (defaults to None)
        @type QWidget (optional)
        """
        super().__init__(parent)
        self.setupUi(self)

        self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
        self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
        self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())

        self.envNameLabel.setText(envName)
        self.envDirectoryLabel.setText(envPath)

        self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""")

        self.upgradePythonCheckBox.toggled.connect(self.__updateOkButton)
        self.upgradeDepsCheckBox.toggled.connect(self.__updateOkButton)
        self.pythonExecPicker.textChanged.connect(self.__updateUpgradeDepsCheckBox)

        self.__updateUpgradeDepsCheckBox()

        msh = self.minimumSizeHint()
        self.resize(max(self.width(), msh.width()), msh.height())

    def __getPyvenvVersion(self):
        """
        Private method to determine the version of the venv module.

        @return tuple containing the venv modules version
        @rtype tuple of (int, int, int)
        """
        calls = []
        if self.pythonExecPicker.text():
            calls.append((self.pythonExecPicker.text(), ["-m", "venv"]))
        calls.extend(
            [
                (Globals.getPythonExecutable(), ["-m", "venv"]),
                ("python3", ["-m", "venv"]),
                ("python", ["-m", "venv"]),
            ]
        )

        proc = QProcess()
        for prog, args in calls:
            proc.start(prog, args)

            if not proc.waitForStarted(5000):
                # try next entry
                continue

            if not proc.waitForFinished(5000):
                # process hangs, kill it and try next entry
                QTimer.singleShot(2000, proc.kill)
                proc.waitForFinished(3000)
                continue

            if proc.exitCode() not in [0, 2]:
                # returned with error code, try next
                continue

            proc.start(prog, ["--version"])
            proc.waitForFinished(5000)
            output = str(
                proc.readAllStandardOutput(),
                Preferences.getSystem("IOEncoding"),
                "replace",
            ).strip()
            match = re.match(self.__versionRe, output)
            if match:
                return Globals.versionToTuple(match.group(1))

        return (0, 0, 0)  # dummy version tuple

    @pyqtSlot()
    def __updateUpgradeDepsCheckBox(self):
        """
        Private slot to set the enabled state of the button depending
        on the version of the given Python interpreter.
        """
        pyvenvVersion = self.__getPyvenvVersion()
        if pyvenvVersion >= (3, 9, 0):
            self.upgradeDepsCheckBox.setEnabled(True)
        else:
            self.upgradeDepsCheckBox.setEnabled(False)
            self.upgradeDepsCheckBox.setChecked(False)

    @pyqtSlot()
    def __updateOkButton(self):
        """
        Private slot to set the enabled state of the OK button.
        """
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
            self.upgradePythonCheckBox.isChecked()
            or self.upgradeDepsCheckBox.isChecked()
        )

    def getData(self):
        """
        Public method to retrieve the dialog data.

        @return tuple containing the selected python executable, the list of
            arguments and a flag indicating to write a log file
        @rtype tuple of (str, list of str, bool)
        """
        args = ["-m", "venv"]
        if self.upgradePythonCheckBox.isChecked():
            args.append("--upgrade")
        if self.upgradeDepsCheckBox.isChecked():
            args.append("--upgrade-deps")
        args.append(self.envDirectoryLabel.text())

        return (
            Utilities.toNativeSeparators(self.pythonExecPicker.text()),
            args,
            self.logCheckBox.isChecked(),
        )

eric ide

mercurial