diff --git a/CHANGES.rst b/CHANGES.rst index 2daed5645..140eb9d98 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,224 +1,200 @@ Click Changelog =============== -This contains all major version changes between Click releases. Version 7.0 ----------- -(upcoming release with new features, release date to be decided) - -- 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`_) -- 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. (`#866`_)(`#869`_) -- Added support for bash completion of type=click.Choice for Options and - Arguments. (`#535`_) -- Fix bug that caused bashcompletion to give improper completions on - chained commands. (`#774`_) -- Fix completion of subcommand options after last argument (`#919`_) -- Fix incorrect completions when defaults are present (`#925`_) -- 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`_). -- Add support for bright colors. -- 't' and 'f' are now converted to True and False. -- 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. +Unreleased + +- Drop support for Python 2.6 and 3.3. (`#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`_) +- ``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`_) +- Added ``FloatRange`` type. (`#538`_, `#553`_) +- Added support for bash completion of ``type=click.Choice`` for ``Options`` and ``Arguments``. (`#535`_) +- Add ``case_sensitive=False`` as an option to Choice. (`#569`_) +- ``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`_) +- ``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_unkown_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`_) +- 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`_, `#790`_, `#806`_) +- Added support for dynamic bash completion from a user-supplied callback. (`#755`_) +- Added support for bash completions containing spaces. (`#773`_) +- Fix option naming routine to match documentation. (`#793`_) +- Use deterministic option name; can't rely on list sort. (`#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`_) +- Add bool conversion for "t" and "f". (`#842`_) +- 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`_) +- Allow autocompletion function to determine whether or not to return completions that start with the incomplete argument. (`#869`_) +- 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`_) +- ``_AtomicFile`` now uses the ``realpath`` of the original filename so that chaning the working directory does not affect it. (`#920`_) +- 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 completion of subcommand options after last argument (`#919`_) +- Fix incorrect completions when defaults are present (`#925`_) +- 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_envar_prefix`` works with command groups. (`#1011`_) +- Don't add newlines by default for progress bars. (`#1013`_) +- Document that parameter names are lowercased 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. -.. _#866: https://github.com/pallets/click/issues/866 -.. _#919: https://github.com/pallets/click/issues/919 -.. _#925: https://github.com/pallets/click/issues/925 -.. _#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 -.. _#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 +.. _#424: https://github.com/pallets/click/pull/424 +.. _#447: https://github.com/pallets/click/issues/447 .. _#487: https://github.com/pallets/click/pull/487 -.. _#999: https://github.com/pallets/click/pull/999 +.. _#500: https://github.com/pallets/click/pull/500 +.. _#514: https://github.com/pallets/click/issues/514 +.. _#533: https://github.com/pallets/click/issues/533 +.. _#535: https://github.com/pallets/click/pull/535 +.. _#538: https://github.com/pallets/click/pull/538 +.. _#553: https://github.com/pallets/click/pull/553 +.. _#557: https://github.com/pallets/click/pull/557 +.. _#569: https://github.com/pallets/click/pull/569 +.. _#598: https://github.com/pallets/click/issues/598 +.. _#612: https://github.com/pallets/click/pull/612 .. _#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 +.. _#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/pull/667 +.. _#675: https://github.com/pallets/click/pull/675 +.. _#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 +.. _#719: https://github.com/pallets/click/issues/719 +.. _#725: https://github.com/pallets/click/issues/725 +.. _#728: https://github.com/pallets/click/issues/728 +.. _#739: https://github.com/pallets/click/issues/739 +.. _#741: https://github.com/pallets/click/issues/741 +.. _#744: https://github.com/pallets/click/issues/744 +.. _#754: https://github.com/pallets/click/pull/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/pull/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 -.. _#868: https://github.com/pallets/click/pull/868 -.. _#889: https://github.com/pallets/click/pull/889 -.. _#409: https://github.com/pallets/click/issues/409 +.. _#842: https://github.com/pallets/click/pull/842 +.. _#862: https://github.com/pallets/click/pull/862 .. _#863: https://github.com/pallets/click/pull/863 -.. _#962: https://github.com/pallets/click/pull/962 -.. _#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 +.. _#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 -.. _#990: https://github.com/pallets/click/pull/990 -.. _#684: https://github.com/pallets/click/pull/684 +.. _#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/issues/880 -.. _#877: https://github.com/pallets/click/pull/877 +.. _#883: https://github.com/pallets/click/pull/883 +.. _#887: https://github.com/pallets/click/pull/887 +.. _#889: https://github.com/pallets/click/pull/889 .. _#918: https://github.com/pallets/click/pull/918 -.. _#929: https://github.com/pallets/click/pull/929 +.. _#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 .. _#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 - -Version 6.8 ------------ - -(bugfix release; yet to be released) +.. _#949: https://github.com/pallets/click/issues/949 +.. _#954: https://github.com/pallets/click/issues/954 +.. _#962: https://github.com/pallets/click/pull/962 +.. _#965: https://github.com/pallets/click/pull/965 +.. _#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 +.. _#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 +.. _#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 +.. _#1055: https://github.com/pallets/click/pull/1055 -- 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 ----------- (bugfix release; released on January 6th 2017) -- Make `click.progressbar` work with `codecs.open` files. See #637. +- Make ``click.progressbar`` work with ``codecs.open`` files. See #637. - Fix bug in bash completion with nested subcommands. See #639. - Fix test runner not saving caller env correctly. See #644. - Fix handling of SIGPIPE. See #626 @@ -229,7 +205,7 @@ Version 6.6 (bugfix release; released on April 4th 2016) -- Fix bug in `click.Path` where it would crash when passed a `-`. See #551. +- Fix bug in ``click.Path`` where it would crash when passed a ``-``. See #551. Version 6.4 ----------- @@ -244,7 +220,7 @@ Version 6.3 (bugfix release; released on February 22 2016) -- Fix argument checks for interpreter invoke with `-m` and `-c` +- Fix argument checks for interpreter invoke with ``-m`` and ``-c`` on Windows. - Fixed a bug that cased locale detection to error out on Python 3. @@ -262,7 +238,7 @@ Version 6.1 - Resolved an issue with invisible progress bars no longer rendering. - Disable chain commands with subcommands as they were inherently broken. -- Fix `MissingParameter` not working without parameters passed. +- Fix ``MissingParameter`` not working without parameters passed. Version 6.0 ----------- @@ -271,7 +247,7 @@ Version 6.0 - Optimized the progressbar rendering to not render when it did not actually change. -- Explicitly disallow nargs=-1 with a set default. +- Explicitly disallow ``nargs=-1`` with a set default. - The context is now closed before it's popped from the stack. - Added support for short aliases for the false flag on toggles. - Click will now attempt to aid you with debugging locale errors @@ -283,17 +259,17 @@ Version 6.0 - For Windows users on Python 2, Click will now handle Unicode more correctly handle Unicode coming in from the system. This also has the disappointing side effect that filenames will now be always - unicode by default in the `Path` type which means that this can + unicode by default in the ``Path`` type which means that this can introduce small bugs for code not aware of this. -- Added a `type` parameter to `Path` to force a specific string type +- Added a ``type`` parameter to ``Path`` to force a specific string type on the value. -- For users running Python on Windows the `echo`) and `prompt` functions +- For users running Python on Windows the ``echo`` and ``prompt`` functions now work with full unicode functionality in the Python windows console by emulating an output stream. This also applies to getting the - virtual output and input streams via `click.get_text_stream(...)`. + virtual output and input streams via ``click.get_text_stream(...)``. - Unittests now always force a certain virtual terminal width. - Added support for allowing dashes to indicate standard streams to the - `Path` type. + ``Path`` type. - Multi commands in chain mode no longer propagate arguments left over from parsing to the callbacks. It's also now disallowed through an exception when optional arguments are attached to multi commands if chain @@ -309,7 +285,7 @@ Version 5.1 (bugfix release, released on 17th August 2015) -- Fix a bug in `pass_obj` that would accidentally pass the context too. +- Fix a bug in ``pass_obj`` that would accidentally pass the context too. Version 5.0 ----------- @@ -317,35 +293,35 @@ Version 5.0 (codename "tok tok", released on 16th August 2015) - Removed various deprecated functionality. -- Atomic files now only accept the `w` mode. +- Atomic files now only accept the ``w`` mode. - Change the usage part of help output for very long commands to wrap their arguments onto the next line, indented by 4 spaces. - Fix a bug where return code and error messages were incorrect when using ``CliRunner``. -- added `get_current_context`. -- added a `meta` dictionary to the context which is shared across the +- added ``get_current_context``. +- added a ``meta`` dictionary to the context which is shared across the linked list of contexts to allow click utilities to place state there. -- introduced `Context.scope`. -- The `echo` function is now threadsafe: It calls the `write` method of the +- introduced ``Context.scope``. +- The ``echo`` function is now threadsafe: It calls the ``write`` method of the underlying object only once. -- `prompt(hide_input=True)` now prints a newline on `^C`. +- ``prompt(hide_input=True)`` now prints a newline on ``^C``. - Click will now warn if users are using ``unicode_literals``. - Click will now ignore the ``PAGER`` environment variable if it is empty or contains only whitespace. -- The `click-contrib` GitHub organization was created. +- The ``click-contrib`` GitHub organization was created. Version 4.1 ----------- (bugfix release, released on July 14th 2015) -- Fix a bug where error messages would include a trailing `None` string. +- Fix a bug where error messages would include a trailing ``None`` string. - Fix a bug where Click would crash on docstrings with trailing newlines. -- Support streams with encoding set to `None` on Python 3 by barfing with +- Support streams with encoding set to ``None`` on Python 3 by barfing with a better error. - Handle ^C in less-pager properly. -- Handle return value of `None` from `sys.getfilesystemencoding` -- Fix crash when writing to unicode files with `click.echo`. +- Handle return value of ``None`` from ``sys.getfilesystemencoding`` +- Fix crash when writing to unicode files with ``click.echo``. - Fix type inference with multiple options. Version 4.0 @@ -353,22 +329,22 @@ Version 4.0 (codename "zoom zoom", released on March 31st 2015) -- Added `color` parameters to lots of interfaces that directly or indirectly +- Added ``color`` parameters to lots of interfaces that directly or indirectly call into echoing. This previously was always autodetection (with the - exception of the `echo_via_pager` function). Now you can forcefully + exception of the ``echo_via_pager`` function). Now you can forcefully enable or disable it, overriding the auto detection of Click. -- Added an `UNPROCESSED` type which does not perform any type changes which +- Added an ``UNPROCESSED`` type which does not perform any type changes which simplifies text handling on 2.x / 3.x in some special advanced usecases. -- Added `NoSuchOption` and `BadOptionUsage` exceptions for more generic +- Added ``NoSuchOption`` and ``BadOptionUsage`` exceptions for more generic handling of errors. - Added support for handling of unprocessed options which can be useful in situations where arguments are forwarded to underlying tools. -- Added `max_content_width` parameter to the context which can be used to +- Added ``max_content_width`` parameter to the context which can be used to change the maximum width of help output. By default Click will not format content for more than 80 characters width. - Added support for writing prompts to stderr. - Fix a bug when showing the default for multiple arguments. -- Added support for custom subclasses to `option` and `argument`. +- Added support for custom subclasses to ``option`` and ``argument``. - Fix bug in ``clear()`` on Windows when colorama is installed. - Reject ``nargs=-1`` for options properly. Options cannot be variadic. - Fixed an issue with bash completion not working properly for commands with @@ -392,7 +368,7 @@ Version 3.2 (bugfix release, released on August 22nd 2014) -- Added missing `err` parameter forwarding to the `secho` function. +- Added missing ``err`` parameter forwarding to the ``secho`` function. - Fixed default parameters not being handled properly by the context invoke method. This is a backwards incompatible change if the function was used improperly. See :ref:`upgrade-to-3.2` for more information. @@ -431,18 +407,18 @@ Version 3.0 created arguments instead of options. - Restructured Click internally to support vendoring. - Added support for multi command chaining. -- Added support for defaults on options with `multiple` and - options and arguments with `nargs != 1`. -- label passed to `progressbar` is no longer rendered with +- Added support for defaults on options with ``multiple`` and + options and arguments with ``nargs != 1``. +- label passed to ``progressbar`` is no longer rendered with whitespace stripped. -- added a way to disable the standalone mode of the `main` +- added a way to disable the standalone mode of the ``main`` method on a Click command to be able to handle errors better. - added support for returning values from command callbacks. -- added simplifications for printing to stderr from `echo`. +- added simplifications for printing to stderr from ``echo``. - added result callbacks for groups. - entering a context multiple times defers the cleanup until the last exit occurs. -- added `open_file`. +- added ``open_file``. Version 2.6 ----------- @@ -471,7 +447,7 @@ Version 2.3 (bugfix release, released on July 3rd 2014) -- Fixed an incorrectly formatted help record for count options.' +- Fixed an incorrectly formatted help record for count options. - Add support for ansi code stripping on Windows if colorama is not available. - restored the Click 1.0 handling of the help parameter for certain @@ -517,7 +493,7 @@ Version 2.0 - added :func:`get_app_dir`; a function to calculate the home folder for configs. - Added transparent handling for ANSI codes into the :func:`echo` - function through `colorama`. + function through ``colorama``. - Added :func:`clear` function. - Breaking change: parameter callbacks now get the parameter object passed as second argument. There is legacy support for old callbacks diff --git a/README.rst b/README.rst index c05c9d754..b6dd4b1e9 100644 --- a/README.rst +++ b/README.rst @@ -1,22 +1,20 @@ \$ click\_ ========== -What's 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. +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 + +- arbitrary nesting of commands +- automatic help page generation +- supports lazy loading of subcommands at runtime Installing @@ -28,7 +26,10 @@ Install and update using `pip`_: $ pip install click -Click supports Python 3.4 and newer, Python 2.7, and PyPy +Click supports Python 3.4 and newer, Python 2.7, and PyPy. + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + A Simple Example ---------------- @@ -61,6 +62,7 @@ And what it looks like when run: Hello John! Hello John! + Donate ------ @@ -69,23 +71,21 @@ it uses. 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://psfmember.org/civicrm/contribute/transact?reset=1&id=20 +.. _please donate today: https://palletsprojects.com/donate Links ----- -* Website: https://www.palletsprojects.com/p/click/ -* Documentation: http://click.pocoo.org/ -* License: `BSD `_ -* Releases: https://pypi.org/project/click/ -* Code: https://github.com/pallets/click -* Issue tracker: https://github.com/pallets/click/issues -* Test status: +* Website: https://palletsprojects.com/p/click/ +* Documentation: https://click.palletsprojects.com/ +* License: `BSD `_ +* 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 + * Linux, Mac: https://travis-ci.org/pallets/click + * Windows: https://ci.appveyor.com/project/pallets/click -* Test coverage: https://codecov.io/gh/pallets/click - -.. _pip: https://pip.pypa.io/en/stable/quickstart/ +* Test coverage: https://codecov.io/gh/pallets/click diff --git a/click/_bashcomplete.py b/click/_bashcomplete.py index 695f379fb..222727894 100644 --- a/click/_bashcomplete.py +++ b/click/_bashcomplete.py @@ -72,7 +72,7 @@ def resolve_ctx(cli, prog_name, args): :param args: full list of args :return: the final context/command parsed """ - ctx = cli.make_context(prog_name, args, resilient_parsing=True, ignore_default_values=True) + ctx = cli.make_context(prog_name, args, resilient_parsing=True) args = ctx.protected_args + ctx.args while args: if isinstance(ctx.command, MultiCommand): @@ -81,8 +81,7 @@ def resolve_ctx(cli, prog_name, args): if cmd is None: return ctx ctx = cmd.make_context(cmd_name, args, parent=ctx, - resilient_parsing=True, - ignore_default_values=True) + resilient_parsing=True) args = ctx.protected_args + ctx.args else: # Walk chained subcommand contexts saving the last one. @@ -93,8 +92,7 @@ def resolve_ctx(cli, prog_name, args): sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, allow_extra_args=True, allow_interspersed_args=False, - resilient_parsing=True, - ignore_default_values=True) + resilient_parsing=True) args = sub_ctx.args ctx = sub_ctx args = sub_ctx.protected_args + sub_ctx.args diff --git a/click/_winconsole.py b/click/_winconsole.py index f1d5e28ca..f4d95ddc1 100644 --- a/click/_winconsole.py +++ b/click/_winconsole.py @@ -15,7 +15,7 @@ import time import ctypes import msvcrt -from click._compat import _NonClosingTextIOWrapper, text_type, PY2 +from ._compat import _NonClosingTextIOWrapper, text_type, PY2 from ctypes import byref, POINTER, c_int, c_char, c_char_p, \ c_void_p, py_object, c_ssize_t, c_ulong, windll, WINFUNCTYPE try: diff --git a/click/core.py b/click/core.py index 03395adf1..cc8fd4663 100644 --- a/click/core.py +++ b/click/core.py @@ -9,7 +9,7 @@ from .types import convert_type, IntRange, BOOL from .utils import make_str, make_default_short_help, echo, get_os_args from .exceptions import ClickException, UsageError, BadParameter, Abort, \ - MissingParameter + MissingParameter, Exit from .termui import prompt, confirm, style from .formatting import HelpFormatter, join_options from .parser import OptionParser, split_opt @@ -182,7 +182,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 @@ -214,7 +215,7 @@ def __init__(self, command, parent=None, info_name=None, obj=None, resilient_parsing=False, allow_extra_args=None, allow_interspersed_args=None, ignore_unknown_options=None, help_option_names=None, - token_normalize_func=None, color=None, ignore_default_values=False): + token_normalize_func=None, color=None): #: the parent context or `None` if none exists. self.parent = parent #: the :class:`Command` for this context. @@ -312,15 +313,10 @@ def __init__(self, command, parent=None, info_name=None, obj=None, 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 - #: Indicates that default values should be ignored. - #: Useful for completion. - - #: .. versionadded:: 7.0 - self.ignore_default_values = ignore_default_values - # If there is no envvar prefix yet, but the parent has one and # the command on this level has a name, we can expand the envvar # prefix automatically. @@ -504,7 +500,7 @@ def abort(self): def exit(self, code=0): """Exits the application with a given exit code.""" - sys.exit(code) + raise Exit(code) def get_usage(self): """Helper method to get formatted usage string for the current @@ -720,6 +716,13 @@ def main(self, args=None, prog_name=None, complete_var=None, rv = self.invoke(ctx) if not standalone_mode: return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness ctx.exit() except (EOFError, KeyboardInterrupt): echo(file=sys.stderr) @@ -734,6 +737,19 @@ def main(self, args=None, prog_name=None, complete_var=None, sys.exit(1) else: raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code except Abort: if not standalone_mode: raise @@ -784,6 +800,10 @@ def __init__(self, name, context_settings=None, callback=None, #: should show up in the help page and execute. Eager parameters #: will automatically be handled before non eager ones. self.params = params or [] + # if a form feed (page break) is found in the help text, truncate help + # text to the content preceding the first form feed + if help and '\f' in help: + help = help.split('\f', 1)[0] self.help = help self.epilog = epilog self.options_metavar = options_metavar @@ -1415,7 +1435,7 @@ def value_is_missing(self, value): def full_process_value(self, ctx, value): value = self.process_value(ctx, value) - if value is None and not ctx.ignore_default_values: + if value is None and not ctx.resilient_parsing: value = self.get_default(ctx) if self.required and self.value_is_missing(value): diff --git a/click/decorators.py b/click/decorators.py index bfc7a058a..c57c53086 100644 --- a/click/decorators.py +++ b/click/decorators.py @@ -61,7 +61,7 @@ def new_func(*args, **kwargs): raise RuntimeError('Managed to invoke callback without a ' 'context object of type %r existing' % object_type.__name__) - return ctx.invoke(f, obj, *args[1:], **kwargs) + return ctx.invoke(f, obj, *args, **kwargs) return update_wrapper(new_func, f) return decorator diff --git a/click/exceptions.py b/click/exceptions.py index b5641343d..6fa17658c 100644 --- a/click/exceptions.py +++ b/click/exceptions.py @@ -223,3 +223,13 @@ def format_message(self): class Abort(RuntimeError): """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + def __init__(self, code=0): + self.exit_code = code diff --git a/click/testing.py b/click/testing.py index bfa67fb7d..1b2924e0b 100644 --- a/click/testing.py +++ b/click/testing.py @@ -83,7 +83,7 @@ def __init__(self, runner, stdout_bytes, stderr_bytes, exit_code, self.stderr_bytes = stderr_bytes #: The exit code as integer. self.exit_code = exit_code - #: The exception that happend if one did. + #: The exception that happened if one did. self.exception = exception #: The traceback self.exc_info = exc_info diff --git a/click/types.py b/click/types.py index e1fe54b29..0d4b122fa 100644 --- a/click/types.py +++ b/click/types.py @@ -126,17 +126,18 @@ def __repr__(self): class Choice(ParamType): - """The choice type allows a value to be checked against a fixed set of - supported values. All of these values have to be strings. + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. - You should only pass *choices* as list or tuple. Other iterables (like - generators) may lead to surprising results. + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. See :ref:`choice-opts` for an example. - :param case_sensitive: Set to false to make choices case insensitive. - Defaults to true. + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. """ + name = 'choice' def __init__(self, choices, case_sensitive=True): @@ -331,9 +332,12 @@ class File(ParamType): opened in binary mode or for writing. The encoding parameter can be used to force a specific encoding. - The `lazy` flag controls if the file should be opened immediately or - upon first IO. The default is to be non lazy for standard input and - output streams as well as files opened for reading, lazy otherwise. + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. Starting with Click 2.0, files can also be opened atomically in which case all writes go into a separate file in the same folder and upon diff --git a/docs/Makefile b/docs/Makefile index 9bca27fe9..6e3c9b90d 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,130 +1,20 @@ -# Makefile for Sphinx documentation +# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build -PAPER = +SPHINXPROJ = Jinja +SOURCEDIR = . BUILDDIR = _build -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - +# Put it first so that "make" without argument is like "make help". help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Classy.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Classy.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Classy" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Classy" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -latexpdf: latex - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." +.PHONY: help Makefile -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/click-icon.png b/docs/_static/click-icon.png new file mode 100644 index 000000000..b883cfaa1 Binary files /dev/null and b/docs/_static/click-icon.png differ diff --git a/docs/_static/click-small@2x.png b/docs/_static/click-logo-sidebar.png similarity index 100% rename from docs/_static/click-small@2x.png rename to docs/_static/click-logo-sidebar.png diff --git a/docs/_static/click@2x.png b/docs/_static/click-logo.png similarity index 100% rename from docs/_static/click@2x.png rename to docs/_static/click-logo.png diff --git a/docs/_static/click-small.png b/docs/_static/click-small.png deleted file mode 100644 index f101a8a31..000000000 Binary files a/docs/_static/click-small.png and /dev/null differ diff --git a/docs/_static/click.png b/docs/_static/click.png deleted file mode 100644 index 64c62f16e..000000000 Binary files a/docs/_static/click.png and /dev/null differ diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html deleted file mode 100644 index 4e49aba4b..000000000 --- a/docs/_templates/sidebarintro.html +++ /dev/null @@ -1,13 +0,0 @@ -

