Skip to content
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

style: add pre-commit and new checks #530

Merged
merged 3 commits into from Dec 27, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
89 changes: 89 additions & 0 deletions .pre-commit-config.yaml
@@ -0,0 +1,89 @@
ci:
autoupdate_commit_msg: "chore: update pre-commit hooks"
autofix_commit_msg: "style: pre-commit fixes"

repos:
- repo: https://github.com/psf/black
rev: 21.12b0
hooks:
- id: black

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: mixed-line-ending
- id: requirements-txt-fixer
- id: trailing-whitespace

- repo: https://github.com/asottile/pyupgrade
rev: v2.29.1
hooks:
- id: pyupgrade
args: [--py36-plus]

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort

- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.0
hooks:
- id: setup-cfg-fmt

- repo: https://github.com/hadialqattan/pycln
rev: v1.1.0
hooks:
- id: pycln
args: [--config=pyproject.toml]

- repo: https://github.com/asottile/yesqa
rev: v1.3.0
hooks:
- id: yesqa
additional_dependencies: &flake8-dependencies
- flake8-bugbear

- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8
exclude: docs/conf.py
additional_dependencies: *flake8-dependencies

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.920
hooks:
- id: mypy
files: ^nox/
args: [--show-error-codes]
additional_dependencies:
- types-jinja2
- packaging
- importlib_metadata

- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
- id: codespell

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:
- id: python-check-blanket-noqa
- id: python-check-blanket-type-ignore
- id: python-no-log-warn
exclude: ^tests/test_sessions.py$
- id: python-no-eval
exclude: ^nox/manifest.py$
- id: python-use-type-annotations
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Expand Up @@ -54,4 +54,4 @@ If you've contributed to Nox, you can get a cute little Nox sticker. Reach out t

## Getting paid

