New upstream version 8.0.3

This commit is contained in:
Sandro Tosi 2022-01-02 20:50:02 -05:00
parent 46bc5bd117
commit 4555a76448
9 changed files with 70 additions and 74 deletions

View file

@ -1,5 +1,18 @@
.. currentmodule:: click
Version 8.0.3
-------------
Released 2021-10-10
- Fix issue with ``Path(resolve_path=True)`` type creating invalid
paths. :issue:`2088`
- Importing ``readline`` does not cause the ``confirm()`` prompt to
disappear when pressing backspace. :issue:`2092`
- Any default values injected by ``invoke()`` are cast to the
corresponding parameter's type. :issue:`2089, 2090`
Version 8.0.2
-------------

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.2"
__version__ = "8.0.3"

View file

@ -739,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.

View file

@ -231,8 +231,10 @@ 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() from None
if value in ("y", "yes"):

View file

@ -836,20 +836,11 @@ class Path(ParamType):
if not is_dash:
if self.resolve_path:
# Get the absolute directory containing the path.
dir_ = os.path.dirname(os.path.abspath(rv))
# os.path.realpath doesn't resolve symlinks on Windows
# until Python 3.8. Use pathlib for now.
import pathlib
# Resolve a symlink. realpath on Windows Python < 3.9
# doesn't resolve symlinks. This might return a relative
# path even if the path to the link is absolute.
if os.path.islink(rv):
rv = os.readlink(rv)
# Join dir_ with the resolved symlink if the resolved
# path is relative. This will make it relative to the
# original containing directory.
if not os.path.isabs(rv):
rv = os.path.join(dir_, rv)
rv = os.fsdecode(pathlib.Path(rv).resolve())
try:
st = os.stat(rv)

View file

@ -1,5 +1,4 @@
import os
import shutil
import tempfile
import pytest
@ -12,20 +11,17 @@ def runner(request):
return CliRunner()
def check_symlink_impl():
"""This function checks if using symlinks is allowed
on the host machine"""
tempdir = tempfile.mkdtemp(prefix="click-")
test_pth = os.path.join(tempdir, "check_sym_impl")
sym_pth = os.path.join(tempdir, "link")
open(test_pth, "w").close()
rv = True
try:
os.symlink(test_pth, sym_pth)
except (NotImplementedError, OSError):
# Creating symlinks on Windows require elevated access.
# OSError is thrown if the function is called without it.
rv = False
finally:
shutil.rmtree(tempdir, ignore_errors=True)
return rv
def _check_symlinks_supported():
with tempfile.TemporaryDirectory(prefix="click-pytest-") as tempdir:
target = os.path.join(tempdir, "target")
open(target, "w").close()
link = os.path.join(tempdir, "link")
try:
os.symlink(target, link)
return True
except OSError:
return False
symlinks_supported = _check_symlinks_supported()

View file

@ -246,15 +246,17 @@ def test_other_command_invoke_with_defaults(runner):
return ctx.invoke(other_cmd)
@click.command()
@click.option("--foo", type=click.INT, default=42)
@click.option("-a", type=click.INT, default=42)
@click.option("-b", type=click.INT, default="15")
@click.option("-c", multiple=True)
@click.pass_context
def other_cmd(ctx, foo):
assert ctx.info_name == "other-cmd"
click.echo(foo)
def other_cmd(ctx, a, b, c):
return ctx.info_name, a, b, c
result = runner.invoke(cli, [])
assert not result.exception
assert result.output == "42\n"
result = runner.invoke(cli, standalone_mode=False)
# invoke should type cast default values, str becomes int, empty
# multiple should be empty tuple instead of None
assert result.return_value == ("other-cmd", 42, 15, ())
def test_invoked_subcommand(runner):

View file

@ -2,7 +2,7 @@ import os.path
import pathlib
import pytest
from conftest import check_symlink_impl
from conftest import symlinks_supported
import click
@ -104,37 +104,27 @@ def test_path_type(runner, cls, expect):
assert result.return_value == expect
@pytest.mark.skipif(not check_symlink_impl(), reason="symlink not allowed on device")
@pytest.mark.parametrize(
("sym_file", "abs_fun"),
[
(("relative_symlink",), os.path.basename),
(("test", "absolute_symlink"), lambda x: x),
],
@pytest.mark.skipif(
not symlinks_supported, reason="The current OS or FS doesn't support symlinks."
)
def test_symlink_resolution(tmpdir, sym_file, abs_fun):
"""This test ensures symlinks are properly resolved by click"""
tempdir = str(tmpdir)
real_path = os.path.join(tempdir, "test_file")
sym_path = os.path.join(tempdir, *sym_file)
def test_path_resolve_symlink(tmp_path, runner):
test_file = tmp_path / "file"
test_file_str = os.fsdecode(test_file)
test_file.write_text("")
# create dirs and files
os.makedirs(os.path.join(tempdir, "test"), exist_ok=True)
open(real_path, "w").close()
os.symlink(abs_fun(real_path), sym_path)
path_type = click.Path(resolve_path=True)
param = click.Argument(["a"], type=path_type)
ctx = click.Context(click.Command("cli", params=[param]))
# test
ctx = click.Context(click.Command("do_stuff"))
rv = click.Path(resolve_path=True).convert(sym_path, None, ctx)
test_dir = tmp_path / "dir"
test_dir.mkdir()
# os.readlink prepends path prefixes to absolute
# links in windows.
# https://docs.microsoft.com/en-us/windows/win32/
# ... fileio/naming-a-file#win32-file-namespaces
#
# Here we strip win32 path prefix from the resolved path
rv_drive, rv_path = os.path.splitdrive(rv)
stripped_rv_drive = rv_drive.split(os.path.sep)[-1]
rv = os.path.join(stripped_rv_drive, rv_path)
abs_link = test_dir / "abs"
abs_link.symlink_to(test_file)
abs_rv = path_type.convert(os.fsdecode(abs_link), param, ctx)
assert abs_rv == test_file_str
assert rv == real_path
rel_link = test_dir / "rel"
rel_link.symlink_to(pathlib.Path("..") / "file")
rel_rv = path_type.convert(os.fsdecode(rel_link), param, ctx)
assert rel_rv == test_file_str

View file

@ -275,8 +275,8 @@ def test_echo_writing_to_standard_error(capfd, monkeypatch):
emulate_input("y\n")
click.confirm("Prompt to stderr", err=True)
out, err = capfd.readouterr()
assert out == ""
assert err == "Prompt to stderr [y/N]: "
assert out == " "
assert err == "Prompt to stderr [y/N]:"
monkeypatch.setattr(click.termui, "isatty", lambda x: True)
monkeypatch.setattr(click.termui, "getchar", lambda: " ")