diff --git a/nancy/__init__.py b/nancy/__init__.py index a44318a..23e7c31 100644 --- a/nancy/__init__.py +++ b/nancy/__init__.py @@ -302,7 +302,7 @@ def main(argv: list[str] = sys.argv[1:]) -> None: inputs[0] = os.getcwd() expand(inputs, args.output, args.path) - except Exception as err: # pylint: disable=broad-exception-caught + except Exception as err: if "DEBUG" in os.environ: logging.error(err, exc_info=True) else: diff --git a/nancy/__main__.py b/nancy/__main__.py index 2cf508e..a9ab5b8 100644 --- a/nancy/__main__.py +++ b/nancy/__main__.py @@ -3,5 +3,6 @@ from . import main + sys.argv[0] = re.sub(r"__main__.py$", "nancy", sys.argv[0]) main() diff --git a/nancy/warnings_util.py b/nancy/warnings_util.py index b6dc50f..53a3bfd 100644 --- a/nancy/warnings_util.py +++ b/nancy/warnings_util.py @@ -1,23 +1,23 @@ -""" -Warning and error routines. +"""Warning and error routines. + Copyright (c) Reuben Thomas 2023. Released under the GPL version 3, or (at your option) any later version. """ import sys +from typing import Callable, NoReturn, Optional, TextIO, Union from warnings import warn -from typing import Callable, Optional, Union, Type, NoReturn, TextIO # Error messages def simple_warning(prog: str) -> Callable[..., None]: - def _warning( # pylint: disable=too-many-arguments + def _warning( message: Union[Warning, str], - category: Type[Warning], # pylint: disable=unused-argument - filename: str, # pylint: disable=unused-argument - lineno: int, # pylint: disable=unused-argument + category: type[Warning], + filename: str, + lineno: int, file: Optional[TextIO] = sys.stderr, - line: Optional[str] = None, # pylint: disable=unused-argument + line: Optional[str] = None, ) -> None: print(f"{prog}: {message}", file=file or sys.stderr) diff --git a/pyproject.toml b/pyproject.toml index 5c3dd97..fa614d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,36 +28,15 @@ requires = [ [tool.setuptools] packages = ["nancy"] -[tool.mypy] -exclude = ['^dist', '^build'] -strict = true - -[tool.pylint.main] -# Use multiple processes to speed up Pylint: 0 = auto-detect. -jobs = 0 - -[tool.pylint.MASTER] -init-hook = 'import sys; sys.path.append(".")' - -[tool.pylint.format] -const-naming-style = "any" -disable = [ - "missing-module-docstring", - "missing-class-docstring", - "missing-function-docstring", - "no-member", - "fixme", - "global-statement", - "redefined-outer-name", - "too-many-locals", - "too-many-branches", - "too-many-function-args", - "too-many-positional-arguments", - "too-many-statements", -] -enable = [ - "useless-suppression", -] - [tool.pytest.ini_options] addopts = "-p no:warnings" + +[tool.ruff.lint] +select = ["D", "E", "F", "I", "UP"] +ignore = ["D1", "D401", "D415", "E501"] + +[tool.ruff.lint.isort] +lines-after-imports = 2 + +[tool.ruff.lint.pydocstyle] +convention = "google" diff --git a/tests/test_nancy.py b/tests/test_nancy.py index 59dbe5e..a89ef1a 100644 --- a/tests/test_nancy.py +++ b/tests/test_nancy.py @@ -1,32 +1,33 @@ -""" -Nancy tests. +"""Nancy tests. + Copyright (c) Reuben Thomas 2024. Released under the GPL version 3, or (at your option) any later version. """ import os -import sys import socket -from pathlib import Path +import sys from collections.abc import Iterator +from pathlib import Path from tempfile import TemporaryDirectory from unittest import mock import pytest from pytest import CaptureFixture, LogCaptureFixture - from testutils import ( - passing_test, + check_links, + failing_cli_test, failing_test, passing_cli_test, - failing_cli_test, - check_links, + passing_test, ) + from nancy import main -if sys.version_info[:2] >= (3, 11): # pragma: no cover - from contextlib import chdir -else: # pragma: no cover + +if sys.version_info[:2] >= (3, 11): # pragma: no cover + from contextlib import chdir # pyright: ignore +else: # pragma: no cover from contextlib import contextmanager @contextmanager @@ -190,12 +191,11 @@ def test_trying_to_output_multiple_files_to_stdout_causes_an_error() -> None: def test_help_option_should_produce_output(capsys: CaptureFixture[str]) -> None: with pytest.raises(SystemExit) as e: main(["--help"]) - assert e.type == SystemExit + assert e.type is SystemExit assert e.value.code == 0 assert capsys.readouterr().out.find("A simple templating system.") != -1 -# pylint: disable-next=invalid-name def test_running_with_a_single_file_as_INPUT_PATH_should_work( capsys: CaptureFixture[str], ) -> None: @@ -241,7 +241,6 @@ def test_invalid_command_line_argument_causes_an_error( failing_cli_test(capsys, caplog, ["--foo", "a"], "unrecognized arguments: --foo") -# pylint: disable-next=invalid-name def test_running_on_a_nonexistent_path_causes_an_error_DEBUG_coverage( capsys: CaptureFixture[str], caplog: LogCaptureFixture, @@ -292,7 +291,6 @@ def test_absolute_build_path_causes_an_error( ) -# pylint: disable-next=invalid-name def test_empty_INPUT_PATH_causes_an_error( capsys: CaptureFixture[str], caplog: LogCaptureFixture, diff --git a/tests/testutils.py b/tests/testutils.py index 2e2788e..414d3a5 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -1,21 +1,22 @@ -""" -Nancy tests utility routines. +"""Nancy tests utility routines. + Copyright (c) Reuben Thomas 2023-2024. Released under the GPL version 3, or (at your option) any later version. """ import contextlib +import difflib +import filecmp import io import os -import sys -import subprocess import re -import filecmp -import difflib +import subprocess +import sys import tempfile -from tempfile import TemporaryDirectory +from contextlib import AbstractContextManager from dataclasses import dataclass -from typing import AnyStr, Callable, List, Optional, Union, ContextManager +from tempfile import TemporaryDirectory +from typing import Callable, Optional, Union import pytest from pytest import CaptureFixture, LogCaptureFixture @@ -26,7 +27,7 @@ @dataclass class Case: name: str - args: List[str] + args: list[str] expected: str path: Optional[str] = None error: Optional[int] = None @@ -34,7 +35,7 @@ class Case: def file_objects_equal( - a: Union[AnyStr, os.PathLike[AnyStr]], b: Union[os.PathLike[AnyStr], AnyStr] + a: Union[os.PathLike[str], str], b: Union[os.PathLike[str], str] ) -> bool: if os.path.isfile(a): with contextlib.ExitStack() as stack: @@ -61,12 +62,12 @@ def file_objects_equal( def passing_test( - input_dirs: List[str], + input_dirs: list[str], expected: str, build_path: Optional[str] = None, output_dir: Optional[str] = None, ) -> None: - ctx_mgr: Union[ContextManager[None], TemporaryDirectory[str]] + ctx_mgr: Union[AbstractContextManager[None], TemporaryDirectory[str]] if output_dir is None: ctx_mgr = tempfile.TemporaryDirectory() output_obj = os.path.join(ctx_mgr.name, "output") @@ -82,7 +83,7 @@ def passing_test( def failing_test( - input_dirs: List[str], + input_dirs: list[str], expected: str, build_path: Optional[str] = None, output_dir: Optional[str] = None, @@ -90,7 +91,7 @@ def failing_test( with TemporaryDirectory() as expected_dir: try: passing_test(input_dirs, expected_dir, build_path, output_dir) - except Exception as err: # pylint: disable=broad-exception-caught + except Exception as err: assert str(err).find(expected) != -1 return raise ValueError("test passed unexpectedly") # pragma: no cover @@ -98,13 +99,13 @@ def failing_test( def passing_cli_test( capsys: CaptureFixture[str], - args: List[str], + args: list[str], expected: str, output_dir: Optional[str] = None, ) -> None: tmp_dir = None if output_dir is None: - tmp_dir = TemporaryDirectory() # pylint: disable=consider-using-with + tmp_dir = TemporaryDirectory() output_obj = os.path.join(tmp_dir.name, "output") else: output_obj = output_dir @@ -124,13 +125,13 @@ def passing_cli_test( def failing_cli_test( capsys: CaptureFixture[str], caplog: LogCaptureFixture, - args: List[str], + args: list[str], expected: str, output_dir: Optional[str] = None, ) -> None: with pytest.raises(SystemExit) as e: passing_cli_test(capsys, args, "", output_dir) - assert e.type == SystemExit + assert e.type is SystemExit assert e.value.code != 0 err = capsys.readouterr().err log = caplog.messages diff --git a/tox.ini b/tox.ini index a44b9fe..11d9b38 100644 --- a/tox.ini +++ b/tox.ini @@ -9,12 +9,12 @@ xfail_strict = True deps = coverage LinkChecker - mypy - pylint + pyright + ruff types-setuptools commands = - mypy . - pylint nancy + pyright nancy + ruff check nancy coverage run -m pytest {posargs} coverage report --show-missing --skip-covered --fail-under=100 extras = test