diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9e7be8cf6db..b28013295a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.4" + rev: "v0.8.0" hooks: - id: ruff args: ["--fix"] diff --git a/src/_pytest/_code/__init__.py b/src/_pytest/_code/__init__.py index 0bfde42604d..7f67a2e3e0a 100644 --- a/src/_pytest/_code/__init__.py +++ b/src/_pytest/_code/__init__.py @@ -16,11 +16,11 @@ __all__ = [ "Code", "ExceptionInfo", - "filter_traceback", "Frame", - "getfslineno", - "getrawcode", + "Source", "Traceback", "TracebackEntry", - "Source", + "filter_traceback", + "getfslineno", + "getrawcode", ] diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index dd3fd7addb6..da2bb5ed762 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -957,7 +957,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) @@ -1186,10 +1186,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) @@ -1373,7 +1371,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: diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 37c09b03467..fba0545b374 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -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 @@ -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("%", "%%") diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 2ac3b6bbc7f..3568390e0a7 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -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 "", + (hasattr(self, "_old") and repr(self._old)) or "", self._state, self.tmpfile, ) @@ -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 "", + (hasattr(self, "_old") and repr(self._old)) or "", self._state, self.tmpfile, ) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 5817e88f47d..70dc2b2027e 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -307,7 +307,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, ...] diff --git a/src/_pytest/mark/expression.py b/src/_pytest/mark/expression.py index 89cc0e94d3b..a1cca057dcb 100644 --- a/src/_pytest/mark/expression.py +++ b/src/_pytest/mark/expression.py @@ -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 @@ -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) @@ -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: diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 14650a64759..75d1e68c1b7 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -562,7 +562,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 @@ -584,10 +584,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] diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 51bc5174628..ce0f170a96b 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -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__( diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 1456b5212d4..32520b05be8 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -432,7 +432,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 @@ -849,12 +849,12 @@ class IdMaker: __slots__ = ( "argnames", - "parametersets", + "config", + "func_name", "idfn", "ids", - "config", "nodeid", - "func_name", + "parametersets", ) # The argnames of the parametrization. diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 0b60301bf5f..8653d22765d 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -533,7 +533,7 @@ def teardown_exact(self, nextitem: Item | None) -> None: When nextitem is None (meaning we're at the last item), the entire stack is torn down. """ - needed_collectors = nextitem and nextitem.listchain() or [] + needed_collectors = (nextitem and nextitem.listchain()) or [] exceptions: list[BaseException] = [] while self.stack: if list(self.stack.keys()) == needed_collectors[: len(self.stack)]: diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 9818be2ab03..f3010033cb9 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -196,7 +196,7 @@ def evaluate_skip_marks(item: Item) -> Skip | None: class Xfail: """The result of evaluate_xfail_marks().""" - __slots__ = ("reason", "run", "strict", "raises") + __slots__ = ("raises", "reason", "run", "strict") reason: str run: bool diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index 5ab2a22b0c0..f0c3516f4cc 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -88,41 +88,27 @@ __all__ = [ - "__version__", - "approx", "Cache", "CallInfo", "CaptureFixture", "Class", - "cmdline", - "Collector", "CollectReport", + "Collector", "Config", - "console_main", - "deprecated_call", "Dir", "Directory", "DoctestItem", - "exit", "ExceptionInfo", "ExitCode", - "fail", "File", - "fixture", "FixtureDef", "FixtureLookupError", "FixtureRequest", - "freeze_includes", "Function", - "hookimpl", "HookRecorder", - "hookspec", - "importorskip", "Item", "LineMatcher", "LogCaptureFixture", - "main", - "mark", "Mark", "MarkDecorator", "MarkGenerator", @@ -131,7 +117,6 @@ "MonkeyPatch", "OptionGroup", "Package", - "param", "Parser", "PytestAssertRewriteWarning", "PytestCacheWarning", @@ -139,31 +124,46 @@ "PytestConfigWarning", "PytestDeprecationWarning", "PytestExperimentalApiWarning", - "PytestRemovedIn9Warning", - "Pytester", "PytestPluginManager", + "PytestRemovedIn9Warning", "PytestUnhandledThreadExceptionWarning", "PytestUnknownMarkWarning", "PytestUnraisableExceptionWarning", "PytestWarning", - "raises", + "Pytester", "RecordedHookCall", - "register_assert_rewrite", "RunResult", "Session", - "set_trace", - "skip", "Stash", "StashKey", - "version_tuple", - "TempdirFactory", "TempPathFactory", + "TempdirFactory", "TerminalReporter", - "Testdir", "TestReport", "TestShortLogReport", + "Testdir", "UsageError", "WarningsRecorder", + "__version__", + "approx", + "cmdline", + "console_main", + "deprecated_call", + "exit", + "fail", + "fixture", + "freeze_includes", + "hookimpl", + "hookspec", + "importorskip", + "main", + "mark", + "param", + "raises", + "register_assert_rewrite", + "set_trace", + "skip", + "version_tuple", "warns", "xfail", "yield_fixture", diff --git a/testing/_py/test_local.py b/testing/_py/test_local.py index 21fbfb3e3ad..b6d49c5425e 100644 --- a/testing/_py/test_local.py +++ b/testing/_py/test_local.py @@ -855,7 +855,7 @@ def test_fnmatch_file_abspath(self, tmpdir): assert b.fnmatch(pattern) def test_sysfind(self): - name = sys.platform == "win32" and "cmd" or "test" + name = (sys.platform == "win32" and "cmd") or "test" x = local.sysfind(name) assert x.check(file=1) assert local.sysfind("jaksdkasldqwe") is None @@ -1250,7 +1250,7 @@ def test_owner_group_not_implemented(self, path1): def test_chmod_simple_int(self, path1): mode = path1.stat().mode # Ensure that we actually change the mode to something different. - path1.chmod(mode == 0 and 1 or 0) + path1.chmod((mode == 0 and 1) or 0) try: print(path1.stat().mode) print(mode)