Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-click for openSUSE:Factory checked in at 2021-10-20 20:23:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-click (Old) and /work/SRC/openSUSE:Factory/.python-click.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-click" Wed Oct 20 20:23:32 2021 rev:15 rq:925757 version:8.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-click/python-click.changes 2021-09-03 21:26:48.870216970 +0200 +++ /work/SRC/openSUSE:Factory/.python-click.new.1890/python-click.changes 2021-10-20 20:24:19.085379327 +0200 @@ -1,0 +2,28 @@ +Sat Oct 16 21:18:48 UTC 2021 - Dirk M??ller <dmuel...@suse.com> + +- update to 8.0.3: + * 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` + * ``is_bool_flag`` is not set to ``True`` if ``is_flag`` is ``False``. + * Bash version detection is locale independent. :issue:`1940` + * Empty ``default`` value is not shown for ``multiple=True``. + * Fix shell completion for arguments that start with a forward slash + such as absolute file paths. :issue:`1929` + * ``Path`` type with ``resolve_path=True`` resolves relative symlinks + to be relative to the containing directory. :issue:`1921` + * Completion does not skip Python's resource cleanup when exiting, + avoiding some unexpected warning output. :issue:`1738, 2017` + * Fix type annotation for ``type`` argument in ``prompt`` function. + * Fix overline and italic styles, which were incorrectly added when + adding underline. :pr:`2058` + * An option with ``count=True`` will not show "[x>=0]" in help text. + * Default values are not cast to the parameter type twice during + processing. + * Options with ``multiple`` and ``flag_value`` use the flag value + instead of leaving an internal placeholder. + +------------------------------------------------------------------- Old: ---- click-8.0.1.tar.gz New: ---- click-8.0.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-click.spec ++++++ --- /var/tmp/diff_new_pack.a2xWce/_old 2021-10-20 20:24:19.505379586 +0200 +++ /var/tmp/diff_new_pack.a2xWce/_new 2021-10-20 20:24:19.505379586 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-click # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-click -Version: 8.0.1 +Version: 8.0.3 Release: 0 Summary: A wrapper around optparse for command line utilities License: BSD-3-Clause ++++++ click-8.0.1.tar.gz -> click-8.0.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/CHANGES.rst new/click-8.0.3/CHANGES.rst --- old/click-8.0.1/CHANGES.rst 2021-05-19 22:59:55.000000000 +0200 +++ new/click-8.0.3/CHANGES.rst 2021-10-10 20:06:49.000000000 +0200 @@ -1,5 +1,46 @@ .. 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 +------------- + +Released 2021-10-08 + +- ``is_bool_flag`` is not set to ``True`` if ``is_flag`` is ``False``. + :issue:`1925` +- Bash version detection is locale independent. :issue:`1940` +- Empty ``default`` value is not shown for ``multiple=True``. + :issue:`1969` +- Fix shell completion for arguments that start with a forward slash + such as absolute file paths. :issue:`1929` +- ``Path`` type with ``resolve_path=True`` resolves relative symlinks + to be relative to the containing directory. :issue:`1921` +- Completion does not skip Python's resource cleanup when exiting, + avoiding some unexpected warning output. :issue:`1738, 2017` +- Fix type annotation for ``type`` argument in ``prompt`` function. + :issue:`2062` +- Fix overline and italic styles, which were incorrectly added when + adding underline. :pr:`2058` +- An option with ``count=True`` will not show "[x>=0]" in help text. + :issue:`2072` +- Default values are not cast to the parameter type twice during + processing. :issue:`2085` +- Options with ``multiple`` and ``flag_value`` use the flag value + instead of leaving an internal placeholder. :issue:`2001` + + Version 8.0.1 ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/PKG-INFO new/click-8.0.3/PKG-INFO --- old/click-8.0.1/PKG-INFO 2021-05-19 23:00:16.507458400 +0200 +++ new/click-8.0.3/PKG-INFO 2021-10-10 20:07:14.952687500 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: click -Version: 8.0.1 +Version: 8.0.3 Summary: Composable command line interface toolkit Home-page: https://palletsprojects.com/p/click/ Author: Armin Ronacher @@ -15,87 +15,6 @@ Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ Project-URL: Twitter, https://twitter.com/PalletsTeam Project-URL: Chat, https://discord.gg/pallets -Description: \$ click\_ - ========== - - Click is a Python package for creating beautiful command line interfaces - in a composable way with as little code as necessary. It's the "Command - Line Interface Creation Kit". It's highly configurable but comes with - sensible defaults out of the box. - - It aims to make the process of writing command line tools quick and fun - while also preventing any frustration caused by the inability to - implement an intended CLI API. - - Click in three points: - - - Arbitrary nesting of commands - - Automatic help page generation - - Supports lazy loading of subcommands at runtime - - - Installing - ---------- - - Install and update using `pip`_: - - .. code-block:: text - - $ pip install -U click - - .. _pip: https://pip.pypa.io/en/stable/quickstart/ - - - A Simple Example - ---------------- - - .. code-block:: python - - import click - - @click.command() - @click.option("--count", default=1, help="Number of greetings.") - @click.option("--name", prompt="Your name", help="The person to greet.") - def hello(count, name): - """Simple program that greets NAME for a total of COUNT times.""" - for _ in range(count): - click.echo(f"Hello, {name}!") - - if __name__ == '__main__': - hello() - - .. code-block:: text - - $ python hello.py --count=3 - Your name: Click - Hello, Click! - Hello, Click! - Hello, Click! - - - Donate - ------ - - The Pallets organization develops and supports Click and other popular - packages. In order to grow the community of contributors and users, and - allow the maintainers to devote more time to the projects, `please - donate today`_. - - .. _please donate today: https://palletsprojects.com/donate - - - Links - ----- - - - Documentation: https://click.palletsprojects.com/ - - Changes: https://click.palletsprojects.com/changes/ - - PyPI Releases: https://pypi.org/project/click/ - - Source Code: https://github.com/pallets/click - - Issue Tracker: https://github.com/pallets/click/issues - - Website: https://palletsprojects.com/p/click - - Twitter: https://twitter.com/PalletsTeam - - Chat: https://discord.gg/pallets - Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers @@ -104,3 +23,87 @@ Classifier: Programming Language :: Python Requires-Python: >=3.6 Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Website: https://palletsprojects.com/p/click +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/README.rst new/click-8.0.3/README.rst --- old/click-8.0.1/README.rst 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/README.rst 2021-10-08 22:28:04.000000000 +0200 @@ -26,7 +26,7 @@ $ pip install -U click -.. _pip: https://pip.pypa.io/en/stable/quickstart/ +.. _pip: https://pip.pypa.io/en/stable/getting-started/ A Simple Example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/docs/api.rst new/click-8.0.3/docs/api.rst --- old/click-8.0.1/docs/api.rst 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/docs/api.rst 2021-10-08 18:57:05.000000000 +0200 @@ -141,6 +141,8 @@ .. autoclass:: FloatRange +.. autoclass:: DateTime + .. autoclass:: Tuple .. autoclass:: ParamType diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/docs/conf.py new/click-8.0.3/docs/conf.py --- old/click-8.0.1/docs/conf.py 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/docs/conf.py 2021-10-08 22:28:04.000000000 +0200 @@ -38,16 +38,16 @@ ProjectLink("PyPI Releases", "https://pypi.org/project/click/"), ProjectLink("Source Code", "https://github.com/pallets/click/"), ProjectLink("Issue Tracker", "https://github.com/pallets/click/issues/"), - ProjectLink("Website", "https://palletsprojects.com/"), + ProjectLink("Website", "https://palletsprojects.com/p/click"), ProjectLink("Twitter", "https://twitter.com/PalletsTeam"), ProjectLink("Chat", "https://discord.gg/pallets"), ] } html_sidebars = { - "index": ["project.html", "localtoc.html", "searchbox.html"], - "**": ["localtoc.html", "relations.html", "searchbox.html"], + "index": ["project.html", "localtoc.html", "searchbox.html", "ethicalads.html"], + "**": ["localtoc.html", "relations.html", "searchbox.html", "ethicalads.html"], } -singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]} +singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]} html_static_path = ["_static"] html_favicon = "_static/click-icon.png" html_logo = "_static/click-logo-sidebar.png" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/docs/utils.rst new/click-8.0.3/docs/utils.rst --- old/click-8.0.1/docs/utils.rst 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/docs/utils.rst 2021-10-08 18:57:05.000000000 +0200 @@ -339,13 +339,18 @@ Showing Progress Bars --------------------- -.. versionadded:: 2.0 - Sometimes, you have command line scripts that need to process a lot of data, but you want to quickly show the user some progress about how long that will take. Click supports simple progress bar rendering for that through the :func:`progressbar` function. +.. note:: + + If you find that you have requirements beyond what Click's progress + bar supports, try using `tqdm`_. + + .. _tqdm: https://tqdm.github.io/ + The basic usage is very simple: the idea is that you have an iterable that you want to operate on. For each item in the iterable it might take some time to do processing. So say you have a loop like this:: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/examples/completion/README new/click-8.0.3/examples/completion/README --- old/click-8.0.1/examples/completion/README 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/examples/completion/README 2021-10-08 18:57:05.000000000 +0200 @@ -11,18 +11,18 @@ .. code-block:: bash - eval "$(_COMPLETION_COMPLETE=source_bash completion)" + eval "$(_COMPLETION_COMPLETE=bash_source completion)" For Zsh: .. code-block:: zsh - eval "$(_COMPLETION_COMPLETE=source_zsh completion)" + eval "$(_COMPLETION_COMPLETE=zsh_source completion)" For Fish: .. code-block:: fish - eval (env _COMPLETION_COMPLETE=source_fish completion) + eval (env _COMPLETION_COMPLETE=fish_source completion) Now press tab (maybe twice) after typing something to see completions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/examples/completion/completion.py new/click-8.0.3/examples/completion/completion.py --- old/click-8.0.1/examples/completion/completion.py 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/examples/completion/completion.py 2021-10-08 18:57:05.000000000 +0200 @@ -38,10 +38,13 @@ # of CompletionItem. You can match on whatever you want, including # the help. items = [("bob", "butcher"), ("alice", "baker"), ("jerry", "candlestick maker")] + out = [] for value, help in items: if incomplete in value or incomplete in help: - yield CompletionItem(value, help=help) + out.append(CompletionItem(value, help=help)) + + return out @group.command(help="Choose a user") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/requirements/dev.txt new/click-8.0.3/requirements/dev.txt --- old/click-8.0.1/requirements/dev.txt 2021-05-19 03:42:48.000000000 +0200 +++ new/click-8.0.3/requirements/dev.txt 2021-10-08 22:28:04.000000000 +0200 @@ -6,81 +6,85 @@ # alabaster==0.7.12 # via sphinx -appdirs==1.4.4 - # via virtualenv attrs==21.2.0 # via pytest babel==2.9.1 # via sphinx -certifi==2020.12.5 +backports.entry-points-selectable==1.1.0 + # via virtualenv +certifi==2021.5.30 # via requests -cfgv==3.2.0 +cfgv==3.3.1 # via pre-commit -chardet==4.0.0 +charset-normalizer==2.0.6 # via requests -click==7.1.2 +click==8.0.1 # via pip-tools -distlib==0.3.1 +distlib==0.3.3 # via virtualenv docutils==0.16 - # via sphinx -filelock==3.0.12 + # via + # sphinx + # sphinx-tabs +filelock==3.3.0 # via # tox # virtualenv -identify==2.2.4 +identify==2.3.0 # via pre-commit -idna==2.10 +idna==3.2 # via requests imagesize==1.2.0 # via sphinx iniconfig==1.1.1 # via pytest -jinja2==2.11.3 +jinja2==3.0.2 # via sphinx -markupsafe==2.0.0 +markupsafe==2.0.1 # via jinja2 mypy-extensions==0.4.3 # via mypy -mypy==0.812 +mypy==0.910 # via -r requirements/typing.in nodeenv==1.6.0 # via pre-commit -packaging==20.9 +packaging==21.0 # via # pallets-sphinx-themes # pytest # sphinx # tox -pallets-sphinx-themes==2.0.0 +pallets-sphinx-themes==2.0.1 # via -r requirements/docs.in -pep517==0.10.0 +pep517==0.11.0 # via pip-tools -pip-tools==6.1.0 +pip-tools==6.3.0 # via -r requirements/dev.in -pluggy==0.13.1 +platformdirs==2.4.0 + # via virtualenv +pluggy==1.0.0 # via # pytest # tox -pre-commit==2.12.1 +pre-commit==2.15.0 # via -r requirements/dev.in py==1.10.0 # via # pytest # tox -pygments==2.9.0 +pygments==2.10.0 # via # sphinx # sphinx-tabs pyparsing==2.4.7 # via packaging -pytest==6.2.4 +pytest==6.2.5 # via -r requirements/tests.in -pytz==2021.1 +pytz==2021.3 # via babel pyyaml==5.4.1 # via pre-commit -requests==2.25.1 +requests==2.26.0 # via sphinx six==1.16.0 # via @@ -90,9 +94,9 @@ # via sphinx sphinx-issues==1.2.0 # via -r requirements/docs.in -sphinx-tabs==2.1.0 +sphinx-tabs==3.2.0 # via -r requirements/docs.in -sphinx==3.5.4 +sphinx==4.2.0 # via # -r requirements/docs.in # pallets-sphinx-themes @@ -103,7 +107,7 @@ # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-htmlhelp==2.0.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx @@ -111,26 +115,28 @@ # via -r requirements/docs.in sphinxcontrib-qthelp==1.0.3 # via sphinx -sphinxcontrib-serializinghtml==1.1.4 +sphinxcontrib-serializinghtml==1.1.5 # via sphinx toml==0.10.2 # via - # pep517 + # mypy # pre-commit # pytest # tox -tox==3.23.1 +tomli==1.2.1 + # via pep517 +tox==3.24.4 # via -r requirements/dev.in -typed-ast==1.4.3 +typing-extensions==3.10.0.2 # via mypy -typing-extensions==3.10.0.0 - # via mypy -urllib3==1.26.4 +urllib3==1.26.7 # via requests -virtualenv==20.4.6 +virtualenv==20.8.1 # via # pre-commit # tox +wheel==0.37.0 + # via pip-tools # The following packages are considered to be unsafe in a requirements file: # pip diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/requirements/docs.txt new/click-8.0.3/requirements/docs.txt --- old/click-8.0.1/requirements/docs.txt 2021-05-19 03:42:48.000000000 +0200 +++ new/click-8.0.3/requirements/docs.txt 2021-10-08 22:28:04.000000000 +0200 @@ -8,43 +8,45 @@ # via sphinx babel==2.9.1 # via sphinx -certifi==2020.12.5 +certifi==2021.5.30 # via requests -chardet==4.0.0 +charset-normalizer==2.0.6 # via requests docutils==0.16 - # via sphinx -idna==2.10 + # via + # sphinx + # sphinx-tabs +idna==3.2 # via requests imagesize==1.2.0 # via sphinx -jinja2==2.11.3 +jinja2==3.0.2 # via sphinx -markupsafe==2.0.0 +markupsafe==2.0.1 # via jinja2 -packaging==20.9 +packaging==21.0 # via # pallets-sphinx-themes # sphinx -pallets-sphinx-themes==2.0.0 +pallets-sphinx-themes==2.0.1 # via -r requirements/docs.in -pygments==2.9.0 +pygments==2.10.0 # via # sphinx # sphinx-tabs pyparsing==2.4.7 # via packaging -pytz==2021.1 +pytz==2021.3 # via babel -requests==2.25.1 +requests==2.26.0 # via sphinx snowballstemmer==2.1.0 # via sphinx sphinx-issues==1.2.0 # via -r requirements/docs.in -sphinx-tabs==2.1.0 +sphinx-tabs==3.2.0 # via -r requirements/docs.in -sphinx==3.5.4 +sphinx==4.2.0 # via # -r requirements/docs.in # pallets-sphinx-themes @@ -55,7 +57,7 @@ # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-htmlhelp==2.0.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx @@ -63,9 +65,9 @@ # via -r requirements/docs.in sphinxcontrib-qthelp==1.0.3 # via sphinx -sphinxcontrib-serializinghtml==1.1.4 +sphinxcontrib-serializinghtml==1.1.5 # via sphinx -urllib3==1.26.4 +urllib3==1.26.7 # via requests # The following packages are considered to be unsafe in a requirements file: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/requirements/tests.txt new/click-8.0.3/requirements/tests.txt --- old/click-8.0.1/requirements/tests.txt 2021-05-19 03:42:48.000000000 +0200 +++ new/click-8.0.3/requirements/tests.txt 2021-10-08 22:28:04.000000000 +0200 @@ -8,15 +8,15 @@ # via pytest iniconfig==1.1.1 # via pytest -packaging==20.9 +packaging==21.0 # via pytest -pluggy==0.13.1 +pluggy==1.0.0 # via pytest py==1.10.0 # via pytest pyparsing==2.4.7 # via packaging -pytest==6.2.4 +pytest==6.2.5 # via -r requirements/tests.in toml==0.10.2 # via pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/requirements/typing.txt new/click-8.0.3/requirements/typing.txt --- old/click-8.0.1/requirements/typing.txt 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/requirements/typing.txt 2021-10-08 22:28:04.000000000 +0200 @@ -6,9 +6,9 @@ # mypy-extensions==0.4.3 # via mypy -mypy==0.812 +mypy==0.910 # via -r requirements/typing.in -typed-ast==1.4.3 +toml==0.10.2 # via mypy -typing-extensions==3.10.0.0 +typing-extensions==3.10.0.2 # via mypy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/__init__.py new/click-8.0.3/src/click/__init__.py --- old/click-8.0.1/src/click/__init__.py 2021-05-19 22:59:55.000000000 +0200 +++ new/click-8.0.3/src/click/__init__.py 2021-10-10 20:06:49.000000000 +0200 @@ -72,4 +72,4 @@ 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" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/_termui_impl.py new/click-8.0.3/src/click/_termui_impl.py --- old/click-8.0.1/src/click/_termui_impl.py 2021-05-19 03:42:48.000000000 +0200 +++ new/click-8.0.3/src/click/_termui_impl.py 2021-10-08 22:28:04.000000000 +0200 @@ -426,7 +426,7 @@ """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 @@ try: os.system(f'{cmd} "{filename}"') finally: + os.close(fd) os.unlink(filename) @@ -497,7 +498,7 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/core.py new/click-8.0.3/src/click/core.py --- old/click-8.0.1/src/click/core.py 2021-05-19 22:56:38.000000000 +0200 +++ new/click-8.0.3/src/click/core.py 2021-10-10 20:04:11.000000000 +0200 @@ -46,17 +46,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/decorators.py new/click-8.0.3/src/click/decorators.py --- old/click-8.0.1/src/click/decorators.py 2021-05-19 04:57:30.000000000 +0200 +++ new/click-8.0.3/src/click/decorators.py 2021-10-08 22:28:04.000000000 +0200 @@ -340,9 +340,8 @@ 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 @@ raise RuntimeError( f"{package_name!r} is not installed. Try passing" " 'package_name' instead." - ) + ) from None if version is None: raise RuntimeError( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/globals.py new/click-8.0.3/src/click/globals.py --- old/click-8.0.1/src/click/globals.py 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/src/click/globals.py 2021-10-08 22:28:04.000000000 +0200 @@ -36,9 +36,9 @@ """ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/parser.py new/click-8.0.3/src/click/parser.py --- old/click-8.0.1/src/click/parser.py 2021-05-19 03:49:48.000000000 +0200 +++ new/click-8.0.3/src/click/parser.py 2021-10-08 18:57:05.000000000 +0200 @@ -300,7 +300,7 @@ """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. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/shell_completion.py new/click-8.0.3/src/click/shell_completion.py --- old/click-8.0.1/src/click/shell_completion.py 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/src/click/shell_completion.py 2021-10-08 18:57:05.000000000 +0200 @@ -302,8 +302,10 @@ 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 _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: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/termui.py new/click-8.0.3/src/click/termui.py --- old/click-8.0.1/src/click/termui.py 2021-05-19 03:42:48.000000000 +0200 +++ new/click-8.0.3/src/click/termui.py 2021-10-10 19:48:13.000000000 +0200 @@ -84,7 +84,7 @@ 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 @@ # 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 @@ 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 @@ 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 @@ 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: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/types.py new/click-8.0.3/src/click/types.py --- old/click-8.0.1/src/click/types.py 2021-05-19 16:37:56.000000000 +0200 +++ new/click-8.0.3/src/click/types.py 2021-10-10 19:20:35.000000000 +0200 @@ -836,11 +836,11 @@ 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 @@ 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 @@ 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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click/utils.py new/click-8.0.3/src/click/utils.py --- old/click-8.0.1/src/click/utils.py 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/src/click/utils.py 2021-10-08 22:28:04.000000000 +0200 @@ -154,7 +154,7 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/src/click.egg-info/PKG-INFO new/click-8.0.3/src/click.egg-info/PKG-INFO --- old/click-8.0.1/src/click.egg-info/PKG-INFO 2021-05-19 23:00:16.000000000 +0200 +++ new/click-8.0.3/src/click.egg-info/PKG-INFO 2021-10-10 20:07:14.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: click -Version: 8.0.1 +Version: 8.0.3 Summary: Composable command line interface toolkit Home-page: https://palletsprojects.com/p/click/ Author: Armin Ronacher @@ -15,87 +15,6 @@ Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ Project-URL: Twitter, https://twitter.com/PalletsTeam Project-URL: Chat, https://discord.gg/pallets -Description: \$ click\_ - ========== - - Click is a Python package for creating beautiful command line interfaces - in a composable way with as little code as necessary. It's the "Command - Line Interface Creation Kit". It's highly configurable but comes with - sensible defaults out of the box. - - It aims to make the process of writing command line tools quick and fun - while also preventing any frustration caused by the inability to - implement an intended CLI API. - - Click in three points: - - - Arbitrary nesting of commands - - Automatic help page generation - - Supports lazy loading of subcommands at runtime - - - Installing - ---------- - - Install and update using `pip`_: - - .. code-block:: text - - $ pip install -U click - - .. _pip: https://pip.pypa.io/en/stable/quickstart/ - - - A Simple Example - ---------------- - - .. code-block:: python - - import click - - @click.command() - @click.option("--count", default=1, help="Number of greetings.") - @click.option("--name", prompt="Your name", help="The person to greet.") - def hello(count, name): - """Simple program that greets NAME for a total of COUNT times.""" - for _ in range(count): - click.echo(f"Hello, {name}!") - - if __name__ == '__main__': - hello() - - .. code-block:: text - - $ python hello.py --count=3 - Your name: Click - Hello, Click! - Hello, Click! - Hello, Click! - - - Donate - ------ - - The Pallets organization develops and supports Click and other popular - packages. In order to grow the community of contributors and users, and - allow the maintainers to devote more time to the projects, `please - donate today`_. - - .. _please donate today: https://palletsprojects.com/donate - - - Links - ----- - - - Documentation: https://click.palletsprojects.com/ - - Changes: https://click.palletsprojects.com/changes/ - - PyPI Releases: https://pypi.org/project/click/ - - Source Code: https://github.com/pallets/click - - Issue Tracker: https://github.com/pallets/click/issues - - Website: https://palletsprojects.com/p/click - - Twitter: https://twitter.com/PalletsTeam - - Chat: https://discord.gg/pallets - Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers @@ -104,3 +23,87 @@ Classifier: Programming Language :: Python Requires-Python: >=3.6 Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Website: https://palletsprojects.com/p/click +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/conftest.py new/click-8.0.3/tests/conftest.py --- old/click-8.0.1/tests/conftest.py 2021-03-04 01:26:07.000000000 +0100 +++ new/click-8.0.3/tests/conftest.py 2021-10-10 19:20:35.000000000 +0200 @@ -1,3 +1,6 @@ +import os +import tempfile + import pytest from click.testing import CliRunner @@ -6,3 +9,19 @@ @pytest.fixture(scope="function") def runner(request): return CliRunner() + + +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() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/test_commands.py new/click-8.0.3/tests/test_commands.py --- old/click-8.0.1/tests/test_commands.py 2021-05-19 19:55:25.000000000 +0200 +++ new/click-8.0.3/tests/test_commands.py 2021-10-10 20:04:11.000000000 +0200 @@ -246,15 +246,17 @@ 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): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/test_options.py new/click-8.0.3/tests/test_options.py --- old/click-8.0.1/tests/test_options.py 2021-05-19 20:54:20.000000000 +0200 +++ new/click-8.0.3/tests/test_options.py 2021-10-10 19:20:35.000000000 +0200 @@ -4,6 +4,7 @@ import pytest import click +from click import Option def test_prefixes(runner): @@ -251,7 +252,7 @@ assert isinstance(opt.type, click.Tuple) assert opt.type.types == [click.INT, click.STRING] ctx = click.Context(click.Command("test")) - assert opt.get_default(ctx) == ((1, "a"),) + assert opt.type_cast_value(ctx, opt.get_default(ctx)) == ((1, "a"),) def test_parse_multiple_default_composite_type(runner): @@ -313,13 +314,36 @@ (click.IntRange(max=32), "x<=32"), ], ) -def test_intrange_default_help_text(runner, type, expect): - option = click.Option(["--count"], type=type, show_default=True, default=2) +def test_intrange_default_help_text(type, expect): + option = click.Option(["--num"], type=type, show_default=True, default=2) context = click.Context(click.Command("test")) result = option.get_help_record(context)[1] assert expect in result +def test_count_default_type_help(): + """A count option with the default type should not show >=0 in help.""" + option = click.Option(["--count"], count=True, help="some words") + context = click.Context(click.Command("test")) + result = option.get_help_record(context)[1] + assert result == "some words" + + +def test_file_type_help_default(): + """The default for a File type is a filename string. The string + should be displayed in help, not an open file object. + + Type casting is only applied to defaults in processing, not when + getting the default value. + """ + option = click.Option( + ["--in"], type=click.File(), default=__file__, show_default=True + ) + context = click.Context(click.Command("test")) + result = option.get_help_record(context)[1] + assert __file__ in result + + def test_toupper_envvar_prefix(runner): @click.command() @click.option("--arg") @@ -727,6 +751,16 @@ assert "[default: None]" not in message +def test_do_not_show_default_empty_multiple(): + """When show_default is True and multiple=True is set, it should not + print empty default value in --help output. + """ + opt = click.Option(["-a"], multiple=True, help="values", show_default=True) + ctx = click.Context(click.Command("cli")) + message = opt.get_help_record(ctx)[1] + assert message == "values" + + @pytest.mark.parametrize( ("args", "expect"), [ @@ -758,8 +792,50 @@ assert result.return_value == expect +def test_multiple_option_with_optional_value(runner): + cli = click.Command( + "cli", + params=[ + click.Option(["-f"], is_flag=False, flag_value="flag", multiple=True), + click.Option(["-a"]), + click.Argument(["b"], nargs=-1), + ], + callback=lambda **kwargs: kwargs, + ) + result = runner.invoke( + cli, + ["-f", "-f", "other", "-f", "-a", "1", "a", "b"], + standalone_mode=False, + catch_exceptions=False, + ) + assert result.return_value == { + "f": ("flag", "other", "flag"), + "a": "1", + "b": ("a", "b"), + } + + def test_type_from_flag_value(): param = click.Option(["-a", "x"], default=True, flag_value=4) assert param.type is click.INT param = click.Option(["-b", "x"], flag_value=8) assert param.type is click.INT + + +@pytest.mark.parametrize( + ("option", "expected"), + [ + # Not boolean flags + pytest.param(Option(["-a"], type=int), False, id="int option"), + pytest.param(Option(["-a"], type=bool), False, id="bool non-flag [None]"), + pytest.param(Option(["-a"], default=True), False, id="bool non-flag [True]"), + pytest.param(Option(["-a"], default=False), False, id="bool non-flag [False]"), + pytest.param(Option(["-a"], flag_value=1), False, id="non-bool flag_value"), + # Boolean flags + pytest.param(Option(["-a"], is_flag=True), True, id="is_flag=True"), + pytest.param(Option(["-a/-A"]), True, id="secondary option [implicit flag]"), + pytest.param(Option(["-a"], flag_value=True), True, id="bool flag_value"), + ], +) +def test_is_bool_flag_is_correctly_set(option, expected): + assert option.is_bool_flag is expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/test_shell_completion.py new/click-8.0.3/tests/test_shell_completion.py --- old/click-8.0.1/tests/test_shell_completion.py 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/tests/test_shell_completion.py 2021-10-08 22:28:04.000000000 +0200 @@ -1,5 +1,3 @@ -import sys - import pytest from click.core import Argument @@ -125,6 +123,14 @@ assert c.type == expect +def test_absolute_path(): + cli = Command("cli", params=[Option(["-f"], type=Path())]) + out = _get_completions(cli, ["-f"], "/ab") + assert len(out) == 1 + c = out[0] + assert c.value == "/ab" + + def test_option_flag(): cli = Command( "cli", @@ -257,7 +263,6 @@ @pytest.fixture() def _patch_for_completion(monkeypatch): - monkeypatch.setattr("click.core._fast_exit", sys.exit) monkeypatch.setattr( "click.shell_completion.BashComplete._check_version", lambda self: True ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/test_types.py new/click-8.0.3/tests/test_types.py --- old/click-8.0.1/tests/test_types.py 2021-04-14 22:27:09.000000000 +0200 +++ new/click-8.0.3/tests/test_types.py 2021-10-10 19:20:35.000000000 +0200 @@ -1,6 +1,8 @@ +import os.path import pathlib import pytest +from conftest import symlinks_supported import click @@ -100,3 +102,29 @@ result = runner.invoke(cli, ["a/b/c.txt"], standalone_mode=False) assert result.exception is None assert result.return_value == expect + + +@pytest.mark.skipif( + not symlinks_supported, reason="The current OS or FS doesn't support symlinks." +) +def test_path_resolve_symlink(tmp_path, runner): + test_file = tmp_path / "file" + test_file_str = os.fsdecode(test_file) + test_file.write_text("") + + path_type = click.Path(resolve_path=True) + param = click.Argument(["a"], type=path_type) + ctx = click.Context(click.Command("cli", params=[param])) + + test_dir = tmp_path / "dir" + test_dir.mkdir() + + 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 + + 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/click-8.0.1/tests/test_utils.py new/click-8.0.3/tests/test_utils.py --- old/click-8.0.1/tests/test_utils.py 2021-05-18 22:57:19.000000000 +0200 +++ new/click-8.0.3/tests/test_utils.py 2021-10-10 19:48:13.000000000 +0200 @@ -67,11 +67,19 @@ ({"bold": True}, "\x1b[1mx y\x1b[0m"), ({"dim": True}, "\x1b[2mx y\x1b[0m"), ({"underline": True}, "\x1b[4mx y\x1b[0m"), - ({"overline": True}, "\x1b[55mx y\x1b[0m"), - ({"italic": True}, "\x1b[23mx y\x1b[0m"), + ({"overline": True}, "\x1b[53mx y\x1b[0m"), + ({"italic": True}, "\x1b[3mx y\x1b[0m"), ({"blink": True}, "\x1b[5mx y\x1b[0m"), ({"reverse": True}, "\x1b[7mx y\x1b[0m"), ({"strikethrough": True}, "\x1b[9mx y\x1b[0m"), + ({"bold": False}, "\x1b[22mx y\x1b[0m"), + ({"dim": False}, "\x1b[22mx y\x1b[0m"), + ({"underline": False}, "\x1b[24mx y\x1b[0m"), + ({"overline": False}, "\x1b[55mx y\x1b[0m"), + ({"italic": False}, "\x1b[23mx y\x1b[0m"), + ({"blink": False}, "\x1b[25mx y\x1b[0m"), + ({"reverse": False}, "\x1b[27mx y\x1b[0m"), + ({"strikethrough": False}, "\x1b[29mx y\x1b[0m"), ({"fg": "black", "reset": False}, "\x1b[30mx y"), ], ) @@ -267,8 +275,8 @@ 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: " ")