Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ select = [
"F", # pyflakes
"I", # isort
"UP", # pyupgrade
"RUF", # ruff
"W", # pycodestyle
]
ignore = [
Expand All @@ -156,6 +157,8 @@ ignore = [
"D402", # First line should not be the function's signature
"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
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
]

[tool.ruff.format]
Expand Down
2 changes: 1 addition & 1 deletion scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,7 @@ def _truncate_recursive_traceback(
extraline: Optional[str] = (
"!!! Recursion error detected, but an error occurred locating the origin of recursion.\n"
" The following exception happened when comparing locals in the stack frame:\n"
f" {type(e).__name__}: {str(e)}\n"
f" {type(e).__name__}: {e!s}\n"
f" Displaying first and last {max_frames} stack frames out of {len(traceback)}."
)
# Type ignored because adding two instances of a List subtype
Expand Down
4 changes: 1 addition & 3 deletions src/_pytest/_py/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -1105,9 +1105,7 @@ def pyimport(self, modname=None, ensuresyspath=True):
modname = self.purebasename
spec = importlib.util.spec_from_file_location(modname, str(self))
if spec is None or spec.loader is None:
raise ImportError(
f"Can't find module {modname} at location {str(self)}"
)
raise ImportError(f"Can't find module {modname} at location {self!s}")
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
# 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]
Expand Down
3 changes: 2 additions & 1 deletion src/_pytest/assertion/truncate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}",
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# https://www.python.org/dev/peps/pep-0484/#support-for-singleton-types-in-unions
class NotSetType(enum.Enum):
token = 0
NOTSET: Final = NotSetType.token # noqa: E305
NOTSET: Final = NotSetType.token
# fmt: on


Expand Down
5 changes: 3 additions & 2 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ def directory_arg(path: str, optname: str) -> str:
"helpconfig", # Provides -p.
)

