eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py

branch
eric7
changeset 9144
135240382a3e
diff -r 82f08c4fd930 -r 135240382a3e eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py	Fri Jun 10 18:13:47 2022 +0200
@@ -0,0 +1,157 @@
+# -*- 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 EricWidgets.EricPathPicker import EricPathPickerModes
+
+from .Ui_VirtualenvUpgradeConfigurationDialog import (
+    Ui_VirtualenvUpgradeConfigurationDialog
+)
+
+import Globals
+import Preferences
+import 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