diff --git a/nox/_decorators.py b/nox/_decorators.py index f8c1b541..72636ae5 100644 --- a/nox/_decorators.py +++ b/nox/_decorators.py @@ -18,11 +18,11 @@ import functools import inspect import types -from typing import Any, Callable, Iterable, TypeVar, cast +from typing import TYPE_CHECKING, Any, Callable, Iterable, TypeVar, cast from . import _typing -if _typing.TYPE_CHECKING: +if TYPE_CHECKING: from ._parametrize import Param @@ -68,7 +68,7 @@ def __init__( self.reuse_venv = reuse_venv self.venv_backend = venv_backend self.venv_params = venv_params - self.should_warn = should_warn or dict() + self.should_warn = should_warn or {} self.tags = tags or [] def __call__(self, *args: Any, **kwargs: Any) -> Any: diff --git a/nox/_option_set.py b/nox/_option_set.py index 39179d8d..4830a3d9 100644 --- a/nox/_option_set.py +++ b/nox/_option_set.py @@ -237,7 +237,7 @@ def parser(self) -> ArgumentParser: } for option in self.options.values(): - if option.hidden is True: + if option.hidden: continue # Every option must have a group (except for hidden options) diff --git a/nox/_options.py b/nox/_options.py index 4129c32d..4e1ff613 100644 --- a/nox/_options.py +++ b/nox/_options.py @@ -157,15 +157,15 @@ def _color_finalizer(value: bool, args: argparse.Namespace) -> bool: Returns: The new value for the "color" option. """ - if args.forcecolor is True and args.nocolor is True: + if args.forcecolor and args.nocolor: raise _option_set.ArgumentError( None, "Can not specify both --no-color and --force-color." ) - if args.forcecolor is True: + if args.forcecolor: return True - if args.nocolor is True: + if args.nocolor: return False return sys.stdout.isatty() @@ -510,7 +510,7 @@ def _session_completer( "invoked_from", group=None, hidden=True, - default=lambda: os.getcwd(), + default=os.getcwd, ), ) diff --git a/nox/_parametrize.py b/nox/_parametrize.py index f9f202c9..a4c43543 100644 --- a/nox/_parametrize.py +++ b/nox/_parametrize.py @@ -36,7 +36,7 @@ def __init__( arg_names: Sequence[str] | None = None, id: str | None = None, ) -> None: - self.args = tuple(args) + self.args = args self.id = id if arg_names is None: diff --git a/nox/_typing.py b/nox/_typing.py index 9820c164..ac2d5ca8 100644 --- a/nox/_typing.py +++ b/nox/_typing.py @@ -14,33 +14,8 @@ from __future__ import annotations -__all__ = ["TYPE_CHECKING", "ClassVar", "NoReturn", "Python"] +__all__ = ["Python"] -import typing as _typing +from typing import Sequence, Union -try: - from typing import TYPE_CHECKING -except ImportError: - try: - from typing import TYPE_CHECKING - except ImportError: - TYPE_CHECKING = False - -try: - from typing import NoReturn -except ImportError: - try: - from typing import NoReturn - except ImportError: - pass - - -try: - from typing import ClassVar -except ImportError: - try: - from typing import ClassVar - except ImportError: - pass - -Python = _typing.Optional[_typing.Union[str, _typing.Sequence[str], bool]] +Python = Union[str, Sequence[str], bool, None] diff --git a/nox/logger.py b/nox/logger.py index cb2b909a..8743adb7 100644 --- a/nox/logger.py +++ b/nox/logger.py @@ -97,7 +97,7 @@ def output(self, msg: str, *args: Any, **kwargs: Any) -> None: def _get_formatter(color: bool, add_timestamp: bool) -> logging.Formatter: - if color is True: + if color: return NoxColoredFormatter( reset=True, log_colors={ @@ -112,8 +112,7 @@ def _get_formatter(color: bool, add_timestamp: bool) -> logging.Formatter: secondary_log_colors=None, add_timestamp=add_timestamp, ) - else: - return NoxFormatter(add_timestamp=add_timestamp) + return NoxFormatter(add_timestamp=add_timestamp) def setup_logging( diff --git a/nox/sessions.py b/nox/sessions.py index 483c34d8..3f378afc 100644 --- a/nox/sessions.py +++ b/nox/sessions.py @@ -24,15 +24,23 @@ import sys import unicodedata from types import TracebackType -from typing import Any, Callable, Generator, Iterable, Mapping, Sequence +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Generator, + Iterable, + Mapping, + NoReturn, + Sequence, +) import nox.command -from nox import _typing from nox._decorators import Func from nox.logger import logger from nox.virtualenv import CondaEnv, PassthroughEnv, ProcessEnv, VirtualEnv -if _typing.TYPE_CHECKING: +if TYPE_CHECKING: from nox.manifest import Manifest @@ -89,7 +97,7 @@ def _dblquote_pkg_install_arg(pkg_req_str: str) -> str: ) if "<" in pkg_req_str or ">" in pkg_req_str: - if pkg_req_str[0] == '"' and pkg_req_str[-1] == '"': + if pkg_req_str[0] == pkg_req_str[-1] == '"': # already double-quoted string return pkg_req_str else: @@ -646,11 +654,11 @@ def debug(self, *args: Any, **kwargs: Any) -> None: """Outputs a debug-level message during the session.""" logger.debug(*args, **kwargs) - def error(self, *args: Any) -> _typing.NoReturn: + def error(self, *args: Any) -> NoReturn: """Immediately aborts the session and optionally logs an error.""" raise _SessionQuit(*args) - def skip(self, *args: Any) -> _typing.NoReturn: + def skip(self, *args: Any) -> NoReturn: """Immediately skips the session and optionally logs a warning.""" raise _SessionSkip(*args) @@ -817,11 +825,12 @@ def imperfect(self) -> str: """ if self.status == Status.SUCCESS: return "was successful" + status = self.status.name.lower() if self.reason: return f"{status}: {self.reason}" - else: - return status + + return status def log(self, message: str) -> None: """Log a message using the appropriate log function. diff --git a/nox/virtualenv.py b/nox/virtualenv.py index 07fae2b6..1617a52f 100644 --- a/nox/virtualenv.py +++ b/nox/virtualenv.py @@ -14,6 +14,7 @@ from __future__ import annotations +import contextlib import os import platform import re @@ -21,11 +22,10 @@ import subprocess import sys from socket import gethostbyname -from typing import Any, Mapping +from typing import Any, ClassVar, Mapping import nox import nox.command -from nox import _typing from nox.logger import logger # Problematic environment variables that are stripped from all commands inside @@ -52,7 +52,7 @@ class ProcessEnv: is_sandboxed = False # Special programs that aren't included in the environment. - allowed_globals: _typing.ClassVar[tuple[Any, ...]] = () + allowed_globals: ClassVar[tuple[Any, ...]] = () def __init__( self, bin_paths: None = None, env: Mapping[str, str] | None = None @@ -207,7 +207,7 @@ def __init__( self.location = os.path.abspath(location) self.interpreter = interpreter self.reuse_existing = reuse_existing - self.venv_params = venv_params if venv_params else [] + self.venv_params = venv_params or [] self.conda_cmd = conda_cmd super().__init__(env={"CONDA_PREFIX": self.location}) @@ -227,10 +227,8 @@ def _clean_location(self) -> bool: ] nox.command.run(cmd, silent=True, log=False) # Make sure that location is clean - try: + with contextlib.suppress(FileNotFoundError): shutil.rmtree(self.location) - except FileNotFoundError: - pass return True @@ -247,8 +245,8 @@ def bin_paths(self) -> list[str]: os.path.join(self.location, "Scripts"), os.path.join(self.location, "bin"), ] - else: - return [os.path.join(self.location, "bin")] + + return [os.path.join(self.location, "bin")] def create(self) -> bool: """Create the conda env.""" @@ -332,7 +330,7 @@ def __init__( self._resolved: None | str | InterpreterNotFound = None self.reuse_existing = reuse_existing self.venv_or_virtualenv = "venv" if venv else "virtualenv" - self.venv_params = venv_params if venv_params else [] + self.venv_params = venv_params or [] super().__init__(env={"VIRTUAL_ENV": self.location}) def _clean_location(self) -> bool: @@ -465,8 +463,7 @@ def bin_paths(self) -> list[str]: """Returns the location of the virtualenv's bin folder.""" if _SYSTEM == "Windows": return [os.path.join(self.location, "Scripts")] - else: - return [os.path.join(self.location, "bin")] + return [os.path.join(self.location, "bin")] def create(self) -> bool: """Create the virtualenv or venv.""" diff --git a/pyproject.toml b/pyproject.toml index 8842712c..ce206ea5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ branch = true omit = [ "nox/_typing.py" ] [tool.coverage.report] -exclude_lines = [ "pragma: no cover", "if _typing.TYPE_CHECKING:", "@overload" ] +exclude_lines = [ "pragma: no cover", "if TYPE_CHECKING:", "@overload" ] [tool.pytest.ini_options] minversion = "6.0"