New upstream version 7.0

This commit is contained in:
aviau 2019-01-07 11:51:19 -05:00
parent 5dd28971f0
commit 0143a0a452
45 changed files with 1285 additions and 564 deletions

View file

@ -1,28 +0,0 @@
environment:
global:
TOXENV: py,codecov
matrix:
- PYTHON: C:\Python36-x64
- PYTHON: C:\Python27-x64
- PYTHON: C:\Python36
- PYTHON: C:\Python27
init:
- SET PATH=%PYTHON%;%PATH%
install:
- python -m pip install -U tox
build: false
test_script:
- python -m tox
branches:
only:
- master
- /^.*-maintenance$/
cache:
- '%LOCALAPPDATA%\pip\Cache'

View file

@ -1,3 +0,0 @@
[run]
branch = true
source = click,tests

15
.gitignore vendored
View file

@ -1,15 +0,0 @@
.DS_Store
*.pyc
*.pyo
*.egg-ignore
*.egg-info
.pytest_cache
dist
build
docs/_build
click.egg-info
venv/
.tox
.cache
.ropeproject
.idea

View file

@ -1,56 +0,0 @@
os: linux
sudo: false
language: python
matrix:
include:
- python: 3.6
env: TOXENV=py,codecov
- python: 3.5
env: TOXENV=py,codecov
- python: 3.4
env: TOXENV=py,codecov
- python: 2.7
env: TOXENV=py,codecov
- python: pypy3
env: TOXENV=py,codecov
- python: nightly
env: TOXENV=py
- os: osx
language: generic
env: TOXENV=py3,py2,codecov
cache:
pip: false
directories:
- $HOME/Library/Caches/Homebrew
- $HOME/Library/Caches/pip
allow_failures:
- python: pypy3
- python: nightly
- os: osx
fast_finish: true
before_install:
- |
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
brew upgrade python
brew install python@2
export PATH="/usr/local/opt/python/libexec/bin:${PATH}"
fi
install:
- pip install tox
script:
- tox
cache:
- pip
branches:
only:
- master
- /^.*-maintenance/
notifications:
email: false

View file

@ -1,216 +1,293 @@
Click Changelog
===============
This contains all major version changes between Click releases.
Version 7.0
-----------
(upcoming release with new features, release date to be decided)
Released 2018-09-25
- Non-standalone calls to Context.exit return the exit code, rather than
calling ``sys.exit`` (`#667`_)(`#533`_)
- Updated test env matrix. (`#1027`_)
- Fixes a ``ZeroDivisionError`` in ``ProgressBar.make_step``,
when the arg passed to the first call of ``ProgressBar.update`` is 0. (`#1012`_)(`#447`_)
- Document that options can be ``required=True``. (`#1022`_)(`#514`_)
- Fix path validation bug. (`#1020`_)(`#795`_)
- Document customizing option names. (`#1016`_)(`#725`_)
- Wrap ``click.Choice``'s missing message. (`#1000`_)(`#202`_)
- Don't add newlines by default for progressbars. (`#1013`_)
- Document how ``auto_envar_prefix`` works with command groups. (`#1011`_)
- Fix failing bash completion function test signature.
- Clarify how paramteres are named. (`#1009`_)(`#949`_)
- Document bytestripping behavior of ``CliRunner``. (`#1010`_)(`#334`_)
- Fix Google App Engine ``ImportError``. (`#995`_)
- Document that ANSI color info isn't parsedfrom bytearrays in Python 2. (`#334`_)
- Add note to documentation on how parameters are named.
- Fix formatting for short help. (`#1008`_)
- Extract bar formatting to its own method. (`#414`_)
- Move ``fcntl`` import. (`#965`_)
- Fixed issues where ``fd`` was undefined. (`#1007`_)
- Added deprecation flag to commands. (`#1005`_)
- Fix various Sphinx errors. (`#883`_)
- Add ``case_sensitive=False`` as an option to Choice types. (`#887`_)
- Add details about Python version support. (`#1004`_)
- Clarify documentation on command line options. (`#1003`_)(`#741`_)
- Add ``case_sensitive=False`` as an option to Choice. (`#569`_)
- Better handling of help text for dynamic default option values. (`#996`_)
- Allow short width to address cmd formatting. (`#1002`_)
- Add test case checking for custom param type. (`#1001`_)
- Make ``Argument.make_metavar()`` default to type metavar. (`#675`_)
- Show progressbar only if total execution time is visible. (`#487`_)
- Allow setting ``prog_name`` as extra in ``CliRunner.invoke`` (`#999`_)(`#616`_)
- Add support for Sphinx 1.7+ (`#991`_)
- Fix ``get_winter_size()`` so it correctly returns ``(0,0)``. (`#997`_)
- Update progress after iteration. (`#706`_)(`#651`_)
- Add ``show_envvar`` for showing environment variables in help. (`#710`_)
- Add support for bright colors. (`#809`_)
- Add documentation for ``ignore_unkown_options``. (`#684`_)
- Allow ``CliRunner`` to separate stdout and stderr. (`#868`_)
- Implement streaming pager. (`#889`_)(`#409`_)
- Progress bar now uses stderr by default. (`#863`_)
- Do not set options twice. (`#962`_)
- Add Py2/ unicode / str compatability for doc tools. (`#993`_)(`#719`_)
- Add copy option attrs so that custom classes can be re-used. (`#994`_)(`#926`_)
- ``param_hint`` in errors now derived from param itself. (`#709`_)(`#704`_)(`#598`_)
- Add a test that ensures that when an Argument is formatted into a usage error,
its metavar is used, not its name. (`#612`_)
- Fix variable precedence. (`#874`_)(`#873`_)
- Fix ``ResourceWarning`` that occurs during some tests. (`#878`_)
- Update README to match flask style and add ``long_description`` to setup.py. (`#990`_)
- Drop testing for 2.6 3.3 and 3.6.
- Make locale optional (`#880`_)
- Fix invalid escape sequences. (`#877`_)
- Added workaround for jupyter. (`#918`_)
- x and a filemodes now use stdout when file is ``'-'``. (`#929`_)
- ``_AtomicFile`` now uses the realpath of the original filename. (`#920`_)
- Fix missing comma in ``__all__`` list (`#935`_)
- Raw strings added so correct escaping occurs. (`#807`_)
- Add bool conversion for ``t`` and ``f``. (`#842`_)
- Update doc to match arg name for ``path_type``. (`#801`_)
- Add bright colors support for ``click.style``
and fix the reset option for parameters ``fg`` and ``bg``. (`#703`_)
- Add test and documentation for ``Option`` naming: functionality. (`#799`_)
- Use deterministic option name; can't rely on list sort. (`#794`_)(`#793`_)
- Added support for bash completions containing spaces. (`#773`_)
- Added support for dynamic bash completion from a user-supplied callback.
(`#755`_)
- Added support for bash completion of ``type=click.Choice`` for ``Options`` and
``Arguments``. (`#535`_)
- The user is now presented with the available choices if ``prompt=True`` and
``type=click.Choice`` in a ``click.option``. The choices are listed within
parenthesis like ``'Choose fruit (apple, orange): '``.
- The exception objects now store unicode properly.
- Added the ability to hide commands and options from help.
- Added Float Range in Types.
- ``secho``'s first argument can now be ``None``, like in ``echo``.
- Usage errors now hint at the ``--help`` option.
- ``launch`` now works properly under Cygwin. (`#650`_)
- ``CliRunner.invoke`` now may receive ``args`` as a string representing
a Unix shell command. See (`#664`_).
- Fix bug that caused bashcompletion to give improper completions on
chained commands. (`#774`_)
- Add support for bright colors.
- ``'t'`` and ``'f'`` are now converted to ``True`` and ``False``.
- Fix bug that caused bashcompletion to give improper completions on
chained commands when a required option/argument was being completed.
(`#790`_)(`#806`_)
- Allow autocompletion function to determine whether or not to return
completions that start with the incomplete argument.
- Add native ZSH autocompletion support. (`#323`_)(`#865`_)
- Add support for auto-completion documentation. See (`#866`_)(`#869`_)
- Subcommands that are named by the function now automatically have the
underscore replaced with a dash. So if you register a function named
``my_command`` it becomes ``my-command`` in the command line interface.
- Stdout is now automatically set to non blocking.
- Use realpath to convert atomic file internally into its full canonical
path so that changing working directories does not harm it.
- Force stdout/stderr writable. This works around issues with badly patched
standard streams like those from jupyter.
- Drop support for Python 2.6 and 3.3. (`#967`_, `#976`_)
- Wrap ``click.Choice``'s missing message. (`#202`_, `#1000`_)
- Add native ZSH autocompletion support. (`#323`_, `#865`_)
- Document that ANSI color info isn't parsed from bytearrays in
Python 2. (`#334`_)
- Document byte-stripping behavior of ``CliRunner``. (`#334`_,
`#1010`_)
- Usage errors now hint at the ``--help`` option. (`#393`_, `#557`_)
- Implement streaming pager. (`#409`_, `#889`_)
- Extract bar formatting to its own method. (`#414`_)
- Add ``DateTime`` type for converting input in given date time
formats. (`#423`_)
- ``secho``'s first argument can now be ``None``, like in ``echo``.
(`#424`_)
- Fixes a ``ZeroDivisionError`` in ``ProgressBar.make_step``, when the
arg passed to the first call of ``ProgressBar.update`` is 0.
(`#447`_, `#1012`_)
- Show progressbar only if total execution time is visible. (`#487`_)
- Added the ability to hide commands and options from help. (`#500`_)
- Document that options can be ``required=True``. (`#514`_, `#1022`_)
- Non-standalone calls to ``Context.exit`` return the exit code,
rather than calling ``sys.exit``. (`#533`_, `#667`_, `#1098`_)
- ``click.getchar()`` returns Unicode in Python 3 on Windows,
consistent with other platforms. (`#537`_, `#821`_, `#822`_,
`#1088`_, `#1108`_)
- Added ``FloatRange`` type. (`#538`_, `#553`_)
- Added support for bash completion of ``type=click.Choice`` for
``Options`` and ``Arguments``. (`#535`_, `#681`_)
- Only allow one positional arg for ``Argument`` parameter
declaration. (`#568`_, `#574`_, `#1014`_)
- Add ``case_sensitive=False`` as an option to Choice. (`#569`_)
- ``click.getchar()`` correctly raises ``KeyboardInterrupt`` on "^C"
and ``EOFError`` on "^D" on Linux. (`#583`_, `#1115`_)
- Fix encoding issue with ``click.getchar(echo=True)`` on Linux.
(`#1115`_)
- ``param_hint`` in errors now derived from param itself. (`#598`_,
`#704`_, `#709`_)
- Add a test that ensures that when an argument is formatted into a
usage error, its metavar is used, not its name. (`#612`_)
- Allow setting ``prog_name`` as extra in ``CliRunner.invoke``.
(`#616`_, `#999`_)
- Help text taken from docstrings truncates at the ``\f`` form feed
character, useful for hiding Sphinx-style parameter documentation.
(`#629`_, `#1091`_)
- ``launch`` now works properly under Cygwin. (`#650`_)
- Update progress after iteration. (`#651`_, `#706`_)
- ``CliRunner.invoke`` now may receive ``args`` as a string
representing a Unix shell command. (`#664`_)
- Make ``Argument.make_metavar()`` default to type metavar. (`#675`_)
- Add documentation for ``ignore_unknown_options``. (`#684`_)
- Add bright colors support for ``click.style`` and fix the reset
option for parameters ``fg`` and ``bg``. (`#703`_, `#809`_)
- Add ``show_envvar`` for showing environment variables in help.
(`#710`_)
- Avoid ``BrokenPipeError`` during interpreter shutdown when stdout or
stderr is a closed pipe. (`#712`_, `#1106`_)
- Document customizing option names. (`#725`_, `#1016`_)
- Disable ``sys._getframes()`` on Python interpreters that don't
support it. (`#728`_)
- Fix bug in test runner when calling ``sys.exit`` with ``None``.
(`#739`_)
- Clarify documentation on command line options. (`#741`_, `#1003`_)
- Fix crash on Windows console. (`#744`_)
- Fix bug that caused bash completion to give improper completions on
chained commands. (`#754`_, `#774`_)
- Added support for dynamic bash completion from a user-supplied
callback. (`#755`_)
- Added support for bash completions containing spaces. (`#773`_)
- Allow autocompletion function to determine whether or not to return
completions that start with the incomplete argument. (`#790`_,
`#806`_)
- Fix option naming routine to match documentation and be
deterministic. (`#793`_, `#794`_)
- Fix path validation bug. (`#795`_, `#1020`_)
- Add test and documentation for ``Option`` naming: functionality.
(`#799`_)
- Update doc to match arg name for ``path_type``. (`#801`_)
- Raw strings added so correct escaping occurs. (`#807`_)
- Fix 16k character limit of ``click.echo`` on Windows. (`#816`_,
`#819`_)
- Overcome 64k character limit when writing to binary stream on
Windows 7. (`#825`_, `#830`_)
- Add bool conversion for "t" and "f". (`#842`_)
- ``NoSuchOption`` errors take ``ctx`` so that ``--help`` hint gets
printed in error output. (`#860`_)
- Fixed the behavior of Click error messages with regards to Unicode
on 2.x and 3.x. Message is now always Unicode and the str and
Unicode special methods work as you expect on that platform.
(`#862`_)
- Progress bar now uses stderr by default. (`#863`_)
- Add support for auto-completion documentation. (`#866`_, `#869`_)
- Allow ``CliRunner`` to separate stdout and stderr. (`#868`_)
- Fix variable precedence. (`#873`_, `#874`_)
- Fix invalid escape sequences. (`#877`_)
- Fix ``ResourceWarning`` that occurs during some tests. (`#878`_)
- When detecting a misconfigured locale, don't fail if the ``locale``
command fails. (`#880`_)
- Add ``case_sensitive=False`` as an option to ``Choice`` types.
(`#887`_)
- Force stdout/stderr writable. This works around issues with badly
patched standard streams like those from Jupyter. (`#918`_)
- Fix completion of subcommand options after last argument (`#919`_,
`#930`_)
- ``_AtomicFile`` now uses the ``realpath`` of the original filename
so that changing the working directory does not affect it.
(`#920`_)
- Fix incorrect completions when defaults are present (`#925`_,
`#930`_)
- Add copy option attrs so that custom classes can be re-used.
(`#926`_, `#994`_)
- "x" and "a" file modes now use stdout when file is ``"-"``.
(`#929`_)
- Fix missing comma in ``__all__`` list. (`#935`_)
- Clarify how parameters are named. (`#949`_, `#1009`_)
- Stdout is now automatically set to non blocking. (`#954`_)
- Do not set options twice. (`#962`_)
- Move ``fcntl`` import. (`#965`_)
- Fix Google App Engine ``ImportError``. (`#995`_)
- Better handling of help text for dynamic default option values.
(`#996`_)
- Fix ``get_winter_size()`` so it correctly returns ``(0,0)``.
(`#997`_)
- Add test case checking for custom param type. (`#1001`_)
- Allow short width to address cmd formatting. (`#1002`_)
- Add details about Python version support. (`#1004`_)
- Added deprecation flag to commands. (`#1005`_)
- Fixed issues where ``fd`` was undefined. (`#1007`_)
- Fix formatting for short help. (`#1008`_)
- Document how ``auto_envvar_prefix`` works with command groups.
(`#1011`_)
- Don't add newlines by default for progress bars. (`#1013`_)
- Use Python sorting order for ZSH completions. (`#1047`_, `#1059`_)
- Document that parameter names are converted to lowercase by default.
(`#1055`_)
- Subcommands that are named by the function now automatically have
the underscore replaced with a dash. If you register a function
named ``my_command`` it becomes ``my-command`` in the command line
interface.
- Hide hidden commands and options from completion. (`#1058`_,
`#1061`_)
- Fix absolute import blocking Click from being vendored into a
project on Windows. (`#1068`_, `#1069`_)
- Fix issue where a lowercase ``auto_envvar_prefix`` would not be
converted to uppercase. (`#1105`_)
.. _#1027: https://github.com/pallets/click/pull/1027
.. _#1012: https://github.com/pallets/click/pull/1012
.. _#447: https://github.com/pallets/click/issues/447
.. _#1022: https://github.com/pallets/click/pull/1022
.. _#869: https://github.com/pallets/click/pull/869
.. _#866: https://github.com/pallets/click/issues/866
.. _#514: https://github.com/pallets/click/issues/514
.. _#1020: https://github.com/pallets/click/pull/1020
.. _#795: https://github.com/pallets/click/issues/795
.. _#1016: https://github.com/pallets/click/pull/1016
.. _#725: https://github.com/pallets/click/issues/725
.. _#1000: https://github.com/pallets/click/pull/1000
.. _#202: https://github.com/pallets/click/issues/202
.. _#1013: https://github.com/pallets/click/pull/1013
.. _#1011: https://github.com/pallets/click/pull/1011
.. _#865: https://github.com/pallets/click/pull/865
.. _#323: https://github.com/pallets/click/issues/323
.. _#1009: https://github.com/pallets/click/pull/1009
.. _#949: https://github.com/pallets/click/issues/949
.. _#1010: https://github.com/pallets/click/pull/1010
.. _#334: https://github.com/pallets/click/issues/334
.. _#995: https://github.com/pallets/click/pull/995
.. _#1008: https://github.com/pallets/click/pull/1008
.. _#393: https://github.com/pallets/click/issues/393
.. _#409: https://github.com/pallets/click/issues/409
.. _#414: https://github.com/pallets/click/pull/414
.. _#965: https://github.com/pallets/click/pull/965
.. _#1005: https://github.com/pallets/click/pull/1005
.. _#423: https://github.com/pallets/click/pull/423
.. _#424: https://github.com/pallets/click/pull/424
.. _#447: https://github.com/pallets/click/issues/447
.. _#487: https://github.com/pallets/click/pull/487
.. _#500: https://github.com/pallets/click/pull/500
.. _#514: https://github.com/pallets/click/issues/514
.. _#533: https://github.com/pallets/click/pull/533
.. _#535: https://github.com/pallets/click/issues/535
.. _#537: https://github.com/pallets/click/issues/537
.. _#538: https://github.com/pallets/click/pull/538
.. _#553: https://github.com/pallets/click/pull/553
.. _#557: https://github.com/pallets/click/pull/557
.. _#568: https://github.com/pallets/click/issues/568
.. _#569: https://github.com/pallets/click/issues/569
.. _#574: https://github.com/pallets/click/issues/574
.. _#583: https://github.com/pallets/click/issues/583
.. _#598: https://github.com/pallets/click/issues/598
.. _#612: https://github.com/pallets/click/pull/612
.. _#616: https://github.com/pallets/click/issues/616
.. _#629: https://github.com/pallets/click/pull/629
.. _#650: https://github.com/pallets/click/pull/650
.. _#651: https://github.com/pallets/click/issues/651
.. _#664: https://github.com/pallets/click/pull/664
.. _#667: https://github.com/pallets/click/issues/667
.. _#675: https://github.com/pallets/click/pull/675
.. _#681: https://github.com/pallets/click/pull/681
.. _#684: https://github.com/pallets/click/pull/684
.. _#703: https://github.com/pallets/click/issues/703
.. _#704: https://github.com/pallets/click/issues/704
.. _#706: https://github.com/pallets/click/pull/706
.. _#709: https://github.com/pallets/click/pull/709
.. _#710: https://github.com/pallets/click/pull/710
.. _#712: https://github.com/pallets/click/pull/712
.. _#719: https://github.com/pallets/click/issues/719
.. _#725: https://github.com/pallets/click/issues/725
.. _#728: https://github.com/pallets/click/pull/728
.. _#739: https://github.com/pallets/click/pull/739
.. _#741: https://github.com/pallets/click/issues/741
.. _#744: https://github.com/pallets/click/issues/744
.. _#754: https://github.com/pallets/click/issues/754
.. _#755: https://github.com/pallets/click/pull/755
.. _#773: https://github.com/pallets/click/pull/773
.. _#774: https://github.com/pallets/click/pull/774
.. _#790: https://github.com/pallets/click/issues/790
.. _#793: https://github.com/pallets/click/issues/793
.. _#794: https://github.com/pallets/click/pull/794
.. _#795: https://github.com/pallets/click/issues/795
.. _#799: https://github.com/pallets/click/pull/799
.. _#801: https://github.com/pallets/click/pull/801
.. _#806: https://github.com/pallets/click/pull/806
.. _#807: https://github.com/pallets/click/pull/807
.. _#809: https://github.com/pallets/click/pull/809
.. _#816: https://github.com/pallets/click/pull/816
.. _#819: https://github.com/pallets/click/pull/819
.. _#821: https://github.com/pallets/click/issues/821
.. _#822: https://github.com/pallets/click/issues/822
.. _#825: https://github.com/pallets/click/issues/825
.. _#830: https://github.com/pallets/click/pull/830
.. _#842: https://github.com/pallets/click/pull/842
.. _#860: https://github.com/pallets/click/issues/860
.. _#862: https://github.com/pallets/click/issues/862
.. _#863: https://github.com/pallets/click/pull/863
.. _#865: https://github.com/pallets/click/pull/865
.. _#866: https://github.com/pallets/click/issues/866
.. _#868: https://github.com/pallets/click/pull/868
.. _#869: https://github.com/pallets/click/pull/869
.. _#873: https://github.com/pallets/click/issues/873
.. _#874: https://github.com/pallets/click/pull/874
.. _#877: https://github.com/pallets/click/pull/877
.. _#878: https://github.com/pallets/click/pull/878
.. _#880: https://github.com/pallets/click/pull/880
.. _#883: https://github.com/pallets/click/pull/883
.. _#887: https://github.com/pallets/click/pull/887
.. _#1004: https://github.com/pallets/click/pull/1004
.. _#1003: https://github.com/pallets/click/pull/1003
.. _#741: https://github.com/pallets/click/issues/741
.. _#569: https://github.com/pallets/click/pull/569
.. _#1007: https://github.com/pallets/click/pull/1007
.. _#996: https://github.com/pallets/click/pull/996
.. _#1002: https://github.com/pallets/click/pull/1002
.. _#1001: https://github.com/pallets/click/pull/1001
.. _#675: https://github.com/pallets/click/pull/675
.. _#487: https://github.com/pallets/click/pull/487
.. _#999: https://github.com/pallets/click/pull/999
.. _#616: https://github.com/pallets/click/issues/616
.. _#991: https://github.com/pallets/click/pull/991
.. _#997: https://github.com/pallets/click/pull/997
.. _#706: https://github.com/pallets/click/pull/706
.. _#651: https://github.com/pallets/click/issues/651
.. _#710: https://github.com/pallets/click/pull/710
.. _#809: https://github.com/pallets/click/pull/809
.. _#868: https://github.com/pallets/click/pull/868
.. _#889: https://github.com/pallets/click/pull/889
.. _#409: https://github.com/pallets/click/issues/409
.. _#863: https://github.com/pallets/click/pull/863
.. _#918: https://github.com/pallets/click/pull/918
.. _#919: https://github.com/pallets/click/issues/919
.. _#920: https://github.com/pallets/click/pull/920
.. _#925: https://github.com/pallets/click/issues/925
.. _#926: https://github.com/pallets/click/issues/926
.. _#929: https://github.com/pallets/click/pull/929
.. _#930: https://github.com/pallets/click/pull/930
.. _#935: https://github.com/pallets/click/pull/935
.. _#949: https://github.com/pallets/click/issues/949
.. _#954: https://github.com/pallets/click/pull/954
.. _#962: https://github.com/pallets/click/pull/962
.. _#965: https://github.com/pallets/click/pull/965
.. _#967: https://github.com/pallets/click/pull/967
.. _#976: https://github.com/pallets/click/pull/976
.. _#990: https://github.com/pallets/click/pull/990
.. _#991: https://github.com/pallets/click/pull/991
.. _#993: https://github.com/pallets/click/pull/993
.. _#994: https://github.com/pallets/click/pull/994
.. _#926: https://github.com/pallets/click/issues/926
.. _#709: https://github.com/pallets/click/pull/709
.. _#612: https://github.com/pallets/click/pull/612
.. _#704: https://github.com/pallets/click/issues/704
.. _#598: https://github.com/pallets/click/issues/598
.. _#719: https://github.com/pallets/click/issues/719
.. _#874: https://github.com/pallets/click/pull/874
.. _#873: https://github.com/pallets/click/issues/873
.. _#990: https://github.com/pallets/click/pull/990
.. _#684: https://github.com/pallets/click/pull/684
.. _#878: https://github.com/pallets/click/pull/878
.. _#880: https://github.com/pallets/click/issues/880
.. _#877: https://github.com/pallets/click/pull/877
.. _#918: https://github.com/pallets/click/pull/918
.. _#929: https://github.com/pallets/click/pull/929
.. _#920: https://github.com/pallets/click/pull/920
.. _#935: https://github.com/pallets/click/pull/935
.. _#807: https://github.com/pallets/click/pull/807
.. _#806: https://github.com/pallets/click/pull/806
.. _#842: https://github.com/pallets/click/pull/842
.. _#801: https://github.com/pallets/click/pull/801
.. _#703: https://github.com/pallets/click/issues/703
.. _#799: https://github.com/pallets/click/pull/799
.. _#794: https://github.com/pallets/click/pull/794
.. _#793: https://github.com/pallets/click/issues/793
.. _#773: https://github.com/pallets/click/pull/773
.. _#755: https://github.com/pallets/click/pull/755
.. _#535: https://github.com/pallets/click/pull/535
.. _#650: https://github.com/pallets/click/pull/650
.. _#664: https://github.com/pallets/click/pull/664
.. _#774: https://github.com/pallets/click/pull/774
.. _#790: https://github.com/pallets/click/pull/790
.. _#995: https://github.com/pallets/click/pull/995
.. _#996: https://github.com/pallets/click/pull/996
.. _#997: https://github.com/pallets/click/pull/997
.. _#999: https://github.com/pallets/click/pull/999
.. _#1000: https://github.com/pallets/click/pull/1000
.. _#1001: https://github.com/pallets/click/pull/1001
.. _#1002: https://github.com/pallets/click/pull/1002
.. _#1003: https://github.com/pallets/click/pull/1003
.. _#1004: https://github.com/pallets/click/pull/1004
.. _#1005: https://github.com/pallets/click/pull/1005
.. _#1007: https://github.com/pallets/click/pull/1007
.. _#1008: https://github.com/pallets/click/pull/1008
.. _#1009: https://github.com/pallets/click/pull/1009
.. _#1010: https://github.com/pallets/click/pull/1010
.. _#1011: https://github.com/pallets/click/pull/1011
.. _#1012: https://github.com/pallets/click/pull/1012
.. _#1013: https://github.com/pallets/click/pull/1013
.. _#1014: https://github.com/pallets/click/pull/1014
.. _#1016: https://github.com/pallets/click/pull/1016
.. _#1020: https://github.com/pallets/click/pull/1020
.. _#1022: https://github.com/pallets/click/pull/1022
.. _#1027: https://github.com/pallets/click/pull/1027
.. _#1047: https://github.com/pallets/click/pull/1047
.. _#1055: https://github.com/pallets/click/pull/1055
.. _#1058: https://github.com/pallets/click/pull/1058
.. _#1059: https://github.com/pallets/click/pull/1059
.. _#1061: https://github.com/pallets/click/pull/1061
.. _#1068: https://github.com/pallets/click/issues/1068
.. _#1069: https://github.com/pallets/click/pull/1069
.. _#1088: https://github.com/pallets/click/issues/1088
.. _#1091: https://github.com/pallets/click/pull/1091
.. _#1098: https://github.com/pallets/click/pull/1098
.. _#1105: https://github.com/pallets/click/pull/1105
.. _#1106: https://github.com/pallets/click/pull/1106
.. _#1108: https://github.com/pallets/click/pull/1108
.. _#1115: https://github.com/pallets/click/pull/1115
Version 6.8
-----------
(bugfix release; yet to be released)
- Disabled ``sys._getframes()`` on Python interpreters that don't support it. See
#728.
- Fix bug in test runner when calling ``sys.exit`` with ``None``. See #739.
- Fix crash on Windows console, see #744.
- Fix bashcompletion on chained commands. See #754.
- Fix option naming routine to match documentation. See #793
- Fixed the behavior of click error messages with regards to unicode on 2.x
and 3.x respectively. Message is now always unicode and the str and unicode
special methods work as you expect on that platform.
Version 6.7
-----------

