Skip to content

Commit

Permalink
add typing to pass pyright
Browse files Browse the repository at this point in the history
  • Loading branch information
dzcode authored and davidism committed Jun 30, 2023
1 parent 6c3a1fc commit 9149ebc
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Unreleased
function. :pr:`2421`
- Bash version detection doesn't fail on Windows. :issue:`2461`
- Completion works if there is a dot (``.``) in the program name. :issue:`2166`
- Improve type annotations for pyright type checker. :issue:`2268`


Version 8.1.3
Expand Down
2 changes: 1 addition & 1 deletion src/click/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def get_text_stderr(


def _wrap_io_open(
file: t.Union[str, "os.PathLike[t.AnyStr]", int],
file: t.Union[str, "os.PathLike[str]", int],
mode: str,
encoding: t.Optional[str],
errors: t.Optional[str],
Expand Down
26 changes: 17 additions & 9 deletions src/click/_termui_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
import typing as t
from gettext import gettext as _
from types import TracebackType

from ._compat import _default_text_stdout
from ._compat import CYGWIN
Expand Down Expand Up @@ -59,15 +60,15 @@ def __init__(
self.show_percent = show_percent
self.show_pos = show_pos
self.item_show_func = item_show_func
self.label = label or ""
self.label: str = label or ""
if file is None:
file = _default_text_stdout()
self.file = file
self.color = color
self.update_min_steps = update_min_steps
self._completed_intervals = 0
self.width = width
self.autowidth = width == 0
self.width: int = width
self.autowidth: bool = width == 0

if length is None:
from operator import length_hint
Expand All @@ -80,25 +81,32 @@ def __init__(
if length is None:
raise TypeError("iterable or length is required")
iterable = t.cast(t.Iterable[V], range(length))
self.iter = iter(iterable)
self.iter: t.Iterable[V] = iter(iterable)
self.length = length
self.pos = 0
self.avg: t.List[float] = []
self.last_eta: float
self.start: float
self.start = self.last_eta = time.time()
self.eta_known = False
self.finished = False
self.eta_known: bool = False
self.finished: bool = False
self.max_width: t.Optional[int] = None
self.entered = False
self.entered: bool = False
self.current_item: t.Optional[V] = None
self.is_hidden = not isatty(self.file)
self.is_hidden: bool = not isatty(self.file)
self._last_line: t.Optional[str] = None

def __enter__(self) -> "ProgressBar[V]":
self.entered = True
self.render_progress()
return self

def __exit__(self, *_: t.Any) -> None:
def __exit__(
self,
exc_type: t.Optional[t.Type[BaseException]],
exc_value: t.Optional[BaseException],
tb: t.Optional[TracebackType],
) -> None:
self.render_finish()

def __iter__(self) -> t.Iterator[V]:
Expand Down
28 changes: 19 additions & 9 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from collections import abc
from contextlib import contextmanager
from contextlib import ExitStack
from functools import partial
from functools import update_wrapper
from gettext import gettext as _
from gettext import ngettext
from itertools import repeat
from types import TracebackType

from . import types
from .exceptions import Abort
Expand Down Expand Up @@ -455,7 +455,12 @@ def __enter__(self) -> "Context":
push_context(self)
return self

def __exit__(self, *_: t.Any) -> None:
def __exit__(
self,
exc_type: t.Optional[t.Type[BaseException]],
exc_value: t.Optional[BaseException],
tb: t.Optional[TracebackType],
) -> None:
self._depth -= 1
if self._depth == 0:
self.close()
Expand Down Expand Up @@ -2097,10 +2102,13 @@ def __init__(
]
] = None,
) -> None:
self.name: t.Optional[str]
self.opts: t.List[str]
self.secondary_opts: t.List[str]
self.name, self.opts, self.secondary_opts = self._parse_decls(
param_decls or (), expose_value
)
self.type = types.convert_type(type, default)
self.type: types.ParamType = types.convert_type(type, default)

# Default nargs to what the type tells us if we have that
# information available.
Expand Down Expand Up @@ -2300,17 +2308,18 @@ def check_iter(value: t.Any) -> t.Iterator[t.Any]:
) from None

if self.nargs == 1 or self.type.is_composite:
convert: t.Callable[[t.Any], t.Any] = partial(
self.type, param=self, ctx=ctx
)

def convert(value: t.Any) -> t.Any:
return self.type(value, param=self, ctx=ctx)

elif self.nargs == -1:

def convert(value: t.Any) -> t.Tuple[t.Any, ...]:
def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...]
return tuple(self.type(x, self, ctx) for x in check_iter(value))