About

-

- Click is a Python package for creating beautiful command line interfaces in a - composable way with as little amount of code as necessary. It’s the “Command - Line Interface Creation Kit”. -

-

Useful Links

- diff --git a/docs/_templates/sidebarlogo.html b/docs/_templates/sidebarlogo.html deleted file mode 100644 index 55c462960..000000000 --- a/docs/_templates/sidebarlogo.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/docs/changelog.rst b/docs/changelog.rst index 9db95927b..7e0e1bbef 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,3 +1,3 @@ .. currentmodule:: click -.. include:: ../CHANGES +.. include:: ../CHANGES.rst diff --git a/docs/clickdoctools.py b/docs/clickdoctools.py deleted file mode 100644 index 1dd47d3d1..000000000 --- a/docs/clickdoctools.py +++ /dev/null @@ -1,282 +0,0 @@ -import os -import sys -import click -import shutil -import tempfile -import contextlib -import subprocess - -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -from docutils import nodes -from docutils.statemachine import ViewList - -from sphinx.domains import Domain -from docutils.parsers.rst import Directive - -PY2 = sys.version_info[0] == 2 - -if PY2: - text_type = unicode -else: - text_type = str - - -class EchoingStdin(object): - - def __init__(self, input, output): - self._input = input - self._output = output - - def __getattr__(self, x): - return getattr(self._input, x) - - def _echo(self, rv): - mark = False - if rv.endswith('\xff'): - rv = rv[:-1] - mark = True - self._output.write(rv) - if mark: - self._output.write('^D\n') - return rv - - def read(self, n=-1): - return self._echo(self._input.read(n)) - - def readline(self, n=-1): - return self._echo(self._input.readline(n)) - - def readlines(self): - return [self._echo(x) for x in self._input.readlines()] - - def __iter__(self): - return iter(self._echo(x) for x in self._input) - - -@contextlib.contextmanager -def fake_modules(): - old_call = subprocess.call - def dummy_call(*args, **kwargs): - with tempfile.TemporaryFile('wb+') as f: - kwargs['stdout'] = f - kwargs['stderr'] = f - rv = subprocess.Popen(*args, **kwargs).wait() - f.seek(0) - click.echo(f.read().decode('utf-8', 'replace').rstrip()) - return rv - subprocess.call = dummy_call - try: - yield - finally: - subprocess.call = old_call - - -@contextlib.contextmanager -def isolation(input=None, env=None): - if isinstance(input, text_type): - input = input.encode('utf-8') - input = StringIO(input or '') - output = StringIO() - sys.stdin = EchoingStdin(input, output) - sys.stdin.encoding = 'utf-8' - - def visible_input(prompt=None): - sys.stdout.write(prompt or '') - val = input.readline().rstrip('\r\n') - sys.stdout.write(val + '\n') - sys.stdout.flush() - return val - - def hidden_input(prompt=None): - sys.stdout.write((prompt or '') + '\n') - sys.stdout.flush() - return input.readline().rstrip('\r\n') - - sys.stdout = output - sys.stderr = output - old_visible_prompt_func = click.termui.visible_prompt_func - old_hidden_prompt_func = click.termui.hidden_prompt_func - click.termui.visible_prompt_func = visible_input - click.termui.hidden_prompt_func = hidden_input - - old_env = {} - try: - if env: - for key, value in env.iteritems(): - old_env[key] = os.environ.get(value) - os.environ[key] = value - yield output - finally: - for key, value in old_env.iteritems(): - if value is None: - try: - del os.environ[key] - except Exception: - pass - else: - os.environ[key] = value - sys.stdout = sys.__stdout__ - sys.stderr = sys.__stderr__ - click.termui.visible_prompt_func = old_visible_prompt_func - click.termui.hidden_prompt_func = old_hidden_prompt_func - - -@contextlib.contextmanager -def isolated_filesystem(): - cwd = os.getcwd() - t = tempfile.mkdtemp() - os.chdir(t) - try: - yield - finally: - os.chdir(cwd) - try: - shutil.rmtree(t) - except (OSError, IOError): - pass - - -class ExampleRunner(object): - - def __init__(self): - self.namespace = { - 'click': click, - '__file__': 'dummy.py', - } - - def declare(self, source): - with fake_modules(): - code = compile(source, '', 'exec') - eval(code, self.namespace) - - def run(self, source): - code = compile(source, '', 'exec') - buffer = [] - - def invoke(cmd, args=None, prog_name=None, - input=None, terminate_input=False, env=None, - **extra): - if env: - for key, value in sorted(env.items()): - if ' ' in value: - value = '"%s"' % value - buffer.append('$ export %s=%s' % (key, value)) - args = args or [] - if prog_name is None: - prog_name = cmd.name.replace('_', '-') - buffer.append(('$ %s %s' % ( - prog_name, - ' '.join(('"%s"' % x) if ' ' in x else x for x in args) - )).rstrip()) - if isinstance(input, (tuple, list)): - input = '\n'.join(input) + '\n' - if terminate_input: - input += '\xff' - with isolation(input=input, env=env) as output: - try: - cmd.main(args=args, prog_name=prog_name.split()[-1], - **extra) - except SystemExit: - pass - buffer.extend(output.getvalue().splitlines()) - - def println(text=''): - buffer.append(text) - - eval(code, self.namespace, { - 'invoke': invoke, - 'println': println, - 'isolated_filesystem': isolated_filesystem, - }) - return buffer - - def close(self): - pass - - -def parse_rst(state, content_offset, doc): - node = nodes.section() - # hack around title style bookkeeping - surrounding_title_styles = state.memo.title_styles - surrounding_section_level = state.memo.section_level - state.memo.title_styles = [] - state.memo.section_level = 0 - state.nested_parse(doc, content_offset, node, match_titles=1) - state.memo.title_styles = surrounding_title_styles - state.memo.section_level = surrounding_section_level - return node.children - - -def get_example_runner(document): - runner = getattr(document, 'click_example_runner', None) - if runner is None: - runner = document.click_example_runner = ExampleRunner() - return runner - - -class ExampleDirective(Directive): - has_content = True - required_arguments = 0 - optional_arguments = 0 - final_argument_whitespace = False - - def run(self): - doc = ViewList() - runner = get_example_runner(self.state.document) - try: - runner.declare('\n'.join(self.content)) - except: - runner.close() - raise - doc.append('.. sourcecode:: python', '') - doc.append('', '') - for line in self.content: - doc.append(' ' + line, '') - return parse_rst(self.state, self.content_offset, doc) - - -class RunExampleDirective(Directive): - has_content = True - required_arguments = 0 - optional_arguments = 0 - final_argument_whitespace = False - - def run(self): - doc = ViewList() - runner = get_example_runner(self.state.document) - try: - rv = runner.run('\n'.join(self.content)) - except: - runner.close() - raise - doc.append('.. sourcecode:: text', '') - doc.append('', '') - for line in rv: - doc.append(' ' + line, '') - return parse_rst(self.state, self.content_offset, doc) - - -class ClickDomain(Domain): - name = 'click' - label = 'Click' - directives = { - 'example': ExampleDirective, - 'run': RunExampleDirective, - } - - -def delete_example_runner_state(app, doctree): - runner = getattr(doctree, 'click_example_runner', None) - if runner is not None: - runner.close() - del doctree.click_example_runner - - -def setup(app): - app.add_domain(ClickDomain) - - app.connect('doctree-read', delete_example_runner_state) diff --git a/docs/commands.rst b/docs/commands.rst index 2320432c1..53834f754 100644 --- a/docs/commands.rst +++ b/docs/commands.rst @@ -87,6 +87,10 @@ script like this: @click.option('--debug/--no-debug', default=False) @click.pass_context def cli(ctx, debug): + # ensure that ctx.obj exists and is a dict (in case `cli()` is called + # by means other than the `if` block below + ctx.ensure_object(dict) + ctx.obj['DEBUG'] = debug @cli.command() diff --git a/docs/complex.rst b/docs/complex.rst index 9907606f4..e9cefb5de 100644 --- a/docs/complex.rst +++ b/docs/complex.rst @@ -187,8 +187,9 @@ The above example only works if there was an outer command that created a ``Repo`` object and stored it in the context. For some more advanced use cases, this might become a problem. The default behavior of :func:`make_pass_decorator` is to call :meth:`Context.find_object` -which will find the object. If it can't find the object, it will raise an -error. The alternative behavior is to use :meth:`Context.ensure_object` +which will find the object. If it can't find the object, +:meth:`make_pass_decorator` will raise an error. +The alternative behavior is to use :meth:`Context.ensure_object` which will find the object, and if it cannot find it, will create one and store it in the innermost context. This behavior can also be enabled for :func:`make_pass_decorator` by passing ``ensure=True``: diff --git a/docs/conf.py b/docs/conf.py index dd699953a..39b6f4612 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,219 +1,46 @@ -# -*- coding: utf-8 -*- -# -# click documentation build configuration file, created by -# sphinx-quickstart on Mon Apr 26 19:53:01 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. +from pallets_sphinx_themes import ProjectLink, get_version -import sys, os -import datetime +# Project -------------------------------------------------------------- -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.append(os.path.abspath('..')) -sys.path.append(os.path.abspath('.')) +project = "Click" +copyright = "2014 Pallets Team" +author = "Pallets Team" +release, version = get_version("Click", version_length=1) -# -- General configuration ----------------------------------------------------- +# General -------------------------------------------------------------- -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +master_doc = "index" +extensions = ["sphinx.ext.autodoc", "sphinx.ext.intersphinx", "pallets_sphinx_themes"] +intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)} -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', - 'clickdoctools'] +# HTML ----------------------------------------------------------------- -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'click' -copyright = u'%d, Armin Ronacher' % datetime.datetime.utcnow().year - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0' -# The full version, including alpha/beta/rc tags. -release = '1.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -#html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { +html_theme = "click" +html_theme_options = {"index_sidebar_logo": False} +html_context = { + "project_links": [ + ProjectLink("Donate to Pallets", "https://palletsprojects.com/donate"), + ProjectLink("Click Website", "https://palletsprojects.com/p/click/"), + ProjectLink("PyPI releases", "https://pypi.org/project/Click/"), + ProjectLink("Source Code", "https://github.com/pallets/click/"), + ProjectLink("Issue Tracker", "https://github.com/pallets/click/issues/"), + ] } - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = ['_themes'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -html_title = 'click' - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. html_sidebars = { - 'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'], - '**': ['sidebarlogo.html', 'localtoc.html', 'relations.html', - 'sourcelink.html', 'searchbox.html'] + "index": ["project.html", "versions.html", "searchbox.html"], + "**": ["localtoc.html", "relations.html", "versions.html", "searchbox.html"], } +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 -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'clickdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# LaTeX ---------------------------------------------------------------- -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'click.tex', u'click documentation', - u'Armin Ronacher', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'click', u'click documentation', - [u'Armin Ronacher'], 1) + (master_doc, "Click-{}.tex".format(version), html_title, author, "manual") ] - -intersphinx_mapping = { - 'http://docs.python.org/dev': None -} diff --git a/docs/documentation.rst b/docs/documentation.rst index c9788b2f0..6d582e00b 100644 --- a/docs/documentation.rst +++ b/docs/documentation.rst @@ -78,6 +78,40 @@ And what it looks like: .. _doc-meta-variables: +Truncating Help Texts +--------------------- + +Click gets command help text from function docstrings. However if you +already use docstrings to document function arguments you may not want +to see :param: and :return: lines in your help text. + +You can use the ``\f`` escape marker to have Click truncate the help text +after the marker. + +Example: + +.. click:example:: + + @click.command() + @click.pass_context + def cli(ctx): + """First paragraph. + + This is a very long second + paragraph and not correctly + wrapped but it will be rewrapped. + \f + + :param click.core.Context ctx: Click context. + """ + +And what it looks like: + +.. click:run:: + + invoke(cli, args=['--help']) + + Meta Variables -------------- diff --git a/docs/index.rst b/docs/index.rst index 8cb77785b..7fac84987 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,12 @@ -Welcome to the Click Documentation -================================== +.. rst-class:: hide-header + +Welcome to Click +================ + +.. image:: _static/click-logo.png + :align: center + :scale: 50% + :target: https://palletsprojects.com/p/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 @@ -50,8 +57,8 @@ You can get the library directly from PyPI:: pip install click -Documentation Contents ----------------------- +Documentation +------------- This part of the documentation guides you through all of the library's usage patterns. diff --git a/docs/make.bat b/docs/make.bat index 1e941d8ca..147946324 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -1,155 +1,36 @@ @ECHO OFF +pushd %~dp0 + REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) +set SOURCEDIR=. set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) +set SPHINXPROJ=Jinja if "%1" == "" goto help -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 ) -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Classy.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Classy.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end +popd diff --git a/docs/options.rst b/docs/options.rst index f31046de4..b1d0dcf9b 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -62,10 +62,10 @@ simply pass in `required=True` as an argument to the decorator. # How to use a Python reserved word such as `from` as a parameter @click.command() - @click.option('--from', '-f', '_from') + @click.option('--from', '-f', 'from_') @click.option('--to', '-t') - def reserved_param_name(_from, to): - click.echo('from %s to %s' % (_from, to)) + def reserved_param_name(from_, to): + click.echo('from %s to %s' % (from_, to)) And on the command line: @@ -124,7 +124,7 @@ the tuple. For this you can directly specify a tuple as type: .. click:example:: @click.command() - @click.option('--item', type=(unicode, int)) + @click.option('--item', type=(str, int)) def putitem(item): click.echo('name=%s id=%d' % item) @@ -141,7 +141,7 @@ used. The above example is thus equivalent to this: .. click:example:: @click.command() - @click.option('--item', nargs=2, type=click.Tuple([unicode, int])) + @click.option('--item', nargs=2, type=click.Tuple([str, int])) def putitem(item): click.echo('name=%s id=%d' % item) diff --git a/docs/parameters.rst b/docs/parameters.rst index b7e212497..112e8fac4 100644 --- a/docs/parameters.rst +++ b/docs/parameters.rst @@ -91,11 +91,14 @@ If all names for a parameter contain dashes, the internal name is generated automatically by taking the longest argument and converting all dashes to underscores. +The internal name is converted to lowercase. + Examples: * For an option with ``('-f', '--foo-bar')``, the parameter name is `foo_bar`. * For an option with ``('-x',)``, the parameter is `x`. * For an option with ``('-f', '--filename', 'dest')``, the parameter name is `dest`. +* For an option with ``('--CamelCaseOption',)``, the parameter is `camelcaseoption`. * For an arguments with ``(`foogle`)``, the parameter name is `foogle`. To provide a different human readable name for use in help text, see the section about :ref:`doc-meta-variables`. diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..dbd475f20 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +Sphinx~=1.7.7 +Pallets-Sphinx-Themes~=1.1.0 diff --git a/docs/testing.rst b/docs/testing.rst index 3c046bfcc..174b77567 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -61,6 +61,11 @@ Example:: assert 'Debug mode is on' in result.output assert 'Syncing' in result.output +Additional keyword arguments passed to ``.invoke()`` will be used to construct the initial Context object. For example, if you want to run your tests against a fixed terminal width you can use the following:: + + runner = CliRunner() + result = runner.invoke(cli, ['--debug', 'sync'], terminal_width=60) + File System Isolation --------------------- diff --git a/setup.py b/setup.py index 53820e65b..194d1d417 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( name='click', version=version, - url='https://www.palletsprojects.com/p/click/', + url='https://palletsprojects.com/p/click/', author='Armin Ronacher', author_email='armin.ronacher@active-4.com', maintainer='Pallets team', @@ -36,13 +36,14 @@ ], 'docs': [ 'sphinx', + 'Pallets-Sphinx-Themes', ] }, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent' + 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', @@ -50,6 +51,7 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", ) diff --git a/tests/test_context.py b/tests/test_context.py index cbf9b98e9..35933beba 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -193,6 +193,7 @@ def test_close_before_pop(runner): @click.pass_context def cli(ctx): ctx.obj = 'test' + @ctx.call_on_close def foo(): assert click.get_current_context().obj == 'test' @@ -203,3 +204,55 @@ def foo(): assert not result.exception assert result.output == 'aha!\n' assert called == [True] + + +def test_make_pass_decorator_args(runner): + """ + Test to check that make_pass_decorator doesn't consume arguments based on + invocation order. + """ + class Foo(object): + title = 'foocmd' + + pass_foo = click.make_pass_decorator(Foo) + + @click.group() + @click.pass_context + def cli(ctx): + ctx.obj = Foo() + + @cli.command() + @click.pass_context + @pass_foo + def test1(foo, ctx): + click.echo(foo.title) + + @cli.command() + @pass_foo + @click.pass_context + def test2(ctx, foo): + click.echo(foo.title) + + result = runner.invoke(cli, ['test1']) + assert not result.exception + assert result.output == 'foocmd\n' + + result = runner.invoke(cli, ['test2']) + assert not result.exception + assert result.output == 'foocmd\n' + + +def test_exit_not_standalone(): + @click.command() + @click.pass_context + def cli(ctx): + ctx.exit(1) + + assert cli.main([], 'test_exit_not_standalone', standalone_mode=False) == 1 + + @click.command() + @click.pass_context + def cli(ctx): + ctx.exit(0) + + assert cli.main([], 'test_exit_not_standalone', standalone_mode=False) == 0 diff --git a/tests/test_formatting.py b/tests/test_formatting.py index 0c0607328..2005f98b5 100644 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -268,3 +268,32 @@ def cmd(param): 'Options:', ' --help Show this message and exit.' ] + + +def test_truncating_docstring(runner): + @click.command() + @click.pass_context + def cli(ctx): + """First paragraph. + + This is a very long second + paragraph and not correctly + wrapped but it will be rewrapped. + \f + + :param click.core.Context ctx: Click context. + """ + + result = runner.invoke(cli, ['--help'], terminal_width=60) + assert not result.exception + assert result.output.splitlines() == [ + 'Usage: cli [OPTIONS]', + '', + ' First paragraph.', + '', + ' This is a very long second paragraph and not correctly', + ' wrapped but it will be rewrapped.', + '', + 'Options:', + ' --help Show this message and exit.', + ] diff --git a/tests/test_testing.py b/tests/test_testing.py index 12f57de39..b8565adbc 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -153,16 +153,34 @@ def cli_string(): click.echo('hello world') sys.exit('error') + @click.command() + @click.pass_context + def cli_string_ctx_exit(ctx): + click.echo('hello world') + ctx.exit('error') + @click.command() def cli_int(): click.echo('hello world') sys.exit(1) + @click.command() + @click.pass_context + def cli_int_ctx_exit(ctx): + click.echo('hello world') + ctx.exit(1) + @click.command() def cli_float(): click.echo('hello world') sys.exit(1.0) + @click.command() + @click.pass_context + def cli_float_ctx_exit(ctx): + click.echo('hello world') + ctx.exit(1.0) + @click.command() def cli_no_error(): click.echo('hello world') @@ -173,14 +191,26 @@ def cli_no_error(): assert result.exit_code == 1 assert result.output == 'hello world\nerror\n' + result = runner.invoke(cli_string_ctx_exit) + assert result.exit_code == 1 + assert result.output == 'hello world\nerror\n' + result = runner.invoke(cli_int) assert result.exit_code == 1 assert result.output == 'hello world\n' + result = runner.invoke(cli_int_ctx_exit) + assert result.exit_code == 1 + assert result.output == 'hello world\n' + result = runner.invoke(cli_float) assert result.exit_code == 1 assert result.output == 'hello world\n1.0\n' + result = runner.invoke(cli_float_ctx_exit) + assert result.exit_code == 1 + assert result.output == 'hello world\n1.0\n' + result = runner.invoke(cli_no_error) assert result.exit_code == 0 assert result.output == 'hello world\n'