View file

@ -7,8 +7,8 @@ Thanks for considering contributing to Click.
Support questions
=================
Please, don't use the issue tracker for this. Check whether the `Pocoo IRC
channel <http://www.pocoo.org/irc/>`_ can help with your issue. If your problem
Please, don't use the issue tracker for this. Check whether the
``#pocoo`` IRC channel on Freenode can help with your issue. If your problem
is not strictly Click-specific, ``#python`` on Freenode is generally more
active. `StackOverflow <https://stackoverflow.com/>`_ is also worth
considering.
@ -33,9 +33,9 @@ Submitting patches
may ignore the line-length-limit if following it would make the code uglier.
- For features: Consider whether your feature would be a better fit for an
`external package <http://click.pocoo.org/contrib/>`_
`external package <https://click.palletsprojects.com/en/7.x/contrib/>`_
- For bugfixes: Submit against the latest maintenance branch instead of master!
- For docs and bug fixes: Submit against the latest maintenance branch instead of master!
Running the testsuite
---------------------

119
Click.egg-info/PKG-INFO Normal file
View file

@ -0,0 +1,119 @@
Metadata-Version: 1.2
Name: Click
Version: 7.0
Summary: Composable command line interface toolkit
Home-page: https://palletsprojects.com/p/click/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets Team
Maintainer-email: contact@palletsprojects.com
License: BSD
Project-URL: Documentation, https://click.palletsprojects.com/
Project-URL: Code, https://github.com/pallets/click
Project-URL: Issue tracker, https://github.com/pallets/click/issues
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 click
Click supports Python 3.4 and newer, Python 2.7, and PyPy.
.. _pip: https://pip.pypa.io/en/stable/quickstart/
A Simple Example
----------------
What does it look like? Here is an example of a simple Click program:
.. 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("Hello, %s!" % name)
if __name__ == '__main__':
hello()
And what it looks like when run:
.. 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
-----
* Website: https://palletsprojects.com/p/click/
* Documentation: https://click.palletsprojects.com/
* License: `BSD <https://github.com/pallets/click/blob/master/LICENSE.rst>`_
* Releases: https://pypi.org/project/click/
* Code: https://github.com/pallets/click
* Issue tracker: https://github.com/pallets/click/issues
* Test status:
* Linux, Mac: https://travis-ci.org/pallets/click
* Windows: https://ci.appveyor.com/project/pallets/click
* Test coverage: https://codecov.io/gh/pallets/click
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*

115
Click.egg-info/SOURCES.txt Normal file
View file