else: # nargs > 1

def convert(value: t.Any) -> t.Tuple[t.Any, ...]:
def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...]
value = tuple(check_iter(value))

if len(value) != self.nargs:
Expand Down Expand Up @@ -2564,13 +2573,14 @@ def __init__(
if flag_value is None:
flag_value = not self.default

self.type: types.ParamType
if is_flag and type is None:
# Re-guess the type from the flag value instead of the
# default.
self.type = types.convert_type(None, flag_value)

self.is_flag: bool = is_flag
self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType)
self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType)
self.flag_value: t.Any = flag_value

# Counting
Expand Down
7 changes: 4 additions & 3 deletions src/click/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .utils import echo

if t.TYPE_CHECKING:
from .core import Command
from .core import Context
from .core import Parameter

Expand Down Expand Up @@ -57,7 +58,7 @@ class UsageError(ClickException):
def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None:
super().__init__(message)
self.ctx = ctx
self.cmd = self.ctx.command if self.ctx else None
self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None

def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None:
if file is None:
Expand Down Expand Up @@ -261,7 +262,7 @@ def __init__(self, filename: str, hint: t.Optional[str] = None) -> None:
hint = _("unknown error")

super().__init__(hint)
self.ui_filename = os.fsdecode(filename)
self.ui_filename: str = os.fsdecode(filename)
self.filename = filename

def format_message(self) -> str:
Expand All @@ -284,4 +285,4 @@ class Exit(RuntimeError):
__slots__ = ("exit_code",)

def __init__(self, code: int = 0) -> None:
self.exit_code = code
self.exit_code: int = code
8 changes: 4 additions & 4 deletions src/click/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def __init__(
):
self._short_opts = []
self._long_opts = []
self.prefixes = set()
self.prefixes: t.Set[str] = set()

for opt in opts:
prefix, value = split_opt(opt)
Expand All @@ -194,7 +194,7 @@ def __init__(
def takes_value(self) -> bool:
return self.action in ("store", "append")

def process(self, value: str, state: "ParsingState") -> None:
def process(self, value: t.Any, state: "ParsingState") -> None:
if self.action == "store":
state.opts[self.dest] = value # type: ignore
elif self.action == "store_const":
Expand Down Expand Up @@ -272,12 +272,12 @@ def __init__(self, ctx: t.Optional["Context"] = None) -> None:
#: If this is set to `False`, the parser will stop on the first
#: non-option. Click uses this to implement nested subcommands
#: safely.
self.allow_interspersed_args = True
self.allow_interspersed_args: bool = True
#: This tells the parser how to deal with unknown options. By
#: default it will error out (which is sensible), but there is a
#: second mode where it will ignore it and continue processing
#: after shifting all the unknown options into the resulting args.
self.ignore_unknown_options = False
self.ignore_unknown_options: bool = False

if ctx is not None:
self.allow_interspersed_args = ctx.allow_interspersed_args
Expand Down
8 changes: 5 additions & 3 deletions src/click/shell_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ def __init__(
help: t.Optional[str] = None,
**kwargs: t.Any,
) -> None:
self.value = value
self.type = type
self.help = help
self.value: t.Any = value
self.type: str = type
self.help: t.Optional[str] = help
self._info = kwargs

def __getattr__(self, name: str) -> t.Any:
Expand Down Expand Up @@ -517,6 +517,8 @@ def _resolve_context(
ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True)
args = ctx.protected_args + ctx.args
else:
sub_ctx = ctx

while args:
name, cmd, args = command.resolve_command(ctx, args)

Expand Down
2 changes: 1 addition & 1 deletion src/click/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def __init__(
mix_stderr: bool = True,
) -> None:
self.charset = charset
self.env = env or {}
self.env: t.Mapping[str, t.Optional[str]] = env or {}
self.echo_stdin = echo_stdin
self.mix_stderr = mix_stderr

Expand Down
16 changes: 10 additions & 6 deletions src/click/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def arity(self) -> int: # type: ignore

class FuncParamType(ParamType):
def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None:
self.name = func.__name__
self.name: str = func.__name__
self.func = func

def to_info_dict(self) -> t.Dict[str, t.Any]:
Expand Down Expand Up @@ -353,7 +353,11 @@ class DateTime(ParamType):
name = "datetime"

def __init__(self, formats: t.Optional[t.Sequence[str]] = None):
self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]
self.formats: t.Sequence[str] = formats or [
"%Y-%m-%d",
"%Y-%m-%dT%H:%M:%S",
"%Y-%m-%d %H:%M:%S",
]

