From b6684ebe02a0ab07665e043338ffa67b950ed8c5 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Mon, 25 Nov 2024 14:15:08 +0100 Subject: [PATCH] Switch linting to ruff This patch switches to ruff from pylint. We migrate a few suppressions from pylint's suppression format to the more general format used by ruff. Additionally we fix a few issues, e.g., around import sorting and globbing, shadowing, unnecessary import hacks for test imports and general style. --- .pre-commit-config.yaml | 18 +----------------- .pylintrc | 12 ------------ pyproject.toml | 4 ++++ tests/test_dir_recursion.py | 10 ++-------- tests/test_formatting.py | 5 ++--- tests/test_samples.py | 4 +--- tests/test_script.py | 8 +++----- tests/testutils.py | 11 +---------- zeek-format | 1 - zeek-script | 1 - zeekscript/__init__.py | 19 ++++++++++++------- zeekscript/cli.py | 10 ++++------ zeekscript/formatter.py | 3 --- zeekscript/output.py | 2 -- zeekscript/script.py | 10 +++++++--- 15 files changed, 37 insertions(+), 81 deletions(-) delete mode 100644 .pylintrc diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 026be82..e0acf47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,28 +9,12 @@ repos: - id: check-yaml - id: check-added-large-files -- repo: https://github.com/PyCQA/pylint - rev: v3.3.1 - hooks: - - id: pylint - additional_dependencies: - - "pytest==8.3.3" - - "syrupy==4.7.2" - - "setuptools" - - "tree-sitter==0.23.0" - - "tree-sitter-zeek==0.1.1" - - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.2 hooks: + - id: ruff - id: ruff-format -- repo: https://github.com/asottile/pyupgrade - rev: v3.19.0 - hooks: - - id: pyupgrade - args: ["--py37-plus"] - - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.42.0 hooks: diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 533e7ff..0000000 --- a/.pylintrc +++ /dev/null @@ -1,12 +0,0 @@ -[MASTER] -disable= - duplicate-code, - fixme, - missing-function-docstring, - missing-class-docstring, - too-many-arguments, - too-many-branches, - too-many-instance-attributes, - too-many-lines, - too-many-positional-arguments, - too-many-statements, diff --git a/pyproject.toml b/pyproject.toml index 9723a5f..761746e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,3 +47,7 @@ Repository = "https://github.com/zeek/zeekscript" [tool.setuptools] packages = ["zeekscript"] script-files = ["zeek-format", "zeek-script"] + +[tool.ruff.lint] +select = ["PL", "UP", "RUF", "N", "I"] +ignore = ["PLR"] diff --git a/tests/test_dir_recursion.py b/tests/test_dir_recursion.py index 6d0afa9..b826bd4 100755 --- a/tests/test_dir_recursion.py +++ b/tests/test_dir_recursion.py @@ -7,13 +7,9 @@ import shutil import unittest import unittest.mock - from os.path import join -# Sets up sys.path and provides helpers import testutils as tu - -# This imports the tree-local zeekscript from testutils import zeekscript @@ -36,13 +32,11 @@ def setUp(self): def tearDown(self): shutil.rmtree("a", ignore_errors=True) - # pylint: disable-next=invalid-name - def assertEqualContent(self, file1, content_expected): + def assertEqualContent(self, file1, content_expected): # noqa: N802 with open(file1, encoding="utf-8") as hdl1: self.assertEqual(hdl1.read(), content_expected) - # pylint: disable-next=invalid-name - def assertNotEqualContent(self, file1, content_expected): + def assertNotEqualContent(self, file1, content_expected): # noqa: N802 with open(file1, encoding="utf-8") as hdl1: self.assertNotEqual(hdl1.read(), content_expected) diff --git a/tests/test_formatting.py b/tests/test_formatting.py index 9ff15a8..1201c1b 100755 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -5,8 +5,8 @@ import os import pathlib import sys -import unittest import textwrap +import unittest # Sets up sys.path and provides helpers import testutils as tu @@ -94,8 +94,7 @@ def _format(self, content): return buf.getvalue(), script.get_error() - # pylint: disable-next=invalid-name - def assertFormatting(self, input_, baseline, error_baseline): + def assertFormatting(self, input_, baseline, error_baseline): # noqa: N802 # Verify formatting and reported error result1, error1 = self._format(tu.normalize(input_)) self.assertEqual(tu.normalize(baseline), result1) diff --git a/tests/test_samples.py b/tests/test_samples.py index 6ecd1b2..b74ebd5 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -14,7 +14,6 @@ import pytest from syrupy.assertion import SnapshotAssertion from syrupy.extensions.single_file import SingleFileSnapshotExtension - from testutils import zeekscript SAMPLES_DIR = Path(__file__).parent / "samples" @@ -23,7 +22,7 @@ # Use a custom snapshot fixture so we emit one file per generated test case # instead of one per module. @pytest.fixture -def snapshot(snapshot: SnapshotAssertion): # pylint: disable=redefined-outer-name +def snapshot(snapshot: SnapshotAssertion): return snapshot.use_extension(SingleFileSnapshotExtension) @@ -47,7 +46,6 @@ def _get_samples(): # For each file in `SAMPLES_DIR` test formatting of the file. @pytest.mark.parametrize("sample", _get_samples()) -# pylint: disable-next=redefined-outer-name def test_samples(sample: Path, snapshot: SnapshotAssertion): input_ = zeekscript.Script(sample) diff --git a/tests/test_script.py b/tests/test_script.py index 441daa4..0aa2c18 100755 --- a/tests/test_script.py +++ b/tests/test_script.py @@ -14,16 +14,14 @@ class TestScript(unittest.TestCase): def setUp(self): # This prints large diffs in case assertEqual() finds discrepancies. - self.maxDiff = None # pylint: disable=invalid-name + self.maxDiff = None - # pylint: disable-next=invalid-name - def assertTreeBinary(self, script, baseline, include_cst=False): + def assertTreeBinary(self, script, baseline, include_cst=False): # noqa: N802 buf = io.BytesIO() script.write_tree(output=buf, include_cst=include_cst) self.assertEqual(tu.normalize(baseline), buf.getvalue()) - # pylint: disable-next=invalid-name - def assertTreeText(self, script, baseline, include_cst=False): + def assertTreeText(self, script, baseline, include_cst=False): # noqa: N802 buf = io.StringIO() script.write_tree(output=buf, include_cst=include_cst) self.assertEqual(tu.fix_lineseps(baseline), buf.getvalue()) diff --git a/tests/testutils.py b/tests/testutils.py index be6b3f2..5d300e0 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -1,17 +1,8 @@ """Helpers for the various test_*.py files.""" import os -import sys -TESTS = os.path.dirname(os.path.realpath(__file__)) -ROOT = os.path.normpath(os.path.join(TESTS, "..")) - -# Prepend the tree's root folder to the module searchpath so we find zeekscript -# via it. This allows tests to run without package installation. (We do need a -# package build though, so the .so bindings library gets created.) -sys.path.insert(0, ROOT) - -import zeekscript # pylint: disable=wrong-import-position +import zeekscript def fix_lineseps(content): diff --git a/zeek-format b/zeek-format index 8b198ac..efc820f 100755 --- a/zeek-format +++ b/zeek-format @@ -1,5 +1,4 @@ #!/usr/bin/env python -# pylint: disable=invalid-name """ This is a Zeek script formatter. It intentionally accepts no formatting arguments. It writes any errors during processing to stderr. When errors arise, diff --git a/zeek-script b/zeek-script index 9f60ba9..fa56806 100755 --- a/zeek-script +++ b/zeek-script @@ -1,5 +1,4 @@ #!/usr/bin/env python -# pylint: disable=invalid-name """ This is a tool for processing Zeek scripts. It currently supports formatting scripts according to codified rules (no optionas at all atm), and showing a diff --git a/zeekscript/__init__.py b/zeekscript/__init__.py index 1cb16fd..a40fad3 100644 --- a/zeekscript/__init__.py +++ b/zeekscript/__init__.py @@ -1,11 +1,16 @@ """Wrapper around more low-level tests.""" __version__ = "1.2.9-38" -__all__ = ["cli", "error", "formatter", "node", "output", "script"] +__all__ = [ + "Formatter", + "Script", + "add_format_cmd", + "add_parse_cmd", + "add_version_arg", + "print_error", +] -from .cli import * -from .error import * -from .formatter import * -from .node import * -from .output import * -from .script import * +from .cli import add_format_cmd, add_parse_cmd, add_version_arg +from .formatter import Formatter +from .output import print_error +from .script import Script diff --git a/zeekscript/cli.py b/zeekscript/cli.py index 76bcc9a..59cb4c5 100644 --- a/zeekscript/cli.py +++ b/zeekscript/cli.py @@ -7,8 +7,8 @@ import traceback from .error import Error, ParserError -from .script import Script from .output import print_error +from .script import Script FILE_HELP = ( 'Use "-" to specify stdin as a filename. Omitting ' @@ -48,9 +48,9 @@ def cmd_format(args): elif os.path.isdir(fname): if args.recursive: # implies --inplace for dirpath, _, filenames in os.walk(fname): - filenames = [n for n in filenames if n.endswith(".zeek")] - filenames = [os.path.join(dirpath, n) for n in filenames] - scripts.extend(filenames) + names = [n for n in filenames if n.endswith(".zeek")] + names = [os.path.join(dirpath, n) for n in names] + scripts.extend(names) else: print_error( f'warning: "{fname}" is a directory but --recursive not set, skipping it' @@ -88,7 +88,6 @@ def do_write(source): print_error("parsing error: " + str(err)) do_write(script.source) return 1 - # pylint: disable-next=broad-exception-caught except Exception as err: print_error("internal error: " + str(err)) traceback.print_exc(file=sys.stderr) @@ -99,7 +98,6 @@ def do_write(source): try: script.format(buf, not args.no_linebreaks) - # pylint: disable-next=broad-exception-caught except Exception as err: print_error("internal error: " + str(err)) traceback.print_exc(file=sys.stderr) diff --git a/zeekscript/formatter.py b/zeekscript/formatter.py index bbbea2b..2fa2dc2 100644 --- a/zeekscript/formatter.py +++ b/zeekscript/formatter.py @@ -196,16 +196,13 @@ def _format_child_range(self, num, hints=None, first_hints=None): # First element of multiple: general hinting; first-element hinting; # avoid line breaks after the element. - # pylint: disable=unsupported-binary-operation self._format_child(hints=hints | first_hints | Hint.NO_LB_AFTER) # Inner elements: general hinting; avoid line breaks for _ in range(num - 2): - # pylint: disable=unsupported-binary-operation self._format_child(hints=hints | Hint.NO_LB_AFTER) # Last element: general hinting; avoid line break before - # pylint: disable=unsupported-binary-operation self._format_child(hints=hints | Hint.NO_LB_BEFORE) def _format_children(self, sep=None): diff --git a/zeekscript/output.py b/zeekscript/output.py index 2a46d22..3893a21 100644 --- a/zeekscript/output.py +++ b/zeekscript/output.py @@ -6,7 +6,6 @@ from .formatter import Formatter, Hint -# pylint: disable-next=too-few-public-methods class Output: """A chunk of data to write out. @@ -117,7 +116,6 @@ def _flush_line(self): after newlines, depending on line-breaking hints present in the formatter objects linked from the Output instances. """ - # pylint: disable=too-many-locals # Without linebreaking active, just flush the buffer. if not self._enable_linebreaks or not self._use_linebreaks: diff --git a/zeekscript/script.py b/zeekscript/script.py index 4119940..5ed2448 100644 --- a/zeekscript/script.py +++ b/zeekscript/script.py @@ -257,11 +257,15 @@ def node_str(node, nesting, script): def do_traverse(ostream): # Pylint wants def instead of lambdas here, which black then wants # to format, turning two simple lines into an abomination. Suppress: - # pylint: disable=unnecessary-lambda-assignment if isinstance(ostream, io.TextIOBase): - encode = lambda x: x + os.linesep + + def encode(x): + return x + os.linesep else: - encode = lambda x: x.encode("UTF-8") + Formatter.NL + + def encode(x): + return x.encode("UTF-8") + Formatter.NL + stringifier = node_stringifier if node_stringifier else node_str for node, nesting in self.traverse(include_cst): ostream.write(encode(stringifier(node, nesting, self)))