@ -0,0 +1,115 @@
CHANGES.rst
CONTRIBUTING.rst
LICENSE.rst
MANIFEST.in
README.rst
setup.cfg
setup.py
tox.ini
Click.egg-info/PKG-INFO
Click.egg-info/SOURCES.txt
Click.egg-info/dependency_links.txt
Click.egg-info/top_level.txt
artwork/logo.svg
click/__init__.py
click/_bashcomplete.py
click/_compat.py
click/_termui_impl.py
click/_textwrap.py
click/_unicodefun.py
click/_winconsole.py
click/core.py
click/decorators.py
click/exceptions.py
click/formatting.py
click/globals.py
click/parser.py
click/termui.py
click/testing.py
click/types.py
click/utils.py
docs/Makefile
docs/advanced.rst
docs/api.rst
docs/arguments.rst
docs/bashcomplete.rst
docs/changelog.rst
docs/commands.rst
docs/complex.rst
docs/conf.py
docs/contrib.rst
docs/documentation.rst
docs/exceptions.rst
docs/index.rst
docs/license.rst
docs/make.bat
docs/options.rst
docs/parameters.rst
docs/prompts.rst
docs/python3.rst
docs/quickstart.rst
docs/requirements.txt
docs/setuptools.rst
docs/testing.rst
docs/upgrading.rst
docs/utils.rst
docs/why.rst
docs/wincmd.rst
docs/_static/click-icon.png
docs/_static/click-logo-sidebar.png
docs/_static/click-logo.png
examples/README
examples/aliases/README
examples/aliases/aliases.ini
examples/aliases/aliases.py
examples/aliases/setup.py
examples/bashcompletion/README
examples/bashcompletion/bashcompletion.py
examples/bashcompletion/setup.py
examples/colors/README
examples/colors/colors.py
examples/colors/setup.py
examples/complex/README
examples/complex/setup.py
examples/complex/complex/__init__.py
examples/complex/complex/cli.py
examples/complex/complex/commands/__init__.py
examples/complex/complex/commands/cmd_init.py
examples/complex/complex/commands/cmd_status.py
examples/imagepipe/.gitignore
examples/imagepipe/README
examples/imagepipe/example01.jpg
examples/imagepipe/example02.jpg
examples/imagepipe/imagepipe.py
examples/imagepipe/setup.py
examples/inout/README
examples/inout/inout.py
examples/inout/setup.py
examples/naval/README
examples/naval/naval.py
examples/naval/setup.py
examples/repo/README
examples/repo/repo.py
examples/repo/setup.py
examples/termui/README
examples/termui/setup.py
examples/termui/termui.py
examples/validation/README
examples/validation/setup.py
examples/validation/validation.py
tests/conftest.py
tests/test_arguments.py
tests/test_bashcomplete.py
tests/test_basic.py
tests/test_chain.py
tests/test_commands.py
tests/test_compat.py
tests/test_context.py
tests/test_defaults.py
tests/test_formatting.py
tests/test_imports.py
tests/test_normalization.py
tests/test_options.py
tests/test_termui.py
tests/test_testing.py
tests/test_utils.py

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
click

38
LICENSE
View file

@ -1,38 +0,0 @@
Copyright (c) 2014 by Armin Ronacher.
Click uses parts of optparse written by Gregory P. Ward and maintained by the
Python software foundation. This is limited to code in the parser.py
module:
Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.
Copyright (c) 2002-2006 Python Software Foundation. All rights reserved.
Some rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

39
LICENSE.rst Normal file
View file

@ -0,0 +1,39 @@
Copyright © 2014 by the Pallets team.
Some rights reserved.
Redistribution and use in source and binary forms of the software as
well as documentation, with or without modification, are permitted
provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
----
Click uses parts of optparse written by Gregory P. Ward and maintained
by the Python Software Foundation. This is limited to code in parser.py.
Copyright © 2001-2006 Gregory P. Ward. All rights reserved.
Copyright © 2002-2006 Python Software Foundation. All rights reserved.

View file

@ -1,9 +1,11 @@
include Makefile CHANGES LICENSE
include CHANGES.rst
include CONTRIBUTING.rst
include LICENSE.rst
include README.rst
include tox.ini
graft artwork
graft tests
graft examples
graft docs
prune docs/_build
graft examples
graft tests
global-exclude *.py[co] .DS_Store

View file

