Skip to content

Commit

Permalink
fix(types): full strictness checking on mypy (#596)
Browse files Browse the repository at this point in the history
* Add some missing generic arguments

* fix(types): add full strict checking

* fix(types): enable extra error checks

* Update .pre-commit-config.yaml

Co-authored-by: Robert Craigie <robert@craigie.dev>
Co-authored-by: Tom Fleet <tomfleet2018@gmail.com>
  • Loading branch information
3 people committed Apr 21, 2022
1 parent d9e2580 commit af96f51
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 44 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ repos:
additional_dependencies: *flake8-dependencies

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
rev: v0.942
hooks:
- id: mypy
files: ^nox/
args: [--show-error-codes]
args: []
additional_dependencies:
- types-jinja2
- packaging
Expand Down
19 changes: 11 additions & 8 deletions nox/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import functools
import inspect
import types
from typing import Any, Callable, Iterable
from typing import Any, Callable, Iterable, TypeVar, cast

from . import _typing

Expand All @@ -34,24 +34,27 @@ def __new__(
return functools.wraps(func)(obj)


def _copy_func(src: Callable, name: str | None = None) -> Callable:
T = TypeVar("T", bound=Callable[..., Any])


def _copy_func(src: T, name: str | None = None) -> T:
dst = types.FunctionType(
src.__code__,
src.__globals__, # type: ignore[attr-defined]
src.__globals__,
name=name or src.__name__,
argdefs=src.__defaults__, # type: ignore[attr-defined]
closure=src.__closure__, # type: ignore[attr-defined]
argdefs=src.__defaults__,
closure=src.__closure__,
)
dst.__dict__.update(copy.deepcopy(src.__dict__))
dst = functools.update_wrapper(dst, src)
dst.__kwdefaults__ = src.__kwdefaults__ # type: ignore[attr-defined]
return dst
dst.__kwdefaults__ = src.__kwdefaults__
return cast(T, dst)


class Func(FunctionDecorator):
def __init__(
self,
func: Callable,
func: Callable[..., Any],
python: _typing.Python = None,
reuse_venv: bool | None = None,
name: str | None = None,
Expand Down
8 changes: 6 additions & 2 deletions nox/_option_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ def __init__(
noxfile: bool = False,
merge_func: Callable[[Namespace, Namespace], Any] | None = None,
finalizer_func: Callable[[Any, Namespace], Any] | None = None,
default: Any | Callable[[], Any] = None,
default: bool
| str
| None
| list[str]
| Callable[[], bool | str | None | list[str]] = None,
hidden: bool = False,
completer: Callable[..., list[str]] | None = None,
**kwargs: Any,
Expand All @@ -101,7 +105,7 @@ def __init__(
self._default = default

@property
def default(self) -> bool | str | None:
def default(self) -> bool | str | None | list[str]:
if callable(self._default):
return self._default()
return self._default
Expand Down
6 changes: 3 additions & 3 deletions nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def _sessions_and_keywords_merge_func(
noxfile_Args (_option_set.Namespace): The options specified in the
Noxfile."""
if not command_args.sessions and not command_args.keywords:
return getattr(noxfile_args, key)
return getattr(command_args, key)
return getattr(noxfile_args, key) # type: ignore[no-any-return]
return getattr(command_args, key) # type: ignore[no-any-return]


def _default_venv_backend_merge_func(
Expand Down Expand Up @@ -123,7 +123,7 @@ def _force_venv_backend_merge_func(
else:
return "none"
else:
return command_args.force_venv_backend or noxfile_args.force_venv_backend
return command_args.force_venv_backend or noxfile_args.force_venv_backend # type: ignore[no-any-return]


def _envdir_merge_func(
Expand Down
2 changes: 1 addition & 1 deletion nox/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class InvalidVersionSpecifier(Exception):

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


def _parse_string_constant(node: ast.AST) -> str | None: # pragma: no cover
Expand Down
8 changes: 4 additions & 4 deletions nox/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ def which(program: str, paths: list[str] | None) -> str:
full_path = py.path.local.sysfind(program, paths=paths)

if full_path:
return full_path.strpath
return full_path.strpath # type: ignore[no-any-return]

full_path = py.path.local.sysfind(program)

if full_path:
return full_path.strpath
return full_path.strpath # type: ignore[no-any-return]

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


def _clean_env(env: dict | None) -> dict | None:
def _clean_env(env: dict[str, str] | None) -> dict[str, str] | None:
if env is None:
return None

Expand All @@ -78,7 +78,7 @@ def _shlex_join(args: Sequence[str]) -> str:
def run(
args: Sequence[str],
*,
env: dict | None = None,
env: dict[str, str] | None = None,
silent: bool = False,
paths: list[str] | None = None,
success_codes: Iterable[int] | None = None,
Expand Down
4 changes: 2 additions & 2 deletions nox/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def format(self, record: Any) -> str:
return super().format(record)


class NoxColoredFormatter(ColoredFormatter):
class NoxColoredFormatter(ColoredFormatter): # type: ignore[misc]
def __init__(
self,
datefmt: Any = None,
Expand All @@ -70,7 +70,7 @@ def __init__(
def format(self, record: Any) -> str:
if record.levelname == "OUTPUT":
return self._simple_fmt.format(record)
return super().format(record)
return super().format(record) # type: ignore[no-any-return]


class LoggerWithSuccessAndOutput(logging.getLoggerClass()): # type: ignore[misc]
Expand Down
3 changes: 1 addition & 2 deletions nox/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import argparse
import ast
import collections.abc
import itertools
from collections import OrderedDict
from typing import Any, Iterable, Iterator, Mapping, Sequence
Expand Down Expand Up @@ -310,7 +309,7 @@ def notify(
raise ValueError(f"Session {session} not found.")


class KeywordLocals(collections.abc.Mapping):
class KeywordLocals(Mapping[str, bool]):
"""Eval locals using keywords.
When looking up a local variable the variable name is compared against
Expand Down
6 changes: 3 additions & 3 deletions nox/popen.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


def shutdown_process(
proc: subprocess.Popen,
proc: subprocess.Popen[bytes],
interrupt_timeout: float | None,
terminate_timeout: float | None,
) -> tuple[bytes, bytes]:
Expand Down Expand Up @@ -61,8 +61,8 @@ def popen(
args: Sequence[str],
env: Mapping[str, str] | None = None,
silent: bool = False,
stdout: int | IO | None = None,
stderr: int | IO = subprocess.STDOUT,
stdout: int | IO[str] | None = None,
stderr: int | IO[str] = subprocess.STDOUT,
interrupt_timeout: float | None = 0.3,
terminate_timeout: float | None = 0.2,
) -> tuple[int, str]:
Expand Down
2 changes: 1 addition & 1 deletion nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def invoked_from(self) -> str:
to the Noxfile's directory before running any sessions. This gives
you the original working directory that Nox was invoked form.
"""
return self._runner.global_config.invoked_from
return self._runner.global_config.invoked_from # type: ignore[no-any-return]

def chdir(self, dir: str | os.PathLike[str]) -> _WorkingDirContext:
"""Change the current working directory.
Expand Down
2 changes: 1 addition & 1 deletion nox/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def locate_via_py(version: str) -> str | None:
py_exe = py.path.local.sysfind("py")
if py_exe is not None:
try:
return py_exe.sysexec("-" + version, "-c", script).strip()
return py_exe.sysexec("-" + version, "-c", script).strip() # type: ignore[no-any-return]
except py.process.cmdexec.Error:
return None
return None
Expand Down
2 changes: 1 addition & 1 deletion nox/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def execute(
"""
try:
# Iterate over each task and run it.
return_value = None
return_value: Any = None
for function_ in workflow:
# Send the previous task's return value if there was one.
args: list[Any] = []
Expand Down
18 changes: 4 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,10 @@ testpaths = [
[tool.mypy]
files = ["nox"]
python_version = "3.7"
warn_unused_configs = true
disallow_any_generics = false
disallow_subclassing_any = false
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = false
no_implicit_reexport = true
strict_equality = true
show_error_codes = true
strict = true
warn_unreachable = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]

[[tool.mypy.overrides]]
module = [ "argcomplete", "colorlog.*", "py", "tox.*" ]
Expand Down

0 comments on commit af96f51

Please sign in to comment.