Syntax Checker eric7

Sat, 02 Sep 2023 15:50:01 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 02 Sep 2023 15:50:01 +0200
branch
eric7
changeset 10188
0f873791d67e
parent 10187
cd500ea7f787
child 10189
1ab3a4674cb4

Syntax Checker
- Added code to the Python syntax checker to report Python Warnings.

docs/changelog.md file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/Editor.py file | annotate | diff | comparison | revisions
--- 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)

eric ide

mercurial