def to_info_dict(self) -> t.Dict[str, t.Any]:
info_dict = super().to_info_dict()
Expand Down Expand Up @@ -662,7 +666,7 @@ class File(ParamType):
"""

name = "filename"
envvar_list_splitter = os.path.pathsep
envvar_list_splitter: t.ClassVar[str] = os.path.pathsep

def __init__(
self,
Expand Down Expand Up @@ -780,7 +784,7 @@ class Path(ParamType):
Added the ``allow_dash`` parameter.
"""

envvar_list_splitter = os.path.pathsep
envvar_list_splitter: t.ClassVar[str] = os.path.pathsep

def __init__(
self,
Expand All @@ -805,7 +809,7 @@ def __init__(
self.type = path_type

if self.file_okay and not self.dir_okay:
self.name = _("file")
self.name: str = _("file")
elif self.dir_okay and not self.file_okay:
self.name = _("directory")
else:
Expand Down Expand Up @@ -942,7 +946,7 @@ class Tuple(CompositeParamType):
"""

def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None:
self.types = [convert_type(ty) for ty in types]
self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types]

def to_info_dict(self) -> t.Dict[str, t.Any]:
info_dict = super().to_info_dict()
Expand Down
18 changes: 15 additions & 3 deletions src/click/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import typing as t
from functools import update_wrapper
from types import ModuleType
from types import TracebackType

from ._compat import _default_text_stderr
from ._compat import _default_text_stdout
Expand Down Expand Up @@ -124,6 +125,7 @@ def __init__(
self.errors = errors
self.atomic = atomic
self._f: t.Optional[t.IO[t.Any]]
self.should_close: bool

if filename == "-":
self._f, self.should_close = open_stream(filename, mode, encoding, errors)
Expand Down Expand Up @@ -177,7 +179,12 @@ def close_intelligently(self) -> None:
def __enter__(self) -> "LazyFile":
return self

def __exit__(self, *_: t.Any) -> None:
def __exit__(
self,
exc_type: t.Optional[t.Type[BaseException]],
exc_value: t.Optional[BaseException],
tb: t.Optional[TracebackType],
) -> None:
self.close_intelligently()

def __iter__(self) -> t.Iterator[t.AnyStr]:
Expand All @@ -187,15 +194,20 @@ def __iter__(self) -> t.Iterator[t.AnyStr]:

class KeepOpenFile:
def __init__(self, file: t.IO[t.Any]) -> None:
self._file = file
self._file: t.IO[t.Any] = file

def __getattr__(self, name: str) -> t.Any:
return getattr(self._file, name)

def __enter__(self) -> "KeepOpenFile":
return self

def __exit__(self, *_: t.Any) -> None:
def __exit__(
self,
exc_type: t.Optional[t.Type[BaseException]],
exc_value: t.Optional[BaseException],
tb: t.Optional[TracebackType],
) -> None:
pass

def __repr__(self) -> str:
Expand Down

0 comments on commit 9149ebc

Please sign in to comment.