VirtualEnv/VirtualenvManager.py

changeset 6349
17b3c75913de
parent 6341
a00e63f6d766
child 6362
ec32d1d7f525
equal deleted inserted replaced
6348:d6c0b8ab1fc6 6349:17b3c75913de
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 import os 12 import os
13 import sys 13 import sys
14 import shutil 14 import shutil
15 import json
16 import copy
15 17
16 from PyQt5.QtCore import pyqtSlot, QObject 18 from PyQt5.QtCore import pyqtSlot, QObject
17 from PyQt5.QtWidgets import QDialog 19 from PyQt5.QtWidgets import QDialog
18 20
19 from E5Gui import E5MessageBox 21 from E5Gui import E5MessageBox
34 """ 36 """
35 super(VirtualenvManager, self).__init__(parent) 37 super(VirtualenvManager, self).__init__(parent)
36 38
37 self.__ui = parent 39 self.__ui = parent
38 40
41 self.__loadSettings()
42
43 self.__virtualenvManagerDialog = None
44
45 def __loadSettings(self):
46 """
47 Private slot to load the virtual environments.
48 """
49 venvString = Preferences.Prefs.settings.value(
50 "PyVenv/VirtualEnvironments", "{}") # __IGNORE_WARNING_M613__
51 environments = json.loads(venvString)
52
39 self.__virtualEnvironments = {} 53 self.__virtualEnvironments = {}
40 self.__virtualEnvironmentInterpreters = {} 54 # each environment entry is a dictionary:
41 environments = Preferences.toDict(Preferences.Prefs.settings.value( 55 # path: the directory of the virtual environment
42 "PyVenv/Environments", {})) 56 # (empty for a global environment)
43 interpreters = Preferences.toDict(Preferences.Prefs.settings.value( 57 # interpreter: the path of the Python interpreter
44 "PyVenv/Interpreters", {})) 58 # variant: Python variant (2 or 3)
45 for venvName, venvExe in interpreters.items(): 59 #
46 # remove all environments, that don't exist anymore 60 for venvName in environments:
47 if os.access(venvExe, os.X_OK): 61 interpreter = environments[venvName]["interpreter"]
48 self.__virtualEnvironmentInterpreters[venvName] = venvExe 62 if os.access(interpreter, os.X_OK):
49 self.__virtualEnvironments[venvName] = environments[venvName] 63 self.__virtualEnvironments[venvName] = environments[venvName]
50 64
65 # check, if the interpreter used to run eric is in the environments
51 defaultPy = sys.executable.replace("w.exe", ".exe") 66 defaultPy = sys.executable.replace("w.exe", ".exe")
52 if defaultPy not in self.__virtualEnvironmentInterpreters.values(): 67 found = False
53 self.__virtualEnvironmentInterpreters["<default>"] = defaultPy 68 for venvName in self.__virtualEnvironments:
54 self.__virtualEnvironments["<default>"] = "" 69 if (defaultPy ==
55 70 self.__virtualEnvironments[venvName]["interpreter"]):
56 self.__updateSettings() 71 found = True
57 72 break
58 self.__virtualenvManagerDialog = None 73 if not found:
59 74 # add an environment entry for the default interpreter
60 def __updateSettings(self): 75 self.__virtualEnvironments["<default>"] = {
76 "path": "",
77 "interpreter": defaultPy,
78 "variant": sys.version_info[0],
79 }
80
81 self.__saveSettings()
82
83 def __saveSettings(self):
61 """ 84 """
62 Private slot to save the virtual environments. 85 Private slot to save the virtual environments.
63 """ 86 """
64 Preferences.Prefs.settings.setValue( 87 Preferences.Prefs.settings.setValue(
65 "PyVenv/Environments", self.__virtualEnvironments) 88 "PyVenv/VirtualEnvironments",
66 Preferences.Prefs.settings.setValue( 89 json.dumps(self.__virtualEnvironments)
67 "PyVenv/Interpreters", self.__virtualEnvironmentInterpreters) 90 )
68 91
69 @pyqtSlot() 92 @pyqtSlot()
70 def createVirtualEnv(self): 93 def createVirtualEnv(self):
71 """ 94 """
72 Public slot to create a new virtual environment. 95 Public slot to create a new virtual environment.
86 self) 109 self)
87 dia.show() 110 dia.show()
88 dia.start(args) 111 dia.start(args)
89 dia.exec_() 112 dia.exec_()
90 113
91 def addVirtualEnv(self, venvName, venvDirectory, venvInterpreter=""): 114 def addVirtualEnv(self, venvName, venvDirectory, venvInterpreter="",
115 venvVariant=3):
92 """ 116 """
93 Public method to add a virtual environment. 117 Public method to add a virtual environment.
94 118
95 @param venvName logical name for the virtual environment 119 @param venvName logical name for the virtual environment
96 @type str 120 @type str
97 @param venvDirectory directory of the virtual environment 121 @param venvDirectory directory of the virtual environment
98 @type str 122 @type str
99 @param venvInterpreter interpreter of the virtual environment 123 @param venvInterpreter interpreter of the virtual environment
124 @type str
125 @param venvVariant Python variant of the virtual environment
126 @type int
100 """ 127 """
101 if venvName in self.__virtualEnvironments: 128 if venvName in self.__virtualEnvironments:
102 ok = E5MessageBox.yesNo( 129 ok = E5MessageBox.yesNo(
103 None, 130 None,
104 self.tr("Add Virtual Environment"), 131 self.tr("Add Virtual Environment"),
112 if not venvInterpreter: 139 if not venvInterpreter:
113 from .VirtualenvInterpreterSelectionDialog import \ 140 from .VirtualenvInterpreterSelectionDialog import \
114 VirtualenvInterpreterSelectionDialog 141 VirtualenvInterpreterSelectionDialog
115 dlg = VirtualenvInterpreterSelectionDialog(venvName, venvDirectory) 142 dlg = VirtualenvInterpreterSelectionDialog(venvName, venvDirectory)
116 if dlg.exec_() == QDialog.Accepted: 143 if dlg.exec_() == QDialog.Accepted:
117 venvInterpreter = dlg.getData() 144 venvInterpreter, venvVariant = dlg.getData()
118 145
119 if venvInterpreter: 146 if venvInterpreter:
120 self.__virtualEnvironmentInterpreters[venvName] = venvInterpreter 147 self.__virtualEnvironments[venvName] = {
121 self.__virtualEnvironments[venvName] = venvDirectory 148 "path": venvDirectory,
149 "interpreter": venvInterpreter,
150 "variant": venvVariant,
151 }
122 152
123 self.__updateSettings() 153 self.__saveSettings()
124 154
125 if self.__virtualenvManagerDialog: 155 if self.__virtualenvManagerDialog:
126 self.__virtualenvManagerDialog.refresh() 156 self.__virtualenvManagerDialog.refresh()
127 157
128 def setVirtualEnv(self, venvName, venvDirectory, venvInterpreter=""): 158 def setVirtualEnv(self, venvName, venvDirectory, venvInterpreter,
159 venvVariant):
129 """ 160 """
130 Public method to change a virtual environment. 161 Public method to change a virtual environment.
131 162
132 @param venvName logical name of the virtual environment 163 @param venvName logical name of the virtual environment
133 @type str 164 @type str
134 @param venvDirectory directory of the virtual environment 165 @param venvDirectory directory of the virtual environment
135 @type str 166 @type str
136 @param venvInterpreter interpreter of the virtual environment 167 @param venvInterpreter interpreter of the virtual environment
168 @type str
169 @param venvVariant Python variant of the virtual environment
170 @type int
137 """ 171 """
138 if venvName not in self.__virtualEnvironments: 172 if venvName not in self.__virtualEnvironments:
139 E5MessageBox.yesNo( 173 E5MessageBox.yesNo(
140 None, 174 None,
141 self.tr("Change Virtual Environment"), 175 self.tr("Change Virtual Environment"),
143 """ exist. Aborting!""") 177 """ exist. Aborting!""")
144 .format(venvName), 178 .format(venvName),
145 icon=E5MessageBox.Warning) 179 icon=E5MessageBox.Warning)
146 return 180 return
147 181
148 self.__virtualEnvironmentInterpreters[venvName] = venvInterpreter 182 self.__virtualEnvironments[venvName] = {
149 self.__virtualEnvironments[venvName] = venvDirectory 183 "path": venvDirectory,
150 184 "interpreter": venvInterpreter,
151 self.__updateSettings() 185 "variant": venvVariant,
186 }
187
188 self.__saveSettings()
152 189
153 if self.__virtualenvManagerDialog: 190 if self.__virtualenvManagerDialog:
154 self.__virtualenvManagerDialog.refresh() 191 self.__virtualenvManagerDialog.refresh()
155 192
156 def renameVirtualEnv(self, oldVenvName, venvName, venvDirectory, 193 def renameVirtualEnv(self, oldVenvName, venvName, venvDirectory,
157 venvInterpreter): 194 venvInterpreter, venvVariant):
158 """ 195 """
159 Public method to substitute a virtual environment entry with a new 196 Public method to substitute a virtual environment entry with a new
160 name. 197 name.
161 198
162 @param oldVenvName old name of the virtual environment 199 @param oldVenvName old name of the virtual environment
164 @param venvName logical name for the virtual environment 201 @param venvName logical name for the virtual environment
165 @type str 202 @type str
166 @param venvDirectory directory of the virtual environment 203 @param venvDirectory directory of the virtual environment
167 @type str 204 @type str
168 @param venvInterpreter interpreter of the virtual environment 205 @param venvInterpreter interpreter of the virtual environment
206 @type str
207 @param venvVariant Python variant of the virtual environment
208 @type int
169 """ 209 """
170 if oldVenvName not in self.__virtualEnvironments: 210 if oldVenvName not in self.__virtualEnvironments:
171 E5MessageBox.yesNo( 211 E5MessageBox.yesNo(
172 None, 212 None,
173 self.tr("Rename Virtual Environment"), 213 self.tr("Rename Virtual Environment"),
176 .format(oldVenvName), 216 .format(oldVenvName),
177 icon=E5MessageBox.Warning) 217 icon=E5MessageBox.Warning)
178 return 218 return
179 219
180 del self.__virtualEnvironments[oldVenvName] 220 del self.__virtualEnvironments[oldVenvName]
181 del self.__virtualEnvironmentInterpreters[oldVenvName] 221 self.addVirtualEnv(venvName, venvDirectory, venvInterpreter,
182 self.addVirtualEnv(venvName, venvDirectory, venvInterpreter) 222 venvVariant)
183 223
184 def deleteVirtualEnvs(self, venvNames): 224 def deleteVirtualEnvs(self, venvNames):
185 """ 225 """
186 Public method to delete virtual environments from the list and disk. 226 Public method to delete virtual environments from the list and disk.
187 227
189 @type list of str 229 @type list of str
190 """ 230 """
191 venvMessages = [] 231 venvMessages = []
192 for venvName in venvNames: 232 for venvName in venvNames:
193 if venvName in self.__virtualEnvironments and \ 233 if venvName in self.__virtualEnvironments and \
194 bool(self.__virtualEnvironments[venvName]): 234 bool(self.__virtualEnvironments[venvName]["path"]):
195 venvMessages.append(self.tr("{0} - {1}").format( 235 venvMessages.append(self.tr("{0} - {1}").format(
196 venvName, self.__virtualEnvironments[venvName])) 236 venvName, self.__virtualEnvironments[venvName]["path"]))
197 if venvMessages: 237 if venvMessages:
198 from UI.DeleteFilesConfirmationDialog import \ 238 from UI.DeleteFilesConfirmationDialog import \
199 DeleteFilesConfirmationDialog 239 DeleteFilesConfirmationDialog
200 dlg = DeleteFilesConfirmationDialog( 240 dlg = DeleteFilesConfirmationDialog(
201 None, 241 None,
205 venvMessages 245 venvMessages
206 ) 246 )
207 if dlg.exec_() == QDialog.Accepted: 247 if dlg.exec_() == QDialog.Accepted:
208 for venvName in venvNames: 248 for venvName in venvNames:
209 if venvName in self.__virtualEnvironments and \ 249 if venvName in self.__virtualEnvironments and \
210 bool(self.__virtualEnvironments[venvName]): 250 bool(self.__virtualEnvironments[venvName]["path"]):
211 shutil.rmtree(self.__virtualEnvironments[venvName], 251 shutil.rmtree(
212 True) 252 self.__virtualEnvironments[venvName]["path"], True)
213 del self.__virtualEnvironments[venvName] 253 del self.__virtualEnvironments[venvName]
214 del self.__virtualEnvironmentInterpreters[venvName]
215 254
216 self.__updateSettings() 255 self.__saveSettings()
217 256
218 if self.__virtualenvManagerDialog: 257 if self.__virtualenvManagerDialog:
219 self.__virtualenvManagerDialog.refresh() 258 self.__virtualenvManagerDialog.refresh()
220 259
221 def removeVirtualEnvs(self, venvNames): 260 def removeVirtualEnvs(self, venvNames):
227 """ 266 """
228 venvMessages = [] 267 venvMessages = []
229 for venvName in venvNames: 268 for venvName in venvNames:
230 if venvName in self.__virtualEnvironments: 269 if venvName in self.__virtualEnvironments:
231 venvMessages.append(self.tr("{0} - {1}").format( 270 venvMessages.append(self.tr("{0} - {1}").format(
232 venvName, self.__virtualEnvironments[venvName])) 271 venvName, self.__virtualEnvironments[venvName]["path"]))
233 if venvMessages: 272 if venvMessages:
234 from UI.DeleteFilesConfirmationDialog import \ 273 from UI.DeleteFilesConfirmationDialog import \
235 DeleteFilesConfirmationDialog 274 DeleteFilesConfirmationDialog
236 dlg = DeleteFilesConfirmationDialog( 275 dlg = DeleteFilesConfirmationDialog(
237 None, 276 None,
242 ) 281 )
243 if dlg.exec_() == QDialog.Accepted: 282 if dlg.exec_() == QDialog.Accepted:
244 for venvName in venvNames: 283 for venvName in venvNames:
245 if venvName in self.__virtualEnvironments: 284 if venvName in self.__virtualEnvironments:
246 del self.__virtualEnvironments[venvName] 285 del self.__virtualEnvironments[venvName]
247 del self.__virtualEnvironmentInterpreters[venvName]
248 286
249 self.__updateSettings() 287 self.__saveSettings()
250 288
251 if self.__virtualenvManagerDialog: 289 if self.__virtualenvManagerDialog:
252 self.__virtualenvManagerDialog.refresh() 290 self.__virtualenvManagerDialog.refresh()
253 291
254 def getEnvironmentEntries(self): 292 def getEnvironmentEntries(self):
255 """ 293 """
256 Public method to a dictionary containing the defined virtual 294 Public method to get a dictionary containing the defined virtual
257 environment entries. 295 environment entries.
258 296
259 @return dictionary containing tuples of the environment path and 297 @return dictionary containing a copy of the defined virtual
260 the associated interpreter 298 environments
261 @rtype dict of (str, str) 299 @rtype dict
262 """ 300 """
263 environments = {} 301 return copy.deepcopy(self.__virtualEnvironments)
264 for venvName in self.__virtualEnvironments:
265 environments[venvName] = (
266 self.__virtualEnvironments[venvName],
267 self.__virtualEnvironmentInterpreters[venvName],
268 )
269
270 return environments
271 302
272 @pyqtSlot() 303 @pyqtSlot()
273 def showVirtualenvManagerDialog(self): 304 def showVirtualenvManagerDialog(self):
274 """ 305 """
275 Public slot to show the virtual environment manager dialog. 306 Public slot to show the virtual environment manager dialog.
307 @param venvName logical name for the virtual environment 338 @param venvName logical name for the virtual environment
308 @type str 339 @type str
309 @return interpreter path 340 @return interpreter path
310 @rtype str 341 @rtype str
311 """ 342 """
312 if venvName in self.__virtualEnvironmentInterpreters: 343 if venvName in self.__virtualEnvironments:
313 return self.__virtualEnvironmentInterpreters[venvName] 344 return self.__virtualEnvironments[venvName]["interpreter"]
314 else: 345 else:
315 return "" 346 return ""
316 347
317 def getVirtualenvDirectory(self, venvName): 348 def getVirtualenvDirectory(self, venvName):
318 """ 349 """
322 @type str 353 @type str
323 @return directory path 354 @return directory path
324 @rtype str 355 @rtype str
325 """ 356 """
326 if venvName in self.__virtualEnvironments: 357 if venvName in self.__virtualEnvironments:
327 return self.__virtualEnvironments[venvName] 358 return self.__virtualEnvironments[venvName]["path"]
328 else: 359 else:
329 return "" 360 return ""
330 361
331 def getVirtualenvNames(self): 362 def getVirtualenvNames(self):
332 """ 363 """
333 Public method to get a list of defined virtual environments. 364 Public method to get a list of defined virtual environments.
334 365
335 @return list of defined virtual environments 366 @return list of defined virtual environments
336 @rtype list of str 367 @rtype list of str
337 """ 368 """
338 return list(self.__virtualEnvironmentInterpreters.keys()) 369 return list(self.__virtualEnvironments.keys())
370
371 def getVirtualenvNamesForVariant(self, variant):
372 """
373 Public method to get a list of virtual environments for a given
374 Python variant.
375
376 @param variant Python variant (2 or 3)
377 @type int
378 @return list of defined virtual environments
379 @rtype list of str
380 """
381 assert variant in (2, 3)
382
383 environments = []
384 for venvName in self.__virtualEnvironments:
385 if self.__virtualEnvironments[venvName]["variant"] == variant:
386 environments.append(venvName)
387
388 return environments

eric ide

mercurial