summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/tests.yaml1
-rw-r--r--.gitignore1
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--CHANGES.rst19
-rw-r--r--docs/.DS_Storebin8196 -> 0 bytes
-rw-r--r--docs/api.rst2
-rw-r--r--docs/options.rst21
-rw-r--r--examples/README2
-rw-r--r--setup.cfg5
-rw-r--r--src/click/__init__.py4
-rw-r--r--src/click/core.py79
-rw-r--r--src/click/termui.py20
-rw-r--r--src/click/utils.py19
-rw-r--r--tests/test_formatting.py3
-rw-r--r--tests/test_options.py31
-rw-r--r--tests/test_shell_completion.py14
-rw-r--r--tox.ini2
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:
diff --git a/.gitignore b/.gitignore
index fc5a65f..c1a1723 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
deleted file mode 100644
index 5a91862..0000000
--- a/docs/.DS_Store
+++ /dev/null
Binary files differ
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/
diff --git a/setup.cfg b/setup.cfg
index 06474f8..848fcdc 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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",
diff --git a/tox.ini b/tox.ini
index d1e4140..056ca0d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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