From be77fdef069fe5d818cca742c56389c7ea53d6bf Mon Sep 17 00:00:00 2001 From: Manlio Perillo Date: Wed, 27 Dec 2023 11:47:14 +0100 Subject: [PATCH] test: exec the codespell executable consistently Currently, in test_basic.py, the run_codespell and run_codespell_stdin functions exec the codespell script from PATH, not the one from the current directory. This means that the codespell_lib package MUST first be installed, before running pytest. The current behavior is unsafe, since an user running pytest in the global environment may get an error or, worse, may actually try to test an old version. Additionally this behavior is not documented in README.md. Update the run_codespell and run_codespell_stdin functions to exec the codespell script via `python -m codespell_lib`. This change will ensure that python will try to search the __main__ module from the current directory first. Copy the codespell_lib directory to the cwd directory, and configure codespell to ignore it using the `-S` option, in order to make the environment clean. Ensure that the cwd parameter in run_codespell and run_codespell_stdin is never None, since the codespell script must not be executed from the current directory. For consistency, also make the args parameter required. --- codespell_lib/tests/test_basic.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py index e768917ceb5..9be9945203d 100644 --- a/codespell_lib/tests/test_basic.py +++ b/codespell_lib/tests/test_basic.py @@ -7,7 +7,7 @@ import sys from io import StringIO from pathlib import Path -from shutil import copyfile +from shutil import copyfile, copytree from typing import Any, Generator, Optional, Tuple, Union import pytest @@ -64,13 +64,15 @@ def main( def run_codespell( - args: Tuple[Any, ...] = (), - cwd: Optional[Path] = None, + args: Tuple[Any, ...], + cwd: Path, ) -> int: """Run codespell.""" + lib = "codespell_lib" + copytree(lib, cwd / lib, dirs_exist_ok=True) args = tuple(str(arg) for arg in args) proc = subprocess.run( - ["codespell", "--count", *args], # noqa: S603, S607 + [sys.executable, "-m", lib, "-S", lib, "--count", *args], # noqa: S603, S607 cwd=cwd, capture_output=True, encoding="utf-8", @@ -83,9 +85,9 @@ def run_codespell( def test_command(tmp_path: Path) -> None: """Test running the codespell executable.""" # With no arguments does "." - assert run_codespell(cwd=tmp_path) == 0 + assert run_codespell(args=(), cwd=tmp_path) == 0 (tmp_path / "bad.txt").write_text("abandonned\nAbandonned\nABANDONNED\nAbAnDoNnEd") - assert run_codespell(cwd=tmp_path) == 4 + assert run_codespell(args=(), cwd=tmp_path) == 4 def test_basic( @@ -1196,11 +1198,13 @@ def FakeStdin(text: str) -> Generator[None, None, None]: def run_codespell_stdin( text: str, args: Tuple[Any, ...], - cwd: Optional[Path] = None, + cwd: Path, ) -> int: """Run codespell in stdin mode and return number of lines in output.""" + lib = "codespell_lib" + copytree(lib, cwd / lib, dirs_exist_ok=True) proc = subprocess.run( - ["codespell", *args, "-"], # noqa: S603, S607 + [sys.executable, "-m", lib, "-S", lib, *args, "-"], # noqa: S603, S607 cwd=cwd, input=text, capture_output=True,