@ -1,11 +0,0 @@
test:
@cd tests; PYTHONPATH=.. pytest --tb=short
upload-docs:
$(MAKE) -C docs dirhtml
rsync -a docs/_build/dirhtml/* flow.srv.pocoo.org:/srv/websites/click.pocoo.org/static/
release:
python setup.py sdist bdist_wheel upload
.PHONY: upload-docs

119
PKG-INFO Normal file
View file

@ -0,0 +1,119 @@
Metadata-Version: 1.2
Name: Click
Version: 7.0
Summary: Composable command line interface toolkit
Home-page: https://palletsprojects.com/p/click/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets Team
Maintainer-email: contact@palletsprojects.com
License: BSD
Project-URL: Documentation, https://click.palletsprojects.com/
Project-URL: Code, https://github.com/pallets/click
Project-URL: Issue tracker, https://github.com/pallets/click/issues
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 click
Click supports Python 3.4 and newer, Python 2.7, and PyPy.
.. _pip: https://pip.pypa.io/en/stable/quickstart/
A Simple Example
----------------
What does it look like? Here is an example of a simple Click program:
.. 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("Hello, %s!" % name)
if __name__ == '__main__':
hello()
And what it looks like when run:
.. 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
-----
* Website: https://palletsprojects.com/p/click/
* Documentation: https://click.palletsprojects.com/
* License: `BSD <https://github.com/pallets/click/blob/master/LICENSE.rst>`_
* Releases: https://pypi.org/project/click/
* Code: https://github.com/pallets/click
* Issue tracker: https://github.com/pallets/click/issues
* Test status:
* Linux, Mac: https://travis-ci.org/pallets/click
* Windows: https://ci.appveyor.com/project/pallets/click
* Test coverage: https://codecov.io/gh/pallets/click
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*

View file

@ -2,8 +2,8 @@
==========
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
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
@ -12,9 +12,9 @@ implement an intended CLI API.
Click in three points:
- arbitrary nesting of commands
- automatic help page generation
- supports lazy loading of subcommands at runtime
- Arbitrary nesting of commands
- Automatic help page generation
- Supports lazy loading of subcommands at runtime
Installing
@ -41,13 +41,13 @@ What does it look like? Here is an example of a simple Click program:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
@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 x in range(count):
click.echo('Hello %s!' % name)
for _ in range(count):
click.echo("Hello, %s!" % name)
if __name__ == '__main__':
hello()
@ -57,17 +57,17 @@ And what it looks like when run:
.. code-block:: text
$ python hello.py --count=3
Your name: John
Hello John!
Hello John!
Hello John!
Your name: Click
Hello, Click!
Hello, Click!
Hello, Click!
Donate
------
The Pallets organization develops and supports Flask and the libraries
it uses. In order to grow the community of contributors and users, and
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`_.
@ -79,7 +79,7 @@ Links
* Website: https://palletsprojects.com/p/click/
* Documentation: https://click.palletsprojects.com/
* License: `BSD <https://github.com/pallets/click/blob/master/LICENSE>`_
* License: `BSD <https://github.com/pallets/click/blob/master/LICENSE.rst>`_
* Releases: https://pypi.org/project/click/
* Code: https://github.com/pallets/click
* Issue tracker: https://github.com/pallets/click/issues

View file

@ -1,17 +1,15 @@
# -*- coding: utf-8 -*-
"""
click
~~~~~
click
~~~~~
Click is a simple Python module that wraps the stdlib's optparse to make
writing command line scripts fun. Unlike other modules, it's based around
a simple API that does not come with too much magic and is composable.
Click is a simple Python module inspired by the stdlib optparse to make
writing command line scripts fun. Unlike other modules, it's based
around a simple API that does not come with too much magic and is
composable.
In case optparse ever gets removed from the stdlib, it will be shipped by
this module.
:copyright: (c) 2014 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
:copyright: © 2014 by the Pallets team.
:license: BSD, see LICENSE.rst for more details.
"""
# Core classes
@ -28,7 +26,7 @@ from .decorators import pass_context, pass_obj, make_pass_decorator, \
# Types
from .types import ParamType, File, Path, Choice, IntRange, Tuple, \
STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange
DateTime, STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange
# Utilities
from .utils import echo, get_binary_stream, get_text_stream, open_file, \
@ -65,8 +63,9 @@ __all__ = [
'version_option', 'help_option',
# Types
'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple', 'STRING',
'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', 'FloatRange',
'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple',
'DateTime', 'STRING', 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED',
'FloatRange',
# Utilities
'echo', 'get_binary_stream', 'get_text_stream', 'open_file',
@ -95,4 +94,4 @@ __all__ = [
disable_unicode_literals_warning = False
__version__ = '7.0-dev'
__version__ = '7.0'

View file

@ -1,4 +1,3 @@
import collections
import copy
import os
import re
@ -8,8 +7,14 @@ from .parser import split_arg_string
from .core import MultiCommand, Option, Argument
from .types import Choice
try:
from collections import abc
except ImportError:
import collections as abc
WORDBREAK = '='
# Note, only BASH version 4.4 and later have the nosort option.
COMPLETION_SCRIPT_BASH = '''
%(complete_func)s() {
local IFS=$'\n'
@ -19,7 +24,18 @@ COMPLETION_SCRIPT_BASH = '''
return 0
}
complete -F %(complete_func)s %(script_names)s
%(complete_func)setup() {
local COMPLETION_OPTIONS=""
local BASH_VERSION_ARR=(${BASH_VERSION//./ })
# Only BASH version 4.4 and later have the nosort option.
if [ ${BASH_VERSION_ARR[0]} -gt 4 ] || ([ ${BASH_VERSION_ARR[0]} -eq 4 ] && [ ${BASH_VERSION_ARR[1]} -ge 4 ]); then
COMPLETION_OPTIONS="-o nosort"
fi
complete $COMPLETION_OPTIONS -F %(complete_func)s %(script_names)s
}
%(complete_func)setup
'''
COMPLETION_SCRIPT_ZSH = '''
@ -41,11 +57,13 @@ COMPLETION_SCRIPT_ZSH = '''
done
if [ -n "$completions_with_descriptions" ]; then
_describe '' completions_with_descriptions
_describe -V unsorted completions_with_descriptions -U -Q
fi
if [ -n "$completions" ]; then
compadd -M 'r:|=* l:|=* r:|=*' -a completions
compadd -U -V unsorted -Q -a completions
fi
compstate[insert]="automenu"
}
compdef %(complete_func)s %(script_names)s
@ -73,18 +91,31 @@ def resolve_ctx(cli, prog_name, args):
:return: the final context/command parsed
"""
ctx = cli.make_context(prog_name, args, resilient_parsing=True)
args_remaining = ctx.protected_args + ctx.args
while ctx is not None and args_remaining:
args = ctx.protected_args + ctx.args
while args:
if isinstance(ctx.command, MultiCommand):
cmd = ctx.command.get_command(ctx, args_remaining[0])
if cmd is None:
return None
ctx = cmd.make_context(
args_remaining[0], args_remaining[1:], parent=ctx, resilient_parsing=True)
args_remaining = ctx.protected_args + ctx.args
if not ctx.command.chain:
cmd_name, cmd, args = ctx.command.resolve_command(ctx, args)
if cmd is None:
return ctx
ctx = cmd.make_context(cmd_name, args, parent=ctx,
resilient_parsing=True)
args = ctx.protected_args + ctx.args
else:
# Walk chained subcommand contexts saving the last one.
while args:
cmd_name, cmd, args = ctx.command.resolve_command(ctx, args)
if cmd is None:
return ctx
sub_ctx = cmd.make_context(cmd_name, args, parent=ctx,
allow_extra_args=True,
allow_interspersed_args=False,
resilient_parsing=True)
args = sub_ctx.args
ctx = sub_ctx
args = sub_ctx.protected_args + sub_ctx.args
else:
ctx = ctx.parent
break
return ctx
@ -132,7 +163,7 @@ def is_incomplete_argument(current_params, cmd_param):
return True
if cmd_param.nargs == -1:
return True
if isinstance(current_param_values, collections.Iterable) \
if isinstance(current_param_values, abc.Iterable) \
and cmd_param.nargs > 1 and len(current_param_values) < cmd_param.nargs:
return True
return False
@ -150,7 +181,7 @@ def get_user_autocompletions(ctx, args, incomplete, cmd_param):
if isinstance(cmd_param.type, Choice):
# Choices don't support descriptions.
results = [(c, None)
for c in cmd_param.type.choices if c.startswith(incomplete)]
for c in cmd_param.type.choices if str(c).startswith(incomplete)]
elif cmd_param.autocompletion is not None:
dynamic_completions = cmd_param.autocompletion(ctx=ctx,
args=args,
@ -160,20 +191,32 @@ def get_user_autocompletions(ctx, args, incomplete, cmd_param):
return results
def get_visible_commands_starting_with(ctx, starts_with):
"""
:param ctx: context associated with the parsed command
:starts_with: string that visible commands must start with.
:return: all visible (not hidden) commands that start with starts_with.
"""
for c in ctx.command.list_commands(ctx):
if c.startswith(starts_with):
command = ctx.command.get_command(ctx, c)
if not command.hidden:
yield command
def add_subcommand_completions(ctx, incomplete, completions_out):
# Add subcommand completions.
if isinstance(ctx.command, MultiCommand):
completions_out.extend(
[(c, ctx.command.get_command(ctx, c).get_short_help_str()) for c in ctx.command.list_commands(ctx) if c.startswith(incomplete)])
[(c.name, c.get_short_help_str()) for c in get_visible_commands_starting_with(ctx, incomplete)])
# Walk up the context list and add any other completion possibilities from chained commands
while ctx.parent is not None:
ctx = ctx.parent
if isinstance(ctx.command, MultiCommand) and ctx.command.chain:
remaining_commands = sorted(
set(ctx.command.list_commands(ctx)) - set(ctx.protected_args))
completions_out.extend(
[(c, ctx.command.get_command(ctx, c).get_short_help_str()) for c in remaining_commands if c.startswith(incomplete)])
remaining_commands = [c for c in get_visible_commands_starting_with(ctx, incomplete)
if c.name not in ctx.protected_args]
completions_out.extend([(c.name, c.get_short_help_str()) for c in remaining_commands])
def get_choices(cli, prog_name, args, incomplete):
@ -203,11 +246,10 @@ def get_choices(cli, prog_name, args, incomplete):
if start_of_option(incomplete):
# completions for partial options
for param in ctx.command.params:
if isinstance(param, Option):
if isinstance(param, Option) and not param.hidden:
param_opts = [param_opt for param_opt in param.opts +
param.secondary_opts if param_opt not in all_args or param.multiple]
completions.extend(
[(o, param.help) for o in param_opts if o.startswith(incomplete)])
completions.extend([(o, param.help) for o in param_opts if o.startswith(incomplete)])
return completions
# completion for option values from user supplied values
for param in ctx.command.params:
@ -216,15 +258,11 @@ def get_choices(cli, prog_name, args, incomplete):
# completion for argument values from user supplied values
for param in ctx.command.params:
if is_incomplete_argument(ctx.params, param):
completions.extend(get_user_autocompletions(
ctx, all_args, incomplete, param))
# Stop looking for other completions only if this argument is required.
if param.required:
return completions
break
return get_user_autocompletions(ctx, all_args, incomplete, param)
add_subcommand_completions(ctx, incomplete, completions)
return completions
# Sort before returning so that proper ordering can be enforced in custom types.
return sorted(completions)
def do_complete(cli, prog_name, include_descriptions):

View file

@ -224,9 +224,11 @@ if PY2:
return set_binary_mode(sys.stdin)
def get_binary_stdout():
_wrap_std_stream('stdout')
return set_binary_mode(sys.stdout)
def get_binary_stderr():
_wrap_std_stream('stderr')
return set_binary_mode(sys.stderr)
def get_text_stdin(encoding=None, errors=None):
@ -237,6 +239,7 @@ if PY2:
force_readable=True)
def get_text_stdout(encoding=None, errors=None):
_wrap_std_stream('stdout')
rv = _get_windows_console_stream(sys.stdout, encoding, errors)
if rv is not None:
return rv
@ -244,6 +247,7 @@ if PY2:
force_writable=True)
def get_text_stderr(encoding=None, errors=None):
_wrap_std_stream('stderr')
rv = _get_windows_console_stream(sys.stderr, encoding, errors)
if rv is not None:
return rv
@ -582,7 +586,7 @@ if WIN:
# Windows has a smaller terminal
DEFAULT_COLUMNS = 79
from ._winconsole import _get_windows_console_stream
from ._winconsole import _get_windows_console_stream, _wrap_std_stream
def _get_argv_encoding():
import locale
@ -644,6 +648,7 @@ else:
return getattr(sys.stdin, 'encoding', None) or get_filesystem_encoding()
_get_windows_console_stream = lambda *x: None
_wrap_std_stream = lambda *x: None
def term_len(x):
@ -669,6 +674,7 @@ def _make_cached_stream_func(src_func, wrapper_func):
return rv
rv = wrapper_func()
try:
stream = src_func() # In case wrapper_func() modified the stream
cache[stream] = rv
except Exception:
pass

View file

@ -1,14 +1,16 @@
# -*- coding: utf-8 -*-
"""
click._termui_impl
~~~~~~~~~~~~~~~~~~
click._termui_impl
~~~~~~~~~~~~~~~~~~
This module contains implementations for the termui module. To keep the
import time of Click down, some infrequently used functionality is placed
in this module and only imported as needed.
This module contains implementations for the termui module. To keep the
import time of Click down, some infrequently used functionality is
placed in this module and only imported as needed.
:copyright: (c) 2014 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
:copyright: © 2014 by the Pallets team.
:license: BSD, see LICENSE.rst for more details.
"""
import os
import sys
import time
@ -527,9 +529,11 @@ def open_url(url, wait=False, locate=False):
def _translate_ch_to_exc(ch):
if ch == '\x03':
if ch == u'\x03':
raise KeyboardInterrupt()
if ch == '\x04':
if ch == u'\x04' and not WIN: # Unix-like, Ctrl+D
raise EOFError()
if ch == u'\x1a' and WIN: # Windows, Ctrl+Z
raise EOFError()
@ -541,16 +545,46 @@ if WIN:
yield
def getchar(echo):
rv = msvcrt.getch()
# The function `getch` will return a bytes object corresponding to
# the pressed character. Since Windows 10 build 1803, it will also
# return \x00 when called a second time after pressing a regular key.
#
# `getwch` does not share this probably-bugged behavior. Moreover, it
# returns a Unicode object by default, which is what we want.
#
# Either of these functions will return \x00 or \xe0 to indicate
# a special key, and you need to call the same function again to get
# the "rest" of the code. The fun part is that \u00e0 is
# "latin small letter a with grave", so if you type that on a French
# keyboard, you _also_ get a \xe0.
# E.g., consider the Up arrow. This returns \xe0 and then \x48. The
# resulting Unicode string reads as "a with grave" + "capital H".
# This is indistinguishable from when the user actually types
# "a with grave" and then "capital H".
#
# When \xe0 is returned, we assume it's part of a special-key sequence
# and call `getwch` again, but that means that when the user types
# the \u00e0 character, `getchar` doesn't return until a second
# character is typed.
# The alternative is returning immediately, but that would mess up
# cross-platform handling of arrow keys and others that start with
# \xe0. Another option is using `getch`, but then we can't reliably
# read non-ASCII characters, because return values of `getch` are
# limited to the current 8-bit codepage.
#
# Anyway, Click doesn't claim to do this Right(tm), and using `getwch`
# is doing the right thing in more situations than with `getch`.
if echo:
msvcrt.putchar(rv)
func = msvcrt.getwche
else:
func = msvcrt.getwch
rv = func()
if rv in (u'\x00', u'\xe0'):
# \x00 and \xe0 are control characters that indicate special key,
# see above.
rv += func()
_translate_ch_to_exc(rv)
if PY2:
enc = getattr(sys.stdin, 'encoding', None)
if enc is not None:
rv = rv.decode(enc, 'replace')
else:
rv = rv.decode('cp1252', 'replace')
return rv
else:
import tty
@ -580,7 +614,8 @@ else:
def getchar(echo):
with raw_terminal() as fd:
ch = os.read(fd, 32)
ch = ch.decode(get_best_encoding(sys.stdin), 'replace')
if echo and isatty(sys.stdout):
sys.stdout.write(ch)
_translate_ch_to_exc(ch)
return ch.decode(get_best_encoding(sys.stdin), 'replace')
return ch

View file

@ -43,7 +43,7 @@ def _check_for_unicode_literals():
'because it can introduce subtle bugs in your '
'code. You should instead use explicit u"" literals '
'for your unicode strings. For more information see '
'http://click.pocoo.org/python3/'),
'https://click.palletsprojects.com/python3/'),
stacklevel=bad_frame)
@ -117,7 +117,9 @@ def _verify_python3_env():
'is not supported'
) % bad_locale
raise RuntimeError('Click will abort further execution because Python 3 '
'was configured to use ASCII as encoding for the '
'environment. Consult http://click.pocoo.org/python3/ '
'for mitigation steps.' + extra)
raise RuntimeError(
'Click will abort further execution because Python 3 was'
' configured to use ASCII as encoding for the environment.'
' Consult https://click.palletsprojects.com/en/7.x/python3/ for'
' mitigation steps.' + extra
)

View file

@ -201,6 +201,40 @@ class ConsoleStream(object):
)
class WindowsChunkedWriter(object):
"""
Wraps a stream (such as stdout), acting as a transparent proxy for all
attribute access apart from method 'write()' which we wrap to write in
limited chunks due to a Windows limitation on binary console streams.
"""
def __init__(self, wrapped):
# double-underscore everything to prevent clashes with names of
# attributes on the wrapped stream object.
self.__wrapped = wrapped
def __getattr__(self, name):
return getattr(self.__wrapped, name)
def write(self, text):
total_to_write = len(text)
written = 0
while written < total_to_write:
to_write = min(total_to_write - written, MAX_BYTES_WRITTEN)
self.__wrapped.write(text[written:written+to_write])
written += to_write
_wrapped_std_streams = set()
def _wrap_std_stream(name):
# Python 2 & Windows 7 and below
if PY2 and sys.getwindowsversion()[:2] <= (6, 1) and name not in _wrapped_std_streams:
setattr(sys, name, WindowsChunkedWriter(getattr(sys, name)))
_wrapped_std_streams.add(name)
def _get_text_stdin(buffer_stream):
text_stream = _NonClosingTextIOWrapper(
io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)),
@ -210,14 +244,14 @@ def _get_text_stdin(buffer_stream):
def _get_text_stdout(buffer_stream):
text_stream = _NonClosingTextIOWrapper(
_WindowsConsoleWriter(STDOUT_HANDLE),
io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)),
'utf-16-le', 'strict', line_buffering=True)
return ConsoleStream(text_stream, buffer_stream)
def _get_text_stderr(buffer_stream):
text_stream = _NonClosingTextIOWrapper(
_WindowsConsoleWriter(STDERR_HANDLE),
io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)),
'utf-16-le', 'strict', line_buffering=True)
return ConsoleStream(text_stream, buffer_stream)

View file

@ -7,7 +7,8 @@ from itertools import repeat
from functools import update_wrapper
from .types import convert_type, IntRange, BOOL
from .utils import make_str, make_default_short_help, echo, get_os_args
from .utils import PacifyFlushWrapper, make_str, make_default_short_help, \
echo, get_os_args
from .exceptions import ClickException, UsageError, BadParameter, Abort, \
MissingParameter, Exit
from .termui import prompt, confirm, style
@ -182,7 +183,8 @@ class Context(object):
add some safety mapping on the right.
:param resilient_parsing: if this flag is enabled then Click will
parse without any interactivity or callback
invocation. This is useful for implementing
invocation. Default values will also be
ignored. This is useful for implementing
things such as completion support.
:param allow_extra_args: if this is set to `True` then extra arguments
at the end will not raise an error and will be
@ -312,7 +314,8 @@ class Context(object):
self.token_normalize_func = token_normalize_func
#: Indicates if resilient parsing is enabled. In that case Click
#: will do its best to not cause any failures.
#: will do its best to not cause any failures and default values
#: will be ignored. Useful for completion.
self.resilient_parsing = resilient_parsing
# If there is no envvar prefix yet, but the parent has one and
@ -325,7 +328,7 @@ class Context(object):
auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix,
self.info_name.upper())
else:
self.auto_envvar_prefix = auto_envvar_prefix.upper()
auto_envvar_prefix = auto_envvar_prefix.upper()
self.auto_envvar_prefix = auto_envvar_prefix
if color is None and parent is not None:
@ -732,6 +735,8 @@ class BaseCommand(object):
sys.exit(e.exit_code)
except IOError as e:
if e.errno == errno.EPIPE:
sys.stdout = PacifyFlushWrapper(sys.stdout)
sys.stderr = PacifyFlushWrapper(sys.stderr)
sys.exit(1)
else:
raise
@ -1177,7 +1182,7 @@ class MultiCommand(Command):
# an option we want to kick off parsing again for arguments to
# resolve things like --help which now should go to the main
# place.
if cmd is None:
if cmd is None and not ctx.resilient_parsing:
if split_opt(cmd_name)[0]:
self.parse_args(ctx, ctx.args)
ctx.fail('No such command "%s".' % original_cmd_name)
@ -1351,7 +1356,7 @@ class Parameter(object):
self.is_eager = is_eager
self.metavar = metavar
self.envvar = envvar
self.autocompletion = autocompletion
self.autocompletion = autocompletion
@property
def human_readable_name(self):
@ -1382,7 +1387,6 @@ class Parameter(object):
def add_to_parser(self, parser, ctx):
pass
def consume_value(self, ctx, opts):
value = opts.get(self.name)
if value is None:
@ -1433,7 +1437,7 @@ class Parameter(object):
def full_process_value(self, ctx, value):
value = self.process_value(ctx, value)
if value is None:
if value is None and not ctx.resilient_parsing:
value = self.get_default(ctx)
if self.required and self.value_is_missing(value):
@ -1832,11 +1836,9 @@ class Argument(Parameter):
if len(decls) == 1:
name = arg = decls[0]
name = name.replace('-', '_').lower()
elif len(decls) == 2:
name, arg = decls
else:
raise TypeError('Arguments take exactly one or two '
'parameter declarations, got %d' % len(decls))
raise TypeError('Arguments take exactly one '
'parameter declaration, got %d' % len(decls))
return name, [arg], []
def get_usage_pieces(self, ctx):

View file

@ -1,20 +1,21 @@
# -*- coding: utf-8 -*-
"""
click.parser
~~~~~~~~~~~~
click.parser
~~~~~~~~~~~~
This module started out as largely a copy paste from the stdlib's
optparse module with the features removed that we do not need from
optparse because we implement them in Click on a higher level (for
instance type handling, help formatting and a lot more).
This module started out as largely a copy paste from the stdlib's
optparse module with the features removed that we do not need from
optparse because we implement them in Click on a higher level (for
instance type handling, help formatting and a lot more).
The plan is to remove more and more from here over time.
The plan is to remove more and more from here over time.
The reason this is a different module and not optparse from the stdlib
is that there are differences in 2.x and 3.x about the error messages
generated and optparse in the stdlib uses gettext for no good reason
and might cause us issues.
The reason this is a different module and not optparse from the stdlib
is that there are differences in 2.x and 3.x about the error messages
generated and optparse in the stdlib uses gettext for no good reason
and might cause us issues.
"""
import re
from collections import deque
from .exceptions import UsageError, NoSuchOption, BadOptionUsage, \
@ -321,7 +322,7 @@ class OptionParser(object):
if opt not in self._long_opt:
possibilities = [word for word in self._long_opt
if word.startswith(opt)]
raise NoSuchOption(opt, possibilities=possibilities)
raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx)
option = self._long_opt[opt]
if option.takes_value:
@ -364,7 +365,7 @@ class OptionParser(object):
if self.ignore_unknown_options:
unknown_options.append(ch)
continue
raise NoSuchOption(opt)
raise NoSuchOption(opt, ctx=self.ctx)
if option.takes_value:
# Any characters left in arg? Pretend they're the
# next arg, and stop consuming characters of arg.

View file

@ -524,7 +524,7 @@ def launch(url, wait=False, locate=False):
Examples::
click.launch('http://click.pocoo.org/')
click.launch('https://click.palletsprojects.com/')
click.launch('/my/downloaded/file', locate=True)
.. versionadded:: 2.0
@ -557,6 +557,10 @@ def getchar(echo=False):
Note that this will always read from the terminal, even if something
is piped into the standard input.
Note for Windows: in rare cases when typing non-ASCII characters, this
function might wait for a second character and then return both at once.
This is because certain Unicode characters look like special-key markers.
.. versionadded:: 2.0
:param echo: if set to `True`, the character read will also show up on

View file

@ -1,5 +1,6 @@
import os
import stat
from datetime import datetime
from ._compat import open_stream, text_type, filename_to_ui, \
get_filesystem_encoding, get_streerror, _get_argv_encoding, PY2
@ -182,6 +183,59 @@ class Choice(ParamType):
return 'Choice(%r)' % list(self.choices)
class DateTime(ParamType):
"""The DateTime type converts date strings into `datetime` objects.
The format strings which are checked are configurable, but default to some
common (non-timezone aware) ISO 8601 formats.
When specifying *DateTime* formats, you should only pass a list or a tuple.
Other iterables, like generators, may lead to surprising results.
The format strings are processed using ``datetime.strptime``, and this
consequently defines the format strings which are allowed.
Parsing is tried using each format, in order, and the first format which
parses successfully is used.
:param formats: A list or tuple of date format strings, in the order in
which they should be tried. Defaults to
``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``,
``'%Y-%m-%d %H:%M:%S'``.
"""
name = 'datetime'
def __init__(self, formats=None):
self.formats = formats or [
'%Y-%m-%d',
'%Y-%m-%dT%H:%M:%S',
'%Y-%m-%d %H:%M:%S'
]
def get_metavar(self, param):
return '[{}]'.format('|'.join(self.formats))
def _try_to_convert_date(self, value, format):
try:
return datetime.strptime(value, format)
except ValueError:
return None
def convert(self, value, param, ctx):
# Exact match
for format in self.formats:
dtime = self._try_to_convert_date(value, format)
if dtime:
return dtime
self.fail(
'invalid datetime format: {}. (choose from {})'.format(
value, ', '.join(self.formats)))
def __repr__(self):
return 'DateTime'
class IntParamType(ParamType):
name = 'integer'

View file

@ -414,3 +414,27 @@ def get_app_dir(app_name, roaming=True, force_posix=False):
return os.path.join(
os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')),
_posixify(app_name))
class PacifyFlushWrapper(object):
"""This wrapper is used to catch and suppress BrokenPipeErrors resulting
from ``.flush()`` being called on broken pipe during the shutdown/final-GC
of the Python interpreter. Notably ``.flush()`` is always called on
``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any
other cleanup code, and the case where the underlying file is not a broken
pipe, all calls and attributes are proxied.
"""
def __init__(self, wrapped):
self.wrapped = wrapped
def flush(self):
try:
self.wrapped.flush()
except IOError as e:
import errno
if e.errno != errno.EPIPE:
raise
def __getattr__(self, attr):
return getattr(self.wrapped, attr)

View file

@ -5,7 +5,7 @@ from pallets_sphinx_themes import ProjectLink, get_version
project = "Click"
copyright = "2014 Pallets Team"
author = "Pallets Team"
release, version = get_version("Click")
release, version = get_version("Click", version_length=1)
# General --------------------------------------------------------------
@ -16,9 +16,7 @@ intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)}
# HTML -----------------------------------------------------------------
html_theme = "click"
html_theme_options = {
"index_sidebar_logo": False,
}
html_theme_options = {"index_sidebar_logo": False}
html_context = {
"project_links": [
ProjectLink("Donate to Pallets", "https://palletsprojects.com/donate"),
@ -36,6 +34,7 @@ singlehtml_sidebars = {"index": ["project.html", "versions.html", "localtoc.html
html_static_path = ["_static"]
html_favicon = "_static/click-icon.png"
html_logo = "_static/click-logo-sidebar.png"
html_title = "Click Documentation ({})".format(version)
html_show_sourcelink = False
html_domain_indices = False
html_experimental_html5_writer = True
@ -43,5 +42,5 @@ html_experimental_html5_writer = True
# LaTeX ----------------------------------------------------------------
latex_documents = [
(master_doc, "Click.tex", "Click Documentation", "Pallets Team", "manual")
(master_doc, "Click-{}.tex".format(version), html_title, author, "manual")
]

View file

@ -10,4 +10,5 @@ of the software without written consent.
License Text
------------
.. include:: ../LICENSE
.. include:: ../LICENSE.rst

View file

@ -70,6 +70,9 @@ different behavior and some are supported out of the box:
.. autoclass:: FloatRange
:noindex:
.. autoclass:: DateTime
:noindex:
Custom parameter types can be implemented by subclassing
:class:`click.ParamType`. For simple cases, passing a Python function that
fails with a `ValueError` is also supported, though discouraged.

View file

@ -120,7 +120,7 @@ If you see something like this error in Python 3::
...
RuntimeError: Click will abort further execution because Python 3 was
configured to use ASCII as encoding for the environment. Either switch
to Python 2 or consult http://click.pocoo.org/python3/ for
to Python 2 or consult the Python 3 section of the docs for
mitigation steps.
You are dealing with an environment where Python 3 thinks you are

View file

@ -227,6 +227,12 @@ script can instead be written like this:
def dropdb():
click.echo('Dropped the database')
You would then invoke the :class:`Group` in your setuptools entry points or
other invocations::
if __name__ == '__main__':
cli()
Adding Parameters
-----------------

View file

@ -1,2 +1,2 @@
Sphinx
Pallets-Sphinx-Themes
Sphinx~=1.8.0
Pallets-Sphinx-Themes~=1.1.0

View file

@ -245,8 +245,8 @@ select the provided file.
Example usage::
click.launch('http://click.pocoo.org/')
click.launch('/my/downloaded/file.txt', locate=True)
click.launch("https://click.palletsprojects.com/")
click.launch("/my/downloaded/file.txt", locate=True)
Printing Filenames

View file

@ -59,14 +59,21 @@ This hackery is used on both Python 2 and Python 3 as neither version of
Python has native support for cmd.exe with unicode characters. There are
some limitations you need to be aware of:
* this unicode support is limited to ``click.echo``, ``click.prompt`` as
* This unicode support is limited to ``click.echo``, ``click.prompt`` as
well as ``click.get_text_stream``.
* depending on if unicode values or byte strings are passed the control
* Depending on if unicode values or byte strings are passed the control
flow goes completely different places internally which can have some
odd artifacts if data partially ends up being buffered. Click
attempts to protect against that by manually always flushing but if
you are mixing and matching different string types to ``stdout`` or
``stderr`` you will need to manually flush.
* The raw output stream is set to binary mode, which is a global
operation on Windows, so ``print`` calls will be affected. Prefer
``click.echo`` over ``print``.
* On Windows 7 and below, there is a limitation where at most 64k
characters can be written in one call in binary mode. In this
situation, ``sys.stdout`` and ``sys.stderr`` are replaced with
wrappers that work around the limitation.
Another important thing to note is that the Windows console's default
fonts do not support a lot of characters which means that you are mostly

View file

@ -9,4 +9,4 @@ Click Examples
through the wrong interpreter.
For more information about this see the documentation:
http://click.pocoo.org/setuptools/
https://click.palletsprojects.com/en/7.x/setuptools/

View file

@ -8,6 +8,7 @@ def cli():
def get_env_vars(ctx, args, incomplete):
# Completions returned as strings do not have a description displayed.
for key in os.environ.keys():
if incomplete in key:
yield key
@ -26,11 +27,13 @@ def group():
def list_users(ctx, args, incomplete):
# Here you can generate completions dynamically
users = ['bob', 'alice']
for user in users:
if user.startswith(incomplete):
yield user
# You can generate completions with descriptions by returning
# tuples in the form (completion, description).
users = [('bob', 'butcher'),
('alice', 'baker'),
('jerry', 'candlestick maker')]
# Ths will allow completion matches based on matches within the description string too!
return [user for user in users if incomplete in user[0] or incomplete in user[1]]
@group.command(help='Choose a user')
@ -38,4 +41,5 @@ def list_users(ctx, args, incomplete):
def subcmd(user):
click.echo('Chosen user is %s' % user)
cli.add_command(group)

View file

@ -1,8 +1,25 @@
[bdist_wheel]
universal=1
[metadata]
license_file = LICENSE
license_file = LICENSE.rst
[bdist_wheel]
universal = 1
[tool:pytest]
addopts = -p no:warnings --tb=short
testpaths = tests
[coverage:run]
branch = True
source =
click
tests
[coverage:paths]
source =
click
.tox/*/lib/python*/site-packages/click
.tox/pypy/site-packages/click
[egg_info]
tag_build =
tag_date = 0

