79 |
78 |
80 |
79 |
81 def __getProgramVersion(exe): |
80 def __getProgramVersion(exe): |
82 """ |
81 """ |
83 Private method to generate a program entry. |
82 Private method to generate a program entry. |
84 |
83 |
85 @param exe name of the executable program |
84 @param exe name of the executable program |
86 @type str |
85 @type str |
87 @return version string of detected version |
86 @return version string of detected version |
88 @rtype str |
87 @rtype str |
89 """ |
88 """ |
90 proc = QProcess() |
89 proc = QProcess() |
91 proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels) |
90 proc.setProcessChannelMode(QProcess.ProcessChannelMode.MergedChannels) |
92 proc.start(exe, ['--version']) |
91 proc.start(exe, ["--version"]) |
93 finished = proc.waitForFinished(10000) |
92 finished = proc.waitForFinished(10000) |
94 if finished: |
93 if finished: |
95 output = str(proc.readAllStandardOutput(), |
94 output = str( |
96 Preferences.getSystem("IOEncoding"), |
95 proc.readAllStandardOutput(), Preferences.getSystem("IOEncoding"), "replace" |
97 'replace') |
96 ) |
98 versionRe = re.compile('^pylint', re.UNICODE) |
97 versionRe = re.compile("^pylint", re.UNICODE) |
99 for line in output.splitlines(): |
98 for line in output.splitlines(): |
100 if versionRe.search(line): |
99 if versionRe.search(line): |
101 return line.split()[-1] |
100 return line.split()[-1] |
102 |
101 |
103 return '0.0.0' |
102 return "0.0.0" |
104 |
103 |
105 |
104 |
106 def _findExecutable(majorVersion): |
105 def _findExecutable(majorVersion): |
107 """ |
106 """ |
108 Restricted function to determine the name and path of the executable. |
107 Restricted function to determine the name and path of the executable. |
109 |
108 |
110 @param majorVersion major python version of the executables |
109 @param majorVersion major python version of the executables |
111 @type int |
110 @type int |
112 @return path name of the executable |
111 @return path name of the executable |
113 @rtype str |
112 @rtype str |
114 """ |
113 """ |
115 # Determine Python Version |
114 # Determine Python Version |
116 if majorVersion == 3: |
115 if majorVersion == 3: |
117 minorVersions = range(10) |
116 minorVersions = range(10) |
118 else: |
117 else: |
119 return [] |
118 return [] |
120 |
119 |
121 executables = set() |
120 executables = set() |
122 if Utilities.isWindowsPlatform(): |
121 if Utilities.isWindowsPlatform(): |
123 # |
122 # |
124 # Windows |
123 # Windows |
125 # |
124 # |
126 try: |
125 try: |
127 import winreg |
126 import winreg |
128 except ImportError: |
127 except ImportError: |
129 import _winreg as winreg # __IGNORE_WARNING__ |
128 import _winreg as winreg # __IGNORE_WARNING__ |
130 |
129 |
131 def getExePath(branch, access, versionStr): |
130 def getExePath(branch, access, versionStr): |
132 exes = [] |
131 exes = [] |
133 with contextlib.suppress(WindowsError, OSError): |
132 with contextlib.suppress(WindowsError, OSError): |
134 software = winreg.OpenKey(branch, 'Software', 0, access) |
133 software = winreg.OpenKey(branch, "Software", 0, access) |
135 python = winreg.OpenKey(software, 'Python', 0, access) |
134 python = winreg.OpenKey(software, "Python", 0, access) |
136 pcore = winreg.OpenKey(python, 'PythonCore', 0, access) |
135 pcore = winreg.OpenKey(python, "PythonCore", 0, access) |
137 version = winreg.OpenKey(pcore, versionStr, 0, access) |
136 version = winreg.OpenKey(pcore, versionStr, 0, access) |
138 installpath = winreg.QueryValue(version, 'InstallPath') |
137 installpath = winreg.QueryValue(version, "InstallPath") |
139 # Look for the batch script variant |
138 # Look for the batch script variant |
140 exe = os.path.join(installpath, 'Scripts', 'pylint.bat') |
139 exe = os.path.join(installpath, "Scripts", "pylint.bat") |
141 if os.access(exe, os.X_OK): |
140 if os.access(exe, os.X_OK): |
142 exes.append(exe) |
141 exes.append(exe) |
143 # Look for the executable variant |
142 # Look for the executable variant |
144 exe = os.path.join(installpath, 'Scripts', 'pylint.exe') |
143 exe = os.path.join(installpath, "Scripts", "pylint.exe") |
145 if os.access(exe, os.X_OK): |
144 if os.access(exe, os.X_OK): |
146 exes.append(exe) |
145 exes.append(exe) |
147 return exes |
146 return exes |
148 |
147 |
149 versionSuffixes = ["", "-32", "-64"] |
148 versionSuffixes = ["", "-32", "-64"] |
150 for minorVersion in minorVersions: |
149 for minorVersion in minorVersions: |
151 for versionSuffix in versionSuffixes: |
150 for versionSuffix in versionSuffixes: |
152 versionStr = '{0}.{1}{2}'.format(majorVersion, minorVersion, |
151 versionStr = "{0}.{1}{2}".format( |
153 versionSuffix) |
152 majorVersion, minorVersion, versionSuffix |
|
153 ) |
154 exePaths = getExePath( |
154 exePaths = getExePath( |
155 winreg.HKEY_CURRENT_USER, |
155 winreg.HKEY_CURRENT_USER, |
156 winreg.KEY_WOW64_32KEY | winreg.KEY_READ, versionStr) |
156 winreg.KEY_WOW64_32KEY | winreg.KEY_READ, |
|
157 versionStr, |
|
158 ) |
157 if exePaths: |
159 if exePaths: |
158 for exePath in exePaths: |
160 for exePath in exePaths: |
159 executables.add(exePath) |
161 executables.add(exePath) |
160 |
162 |
161 exePaths = getExePath( |
163 exePaths = getExePath( |
162 winreg.HKEY_LOCAL_MACHINE, |
164 winreg.HKEY_LOCAL_MACHINE, |
163 winreg.KEY_WOW64_32KEY | winreg.KEY_READ, versionStr) |
165 winreg.KEY_WOW64_32KEY | winreg.KEY_READ, |
|
166 versionStr, |
|
167 ) |
164 if exePaths: |
168 if exePaths: |
165 for exePath in exePaths: |
169 for exePath in exePaths: |
166 executables.add(exePath) |
170 executables.add(exePath) |
167 |
171 |
168 # Even on Intel 64-bit machines it's 'AMD64' |
172 # Even on Intel 64-bit machines it's 'AMD64' |
169 if platform.machine() == 'AMD64': |
173 if platform.machine() == "AMD64": |
170 exePaths = getExePath( |
174 exePaths = getExePath( |
171 winreg.HKEY_CURRENT_USER, |
175 winreg.HKEY_CURRENT_USER, |
172 winreg.KEY_WOW64_64KEY | winreg.KEY_READ, versionStr) |
176 winreg.KEY_WOW64_64KEY | winreg.KEY_READ, |
|
177 versionStr, |
|
178 ) |
173 if exePaths: |
179 if exePaths: |
174 for exePath in exePaths: |
180 for exePath in exePaths: |
175 executables.add(exePath) |
181 executables.add(exePath) |
176 |
182 |
177 exePaths = getExePath( |
183 exePaths = getExePath( |
178 winreg.HKEY_LOCAL_MACHINE, |
184 winreg.HKEY_LOCAL_MACHINE, |
179 winreg.KEY_WOW64_64KEY | winreg.KEY_READ, versionStr) |
185 winreg.KEY_WOW64_64KEY | winreg.KEY_READ, |
|
186 versionStr, |
|
187 ) |
180 if exePaths: |
188 if exePaths: |
181 for exePath in exePaths: |
189 for exePath in exePaths: |
182 executables.add(exePath) |
190 executables.add(exePath) |
183 |
191 |
184 if not executables and majorVersion >= 3: |
192 if not executables and majorVersion >= 3: |
185 # check the PATH environment variable if nothing was found |
193 # check the PATH environment variable if nothing was found |
186 # Python 3 only |
194 # Python 3 only |
187 path = Utilities.getEnvironmentEntry('PATH') |
195 path = Utilities.getEnvironmentEntry("PATH") |
188 if path: |
196 if path: |
189 dirs = path.split(os.pathsep) |
197 dirs = path.split(os.pathsep) |
190 for directory in dirs: |
198 for directory in dirs: |
191 for suffix in (".bat", ".exe"): |
199 for suffix in (".bat", ".exe"): |
192 exe = os.path.join(directory, "pylint" + suffix) |
200 exe = os.path.join(directory, "pylint" + suffix) |
193 if os.access(exe, os.X_OK): |
201 if os.access(exe, os.X_OK): |
194 executables.add(exe) |
202 executables.add(exe) |
195 else: |
203 else: |
196 # |
204 # |
197 # Linux, Unix ... |
205 # Linux, Unix ... |
198 pylintScript = 'pylint' |
206 pylintScript = "pylint" |
199 scriptSuffixes = ["", |
207 scriptSuffixes = [ |
200 "-python{0}".format(majorVersion), |
208 "", |
201 "{0}".format(majorVersion), |
209 "-python{0}".format(majorVersion), |
202 ] |
210 "{0}".format(majorVersion), |
|
211 ] |
203 for minorVersion in minorVersions: |
212 for minorVersion in minorVersions: |
204 scriptSuffixes.append( |
213 scriptSuffixes.append("-python{0}.{1}".format(majorVersion, minorVersion)) |
205 "-python{0}.{1}".format(majorVersion, minorVersion)) |
|
206 # There could be multiple pylint executables in the path |
214 # There could be multiple pylint executables in the path |
207 # e.g. for different python variants |
215 # e.g. for different python variants |
208 path = Utilities.getEnvironmentEntry('PATH') |
216 path = Utilities.getEnvironmentEntry("PATH") |
209 # environment variable not defined |
217 # environment variable not defined |
210 if path is None: |
218 if path is None: |
211 return [] |
219 return [] |
212 |
220 |
213 # step 1: determine possible candidates |
221 # step 1: determine possible candidates |
214 exes = [] |
222 exes = [] |
215 dirs = path.split(os.pathsep) |
223 dirs = path.split(os.pathsep) |
216 for directory in dirs: |
224 for directory in dirs: |
217 for suffix in scriptSuffixes: |
225 for suffix in scriptSuffixes: |
218 exe = os.path.join(directory, pylintScript + suffix) |
226 exe = os.path.join(directory, pylintScript + suffix) |
219 if os.access(exe, os.X_OK): |
227 if os.access(exe, os.X_OK): |
220 exes.append(exe) |
228 exes.append(exe) |
221 |
229 |
222 # step 2: determine the Python variant |
230 # step 2: determine the Python variant |
223 _exePy3 = set() |
231 _exePy3 = set() |
224 versionArgs = ["-c", "import sys; print(sys.version_info[0])"] |
232 versionArgs = ["-c", "import sys; print(sys.version_info[0])"] |
225 for exe in exes: |
233 for exe in exes: |
226 with open(exe, "r") as f: |
234 with open(exe, "r") as f: |
250 |
258 |
251 |
259 |
252 def _checkProgram(): |
260 def _checkProgram(): |
253 """ |
261 """ |
254 Restricted function to check the availability of pylint. |
262 Restricted function to check the availability of pylint. |
255 |
263 |
256 @return flag indicating availability |
264 @return flag indicating availability |
257 @rtype bool |
265 @rtype bool |
258 """ |
266 """ |
259 global error, exePy3 |
267 global error, exePy3 |
260 |
268 |
261 exePy3 = _findExecutable(3) |
269 exePy3 = _findExecutable(3) |
262 if exePy3[0] == '': |
270 if exePy3[0] == "": |
263 error = QCoreApplication.translate( |
271 error = QCoreApplication.translate( |
264 "PyLintPlugin", "The pylint executable could not be found.") |
272 "PyLintPlugin", "The pylint executable could not be found." |
|
273 ) |
265 return False |
274 return False |
266 else: |
275 else: |
267 return True |
276 return True |
268 |
277 |
269 |
278 |
270 class PyLintPlugin(QObject): |
279 class PyLintPlugin(QObject): |
271 """ |
280 """ |
272 Class implementing the PyLint plug-in. |
281 Class implementing the PyLint plug-in. |
273 """ |
282 """ |
|
283 |
274 def __init__(self, ui): |
284 def __init__(self, ui): |
275 """ |
285 """ |
276 Constructor |
286 Constructor |
277 |
287 |
278 @param ui reference to the user interface object |
288 @param ui reference to the user interface object |
279 @type UserInterface |
289 @type UserInterface |
280 """ |
290 """ |
281 QObject.__init__(self, ui) |
291 QObject.__init__(self, ui) |
282 self.__ui = ui |
292 self.__ui = ui |
283 self.__initialize() |
293 self.__initialize() |
284 |
294 |
285 self.__translator = None |
295 self.__translator = None |
286 self.__loadTranslator() |
296 self.__loadTranslator() |
287 |
297 |
288 def __initialize(self): |
298 def __initialize(self): |
289 """ |
299 """ |
290 Private slot to (re)initialize the plugin. |
300 Private slot to (re)initialize the plugin. |
291 """ |
301 """ |
292 self.__projectAct = None |
302 self.__projectAct = None |
293 self.__projectShowAct = None |
303 self.__projectShowAct = None |
294 self.__pylintPDialog = None |
304 self.__pylintPDialog = None |
295 |
305 |
296 self.__projectBrowserAct = None |
306 self.__projectBrowserAct = None |
297 self.__projectBrowserShowAct = None |
307 self.__projectBrowserShowAct = None |
298 self.__projectBrowserMenu = None |
308 self.__projectBrowserMenu = None |
299 self.__pylintPsbDialog = None |
309 self.__pylintPsbDialog = None |
300 |
310 |
301 self.__editors = [] |
311 self.__editors = [] |
302 self.__editorAct = None |
312 self.__editorAct = None |
303 self.__editorPylintDialog = None |
313 self.__editorPylintDialog = None |
304 self.__editorParms = None |
314 self.__editorParms = None |
305 |
315 |
306 def activate(self): |
316 def activate(self): |
307 """ |
317 """ |
308 Public method to activate this plugin. |
318 Public method to activate this plugin. |
309 |
319 |
310 @return tuple of None and activation status |
320 @return tuple of None and activation status |
311 @rtype tuple of (None, bool) |
321 @rtype tuple of (None, bool) |
312 """ |
322 """ |
313 global error |
323 global error |
314 |
324 |
315 # There is already an error, don't activate |
325 # There is already an error, don't activate |
316 if error: |
326 if error: |
317 return None, False |
327 return None, False |
318 # pylint is only activated if it is available |
328 # pylint is only activated if it is available |
319 if not _checkProgram(): |
329 if not _checkProgram(): |
320 return None, False |
330 return None, False |
321 |
331 |
322 menu = ericApp().getObject("Project").getMenu("Checks") |
332 menu = ericApp().getObject("Project").getMenu("Checks") |
323 if menu: |
333 if menu: |
324 self.__projectAct = EricAction( |
334 self.__projectAct = EricAction( |
325 self.tr('Run PyLint'), |
335 self.tr("Run PyLint"), |
326 self.tr('Run &PyLint...'), 0, 0, |
336 self.tr("Run &PyLint..."), |
327 self, 'project_check_pylint') |
337 0, |
|
338 0, |
|
339 self, |
|
340 "project_check_pylint", |
|
341 ) |
328 self.__projectAct.setStatusTip( |
342 self.__projectAct.setStatusTip( |
329 self.tr('Check project, packages or modules with pylint.')) |
343 self.tr("Check project, packages or modules with pylint.") |
330 self.__projectAct.setWhatsThis(self.tr( |
344 ) |
331 """<b>Run PyLint...</b>""" |
345 self.__projectAct.setWhatsThis( |
332 """<p>This checks the project, packages or modules using""" |
346 self.tr( |
333 """ pylint.</p>""" |
347 """<b>Run PyLint...</b>""" |
334 )) |
348 """<p>This checks the project, packages or modules using""" |
|
349 """ pylint.</p>""" |
|
350 ) |
|
351 ) |
335 self.__projectAct.triggered.connect(self.__projectPylint) |
352 self.__projectAct.triggered.connect(self.__projectPylint) |
336 ericApp().getObject("Project").addEricActions([self.__projectAct]) |
353 ericApp().getObject("Project").addEricActions([self.__projectAct]) |
337 menu.addAction(self.__projectAct) |
354 menu.addAction(self.__projectAct) |
338 |
355 |
339 self.__projectShowAct = EricAction( |
356 self.__projectShowAct = EricAction( |
340 self.tr('Show PyLint Dialog'), |
357 self.tr("Show PyLint Dialog"), |
341 self.tr('Show Py&Lint Dialog...'), 0, 0, |
358 self.tr("Show Py&Lint Dialog..."), |
342 self, 'project_check_pylintshow') |
359 0, |
343 self.__projectShowAct.setStatusTip(self.tr( |
360 0, |
344 'Show the PyLint dialog with the results of the last run.')) |
361 self, |
345 self.__projectShowAct.setWhatsThis(self.tr( |
362 "project_check_pylintshow", |
346 """<b>Show PyLint Dialog...</b>""" |
363 ) |
347 """<p>This shows the PyLint dialog with the results""" |
364 self.__projectShowAct.setStatusTip( |
348 """ of the last run.</p>""" |
365 self.tr("Show the PyLint dialog with the results of the last run.") |
349 )) |
366 ) |
350 self.__projectShowAct.triggered.connect( |
367 self.__projectShowAct.setWhatsThis( |
351 self.__projectPylintShow) |
368 self.tr( |
352 ericApp().getObject("Project").addEricActions( |
369 """<b>Show PyLint Dialog...</b>""" |
353 [self.__projectShowAct]) |
370 """<p>This shows the PyLint dialog with the results""" |
|
371 """ of the last run.</p>""" |
|
372 ) |
|
373 ) |
|
374 self.__projectShowAct.triggered.connect(self.__projectPylintShow) |
|
375 ericApp().getObject("Project").addEricActions([self.__projectShowAct]) |
354 menu.addAction(self.__projectShowAct) |
376 menu.addAction(self.__projectShowAct) |
355 |
377 |
356 self.__editorAct = EricAction( |
378 self.__editorAct = EricAction( |
357 self.tr('Run PyLint'), |
379 self.tr("Run PyLint"), self.tr("Run &PyLint..."), 0, 0, self, "" |
358 self.tr('Run &PyLint...'), 0, 0, |
380 ) |
359 self, "") |
381 self.__editorAct.setWhatsThis( |
360 self.__editorAct.setWhatsThis(self.tr( |
382 self.tr( |
361 """<b>Run PyLint...</b>""" |
383 """<b>Run PyLint...</b>""" |
362 """<p>This checks the loaded module using pylint.</p>""" |
384 """<p>This checks the loaded module using pylint.</p>""" |
363 )) |
385 ) |
|
386 ) |
364 self.__editorAct.triggered.connect(self.__editorPylint) |
387 self.__editorAct.triggered.connect(self.__editorPylint) |
365 |
388 |
366 ericApp().getObject("Project").showMenu.connect(self.__projectShowMenu) |
389 ericApp().getObject("Project").showMenu.connect(self.__projectShowMenu) |
367 ericApp().getObject("ProjectBrowser").getProjectBrowser( |
390 ericApp().getObject("ProjectBrowser").getProjectBrowser( |
368 "sources").showMenu.connect(self.__projectBrowserShowMenu) |
391 "sources" |
369 ericApp().getObject("ViewManager").editorOpenedEd.connect( |
392 ).showMenu.connect(self.__projectBrowserShowMenu) |
370 self.__editorOpened) |
393 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened) |
371 ericApp().getObject("ViewManager").editorClosedEd.connect( |
394 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed) |
372 self.__editorClosed) |
395 |
373 |
|
374 for editor in ericApp().getObject("ViewManager").getOpenEditors(): |
396 for editor in ericApp().getObject("ViewManager").getOpenEditors(): |
375 self.__editorOpened(editor) |
397 self.__editorOpened(editor) |
376 |
398 |
377 error = "" |
399 error = "" |
378 return None, True |
400 return None, True |
379 |
401 |
380 def deactivate(self): |
402 def deactivate(self): |
381 """ |
403 """ |
382 Public method to deactivate this plugin. |
404 Public method to deactivate this plugin. |
383 """ |
405 """ |
384 ericApp().getObject("Project").showMenu.disconnect( |
406 ericApp().getObject("Project").showMenu.disconnect(self.__projectShowMenu) |
385 self.__projectShowMenu) |
|
386 ericApp().getObject("ProjectBrowser").getProjectBrowser( |
407 ericApp().getObject("ProjectBrowser").getProjectBrowser( |
387 "sources").showMenu.disconnect(self.__projectBrowserShowMenu) |
408 "sources" |
|
409 ).showMenu.disconnect(self.__projectBrowserShowMenu) |
388 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( |
410 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( |
389 self.__editorOpened) |
411 self.__editorOpened |
|
412 ) |
390 ericApp().getObject("ViewManager").editorClosedEd.disconnect( |
413 ericApp().getObject("ViewManager").editorClosedEd.disconnect( |
391 self.__editorClosed) |
414 self.__editorClosed |
392 |
415 ) |
|
416 |
393 menu = ericApp().getObject("Project").getMenu("Checks") |
417 menu = ericApp().getObject("Project").getMenu("Checks") |
394 if menu: |
418 if menu: |
395 if self.__projectAct: |
419 if self.__projectAct: |
396 menu.removeAction(self.__projectAct) |
420 menu.removeAction(self.__projectAct) |
397 ericApp().getObject("Project").removeEricActions( |
421 ericApp().getObject("Project").removeEricActions([self.__projectAct]) |
398 [self.__projectAct]) |
|
399 if self.__projectShowAct: |
422 if self.__projectShowAct: |
400 menu.removeAction(self.__projectShowAct) |
423 menu.removeAction(self.__projectShowAct) |
401 ericApp().getObject("Project").removeEricActions( |
424 ericApp().getObject("Project").removeEricActions( |
402 [self.__projectShowAct]) |
425 [self.__projectShowAct] |
403 |
426 ) |
|
427 |
404 if self.__projectBrowserMenu: |
428 if self.__projectBrowserMenu: |
405 if self.__projectBrowserAct: |
429 if self.__projectBrowserAct: |
406 self.__projectBrowserMenu.removeAction( |
430 self.__projectBrowserMenu.removeAction(self.__projectBrowserAct) |
407 self.__projectBrowserAct) |
|
408 if self.__projectBrowserShowAct: |
431 if self.__projectBrowserShowAct: |
409 self.__projectBrowserMenu.removeAction( |
432 self.__projectBrowserMenu.removeAction(self.__projectBrowserShowAct) |
410 self.__projectBrowserShowAct) |
433 |
411 |
|
412 for editor in self.__editors: |
434 for editor in self.__editors: |
413 editor.showMenu.disconnect(self.__editorShowMenu) |
435 editor.showMenu.disconnect(self.__editorShowMenu) |
414 menu = editor.getMenu("Checks") |
436 menu = editor.getMenu("Checks") |
415 if menu is not None: |
437 if menu is not None: |
416 menu.removeAction(self.__editorAct) |
438 menu.removeAction(self.__editorAct) |
417 |
439 |
418 self.__initialize() |
440 self.__initialize() |
419 |
441 |
420 def __loadTranslator(self): |
442 def __loadTranslator(self): |
421 """ |
443 """ |
422 Private method to load the translation file. |
444 Private method to load the translation file. |
423 """ |
445 """ |
424 if self.__ui is not None: |
446 if self.__ui is not None: |
425 loc = self.__ui.getLocale() |
447 loc = self.__ui.getLocale() |
426 if loc and loc != "C": |
448 if loc and loc != "C": |
427 locale_dir = os.path.join(os.path.dirname(__file__), |
449 locale_dir = os.path.join( |
428 "PyLintInterface", "i18n") |
450 os.path.dirname(__file__), "PyLintInterface", "i18n" |
|
451 ) |
429 translation = "pylint_{0}".format(loc) |
452 translation = "pylint_{0}".format(loc) |
430 translator = QTranslator(None) |
453 translator = QTranslator(None) |
431 loaded = translator.load(translation, locale_dir) |
454 loaded = translator.load(translation, locale_dir) |
432 if loaded: |
455 if loaded: |
433 self.__translator = translator |
456 self.__translator = translator |
434 ericApp().installTranslator(self.__translator) |
457 ericApp().installTranslator(self.__translator) |
435 else: |
458 else: |
436 print("Warning: translation file '{0}' could not be" |
459 print( |
437 " loaded.".format(translation)) |
460 "Warning: translation file '{0}' could not be" |
|
461 " loaded.".format(translation) |
|
462 ) |
438 print("Using default.") |
463 print("Using default.") |
439 |
464 |
440 def __projectShowMenu(self, menuName, menu): |
465 def __projectShowMenu(self, menuName, menu): |
441 """ |
466 """ |
442 Private slot called, when the the project menu or a submenu is |
467 Private slot called, when the the project menu or a submenu is |
443 about to be shown. |
468 about to be shown. |
444 |
469 |
445 @param menuName name of the menu to be shown |
470 @param menuName name of the menu to be shown |
446 @type str |
471 @type str |
447 @param menu reference to the menu |
472 @param menu reference to the menu |
448 @type QMenu |
473 @type QMenu |
449 """ |
474 """ |
452 if self.__projectAct is not None: |
477 if self.__projectAct is not None: |
453 self.__projectAct.setEnabled(lang.startswith("Python")) |
478 self.__projectAct.setEnabled(lang.startswith("Python")) |
454 if self.__projectShowAct is not None: |
479 if self.__projectShowAct is not None: |
455 self.__projectShowAct.setEnabled(lang.startswith("Python")) |
480 self.__projectShowAct.setEnabled(lang.startswith("Python")) |
456 self.__projectShowAct.setEnabled(self.__pylintPDialog is not None) |
481 self.__projectShowAct.setEnabled(self.__pylintPDialog is not None) |
457 |
482 |
458 def __projectBrowserShowMenu(self, menuName, menu): |
483 def __projectBrowserShowMenu(self, menuName, menu): |
459 """ |
484 """ |
460 Private slot called, when the the project browser menu or a submenu is |
485 Private slot called, when the the project browser menu or a submenu is |
461 about to be shown. |
486 about to be shown. |
462 |
487 |
463 @param menuName name of the menu to be shown |
488 @param menuName name of the menu to be shown |
464 @type str |
489 @type str |
465 @param menu reference to the menu |
490 @param menu reference to the menu |
466 @type QMenu |
491 @type QMenu |
467 """ |
492 """ |
468 if ( |
493 if menuName == "Checks" and ericApp().getObject( |
469 menuName == "Checks" and |
494 "Project" |
470 ericApp().getObject("Project").getProjectLanguage() |
495 ).getProjectLanguage().startswith("Python"): |
471 .startswith("Python") |
|
472 ): |
|
473 self.__projectBrowserMenu = menu |
496 self.__projectBrowserMenu = menu |
474 if self.__projectBrowserAct is None: |
497 if self.__projectBrowserAct is None: |
475 self.__projectBrowserAct = EricAction( |
498 self.__projectBrowserAct = EricAction( |
476 self.tr('Run PyLint'), |
499 self.tr("Run PyLint"), self.tr("Run &PyLint..."), 0, 0, self, "" |
477 self.tr('Run &PyLint...'), 0, 0, |
500 ) |
478 self, '') |
501 self.__projectBrowserAct.setWhatsThis( |
479 self.__projectBrowserAct.setWhatsThis(self.tr( |
502 self.tr( |
480 """<b>Run PyLint...</b>""" |
503 """<b>Run PyLint...</b>""" |
481 """<p>This checks the project, packages or modules""" |
504 """<p>This checks the project, packages or modules""" |
482 """ using pylint.</p>""" |
505 """ using pylint.</p>""" |
483 )) |
506 ) |
484 self.__projectBrowserAct.triggered.connect( |
507 ) |
485 self.__projectBrowserPylint) |
508 self.__projectBrowserAct.triggered.connect(self.__projectBrowserPylint) |
486 |
509 |
487 if self.__projectBrowserShowAct is None: |
510 if self.__projectBrowserShowAct is None: |
488 self.__projectBrowserShowAct = EricAction( |
511 self.__projectBrowserShowAct = EricAction( |
489 self.tr('Show PyLint Dialog'), |
512 self.tr("Show PyLint Dialog"), |
490 self.tr('Show Py&Lint Dialog...'), 0, 0, |
513 self.tr("Show Py&Lint Dialog..."), |
491 self, '') |
514 0, |
492 self.__projectBrowserShowAct.setWhatsThis(self.tr( |
515 0, |
493 """<b>Show PyLint Dialog...</b>""" |
516 self, |
494 """<p>This shows the PyLint dialog with the results""" |
517 "", |
495 """ of the last run.</p>""" |
518 ) |
496 )) |
519 self.__projectBrowserShowAct.setWhatsThis( |
|
520 self.tr( |
|
521 """<b>Show PyLint Dialog...</b>""" |
|
522 """<p>This shows the PyLint dialog with the results""" |
|
523 """ of the last run.</p>""" |
|
524 ) |
|
525 ) |
497 self.__projectBrowserShowAct.triggered.connect( |
526 self.__projectBrowserShowAct.triggered.connect( |
498 self.__projectBrowserPylintShow) |
527 self.__projectBrowserPylintShow |
499 |
528 ) |
|
529 |
500 if self.__projectBrowserAct not in menu.actions(): |
530 if self.__projectBrowserAct not in menu.actions(): |
501 menu.addAction(self.__projectBrowserAct) |
531 menu.addAction(self.__projectBrowserAct) |
502 if self.__projectBrowserShowAct not in menu.actions(): |
532 if self.__projectBrowserShowAct not in menu.actions(): |
503 menu.addAction(self.__projectBrowserShowAct) |
533 menu.addAction(self.__projectBrowserShowAct) |
504 |
534 |
505 enable = ( |
535 enable = ( |
506 ericApp().getObject("ProjectBrowser") |
536 ericApp() |
|
537 .getObject("ProjectBrowser") |
507 .getProjectBrowser("sources") |
538 .getProjectBrowser("sources") |
508 .getSelectedItemsCount([ProjectBrowserFileItem]) == 1) |
539 .getSelectedItemsCount([ProjectBrowserFileItem]) |
|
540 == 1 |
|
541 ) |
509 self.__projectBrowserAct.setEnabled(enable) |
542 self.__projectBrowserAct.setEnabled(enable) |
510 self.__projectBrowserShowAct.setEnabled( |
543 self.__projectBrowserShowAct.setEnabled( |
511 enable and self.__pylintPsbDialog is not None) |
544 enable and self.__pylintPsbDialog is not None |
512 |
545 ) |
|
546 |
513 def __pyLint(self, project, mpName, forProject, forEditor=False): |
547 def __pyLint(self, project, mpName, forProject, forEditor=False): |
514 """ |
548 """ |
515 Private method used to perform a PyLint run. |
549 Private method used to perform a PyLint run. |
516 |
550 |
517 @param project reference to the Project object |
551 @param project reference to the Project object |
518 @type Project |
552 @type Project |
519 @param mpName name of module or package to be checked |
553 @param mpName name of module or package to be checked |
520 @type str |
554 @type str |
521 @param forProject flag indicating a run for the project |
555 @param forProject flag indicating a run for the project |
526 if forEditor: |
560 if forEditor: |
527 parms = copy.deepcopy(self.__editorParms) |
561 parms = copy.deepcopy(self.__editorParms) |
528 editor = ericApp().getObject("ViewManager").getOpenEditor(mpName) |
562 editor = ericApp().getObject("ViewManager").getOpenEditor(mpName) |
529 majorVersionStr = editor.getLanguage() |
563 majorVersionStr = editor.getLanguage() |
530 else: |
564 else: |
531 parms = project.getData('CHECKERSPARMS', "PYLINT") |
565 parms = project.getData("CHECKERSPARMS", "PYLINT") |
532 majorVersionStr = project.getProjectLanguage() |
566 majorVersionStr = project.getProjectLanguage() |
533 exe, version = {"Python3": exePy3}.get(majorVersionStr) |
567 exe, version = {"Python3": exePy3}.get(majorVersionStr) |
534 if exe == '': |
568 if exe == "": |
535 EricMessageBox.critical( |
569 EricMessageBox.critical( |
536 None, |
570 None, |
537 self.tr("pylint"), |
571 self.tr("pylint"), |
538 self.tr("""The pylint executable could not be found.""")) |
572 self.tr("""The pylint executable could not be found."""), |
|
573 ) |
539 return |
574 return |
540 |
575 |
541 from PyLintInterface.PyLintConfigDialog import PyLintConfigDialog |
576 from PyLintInterface.PyLintConfigDialog import PyLintConfigDialog |
|
577 |
542 dlg = PyLintConfigDialog(project.getProjectPath(), exe, parms, version) |
578 dlg = PyLintConfigDialog(project.getProjectPath(), exe, parms, version) |
543 if dlg.exec() == QDialog.DialogCode.Accepted: |
579 if dlg.exec() == QDialog.DialogCode.Accepted: |
544 args, parms = dlg.generateParameters() |
580 args, parms = dlg.generateParameters() |
545 self.__editorParms = copy.deepcopy(parms) |
581 self.__editorParms = copy.deepcopy(parms) |
546 if not forEditor: |
582 if not forEditor: |
547 project.setData('CHECKERSPARMS', "PYLINT", parms) |
583 project.setData("CHECKERSPARMS", "PYLINT", parms) |
548 |
584 |
549 # now do the call |
585 # now do the call |
550 from PyLintInterface.PyLintExecDialog import PyLintExecDialog |
586 from PyLintInterface.PyLintExecDialog import PyLintExecDialog |
|
587 |
551 dlg2 = PyLintExecDialog() |
588 dlg2 = PyLintExecDialog() |
552 reportFile = parms.get('reportFile', None) |
589 reportFile = parms.get("reportFile", None) |
553 res = dlg2.start(args, mpName, reportFile, |
590 res = dlg2.start(args, mpName, reportFile, project.getProjectPath()) |
554 project.getProjectPath()) |
|
555 if res: |
591 if res: |
556 dlg2.show() |
592 dlg2.show() |
557 if forProject: |
593 if forProject: |
558 self.__pylintPDialog = dlg2 |
594 self.__pylintPDialog = dlg2 |
559 elif forEditor: |
595 elif forEditor: |
560 self.__editorPylintDialog = dlg2 |
596 self.__editorPylintDialog = dlg2 |
561 else: |
597 else: |
562 self.__pylintPsbDialog = dlg2 |
598 self.__pylintPsbDialog = dlg2 |
563 |
599 |
564 def __projectPylint(self): |
600 def __projectPylint(self): |
565 """ |
601 """ |
566 Private slot used to check the project files with Pylint. |
602 Private slot used to check the project files with Pylint. |
567 """ |
603 """ |
568 project = ericApp().getObject("Project") |
604 project = ericApp().getObject("Project") |
569 project.saveAllScripts() |
605 project.saveAllScripts() |
570 self.__pyLint(project, project.getProjectPath(), True) |
606 self.__pyLint(project, project.getProjectPath(), True) |
571 |
607 |
572 def __projectPylintShow(self): |
608 def __projectPylintShow(self): |
573 """ |
609 """ |
574 Private slot to show the PyLint dialog with the results of the last |
610 Private slot to show the PyLint dialog with the results of the last |
575 run. |
611 run. |
576 """ |
612 """ |
577 if self.__pylintPDialog is not None: |
613 if self.__pylintPDialog is not None: |
578 self.__pylintPDialog.show() |
614 self.__pylintPDialog.show() |
579 |
615 |
580 def __projectBrowserPylint(self): |
616 def __projectBrowserPylint(self): |
581 """ |
617 """ |
582 Private method to handle the Pylint context menu action of the project |
618 Private method to handle the Pylint context menu action of the project |
583 sources browser. |
619 sources browser. |
584 """ |
620 """ |
585 project = ericApp().getObject("Project") |
621 project = ericApp().getObject("Project") |
586 browser = ( |
622 browser = ericApp().getObject("ProjectBrowser").getProjectBrowser("sources") |
587 ericApp().getObject("ProjectBrowser").getProjectBrowser("sources") |
|
588 ) |
|
589 itm = browser.model().item(browser.currentIndex()) |
623 itm = browser.model().item(browser.currentIndex()) |
590 try: |
624 try: |
591 fn = itm.fileName() |
625 fn = itm.fileName() |
592 except AttributeError: |
626 except AttributeError: |
593 fn = itm.dirName() |
627 fn = itm.dirName() |
594 self.__pyLint(project, fn, False) |
628 self.__pyLint(project, fn, False) |
595 |
629 |
596 def __projectBrowserPylintShow(self): |
630 def __projectBrowserPylintShow(self): |
597 """ |
631 """ |
598 Private slot to show the PyLint dialog with the results of the last |
632 Private slot to show the PyLint dialog with the results of the last |
599 run. |
633 run. |
600 """ |
634 """ |
601 if self.__pylintPsbDialog is not None: |
635 if self.__pylintPsbDialog is not None: |
602 self.__pylintPsbDialog.show() |
636 self.__pylintPsbDialog.show() |
603 |
637 |
604 def __editorOpened(self, editor): |
638 def __editorOpened(self, editor): |
605 """ |
639 """ |
606 Private slot called, when a new editor was opened. |
640 Private slot called, when a new editor was opened. |
607 |
641 |
608 @param editor reference to the new editor |
642 @param editor reference to the new editor |
609 @type Editor |
643 @type Editor |
610 """ |
644 """ |
611 menu = editor.getMenu("Checks") |
645 menu = editor.getMenu("Checks") |
612 if menu is not None: |
646 if menu is not None: |
613 menu.addAction(self.__editorAct) |
647 menu.addAction(self.__editorAct) |
614 editor.showMenu.connect(self.__editorShowMenu) |
648 editor.showMenu.connect(self.__editorShowMenu) |
615 self.__editors.append(editor) |
649 self.__editors.append(editor) |
616 |
650 |
617 def __editorClosed(self, editor): |
651 def __editorClosed(self, editor): |
618 """ |
652 """ |
619 Private slot called, when an editor was closed. |
653 Private slot called, when an editor was closed. |
620 |
654 |
621 @param editor reference to the editor |
655 @param editor reference to the editor |
622 @type Editor |
656 @type Editor |
623 """ |
657 """ |
624 with contextlib.suppress(ValueError): |
658 with contextlib.suppress(ValueError): |
625 self.__editors.remove(editor) |
659 self.__editors.remove(editor) |
626 |
660 |
627 def __editorShowMenu(self, menuName, menu, editor): |
661 def __editorShowMenu(self, menuName, menu, editor): |
628 """ |
662 """ |
629 Private slot called, when the the editor context menu or a submenu is |
663 Private slot called, when the the editor context menu or a submenu is |
630 about to be shown. |
664 about to be shown. |
631 |
665 |
632 @param menuName name of the menu to be shown |
666 @param menuName name of the menu to be shown |
633 @type str |
667 @type str |
634 @param menu reference to the menu |
668 @param menu reference to the menu |
635 @type QMenu |
669 @type QMenu |
636 @param editor reference to the editor |
670 @param editor reference to the editor |