Syntax Checker eric7

Sat, 08 Jul 2023 16:20:59 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 08 Jul 2023 16:20:59 +0200
branch
eric7
changeset 10111
049fbbd2253d
parent 10110
009526532fa5
child 10112
dcbb8703b5b2

Syntax Checker
- Added code to guard against checking an empty file.

src/eric7/Plugins/CheckerPlugins/SyntaxChecker/jsonCheckSyntax.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/SyntaxChecker/yamlCheckSyntax.py file | annotate | diff | comparison | revisions
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/jsonCheckSyntax.py	Sat Jul 08 12:08:27 2023 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/jsonCheckSyntax.py	Sat Jul 08 16:20:59 2023 +0200
@@ -146,7 +146,7 @@
 
 def __jsonSyntaxCheck(file, codestring):
     """
-    Function to check a YAML source file for syntax errors.
+    Function to check a JSON source file for syntax errors.
 
     @param file source filename
     @type str
@@ -158,16 +158,17 @@
             errors), the message, a list with arguments for the message)
     @rtype dict
     """
-    try:
-        json.loads(codestring)
-    except json.JSONDecodeError as exc:
-        line = exc.lineno
-        column = exc.colno
-        error = exc.msg
+    if codestring:
+        try:
+            json.loads(codestring)
+        except json.JSONDecodeError as exc:
+            line = exc.lineno
+            column = exc.colno
+            error = exc.msg
 
-        cline = min(len(codestring.splitlines()), int(line)) - 1
-        code = codestring.splitlines()[cline]
+            cline = min(len(codestring.splitlines()), int(line)) - 1
+            code = codestring.splitlines()[cline]
 
