src/eric7/VirtualEnv/VirtualenvConfigurationDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
29 class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog): 29 class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog):
30 """ 30 """
31 Class implementing a dialog to enter the parameters for the 31 Class implementing a dialog to enter the parameters for the
32 virtual environment. 32 virtual environment.
33 """ 33 """
34
34 def __init__(self, baseDir="", parent=None): 35 def __init__(self, baseDir="", parent=None):
35 """ 36 """
36 Constructor 37 Constructor
37 38
38 @param baseDir base directory for the virtual environments 39 @param baseDir base directory for the virtual environments
39 @type str 40 @type str
40 @param parent reference to the parent widget 41 @param parent reference to the parent widget
41 @type QWidget 42 @type QWidget
42 """ 43 """
43 super().__init__(parent) 44 super().__init__(parent)
44 self.setupUi(self) 45 self.setupUi(self)
45 46
46 if not baseDir: 47 if not baseDir:
47 baseDir = Utilities.getHomeDir() 48 baseDir = Utilities.getHomeDir()
48 self.__envBaseDir = baseDir 49 self.__envBaseDir = baseDir
49 50
50 self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 51 self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
51 self.targetDirectoryPicker.setWindowTitle( 52 self.targetDirectoryPicker.setWindowTitle(
52 self.tr("Virtualenv Target Directory")) 53 self.tr("Virtualenv Target Directory")
54 )
53 self.targetDirectoryPicker.setText(baseDir) 55 self.targetDirectoryPicker.setText(baseDir)
54 self.targetDirectoryPicker.setDefaultDirectory(baseDir) 56 self.targetDirectoryPicker.setDefaultDirectory(baseDir)
55 57
56 self.extraSearchPathPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) 58 self.extraSearchPathPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
57 self.extraSearchPathPicker.setWindowTitle( 59 self.extraSearchPathPicker.setWindowTitle(
58 self.tr("Extra Search Path for setuptools/pip")) 60 self.tr("Extra Search Path for setuptools/pip")
61 )
59 self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir()) 62 self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir())
60 63
61 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) 64 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
62 self.pythonExecPicker.setWindowTitle( 65 self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter"))
63 self.tr("Python Interpreter")) 66 self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable())
64 self.pythonExecPicker.setDefaultDirectory( 67
65 Globals.getPythonExecutable()) 68 self.condaTargetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
66
67 self.condaTargetDirectoryPicker.setMode(
68 EricPathPickerModes.DIRECTORY_MODE)
69 self.condaTargetDirectoryPicker.setWindowTitle( 69 self.condaTargetDirectoryPicker.setWindowTitle(
70 self.tr("Conda Environment Location")) 70 self.tr("Conda Environment Location")
71 self.condaTargetDirectoryPicker.setDefaultDirectory( 71 )
72 Utilities.getHomeDir()) 72 self.condaTargetDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir())
73 73
74 self.condaCloneDirectoryPicker.setMode( 74 self.condaCloneDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
75 EricPathPickerModes.DIRECTORY_MODE)
76 self.condaCloneDirectoryPicker.setWindowTitle( 75 self.condaCloneDirectoryPicker.setWindowTitle(
77 self.tr("Conda Environment Location")) 76 self.tr("Conda Environment Location")
78 self.condaCloneDirectoryPicker.setDefaultDirectory( 77 )
79 Utilities.getHomeDir()) 78 self.condaCloneDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir())
80 79
81 self.condaRequirementsFilePicker.setMode( 80 self.condaRequirementsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
82 EricPathPickerModes.OPEN_FILE_MODE)
83 self.condaRequirementsFilePicker.setWindowTitle( 81 self.condaRequirementsFilePicker.setWindowTitle(
84 self.tr("Conda Requirements File")) 82 self.tr("Conda Requirements File")
85 self.condaRequirementsFilePicker.setDefaultDirectory( 83 )
86 Utilities.getHomeDir()) 84 self.condaRequirementsFilePicker.setDefaultDirectory(Utilities.getHomeDir())
87 self.condaRequirementsFilePicker.setFilters( 85 self.condaRequirementsFilePicker.setFilters(
88 self.tr("Text Files (*.txt);;All Files (*)")) 86 self.tr("Text Files (*.txt);;All Files (*)")
89 87 )
88
90 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""") 89 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""")
91 90
92 self.__virtualenvFound = False 91 self.__virtualenvFound = False
93 self.__pyvenvFound = False 92 self.__pyvenvFound = False
94 self.__condaFound = False 93 self.__condaFound = False
95 self.buttonBox.button( 94 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
96 QDialogButtonBox.StandardButton.Ok).setEnabled(False) 95
97
98 self.__mandatoryStyleSheet = ( 96 self.__mandatoryStyleSheet = (
99 "QLineEdit {border: 2px solid; border-color: #dd8888}" 97 "QLineEdit {border: 2px solid; border-color: #dd8888}"
100 if ericApp().usesDarkPalette() else 98 if ericApp().usesDarkPalette()
101 "QLineEdit {border: 2px solid; border-color: #800000}" 99 else "QLineEdit {border: 2px solid; border-color: #800000}"
102 ) 100 )
103 self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet) 101 self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet)
104 self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet) 102 self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet)
105 self.condaTargetDirectoryPicker.setStyleSheet( 103 self.condaTargetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet)
106 self.__mandatoryStyleSheet)
107 self.condaNameEdit.setStyleSheet(self.__mandatoryStyleSheet) 104 self.condaNameEdit.setStyleSheet(self.__mandatoryStyleSheet)
108 105
109 self.__setVirtualenvVersion() 106 self.__setVirtualenvVersion()
110 self.__setPyvenvVersion() 107 self.__setPyvenvVersion()
111 self.__setCondaVersion() 108 self.__setCondaVersion()
112 if self.__pyvenvFound: 109 if self.__pyvenvFound:
113 self.pyvenvButton.setChecked(True) 110 self.pyvenvButton.setChecked(True)
114 elif self.__virtualenvFound: 111 elif self.__virtualenvFound:
115 self.virtualenvButton.setChecked(True) 112 self.virtualenvButton.setChecked(True)
116 elif self.__condaFound: 113 elif self.__condaFound:
117 self.condaButton.setChecked(True) 114 self.condaButton.setChecked(True)
118 115
119 self.condaInsecureCheckBox.setEnabled( 116 self.condaInsecureCheckBox.setEnabled(
120 CondaInterface.condaVersion() >= (4, 3, 18)) 117 CondaInterface.condaVersion() >= (4, 3, 18)
121 118 )
119
122 msh = self.minimumSizeHint() 120 msh = self.minimumSizeHint()
123 self.resize(max(self.width(), msh.width()), msh.height()) 121 self.resize(max(self.width(), msh.width()), msh.height())
124 122
125 def __updateOK(self): 123 def __updateOK(self):
126 """ 124 """
127 Private method to update the enabled status of the OK button. 125 Private method to update the enabled status of the OK button.
128 """ 126 """
129 if self.virtualenvButton.isChecked() or self.pyvenvButton.isChecked(): 127 if self.virtualenvButton.isChecked() or self.pyvenvButton.isChecked():
130 enable = ( 128 enable = (
131 (self.__virtualenvFound or self.__pyvenvFound) and 129 (self.__virtualenvFound or self.__pyvenvFound)
132 bool(self.targetDirectoryPicker.text()) and 130 and bool(self.targetDirectoryPicker.text())
133 bool(self.nameEdit.text()) 131 and bool(self.nameEdit.text())
134 ) 132 )
135 enable &= self.targetDirectoryPicker.text() != self.__envBaseDir 133 enable &= self.targetDirectoryPicker.text() != self.__envBaseDir
136 self.buttonBox.button( 134 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
137 QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
138 elif self.condaButton.isChecked(): 135 elif self.condaButton.isChecked():
139 enable = ( 136 enable = bool(self.condaNameEdit.text()) or bool(
140 bool(self.condaNameEdit.text()) or 137 self.condaTargetDirectoryPicker.text()
141 bool(self.condaTargetDirectoryPicker.text())
142 ) 138 )
143 if self.condaSpecialsGroup.isChecked(): 139 if self.condaSpecialsGroup.isChecked():
144 if self.condaCloneButton.isChecked(): 140 if self.condaCloneButton.isChecked():
145 enable &= ( 141 enable &= bool(self.condaCloneNameEdit.text()) or bool(
146 bool(self.condaCloneNameEdit.text()) or 142 self.condaCloneDirectoryPicker.text()
147 bool(self.condaCloneDirectoryPicker.text())
148 ) 143 )
149 elif self.condaRequirementsButton.isChecked(): 144 elif self.condaRequirementsButton.isChecked():
150 enable &= bool(self.condaRequirementsFilePicker.text()) 145 enable &= bool(self.condaRequirementsFilePicker.text())
151 self.buttonBox.button( 146 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
152 QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
153 else: 147 else:
154 self.buttonBox.button( 148 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
155 QDialogButtonBox.StandardButton.Ok).setEnabled(False) 149
156
157 def __updateUi(self): 150 def __updateUi(self):
158 """ 151 """
159 Private method to update the UI depending on the selected 152 Private method to update the UI depending on the selected
160 virtual environment creator (virtualenv or pyvenv). 153 virtual environment creator (virtualenv or pyvenv).
161 """ 154 """
171 self.versionComboBox.setEnabled(enable) 164 self.versionComboBox.setEnabled(enable)
172 self.unzipCheckBox.setEnabled(enable) 165 self.unzipCheckBox.setEnabled(enable)
173 self.noSetuptoolsCheckBox.setEnabled(enable) 166 self.noSetuptoolsCheckBox.setEnabled(enable)
174 self.symlinkCheckBox.setEnabled(not enable) 167 self.symlinkCheckBox.setEnabled(not enable)
175 self.upgradeCheckBox.setEnabled(not enable) 168 self.upgradeCheckBox.setEnabled(not enable)
176 169
177 # conda page 170 # conda page
178 enable = not self.condaSpecialsGroup.isChecked() 171 enable = not self.condaSpecialsGroup.isChecked()
179 self.condaPackagesEdit.setEnabled(enable) 172 self.condaPackagesEdit.setEnabled(enable)
180 self.condaPythonEdit.setEnabled(enable) 173 self.condaPythonEdit.setEnabled(enable)
181 self.condaInsecureCheckBox.setEnabled( 174 self.condaInsecureCheckBox.setEnabled(
182 enable and CondaInterface.condaVersion() >= (4, 3, 18)) 175 enable and CondaInterface.condaVersion() >= (4, 3, 18)
176 )
183 self.condaDryrunCheckBox.setEnabled(enable) 177 self.condaDryrunCheckBox.setEnabled(enable)
184 178
185 # select page 179 # select page
186 if self.condaButton.isChecked(): 180 if self.condaButton.isChecked():
187 self.venvStack.setCurrentWidget(self.condaPage) 181 self.venvStack.setCurrentWidget(self.condaPage)
188 else: 182 else:
189 self.venvStack.setCurrentWidget(self.venvPage) 183 self.venvStack.setCurrentWidget(self.venvPage)
190 184
191 @pyqtSlot(str) 185 @pyqtSlot(str)
192 def on_nameEdit_textChanged(self, txt): 186 def on_nameEdit_textChanged(self, txt):
193 """ 187 """
194 Private slot handling a change of the virtual environment name. 188 Private slot handling a change of the virtual environment name.
195 189
196 @param txt name of the virtual environment 190 @param txt name of the virtual environment
197 @type str 191 @type str
198 """ 192 """
199 self.__updateOK() 193 self.__updateOK()
200 194
201 @pyqtSlot(str) 195 @pyqtSlot(str)
202 def on_targetDirectoryPicker_textChanged(self, txt): 196 def on_targetDirectoryPicker_textChanged(self, txt):
203 """ 197 """
204 Private slot handling a change of the target directory. 198 Private slot handling a change of the target directory.
205 199
206 @param txt target directory 200 @param txt target directory
207 @type str 201 @type str
208 """ 202 """
209 self.__updateOK() 203 self.__updateOK()
210 204
211 @pyqtSlot(str) 205 @pyqtSlot(str)
212 def on_pythonExecPicker_textChanged(self, txt): 206 def on_pythonExecPicker_textChanged(self, txt):
213 """ 207 """
214 Private slot to react to a change of the Python executable. 208 Private slot to react to a change of the Python executable.
215 209
216 @param txt contents of the picker's line edit 210 @param txt contents of the picker's line edit
217 @type str 211 @type str
218 """ 212 """
219 self.__setVirtualenvVersion() 213 self.__setVirtualenvVersion()
220 self.__setPyvenvVersion() 214 self.__setPyvenvVersion()
221 self.__updateOK() 215 self.__updateOK()
222 216
223 @pyqtSlot(bool) 217 @pyqtSlot(bool)
224 def on_virtualenvButton_toggled(self, checked): 218 def on_virtualenvButton_toggled(self, checked):
225 """ 219 """
226 Private slot to react to the selection of 'virtualenv'. 220 Private slot to react to the selection of 'virtualenv'.
227 221
228 @param checked state of the checkbox 222 @param checked state of the checkbox
229 @type bool 223 @type bool
230 """ 224 """
231 self.__updateUi() 225 self.__updateUi()
232 226
233 @pyqtSlot(bool) 227 @pyqtSlot(bool)
234 def on_pyvenvButton_toggled(self, checked): 228 def on_pyvenvButton_toggled(self, checked):
235 """ 229 """
236 Private slot to react to the selection of 'pyvenv'. 230 Private slot to react to the selection of 'pyvenv'.
237 231
238 @param checked state of the checkbox 232 @param checked state of the checkbox
239 @type bool 233 @type bool
240 """ 234 """
241 self.__updateUi() 235 self.__updateUi()
242 236
243 @pyqtSlot(bool) 237 @pyqtSlot(bool)
244 def on_condaButton_toggled(self, checked): 238 def on_condaButton_toggled(self, checked):
245 """ 239 """
246 Private slot to react to the selection of 'conda'. 240 Private slot to react to the selection of 'conda'.
247 241
248 @param checked state of the checkbox 242 @param checked state of the checkbox
249 @type bool 243 @type bool
250 """ 244 """
251 self.__updateUi() 245 self.__updateUi()
252 246
253 @pyqtSlot(str) 247 @pyqtSlot(str)
254 def on_condaNameEdit_textChanged(self, txt): 248 def on_condaNameEdit_textChanged(self, txt):
255 """ 249 """
256 Private slot handling a change of the conda environment name. 250 Private slot handling a change of the conda environment name.
257 251
258 @param txt environment name 252 @param txt environment name
259 @type str 253 @type str
260 """ 254 """
261 self.__updateOK() 255 self.__updateOK()
262 256
263 @pyqtSlot(str) 257 @pyqtSlot(str)
264 def on_condaTargetDirectoryPicker_textChanged(self, txt): 258 def on_condaTargetDirectoryPicker_textChanged(self, txt):
265 """ 259 """
266 Private slot handling a change of the conda target directory. 260 Private slot handling a change of the conda target directory.
267 261
268 @param txt target directory 262 @param txt target directory
269 @type str 263 @type str
270 """ 264 """
271 self.__updateOK() 265 self.__updateOK()
272 266
273 @pyqtSlot() 267 @pyqtSlot()
274 def on_condaSpecialsGroup_clicked(self): 268 def on_condaSpecialsGroup_clicked(self):
275 """ 269 """
276 Private slot handling the selection of the specials group. 270 Private slot handling the selection of the specials group.
277 """ 271 """
278 self.__updateOK() 272 self.__updateOK()
279 self.__updateUi() 273 self.__updateUi()
280 274
281 @pyqtSlot(str) 275 @pyqtSlot(str)
282 def on_condaCloneNameEdit_textChanged(self, txt): 276 def on_condaCloneNameEdit_textChanged(self, txt):
283 """ 277 """
284 Private slot handling a change of the conda source environment name. 278 Private slot handling a change of the conda source environment name.
285 279
286 @param txt name of the environment to be cloned 280 @param txt name of the environment to be cloned
287 @type str 281 @type str
288 """ 282 """
289 self.__updateOK() 283 self.__updateOK()
290 284
291 @pyqtSlot(str) 285 @pyqtSlot(str)
292 def on_condaCloneDirectoryPicker_textChanged(self, txt): 286 def on_condaCloneDirectoryPicker_textChanged(self, txt):
293 """ 287 """
294 Private slot handling a change of the cloned from directory. 288 Private slot handling a change of the cloned from directory.
295 289
296 @param txt target directory 290 @param txt target directory
297 @type str 291 @type str
298 """ 292 """
299 self.__updateOK() 293 self.__updateOK()
300 294
301 @pyqtSlot() 295 @pyqtSlot()
302 def on_condaCloneButton_clicked(self): 296 def on_condaCloneButton_clicked(self):
303 """ 297 """
304 Private slot handling the selection of the clone button. 298 Private slot handling the selection of the clone button.
305 """ 299 """
306 self.__updateOK() 300 self.__updateOK()
307 301
308 @pyqtSlot() 302 @pyqtSlot()
309 def on_condaRequirementsButton_clicked(self): 303 def on_condaRequirementsButton_clicked(self):
310 """ 304 """
311 Private slot handling the selection of the requirements button. 305 Private slot handling the selection of the requirements button.
312 """ 306 """
313 self.__updateOK() 307 self.__updateOK()
314 308
315 @pyqtSlot(str) 309 @pyqtSlot(str)
316 def on_condaRequirementsFilePicker_textChanged(self, txt): 310 def on_condaRequirementsFilePicker_textChanged(self, txt):
317 """ 311 """
318 Private slot handling a change of the requirements file entry. 312 Private slot handling a change of the requirements file entry.
319 313
320 @param txt current text of the requirements file entry 314 @param txt current text of the requirements file entry
321 @type str 315 @type str
322 """ 316 """
323 self.__updateOK() 317 self.__updateOK()
324 318
325 def __setVirtualenvVersion(self): 319 def __setVirtualenvVersion(self):
326 """ 320 """
327 Private method to determine the virtualenv version and set the 321 Private method to determine the virtualenv version and set the
328 respective label. 322 respective label.
329 """ 323 """
330 calls = [] 324 calls = []
331 if self.pythonExecPicker.text(): 325 if self.pythonExecPicker.text():
332 calls.append((self.pythonExecPicker.text(), 326 calls.append(
333 ["-m", "virtualenv", "--version"])) 327 (self.pythonExecPicker.text(), ["-m", "virtualenv", "--version"])
334 calls.extend([ 328 )
335 (Globals.getPythonExecutable(), ["-m", "virtualenv", "--version"]), 329 calls.extend(
336 ("virtualenv", ["--version"]), 330 [
337 ]) 331 (Globals.getPythonExecutable(), ["-m", "virtualenv", "--version"]),
338 332 ("virtualenv", ["--version"]),
333 ]
334 )
335
339 proc = QProcess() 336 proc = QProcess()
340 for prog, args in calls: 337 for prog, args in calls:
341 proc.start(prog, args) 338 proc.start(prog, args)
342 339
343 if not proc.waitForStarted(5000): 340 if not proc.waitForStarted(5000):
344 # try next entry 341 # try next entry
345 continue 342 continue
346 343
347 if not proc.waitForFinished(5000): 344 if not proc.waitForFinished(5000):
348 # process hangs, kill it 345 # process hangs, kill it
349 QTimer.singleShot(2000, proc.kill) 346 QTimer.singleShot(2000, proc.kill)
350 proc.waitForFinished(3000) 347 proc.waitForFinished(3000)
351 version = self.tr('<virtualenv did not finish within 5s.>') 348 version = self.tr("<virtualenv did not finish within 5s.>")
352 self.__virtualenvFound = False 349 self.__virtualenvFound = False
353 break 350 break
354 351
355 if proc.exitCode() != 0: 352 if proc.exitCode() != 0:
356 # returned with error code, try next 353 # returned with error code, try next
357 continue 354 continue
358 355
359 output = str(proc.readAllStandardOutput(), 356 output = str(
360 Preferences.getSystem("IOEncoding"), 357 proc.readAllStandardOutput(),
361 'replace').strip() 358 Preferences.getSystem("IOEncoding"),
359 "replace",
360 ).strip()
362 match = re.match(self.__versionRe, output) 361 match = re.match(self.__versionRe, output)
363 if match: 362 if match:
364 self.__virtualenvFound = True 363 self.__virtualenvFound = True
365 version = match.group(1) 364 version = match.group(1)
366 break 365 break
367 else: 366 else:
368 self.__virtualenvFound = False 367 self.__virtualenvFound = False
369 version = self.tr('<No suitable virtualenv found.>') 368 version = self.tr("<No suitable virtualenv found.>")
370 369
371 self.virtualenvButton.setText(self.tr( 370 self.virtualenvButton.setText(
372 "virtualenv Version: {0}".format(version))) 371 self.tr("virtualenv Version: {0}".format(version))
372 )
373 self.virtualenvButton.setEnabled(self.__virtualenvFound) 373 self.virtualenvButton.setEnabled(self.__virtualenvFound)
374 if not self.__virtualenvFound: 374 if not self.__virtualenvFound:
375 self.virtualenvButton.setChecked(False) 375 self.virtualenvButton.setChecked(False)
376 376
377 def __setPyvenvVersion(self): 377 def __setPyvenvVersion(self):
378 """ 378 """
379 Private method to determine the pyvenv version and set the respective 379 Private method to determine the pyvenv version and set the respective
380 label. 380 label.
381 """ 381 """
382 calls = [] 382 calls = []
383 if self.pythonExecPicker.text(): 383 if self.pythonExecPicker.text():
384 calls.append((self.pythonExecPicker.text(), 384 calls.append((self.pythonExecPicker.text(), ["-m", "venv"]))
385 ["-m", "venv"])) 385 calls.extend(
386 calls.extend([ 386 [
387 (Globals.getPythonExecutable(), ["-m", "venv"]), 387 (Globals.getPythonExecutable(), ["-m", "venv"]),
388 ("python3", ["-m", "venv"]), 388 ("python3", ["-m", "venv"]),
389 ("python", ["-m", "venv"]), 389 ("python", ["-m", "venv"]),
390 ]) 390 ]
391 391 )
392
392 proc = QProcess() 393 proc = QProcess()
393 for prog, args in calls: 394 for prog, args in calls:
394 proc.start(prog, args) 395 proc.start(prog, args)
395 396
396 if not proc.waitForStarted(5000): 397 if not proc.waitForStarted(5000):
397 # try next entry 398 # try next entry
398 continue 399 continue
399 400
400 if not proc.waitForFinished(5000): 401 if not proc.waitForFinished(5000):
401 # process hangs, kill it 402 # process hangs, kill it
402 QTimer.singleShot(2000, proc.kill) 403 QTimer.singleShot(2000, proc.kill)
403 proc.waitForFinished(3000) 404 proc.waitForFinished(3000)
404 version = self.tr('<pyvenv did not finish within 5s.>') 405 version = self.tr("<pyvenv did not finish within 5s.>")
405 self.__pyvenvFound = False 406 self.__pyvenvFound = False
406 break 407 break
407 408
408 if proc.exitCode() not in [0, 2]: 409 if proc.exitCode() not in [0, 2]:
409 # returned with error code, try next 410 # returned with error code, try next
410 continue 411 continue
411 412
412 proc.start(prog, ["--version"]) 413 proc.start(prog, ["--version"])
413 proc.waitForFinished(5000) 414 proc.waitForFinished(5000)
414 output = str(proc.readAllStandardOutput(), 415 output = str(
415 Preferences.getSystem("IOEncoding"), 416 proc.readAllStandardOutput(),
416 'replace').strip() 417 Preferences.getSystem("IOEncoding"),
418 "replace",
419 ).strip()
417 match = re.match(self.__versionRe, output) 420 match = re.match(self.__versionRe, output)
418 if match: 421 if match:
419 self.__pyvenvFound = True 422 self.__pyvenvFound = True
420 version = match.group(1) 423 version = match.group(1)
421 break 424 break
422 else: 425 else:
423 self.__pyvenvFound = False 426 self.__pyvenvFound = False
424 version = self.tr('<No suitable pyvenv found.>') 427 version = self.tr("<No suitable pyvenv found.>")
425 428
426 self.pyvenvButton.setText(self.tr( 429 self.pyvenvButton.setText(self.tr("pyvenv Version: {0}".format(version)))
427 "pyvenv Version: {0}".format(version)))
428 self.pyvenvButton.setEnabled(self.__pyvenvFound) 430 self.pyvenvButton.setEnabled(self.__pyvenvFound)
429 if not self.__pyvenvFound: 431 if not self.__pyvenvFound:
430 self.pyvenvButton.setChecked(False) 432 self.pyvenvButton.setChecked(False)
431 433
432 def __setCondaVersion(self): 434 def __setCondaVersion(self):
433 """ 435 """
434 Private method to determine the conda version and set the respective 436 Private method to determine the conda version and set the respective
435 label. 437 label.
436 """ 438 """
437 self.__condaFound = bool(CondaInterface.condaVersion()) 439 self.__condaFound = bool(CondaInterface.condaVersion())
438 self.condaButton.setText(self.tr( 440 self.condaButton.setText(
439 "conda Version: {0}".format(CondaInterface.condaVersionStr()))) 441 self.tr("conda Version: {0}".format(CondaInterface.condaVersionStr()))
442 )
440 self.condaButton.setEnabled(self.__condaFound) 443 self.condaButton.setEnabled(self.__condaFound)
441 if not self.__condaFound: 444 if not self.__condaFound:
442 self.condaButton.setChecked(False) 445 self.condaButton.setChecked(False)
443 446
444 def __generateTargetDir(self): 447 def __generateTargetDir(self):
445 """ 448 """
446 Private method to generate a valid target directory path. 449 Private method to generate a valid target directory path.
447 450
448 @return target directory path 451 @return target directory path
449 @rtype str 452 @rtype str
450 """ 453 """
451 targetDirectory = Utilities.toNativeSeparators( 454 targetDirectory = Utilities.toNativeSeparators(
452 self.targetDirectoryPicker.text()) 455 self.targetDirectoryPicker.text()
456 )
453 if not os.path.isabs(targetDirectory): 457 if not os.path.isabs(targetDirectory):
454 targetDirectory = os.path.join(os.path.expanduser("~"), 458 targetDirectory = os.path.join(os.path.expanduser("~"), targetDirectory)
455 targetDirectory)
456 return targetDirectory 459 return targetDirectory
457 460
458 def __generateArguments(self): 461 def __generateArguments(self):
459 """ 462 """
460 Private method to generate the process arguments. 463 Private method to generate the process arguments.
461 464
462 @return process arguments 465 @return process arguments
463 @rtype list of str 466 @rtype list of str
464 """ 467 """
465 args = [] 468 args = []
466 if self.condaButton.isChecked(): 469 if self.condaButton.isChecked():
467 if bool(self.condaNameEdit.text()): 470 if bool(self.condaNameEdit.text()):
468 args.extend(["--name", self.condaNameEdit.text()]) 471 args.extend(["--name", self.condaNameEdit.text()])
469 if bool(self.condaTargetDirectoryPicker.text()): 472 if bool(self.condaTargetDirectoryPicker.text()):
470 args.extend(["--prefix", 473 args.extend(["--prefix", self.condaTargetDirectoryPicker.text()])
471 self.condaTargetDirectoryPicker.text()])
472 if self.condaSpecialsGroup.isChecked(): 474 if self.condaSpecialsGroup.isChecked():
473 if self.condaCloneButton.isChecked(): 475 if self.condaCloneButton.isChecked():
474 if bool(self.condaCloneNameEdit.text()): 476 if bool(self.condaCloneNameEdit.text()):
475 args.extend( 477 args.extend(["--clone", self.condaCloneNameEdit.text()])
476 ["--clone", self.condaCloneNameEdit.text()]
477 )
478 elif bool(self.condaCloneDirectoryPicker.text()): 478 elif bool(self.condaCloneDirectoryPicker.text()):
479 args.extend(["--clone", 479 args.extend(["--clone", self.condaCloneDirectoryPicker.text()])
480 self.condaCloneDirectoryPicker.text()])
481 elif self.condaRequirementsButton.isChecked(): 480 elif self.condaRequirementsButton.isChecked():
482 args.extend( 481 args.extend(["--file", self.condaRequirementsFilePicker.text()])
483 ["--file", self.condaRequirementsFilePicker.text()]
484 )
485 if self.condaInsecureCheckBox.isChecked(): 482 if self.condaInsecureCheckBox.isChecked():
486 args.append("--insecure") 483 args.append("--insecure")
487 if self.condaDryrunCheckBox.isChecked(): 484 if self.condaDryrunCheckBox.isChecked():
488 args.append("--dry-run") 485 args.append("--dry-run")
489 if not self.condaSpecialsGroup.isChecked(): 486 if not self.condaSpecialsGroup.isChecked():
490 if bool(self.condaPythonEdit.text()): 487 if bool(self.condaPythonEdit.text()):
491 args.append("python={0}".format( 488 args.append("python={0}".format(self.condaPythonEdit.text()))
492 self.condaPythonEdit.text()))
493 if bool(self.condaPackagesEdit.text()): 489 if bool(self.condaPackagesEdit.text()):
494 args.extend(self.condaPackagesEdit.text().split()) 490 args.extend(self.condaPackagesEdit.text().split())
495 else: 491 else:
496 if self.virtualenvButton.isChecked(): 492 if self.virtualenvButton.isChecked():
497 if self.extraSearchPathPicker.text(): 493 if self.extraSearchPathPicker.text():
498 args.append("--extra-search-dir={0}".format( 494 args.append(
499 Utilities.toNativeSeparators( 495 "--extra-search-dir={0}".format(
500 self.extraSearchPathPicker.text()))) 496 Utilities.toNativeSeparators(
497 self.extraSearchPathPicker.text()
498 )
499 )
500 )
501 if self.promptPrefixEdit.text(): 501 if self.promptPrefixEdit.text():
502 args.append("--prompt={0}".format( 502 args.append(
503 self.promptPrefixEdit.text().replace(" ", "_"))) 503 "--prompt={0}".format(
504 self.promptPrefixEdit.text().replace(" ", "_")
505 )
506 )
504 if self.pythonExecPicker.text(): 507 if self.pythonExecPicker.text():
505 args.append("--python={0}".format( 508 args.append(
506 Utilities.toNativeSeparators( 509 "--python={0}".format(
507 self.pythonExecPicker.text()))) 510 Utilities.toNativeSeparators(self.pythonExecPicker.text())
511 )
512 )
508 elif self.versionComboBox.currentText(): 513 elif self.versionComboBox.currentText():
509 args.append("--python=python{0}".format( 514 args.append(
510 self.versionComboBox.currentText())) 515 "--python=python{0}".format(self.versionComboBox.currentText())
516 )
511 if self.verbositySpinBox.value() == 1: 517 if self.verbositySpinBox.value() == 1:
512 args.append("--verbose") 518 args.append("--verbose")
513 elif self.verbositySpinBox.value() == -1: 519 elif self.verbositySpinBox.value() == -1:
514 args.append("--quiet") 520 args.append("--quiet")
515 if self.clearCheckBox.isChecked(): 521 if self.clearCheckBox.isChecked():
537 args.append("--symlinks") 543 args.append("--symlinks")
538 if self.upgradeCheckBox.isChecked(): 544 if self.upgradeCheckBox.isChecked():
539 args.append("--upgrade") 545 args.append("--upgrade")
540 targetDirectory = self.__generateTargetDir() 546 targetDirectory = self.__generateTargetDir()
541 args.append(targetDirectory) 547 args.append(targetDirectory)
542 548
543 return args 549 return args
544 550
545 def getData(self): 551 def getData(self):
546 """ 552 """
547 Public method to retrieve the dialog data. 553 Public method to retrieve the dialog data.
548 554
549 @return dictionary containing the data for the two environment 555 @return dictionary containing the data for the two environment
550 variants. The keys for both variants are 'arguments' containing the 556 variants. The keys for both variants are 'arguments' containing the
551 command line arguments, 'logicalName' containing the environment 557 command line arguments, 'logicalName' containing the environment
552 name to be used with the virtual env manager and 'envType' 558 name to be used with the virtual env manager and 'envType'
553 containing the environment type (virtualenv, pyvenv or conda). The 559 containing the environment type (virtualenv, pyvenv or conda). The
564 resultDict = { 570 resultDict = {
565 "arguments": args, 571 "arguments": args,
566 "logicalName": self.nameEdit.text(), 572 "logicalName": self.nameEdit.text(),
567 } 573 }
568 if self.condaButton.isChecked(): 574 if self.condaButton.isChecked():
569 resultDict.update({ 575 resultDict.update(
570 "envType": "conda", 576 {
571 "command": "create", 577 "envType": "conda",
572 }) 578 "command": "create",
579 }
580 )
573 else: 581 else:
574 resultDict.update({ 582 resultDict.update(
575 "envType": ("pyvenv" if self.pyvenvButton.isChecked() else 583 {
576 "virtualenv"), 584 "envType": (
577 "openTarget": self.openCheckBox.isChecked(), 585 "pyvenv" if self.pyvenvButton.isChecked() else "virtualenv"
578 "createLog": self.logCheckBox.isChecked(), 586 ),
579 "createScript": self.scriptCheckBox.isChecked(), 587 "openTarget": self.openCheckBox.isChecked(),
580 "targetDirectory": self.__generateTargetDir(), 588 "createLog": self.logCheckBox.isChecked(),
581 "pythonExe": Utilities.toNativeSeparators( 589 "createScript": self.scriptCheckBox.isChecked(),
582 self.pythonExecPicker.text()), 590 "targetDirectory": self.__generateTargetDir(),
583 }) 591 "pythonExe": Utilities.toNativeSeparators(
584 592 self.pythonExecPicker.text()
593 ),
594 }
595 )
596
585 return resultDict 597 return resultDict

eric ide

mercurial