Update vendored click to 8.0.3

This commit is contained in:
Frost Ming
2021-11-12 11:57:33 +08:00
parent 2482e2d3a4
commit 8bdb310ca3
12 changed files with 71 additions and 65 deletions
+1
View File
@@ -0,0 +1 @@
Update ``click`` from ``8.0.1`` to ``8.0.3``, to fix a problem with bash completion.
+1 -1
View File
@@ -72,4 +72,4 @@ from .utils import get_os_args as get_os_args
from .utils import get_text_stream as get_text_stream
from .utils import open_file as open_file
__version__ = "8.0.1"
__version__ = "8.0.3"
+3 -2
View File
@@ -426,7 +426,7 @@ def _tempfilepager(
"""Page through text by invoking a program on a temporary file."""
import tempfile
_, filename = tempfile.mkstemp()
fd, filename = tempfile.mkstemp()
# TODO: This never terminates if the passed generator never terminates.
text = "".join(generator)
if not color:
@@ -437,6 +437,7 @@ def _tempfilepager(
try:
os.system(f'{cmd} "{filename}"')
finally:
os.close(fd)
os.unlink(filename)
@@ -497,7 +498,7 @@ class Editor:
except OSError as e:
raise ClickException(
_("{editor}: Editing failed: {e}").format(editor=editor, e=e)
)
) from e
def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]:
import tempfile
+31 -35
View File
@@ -46,17 +46,6 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
V = t.TypeVar("V")
def _fast_exit(code: int) -> "te.NoReturn":
"""Low-level exit that skips Python's cleanup but speeds up exit by
about 10ms for things like shell completion.
:param code: Exit code.
"""
sys.stdout.flush()
sys.stderr.flush()
os._exit(code)
def _complete_visible_commands(
ctx: "Context", incomplete: str
) -> t.Iterator[t.Tuple[str, "Command"]]:
@@ -750,7 +739,9 @@ class Context:
for param in other_cmd.params:
if param.name not in kwargs and param.expose_value:
kwargs[param.name] = param.get_default(ctx) # type: ignore
kwargs[param.name] = param.type_cast_value( # type: ignore
ctx, param.get_default(ctx)
)
# Track all kwargs as params, so that forward() will pass
# them on in subsequent calls.
@@ -1072,7 +1063,7 @@ class BaseCommand:
ctx.exit()
except (EOFError, KeyboardInterrupt):
echo(file=sys.stderr)
raise Abort()
raise Abort() from None
except ClickException as e:
if not standalone_mode:
raise
@@ -1130,7 +1121,7 @@ class BaseCommand:
from .shell_completion import shell_complete
rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction)
_fast_exit(rv)
sys.exit(rv)
def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
"""Alias for :meth:`main`."""
@@ -2197,12 +2188,15 @@ class Parameter:
self, ctx: Context, call: bool = True
) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
"""Get the default for the parameter. Tries
:meth:`Context.lookup_value` first, then the local default.
:meth:`Context.lookup_default` first, then the local default.
:param ctx: Current context.
:param call: If the default is a callable, call it. Disable to
return the callable instead.
.. versionchanged:: 8.0.2
Type casting is no longer performed when getting a default.
.. versionchanged:: 8.0.1
Type casting can fail in resilient parsing mode. Invalid
defaults will not prevent showing help text.
@@ -2218,20 +2212,10 @@ class Parameter:
if value is None:
value = self.default
if callable(value):
if not call:
# Don't type cast the callable.
return value
if call and callable(value):
value = value()
try:
return self.type_cast_value(ctx, value)
except BadParameter:
if ctx.resilient_parsing:
return value
raise
return value
def add_to_parser(self, parser: OptionParser, ctx: Context) -> None:
raise NotImplementedError()
@@ -2316,8 +2300,7 @@ class Parameter:
return False
def process_value(self, ctx: Context, value: t.Any) -> t.Any:
if value is not None:
value = self.type_cast_value(ctx, value)
value = self.type_cast_value(ctx, value)
if self.required and self.value_is_missing(value):
raise MissingParameter(ctx=ctx, param=self)
@@ -2461,7 +2444,7 @@ class Option(Parameter):
def __init__(
self,
param_decls: t.Optional[t.Sequence[str]] = None,
show_default: bool = False,
show_default: t.Union[bool, str] = False,
prompt: t.Union[bool, str] = False,
confirmation_prompt: t.Union[bool, str] = False,
prompt_required: bool = True,
@@ -2528,7 +2511,7 @@ class Option(Parameter):
self.type = types.convert_type(None, flag_value)
self.is_flag: bool = is_flag
self.is_bool_flag = isinstance(self.type, types.BoolParamType)
self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType)
self.flag_value: t.Any = flag_value
# Counting
@@ -2590,7 +2573,7 @@ class Option(Parameter):
for decl in decls:
if decl.isidentifier():
if name is not None:
raise TypeError("Name defined twice")
raise TypeError(f"Name '{name}' defined twice")
name = decl
else:
split_char = ";" if decl[:1] == "/" else "/"
@@ -2748,9 +2731,14 @@ class Option(Parameter):
else:
default_string = str(default_value)
extra.append(_("default: {default}").format(default=default_string))
if default_string:
extra.append(_("default: {default}").format(default=default_string))
if isinstance(self.type, types._NumberRangeBase):
if (
isinstance(self.type, types._NumberRangeBase)
# skip count with default range type
and not (self.count and self.type.min == 0 and self.type.max is None)
):
range_str = self.type._describe_range()
if range_str:
@@ -2760,7 +2748,7 @@ class Option(Parameter):
extra.append(_("required"))
if extra:
extra_str = ";".join(extra)
extra_str = "; ".join(extra)
help = f"{help} [{extra_str}]" if help else f"[{extra_str}]"
return ("; " if any_prefix_is_slash else " / ").join(rv), help
@@ -2867,6 +2855,14 @@ class Option(Parameter):
value = self.flag_value
source = ParameterSource.COMMANDLINE
elif (
self.multiple
and value is not None
and any(v is _flag_needs_value for v in value)
):
value = [self.flag_value if v is _flag_needs_value else v for v in value]
source = ParameterSource.COMMANDLINE
# The value wasn't set, or used the param's default, prompt if
# prompting is enabled.
elif (
+3 -4
View File
@@ -340,9 +340,8 @@ def version_option(
if version is None and package_name is None:
frame = inspect.currentframe()
assert frame is not None
assert frame.f_back is not None
f_globals = frame.f_back.f_globals if frame is not None else None
f_back = frame.f_back if frame is not None else None
f_globals = f_back.f_globals if f_back is not None else None
# break reference cycle
# https://docs.python.org/3/library/inspect.html#the-interpreter-stack
del frame
@@ -381,7 +380,7 @@ def version_option(
raise RuntimeError(
f"{package_name!r} is not installed. Try passing"
" 'package_name' instead."
)
) from None
if version is None:
raise RuntimeError(
+2 -2
View File
@@ -36,9 +36,9 @@ def get_current_context(silent: bool = False) -> t.Optional["Context"]:
"""
try:
return t.cast("Context", _local.stack[-1])
except (AttributeError, IndexError):
except (AttributeError, IndexError) as e:
if not silent:
raise RuntimeError("There is no active click context.")
raise RuntimeError("There is no active click context.") from e
return None
+1 -1
View File
@@ -300,7 +300,7 @@ class OptionParser:
"""Adds a new option named `dest` to the parser. The destination
is not inferred (unlike with optparse) and needs to be explicitly
provided. Action can be any of ``store``, ``store_const``,
``append``, ``appnd_const`` or ``count``.
``append``, ``append_const`` or ``count``.
The `obj` can be used to identify the option in the order list
that is returned from the parser.
+10 -3
View File
@@ -302,8 +302,10 @@ class BashComplete(ShellComplete):
def _check_version(self) -> None:
import subprocess
output = subprocess.run(["bash", "--version"], stdout=subprocess.PIPE)
match = re.search(r"version (\d)\.(\d)\.\d", output.stdout.decode())
output = subprocess.run(
["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE
)
match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())
if match is not None:
major, minor = match.groups()
@@ -448,7 +450,12 @@ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool:
def _start_of_option(value: str) -> bool:
"""Check if the value looks like the start of an option."""
return not value[0].isalnum() if value else False
if not value:
return False
c = value[0]
# Allow "/" since that starts a path.
return not c.isalnum() and c != "/"
def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool:
+11 -9
View File
@@ -84,7 +84,7 @@ def prompt(
default: t.Optional[t.Any] = None,
hide_input: bool = False,
confirmation_prompt: t.Union[bool, str] = False,
type: t.Optional[ParamType] = None,
type: t.Optional[t.Union[ParamType, t.Any]] = None,
value_proc: t.Optional[t.Callable[[str], t.Any]] = None,
prompt_suffix: str = ": ",
show_default: bool = True,
@@ -147,7 +147,7 @@ def prompt(
# A doc bug has been filed at https://bugs.python.org/issue24711
if hide_input:
echo(None, err=err)
raise Abort()
raise Abort() from None
if value_proc is None:
value_proc = convert_type(type, default)
@@ -231,10 +231,12 @@ def confirm(
try:
# Write the prompt separately so that we get nice
# coloring through colorama on Windows
echo(prompt, nl=False, err=err)
value = visible_prompt_func("").lower().strip()
echo(prompt.rstrip(" "), nl=False, err=err)
# Echo a space to stdout to work around an issue where
# readline causes backspace to clear the whole line.
value = visible_prompt_func(" ").lower().strip()
except (KeyboardInterrupt, EOFError):
raise Abort()
raise Abort() from None
if value in ("y", "yes"):
rv = True
elif value in ("n", "no"):
@@ -581,13 +583,13 @@ def style(
try:
bits.append(f"\033[{_interpret_color(fg)}m")
except KeyError:
raise TypeError(f"Unknown color {fg!r}")
raise TypeError(f"Unknown color {fg!r}") from None
if bg:
try:
bits.append(f"\033[{_interpret_color(bg, 10)}m")
except KeyError:
raise TypeError(f"Unknown color {bg!r}")
raise TypeError(f"Unknown color {bg!r}") from None
if bold is not None:
bits.append(f"\033[{1 if bold else 22}m")
@@ -596,9 +598,9 @@ def style(
if underline is not None:
bits.append(f"\033[{4 if underline else 24}m")
if overline is not None:
bits.append(f"\033[{53 if underline else 55}m")
bits.append(f"\033[{53 if overline else 55}m")
if italic is not None:
bits.append(f"\033[{5 if underline else 23}m")
bits.append(f"\033[{3 if italic else 23}m")
if blink is not None:
bits.append(f"\033[{5 if blink else 25}m")
if reverse is not None:
+6 -6
View File
@@ -836,11 +836,11 @@ class Path(ParamType):
if not is_dash:
if self.resolve_path:
# realpath on Windows Python < 3.8 doesn't resolve symlinks
if os.path.islink(rv):
rv = os.readlink(rv)
# os.path.realpath doesn't resolve symlinks on Windows
# until Python 3.8. Use pathlib for now.
import pathlib
rv = os.path.realpath(rv)
rv = os.fsdecode(pathlib.Path(rv).resolve())
try:
st = os.stat(rv)
@@ -871,7 +871,7 @@ class Path(ParamType):
param,
ctx,
)
if self.writable and not os.access(value, os.W_OK):
if self.writable and not os.access(rv, os.W_OK):
self.fail(
_("{name} {filename!r} is not writable.").format(
name=self.name.title(), filename=os.fsdecode(value)
@@ -879,7 +879,7 @@ class Path(ParamType):
param,
ctx,
)
if self.readable and not os.access(value, os.R_OK):
if self.readable and not os.access(rv, os.R_OK):
self.fail(
_("{name} {filename!r} is not readable.").format(
name=self.name.title(), filename=os.fsdecode(value)
+1 -1
View File
@@ -154,7 +154,7 @@ class LazyFile:
except OSError as e: # noqa: E402
from .exceptions import FileError
raise FileError(self.name, hint=e.strerror)
raise FileError(self.name, hint=e.strerror) from e
self._f = rv
return rv
+1 -1
View File
@@ -6,7 +6,7 @@ certifi==2021.5.30
chardet==4.0.0
charset-normalizer==2.0.3
click-didyoumean==0.0.3
click==8.0.1
click==8.0.3
colorama==0.4.4
distlib==0.3.2
docopt==0.6.2