src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
20 20
21 class VirtualenvUpgradeExecDialog(QDialog, Ui_VirtualenvExecDialog): 21 class VirtualenvUpgradeExecDialog(QDialog, Ui_VirtualenvExecDialog):
22 """ 22 """
23 Class implementing the virtualenv upgrade execution dialog. 23 Class implementing the virtualenv upgrade execution dialog.
24 """ 24 """
25 def __init__(self, venvName, interpreter, createLog, venvManager, 25
26 parent=None): 26 def __init__(self, venvName, interpreter, createLog, venvManager, parent=None):
27 """ 27 """
28 Constructor 28 Constructor
29 29
30 @param venvName name of the virtual environment to be upgraded 30 @param venvName name of the virtual environment to be upgraded
31 @type str 31 @type str
32 @param interpreter interpreter to be used for the upgrade 32 @param interpreter interpreter to be used for the upgrade
33 @type str 33 @type str
34 @param createLog flag indicating to create a log file for the upgrade 34 @param createLog flag indicating to create a log file for the upgrade
38 @param parent reference to the parent widget 38 @param parent reference to the parent widget
39 @type QWidget 39 @type QWidget
40 """ 40 """
41 super().__init__(parent) 41 super().__init__(parent)
42 self.setupUi(self) 42 self.setupUi(self)
43 43
44 self.buttonBox.button( 44 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
45 QDialogButtonBox.StandardButton.Close).setEnabled(False) 45 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
46 self.buttonBox.button( 46
47 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
48
49 self.__process = None 47 self.__process = None
50 self.__cmd = "" 48 self.__cmd = ""
51 49
52 self.__progs = [] 50 self.__progs = []
53 if interpreter: 51 if interpreter:
54 self.__progs.append(interpreter) 52 self.__progs.append(interpreter)
55 self.__progs.extend([ 53 self.__progs.extend(
56 getPythonExecutable(), 54 [
57 "python3", 55 getPythonExecutable(),
58 "python", 56 "python3",
59 ]) 57 "python",
58 ]
59 )
60 self.__callIndex = 0 60 self.__callIndex = 0
61 self.__callArgs = [] 61 self.__callArgs = []
62 62
63 self.__venvName = venvName 63 self.__venvName = venvName
64 self.__venvDirectory = "" 64 self.__venvDirectory = ""
65 self.__createLog = createLog 65 self.__createLog = createLog
66 self.__manager = venvManager 66 self.__manager = venvManager
67 67
68 def start(self, arguments): 68 def start(self, arguments):
69 """ 69 """
70 Public slot to start the virtualenv command. 70 Public slot to start the virtualenv command.
71 71
72 @param arguments commandline arguments for virtualenv/pyvenv program 72 @param arguments commandline arguments for virtualenv/pyvenv program
73 (list of strings) 73 (list of strings)
74 """ 74 """
75 if self.__callIndex == 0: 75 if self.__callIndex == 0:
76 # first attempt, add a given python interpreter and do 76 # first attempt, add a given python interpreter and do
77 # some other setup 77 # some other setup
78 self.errorGroup.hide() 78 self.errorGroup.hide()
79 self.contents.clear() 79 self.contents.clear()
80 self.errors.clear() 80 self.errors.clear()
81 81
82 self.__process = QProcess() 82 self.__process = QProcess()
83 self.__process.readyReadStandardOutput.connect(self.__readStdout) 83 self.__process.readyReadStandardOutput.connect(self.__readStdout)
84 self.__process.readyReadStandardError.connect(self.__readStderr) 84 self.__process.readyReadStandardError.connect(self.__readStderr)
85 self.__process.finished.connect(self.__finish) 85 self.__process.finished.connect(self.__finish)
86 86
87 self.__callArgs = arguments 87 self.__callArgs = arguments
88 self.__venvDirectory = arguments[-1] 88 self.__venvDirectory = arguments[-1]
89 89
90 prog = self.__progs[self.__callIndex] 90 prog = self.__progs[self.__callIndex]
91 self.__cmd = "{0} {1}".format(prog, " ".join(arguments)) 91 self.__cmd = "{0} {1}".format(prog, " ".join(arguments))
92 self.__logOutput(self.tr("Executing: {0}\n").format( 92 self.__logOutput(self.tr("Executing: {0}\n").format(self.__cmd))
93 self.__cmd))
94 self.__process.start(prog, arguments) 93 self.__process.start(prog, arguments)
95 procStarted = self.__process.waitForStarted(5000) 94 procStarted = self.__process.waitForStarted(5000)
96 if not procStarted: 95 if not procStarted:
97 self.__logOutput(self.tr("Failed\n\n")) 96 self.__logOutput(self.tr("Failed\n\n"))
98 self.__nextAttempt() 97 self.__nextAttempt()
99 98
100 def on_buttonBox_clicked(self, button): 99 def on_buttonBox_clicked(self, button):
101 """ 100 """
102 Private slot called by a button of the button box clicked. 101 Private slot called by a button of the button box clicked.
103 102
104 @param button button that was clicked (QAbstractButton) 103 @param button button that was clicked (QAbstractButton)
105 """ 104 """
106 if button == self.buttonBox.button( 105 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
107 QDialogButtonBox.StandardButton.Close
108 ):
109 self.accept() 106 self.accept()
110 elif button == self.buttonBox.button( 107 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
111 QDialogButtonBox.StandardButton.Cancel
112 ):
113 self.__finish(0, 0, giveUp=True) 108 self.__finish(0, 0, giveUp=True)
114 109
115 def __finish(self, exitCode, exitStatus, giveUp=False): 110 def __finish(self, exitCode, exitStatus, giveUp=False):
116 """ 111 """
117 Private slot called when the process finished. 112 Private slot called when the process finished.
118 113
119 It is called when the process finished or 114 It is called when the process finished or
120 the user pressed the button. 115 the user pressed the button.
121 116
122 @param exitCode exit code of the process (integer) 117 @param exitCode exit code of the process (integer)
123 @param exitStatus exit status of the process (QProcess.ExitStatus) 118 @param exitStatus exit status of the process (QProcess.ExitStatus)
124 @param giveUp flag indicating to not start another attempt (boolean) 119 @param giveUp flag indicating to not start another attempt (boolean)
125 """ 120 """
126 if ( 121 if (
127 self.__process is not None and 122 self.__process is not None
128 self.__process.state() != QProcess.ProcessState.NotRunning 123 and self.__process.state() != QProcess.ProcessState.NotRunning
129 ): 124 ):
130 self.__process.terminate() 125 self.__process.terminate()
131 QTimer.singleShot(2000, self.__process.kill) 126 QTimer.singleShot(2000, self.__process.kill)
132 self.__process.waitForFinished(3000) 127 self.__process.waitForFinished(3000)
133 128
134 self.buttonBox.button( 129 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
135 QDialogButtonBox.StandardButton.Close).setEnabled(True) 130 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
136 self.buttonBox.button( 131 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
137 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) 132
138 self.buttonBox.button(
139 QDialogButtonBox.StandardButton.Close).setDefault(True)
140
141 if not giveUp: 133 if not giveUp:
142 if exitCode != 0: 134 if exitCode != 0:
143 self.__logOutput(self.tr("Failed\n\n")) 135 self.__logOutput(self.tr("Failed\n\n"))
144 if len(self.errors.toPlainText().splitlines()) == 1: 136 if len(self.errors.toPlainText().splitlines()) == 1:
145 self.errors.clear() 137 self.errors.clear()
146 self.errorGroup.hide() 138 self.errorGroup.hide()
147 self.__nextAttempt() 139 self.__nextAttempt()
148 return 140 return
149 141
150 self.__process = None 142 self.__process = None
151 143
152 self.__logOutput(self.tr('\npyvenv finished.\n')) 144 self.__logOutput(self.tr("\npyvenv finished.\n"))
153 145
154 if self.__createLog: 146 if self.__createLog:
155 self.__writeLogFile() 147 self.__writeLogFile()
156 148
157 self.__changeVirtualEnvironmentInterpreter() 149 self.__changeVirtualEnvironmentInterpreter()
158 150
159 def __nextAttempt(self): 151 def __nextAttempt(self):
160 """ 152 """
161 Private method to start another attempt. 153 Private method to start another attempt.
162 """ 154 """
163 self.__callIndex += 1 155 self.__callIndex += 1
164 if self.__callIndex < len(self.__progs): 156 if self.__callIndex < len(self.__progs):
165 self.start(self.__callArgs) 157 self.start(self.__callArgs)
166 else: 158 else:
167 self.__logError( 159 self.__logError(
168 self.tr('No suitable pyvenv program could be' 160 self.tr("No suitable pyvenv program could be" " started.\n")
169 ' started.\n')) 161 )
170 self.__cmd = "" 162 self.__cmd = ""
171 self.__finish(0, 0, giveUp=True) 163 self.__finish(0, 0, giveUp=True)
172 164
173 def __readStdout(self): 165 def __readStdout(self):
174 """ 166 """
175 Private slot to handle the readyReadStandardOutput signal. 167 Private slot to handle the readyReadStandardOutput signal.
176 168
177 It reads the output of the process, formats it and inserts it into 169 It reads the output of the process, formats it and inserts it into
178 the contents pane. 170 the contents pane.
179 """ 171 """
180 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput) 172 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput)
181 173
182 while self.__process.canReadLine(): 174 while self.__process.canReadLine():
183 s = str(self.__process.readLine(), 175 s = str(
184 Preferences.getSystem("IOEncoding"), 176 self.__process.readLine(),
185 'replace') 177 Preferences.getSystem("IOEncoding"),
178 "replace",
179 )
186 self.__logOutput(s) 180 self.__logOutput(s)
187 181
188 def __readStderr(self): 182 def __readStderr(self):
189 """ 183 """
190 Private slot to handle the readyReadStandardError signal. 184 Private slot to handle the readyReadStandardError signal.
191 185
192 It reads the error output of the process and inserts it into the 186 It reads the error output of the process and inserts it into the
193 error pane. 187 error pane.
194 """ 188 """
195 self.__process.setReadChannel(QProcess.ProcessChannel.StandardError) 189 self.__process.setReadChannel(QProcess.ProcessChannel.StandardError)
196 190
197 while self.__process.canReadLine(): 191 while self.__process.canReadLine():
198 s = str(self.__process.readLine(), 192 s = str(
199 Preferences.getSystem("IOEncoding"), 193 self.__process.readLine(),
200 'replace') 194 Preferences.getSystem("IOEncoding"),
195 "replace",
196 )
201 self.__logError(s) 197 self.__logError(s)
202 198
203 def __logOutput(self, s): 199 def __logOutput(self, s):
204 """ 200 """
205 Private method to log some output. 201 Private method to log some output.
206 202
207 @param s output string to log (string) 203 @param s output string to log (string)
208 """ 204 """
209 self.contents.insertPlainText(s) 205 self.contents.insertPlainText(s)
210 self.contents.ensureCursorVisible() 206 self.contents.ensureCursorVisible()
211 207
212 def __logError(self, s): 208 def __logError(self, s):
213 """ 209 """
214 Private method to log an error. 210 Private method to log an error.
215 211
216 @param s error string to log (string) 212 @param s error string to log (string)
217 """ 213 """
218 self.errorGroup.show() 214 self.errorGroup.show()
219 self.errors.insertPlainText(s) 215 self.errors.insertPlainText(s)
220 self.errors.ensureCursorVisible() 216 self.errors.ensureCursorVisible()
221 217
222 def __writeLogFile(self): 218 def __writeLogFile(self):
223 """ 219 """
224 Private method to write a log file to the virtualenv directory. 220 Private method to write a log file to the virtualenv directory.
225 """ 221 """
226 outtxt = self.contents.toPlainText() 222 outtxt = self.contents.toPlainText()
227 logFile = os.path.join(self.__venvDirectory, "pyvenv_upgrade.log") 223 logFile = os.path.join(self.__venvDirectory, "pyvenv_upgrade.log")
228 self.__logOutput(self.tr("\nWriting log file '{0}'.\n") 224 self.__logOutput(self.tr("\nWriting log file '{0}'.\n").format(logFile))
229 .format(logFile)) 225
230
231 try: 226 try:
232 with open(logFile, "w", encoding="utf-8") as f: 227 with open(logFile, "w", encoding="utf-8") as f:
233 f.write(self.tr("Output:\n")) 228 f.write(self.tr("Output:\n"))
234 f.write(outtxt) 229 f.write(outtxt)
235 errtxt = self.errors.toPlainText() 230 errtxt = self.errors.toPlainText()
237 f.write("\n") 232 f.write("\n")
238 f.write(self.tr("Errors:\n")) 233 f.write(self.tr("Errors:\n"))
239 f.write(errtxt) 234 f.write(errtxt)
240 except OSError as err: 235 except OSError as err:
241 self.__logError( 236 self.__logError(
242 self.tr("""The logfile '{0}' could not be written.\n""" 237 self.tr(
243 """Reason: {1}\n""").format(logFile, str(err))) 238 """The logfile '{0}' could not be written.\n""" """Reason: {1}\n"""
239 ).format(logFile, str(err))
240 )
244 self.__logOutput(self.tr("Done.\n")) 241 self.__logOutput(self.tr("Done.\n"))
245 242
246 def __changeVirtualEnvironmentInterpreter(self): 243 def __changeVirtualEnvironmentInterpreter(self):
247 """ 244 """
248 Private method to change the interpreter of the upgraded virtual 245 Private method to change the interpreter of the upgraded virtual
249 environment. 246 environment.
250 """ 247 """
251 from .VirtualenvInterpreterSelectionDialog import ( 248 from .VirtualenvInterpreterSelectionDialog import (
252 VirtualenvInterpreterSelectionDialog 249 VirtualenvInterpreterSelectionDialog,
253 ) 250 )
254 251
255 venvInterpreter = "" 252 venvInterpreter = ""
256 dlg = VirtualenvInterpreterSelectionDialog( 253 dlg = VirtualenvInterpreterSelectionDialog(
257 self.__venvName, self.__venvDirectory) 254 self.__venvName, self.__venvDirectory
255 )
258 if dlg.exec() == QDialog.DialogCode.Accepted: 256 if dlg.exec() == QDialog.DialogCode.Accepted:
259 venvInterpreter = dlg.getData() 257 venvInterpreter = dlg.getData()
260 258
261 if venvInterpreter: 259 if venvInterpreter:
262 self.__manager.setVirtualEnvInterpreter( 260 self.__manager.setVirtualEnvInterpreter(self.__venvName, venvInterpreter)
263 self.__venvName, venvInterpreter)

eric ide

mercurial