29 ): |
29 ): |
30 """ |
30 """ |
31 Class implementing a dialog to enter the virtual environment upgrade |
31 Class implementing a dialog to enter the virtual environment upgrade |
32 parameters. |
32 parameters. |
33 """ |
33 """ |
|
34 |
34 def __init__(self, envName, envPath, parent=None): |
35 def __init__(self, envName, envPath, parent=None): |
35 """ |
36 """ |
36 Constructor |
37 Constructor |
37 |
38 |
38 @param envName name of the environment to be upgraded |
39 @param envName name of the environment to be upgraded |
39 @type str |
40 @type str |
40 @param envPath directory of the environment to be upgraded |
41 @param envPath directory of the environment to be upgraded |
41 @type str |
42 @type str |
42 @param parent reference to the parent widget (defaults to None) |
43 @param parent reference to the parent widget (defaults to None) |
43 @type QWidget (optional) |
44 @type QWidget (optional) |
44 """ |
45 """ |
45 super().__init__(parent) |
46 super().__init__(parent) |
46 self.setupUi(self) |
47 self.setupUi(self) |
47 |
48 |
48 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
49 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
49 self.pythonExecPicker.setWindowTitle( |
50 self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter")) |
50 self.tr("Python Interpreter")) |
51 self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable()) |
51 self.pythonExecPicker.setDefaultDirectory( |
52 |
52 Globals.getPythonExecutable()) |
|
53 |
|
54 self.envNameLabel.setText(envName) |
53 self.envNameLabel.setText(envName) |
55 self.envDirectoryLabel.setText(envPath) |
54 self.envDirectoryLabel.setText(envPath) |
56 |
55 |
57 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""") |
56 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""") |
58 |
57 |
59 self.upgradePythonCheckBox.toggled.connect(self.__updateOkButton) |
58 self.upgradePythonCheckBox.toggled.connect(self.__updateOkButton) |
60 self.upgradeDepsCheckBox.toggled.connect(self.__updateOkButton) |
59 self.upgradeDepsCheckBox.toggled.connect(self.__updateOkButton) |
61 self.pythonExecPicker.textChanged.connect( |
60 self.pythonExecPicker.textChanged.connect(self.__updateUpgradeDepsCheckBox) |
62 self.__updateUpgradeDepsCheckBox) |
61 |
63 |
|
64 self.__updateUpgradeDepsCheckBox() |
62 self.__updateUpgradeDepsCheckBox() |
65 |
63 |
66 msh = self.minimumSizeHint() |
64 msh = self.minimumSizeHint() |
67 self.resize(max(self.width(), msh.width()), msh.height()) |
65 self.resize(max(self.width(), msh.width()), msh.height()) |
68 |
66 |
69 def __getPyvenvVersion(self): |
67 def __getPyvenvVersion(self): |
70 """ |
68 """ |
71 Private method to determine the version of the venv module. |
69 Private method to determine the version of the venv module. |
72 |
70 |
73 @return tuple containing the venv modules version |
71 @return tuple containing the venv modules version |
74 @rtype tuple of (int, int, int) |
72 @rtype tuple of (int, int, int) |
75 """ |
73 """ |
76 calls = [] |
74 calls = [] |
77 if self.pythonExecPicker.text(): |
75 if self.pythonExecPicker.text(): |
78 calls.append((self.pythonExecPicker.text(), |
76 calls.append((self.pythonExecPicker.text(), ["-m", "venv"])) |
79 ["-m", "venv"])) |
77 calls.extend( |
80 calls.extend([ |
78 [ |
81 (Globals.getPythonExecutable(), ["-m", "venv"]), |
79 (Globals.getPythonExecutable(), ["-m", "venv"]), |
82 ("python3", ["-m", "venv"]), |
80 ("python3", ["-m", "venv"]), |
83 ("python", ["-m", "venv"]), |
81 ("python", ["-m", "venv"]), |
84 ]) |
82 ] |
85 |
83 ) |
|
84 |
86 proc = QProcess() |
85 proc = QProcess() |
87 for prog, args in calls: |
86 for prog, args in calls: |
88 proc.start(prog, args) |
87 proc.start(prog, args) |
89 |
88 |
90 if not proc.waitForStarted(5000): |
89 if not proc.waitForStarted(5000): |
91 # try next entry |
90 # try next entry |
92 continue |
91 continue |
93 |
92 |
94 if not proc.waitForFinished(5000): |
93 if not proc.waitForFinished(5000): |
95 # process hangs, kill it and try next entry |
94 # process hangs, kill it and try next entry |
96 QTimer.singleShot(2000, proc.kill) |
95 QTimer.singleShot(2000, proc.kill) |
97 proc.waitForFinished(3000) |
96 proc.waitForFinished(3000) |
98 continue |
97 continue |
99 |
98 |
100 if proc.exitCode() not in [0, 2]: |
99 if proc.exitCode() not in [0, 2]: |
101 # returned with error code, try next |
100 # returned with error code, try next |
102 continue |
101 continue |
103 |
102 |
104 proc.start(prog, ["--version"]) |
103 proc.start(prog, ["--version"]) |
105 proc.waitForFinished(5000) |
104 proc.waitForFinished(5000) |
106 output = str(proc.readAllStandardOutput(), |
105 output = str( |
107 Preferences.getSystem("IOEncoding"), |
106 proc.readAllStandardOutput(), |
108 'replace').strip() |
107 Preferences.getSystem("IOEncoding"), |
|
108 "replace", |
|
109 ).strip() |
109 match = re.match(self.__versionRe, output) |
110 match = re.match(self.__versionRe, output) |
110 if match: |
111 if match: |
111 return Globals.versionToTuple(match.group(1)) |
112 return Globals.versionToTuple(match.group(1)) |
112 |
113 |
113 return (0, 0, 0) # dummy version tuple |
114 return (0, 0, 0) # dummy version tuple |
114 |
115 |
115 @pyqtSlot() |
116 @pyqtSlot() |
116 def __updateUpgradeDepsCheckBox(self): |
117 def __updateUpgradeDepsCheckBox(self): |
117 """ |
118 """ |
118 Private slot to set the enabled state of the button depending |
119 Private slot to set the enabled state of the button depending |
119 on the version of the given Python interpreter. |
120 on the version of the given Python interpreter. |
122 if pyvenvVersion >= (3, 9, 0): |
123 if pyvenvVersion >= (3, 9, 0): |
123 self.upgradeDepsCheckBox.setEnabled(True) |
124 self.upgradeDepsCheckBox.setEnabled(True) |
124 else: |
125 else: |
125 self.upgradeDepsCheckBox.setEnabled(False) |
126 self.upgradeDepsCheckBox.setEnabled(False) |
126 self.upgradeDepsCheckBox.setChecked(False) |
127 self.upgradeDepsCheckBox.setChecked(False) |
127 |
128 |
128 @pyqtSlot() |
129 @pyqtSlot() |
129 def __updateOkButton(self): |
130 def __updateOkButton(self): |
130 """ |
131 """ |
131 Private slot to set the enabled state of the OK button. |
132 Private slot to set the enabled state of the OK button. |
132 """ |
133 """ |
133 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( |
134 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( |
134 self.upgradePythonCheckBox.isChecked() or |
135 self.upgradePythonCheckBox.isChecked() |
135 self.upgradeDepsCheckBox.isChecked() |
136 or self.upgradeDepsCheckBox.isChecked() |
136 ) |
137 ) |
137 |
138 |
138 def getData(self): |
139 def getData(self): |
139 """ |
140 """ |
140 Public method to retrieve the dialog data. |
141 Public method to retrieve the dialog data. |
141 |
142 |
142 @return tuple containing the selected python executable, the list of |
143 @return tuple containing the selected python executable, the list of |
143 arguments and a flag indicating to write a log file |
144 arguments and a flag indicating to write a log file |
144 @rtype tuple of (str, list of str, bool) |
145 @rtype tuple of (str, list of str, bool) |
145 """ |
146 """ |
146 args = ["-m", "venv"] |
147 args = ["-m", "venv"] |
147 if self.upgradePythonCheckBox.isChecked(): |
148 if self.upgradePythonCheckBox.isChecked(): |
148 args.append("--upgrade") |
149 args.append("--upgrade") |
149 if self.upgradeDepsCheckBox.isChecked(): |
150 if self.upgradeDepsCheckBox.isChecked(): |
150 args.append("--upgrade-deps") |
151 args.append("--upgrade-deps") |
151 args.append(self.envDirectoryLabel.text()) |
152 args.append(self.envDirectoryLabel.text()) |
152 |
153 |
153 return ( |
154 return ( |
154 Utilities.toNativeSeparators(self.pythonExecPicker.text()), |
155 Utilities.toNativeSeparators(self.pythonExecPicker.text()), |
155 args, |
156 args, |
156 self.logCheckBox.isChecked(), |
157 self.logCheckBox.isChecked(), |
157 ) |
158 ) |