View file

@ -1,57 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import io
import re
from setuptools import setup
_version_re = re.compile(r'__version__\s+=\s+(.*)')
with io.open('README.rst', 'rt', encoding='utf8') as f:
with io.open("README.rst", "rt", encoding="utf8") as f:
readme = f.read()
with io.open('click/__init__.py', 'rt', encoding='utf8') as f:
version = re.search(r'__version__ = \'(.*?)\'', f.read()).group(1)
with io.open("click/__init__.py", "rt", encoding="utf8") as f:
version = re.search(r"__version__ = \'(.*?)\'", f.read()).group(1)
setup(
name='click',
name="Click",
version=version,
url='https://palletsprojects.com/p/click/',
author='Armin Ronacher',
author_email='armin.ronacher@active-4.com',
maintainer='Pallets team',
maintainer_email='contact@palletsprojects.com',
long_description=readme,
packages=['click'],
description='A simple wrapper around optparse for '
'powerful command line utilities.',
license='BSD',
extras_require={
'dev': [
'pytest>=3',
'coverage',
'tox',
'sphinx',
],
'docs': [
'sphinx',
'Pallets-Sphinx-Themes',
]
url="https://palletsprojects.com/p/click/",
project_urls={
"Documentation": "https://click.palletsprojects.com/",
"Code": "https://github.com/pallets/click",
"Issue tracker": "https://github.com/pallets/click/issues",
},
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
license="BSD",
author="Armin Ronacher",
author_email="armin.ronacher@active-4.com",
maintainer="Pallets Team",
maintainer_email="contact@palletsprojects.com",
description="Composable command line interface toolkit",
long_description=readme,
packages=["click"],
include_package_data=True,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
)

View file

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import pytest
import click
from click._compat import PY2
@ -287,3 +288,11 @@ def test_defaults_for_nargs(runner):
result = runner.invoke(cmd, ['3'])
assert result.exception is not None
assert 'argument a takes 2 values' in result.output
def test_multiple_param_decls_not_allowed(runner):
with pytest.raises(TypeError):
@click.command()
@click.argument('x', click.Choice(['a', 'b']))
def copy(x):
click.echo(x)

View file

@ -132,7 +132,8 @@ def test_long_chain():
def test_chaining():
@click.group('cli', chain=True)
@click.option('--cli-opt')
def cli(cli_opt):
@click.argument('arg', type=click.Choice(['cliarg1', 'cliarg2']))
def cli(cli_opt, arg):
pass
@cli.command()
@ -142,33 +143,35 @@ def test_chaining():
@cli.command(help='bsub help')
@click.option('--bsub-opt')
@click.argument('arg', type=click.Choice(['arg1', 'arg2']), required=True)
@click.argument('arg', type=click.Choice(['arg1', 'arg2']))
def bsub(bsub_opt, arg):
pass
@cli.command()
@click.option('--csub-opt')
@click.argument('arg', type=click.Choice(['carg1', 'carg2']), required=False)
@click.argument('arg', type=click.Choice(['carg1', 'carg2']), default='carg1')
def csub(csub_opt, arg):
pass
assert choices_without_help(cli, [], '-') == ['--cli-opt']
assert choices_without_help(cli, [], '') == ['asub', 'bsub', 'csub']
assert choices_without_help(cli, ['asub'], '-') == ['--asub-opt']
assert choices_without_help(cli, ['asub'], '') == ['bsub', 'csub']
assert choices_without_help(cli, ['bsub'], '') == ['arg1', 'arg2']
assert choices_without_help(cli, ['asub', '--asub-opt'], '') == []
assert choices_without_help(cli, ['asub', '--asub-opt', '5', 'bsub'], '-') == ['--bsub-opt']
assert choices_without_help(cli, ['asub', 'bsub'], '-') == ['--bsub-opt']
assert choices_with_help(cli, ['asub'], 'b') == [('bsub', 'bsub help')]
assert choices_without_help(cli, ['asub', 'csub'], '-') == ['--csub-opt']
assert choices_without_help(cli, [], '') == ['cliarg1', 'cliarg2']
assert choices_without_help(cli, ['cliarg1', 'asub'], '-') == ['--asub-opt']
assert choices_without_help(cli, ['cliarg1', 'asub'], '') == ['bsub', 'csub']
assert choices_without_help(cli, ['cliarg1', 'bsub'], '') == ['arg1', 'arg2']
assert choices_without_help(cli, ['cliarg1', 'asub', '--asub-opt'], '') == []
assert choices_without_help(cli, ['cliarg1', 'asub', '--asub-opt', '5', 'bsub'], '-') == ['--bsub-opt']
assert choices_without_help(cli, ['cliarg1', 'asub', 'bsub'], '-') == ['--bsub-opt']
assert choices_without_help(cli, ['cliarg1', 'asub', 'csub'], '') == ['carg1', 'carg2']
assert choices_without_help(cli, ['cliarg1', 'bsub', 'arg1', 'csub'], '') == ['carg1', 'carg2']
assert choices_without_help(cli, ['cliarg1', 'asub', 'csub'], '-') == ['--csub-opt']
assert choices_with_help(cli, ['cliarg1', 'asub'], 'b') == [('bsub', 'bsub help')]
def test_argument_choice():
@click.command()
@click.argument('arg1', required=False, type=click.Choice(['arg11', 'arg12']))
@click.argument('arg2', required=False, type=click.Choice(['arg21', 'arg22']))
@click.argument('arg3', required=False, type=click.Choice(['arg', 'argument']))
@click.argument('arg1', required=True, type=click.Choice(['arg11', 'arg12']))
@click.argument('arg2', type=click.Choice(['arg21', 'arg22']), default='arg21')
@click.argument('arg3', type=click.Choice(['arg', 'argument']), default='arg')
def cli():
pass
@ -182,7 +185,7 @@ def test_argument_choice():
def test_option_choice():
@click.command()
@click.option('--opt1', type=click.Choice(['opt11', 'opt12']), help='opt1 help')
@click.option('--opt2', type=click.Choice(['opt21', 'opt22']))
@click.option('--opt2', type=click.Choice(['opt21', 'opt22']), default='opt21')
@click.option('--opt3', type=click.Choice(['opt', 'option']))
def cli():
pass
@ -218,6 +221,8 @@ def test_option_and_arg_choice():
assert choices_without_help(cli, [''], '--opt1=') == ['opt11', 'opt12']
assert choices_without_help(cli, [], '') == ['arg11', 'arg12']
assert choices_without_help(cli, ['--opt2'], '') == ['opt21', 'opt22']
assert choices_without_help(cli, ['arg11'], '--opt') == ['--opt1', '--opt2']
assert choices_without_help(cli, [], '--opt') == ['--opt1', '--opt2']
def test_boolean_flag_choice():
@ -258,11 +263,37 @@ def test_multi_option_choice():
def test_variadic_argument_choice():
@click.command()
@click.option('--opt', type=click.Choice(['opt1', 'opt2']))
@click.argument('src', nargs=-1, type=click.Choice(['src1', 'src2']))
def cli(local_opt):
pass
assert choices_without_help(cli, ['src1', 'src2'], '') == ['src1', 'src2']
assert choices_without_help(cli, ['src1', 'src2'], '--o') == ['--opt']
assert choices_without_help(cli, ['src1', 'src2', '--opt'], '') == ['opt1', 'opt2']
assert choices_without_help(cli, ['src1', 'src2'], '') == ['src1', 'src2']
def test_variadic_argument_complete():
def _complete(ctx, args, incomplete):
return ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz']
@click.group()
def entrypoint():
pass
@click.command()
@click.option('--opt', autocompletion=_complete)
@click.argument('arg', nargs=-1)
def subcommand(opt, arg):
pass
entrypoint.add_command(subcommand)
assert choices_without_help(entrypoint, ['subcommand', '--opt'], '') == _complete(0,0,0)
assert choices_without_help(entrypoint, ['subcommand', 'whatever', '--opt'], '') == _complete(0,0,0)
assert choices_without_help(entrypoint, ['subcommand', 'whatever', '--opt', 'abc'], '') == []
def test_long_chain_choice():
@ -273,7 +304,7 @@ def test_long_chain_choice():
@cli.group()
@click.option('--sub-opt', type=click.Choice(['subopt1', 'subopt2']))
@click.argument('sub-arg', required=False, type=click.Choice(['subarg1', 'subarg2']))
def sub(sub_opt):
def sub(sub_opt, sub_arg):
pass
@sub.command(short_help='bsub help')
@ -283,15 +314,96 @@ def test_long_chain_choice():
def bsub(bsub_opt):
pass
assert choices_with_help(cli, ['sub'], '') == [('subarg1', None), ('subarg2', None), ('bsub', 'bsub help')]
@sub.group('csub')
def csub():
pass
@csub.command()
def dsub():
pass
assert choices_with_help(cli, ['sub', 'subarg1'], '') == [('bsub', 'bsub help'), ('csub', '')]
assert choices_without_help(cli, ['sub'], '') == ['subarg1', 'subarg2']
assert choices_without_help(cli, ['sub', '--sub-opt'], '') == ['subopt1', 'subopt2']
assert choices_without_help(cli, ['sub', '--sub-opt', 'subopt1'], '') == \
['subarg1', 'subarg2', 'bsub']
['subarg1', 'subarg2']
assert choices_without_help(cli,
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub'], '-') == ['--bsub-opt']
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub'], '-') == ['--bsub-opt']
assert choices_without_help(cli,
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt'], '') == \
['bsubopt1', 'bsubopt2']
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub'], '') == ['bsubarg1', 'bsubarg2']
assert choices_without_help(cli,
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt', 'bsubopt1', 'bsubarg1'],
'') == ['bbsubarg1', 'bbsubarg2']
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt'], '') == \
['bsubopt1', 'bsubopt2']
assert choices_without_help(cli,
['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt', 'bsubopt1', 'bsubarg1'],
'') == ['bbsubarg1', 'bbsubarg2']
assert choices_without_help(cli,
['sub', '--sub-opt', 'subopt1', 'subarg1', 'csub'],
'') == ['dsub']
def test_chained_multi():
@click.group()
def cli():
pass
@cli.group()
def sub():
pass
@sub.group()
def bsub():
pass
@sub.group(chain=True)
def csub():
pass
@csub.command()
def dsub():
pass
@csub.command()
def esub():
pass
assert choices_without_help(cli, ['sub'], '') == ['bsub', 'csub']
assert choices_without_help(cli, ['sub'], 'c') == ['csub']
assert choices_without_help(cli, ['sub', 'csub'], '') == ['dsub', 'esub']
assert choices_without_help(cli, ['sub', 'csub', 'dsub'], '') == ['esub']
def test_hidden():
@click.group()
@click.option('--name', hidden=True)
@click.option('--choices', type=click.Choice([1, 2]), hidden=True)
def cli(name):
pass
@cli.group(hidden=True)
def hgroup():
pass
@hgroup.group()
def hgroupsub():
pass
@cli.command()
def asub():
pass
@cli.command(hidden=True)
@click.option('--hname')
def hsub():
pass
assert choices_without_help(cli, [], '--n') == []
assert choices_without_help(cli, [], '--c') == []
# If the user exactly types out the hidden param, complete its options.
assert choices_without_help(cli, ['--choices'], '') == [1, 2]
assert choices_without_help(cli, [], '') == ['asub']
assert choices_without_help(cli, [], '') == ['asub']
assert choices_without_help(cli, [], 'h') == []
# If the user exactly types out the hidden command, complete its subcommands.
assert choices_without_help(cli, ['hgroup'], '') == ['hgroupsub']
assert choices_without_help(cli, ['hsub'], '--h') == ['--hname']

View file

@ -332,6 +332,44 @@ def test_choice_option(runner):
assert '--method [foo|bar|baz]' in result.output
def test_datetime_option_default(runner):
@click.command()
@click.option('--start_date', type=click.DateTime())
def cli(start_date):
click.echo(start_date.strftime('%Y-%m-%dT%H:%M:%S'))
result = runner.invoke(cli, ['--start_date=2015-09-29'])
assert not result.exception
assert result.output == '2015-09-29T00:00:00\n'
result = runner.invoke(cli, ['--start_date=2015-09-29T09:11:22'])
assert not result.exception
assert result.output == '2015-09-29T09:11:22\n'
result = runner.invoke(cli, ['--start_date=2015-09'])
assert result.exit_code == 2
assert ('Invalid value for "--start_date": '
'invalid datetime format: 2015-09. '
'(choose from %Y-%m-%d, %Y-%m-%dT%H:%M:%S, %Y-%m-%d %H:%M:%S)'
) in result.output
result = runner.invoke(cli, ['--help'])
assert '--start_date [%Y-%m-%d|%Y-%m-%dT%H:%M:%S|%Y-%m-%d %H:%M:%S]' in result.output
def test_datetime_option_custom(runner):
@click.command()
@click.option('--start_date',
type=click.DateTime(formats=['%A %B %d, %Y']))
def cli(start_date):
click.echo(start_date.strftime('%Y-%m-%dT%H:%M:%S'))
result = runner.invoke(cli, ['--start_date=Wednesday June 05, 2010'])
assert not result.exception
assert result.output == '2010-06-05T00:00:00\n'
def test_int_range_option(runner):
@click.command()
@click.option('--x', type=click.IntRange(0, 5))

View file

@ -32,7 +32,7 @@ click.echo(json.dumps(rv))
ALLOWED_IMPORTS = set([
'weakref', 'os', 'struct', 'collections', 'sys', 'contextlib',
'functools', 'stat', 're', 'codecs', 'inspect', 'itertools', 'io',
'threading', 'colorama', 'errno', 'fcntl'
'threading', 'colorama', 'errno', 'fcntl', 'datetime'
])
if WIN:

View file

@ -202,6 +202,19 @@ def test_dynamic_default_help_text(runner):
assert 'lambda' not in result.output
assert '(current user)' in result.output
def test_toupper_envvar_prefix(runner):
@click.command()
@click.option('--arg')
def cmd(arg):
click.echo(arg)
result = runner.invoke(cmd, [], auto_envvar_prefix='test',
env={'TEST_ARG': 'foo'})
assert not result.exception
assert result.output == 'foo\n'
def test_nargs_envvar(runner):
@click.command()
@click.option('--arg', nargs=2)

12
tox.ini
View file

@ -1,5 +1,9 @@
[tox]
envlist = py{36,35,34,27,py}
envlist =
py{37,36,35,34,27,py3,py}
docs-html
coverage-report
skip_missing_interpreters = true
[testenv]
passenv = LANG
@ -7,14 +11,14 @@ deps =
pytest
coverage
colorama
commands = coverage run -p -m pytest {posargs:tests}
commands = coverage run -p -m pytest {posargs}
[testenv:docs-html]
deps = sphinx
deps = -r docs/requirements.txt
commands = sphinx-build -W -b html -d {envtmpdir}/doctrees docs {envtmpdir}/html
[testenv:docs-linkcheck]
deps = sphinx
deps = -r docs/requirements.txt
commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees docs {envtmpdir}/linkcheck
[testenv:coverage-report]