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 type hints, update few functions #728

Merged
merged 1 commit into from
Jul 16, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions nox/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,34 @@
from __future__ import annotations

import sys
from typing import Any

from nox import _options, tasks, workflow
from nox._version import get_nox_version
from nox.logger import setup_logging


def execute_workflow(args: Any) -> int:
"""
Execute the appropriate tasks.
"""

return workflow.execute(
global_config=args,
workflow=(
tasks.load_nox_module,
tasks.merge_noxfile_options,
tasks.discover_manifest,
tasks.filter_manifest,
tasks.honor_list_request,
tasks.run_manifest,
tasks.print_summary,
tasks.create_report,
tasks.final_reduce,
),
)


def main() -> None:
args = _options.options.parse_args()

Expand All @@ -43,21 +65,7 @@ def main() -> None:
color=args.color, verbose=args.verbose, add_timestamp=args.add_timestamp
)

# Execute the appropriate tasks.
exit_code = workflow.execute(
global_config=args,
workflow=(
tasks.load_nox_module,
tasks.merge_noxfile_options,
tasks.discover_manifest,
tasks.filter_manifest,
tasks.honor_list_request,
tasks.run_manifest,
tasks.print_summary,
tasks.create_report,
tasks.final_reduce,
),
)
exit_code = execute_workflow(args)

# Done; exit.
sys.exit(exit_code)
Expand Down
28 changes: 21 additions & 7 deletions nox/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,23 @@
if TYPE_CHECKING:
from ._parametrize import Param

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


class FunctionDecorator:
"""This is a function decorator."""

def __new__(
cls, func: Callable[..., Any], *args: Any, **kwargs: Any
cls: Any, func: Callable[..., Any], *args: Any, **kwargs: Any
) -> FunctionDecorator:
obj = super().__new__(cls)
return functools.wraps(func)(obj)


T = TypeVar("T", bound=Callable[..., Any])
functools.update_wrapper(obj, func)
return cast(FunctionDecorator, obj)


def _copy_func(src: T, name: str | None = None) -> T:
"""This function copies another function, optionally with a new name."""

dst = types.FunctionType(
src.__code__,
src.__globals__,
Expand All @@ -53,6 +57,8 @@ def _copy_func(src: T, name: str | None = None) -> T:


class Func(FunctionDecorator):
"""This is a function decorator that adds additional Nox-specific metadata."""

def __init__(
self,
func: Callable[..., Any],
Expand All @@ -63,7 +69,7 @@ def __init__(
venv_params: Any = None,
should_warn: Mapping[str, Any] | None = None,
tags: Sequence[str] | None = None,
):
) -> None:
self.func = func
self.python = python
self.reuse_venv = reuse_venv
Expand All @@ -77,6 +83,8 @@ def __call__(self, *args: Any, **kwargs: Any) -> Any:
return self.func(*args, **kwargs)

def copy(self, name: str | None = None) -> Func:
"""Copy this function with a new name."""

return Func(
_copy_func(self.func, name),
self.python,
Expand All @@ -90,6 +98,8 @@ def copy(self, name: str | None = None) -> Func:


class Call(Func):
"""This represents a call of a function with a particular set of arguments."""

def __init__(self, func: Func, param_spec: Param) -> None:
call_spec = param_spec.call_spec
session_signature = f"({param_spec})"
Expand Down Expand Up @@ -124,5 +134,9 @@ def __call__(self, *args: Any, **kwargs: Any) -> Any:
return super().__call__(*args, **kwargs)

@classmethod
def generate_calls(cls, func: Func, param_specs: Iterable[Param]) -> list[Call]:
def generate_calls(
cls: type[Call], func: Func, param_specs: Iterable[Param]
) -> list[Call]:
"""Generates a list of calls based on the function and parameters."""

return [cls(func, param_spec) for param_spec in param_specs]
6 changes: 4 additions & 2 deletions nox/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
else: # pragma: no cover
from typing import Literal

ExternalType = Literal["error", True, False]


class CommandFailed(Exception):
"""Raised when an executed command returns a non-success status code."""
Expand All @@ -53,7 +55,7 @@ def which(program: str | os.PathLike[str], paths: Sequence[str] | None) -> str:
raise CommandFailed(f"Program {program} not found")


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

Expand All @@ -80,7 +82,7 @@ def run(
paths: Sequence[str] | None = None,
success_codes: Iterable[int] | None = None,
log: bool = True,
external: Literal["error"] | bool = False,
external: ExternalType = False,
**popen_kws: Any,
) -> str | bool:
"""Run a command-line program."""
Expand Down
16 changes: 8 additions & 8 deletions nox/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,25 @@ def session_decorator(__func: F) -> F:
@overload
def session_decorator(
__func: None = ...,
python: Python = ...,
py: Python = ...,
python: Python | None = ...,
py: Python | None = ...,
reuse_venv: bool | None = ...,
name: str | None = ...,
venv_backend: Any = ...,
venv_params: Any = ...,
venv_backend: Any | None = ...,
venv_params: Any | None = ...,
tags: Sequence[str] | None = ...,
) -> Callable[[F], F]:
...


def session_decorator(
func: F | None = None,
python: Python = None,
py: Python = None,
python: Python | None = None,
py: Python | None = None,
reuse_venv: bool | None = None,
name: str | None = None,
venv_backend: Any = None,
venv_params: Any = None,
venv_backend: Any | None = None,
venv_params: Any | None = None,
tags: Sequence[str] | None = None,
) -> F | Callable[[F], F]:
"""Designate the decorated function as a session."""
Expand Down
11 changes: 9 additions & 2 deletions nox/tox_to_nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@


def wrapjoin(seq: Iterator[Any]) -> str:
"""Wrap each item in single quotes and join them with a comma."""
return ", ".join([f"'{item}'" for item in seq])


def fixname(envname: str) -> str:
"""Replace dashes with underscores and check if the result is a valid identifier."""
envname = envname.replace("-", "_")
if not envname.isidentifier():
print(
Expand All @@ -44,6 +46,12 @@ def fixname(envname: str) -> str:
return envname


def write_output_to_file(output: str, filename: str) -> None:
"""Write output to a file."""
with open(filename, "w") as outfile:
outfile.write(output)


def main() -> None:
parser = argparse.ArgumentParser(description="Converts toxfiles to noxfiles.")
parser.add_argument("--output", default="noxfile.py")
Expand All @@ -53,5 +61,4 @@ def main() -> None:
config = tox.config.parseconfig([])
output = _TEMPLATE.render(config=config, wrapjoin=wrapjoin, fixname=fixname)

with open(args.output, "w") as outfile:
outfile.write(output)
write_output_to_file(output, args.output)
3 changes: 2 additions & 1 deletion nox/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def execute(
args: list[Any] = []
if return_value is not None:
args.append(return_value)
return_value = function_(*args, global_config=global_config)
kwargs: dict[str, Any] = {"global_config": global_config}
return_value = function_(*args, **kwargs)

# If we got an integer value as a result, abort task processing
# and return it.
Expand Down