New upstream version 7.0
This commit is contained in:
parent
5dd28971f0
commit
0143a0a452
|
@ -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'
|
|
@ -1,3 +0,0 @@
|
|||
[run]
|
||||
branch = true
|
||||
source = click,tests
|
15
.gitignore
vendored
15
.gitignore
vendored
|
@ -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
|
56
.travis.yml
56
.travis.yml
|
@ -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
|
461
CHANGES.rst
461
CHANGES.rst
|
@ -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
|
||||
-----------
|
||||
|
||||
|
|
|
@ -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
119
Click.egg-info/PKG-INFO
Normal 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
115
Click.egg-info/SOURCES.txt
Normal 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
|
1
Click.egg-info/dependency_links.txt
Normal file
1
Click.egg-info/dependency_links.txt
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
Click.egg-info/top_level.txt
Normal file
1
Click.egg-info/top_level.txt
Normal file
|
@ -0,0 +1 @@
|
|||
click
|
38
LICENSE
38
LICENSE
|
@ -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
39
LICENSE.rst
Normal 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.
|
12
MANIFEST.in
12
MANIFEST.in
|
@ -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
|
||||
|
|
11
Makefile
11
Makefile
|
@ -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
119
PKG-INFO
Normal 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.*
|
34
README.rst
34
README.rst
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
]
|
||||
|
|
|
@ -10,4 +10,5 @@ of the software without written consent.
|
|||
License Text
|
||||
------------
|
||||
|
||||
.. include:: ../LICENSE
|
||||
.. include:: ../LICENSE.rst
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
Sphinx
|
||||
Pallets-Sphinx-Themes
|
||||
Sphinx~=1.8.0
|
||||
Pallets-Sphinx-Themes~=1.1.0
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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)
|
||||
|
|
27
setup.cfg
27
setup.cfg
|
@ -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
|
||||
|
||||
|
|
77
setup.py
77
setup.py
|
@ -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",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
12
tox.ini
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue