Skip to content

Upgrade ruff to 0.8.1 and fix existing issues #13009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 30, 2024
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.7.4"
rev: "v0.8.1"
hooks:
- id: ruff
args: ["--fix"]
Expand Down
2 changes: 1 addition & 1 deletion bench/empty.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


for i in range(1000):
exec("def test_func_%d(): pass" % i)
exec(f"def test_func_{i}(): pass")
8 changes: 4 additions & 4 deletions src/_pytest/_code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
__all__ = [
"Code",
"ExceptionInfo",
"filter_traceback",
"Frame",
"getfslineno",
"getrawcode",
"Source",
"Traceback",
"TracebackEntry",
"Source",
"filter_traceback",
"getfslineno",
"getrawcode",
]
19 changes: 6 additions & 13 deletions src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def relline(self) -> int:
return self.lineno - self.frame.code.firstlineno

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

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

@property
def name(self) -> str:
Expand Down Expand Up @@ -953,7 +948,7 @@ def repr_traceback_entry(
if short:
message = f"in {entry.name}"
else:
message = excinfo and excinfo.typename or ""
message = (excinfo and excinfo.typename) or ""
entry_path = entry.path
path = self._makepath(entry_path)
reprfileloc = ReprFileLocation(path, entry.lineno + 1, message)
Expand Down Expand Up @@ -1182,10 +1177,8 @@ def toterminal(self, tw: TerminalWriter) -> None:
entry.toterminal(tw)
if i < len(self.reprentries) - 1:
next_entry = self.reprentries[i + 1]
if (
entry.style == "long"
or entry.style == "short"
and next_entry.style == "long"
if entry.style == "long" or (
entry.style == "short" and next_entry.style == "long"
):
tw.sep(self.entrysep)

Expand Down Expand Up @@ -1369,7 +1362,7 @@ def getfslineno(obj: object) -> tuple[str | Path, int]:
except TypeError:
return "", -1

fspath = fn and absolutepath(fn) or ""
fspath = (fn and absolutepath(fn)) or ""
lineno = -1
if fspath:
try:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/_io/pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ def _pprint_deque(
) -> None:
stream.write(object.__class__.__name__ + "(")
if object.maxlen is not None:
stream.write("maxlen=%d, " % object.maxlen)
stream.write(f"maxlen={object.maxlen}, ")
stream.write("[")

self._format_items(object, stream, indent, allowance + 1, context, level)
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/_py/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _geterrnoclass(self, eno: int) -> type[Error]:
try:
return self._errno2class[eno]
except KeyError:
clsname = errno.errorcode.get(eno, "UnknownErrno%d" % (eno,))
clsname = errno.errorcode.get(eno, f"UnknownErrno{eno}")
errorcls = type(
clsname,
(Error,),
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Sentinel:

# pytest caches rewritten pycs in pycache dirs
PYTEST_TAG = f"{sys.implementation.cache_tag}-pytest-{version}"
PYC_EXT = ".py" + (__debug__ and "c" or "o")
PYC_EXT = ".py" + ((__debug__ and "c") or "o")
PYC_TAIL = "." + PYTEST_TAG + PYC_EXT

# Special marker that denotes we have just left a scope definition
Expand Down Expand Up @@ -481,7 +481,7 @@ def _should_repr_global_name(obj: object) -> bool:


def _format_boolop(explanations: Iterable[str], is_or: bool) -> str:
explanation = "(" + (is_or and " or " or " and ").join(explanations) + ")"
explanation = "(" + ((is_or and " or ") or " and ").join(explanations) + ")"
return explanation.replace("%", "%%")


Expand Down
9 changes: 3 additions & 6 deletions src/_pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,7 @@ def _compare_eq_sequence(
]
else:
explanation += [
"%s contains %d more items, first extra item: %s"
% (dir_with_more, len_diff, highlighter(extra))
f"{dir_with_more} contains {len_diff} more items, first extra item: {highlighter(extra)}"
]
return explanation

Expand Down Expand Up @@ -510,8 +509,7 @@ def _compare_eq_dict(
len_extra_left = len(extra_left)
if len_extra_left:
explanation.append(
"Left contains %d more item%s:"
% (len_extra_left, "" if len_extra_left == 1 else "s")
f"Left contains {len_extra_left} more item{'' if len_extra_left == 1 else 's'}:"
)
explanation.extend(
highlighter(pprint.pformat({k: left[k] for k in extra_left})).splitlines()
Expand All @@ -520,8 +518,7 @@ def _compare_eq_dict(
len_extra_right = len(extra_right)
if len_extra_right:
explanation.append(
"Right contains %d more item%s:"
% (len_extra_right, "" if len_extra_right == 1 else "s")
f"Right contains {len_extra_right} more item{'' if len_extra_right == 1 else 's'}:"
)
explanation.extend(
highlighter(pprint.pformat({k: right[k] for k in extra_right})).splitlines()
Expand Down
6 changes: 3 additions & 3 deletions src/_pytest/cacheprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,8 @@ def pytest_collection_modifyitems(
if not previously_failed:
# Running a subset of all tests with recorded failures
# only outside of it.
self._report_status = "%d known failures not in selected tests" % (
len(self.lastfailed),
self._report_status = (
f"{len(self.lastfailed)} known failures not in selected tests"
)
else:
if self.config.getoption("lf"):
Expand Down Expand Up @@ -622,5 +622,5 @@ def cacheshow(config: Config, session: Session) -> int:
# print("%s/" % p.relative_to(basedir))
if p.is_file():
key = str(p.relative_to(basedir))
tw.line(f"{key} is a file of length {p.stat().st_size:d}")
tw.line(f"{key} is a file of length {p.stat().st_size}")
return 0
4 changes: 2 additions & 2 deletions src/_pytest/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def repr(self, class_name: str) -> str:
return "<{} {} _old={} _state={!r} tmpfile={!r}>".format(
class_name,
self.name,
hasattr(self, "_old") and repr(self._old) or "<UNSET>",
(hasattr(self, "_old") and repr(self._old)) or "<UNSET>",
self._state,
self.tmpfile,
)
Expand All @@ -369,7 +369,7 @@ def __repr__(self) -> str:
return "<{} {} _old={} _state={!r} tmpfile={!r}>".format(
self.__class__.__name__,
self.name,
hasattr(self, "_old") and repr(self._old) or "<UNSET>",
(hasattr(self, "_old") and repr(self._old)) or "<UNSET>",
self._state,
self.tmpfile,
)
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ def getlocation(function, curdir: str | os.PathLike[str] | None = None) -> str:
except ValueError:
pass
else:
return "%s:%d" % (relfn, lineno + 1)
return "%s:%d" % (fn, lineno + 1)
return f"{relfn}:{lineno+1}"
return f"{fn}:{lineno+1}"


def num_mock_patch_args(function) -> int:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/doctest.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def repr_failure( # type: ignore[override]
# add line numbers to the left of the error message
assert test.lineno is not None
lines = [
"%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines)
f"{i + test.lineno + 1:03d} {x}" for (i, x) in enumerate(lines)
]
# trim docstring error lines to 10
lines = lines[max(example.lineno - 9, 0) : example.lineno + 1]
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class FuncFixtureInfo:
these are not reflected here.
"""

__slots__ = ("argnames", "initialnames", "names_closure", "name2fixturedefs")
__slots__ = ("argnames", "initialnames", "name2fixturedefs", "names_closure")

# Fixture names that the item requests directly by function parameters.
argnames: tuple[str, ...]
Expand Down Expand Up @@ -884,7 +884,7 @@ def toterminal(self, tw: TerminalWriter) -> None:
red=True,
)
tw.line()
tw.line("%s:%d" % (os.fspath(self.filename), self.firstlineno + 1))
tw.line(f"{os.fspath(self.filename)}:{self.firstlineno + 1}")


def call_fixture_func(
Expand Down
18 changes: 8 additions & 10 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,7 @@ def pytest_collection(session: Session) -> None:
def pytest_runtestloop(session: Session) -> bool:
if session.testsfailed and not session.config.option.continue_on_collection_errors:
raise session.Interrupted(
"%d error%s during collection"
% (session.testsfailed, "s" if session.testsfailed != 1 else "")
f"{session.testsfailed} error{'s' if session.testsfailed != 1 else ''} during collection"
)

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

def __repr__(self) -> str:
return "<%s %s exitstatus=%r testsfailed=%d testscollected=%d>" % (
self.__class__.__name__,
self.name,
getattr(self, "exitstatus", "<UNSET>"),
self.testsfailed,
self.testscollected,
)
return (
f"<{self.__class__.__name__} {self.name} "
f"exitstatus=%r "
f"testsfailed={self.testsfailed} "
f"testscollected={self.testscollected}>"
) % getattr(self, "exitstatus", "<UNSET>")

@property
def shouldstop(self) -> bool | str:
Expand Down Expand Up @@ -654,7 +652,7 @@ def pytest_runtest_logreport(self, report: TestReport | CollectReport) -> None:
self.testsfailed += 1
maxfail = self.config.getvalue("maxfail")
if maxfail and self.testsfailed >= maxfail:
self.shouldfail = "stopping after %d failures" % (self.testsfailed)
self.shouldfail = f"stopping after {self.testsfailed} failures"

pytest_collectreport = pytest_runtest_logreport

Expand Down
10 changes: 4 additions & 6 deletions src/_pytest/mark/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class TokenType(enum.Enum):

@dataclasses.dataclass(frozen=True)
class Token:
__slots__ = ("type", "value", "pos")
__slots__ = ("pos", "type", "value")
type: TokenType
value: str
pos: int
Expand All @@ -80,7 +80,7 @@ def __str__(self) -> str:


class Scanner:
__slots__ = ("tokens", "current")
__slots__ = ("current", "tokens")

def __init__(self, input: str) -> None:
self.tokens = self.lex(input)
Expand Down Expand Up @@ -238,10 +238,8 @@ def single_kwarg(s: Scanner) -> ast.keyword:
value: str | int | bool | None = value_token.value[1:-1] # strip quotes
else:
value_token = s.accept(TokenType.IDENT, reject=True)
if (
(number := value_token.value).isdigit()
or number.startswith("-")
and number[1:].isdigit()
if (number := value_token.value).isdigit() or (
number.startswith("-") and number[1:].isdigit()
):
value = int(number)
elif value_token.value in BUILTIN_MATCHERS:
Expand Down
18 changes: 5 additions & 13 deletions src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,7 @@ def get_empty_parameterset_mark(
from ..nodes import Collector

fs, lineno = getfslineno(func)
reason = "got empty parameter set %r, function %s at %s:%d" % (
argnames,
func.__name__,
fs,
lineno,
)

reason = f"got empty parameter set {argnames!r}, function {func.__name__} at {fs}:{lineno}"
requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION)
if requested_mark in ("", None, "skip"):
mark = MARK_GEN.skip(reason=reason)
Expand All @@ -64,7 +58,7 @@ def get_empty_parameterset_mark(
f_name = func.__name__
_, lineno = getfslineno(func)
raise Collector.CollectError(
"Empty parameter set in '%s' at line %d" % (f_name, lineno + 1)
f"Empty parameter set in '{f_name}' at line {lineno + 1}"
)
else:
raise LookupError(requested_mark)
Expand Down Expand Up @@ -562,7 +556,7 @@ def __getattr__(self, name: str) -> MarkDecorator:

@final
class NodeKeywords(MutableMapping[str, Any]):
__slots__ = ("node", "parent", "_markers")
__slots__ = ("_markers", "node", "parent")

def __init__(self, node: Node) -> None:
self.node = node
Expand All @@ -584,10 +578,8 @@ def __setitem__(self, key: str, value: Any) -> None:
# below and use the collections.abc fallback, but that would be slow.

def __contains__(self, key: object) -> bool:
return (
key in self._markers
or self.parent is not None
and key in self.parent.keywords
return key in self._markers or (
self.parent is not None and key in self.parent.keywords
)

def update( # type: ignore[override]
Expand Down
10 changes: 5 additions & 5 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ class Node(abc.ABC, metaclass=NodeMeta):
# Use __slots__ to make attribute access faster.
# Note that __dict__ is still available.
__slots__ = (
"__dict__",
"_nodeid",
"_store",
"config",
"name",
"parent",
"config",
"session",
"path",
"_nodeid",
"_store",
"__dict__",
"session",
)

def __init__(
Expand Down
6 changes: 4 additions & 2 deletions src/_pytest/pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,10 @@ def __init__(

def __repr__(self) -> str:
return (
"<RunResult ret=%s len(stdout.lines)=%d len(stderr.lines)=%d duration=%.2fs>"
% (self.ret, len(self.stdout.lines), len(self.stderr.lines), self.duration)
f"<RunResult ret={self.ret!s} "
f"len(stdout.lines)={len(self.stdout.lines)} "
f"len(stderr.lines)={len(self.stderr.lines)} "
f"duration={self.duration:.2f}s>"
)

def parseoutcomes(self) -> dict[str, int]:
Expand Down
8 changes: 4 additions & 4 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ def _genfunctions(self, name: str, funcobj) -> Iterator[Function]:
assert modulecol is not None
module = modulecol.obj
clscol = self.getparent(Class)
cls = clscol and clscol.obj or None
cls = (clscol and clscol.obj) or None

definition = FunctionDefinition.from_parent(self, name=name, callobj=funcobj)
fixtureinfo = definition._fixtureinfo
Expand Down Expand Up @@ -848,12 +848,12 @@ class IdMaker:

__slots__ = (
"argnames",
"parametersets",
"config",
"func_name",
"idfn",
"ids",
"config",
"nodeid",
"func_name",
"parametersets",
)

# The argnames of the parametrization.
Expand Down
Loading