Sat, 08 Jul 2023 16:20:59 +0200
Syntax Checker
- Added code to guard against checking an empty file.
--- 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 [{}]