Sat, 02 Sep 2023 15:50:01 +0200
Syntax Checker
- Added code to the Python syntax checker to report Python Warnings.
--- a/docs/changelog.md Sat Sep 02 12:33:58 2023 +0200 +++ b/docs/changelog.md Sat Sep 02 15:50:01 2023 +0200 @@ -2,6 +2,8 @@ ### Version 23.10 - bug fixes +- Syntax Checker + - Added code to the Python syntax checker to report Python Warnings. - Third Party packages - Upgraded eradicate to version 2.3.0. - Upgraded pip-licenses to version 4.3.2.
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py Sat Sep 02 12:33:58 2023 +0200 +++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py Sat Sep 02 15:50:01 2023 +0200 @@ -432,7 +432,7 @@ _fn, lineno, col, code, msg = error self.__createResultItem(_fn, lineno, col, msg, code, False) - warnings = problems.get("warnings", []) + warnings = problems.get("py_warnings") + problems.get("warnings", []) if warnings: if self.__batch: try: @@ -447,12 +447,12 @@ self.noResults = False if source: try: - scr_line = source[lineno - 1].strip() + src_line = source[lineno - 1].strip() except IndexError: - scr_line = "" + src_line = "" else: - scr_line = "" - self.__createResultItem(filename, lineno, col, msg, scr_line, True) + src_line = "" + self.__createResultItem(filename, lineno, col, msg, src_line, True) self.progress += 1 self.checkProgress.setValue(self.progress)
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py Sat Sep 02 12:33:58 2023 +0200 +++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py Sat Sep 02 15:50:01 2023 +0200 @@ -107,10 +107,11 @@ @type bool @param additionalBuiltins list of names pyflakes should consider as builtins @type list of str - @return dictionary with the keys 'error' and 'warnings' which - hold a list containing details about the error/warnings - (file name, line number, column, codestring (only at syntax - errors), the message, a list with arguments for the message) + @return dictionary with the keys 'error', 'py_warnings' and 'warnings' which + hold a list containing details about the syntax error, Python warnings + and PyFlakes warnings (file name, line number, column, codestring (only + for syntax errors), the message and an optional list with arguments for + the message) @rtype dict """ return __pySyntaxAndPyflakesCheck( @@ -237,15 +238,38 @@ @type bool @param additionalBuiltins list of names pyflakes should consider as builtins @type list of str - @return dictionary with the keys 'error' and 'warnings' which - hold a list containing details about the error/ warnings - (file name, line number, column, codestring (only at syntax - errors), the message, a list with arguments for the message) + @return dictionary with the keys 'error', 'py_warnings' and 'warnings' which + hold a list containing details about the syntax error, Python warnings + and PyFlakes warnings (file name, line number, column, codestring (only + for syntax errors), the message and an optional list with arguments for + the message) @rtype dict """ if codestring: - warnings.filterwarnings("error") errorDict = {} + pyWarnings = [] + + def showwarning( + message, + category, + filename, + lineno, + file=None, # noqa: U100 + line=None, # noqa: U100 + ): + pyWarnings.append( + ( + filename, + lineno, + 0, + "", + "{0}: {1}".format(category.__name__, message), + ) + ) + + warnings.showwarning = showwarning + warnings.filterwarnings("always") + try: # Check for VCS conflict markers for conflictMarkerRe in VcsConflictMarkerRegExpList: @@ -321,42 +345,42 @@ finally: warnings.resetwarnings() - # return the syntax error or warning, if one was detected + # return the syntax error, if one was detected if errorDict: return [errorDict] # pyflakes - if not checkFlakes: - return [{}] - results = [] - lines = codestring.splitlines() - try: - flakesWarnings = Checker( - module, filename, builtins=additionalBuiltins, withDoctest=True - ) - flakesWarnings.messages.sort(key=lambda a: a.lineno) - for flakesWarning in flakesWarnings.messages: - if ignoreStarImportWarnings and isinstance( - flakesWarning, (ImportStarUsed, ImportStarUsage) - ): - continue + if checkFlakes: + lines = codestring.splitlines() + try: + flakesWarnings = Checker( + module, filename, builtins=additionalBuiltins, withDoctest=True + ) + flakesWarnings.messages.sort(key=lambda a: a.lineno) + for flakesWarning in flakesWarnings.messages: + if ignoreStarImportWarnings and isinstance( + flakesWarning, (ImportStarUsed, ImportStarUsage) + ): + continue - _fn, lineno, col, message, msg_args = flakesWarning.getMessageData() - lineFlags = extractLineFlags(lines[lineno - 1].strip()) - with contextlib.suppress(IndexError): - lineFlags += extractLineFlags(lines[lineno].strip(), flagsLine=True) - if ( - "__IGNORE_WARNING__" not in lineFlags - and "__IGNORE_FLAKES_WARNING__" not in lineFlags - and "noqa" not in lineFlags - ): - results.append((_fn, lineno, col, "", message, msg_args)) - except SyntaxError as err: - msg = err.text.strip() if err.text.strip() else err.msg - results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, [])) + _fn, lineno, col, message, msg_args = flakesWarning.getMessageData() + lineFlags = extractLineFlags(lines[lineno - 1].strip()) + with contextlib.suppress(IndexError): + lineFlags += extractLineFlags( + lines[lineno].strip(), flagsLine=True + ) + if ( + "__IGNORE_WARNING__" not in lineFlags + and "__IGNORE_FLAKES_WARNING__" not in lineFlags + and "noqa" not in lineFlags + ): + results.append((_fn, lineno, col, "", message, msg_args)) + except SyntaxError as err: + msg = err.text.strip() if err.text.strip() else err.msg + results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, [])) - return [{"warnings": results}] + return [{"py_warnings": pyWarnings, "warnings": results}] else: return [{}]
--- a/src/eric7/QScintilla/Editor.py Sat Sep 02 12:33:58 2023 +0200 +++ b/src/eric7/QScintilla/Editor.py Sat Sep 02 15:50:01 2023 +0200 @@ -147,7 +147,8 @@ mouseDoubleClick = pyqtSignal(QPoint, Qt.MouseButton) WarningCode = 1 - WarningStyle = 2 + WarningPython = 2 + WarningStyle = 3 # Autocompletion icon definitions ClassID = 1 @@ -6231,9 +6232,13 @@ _fn, lineno, col, code, msg = error self.toggleSyntaxError(lineno, col, True, msg) + warnings = problems.get("py_warnings", []) + for _fn, lineno, col, _code, msg in warnings: + self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningPython) + warnings = problems.get("warnings", []) for _fn, lineno, col, _code, msg in warnings: - self.toggleWarning(lineno, col, True, msg) + self.toggleWarning(lineno, col, True, msg, warningType=Editor.WarningCode) self.updateVerticalScrollBar() @@ -6801,6 +6806,7 @@ Public slot to clear all pyflakes warnings. """ self.__clearTypedWarning(Editor.WarningCode) + self.__clearTypedWarning(Editor.WarningPython) def clearStyleWarnings(self): """ @@ -6813,7 +6819,7 @@ Private method to clear warnings of a specific kind. @param warningKind kind of warning to clear (Editor.WarningCode, - Editor.WarningStyle) + Editor.WarningPython, Editor.WarningStyle) """ for handle in list(self.warnings.keys()): warnings = [] @@ -6927,8 +6933,10 @@ for handle in self.warnings: if self.markerLine(handle) == line: for msg, warningType in self.warnings[handle]: - if warningType == self.WarningStyle: + if warningType == Editor.WarningStyle: styleAnnotations.append(self.tr("Style: {0}").format(msg)) + elif warningType == Editor.WarningPython: + warningAnnotations.append(msg) else: warningAnnotations.append( self.tr("Warning: {0}").format(msg)