diff --git a/pyproject.toml b/pyproject.toml index 723da45dd..c93111492 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -158,7 +158,6 @@ ignore = [ "D404", # First word of the docstring should not be "This" "D415", # First line should end with a period, question mark, or exclamation point # ruff ignore - "RUF005", # Consider `(x, *y)` instead of concatenation "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` ] diff --git a/scripts/release.py b/scripts/release.py index 66617feb5..73f5f52b1 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -107,7 +107,7 @@ def pre_release( def changelog(version: str, write_out: bool = False) -> None: addopts = [] if write_out else ["--draft"] - check_call(["towncrier", "--yes", "--version", version] + addopts) + check_call(["towncrier", "--yes", "--version", version, *addopts]) def main() -> None: diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 0ab6eaa13..9f3b65e8f 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -925,7 +925,7 @@ class AssertionRewriter(ast.NodeVisitor): # If any hooks implement assert_pass hook hook_impl_test = ast.If( self.helper("_check_if_assertion_pass_impl"), - self.expl_stmts + [hook_call_pass], + [*self.expl_stmts, hook_call_pass], [], ) statements_pass = [hook_impl_test] diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index 902d4baf8..4fdfd86a5 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -92,7 +92,8 @@ def _truncate_explanation( else: # Add proper ellipsis when we were able to fit a full line exactly truncated_explanation[-1] = "..." - return truncated_explanation + [ + return [ + *truncated_explanation, "", f"...Full output truncated ({truncated_line_count} line" f"{'' if truncated_line_count == 1 else 's'} hidden), {USAGE_MSG}", diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 33dcd4628..ca3df7490 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -233,8 +233,8 @@ def assertrepr_compare( return None if explanation[0] != "": - explanation = [""] + explanation - return [summary] + explanation + explanation = ["", *explanation] + return [summary, *explanation] def _compare_eq_any( diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index f5efc8ec9..0d48ef489 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -238,7 +238,8 @@ essential_plugins = ( "helpconfig", # Provides -p. ) -default_plugins = essential_plugins + ( +default_plugins = ( + *essential_plugins, "python", "terminal", "debugging", diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index 18cf4600a..da05acf39 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -122,7 +122,7 @@ class Parser: from _pytest._argcomplete import filescompleter optparser = MyOptionParser(self, self.extra_info, prog=self.prog) - groups = self._groups + [self._anonymous] + groups = [*self._groups, self._anonymous] for group in groups: if group.options: desc = group.description or group.name diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 5190bc35a..8002528b9 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1061,7 +1061,7 @@ class Pytester: :param cmdlineargs: Any extra command line arguments to use. """ p = self.makepyfile(source) - values = list(cmdlineargs) + [p] + values = [*list(cmdlineargs), p] return self.inline_run(*values) def inline_genitems(self, *args) -> Tuple[List[Item], HookRecorder]: @@ -1491,10 +1491,10 @@ class Pytester: """ __tracebackhide__ = True p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700) - args = ("--basetemp=%s" % p,) + args + args = ("--basetemp=%s" % p, *args) plugins = [x for x in self.plugins if isinstance(x, str)] if plugins: - args = ("-p", plugins[0]) + args + args = ("-p", plugins[0], *args) args = self._getpytestargs() + args return self.run(*args, timeout=timeout) diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 40f6d2e5b..aa58d43b4 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -79,7 +79,7 @@ def deprecated_call( """ __tracebackhide__ = True if func is not None: - args = (func,) + args + args = (func, *args) return warns( (DeprecationWarning, PendingDeprecationWarning, FutureWarning), *args, **kwargs ) diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 846e23b2a..a0ee28d48 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -1739,7 +1739,7 @@ def test_hidden_entries_of_chained_exceptions_are_not_shown(pytester: Pytester) def add_note(err: BaseException, msg: str) -> None: """Adds a note to an exception inplace.""" if sys.version_info < (3, 11): - err.__notes__ = getattr(err, "__notes__", []) + [msg] # type: ignore[attr-defined] + err.__notes__ = [*getattr(err, "__notes__", []), msg] # type: ignore[attr-defined] else: err.add_note(msg) diff --git a/testing/freeze/create_executable.py b/testing/freeze/create_executable.py index 3803b3b24..fbfda2e5d 100644 --- a/testing/freeze/create_executable.py +++ b/testing/freeze/create_executable.py @@ -9,5 +9,5 @@ if __name__ == "__main__": for x in pytest.freeze_includes(): hidden.extend(["--hidden-import", x]) hidden.extend(["--hidden-import", "distutils"]) - args = ["pyinstaller", "--noconfirm"] + hidden + ["runtests_script.py"] + args = ["pyinstaller", "--noconfirm", *hidden, "runtests_script.py"] subprocess.check_call(" ".join(args), shell=True) diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 432c46e8d..d0e8723cb 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -4536,5 +4536,5 @@ def test_yield_fixture_with_no_value(pytester: Pytester) -> None: def test_deduplicate_names() -> None: items = deduplicate_names("abacd") assert items == ("a", "b", "c", "d") - items = deduplicate_names(items + ("g", "f", "g", "e", "b")) + items = deduplicate_names((*items, "g", "f", "g", "e", "b")) assert items == ("a", "b", "c", "d", "g", "f", "e") diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 9b8030e7d..42104255b 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -42,7 +42,7 @@ class RunAndParse: self, *args: Union[str, "os.PathLike[str]"], family: Optional[str] = "xunit1" ) -> Tuple[RunResult, "DomNode"]: if family: - args = ("-o", "junit_family=" + family) + args + args = ("-o", "junit_family=" + family, *args) xml_path = self.pytester.path.joinpath("junit.xml") result = self.pytester.runpytest("--junitxml=%s" % xml_path, *args) if family == "xunit2": diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 0eb50926e..22f041ced 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -417,8 +417,8 @@ class TestTerminal: result = pytester.runpytest("-v") result.stdout.fnmatch_lines( - common_output - + [ + [ + *common_output, "test_verbose_skip_reason.py::test_long_skip SKIPPED (1 cannot *...) *", "test_verbose_skip_reason.py::test_long_xfail XFAIL (2 cannot *...) *", ] @@ -426,17 +426,13 @@ class TestTerminal: result = pytester.runpytest("-vv") result.stdout.fnmatch_lines( - common_output - + [ - ( - "test_verbose_skip_reason.py::test_long_skip SKIPPED" - " (1 cannot do foobar" - ), + [ + *common_output, + "test_verbose_skip_reason.py::test_long_skip SKIPPED" + " (1 cannot do foobar", "because baz is missing due to I don't know what) *", - ( - "test_verbose_skip_reason.py::test_long_xfail XFAIL" - " (2 cannot do foobar" - ), + "test_verbose_skip_reason.py::test_long_xfail XFAIL" + " (2 cannot do foobar", "because baz is missing due to I don't know what) *", ] )