Skip to content

Commit

Permalink
chore: add more Ruff checks and fix issues
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <[email protected]>
  • Loading branch information
henryiii committed Nov 12, 2024
1 parent 9731a53 commit 6f3b191
Show file tree
Hide file tree
Showing 33 changed files with 326 additions and 229 deletions.
18 changes: 12 additions & 6 deletions .github/action_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ def filter_version(version: str) -> str:

version_parts = version_.split(".")
if len(version_parts) < 2:
raise ValueError(f"invalid version: {version}")
msg = f"invalid version: {version}"
raise ValueError(msg)
if not version_parts[0].isdigit():
raise ValueError(f"invalid major python version: {version}")
msg = f"invalid major python version: {version}"
raise ValueError(msg)
if not version_parts[1].isdigit():
raise ValueError(f"invalid minor python version: {version}")
msg = f"invalid minor python version: {version}"
raise ValueError(msg)
return ".".join(version_parts[:2])


Expand All @@ -36,20 +39,22 @@ def setup_action(input_: str) -> None:
pypy_versions = [version for version in versions if version.startswith("pypy")]
pypy_versions_filtered = [filter_version(version) for version in pypy_versions]
if len(pypy_versions) != len(set(pypy_versions_filtered)):
raise ValueError(
msg = (
"multiple versions specified for the same 'major.minor' PyPy interpreter:"
f" {pypy_versions}"
)
raise ValueError(msg)

cpython_versions = [version for version in versions if version not in pypy_versions]
cpython_versions_filtered = [
filter_version(version) for version in cpython_versions
]
if len(cpython_versions) != len(set(cpython_versions_filtered)):
raise ValueError(
msg = (
"multiple versions specified for the same 'major.minor' CPython"
f" interpreter: {cpython_versions}"
)
raise ValueError(msg)

# cpython shall be installed last because
# other interpreters also define pythonX.Y symlinks.
Expand All @@ -70,5 +75,6 @@ def setup_action(input_: str) -> None:

if __name__ == "__main__":
if len(sys.argv) != 2:
raise AssertionError(f"invalid arguments: {sys.argv}")
msg = f"invalid arguments: {sys.argv}"
raise AssertionError(msg)
setup_action(sys.argv[1])
2 changes: 1 addition & 1 deletion nox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from nox import project
from nox._cli import main
from nox._options import noxfile_options as options
from nox._parametrize import Param as param
from nox._parametrize import Param as param # noqa: N813
from nox._parametrize import parametrize_decorator as parametrize
from nox.registry import session_decorator as session
from nox.sessions import Session
Expand Down
14 changes: 7 additions & 7 deletions nox/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
import functools
import inspect
import types
from collections.abc import Iterable, Mapping, Sequence
from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast

from . import _typing

if TYPE_CHECKING:
from collections.abc import Iterable, Mapping, Sequence

from . import _typing
from ._parametrize import Param

T = TypeVar("T", bound=Callable[..., Any])
Expand All @@ -32,12 +32,12 @@
class FunctionDecorator:
"""This is a function decorator."""

def __new__(
def __new__( # noqa: PYI034
cls: Any, func: Callable[..., Any], *args: Any, **kwargs: Any
) -> FunctionDecorator:
obj = super().__new__(cls)
functools.update_wrapper(obj, func)
return cast(FunctionDecorator, obj)
self = super().__new__(cls)
functools.update_wrapper(self, func)
return cast(FunctionDecorator, self)


def _copy_func(src: T, name: str | None = None) -> T:
Expand Down
15 changes: 9 additions & 6 deletions nox/_option_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
import functools
from argparse import ArgumentError as ArgumentError # noqa: PLC0414
from argparse import ArgumentParser, Namespace
from collections.abc import Callable, Iterable
from typing import Any, Literal
from typing import TYPE_CHECKING, Any, Literal

import argcomplete

if TYPE_CHECKING:
from collections.abc import Callable, Iterable


# Python 3.10+ has slots=True (or attrs does), also kwonly=True
@dataclasses.dataclass
Expand Down Expand Up @@ -203,6 +205,7 @@ def make_flag_pair(
name: str,
enable_flags: tuple[str, str] | tuple[str],
disable_flags: tuple[str, str] | tuple[str],
*,
default: bool | Callable[[], bool] = False,
**kwargs: Any,
) -> tuple[Option, Option]:
Expand Down Expand Up @@ -282,9 +285,8 @@ def parser(self) -> ArgumentParser:

# Every option must have a group (except for hidden options)
if option.group is None:
raise ValueError(
f"Option {option.name} must either have a group or be hidden."
)
msg = f"Option {option.name} must either have a group or be hidden."
raise ValueError(msg)

argument = groups[option.group.name].add_argument(
*option.flags, help=option.help, default=option.default, **option.kwargs
Expand Down Expand Up @@ -336,7 +338,8 @@ def namespace(self, **kwargs: Any) -> argparse.Namespace:
# used in tests.
for key, value in kwargs.items():
if key not in args:
raise KeyError(f"{key} is not an option.")
msg = f"{key} is not an option."
raise KeyError(msg)
args[key] = value

return argparse.Namespace(**args)
Expand Down
35 changes: 22 additions & 13 deletions nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
import itertools
import os
import sys
from collections.abc import Iterable
from typing import Any, Callable, Literal, Sequence
from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence

import argcomplete

from nox import _option_set
from nox._option_set import NoxOptions
from nox.tasks import discover_manifest, filter_manifest, load_nox_module
from nox.virtualenv import ALL_VENVS

if TYPE_CHECKING:
from collections.abc import Iterable

from nox._option_set import NoxOptions

ReuseVenvType = Literal["no", "yes", "never", "always"]

"""All of Nox's configuration options."""
Expand Down Expand Up @@ -129,9 +132,8 @@ def _force_venv_backend_merge_func(
command_args.force_venv_backend is not None
and command_args.force_venv_backend != "none"
):
raise ValueError(
"You can not use `--no-venv` with a non-none `--force-venv-backend`"
)
msg = "You can not use `--no-venv` with a non-none `--force-venv-backend`"
raise ValueError(msg)
return "none"
return command_args.force_venv_backend or noxfile_args.force_venv_backend # type: ignore[return-value]

Expand Down Expand Up @@ -191,7 +193,7 @@ def _default_list() -> list[str] | None:
return _default_list


def _color_finalizer(value: bool, args: argparse.Namespace) -> bool:
def _color_finalizer(_value: bool, args: argparse.Namespace) -> bool: # noqa: FBT001
"""Figures out the correct value for "color" based on the two color flags.
Args:
Expand Down Expand Up @@ -224,7 +226,7 @@ def _force_pythons_finalizer(
return value


def _R_finalizer(value: bool, args: argparse.Namespace) -> bool:
def _R_finalizer(value: bool, args: argparse.Namespace) -> bool: # noqa: FBT001
"""Propagate -R to --reuse-existing-virtualenvs and --no-install and --reuse-venv=yes."""
if value:
args.reuse_venv = "yes"
Expand All @@ -233,7 +235,8 @@ def _R_finalizer(value: bool, args: argparse.Namespace) -> bool:


def _reuse_existing_virtualenvs_finalizer(
value: bool, args: argparse.Namespace
value: bool, # noqa: FBT001
args: argparse.Namespace,
) -> bool:
"""Propagate --reuse-existing-virtualenvs to --reuse-venv=yes."""
if value:
Expand All @@ -242,7 +245,7 @@ def _reuse_existing_virtualenvs_finalizer(


def _posargs_finalizer(
value: Sequence[Any], args: argparse.Namespace
value: Sequence[Any], _args: argparse.Namespace
) -> Sequence[Any] | list[Any]:
"""Removes the leading "--"s in the posargs array (if any) and asserts that
remaining arguments came after a "--".
Expand All @@ -268,7 +271,9 @@ def _posargs_finalizer(


def _python_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
prefix: str, # noqa: ARG001
parsed_args: argparse.Namespace,
**kwargs: Any,
) -> Iterable[str]:
module = load_nox_module(parsed_args)
manifest = discover_manifest(module, parsed_args)
Expand All @@ -282,7 +287,9 @@ def _python_completer(


def _session_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
prefix: str, # noqa: ARG001
parsed_args: argparse.Namespace,
**kwargs: Any,
) -> Iterable[str]:
parsed_args.list_sessions = True
module = load_nox_module(parsed_args)
Expand All @@ -296,7 +303,9 @@ def _session_completer(


def _tag_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
prefix: str, # noqa: ARG001
parsed_args: argparse.Namespace,
**kwargs: Any,
) -> Iterable[str]:
module = load_nox_module(parsed_args)
manifest = discover_manifest(module, parsed_args)
Expand Down
6 changes: 4 additions & 2 deletions nox/_parametrize.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

import functools
import itertools
from collections.abc import Callable, Sequence
from typing import Any, Iterable, Union
from typing import TYPE_CHECKING, Any, Iterable, Union

if TYPE_CHECKING:
from collections.abc import Callable, Sequence


class Param:
Expand Down
4 changes: 3 additions & 1 deletion nox/_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class CycleError(ValueError):
def lazy_stable_topo_sort(
dependencies: Mapping[Node, Iterable[Node]],
root: Node,
*,
drop_root: bool = True,
) -> Iterator[Node]:
"""Returns the "lazy, stable" topological sort of a dependency graph.
Expand Down Expand Up @@ -191,7 +192,8 @@ def extend_walk(
# Dependency cycle found.
walk_list = list(walk)
cycle = walk_list[walk_list.index(node) :] + [node]
raise CycleError("Nodes are in a dependency cycle", tuple(cycle))
msg = "Nodes are in a dependency cycle"
raise CycleError(msg, tuple(cycle))
walk[node] = None
return walk

Expand Down
5 changes: 2 additions & 3 deletions nox/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,8 @@ def _check_nox_version_satisfies(needs_version: str) -> None:
raise InvalidVersionSpecifier(message) from error

if not specifiers.contains(version, prereleases=True):
raise VersionCheckFailed(
f"The Noxfile requires Nox {specifiers}, you have {version}"
)
msg = f"The Noxfile requires Nox {specifiers}, you have {version}"
raise VersionCheckFailed(msg)


def check_nox_version(filename: str) -> None:
Expand Down
19 changes: 10 additions & 9 deletions nox/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@
import shutil
import subprocess
import sys
from collections.abc import Iterable, Mapping, Sequence
from typing import Literal
from typing import TYPE_CHECKING, Literal

from nox.logger import logger
from nox.popen import DEFAULT_INTERRUPT_TIMEOUT, DEFAULT_TERMINATE_TIMEOUT, popen

TYPE_CHECKING = False

if TYPE_CHECKING:
from collections.abc import Iterable, Mapping, Sequence
from typing import IO

ExternalType = Literal["error", True, False]
Expand All @@ -53,7 +51,8 @@ def which(program: str | os.PathLike[str], paths: Sequence[str] | None) -> str:
return os.fspath(full_path)

logger.error(f"Program {program} not found.")
raise CommandFailed(f"Program {program} not found")
msg = f"Program {program} not found"
raise CommandFailed(msg)


def _clean_env(env: Mapping[str, str | None] | None = None) -> dict[str, str] | None:
Expand Down Expand Up @@ -111,7 +110,8 @@ def run(
f" at {cmd_path}. Pass external=True into run() to explicitly allow"
" this."
)
raise CommandFailed("External program disallowed.")
msg = "External program disallowed."
raise CommandFailed(msg)
if external is False:
logger.warning(
f"Warning: {cmd} is not installed into the virtualenv, it is"
Expand Down Expand Up @@ -141,13 +141,14 @@ def run(
if silent:
sys.stderr.write(output)

raise CommandFailed(f"Returned code {return_code}")
msg = f"Returned code {return_code}"
raise CommandFailed(msg)

if output:
logger.output(output)

return output if silent else True

except KeyboardInterrupt:
logger.error("Interrupted...")
raise

return output if silent else True
11 changes: 6 additions & 5 deletions nox/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
OUTPUT = logging.DEBUG - 1


def _get_format(colorlog: bool, add_timestamp: bool) -> str:
def _get_format(*, colorlog: bool, add_timestamp: bool) -> str:
if colorlog:
if add_timestamp:
return "%(cyan)s%(name)s > [%(asctime)s] %(log_color)s%(message)s"
Expand All @@ -36,7 +36,7 @@ def _get_format(colorlog: bool, add_timestamp: bool) -> str:


class NoxFormatter(logging.Formatter):
def __init__(self, add_timestamp: bool = False) -> None:
def __init__(self, *, add_timestamp: bool = False) -> None:
super().__init__(fmt=_get_format(colorlog=False, add_timestamp=add_timestamp))
self._simple_fmt = logging.Formatter("%(message)s")

Expand All @@ -49,6 +49,7 @@ def format(self, record: Any) -> str:
class NoxColoredFormatter(ColoredFormatter):
def __init__(
self,
*,
datefmt: Any = None,
style: Any = None,
log_colors: Any = None,
Expand Down Expand Up @@ -91,7 +92,7 @@ def output(self, msg: str, *args: Any, **kwargs: Any) -> None:
logger = cast(LoggerWithSuccessAndOutput, logging.getLogger("nox"))


def _get_formatter(color: bool, add_timestamp: bool) -> logging.Formatter:
def _get_formatter(*, color: bool, add_timestamp: bool) -> logging.Formatter:
if color:
return NoxColoredFormatter(
reset=True,
Expand All @@ -111,7 +112,7 @@ def _get_formatter(color: bool, add_timestamp: bool) -> logging.Formatter:


def setup_logging(
color: bool, verbose: bool = False, add_timestamp: bool = False
*, color: bool, verbose: bool = False, add_timestamp: bool = False
) -> None: # pragma: no cover
"""Setup logging.
Expand All @@ -126,7 +127,7 @@ def setup_logging(
root_logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()

handler.setFormatter(_get_formatter(color, add_timestamp))
handler.setFormatter(_get_formatter(color=color, add_timestamp=add_timestamp))
root_logger.addHandler(handler)

# Silence noisy loggers
Expand Down
Loading

0 comments on commit 6f3b191

Please sign in to comment.