From afc6a3a6d38d0c40de6b06bf384e06a2064a4ec5 Mon Sep 17 00:00:00 2001 From: densnow <48718090+densnow@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:11:31 +0000 Subject: [PATCH] Fix #16: escape sequence error (#18) - pass list to subprocess, without modifying list in `checkers` - handle pathnames for Windows --- src/algoesup/magics.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/algoesup/magics.py b/src/algoesup/magics.py index d060217..a2cdb00 100644 --- a/src/algoesup/magics.py +++ b/src/algoesup/magics.py @@ -60,9 +60,9 @@ def show_pytype_errors(checker: str, output: str, filename: str) -> None: # register the supported checkers, their commands and the output processor checkers: dict[str, tuple[str, Callable]] = { - "pytype": ("pytype", show_pytype_errors), - "allowed": ("allowed", show_errors), - "ruff": ("ruff check --output-format json", show_ruff_json), + "pytype": [["pytype"], show_pytype_errors], + "allowed": [["allowed"], show_errors], + "ruff": [["ruff", "check", "--output-format", "json"], show_ruff_json], } # initially no checker is active active: set[str] = set() @@ -145,8 +145,8 @@ def allowed(line: str) -> None: ``` """ args = parse_argstring(allowed, line) - config = f"-c {args.config}" if args.config else "" - checkers["allowed"] = (f"allowed {config}", show_errors) + if args.config: + checkers["allowed"][0] = ["allowed", "-c", f"{args.config}"] process_status("allowed", args.status) @@ -228,17 +228,19 @@ def run_checkers(result) -> None: with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as temp: # transform IPython to pure Python to avoid linters reporting syntax errors temp.write(TransformerManager().transform_cell(result.info.raw_cell)) - temp_name = temp.name + # Backslash causes esc sequence error from standard Windows file paths, + # but Windows accepts both "\" and "/" as separators. + temp_name = temp.name.replace("\\", "/") for checker in active: command, display = checkers[checker] - command += " " + temp_name + lint_file = command + [temp_name] try: output = subprocess.run( - command, capture_output=True, text=True, check=False, shell=True + lint_file, capture_output=True, text=True, check=False, ).stdout display(checker, output, temp_name) except Exception as e: - print(f"Error on executing {command}:\n{e}") + print(f"Error on executing {command[0]}:\n{e}") except Exception as e: print(f"Error on writing cell to a temporary file:\n{e}") finally: @@ -248,9 +250,9 @@ def run_checkers(result) -> None: def load_ipython_extension(ipython): """Loads the ipython extension, and registers run_checkers with post_cell_run - This functions hooks into the ipython extension system so the magic commands defined + This function hooks into the ipython extension system so the magic commands defined in this module can be loaded with `load_ext algoesup.magics`. It also registers - run_checkers with the post_run_cell event so the linters are run with the contents of - each ipython cell after it has been executed. + `run_checkers` with the `post_run_cell` event so the linters are run with the + contents of each ipython cell after it has been executed. """ ipython.events.register("post_run_cell", run_checkers) # type: ignore[name-defined]