-        return [{"error": (file, line, column, code, error)}]
+            return [{"error": (file, line, column, code, error)}]
 
     return [{}]
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py	Sat Jul 08 12:08:27 2023 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/pyCheckSyntax.py	Sat Jul 08 16:20:59 2023 +0200
@@ -242,96 +242,112 @@
             errors), the message, a list with arguments for the message)
     @rtype dict
     """
-    try:
-        # Check for VCS conflict markers
-        for conflictMarkerRe in VcsConflictMarkerRegExpList:
-            conflict = conflictMarkerRe.search(codestring)
-            if conflict is not None:
-                start, i = conflict.span()
-                lineindex = 1 + codestring.count("\n", 0, start)
-                return [
-                    {"error": (filename, lineindex, 0, "", "VCS conflict marker found")}
-                ]
-
-        if filename.endswith(".ptl"):
-            try:
-                import quixote.ptl_compile  # __IGNORE_WARNING_I10__
-            except ImportError:
-                return [{"error": (filename, 0, 0, "", "Quixote plugin not found.")}]
-            template = quixote.ptl_compile.Template(codestring, filename)
-            template.compile()
-        else:
-            module = builtins.compile(codestring, filename, "exec", ast.PyCF_ONLY_AST)
-    except SyntaxError as detail:
-        index = 0
-        code = ""
-        error = ""
-        lines = traceback.format_exception_only(SyntaxError, detail)
-        match = re.match(
-            r'\s*File "(.+)", line (\d+)', lines[0].replace("<string>", filename)
-        )
-        if match is not None:
-            fn, line = match.group(1, 2)
-            if lines[1].startswith("SyntaxError:"):
-                error = re.match("SyntaxError: (.+)", lines[1]).group(1)
-            else:
-                code = re.match("(.+)", lines[1]).group(1)
-                for seLine in lines[2:]:
-                    if seLine.startswith("SyntaxError:"):
-                        error = re.match("SyntaxError: (.+)", seLine).group(1)
-                    elif seLine.rstrip().endswith("^"):
-                        index = len(seLine.rstrip()) - 4
-        else:
-            fn = detail.filename
-            line = detail.lineno or 1
-            error = detail.msg
-        return [{"error": (fn, int(line), index, code.strip(), error)}]
-    except ValueError as detail:
+    if codestring:
         try:
-            fn = detail.filename
-            line = detail.lineno
-            error = detail.msg
-        except AttributeError:
-            fn = filename
-            line = 1
-            error = str(detail)
-        return [{"error": (fn, line, 0, "", error)}]
-    except Exception as detail:
-        with contextlib.suppress(AttributeError):
-            fn = detail.filename
-            line = detail.lineno
-            error = detail.msg
-            return [{"error": (fn, line, 0, "", error)}]
-
-    # pyflakes
-    if not checkFlakes:
-        return [{}]
+            # Check for VCS conflict markers
+            for conflictMarkerRe in VcsConflictMarkerRegExpList:
+                conflict = conflictMarkerRe.search(codestring)
+                if conflict is not None:
+                    start, i = conflict.span()
+                    lineindex = 1 + codestring.count("\n", 0, start)
+                    return [
+                        {
+                            "error": (
+                                filename,
+                                lineindex,
+                                0,
+                                "",
+                                "VCS conflict marker found",
+                            )
+                        }
+                    ]
 
-    results = []
-    lines = codestring.splitlines()
-    try:
-        warnings = Checker(
-            module, filename, builtins=additionalBuiltins, withDoctest=True
-        )
-        warnings.messages.sort(key=lambda a: a.lineno)
-        for warning in warnings.messages:
-            if ignoreStarImportWarnings and isinstance(
-                warning, (ImportStarUsed, ImportStarUsage)
-            ):
-                continue
+            if filename.endswith(".ptl"):
+                try:
+                    import quixote.ptl_compile  # __IGNORE_WARNING_I10__
+                except ImportError:
+                    return [
+                        {"error": (filename, 0, 0, "", "Quixote plugin not found.")}
+                    ]
+                template = quixote.ptl_compile.Template(codestring, filename)
+                template.compile()
+            else:
+                module = builtins.compile(
+                    codestring, filename, "exec", ast.PyCF_ONLY_AST
+                )
+        except SyntaxError as detail:
+            index = 0
+            code = ""
+            error = ""
+            lines = traceback.format_exception_only(SyntaxError, detail)
+            match = re.match(
+                r'\s*File "(.+)", line (\d+)', lines[0].replace("<string>", filename)
+            )
+            if match is not None:
+                fn, line = match.group(1, 2)
+                if lines[1].startswith("SyntaxError:"):
+                    error = re.match("SyntaxError: (.+)", lines[1]).group(1)
+                else:
+                    code = re.match("(.+)", lines[1]).group(1)
+                    for seLine in lines[2:]:
+                        if seLine.startswith("SyntaxError:"):
+                            error = re.match("SyntaxError: (.+)", seLine).group(1)
+                        elif seLine.rstrip().endswith("^"):
+                            index = len(seLine.rstrip()) - 4
+            else:
+                fn = detail.filename
+                line = detail.lineno or 1
+                error = detail.msg
+            return [{"error": (fn, int(line), index, code.strip(), error)}]
+        except ValueError as detail:
+            try:
+                fn = detail.filename
+                line = detail.lineno
+                error = detail.msg
+            except AttributeError:
+                fn = filename
+                line = 1
+                error = str(detail)
+            return [{"error": (fn, line, 0, "", error)}]
+        except Exception as detail:
+            with contextlib.suppress(AttributeError):
+                fn = detail.filename
+                line = detail.lineno
+                error = detail.msg
+                return [{"error": (fn, line, 0, "", error)}]
 
-            _fn, lineno, col, message, msg_args = warning.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, []))
+        # pyflakes
+        if not checkFlakes:
+            return [{}]
+
+        results = []
+        lines = codestring.splitlines()
+        try:
+            warnings = Checker(
+                module, filename, builtins=additionalBuiltins, withDoctest=True
+            )
+            warnings.messages.sort(key=lambda a: a.lineno)
+            for warning in warnings.messages:
+                if ignoreStarImportWarnings and isinstance(
+                    warning, (ImportStarUsed, ImportStarUsage)
+                ):
+                    continue
 
-    return [{"warnings": results}]
+                _fn, lineno, col, message, msg_args = warning.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}]
+
+    else:
+        return [{}]
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py	Sat Jul 08 12:08:27 2023 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py	Sat Jul 08 16:20:59 2023 +0200
@@ -157,30 +157,31 @@
             errors), the message, a list with arguments for the message)
     @rtype dict
     """
