Skip to content

Commit 17c5bbb

Browse files
[Fix UP031] Manually, keeping some required %r specifiers
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
1 parent 049bb29 commit 17c5bbb

21 files changed

+53
-72
lines changed

bench/empty.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33

44
for i in range(1000):
5-
exec("def test_func_%d(): pass" % i)
5+
exec(f"def test_func_{i}(): pass")

pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ lint.ignore = [
158158
"PLW2901", # for loop variable overwritten by assignment target
159159
# ruff ignore
160160
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
161-
"UP031",
162161
]
163162
lint.per-file-ignores."src/_pytest/_py/**/*.py" = [
164163
"B",

src/_pytest/_code/code.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def relline(self) -> int:
217217
return self.lineno - self.frame.code.firstlineno
218218

219219
def __repr__(self) -> str:
220-
return "<TracebackEntry %s:%d>" % (self.frame.code.path, self.lineno + 1)
220+
return f"<TracebackEntry {self.frame.code.path}:{self.lineno+1}>"
221221

222222
@property
223223
def statement(self) -> Source:
@@ -303,12 +303,7 @@ def __str__(self) -> str:
303303
# This output does not quite match Python's repr for traceback entries,
304304
# but changing it to do so would break certain plugins. See
305305
# https://github.com/pytest-dev/pytest/pull/7535/ for details.
306-
return " File %r:%d in %s\n %s\n" % (
307-
str(self.path),
308-
self.lineno + 1,
309-
name,
310-
line,
311-
)
306+
return f" File '{self.path}':{self.lineno+1} in {name}\n {line}\n"
312307

313308
@property
314309
def name(self) -> str:

src/_pytest/_io/pprint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ def _pprint_deque(
540540
) -> None:
541541
stream.write(object.__class__.__name__ + "(")
542542
if object.maxlen is not None:
543-
stream.write("maxlen=%d, " % object.maxlen)
543+
stream.write(f"maxlen={object.maxlen}, ")
544544
stream.write("[")
545545

546546
self._format_items(object, stream, indent, allowance + 1, context, level)

src/_pytest/_py/error.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def _geterrnoclass(self, eno: int) -> type[Error]:
6969
try:
7070
return self._errno2class[eno]
7171
except KeyError:
72-
clsname = errno.errorcode.get(eno, "UnknownErrno%d" % (eno,))
72+
clsname = errno.errorcode.get(eno, f"UnknownErrno{eno}")
7373
errorcls = type(
7474
clsname,
7575
(Error,),

src/_pytest/assertion/util.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,7 @@ def _compare_eq_sequence(
406406
]
407407
else:
408408
explanation += [
409-
"%s contains %d more items, first extra item: %s"
410-
% (dir_with_more, len_diff, highlighter(extra))
409+
f"{dir_with_more} contains {len_diff} more items, first extra item: {highlighter(extra)}"
411410
]
412411
return explanation
413412

@@ -510,8 +509,7 @@ def _compare_eq_dict(
510509
len_extra_left = len(extra_left)
511510
if len_extra_left:
512511
explanation.append(
513-
"Left contains %d more item%s:"
514-
% (len_extra_left, "" if len_extra_left == 1 else "s")
512+
f"Left contains {len_extra_left} more item{'' if len_extra_left == 1 else 's'}:"
515513
)
516514
explanation.extend(
517515
highlighter(pprint.pformat({k: left[k] for k in extra_left})).splitlines()
@@ -520,8 +518,7 @@ def _compare_eq_dict(
520518
len_extra_right = len(extra_right)
521519
if len_extra_right:
522520
explanation.append(
523-
"Right contains %d more item%s:"
524-
% (len_extra_right, "" if len_extra_right == 1 else "s")
521+
f"Right contains {len_extra_right} more item{'' if len_extra_right == 1 else 's'}:"
525522
)
526523
explanation.extend(
527524
highlighter(pprint.pformat({k: right[k] for k in extra_right})).splitlines()

src/_pytest/cacheprovider.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ def pytest_collection_modifyitems(
388388
if not previously_failed:
389389
# Running a subset of all tests with recorded failures
390390
# only outside of it.
391-
self._report_status = "%d known failures not in selected tests" % (
392-
len(self.lastfailed),
391+
self._report_status = (
392+
f"{len(self.lastfailed)} known failures not in selected tests"
393393
)
394394
else:
395395
if self.config.getoption("lf"):
@@ -622,5 +622,5 @@ def cacheshow(config: Config, session: Session) -> int:
622622
# print("%s/" % p.relative_to(basedir))
623623
if p.is_file():
624624
key = str(p.relative_to(basedir))
625-
tw.line(f"{key} is a file of length {p.stat().st_size:d}")
625+
tw.line(f"{key} is a file of length {p.stat().st_size}")
626626
return 0

src/_pytest/compat.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ def getlocation(function, curdir: str | os.PathLike[str] | None = None) -> str:
7171
except ValueError:
7272
pass
7373
else:
74-
return "%s:%d" % (relfn, lineno + 1)
75-
return "%s:%d" % (fn, lineno + 1)
74+
return f"{relfn}:{lineno+1}"
75+
return f"{fn}:{lineno+1}"
7676

7777

7878
def num_mock_patch_args(function) -> int:

src/_pytest/doctest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ def repr_failure( # type: ignore[override]
353353
# add line numbers to the left of the error message
354354
assert test.lineno is not None
355355
lines = [
356-
"%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines)
356+
f"{i + test.lineno + 1:03d} {x}" for (i, x) in enumerate(lines)
357357
]
358358
# trim docstring error lines to 10
359359
lines = lines[max(example.lineno - 9, 0) : example.lineno + 1]

src/_pytest/fixtures.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ def toterminal(self, tw: TerminalWriter) -> None:
884884
red=True,
885885
)
886886
tw.line()
887-
tw.line("%s:%d" % (os.fspath(self.filename), self.firstlineno + 1))
887+
tw.line(f"{os.fspath(self.filename)}:{self.firstlineno + 1}")
888888

889889

890890
def call_fixture_func(

src/_pytest/main.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,7 @@ def pytest_collection(session: Session) -> None:
349349
def pytest_runtestloop(session: Session) -> bool:
350350
if session.testsfailed and not session.config.option.continue_on_collection_errors:
351351
raise session.Interrupted(
352-
"%d error%s during collection"
353-
% (session.testsfailed, "s" if session.testsfailed != 1 else "")
352+
f"{session.testsfailed} error{'s' if session.testsfailed != 1 else ''} during collection"
354353
)
355354

356355
if session.config.option.collectonly:
@@ -585,13 +584,12 @@ def from_config(cls, config: Config) -> Session:
585584
return session
586585

587586
def __repr__(self) -> str:
588-
return "<%s %s exitstatus=%r testsfailed=%d testscollected=%d>" % (
589-
self.__class__.__name__,
590-
self.name,
591-
getattr(self, "exitstatus", "<UNSET>"),
592-
self.testsfailed,
593-
self.testscollected,
594-
)
587+
return (
588+
f"<{self.__class__.__name__} {self.name} "
589+
f"exitstatus=%r "
590+
f"testsfailed={self.testsfailed} "
591+
f"testscollected={self.testscollected}>"
592+
) % getattr(self, "exitstatus", "<UNSET>")
595593

596594
@property
597595
def shouldstop(self) -> bool | str:
@@ -654,7 +652,7 @@ def pytest_runtest_logreport(self, report: TestReport | CollectReport) -> None:
654652
self.testsfailed += 1
655653
maxfail = self.config.getvalue("maxfail")
656654
if maxfail and self.testsfailed >= maxfail:
657-
self.shouldfail = "stopping after %d failures" % (self.testsfailed)
655+
self.shouldfail = f"stopping after {self.testsfailed} failures"
658656

659657
pytest_collectreport = pytest_runtest_logreport
660658

src/_pytest/mark/structures.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,7 @@ def get_empty_parameterset_mark(
4848
from ..nodes import Collector
4949

5050
fs, lineno = getfslineno(func)
51-
reason = "got empty parameter set %r, function %s at %s:%d" % (
52-
argnames,
53-
func.__name__,
54-
fs,
55-
lineno,
56-
)
57-
51+
reason = f"got empty parameter set {argnames!r}, function {func.__name__} at {fs}:{lineno}"
5852
requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION)
5953
if requested_mark in ("", None, "skip"):
6054
mark = MARK_GEN.skip(reason=reason)
@@ -64,7 +58,7 @@ def get_empty_parameterset_mark(
6458
f_name = func.__name__
6559
_, lineno = getfslineno(func)
6660
raise Collector.CollectError(
67-
"Empty parameter set in '%s' at line %d" % (f_name, lineno + 1)
61+
f"Empty parameter set in '{f_name}' at line {lineno + 1}"
6862
)
6963
else:
7064
raise LookupError(requested_mark)

src/_pytest/pytester.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,10 @@ def __init__(
547547

548548
def __repr__(self) -> str:
549549
return (
550-
"<RunResult ret=%s len(stdout.lines)=%d len(stderr.lines)=%d duration=%.2fs>"
551-
% (self.ret, len(self.stdout.lines), len(self.stderr.lines), self.duration)
550+
f"<RunResult ret={self.ret!s} "
551+
f"len(stdout.lines)={len(self.stdout.lines)} "
552+
f"len(stderr.lines)={len(self.stderr.lines)} "
553+
f"duration={self.duration:.2f}s>"
552554
)
553555

554556
def parseoutcomes(self) -> dict[str, int]:

src/_pytest/terminal.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -766,13 +766,13 @@ def report_collect(self, final: bool = False) -> None:
766766
str(self._numcollected) + " item" + ("" if self._numcollected == 1 else "s")
767767
)
768768
if errors:
769-
line += " / %d error%s" % (errors, "s" if errors != 1 else "")
769+
line += f" / {errors} error{'s' if errors != 1 else ''}"
770770
if deselected:
771-
line += " / %d deselected" % deselected
771+
line += f" / {deselected} deselected"
772772
if skipped:
773-
line += " / %d skipped" % skipped
773+
line += f" / {skipped} skipped"
774774
if self._numcollected > selected:
775-
line += " / %d selected" % selected
775+
line += f" / {selected} selected"
776776
if self.isatty:
777777
self.rewrite(line, bold=True, erase=True)
778778
if final:
@@ -862,7 +862,7 @@ def _printcollecteditems(self, items: Sequence[Item]) -> None:
862862
if test_cases_verbosity < -1:
863863
counts = Counter(item.nodeid.split("::", 1)[0] for item in items)
864864
for name, count in sorted(counts.items()):
865-
self._tw.line("%s: %d" % (name, count))
865+
self._tw.line(f"{name}: {count}")
866866
else:
867867
for item in items:
868868
self._tw.line(item.nodeid)
@@ -1254,11 +1254,9 @@ def show_skipped_folded(lines: list[str]) -> None:
12541254
if reason.startswith(prefix):
12551255
reason = reason[len(prefix) :]
12561256
if lineno is not None:
1257-
lines.append(
1258-
"%s [%d] %s:%d: %s" % (markup_word, num, fspath, lineno, reason)
1259-
)
1257+
lines.append(f"{markup_word} [{num}] {fspath}:{lineno}: {reason}")
12601258
else:
1261-
lines.append("%s [%d] %s: %s" % (markup_word, num, fspath, reason))
1259+
lines.append(f"{markup_word} [{num}] {fspath}: {reason}")
12621260

12631261
def show_skipped_unfolded(lines: list[str]) -> None:
12641262
skipped: list[CollectReport] = self.stats.get("skipped", [])
@@ -1375,7 +1373,7 @@ def _build_normal_summary_stats_line(
13751373
count = len(reports)
13761374
color = _color_for_type.get(key, _color_for_type_default)
13771375
markup = {color: True, "bold": color == main_color}
1378-
parts.append(("%d %s" % pluralize(count, key), markup))
1376+
parts.append(("%d %s" % pluralize(count, key), markup)) # noqa: UP031
13791377

13801378
if not parts:
13811379
parts = [("no tests ran", {_color_for_type_default: True})]
@@ -1394,7 +1392,7 @@ def _build_collect_only_summary_stats_line(
13941392

13951393
elif deselected == 0:
13961394
main_color = "green"
1397-
collected_output = "%d %s collected" % pluralize(self._numcollected, "test")
1395+
collected_output = "%d %s collected" % pluralize(self._numcollected, "test") # noqa: UP031
13981396
parts = [(collected_output, {main_color: True})]
13991397
else:
14001398
all_tests_were_deselected = self._numcollected == deselected
@@ -1410,7 +1408,7 @@ def _build_collect_only_summary_stats_line(
14101408

14111409
if errors:
14121410
main_color = _color_for_type["error"]
1413-
parts += [("%d %s" % pluralize(errors, "error"), {main_color: True})]
1411+
parts += [("%d %s" % pluralize(errors, "error"), {main_color: True})] # noqa: UP031
14141412

14151413
return parts, main_color
14161414

testing/_py/test_local.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ def test_make_numbered_dir(self, tmpdir):
948948
prefix="base.", rootdir=tmpdir, keep=2, lock_timeout=0
949949
)
950950
assert numdir.check()
951-
assert numdir.basename == "base.%d" % i
951+
assert numdir.basename == f"base.{i}"
952952
if i >= 1:
953953
assert numdir.new(ext=str(i - 1)).check()
954954
if i >= 2:
@@ -993,7 +993,7 @@ def test_locked_make_numbered_dir(self, tmpdir):
993993
for i in range(10):
994994
numdir = local.make_numbered_dir(prefix="base2.", rootdir=tmpdir, keep=2)
995995
assert numdir.check()
996-
assert numdir.basename == "base2.%d" % i
996+
assert numdir.basename == f"base2.{i}"
997997
for j in range(i):
998998
assert numdir.new(ext=str(j)).check()
999999

testing/example_scripts/dataclasses/test_compare_dataclasses_with_custom_eq.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ class SimpleDataObject:
1010
field_a: int = field()
1111
field_b: str = field()
1212

13-
def __eq__(self, __o: object, /) -> bool:
14-
return super().__eq__(__o)
13+
def __eq__(self, o: object, /) -> bool:
14+
return super().__eq__(o)
1515

1616
left = SimpleDataObject(1, "b")
1717
right = SimpleDataObject(1, "c")

testing/python/metafunc.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1438,13 +1438,13 @@ def test_parametrize_scope_overrides(
14381438
self, pytester: Pytester, scope: str, length: int
14391439
) -> None:
14401440
pytester.makepyfile(
1441-
"""
1441+
f"""
14421442
import pytest
14431443
values = []
14441444
def pytest_generate_tests(metafunc):
14451445
if "arg" in metafunc.fixturenames:
14461446
metafunc.parametrize("arg", [1,2], indirect=True,
1447-
scope=%r)
1447+
scope={scope!r})
14481448
@pytest.fixture
14491449
def arg(request):
14501450
values.append(request.param)
@@ -1454,9 +1454,8 @@ def test_hello(arg):
14541454
def test_world(arg):
14551455
assert arg in (1,2)
14561456
def test_checklength():
1457-
assert len(values) == %d
1457+
assert len(values) == {length}
14581458
"""
1459-
% (scope, length)
14601459
)
14611460
reprec = pytester.inline_run()
14621461
reprec.assertoutcome(passed=5)

testing/test_assertion.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1406,15 +1406,14 @@ def test_full_output_truncated(self, monkeypatch, pytester: Pytester) -> None:
14061406
line_len = 100
14071407
expected_truncated_lines = 2
14081408
pytester.makepyfile(
1409-
r"""
1409+
rf"""
14101410
def test_many_lines():
1411-
a = list([str(i)[0] * %d for i in range(%d)])
1411+
a = list([str(i)[0] * {line_len} for i in range({line_count})])
14121412
b = a[::2]
14131413
a = '\n'.join(map(str, a))
14141414
b = '\n'.join(map(str, b))
14151415
assert a == b
14161416
"""
1417-
% (line_len, line_count)
14181417
)
14191418
monkeypatch.delenv("CI", raising=False)
14201419

@@ -1424,7 +1423,7 @@ def test_many_lines():
14241423
[
14251424
"*+ 1*",
14261425
"*+ 3*",
1427-
"*truncated (%d lines hidden)*use*-vv*" % expected_truncated_lines,
1426+
f"*truncated ({expected_truncated_lines} lines hidden)*use*-vv*",
14281427
]
14291428
)
14301429

testing/test_conftest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -699,9 +699,9 @@ def out_of_reach(): pass
699699
result = pytester.runpytest(*args)
700700
match = ""
701701
if passed:
702-
match += "*%d passed*" % passed
702+
match += f"*{passed} passed*"
703703
if error:
704-
match += "*%d error*" % error
704+
match += f"*{error} error*"
705705
result.stdout.fnmatch_lines(match)
706706

707707

testing/test_doctest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ def test_bar():
13281328
params = ("--doctest-modules",) if enable_doctest else ()
13291329
passes = 3 if enable_doctest else 2
13301330
result = pytester.runpytest(*params)
1331-
result.stdout.fnmatch_lines(["*=== %d passed in *" % passes])
1331+
result.stdout.fnmatch_lines([f"*=== {passes} passed in *"])
13321332

13331333
@pytest.mark.parametrize("scope", SCOPES)
13341334
@pytest.mark.parametrize("autouse", [True, False])

testing/test_terminal.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(self, verbosity=0):
4949
@property
5050
def args(self):
5151
values = []
52-
values.append("--verbosity=%d" % self.verbosity)
52+
values.append(f"--verbosity={self.verbosity}")
5353
return values
5454

5555

0 commit comments

Comments
 (0)