Repository: pallets/click
Pull request #1117 (2018-09-19 03:55:36)

Clarify Group invocation in quickstart
For new users and, as noted in #663 , especially those whose introduction to click may coincide with their introduction to python, it may not be clear that a Group is a callable. More specifically: the "root" of your command tree is the callable you actually want to invoke to run your CLI.

closes #663


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index a2fe9df..8eaee82 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,222 +1,215 @@
 Click Changelog
 ===============
 
+This contains all major version changes between Click releases.
 
 Version 7.0
 -----------
 
-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`_)
--   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`_)
--   ``click.getchar()`` now returns unicode in Python 3 on Windows, same as 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`_)
--   Only allow one positional arg for ``Argument`` parameter delcaration. (`#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`_)
--   ``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`_)
--   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`_)
--   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 chaning 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_envar_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 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.
--   Hide hidden commands and options from completion. (`#1058`_, `#1061`_)
--   Fix issue where a lowercase ``auto_envvar_prefix`` would not be converted to uppercase. (`#1105`_)
+(upcoming release with new features, release date to be decided)
+
+- 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.
 
+.. _#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
-.. _#393: https://github.com/pallets/click/issues/393
-.. _#409: https://github.com/pallets/click/issues/409
+.. _#995: https://github.com/pallets/click/pull/995
+.. _#1008: https://github.com/pallets/click/pull/1008
 .. _#414: https://github.com/pallets/click/pull/414
-.. _#423: https://github.com/pallets/click/pull/423
-.. _#424: https://github.com/pallets/click/pull/424
-.. _#447: https://github.com/pallets/click/issues/447
+.. _#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
 .. _#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
+.. _#999: https://github.com/pallets/click/pull/999
 .. _#616: https://github.com/pallets/click/issues/616
-.. _#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
-.. _#684: https://github.com/pallets/click/pull/684
-.. _#703: https://github.com/pallets/click/issues/703
-.. _#704: https://github.com/pallets/click/issues/704
+.. _#991: https://github.com/pallets/click/pull/991
+.. _#997: https://github.com/pallets/click/pull/997
 .. _#706: https://github.com/pallets/click/pull/706
-.. _#709: https://github.com/pallets/click/pull/709
+.. _#651: https://github.com/pallets/click/issues/651
 .. _#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/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
-.. _#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
+.. _#889: https://github.com/pallets/click/pull/889
+.. _#409: https://github.com/pallets/click/issues/409
+.. _#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
-.. _#877: https://github.com/pallets/click/pull/877
+.. _#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/pull/880
-.. _#883: https://github.com/pallets/click/pull/883
-.. _#887: https://github.com/pallets/click/pull/887
-.. _#889: https://github.com/pallets/click/pull/889
+.. _#880: https://github.com/pallets/click/issues/880
+.. _#877: https://github.com/pallets/click/pull/877
 .. _#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
+.. _#920: https://github.com/pallets/click/pull/920
 .. _#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
-.. _#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
-.. _#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
-.. _#1088: https://github.com/pallets/click/issues/1088
-.. _#1105: https://github.com/pallets/click/pull/1105
-.. _#1108: https://github.com/pallets/click/pull/1108
-.. _#1115: https://github.com/pallets/click/pull/1115
+.. _#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)
+
+- 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
 -----------
diff --git a/click/__init__.py b/click/__init__.py
index fc40c7e..6de314b 100644
--- a/click/__init__.py
+++ b/click/__init__.py
@@ -28,7 +28,7 @@ from .decorators import pass_context, pass_obj, make_pass_decorator, \
 
 # Types
 from .types import ParamType, File, Path, Choice, IntRange, Tuple, \
-     DateTime, STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange
+     STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED, FloatRange
 
 # Utilities
 from .utils import echo, get_binary_stream, get_text_stream, open_file, \
@@ -65,9 +65,8 @@ __all__ = [
     'version_option', 'help_option',
 
     # Types
-    'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple',
-    'DateTime', 'STRING', 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED',
-    'FloatRange',
+    'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple', 'STRING',
+    'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', 'FloatRange',
 
     # Utilities
     'echo', 'get_binary_stream', 'get_text_stream', 'open_file',
diff --git a/click/_bashcomplete.py b/click/_bashcomplete.py
index fba6e99..db42865 100644
--- a/click/_bashcomplete.py
+++ b/click/_bashcomplete.py
@@ -10,7 +10,6 @@ from .types import Choice
 
 WORDBREAK = '='
 
-# Note, only BASH version 4.4 and later have the nosort option.
 COMPLETION_SCRIPT_BASH = '''
 %(complete_func)s() {
     local IFS=$'\n'
@@ -20,18 +19,7 @@ COMPLETION_SCRIPT_BASH = '''
     return 0
 }
 
