diff options
-rw-r--r-- | .github/workflows/tests.yaml | 1 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .pre-commit-config.yaml | 2 | ||||
-rw-r--r-- | CHANGES.rst | 19 | ||||
-rw-r--r-- | docs/.DS_Store | bin | 8196 -> 0 bytes | |||
-rw-r--r-- | docs/api.rst | 2 | ||||
-rw-r--r-- | docs/options.rst | 21 | ||||
-rw-r--r-- | examples/README | 2 | ||||
-rw-r--r-- | setup.cfg | 5 | ||||
-rw-r--r-- | src/click/__init__.py | 4 | ||||
-rw-r--r-- | src/click/core.py | 79 | ||||
-rw-r--r-- | src/click/termui.py | 20 | ||||
-rw-r--r-- | src/click/utils.py | 19 | ||||
-rw-r--r-- | tests/test_formatting.py | 3 | ||||
-rw-r--r-- | tests/test_options.py | 31 | ||||
-rw-r--r-- | tests/test_shell_completion.py | 14 | ||||
-rw-r--r-- | tox.ini | 2 |
17 files changed, 96 insertions, 129 deletions
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4e48dd9..e6ef91f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,7 +31,6 @@ jobs: - {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39} - {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38} - {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37} - - {name: '3.6', python: '3.6', os: ubuntu-latest, tox: py36} - {name: 'PyPy', python: 'pypy-3.7', os: ubuntu-latest, tox: pypy37} - {name: Typing, python: '3.10', os: ubuntu-latest, tox: typing} steps: @@ -1,5 +1,6 @@ /.idea/ /.vscode/ +.DS_Store/ /env/ /venv/ __pycache__/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eb55351..5cc04f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: rev: v2.29.1 hooks: - id: pyupgrade - args: ["--py36-plus"] + args: ["--py37-plus"] - repo: https://github.com/asottile/reorder_python_imports rev: v2.6.0 hooks: diff --git a/CHANGES.rst b/CHANGES.rst index f46d446..43f1f51 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,5 +1,24 @@ .. currentmodule:: click +Version 8.1.0 +------------- + +Unreleased + +- Drop support for Python 3.6. :pr:`2129` +- Remove previously deprecated code. :pr:`2130` + + - ``Group.resultcallback`` is renamed to ``result_callback``. + - ``autocompletion`` parameter to ``Command`` is renamed to + ``shell_complete``. + - ``get_terminal_size`` is removed, use + ``shutil.get_terminal_size`` instead. + - ``get_os_args`` is removed, use ``sys.argv[1:]`` instead. + +- Single options boolean flags with ``show_default=True`` only show + the default if it is ``True``. :issue:`1971` + + Version 8.0.4 ------------- diff --git a/docs/.DS_Store b/docs/.DS_Store Binary files differdeleted file mode 100644 index 5a91862..0000000 --- a/docs/.DS_Store +++ /dev/null diff --git a/docs/api.rst b/docs/api.rst index 5133085..09efd03 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -63,8 +63,6 @@ Utilities .. autofunction:: pause -.. autofunction:: get_terminal_size - .. autofunction:: get_binary_stream .. autofunction:: get_text_stream diff --git a/docs/options.rst b/docs/options.rst index 277a98b..b54fbba 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -109,6 +109,27 @@ To show the default values when showing command help, use ``show_default=True`` invoke(dots, args=['--help']) +For single option boolean flags, the default remains hidden if the default +value is False. + +.. click:example:: + + @click.command() + @click.option('--n', default=1, show_default=True) + @click.option("--gr", is_flag=True, show_default=True, default=False, help="Greet the world.") + @click.option("--br", is_flag=True, show_default=True, default=True, help="Add a thematic break") + def dots(n, gr, br): + if gr: + click.echo('Hello world!') + click.echo('.' * n) + if br: + click.echo('-' * n) + +.. click:run:: + + invoke(dots, args=['--help']) + + Multi Value Options ------------------- diff --git a/examples/README b/examples/README index 6be3296..566153f 100644 --- a/examples/README +++ b/examples/README @@ -9,4 +9,4 @@ Click Examples through the wrong interpreter. For more information about this see the documentation: - https://click.palletsprojects.com/en/7.x/setuptools/ + https://click.palletsprojects.com/setuptools/ @@ -30,7 +30,7 @@ classifiers = packages = find: package_dir = = src include_package_data = true -python_requires = >= 3.6 +python_requires = >= 3.7 # Dependencies are in setup.py for GitHub's dependency graph. [options.packages.find] @@ -69,6 +69,7 @@ ignore = E722 # bin op line break, invalid W503 + # up to 88 allowed by bugbear B950 max-line-length = 80 per-file-ignores = @@ -77,7 +78,7 @@ per-file-ignores = [mypy] files = src/click -python_version = 3.6 +python_version = 3.7 show_error_codes = True disallow_subclassing_any = True disallow_untyped_calls = True diff --git a/src/click/__init__.py b/src/click/__init__.py index a2ed5d1..33080c0 100644 --- a/src/click/__init__.py +++ b/src/click/__init__.py @@ -41,7 +41,6 @@ from .termui import clear as clear from .termui import confirm as confirm from .termui import echo_via_pager as echo_via_pager from .termui import edit as edit -from .termui import get_terminal_size as get_terminal_size from .termui import getchar as getchar from .termui import launch as launch from .termui import pause as pause @@ -68,8 +67,7 @@ from .utils import echo as echo from .utils import format_filename as format_filename from .utils import get_app_dir as get_app_dir from .utils import get_binary_stream as get_binary_stream -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.3" +__version__ = "8.1.0.dev0" diff --git a/src/click/core.py b/src/click/core.py index c969e2b..96c6377 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -1567,17 +1567,6 @@ class MultiCommand(Command): return decorator - def resultcallback(self, replace: bool = False) -> t.Callable[[F], F]: - import warnings - - warnings.warn( - "'resultcallback' has been renamed to 'result_callback'." - " The old name will be removed in Click 8.1.", - DeprecationWarning, - stacklevel=2, - ) - return self.result_callback(replace=replace) - def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: """Extra format methods for multi methods that adds all the commands after the options. @@ -2019,11 +2008,6 @@ class Parameter: t.Union[t.List["CompletionItem"], t.List[str]], ] ] = None, - autocompletion: t.Optional[ - t.Callable[ - [Context, t.List[str], str], t.List[t.Union[t.Tuple[str, str], str]] - ] - ] = None, ) -> None: self.name, self.opts, self.secondary_opts = self._parse_decls( param_decls or (), expose_value @@ -2047,36 +2031,6 @@ class Parameter: self.is_eager = is_eager self.metavar = metavar self.envvar = envvar - - if autocompletion is not None: - import warnings - - warnings.warn( - "'autocompletion' is renamed to 'shell_complete'. The old name is" - " deprecated and will be removed in Click 8.1. See the docs about" - " 'Parameter' for information about new behavior.", - DeprecationWarning, - stacklevel=2, - ) - - def shell_complete( - ctx: Context, param: "Parameter", incomplete: str - ) -> t.List["CompletionItem"]: - from click.shell_completion import CompletionItem - - out = [] - - for c in autocompletion(ctx, [], incomplete): # type: ignore - if isinstance(c, tuple): - c = CompletionItem(c[0], help=c[1]) - elif isinstance(c, str): - c = CompletionItem(c) - - if c.value.startswith(incomplete): - out.append(c) - - return out - self._custom_shell_complete = shell_complete if __debug__: @@ -2398,25 +2352,26 @@ class Option(Parameter): All other parameters are passed onwards to the parameter constructor. - :param show_default: controls if the default value should be shown on the - help page. Normally, defaults are not shown. If this - value is a string, it shows the string instead of the - value. This is particularly useful for dynamic options. - :param show_envvar: controls if an environment variable should be shown on - the help page. Normally, environment variables - are not shown. - :param prompt: if set to `True` or a non empty string then the user will be - prompted for input. If set to `True` the prompt will be the - option name capitalized. + :param show_default: Controls if the default value should be shown + on the help page. Normally, defaults are not shown. If this + value is a string, it shows that string in parentheses instead + of the actual value. This is particularly useful for dynamic + options. For single option boolean flags, the default remains + hidden if its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment ariables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. :param confirmation_prompt: Prompt a second time to confirm the value if it was prompted for. Can be set to a string instead of ``True`` to customize the message. :param prompt_required: If set to ``False``, the user will be prompted for input only when the option was specified as a flag without a value. - :param hide_input: if this is `True` then the input on the prompt will be - hidden from the user. This is useful for password - input. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. :param is_flag: forces this option to act as a flag. The default is auto detection. :param flag_value: which value should be used for this flag if it's @@ -2434,6 +2389,10 @@ class Option(Parameter): :param help: the help string. :param hidden: hide this option from help outputs. + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + .. versionchanged:: 8.0.1 ``type`` is detected from ``flag_value`` if given. """ @@ -2727,6 +2686,8 @@ class Option(Parameter): default_string = split_opt( (self.opts if self.default else self.secondary_opts)[0] )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" else: default_string = str(default_value) diff --git a/src/click/termui.py b/src/click/termui.py index e21be0a..2a37785 100644 --- a/src/click/termui.py +++ b/src/click/termui.py @@ -249,26 +249,6 @@ def confirm( return rv -def get_terminal_size() -> os.terminal_size: - """Returns the current size of the terminal as tuple in the form - ``(width, height)`` in columns and rows. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Use - :func:`shutil.get_terminal_size` instead. - """ - import shutil - import warnings - - warnings.warn( - "'click.get_terminal_size()' is deprecated and will be removed" - " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", - DeprecationWarning, - stacklevel=2, - ) - return shutil.get_terminal_size() - - def echo_via_pager( text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], color: t.Optional[bool] = None, diff --git a/src/click/utils.py b/src/click/utils.py index 051cf70..03fbaa7 100644 --- a/src/click/utils.py +++ b/src/click/utils.py @@ -379,25 +379,6 @@ def open_file( return f -def get_os_args() -> t.Sequence[str]: - """Returns the argument part of ``sys.argv``, removing the first - value which is the name of the script. - - .. deprecated:: 8.0 - Will be removed in Click 8.1. Access ``sys.argv[1:]`` directly - instead. - """ - import warnings - - warnings.warn( - "'get_os_args' is deprecated and will be removed in Click 8.1." - " Access 'sys.argv[1:]' directly instead.", - DeprecationWarning, - stacklevel=2, - ) - return sys.argv[1:] - - def format_filename( filename: t.Union[str, bytes, os.PathLike], shorten: bool = False ) -> str: diff --git a/tests/test_formatting.py b/tests/test_formatting.py index f957e01..1cbf32b 100644 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -322,12 +322,13 @@ def test_global_show_default(runner): pass result = runner.invoke(cli, ["--help"]) + # the default to "--help" is not shown because it is False assert result.output.splitlines() == [ "Usage: cli [OPTIONS]", "", "Options:", " -f TEXT Output file name [default: out.txt]", - " --help Show this message and exit. [default: False]", + " --help Show this message and exit.", ] diff --git a/tests/test_options.py b/tests/test_options.py index 2e34337..739da4e 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -723,16 +723,37 @@ def test_show_default_boolean_flag_name(runner, default, expect): assert f"[default: {expect}]" in message -def test_show_default_boolean_flag_value(runner): - """When a boolean flag only has one opt, it will show the default - value, not the opt name. +def test_show_true_default_boolean_flag_value(runner): + """When a boolean flag only has one opt and its default is True, + it will show the default value, not the opt name. """ opt = click.Option( - ("--cache",), is_flag=True, show_default=True, help="Enable the cache." + ("--cache",), + is_flag=True, + show_default=True, + default=True, + help="Enable the cache.", + ) + ctx = click.Context(click.Command("test")) + message = opt.get_help_record(ctx)[1] + assert "[default: True]" in message + + +@pytest.mark.parametrize("default", [False, None]) +def test_hide_false_default_boolean_flag_value(runner, default): + """When a boolean flag only has one opt and its default is False or + None, it will not show the default + """ + opt = click.Option( + ("--cache",), + is_flag=True, + show_default=True, + default=default, + help="Enable the cache.", ) ctx = click.Context(click.Command("test")) message = opt.get_help_record(ctx)[1] - assert "[default: False]" in message + assert "[default: " not in message def test_show_default_string(runner): diff --git a/tests/test_shell_completion.py b/tests/test_shell_completion.py index 8338d0e..08fa057 100644 --- a/tests/test_shell_completion.py +++ b/tests/test_shell_completion.py @@ -161,20 +161,6 @@ def test_option_custom(): assert _get_words(cli, ["a", "b"], "c") == ["C"] -def test_autocompletion_deprecated(): - # old function takes args and not param, returns all values, can mix - # strings and tuples - def custom(ctx, args, incomplete): - assert isinstance(args, list) - return [("art", "x"), "bat", "cat"] - - with pytest.deprecated_call(): - cli = Command("cli", params=[Argument(["x"], autocompletion=custom)]) - - assert _get_words(cli, [], "") == ["art", "bat", "cat"] - assert _get_words(cli, [], "c") == ["cat"] - - def test_option_multiple(): cli = Command( "type", @@ -1,6 +1,6 @@ [tox] envlist = - py3{11,10,9,8,7,6},pypy37 + py3{11,10,9,8,7},pypy3{8,7} style typing docs |