default_plugins = essential_plugins + (
default_plugins = (
*essential_plugins,
"python",
"terminal",
"debugging",
Expand Down Expand Up @@ -671,7 +672,7 @@ def _importconftest(
if dirpath in path.parents or path == dirpath:
if mod in mods:
raise AssertionError(
f"While trying to load conftest path {str(conftestpath)}, "
f"While trying to load conftest path {conftestpath!s}, "
f"found that the module {mod} is already loaded with path {mod.__file__}. "
"This is not supposed to happen. Please report this issue to pytest."
)
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/config/argparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def _getparser(self) -> "MyOptionParser":
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
Expand Down
8 changes: 4 additions & 4 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ def fixture(


@overload
def fixture( # noqa: F811
def fixture(
fixture_function: None = ...,
*,
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ...,
Expand All @@ -1239,7 +1239,7 @@ def fixture( # noqa: F811
...


def fixture( # noqa: F811
def fixture(
fixture_function: Optional[FixtureFunction] = None,
*,
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function",
Expand Down Expand Up @@ -1673,7 +1673,7 @@ def parsefactories(
raise NotImplementedError()

@overload
def parsefactories( # noqa: F811
def parsefactories(
self,
node_or_obj: object,
nodeid: Optional[str],
Expand All @@ -1682,7 +1682,7 @@ def parsefactories( # noqa: F811
) -> None:
raise NotImplementedError()

def parsefactories( # noqa: F811
def parsefactories(
self,
node_or_obj: Union[nodes.Node, object],
nodeid: Union[str, NotSetType, None] = NOTSET,
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/junitxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ def record_func(name: str, value: object) -> None:

xml = request.config.stash.get(xml_key, None)
if xml is not None:
record_func = xml.add_global_property # noqa
record_func = xml.add_global_property
return record_func


Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,12 +726,12 @@ def perform_collect(
...

@overload
def perform_collect( # noqa: F811
def perform_collect(
self, args: Optional[Sequence[str]] = ..., genitems: bool = ...
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
...

def perform_collect( # noqa: F811
def perform_collect(
self, args: Optional[Sequence[str]] = None, genitems: bool = True
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
"""Perform the collection phase for this session.
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def normalize_mark_list(
for mark in mark_list:
mark_obj = getattr(mark, "mark", mark)
if not isinstance(mark_obj, Mark):
raise TypeError(f"got {repr(mark_obj)} instead of Mark")
raise TypeError(f"got {mark_obj!r} instead of Mark")
yield mark_obj


Expand Down
6 changes: 3 additions & 3 deletions src/_pytest/pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ def inline_runsource(self, source: str, *cmdlineargs) -> HookRecorder:
: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]:
Expand Down Expand Up @@ -1491,10 +1491,10 @@ def runpytest_subprocess(
"""
__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)

Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def reportinfo(self) -> Tuple[Union["os.PathLike[str]", str], Optional[int], str
# hook is not called for them.
# fmt: off
class _EmptyClass: pass # noqa: E701
IGNORED_ATTRIBUTES = frozenset.union( # noqa: E305
IGNORED_ATTRIBUTES = frozenset.union(
frozenset(),
# Module.
dir(types.ModuleType("empty_module")),
Expand Down
6 changes: 3 additions & 3 deletions src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
# Type ignored because the error is wrong -- not unreachable.
and not isinstance(expected, STRING_TYPES) # type: ignore[unreachable]
):
msg = f"pytest.approx() only supports ordered sequences, but got: {repr(expected)}"
msg = f"pytest.approx() only supports ordered sequences, but got: {expected!r}"
raise TypeError(msg)
else:
cls = ApproxScalar
Expand Down Expand Up @@ -780,7 +780,7 @@ def raises(


@overload
def raises( # noqa: F811
def raises(
expected_exception: Union[Type[E], Tuple[Type[E], ...]],
func: Callable[..., Any],
*args: Any,
Expand All @@ -789,7 +789,7 @@ def raises( # noqa: F811
...


def raises( # noqa: F811
def raises(
expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any
) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]:
r"""Assert that a code block/function call raises an exception type, or one of its subclasses.
Expand Down
12 changes: 5 additions & 7 deletions src/_pytest/recwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ def deprecated_call(


@overload
def deprecated_call( # noqa: F811
func: Callable[..., T], *args: Any, **kwargs: Any
) -> T:
def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
...


def deprecated_call( # noqa: F811
def deprecated_call(
func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
) -> Union["WarningsRecorder", Any]:
"""Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning`` or ``FutureWarning``.
Expand Down Expand Up @@ -81,7 +79,7 @@ def deprecated_call( # noqa: F811
"""
__tracebackhide__ = True
if func is not None:
args = (func,) + args
args = (func, *args)
return warns(
(DeprecationWarning, PendingDeprecationWarning, FutureWarning), *args, **kwargs
)
Expand All @@ -97,7 +95,7 @@ def warns(


@overload
def warns( # noqa: F811
def warns(
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]],
func: Callable[..., T],
*args: Any,
Expand All @@ -106,7 +104,7 @@ def warns( # noqa: F811
...


def warns( # noqa: F811
def warns(
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
*args: Any,
match: Optional[Union[str, Pattern[str]]] = None,
Expand Down
2 changes: 1 addition & 1 deletion testing/_py/test_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
def ignore_encoding_warning():
with warnings.catch_warnings():
with contextlib.suppress(NameError): # new in 3.10
warnings.simplefilter("ignore", EncodingWarning) # type: ignore [name-defined] # noqa: F821
warnings.simplefilter("ignore", EncodingWarning) # type: ignore [name-defined]
yield


Expand Down
2 changes: 1 addition & 1 deletion testing/code/test_excinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ def test():
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)

Expand Down
2 changes: 1 addition & 1 deletion testing/freeze/create_executable.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
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)
2 changes: 1 addition & 1 deletion testing/io/test_wcwidth.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
("\u1ABE", 0),
("\u0591", 0),
("🉐", 2),
("$", 2),
("$", 2), # noqa: RUF001
],
)
def test_wcwidth(c: str, expected: int) -> None:
Expand Down
2 changes: 1 addition & 1 deletion testing/logging/test_reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ def test_log_set_path(pytester: Pytester) -> None:
def pytest_runtest_setup(item):
config = item.config
logging_plugin = config.pluginmanager.get_plugin("logging-plugin")
report_file = os.path.join({repr(report_dir_base)}, item._request.node.name)
report_file = os.path.join({report_dir_base!r}, item._request.node.name)
logging_plugin.set_log_path(report_file)
return (yield)
"""
Expand Down
2 changes: 1 addition & 1 deletion testing/python/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ def test_bar(self):
classcol = pytester.collect_by_name(modcol, "TestClass")
assert isinstance(classcol, Class)
path, lineno, msg = classcol.reportinfo()
func = list(classcol.collect())[0]
func = next(iter(classcol.collect()))
assert isinstance(func, Function)
path, lineno, msg = func.reportinfo()

Expand Down
4 changes: 2 additions & 2 deletions testing/python/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -3086,7 +3086,7 @@ def test_baz(base, fix2):
def test_other():
pass
""" # noqa: UP031 (python syntax issues)
% {"scope": scope} # noqa: UP031 (python syntax issues)
% {"scope": scope}
)
reprec = pytester.inline_run("-lvs")
reprec.assertoutcome(passed=3)
Expand Down Expand Up @@ -4536,5 +4536,5 @@ def test_fixt(custom):
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")
4 changes: 2 additions & 2 deletions testing/python/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ def test_no_raise_message(self) -> None:
try:
pytest.raises(ValueError, int, "0")
except pytest.fail.Exception as e:
assert e.msg == f"DID NOT RAISE {repr(ValueError)}"
assert e.msg == f"DID NOT RAISE {ValueError!r}"
else:
assert False, "Expected pytest.raises.Exception"

try:
with pytest.raises(ValueError):
pass
except pytest.fail.Exception as e:
assert e.msg == f"DID NOT RAISE {repr(ValueError)}"
assert e.msg == f"DID NOT RAISE {ValueError!r}"
else:
assert False, "Expected pytest.raises.Exception"

Expand Down
10 changes: 5 additions & 5 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,16 +914,16 @@ def test_nfc_nfd_same_string(self) -> None:
assert expl == [
r"'hyv\xe4' == 'hyva\u0308'",
"",
f"- {str(right)}",
f"+ {str(left)}",
f"- {right!s}",
f"+ {left!s}",
]

expl = callequal(left, right, verbose=2)
assert expl == [
r"'hyv\xe4' == 'hyva\u0308'",
"",
f"- {str(right)}",
f"+ {str(left)}",
f"- {right!s}",
f"+ {left!s}",
]


Expand Down Expand Up @@ -1149,7 +1149,7 @@ class SimpleDataObjectTwo:
def test_attrs_with_auto_detect_and_custom_eq(self) -> None:
@attr.s(
auto_detect=True
) # attr.s doesnt ignore a custom eq if auto_detect=True
) # attr.s doesn't ignore a custom eq if auto_detect=True
class SimpleDataObject:
field_a = attr.ib()

Expand Down
Loading