-%(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
+complete -F %(complete_func)s %(script_names)s
 '''
 
 COMPLETION_SCRIPT_ZSH = '''
@@ -53,13 +41,11 @@ COMPLETION_SCRIPT_ZSH = '''
     done
 
     if [ -n "$completions_with_descriptions" ]; then
-        _describe -V unsorted completions_with_descriptions -U -Q
+        _describe '' completions_with_descriptions
     fi
-
     if [ -n "$completions" ]; then
-        compadd -U -V unsorted -Q -a completions
+        compadd -M 'r:|=* l:|=* r:|=*' -a completions
     fi
-    compstate[insert]="automenu"
 }
 
 compdef %(complete_func)s %(script_names)s
@@ -87,31 +73,18 @@ def resolve_ctx(cli, prog_name, args):
     :return: the final context/command parsed
     """
     ctx = cli.make_context(prog_name, args, resilient_parsing=True)
-    args = ctx.protected_args + ctx.args
-    while args:
+    args_remaining = ctx.protected_args + ctx.args
+    while ctx is not None and args_remaining:
         if isinstance(ctx.command, MultiCommand):
-            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
+            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
         else:
-            break
+            ctx = ctx.parent
+
     return ctx
 
 
@@ -177,7 +150,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 str(c).startswith(incomplete)]
+                   for c in cmd_param.type.choices if c.startswith(incomplete)]
     elif cmd_param.autocompletion is not None:
         dynamic_completions = cmd_param.autocompletion(ctx=ctx,
                                                        args=args,
@@ -187,32 +160,20 @@ 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.name, c.get_short_help_str()) for c in get_visible_commands_starting_with(ctx, incomplete)])
+            [(c, ctx.command.get_command(ctx, c).get_short_help_str()) for c in ctx.command.list_commands(ctx) if c.startswith(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 = [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])
+            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)])
 
 
 def get_choices(cli, prog_name, args, incomplete):
@@ -242,10 +203,11 @@ 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) and not param.hidden:
+            if isinstance(param, Option):
                 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:
@@ -254,11 +216,15 @@ 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):
-            return get_user_autocompletions(ctx, all_args, incomplete, 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
 
     add_subcommand_completions(ctx, incomplete, completions)
-    # Sort before returning so that proper ordering can be enforced in custom types.
-    return sorted(completions)
+    return completions
 
 
 def do_complete(cli, prog_name, include_descriptions):
diff --git a/click/_termui_impl.py b/click/_termui_impl.py
index b7fcbb5..0b39731 100644
--- a/click/_termui_impl.py
+++ b/click/_termui_impl.py
@@ -527,11 +527,9 @@ def open_url(url, wait=False, locate=False):
 
 
 def _translate_ch_to_exc(ch):
-    if ch == u'\x03':
+    if ch == '\x03':
         raise KeyboardInterrupt()
-    if ch == u'\x04' and not WIN:  # Unix-like, Ctrl+D
-        raise EOFError()
-    if ch == u'\x1a' and WIN:      # Windows, Ctrl+Z
+    if ch == '\x04':
         raise EOFError()
 
 
@@ -543,46 +541,16 @@ if WIN:
         yield
 
     def getchar(echo):
-        # 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`.
+        rv = msvcrt.getch()
         if echo:
-            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()
+            msvcrt.putchar(rv)
         _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
@@ -612,8 +580,7 @@ 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
+            return ch.decode(get_best_encoding(sys.stdin), 'replace')
diff --git a/click/_winconsole.py b/click/_winconsole.py
index 4530051..f4d95dd 100644
--- a/click/_winconsole.py
+++ b/click/_winconsole.py
@@ -210,14 +210,14 @@ def _get_text_stdin(buffer_stream):
 
 def _get_text_stdout(buffer_stream):
     text_stream = _NonClosingTextIOWrapper(
-        io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)),
+        _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(
-        io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)),
+        _WindowsConsoleWriter(STDERR_HANDLE),
         'utf-16-le', 'strict', line_buffering=True)
     return ConsoleStream(text_stream, buffer_stream)
 
diff --git a/click/core.py b/click/core.py
index f68fa15..30aec62 100644
--- a/click/core.py
+++ b/click/core.py
@@ -182,8 +182,7 @@ 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.  Default values will also be
-                              ignored.  This is useful for implementing
+                              invocation.  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
@@ -313,8 +312,7 @@ 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 and default values
-        #: will be ignored. Useful for completion.
+        #: will do its best to not cause any failures.
         self.resilient_parsing = resilient_parsing
 
         # If there is no envvar prefix yet, but the parent has one and
@@ -327,7 +325,7 @@ class Context(object):
                 auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix,
                                            self.info_name.upper())
         else:
-            auto_envvar_prefix = auto_envvar_prefix.upper()
+            self.auto_envvar_prefix = auto_envvar_prefix.upper()
         self.auto_envvar_prefix = auto_envvar_prefix
 
         if color is None and parent is not None:
@@ -1179,7 +1177,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 and not ctx.resilient_parsing:
+        if cmd is None:
             if split_opt(cmd_name)[0]:
                 self.parse_args(ctx, ctx.args)
             ctx.fail('No such command "%s".' % original_cmd_name)
@@ -1353,7 +1351,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):
@@ -1384,6 +1382,7 @@ 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:
@@ -1434,7 +1433,7 @@ class Parameter(object):
     def full_process_value(self, ctx, value):
         value = self.process_value(ctx, value)
 
-        if value is None and not ctx.resilient_parsing:
+        if value is None:
             value = self.get_default(ctx)
 
         if self.required and self.value_is_missing(value):
@@ -1833,9 +1832,11 @@ 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 '
-                            'parameter declaration, got %d' % len(decls))
+            raise TypeError('Arguments take exactly one or two '
+                            'parameter declarations, got %d' % len(decls))
         return name, [arg], []
 
     def get_usage_pieces(self, ctx):
diff --git a/click/parser.py b/click/parser.py
index 5e8c213..4fe3d2f 100644
--- a/click/parser.py
+++ b/click/parser.py
@@ -321,7 +321,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, ctx=self.ctx)
+            raise NoSuchOption(opt, possibilities=possibilities)
 
         option = self._long_opt[opt]
         if option.takes_value:
@@ -364,7 +364,7 @@ class OptionParser(object):
                 if self.ignore_unknown_options:
                     unknown_options.append(ch)
                     continue
-                raise NoSuchOption(opt, ctx=self.ctx)
+                raise NoSuchOption(opt)
             if option.takes_value:
                 # Any characters left in arg?  Pretend they're the
                 # next arg, and stop consuming characters of arg.
diff --git a/click/termui.py b/click/termui.py
index 4398ffc..70eaceb 100644
--- a/click/termui.py
+++ b/click/termui.py
@@ -557,10 +557,6 @@ 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
diff --git a/click/types.py b/click/types.py
index 1f88032..0d4b122 100644
--- a/click/types.py
+++ b/click/types.py
@@ -1,6 +1,5 @@
 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
@@ -183,59 +182,6 @@ 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'
 
diff --git a/docs/conf.py b/docs/conf.py
index 39b6f46..d64f8fa 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -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", version_length=1)
+release, version = get_version("Click")
 
 # General --------------------------------------------------------------
 
@@ -16,7 +16,9 @@ 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"),
@@ -34,7 +36,6 @@ 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
@@ -42,5 +43,5 @@ html_experimental_html5_writer = True
 # LaTeX ----------------------------------------------------------------
 
 latex_documents = [
-    (master_doc, "Click-{}.tex".format(version), html_title, author, "manual")
+    (master_doc, "Click.tex", "Click Documentation", "Pallets Team", "manual")
 ]
diff --git a/docs/parameters.rst b/docs/parameters.rst
index 9ca3208..112e8fa 100644
--- a/docs/parameters.rst
+++ b/docs/parameters.rst
@@ -70,9 +70,6 @@ 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.
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 4824f66..4479d0e 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -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
 -----------------
 
diff --git a/docs/requirements.txt b/docs/requirements.txt
index dbd475f..6bb1491 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,2 +1,2 @@
-Sphinx~=1.7.7
-Pallets-Sphinx-Themes~=1.1.0
+Sphinx
+Pallets-Sphinx-Themes
diff --git a/examples/bashcompletion/bashcompletion.py b/examples/bashcompletion/bashcompletion.py
index 1072840..4d9fdde 100644
--- a/examples/bashcompletion/bashcompletion.py
+++ b/examples/bashcompletion/bashcompletion.py
@@ -8,7 +8,6 @@ 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
@@ -27,13 +26,11 @@ def group():
 
 
 def list_users(ctx, args, incomplete):
-    # 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]]
+    # Here you can generate completions dynamically
+    users = ['bob', 'alice']
+    for user in users:
+        if user.startswith(incomplete):
+            yield user
 
 
 @group.command(help='Choose a user')
@@ -41,5 +38,4 @@ def list_users(ctx, args, incomplete):
 def subcmd(user):
     click.echo('Chosen user is %s' % user)
 
-
 cli.add_command(group)


Test patch:
diff --git a/tests/test_arguments.py b/tests/test_arguments.py
index ca48fed..a6a3258 100644
--- a/tests/test_arguments.py
+++ b/tests/test_arguments.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-import pytest
 import click
 from click._compat import PY2
 
@@ -288,11 +287,3 @@ 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)
diff --git a/tests/test_bashcomplete.py b/tests/test_bashcomplete.py
index 7214d1a..0390841 100644
--- a/tests/test_bashcomplete.py
+++ b/tests/test_bashcomplete.py
@@ -132,8 +132,7 @@ def test_long_chain():
 def test_chaining():
     @click.group('cli', chain=True)
     @click.option('--cli-opt')
-    @click.argument('arg', type=click.Choice(['cliarg1', 'cliarg2']))
-    def cli(cli_opt, arg):
+    def cli(cli_opt):
         pass
 
     @cli.command()
@@ -143,35 +142,33 @@ def test_chaining():
 
     @cli.command(help='bsub help')
     @click.option('--bsub-opt')
-    @click.argument('arg', type=click.Choice(['arg1', 'arg2']))
+    @click.argument('arg', type=click.Choice(['arg1', 'arg2']), required=True)
     def bsub(bsub_opt, arg):
         pass
 
     @cli.command()
     @click.option('--csub-opt')
-    @click.argument('arg', type=click.Choice(['carg1', 'carg2']), default='carg1')
+    @click.argument('arg', type=click.Choice(['carg1', 'carg2']), required=False)
     def csub(csub_opt, arg):
         pass
 
     assert choices_without_help(cli, [], '-') == ['--cli-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')]
+    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']
 
 
 def test_argument_choice():
     @click.command()
-    @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')
+    @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']))
     def cli():
         pass
 
@@ -185,7 +182,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']), default='opt21')
+    @click.option('--opt2', type=click.Choice(['opt21', 'opt22']))
     @click.option('--opt3', type=click.Choice(['opt', 'option']))
     def cli():
         pass
@@ -221,8 +218,6 @@ 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():
@@ -263,37 +258,11 @@ 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():
@@ -304,7 +273,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, sub_arg):
+    def sub(sub_opt):
         pass
 
     @sub.command(short_help='bsub help')
@@ -314,96 +283,15 @@ def test_long_chain_choice():
     def bsub(bsub_opt):
         pass
 
-    @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_with_help(cli, ['sub'], '') == [('subarg1', None), ('subarg2', None), ('bsub', 'bsub help')]
     assert choices_without_help(cli, ['sub', '--sub-opt'], '') == ['subopt1', 'subopt2']
     assert choices_without_help(cli, ['sub', '--sub-opt', 'subopt1'], '') == \
-           ['subarg1', 'subarg2']
+        ['subarg1', 'subarg2', 'bsub']
     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'], '') == ['bsubarg1', 'bsubarg2']
+        ['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt'], '') == \
+        ['bsubopt1', 'bsubopt2']
     assert choices_without_help(cli,
-                                ['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']
+        ['sub', '--sub-opt', 'subopt1', 'subarg1', 'bsub', '--bsub-opt', 'bsubopt1', 'bsubarg1'],
+                            '') == ['bbsubarg1', 'bbsubarg2']
diff --git a/tests/test_basic.py b/tests/test_basic.py
index 8de6301..8ba251f 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -332,44 +332,6 @@ 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))
diff --git a/tests/test_imports.py b/tests/test_imports.py
index 8e9a97d..f400fa8 100644
--- a/tests/test_imports.py
+++ b/tests/test_imports.py
@@ -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', 'datetime'
+    'threading', 'colorama', 'errno', 'fcntl'
 ])
 
 if WIN:
diff --git a/tests/test_options.py b/tests/test_options.py
index bd346c2..46a4adb 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -202,19 +202,6 @@ 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)