diff options
author | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2023-03-14 19:44:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-14 19:44:38 +0100 |
commit | 1eef2273aee4c5a2e287f7470d6da3a3ae7d0760 (patch) | |
tree | cb29286317426645a9e42eb04f66d4cdf31afeb3 | |
parent | 0d463f6e2127b81e2d13c482871f82b4c991f7bd (diff) | |
download | pylint-git-1eef2273aee4c5a2e287f7470d6da3a3ae7d0760.tar.gz |
[ruff] Add RUF specific rules and autofix (#8449)
-rw-r--r-- | pylint/checkers/base/basic_checker.py | 2 | ||||
-rw-r--r-- | pylint/checkers/stdlib.py | 2 | ||||
-rw-r--r-- | pylint/checkers/typecheck.py | 2 | ||||
-rw-r--r-- | pylint/checkers/utils.py | 2 | ||||
-rw-r--r-- | pylint/checkers/variables.py | 4 | ||||
-rw-r--r-- | pylint/config/find_default_config_files.py | 2 | ||||
-rw-r--r-- | pylint/lint/expand_modules.py | 2 | ||||
-rw-r--r-- | pylint/lint/parallel.py | 2 | ||||
-rw-r--r-- | pylint/lint/pylinter.py | 3 | ||||
-rw-r--r-- | pylint/reporters/ureports/nodes.py | 2 | ||||
-rw-r--r-- | pyproject.toml | 2 | ||||
-rw-r--r-- | tests/checkers/unittest_format.py | 7 | ||||
-rw-r--r-- | tests/lint/unittest_lint.py | 4 | ||||
-rw-r--r-- | tests/primer/test_primer_external.py | 2 | ||||
-rw-r--r-- | tests/primer/test_primer_stdlib.py | 2 | ||||
-rw-r--r-- | tests/test_func.py | 2 | ||||
-rw-r--r-- | tests/test_self.py | 22 | ||||
-rw-r--r-- | tests/testutils/_primer/test_package_to_lint.py | 3 | ||||
-rw-r--r-- | tests/testutils/_primer/test_primer.py | 4 |
19 files changed, 38 insertions, 33 deletions
diff --git a/pylint/checkers/base/basic_checker.py b/pylint/checkers/base/basic_checker.py index 08d582b7f..252266109 100644 --- a/pylint/checkers/base/basic_checker.py +++ b/pylint/checkers/base/basic_checker.py @@ -329,7 +329,7 @@ class BasicChecker(_BasicChecker): nodes.Subscript, ) inferred = None - emit = isinstance(test, (nodes.Const,) + structs + const_nodes) + emit = isinstance(test, (nodes.Const, *structs, *const_nodes)) maybe_generator_call = None if not isinstance(test, except_nodes): inferred = utils.safe_infer(test) diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py index 96b273c74..82b4188a6 100644 --- a/pylint/checkers/stdlib.py +++ b/pylint/checkers/stdlib.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: DeprecationDict = Dict[Tuple[int, int, int], Set[str]] OPEN_FILES_MODE = ("open", "file") -OPEN_FILES_FUNCS = OPEN_FILES_MODE + ("read_text", "write_text") +OPEN_FILES_FUNCS = (*OPEN_FILES_MODE, "read_text", "write_text") UNITTEST_CASE = "unittest.case" THREADING_THREAD = "threading.Thread" COPY_COPY = "copy.copy" diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 8e00384d7..254ad78f9 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -157,7 +157,7 @@ def _(node: nodes.ClassDef | bases.Instance) -> Iterable[str]: def _string_distance(seq1: str, seq2: str) -> int: seq2_length = len(seq2) - row = list(range(1, seq2_length + 1)) + [0] + row = [*list(range(1, seq2_length + 1)), 0] for seq1_index, seq1_char in enumerate(seq1): last_row = row row = [0] * seq2_length + [seq1_index + 1] diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index 0104ff532..c99c90457 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -358,7 +358,7 @@ def is_defined_before(var_node: nodes.Name) -> bool: if defnode is None: continue defnode_scope = defnode.scope() - if isinstance(defnode_scope, COMP_NODE_TYPES + (nodes.Lambda,)): + if isinstance(defnode_scope, (*COMP_NODE_TYPES, nodes.Lambda)): # Avoid the case where var_node_scope is a nested function # FunctionDef is a Lambda until https://github.com/PyCQA/astroid/issues/291 if isinstance(defnode_scope, nodes.FunctionDef): diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 25ca3bc7c..e240e7f7c 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2234,7 +2234,7 @@ class VariablesChecker(BaseChecker): return any( VariablesChecker._maybe_used_and_assigned_at_once(elt) for elt in defstmt.value.elts - if isinstance(elt, NODES_WITH_VALUE_ATTR + (nodes.IfExp, nodes.Match)) + if isinstance(elt, (*NODES_WITH_VALUE_ATTR, nodes.IfExp, nodes.Match)) ) value = defstmt.value if isinstance(value, nodes.IfExp): @@ -2876,7 +2876,7 @@ class VariablesChecker(BaseChecker): @staticmethod def _nodes_to_unpack(node: nodes.NodeNG) -> list[nodes.NodeNG] | None: """Return the list of values of the `Assign` node.""" - if isinstance(node, (nodes.Tuple, nodes.List) + DICT_TYPES): + if isinstance(node, (nodes.Tuple, nodes.List, *DICT_TYPES)): return node.itered() # type: ignore[no-any-return] if isinstance(node, astroid.Instance) and any( ancestor.qname() == "typing.NamedTuple" for ancestor in node.ancestors() diff --git a/pylint/config/find_default_config_files.py b/pylint/config/find_default_config_files.py index 15c0d35bc..32429096d 100644 --- a/pylint/config/find_default_config_files.py +++ b/pylint/config/find_default_config_files.py @@ -16,7 +16,7 @@ else: import tomli as tomllib RC_NAMES = (Path("pylintrc"), Path(".pylintrc")) -CONFIG_NAMES = RC_NAMES + (Path("pyproject.toml"), Path("setup.cfg")) +CONFIG_NAMES = (*RC_NAMES, Path("pyproject.toml"), Path("setup.cfg")) def _toml_has_config(path: Path | str) -> bool: diff --git a/pylint/lint/expand_modules.py b/pylint/lint/expand_modules.py index 6ee96e4bd..73d7c45f8 100644 --- a/pylint/lint/expand_modules.py +++ b/pylint/lint/expand_modules.py @@ -88,7 +88,7 @@ def expand_modules( ): continue module_package_path = discover_package_path(something, source_roots) - additional_search_path = [".", module_package_path] + path + additional_search_path = [".", module_package_path, *path] if os.path.exists(something): # this is a file or a directory try: diff --git a/pylint/lint/parallel.py b/pylint/lint/parallel.py index a5e1a4665..80b86b5e8 100644 --- a/pylint/lint/parallel.py +++ b/pylint/lint/parallel.py @@ -165,4 +165,4 @@ def check_parallel( linter.msg_status |= msg_status _merge_mapreduce_data(linter, all_mapreduce_data) - linter.stats = merge_stats([linter.stats] + all_stats) + linter.stats = merge_stats([linter.stats, *all_stats]) diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index cec815ae5..90f7cd75c 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -311,7 +311,8 @@ class PyLinter( self.options: Options = options + _make_linter_options(self) for opt_group in option_groups: self.option_groups_descs[opt_group[0]] = opt_group[1] - self._option_groups: tuple[tuple[str, str], ...] = option_groups + ( + self._option_groups: tuple[tuple[str, str], ...] = ( + *option_groups, ("Messages control", "Options controlling analysis messages"), ("Reports", "Options related to output formatting and reporting"), ) diff --git a/pylint/reporters/ureports/nodes.py b/pylint/reporters/ureports/nodes.py index 8b6bf32c6..a09ca8922 100644 --- a/pylint/reporters/ureports/nodes.py +++ b/pylint/reporters/ureports/nodes.py @@ -72,7 +72,7 @@ class BaseLayout(VNode): assert self.parent is not self if self.parent is None: return [] - return [self.parent] + self.parent.parents() + return [self.parent, *self.parent.parents()] def add_text(self, text: str) -> None: """Shortcut to add text data.""" diff --git a/pyproject.toml b/pyproject.toml index 238b1fcb0..37afb2974 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -143,6 +143,7 @@ select = [ "W", # pycodestyle "B", # bugbear "I", # isort + "RUF", # ruff ] ignore = [ @@ -155,4 +156,5 @@ fixable = [ "W", # pycodestyle "B", # bugbear "I", # isort + "RUF", # ruff ] diff --git a/tests/checkers/unittest_format.py b/tests/checkers/unittest_format.py index fd0699daa..bce643b52 100644 --- a/tests/checkers/unittest_format.py +++ b/tests/checkers/unittest_format.py @@ -148,9 +148,10 @@ class TestCheckSpace(CheckerTestCase): encoding_token = tokenize.TokenInfo( tokenize.ENCODING, "utf-8", (0, 0), (0, 0), "" ) - tokens = [encoding_token] + _tokenize_str( - "if (\n None):\n pass\n" - ) + tokens = [ + encoding_token, + *_tokenize_str("if (\n None):\n pass\n"), + ] self.checker.process_tokens(tokens) diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py index 4808151b8..57c9a83d0 100644 --- a/tests/lint/unittest_lint.py +++ b/tests/lint/unittest_lint.py @@ -127,7 +127,7 @@ def test_no_args(fake_path: list[str]) -> None: def test_one_arg(fake_path: list[str], case: list[str]) -> None: with tempdir() as chroot: create_files(["a/b/__init__.py"]) - expected = [join(chroot, "a")] + fake_path + expected = [join(chroot, "a"), *fake_path] extra_sys_paths = [ expand_modules.discover_package_path(arg, []) for arg in case @@ -151,7 +151,7 @@ def test_one_arg(fake_path: list[str], case: list[str]) -> None: def test_two_similar_args(fake_path: list[str], case: list[str]) -> None: with tempdir() as chroot: create_files(["a/b/__init__.py", "a/c/__init__.py"]) - expected = [join(chroot, "a")] + fake_path + expected = [join(chroot, "a"), *fake_path] extra_sys_paths = [ expand_modules.discover_package_path(arg, []) for arg in case diff --git a/tests/primer/test_primer_external.py b/tests/primer/test_primer_external.py index 01b1367b1..65e21f280 100644 --- a/tests/primer/test_primer_external.py +++ b/tests/primer/test_primer_external.py @@ -64,7 +64,7 @@ class TestPrimer: enables = ["--enable-all-extensions", "--enable=all"] # Duplicate code takes too long and is relatively safe disables = ["--disable=duplicate-code"] - command = ["pylint"] + enables + disables + package.pylint_args + command = ["pylint", *enables, *disables, *package.pylint_args] logging.info("Launching primer:\n%s", " ".join(command)) subprocess.run(command, check=True) except subprocess.CalledProcessError as ex: diff --git a/tests/primer/test_primer_stdlib.py b/tests/primer/test_primer_stdlib.py index c2d879764..1a0adacdf 100644 --- a/tests/primer/test_primer_stdlib.py +++ b/tests/primer/test_primer_stdlib.py @@ -63,7 +63,7 @@ def test_primer_stdlib_no_crash( disables = ["--disable=duplicate-code", "--ignore=test"] with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) - Run([test_module_name] + enables + disables) + Run([test_module_name, *enables, *disables]) except SystemExit as ex: out, err = capsys.readouterr() assert not err, err diff --git a/tests/test_func.py b/tests/test_func.py index f67b89391..f68e53135 100644 --- a/tests/test_func.py +++ b/tests/test_func.py @@ -72,7 +72,7 @@ class LintTestUsingModule: try: self.linter.check(tocheck) except Exception as ex: - print(f"Exception: {ex} in {tocheck}:: {'‚ '.join(ex.args)}") + print(f"Exception: {ex} in {tocheck}:: {', '.join(ex.args)}") # This is legacy code we're trying to remove, not worth it to type correctly ex.file = tocheck # type: ignore[attr-defined] print(ex) diff --git a/tests/test_self.py b/tests/test_self.py index a4c928e5c..988862ab2 100644 --- a/tests/test_self.py +++ b/tests/test_self.py @@ -133,7 +133,7 @@ class TestRunTC: @staticmethod def _run_pylint(args: list[str], out: TextIO, reporter: Any = None) -> int: - args = _add_rcfile_default_pylintrc(args + ["--persistent=no"]) + args = _add_rcfile_default_pylintrc([*args, "--persistent=no"]) with _patch_streams(out): with pytest.raises(SystemExit) as cm: with warnings.catch_warnings(): @@ -775,7 +775,7 @@ a.py:1:4: E0001: Parsing failed: 'invalid syntax (<unknown>, line 1)' (syntax-er ) def test_fail_on_edge_case(self, opts: list[str], out: int) -> None: self._runtest( - opts + [join(HERE, "regrtest_data", "fail_under_plus7_5.py")], + [*opts, join(HERE, "regrtest_data", "fail_under_plus7_5.py")], code=out, ) @@ -898,7 +898,7 @@ a.py:1:4: E0001: Parsing failed: 'invalid syntax (<unknown>, line 1)' (syntax-er for path in ("astroid.py", "hmac.py"): file_path = tmp_path / path file_path.write_text("'Docstring'\nimport completely_unknown\n") - pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + pylint_call = [sys.executable, "-m", "pylint", *args, path] with _test_cwd(tmp_path): subprocess.check_output(pylint_call, cwd=str(tmp_path)) new_python_path = os.environ.get("PYTHONPATH", "").strip(":") @@ -1022,7 +1022,7 @@ a.py:1:4: E0001: Parsing failed: 'invalid syntax (<unknown>, line 1)' (syntax-er path = join(HERE, "regrtest_data", "fail_on.py") # We set fail-under to be something very low so that even with the warnings # and errors that are generated they don't affect the exit code. - self._runtest([path, "--fail-under=-10", "--disable=C"] + args, code=expected) + self._runtest([path, "--fail-under=-10", "--disable=C", *args], code=expected) def test_one_module_fatal_error(self) -> None: """Fatal errors in one of several modules linted still exits non-zero.""" @@ -1046,7 +1046,7 @@ a.py:1:4: E0001: Parsing failed: 'invalid syntax (<unknown>, line 1)' (syntax-er ) def test_fail_on_info_only_exit_code(self, args: list[str], expected: int) -> None: path = join(HERE, "regrtest_data", "fail_on_info_only.py") - self._runtest([path] + args, code=expected) + self._runtest([path, *args], code=expected) @pytest.mark.parametrize( "output_format, expected_output", @@ -1332,7 +1332,7 @@ class TestCallbackOptions: """Test whether certain strings are in the output of a callback command.""" command = _add_rcfile_default_pylintrc(command) process = subprocess.run( - [sys.executable, "-m", "pylint"] + command, + [sys.executable, "-m", "pylint", *command], capture_output=True, encoding="utf-8", check=False, @@ -1356,7 +1356,7 @@ class TestCallbackOptions: """Test the --help-msg flag.""" args = _add_rcfile_default_pylintrc(args) process = subprocess.run( - [sys.executable, "-m", "pylint"] + args, + [sys.executable, "-m", "pylint", *args], capture_output=True, encoding="utf-8", check=False, @@ -1373,7 +1373,7 @@ class TestCallbackOptions: """Test the --generate-rcfile flag.""" args = _add_rcfile_default_pylintrc(["--generate-rcfile"]) process = subprocess.run( - [sys.executable, "-m", "pylint"] + args, + [sys.executable, "-m", "pylint", *args], capture_output=True, encoding="utf-8", check=False, @@ -1384,7 +1384,7 @@ class TestCallbackOptions: assert "profile" not in process.stdout args = _add_rcfile_default_pylintrc(["--generate-rcfile"]) process_two = subprocess.run( - [sys.executable, "-m", "pylint"] + args, + [sys.executable, "-m", "pylint", *args], capture_output=True, encoding="utf-8", check=False, @@ -1436,7 +1436,7 @@ class TestCallbackOptions: ] ) process = subprocess.run( - [sys.executable, "-m", "pylint"] + args, + [sys.executable, "-m", "pylint", *args], capture_output=True, encoding="utf-8", check=False, @@ -1449,7 +1449,7 @@ class TestCallbackOptions: assert 'preferred-modules = ["a:b"]' in process.stdout process_two = subprocess.run( - [sys.executable, "-m", "pylint"] + args, + [sys.executable, "-m", "pylint", *args], capture_output=True, encoding="utf-8", check=False, diff --git a/tests/testutils/_primer/test_package_to_lint.py b/tests/testutils/_primer/test_package_to_lint.py index 220e2c0b2..6fce306b3 100644 --- a/tests/testutils/_primer/test_package_to_lint.py +++ b/tests/testutils/_primer/test_package_to_lint.py @@ -31,7 +31,8 @@ def test_package_to_lint() -> None: expected_args = [ str(expected_path_to_lint), f"--rcfile={expected_pylintrc_path}", - ] + args + *args, + ] assert package_to_lint.pylint_args == expected_args diff --git a/tests/testutils/_primer/test_primer.py b/tests/testutils/_primer/test_primer.py index d57e98d21..96430f537 100644 --- a/tests/testutils/_primer/test_primer.py +++ b/tests/testutils/_primer/test_primer.py @@ -29,7 +29,7 @@ DEFAULT_ARGS = ["python tests/primer/__main__.py", "compare", "--commit=v2.14.2" @pytest.mark.parametrize("args", [[], ["wrong_command"]]) def test_primer_launch_bad_args(args: list[str], capsys: CaptureFixture) -> None: with pytest.raises(SystemExit): - with patch("sys.argv", ["python tests/primer/__main__.py"] + args): + with patch("sys.argv", ["python tests/primer/__main__.py", *args]): Primer(PRIMER_DIRECTORY, PACKAGES_TO_PRIME_PATH).run() out, err = capsys.readouterr() assert not out @@ -84,7 +84,7 @@ class TestPrimer: pr = directory / "pr.json" if expected_file is None: expected_file = directory / "expected.txt" - new_argv = DEFAULT_ARGS + [f"--base-file={main}", f"--new-file={pr}"] + new_argv = [*DEFAULT_ARGS, f"--base-file={main}", f"--new-file={pr}"] with patch("sys.argv", new_argv): Primer(PRIMER_DIRECTORY, PACKAGES_TO_PRIME_PATH).run() with open(PRIMER_DIRECTORY / "comment.txt", encoding="utf8") as f: |