Contributions to Nox can be expensed through [our Open Collective](https://opencollective.com/python-nox). The maintainers will let you know when and for how much you can expense contributions, but always feel free to ask.
Contributions to Nox can be expensed through [our Open Collective](https://opencollective.com/python-nox). The maintainers will let you know when and for how much you can expense contributions, but always feel free to ask.
2 changes: 1 addition & 1 deletion docs/_static/custom.css
Expand Up @@ -120,7 +120,7 @@ div.footer::before {

div.footer {
text-align: center;
color: #029be2;
color: #029be2;
}

div.footer a {
Expand Down
1 change: 0 additions & 1 deletion docs/conf.py
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# nox documentation build configuration file, created by
# sphinx-quickstart on Sun Feb 28 00:05:25 2016.
Expand Down
6 changes: 3 additions & 3 deletions docs/cookbook.rst
Expand Up @@ -40,7 +40,7 @@ Enter the ``dev`` nox session:
.. code-block:: python

import os

import nox

# It's a good idea to keep your dev session out of the default list
Expand Down Expand Up @@ -91,7 +91,7 @@ Even more so with a sprinkling of Nox:
Kicks off an automated release process by creating and pushing a new tag.

Invokes bump2version with the posarg setting the version.

Usage:
$ nox -s release -- [major|minor|patch]
"""
Expand Down Expand Up @@ -126,4 +126,4 @@ Even more so with a sprinkling of Nox:
session.run("git", "push", external=True)
session.run("git", "push", "--tags", external=True)

Now a simple ``nox -s release -- patch`` will automate your release (provided you have Bump2Version set up to change your files). This is especially powerful if you have a CI/CD pipeline set up!
Now a simple ``nox -s release -- patch`` will automate your release (provided you have Bump2Version set up to change your files). This is especially powerful if you have a CI/CD pipeline set up!
2 changes: 1 addition & 1 deletion docs/tutorial.rst
Expand Up @@ -273,7 +273,7 @@ If you want to queue up (or "notify") another session from the current one, you
session.install("pytest")
session.run("pytest")
# Here we queue up the test coverage session to run next
session.notify("coverage")
session.notify("coverage")
@nox.session
def coverage(session):
Expand Down
2 changes: 1 addition & 1 deletion docs/usage.rst
Expand Up @@ -128,7 +128,7 @@ Note that using this option does not change the backend for sessions where ``ven
Forcing the sessions backend
----------------------------

You might work in a different environment than a project's default continuous integration setttings, and might wish to get a quick way to execute the same tasks but on a different venv backend. For this purpose, you can temporarily force the backend used by **all** sessions in the current nox execution by using ``-fb <backend>`` or ``--force-venv-backend <backend>``. No exceptions are made, the backend will be forced for all sessions run whatever the other options values and nox file configuration. Supported names are ``('none', 'virtualenv', 'conda', 'venv')``.
You might work in a different environment than a project's default continuous integration settings, and might wish to get a quick way to execute the same tasks but on a different venv backend. For this purpose, you can temporarily force the backend used by **all** sessions in the current nox execution by using ``-fb <backend>`` or ``--force-venv-backend <backend>``. No exceptions are made, the backend will be forced for all sessions run whatever the other options values and nox file configuration. Supported names are ``('none', 'virtualenv', 'conda', 'venv')``.

.. code-block:: console
Expand Down
8 changes: 4 additions & 4 deletions nox/_decorators.py
Expand Up @@ -35,14 +35,14 @@ def __new__(
def _copy_func(src: Callable, name: Optional[str] = None) -> Callable:
dst = types.FunctionType(
src.__code__,
src.__globals__, # type: ignore
src.__globals__, # type: ignore[attr-defined]
name=name or src.__name__,
argdefs=src.__defaults__, # type: ignore
closure=src.__closure__, # type: ignore
argdefs=src.__defaults__, # type: ignore[attr-defined]
closure=src.__closure__, # type: ignore[attr-defined]
)
dst.__dict__.update(copy.deepcopy(src.__dict__))
dst = functools.update_wrapper(dst, src)
dst.__kwdefaults__ = src.__kwdefaults__ # type: ignore
dst.__kwdefaults__ = src.__kwdefaults__ # type: ignore[attr-defined]
return dst


Expand Down
12 changes: 5 additions & 7 deletions nox/_option_set.py
Expand Up @@ -191,12 +191,10 @@ class OptionSet:
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.parser_args = args
self.parser_kwargs = kwargs
self.options = (
self.options: "collections.OrderedDict[str, Option]" = collections.OrderedDict()
self.groups: "collections.OrderedDict[str, OptionGroup]" = (
collections.OrderedDict()
) # type: collections.OrderedDict[str, Option]
self.groups = (
collections.OrderedDict()
) # type: collections.OrderedDict[str, OptionGroup]
)

def add_options(self, *args: Option) -> None:
"""Adds a sequence of Options to the OptionSet.
Expand Down Expand Up @@ -242,8 +240,8 @@ def parser(self) -> ArgumentParser:
argument = groups[option.group.name].add_argument(
*option.flags, help=option.help, default=option.default, **option.kwargs
)
if getattr(option, "completer"):
setattr(argument, "completer", option.completer)
if option.completer:
cjolowicz marked this conversation as resolved.
Show resolved Hide resolved
argument.completer = option.completer # type: ignore[attr-defined]

return parser

Expand Down
6 changes: 3 additions & 3 deletions nox/_parametrize.py
Expand Up @@ -81,7 +81,7 @@ def __eq__(self, other: object) -> bool:
def _apply_param_specs(param_specs: List[Param], f: Any) -> Any:
previous_param_specs = getattr(f, "parametrize", None)
new_param_specs = update_param_specs(previous_param_specs, param_specs)
setattr(f, "parametrize", new_param_specs)
f.parametrize = new_param_specs
cjolowicz marked this conversation as resolved.
Show resolved Hide resolved
return f


Expand Down Expand Up @@ -119,7 +119,7 @@ def parametrize_decorator(

# If there's only one arg_name, arg_values_list should be a single item
# or list. Transform it so it'll work with the combine step.
_arg_values_list = [] # type: List[Union[Param, Iterable[Union[Any, ArgValue]]]]
_arg_values_list: List[Union[Param, Iterable[Union[Any, ArgValue]]]] = []
if len(arg_names) == 1:
# In this case, the arg_values_list can also just be a single item.
# Must be mutable for the transformation steps
Expand All @@ -141,7 +141,7 @@ def parametrize_decorator(
ids = []

# Generate params for each item in the param_args_values list.
param_specs = [] # type: List[Param]
param_specs: List[Param] = []
for param_arg_values, param_id in itertools.zip_longest(_arg_values_list, ids):
if isinstance(param_arg_values, Param):
param_spec = param_arg_values
Expand Down
2 changes: 1 addition & 1 deletion nox/_version.py
Expand Up @@ -36,7 +36,7 @@ class InvalidVersionSpecifier(Exception):

def get_nox_version() -> str:
"""Return the version of the installed Nox package."""
return metadata.version("nox") # type: ignore
return metadata.version("nox") # type: ignore[no-untyped-call]


def _parse_string_constant(node: ast.AST) -> Optional[str]: # pragma: no cover
Expand Down
2 changes: 1 addition & 1 deletion nox/command.py
Expand Up @@ -32,7 +32,7 @@ class CommandFailed(Exception):
"""Raised when an executed command returns a non-success status code."""

def __init__(self, reason: Optional[str] = None) -> None:
super(CommandFailed, self).__init__(reason)
super().__init__(reason)
self.reason = reason


Expand Down
2 changes: 1 addition & 1 deletion nox/logger.py
Expand Up @@ -71,7 +71,7 @@ def format(self, record: Any) -> str:
return super().format(record)


class LoggerWithSuccessAndOutput(logging.getLoggerClass()): # type: ignore
class LoggerWithSuccessAndOutput(logging.getLoggerClass()): # type: ignore[misc]
def __init__(self, name: str, level: int = logging.NOTSET):
super().__init__(name, level)
logging.addLevelName(SUCCESS, "SUCCESS")
Expand Down
14 changes: 7 additions & 7 deletions nox/manifest.py
Expand Up @@ -65,11 +65,11 @@ def __init__(
global_config: argparse.Namespace,
module_docstring: Optional[str] = None,
) -> None:
self._all_sessions = [] # type: List[SessionRunner]
self._queue = [] # type: List[SessionRunner]
self._consumed = [] # type: List[SessionRunner]
self._config = global_config # type: argparse.Namespace
self.module_docstring = module_docstring # type: Optional[str]
self._all_sessions: List[SessionRunner] = []
self._queue: List[SessionRunner] = []
self._consumed: List[SessionRunner] = []
self._config: argparse.Namespace = global_config
self.module_docstring: Optional[str] = module_docstring

# Create the sessions based on the provided session functions.
for name, func in session_functions.items():
Expand Down Expand Up @@ -217,7 +217,7 @@ def make_session(
if self._config.extra_pythons:
# If extra python is provided, expand the func.python list to
# include additional python interpreters
extra_pythons = self._config.extra_pythons # type: List[str]
extra_pythons: List[str] = self._config.extra_pythons
if isinstance(func.python, (list, tuple, set)):
func.python = _unique_list(*func.python, *extra_pythons)
elif not multi and func.python:
Expand Down Expand Up @@ -253,7 +253,7 @@ def make_session(

# Since this function is parametrized, we need to add a distinct
# session for each permutation.
parametrize = func.parametrize # type: ignore
parametrize = func.parametrize # type: ignore[attr-defined]
calls = Call.generate_calls(func, parametrize)
for call in calls:
long_names = []
Expand Down
2 changes: 1 addition & 1 deletion nox/py.typed
@@ -1 +1 @@
# Marker file for PEP 561. The nox package uses inline types.
# Marker file for PEP 561. The nox package uses inline types.
2 changes: 1 addition & 1 deletion nox/registry.py
Expand Up @@ -22,7 +22,7 @@

F = TypeVar("F", bound=Callable[..., Any])

_REGISTRY = collections.OrderedDict() # type: collections.OrderedDict[str, Func]
_REGISTRY: "collections.OrderedDict[str, Func]" = collections.OrderedDict()


@overload
Expand Down
12 changes: 6 additions & 6 deletions nox/sessions.py
Expand Up @@ -128,7 +128,7 @@ def __init__(self, runner: "SessionRunner") -> None:
self._runner = runner

@property
def __dict__(self) -> "Dict[str, SessionRunner]": # type: ignore
def __dict__(self) -> "Dict[str, SessionRunner]": # type: ignore[override]
"""Attribute dictionary for object inspection.

This is needed because ``__slots__`` turns off ``__dict__`` by
Expand Down Expand Up @@ -411,7 +411,7 @@ def conda_install(
"""
venv = self._runner.venv

prefix_args = () # type: Tuple[str, ...]
prefix_args: Tuple[str, ...] = ()
if isinstance(venv, CondaEnv):
prefix_args = ("--prefix", venv.location)
elif not isinstance(venv, PassthroughEnv): # pragma: no cover
Expand All @@ -431,7 +431,7 @@ def conda_install(
if "silent" not in kwargs:
kwargs["silent"] = True

extraopts = [] # type: List[str]
extraopts: List[str] = []
if auto_offline and venv.is_offline():
logger.warning(
"Automatically setting the `--offline` flag as conda repo seems unreachable."
Expand Down Expand Up @@ -612,22 +612,22 @@ def _create_venv(self) -> None:
if backend is None or backend == "virtualenv":
self.venv = VirtualEnv(
self.envdir,
interpreter=self.func.python, # type: ignore
interpreter=self.func.python, # type: ignore[arg-type]
reuse_existing=reuse_existing,
venv_params=self.func.venv_params,
)
elif backend in {"conda", "mamba"}:
self.venv = CondaEnv(
self.envdir,
interpreter=self.func.python, # type: ignore
interpreter=self.func.python, # type: ignore[arg-type]
reuse_existing=reuse_existing,
venv_params=self.func.venv_params,
conda_cmd=backend,
)
elif backend == "venv":
self.venv = VirtualEnv(
self.envdir,
interpreter=self.func.python, # type: ignore
interpreter=self.func.python, # type: ignore[arg-type]
reuse_existing=reuse_existing,
venv=True,
venv_params=self.func.venv_params,
Expand Down