-    try:
-        import tomlkit  # __IGNORE_WARNING_I10__
+    if codestring:
+        try:
+            import tomlkit  # __IGNORE_WARNING_I10__
 
-        from tomlkit.exceptions import (  # __IGNORE_WARNING_I10__
-            KeyAlreadyPresent,
-            ParseError,
-        )
-    except ImportError:
-        error = "tomlkit not available. Install it via the PyPI interface."
-        return [{"error": (file, 0, 0, "", error)}]
+            from tomlkit.exceptions import (  # __IGNORE_WARNING_I10__
+                KeyAlreadyPresent,
+                ParseError,
+            )
+        except ImportError:
+            error = "tomlkit not available. Install it via the PyPI interface."
+            return [{"error": (file, 0, 0, "", error)}]
 
-    try:
-        tomlkit.parse(codestring)
-    except ParseError as exc:
-        line = exc.line
-        column = exc.col
-        error = str(exc).split(" at ", 1)[0].strip()
-        # get error message without location
+        try:
+            tomlkit.parse(codestring)
+        except ParseError as exc:
+            line = exc.line
+            column = exc.col
+            error = str(exc).split(" at ", 1)[0].strip()
+            # get error message without location
 
-        cline = min(len(codestring.splitlines()), int(line)) - 1
-        code = codestring.splitlines()[cline]
+            cline = min(len(codestring.splitlines()), int(line)) - 1
+            code = codestring.splitlines()[cline]
 
-        return [{"error": (file, line, column, code, error)}]
-    except KeyAlreadyPresent as exc:
-        return [{"error": (file, 0, 0, "", str(exc))}]
+            return [{"error": (file, line, column, code, error)}]
+        except KeyAlreadyPresent as exc:
+            return [{"error": (file, 0, 0, "", str(exc))}]
 
     return [{}]
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/yamlCheckSyntax.py	Sat Jul 08 12:08:27 2023 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/yamlCheckSyntax.py	Sat Jul 08 16:20:59 2023 +0200
@@ -157,27 +157,28 @@
             errors), the message, a list with arguments for the message)
     @rtype dict
     """
-    try:
-        from yaml import MarkedYAMLError, safe_load_all  # __IGNORE_WARNING_I10__
-    except ImportError:
-        error = "pyyaml not available. Install it via the PyPI interface."
-        return [{"error": (file, 0, 0, "", error)}]
+    if codestring:
+        try:
+            from yaml import MarkedYAMLError, safe_load_all  # __IGNORE_WARNING_I10__
+        except ImportError:
+            error = "pyyaml not available. Install it via the PyPI interface."
+            return [{"error": (file, 0, 0, "", error)}]
 
-    try:
-        for _obj in safe_load_all(codestring):
-            # do nothing with it, just to get parse errors
-            pass
-    except MarkedYAMLError as exc:
-        if exc.problem_mark:
-            line = exc.problem_mark.line + 1
-            column = exc.problem_mark.column
-        else:
-            line, column = 0, 0
-        error = exc.problem
+        try:
+            for _obj in safe_load_all(codestring):
+                # do nothing with it, just to get parse errors
+                pass
+        except MarkedYAMLError as exc:
+            if exc.problem_mark:
+                line = exc.problem_mark.line + 1
+                column = exc.problem_mark.column
+            else:
+                line, column = 0, 0
+            error = exc.problem
 
-        cline = min(len(codestring.splitlines()), int(line)) - 1
-        code = codestring.splitlines()[cline]
+            cline = min(len(codestring.splitlines()), int(line)) - 1
+            code = codestring.splitlines()[cline]
 
-        return [{"error": (file, line, column, code, error)}]
+            return [{"error": (file, line, column, code, error)}]
 
     return [{}]

eric ide

mercurial