diff planemo/lib/python3.7/site-packages/click/core.py @ 0:d30785e31577 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:18:57 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planemo/lib/python3.7/site-packages/click/core.py	Fri Jul 31 00:18:57 2020 -0400
@@ -0,0 +1,2030 @@
+import errno
+import inspect
+import os
+import sys
+from contextlib import contextmanager
+from functools import update_wrapper
+from itertools import repeat
+
+from ._compat import isidentifier
+from ._compat import iteritems
+from ._compat import PY2
+from ._compat import string_types
+from ._unicodefun import _check_for_unicode_literals
+from ._unicodefun import _verify_python3_env
+from .exceptions import Abort
+from .exceptions import BadParameter
+from .exceptions import ClickException
+from .exceptions import Exit
+from .exceptions import MissingParameter
+from .exceptions import UsageError
+from .formatting import HelpFormatter
+from .formatting import join_options
+from .globals import pop_context
+from .globals import push_context
+from .parser import OptionParser
+from .parser import split_opt
+from .termui import confirm
+from .termui import prompt
+from .termui import style
+from .types import BOOL
+from .types import convert_type
+from .types import IntRange
+from .utils import echo
+from .utils import get_os_args
+from .utils import make_default_short_help
+from .utils import make_str
+from .utils import PacifyFlushWrapper
+
+_missing = object()
+
+SUBCOMMAND_METAVAR = "COMMAND [ARGS]..."
+SUBCOMMANDS_METAVAR = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."
+
+DEPRECATED_HELP_NOTICE = " (DEPRECATED)"
+DEPRECATED_INVOKE_NOTICE = "DeprecationWarning: The command %(name)s is deprecated."
+
+
+def _maybe_show_deprecated_notice(cmd):
+    if cmd.deprecated:
+        echo(style(DEPRECATED_INVOKE_NOTICE % {"name": cmd.name}, fg="red"), err=True)
+
+
+def fast_exit(code):
+    """Exit without garbage collection, this speeds up exit by about 10ms for
+    things like bash completion.
+    """
+    sys.stdout.flush()
+    sys.stderr.flush()
+    os._exit(code)
+
+
+def _bashcomplete(cmd, prog_name, complete_var=None):
+    """Internal handler for the bash completion support."""
+    if complete_var is None:
+        complete_var = "_{}_COMPLETE".format(prog_name.replace("-", "_").upper())
+    complete_instr = os.environ.get(complete_var)
+    if not complete_instr:
+        return
+
+    from ._bashcomplete import bashcomplete
+
+    if bashcomplete(cmd, prog_name, complete_var, complete_instr):
+        fast_exit(1)
+
+
+def _check_multicommand(base_command, cmd_name, cmd, register=False):
+    if not base_command.chain or not isinstance(cmd, MultiCommand):
+        return
+    if register:
+        hint = (
+            "It is not possible to add multi commands as children to"
+            " another multi command that is in chain mode."
+        )
+    else:
+        hint = (
+            "Found a multi command as subcommand to a multi command"
+            " that is in chain mode. This is not supported."
+        )
+    raise RuntimeError(
+        "{}. Command '{}' is set to chain and '{}' was added as"
+        " subcommand but it in itself is a multi command. ('{}' is a {}"
+        " within a chained {} named '{}').".format(
+            hint,
+            base_command.name,
+            cmd_name,
+            cmd_name,
+            cmd.__class__.__name__,
+            base_command.__class__.__name__,
+            base_command.name,
+        )
+    )
+
+
+def batch(iterable, batch_size):
+    return list(zip(*repeat(iter(iterable), batch_size)))
+
+
+def invoke_param_callback(callback, ctx, param, value):
+    code = getattr(callback, "__code__", None)
+    args = getattr(code, "co_argcount", 3)
+
+    if args < 3:
+        from warnings import warn
+
+        warn(
+            "Parameter callbacks take 3 args, (ctx, param, value). The"
+            " 2-arg style is deprecated and will be removed in 8.0.".format(callback),
+            DeprecationWarning,
+            stacklevel=3,
+        )
+        return callback(ctx, value)
+
+    return callback(ctx, param, value)
+
+
+@contextmanager
+def augment_usage_errors(ctx, param=None):
+    """Context manager that attaches extra information to exceptions."""
+    try:
+        yield
+    except BadParameter as e:
+        if e.ctx is None:
+            e.ctx = ctx
+        if param is not None and e.param is None:
+            e.param = param
+        raise
+    except UsageError as e:
+        if e.ctx is None:
+            e.ctx = ctx
+        raise
+
+
+def iter_params_for_processing(invocation_order, declaration_order):
+    """Given a sequence of parameters in the order as should be considered
+    for processing and an iterable of parameters that exist, this returns
+    a list in the correct order as they should be processed.
+    """
+
+    def sort_key(item):
+        try:
+            idx = invocation_order.index(item)
+        except ValueError:
+            idx = float("inf")
+        return (not item.is_eager, idx)
+
+    return sorted(declaration_order, key=sort_key)
+
+
+class Context(object):
+    """The context is a special internal object that holds state relevant
+    for the script execution at every single level.  It's normally invisible
+    to commands unless they opt-in to getting access to it.
+
+    The context is useful as it can pass internal objects around and can
+    control special execution features such as reading data from
+    environment variables.
+
+    A context can be used as context manager in which case it will call
+    :meth:`close` on teardown.
+
+    .. versionadded:: 2.0
+       Added the `resilient_parsing`, `help_option_names`,
+       `token_normalize_func` parameters.
+
+    .. versionadded:: 3.0
+       Added the `allow_extra_args` and `allow_interspersed_args`
+       parameters.
+
+    .. versionadded:: 4.0
+       Added the `color`, `ignore_unknown_options`, and
+       `max_content_width` parameters.
+
+    .. versionadded:: 7.1
+       Added the `show_default` parameter.
+
+    :param command: the command class for this context.
+    :param parent: the parent context.
+    :param info_name: the info name for this invocation.  Generally this
+                      is the most descriptive name for the script or
+                      command.  For the toplevel script it is usually
+                      the name of the script, for commands below it it's
+                      the name of the script.
+    :param obj: an arbitrary object of user data.
+    :param auto_envvar_prefix: the prefix to use for automatic environment
+                               variables.  If this is `None` then reading
+                               from environment variables is disabled.  This
+                               does not affect manually set environment
+                               variables which are always read.
+    :param default_map: a dictionary (like object) with default values
+                        for parameters.
+    :param terminal_width: the width of the terminal.  The default is
+                           inherit from parent context.  If no context
+                           defines the terminal width then auto
+                           detection will be applied.
+    :param max_content_width: the maximum width for content rendered by
+                              Click (this currently only affects help
+                              pages).  This defaults to 80 characters if
+                              not overridden.  In other words: even if the
+                              terminal is larger than that, Click will not
+                              format things wider than 80 characters by
+                              default.  In addition to that, formatters might
+                              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
+                              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
+                             kept on the context.  The default is to inherit
+                             from the command.
+    :param allow_interspersed_args: if this is set to `False` then options
+                                    and arguments cannot be mixed.  The
+                                    default is to inherit from the command.
+    :param ignore_unknown_options: instructs click to ignore options it does
+                                   not know and keeps them for later
+                                   processing.
+    :param help_option_names: optionally a list of strings that define how
+                              the default help parameter is named.  The
+                              default is ``['--help']``.
+    :param token_normalize_func: an optional function that is used to
+                                 normalize tokens (options, choices,
+                                 etc.).  This for instance can be used to
+                                 implement case insensitive behavior.
+    :param color: controls if the terminal supports ANSI colors or not.  The
+                  default is autodetection.  This is only needed if ANSI
+                  codes are used in texts that Click prints which is by
+                  default not the case.  This for instance would affect
+                  help output.
+    :param show_default: if True, shows defaults for all options.
+                    Even if an option is later created with show_default=False,
+                    this command-level setting overrides it.
+    """
+
+    def __init__(
+        self,
+        command,
+        parent=None,
+        info_name=None,
+        obj=None,
+        auto_envvar_prefix=None,
+        default_map=None,
+        terminal_width=None,
+        max_content_width=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,
+        show_default=None,
+    ):
+        #: the parent context or `None` if none exists.
+        self.parent = parent
+        #: the :class:`Command` for this context.
+        self.command = command
+        #: the descriptive information name
+        self.info_name = info_name
+        #: the parsed parameters except if the value is hidden in which
+        #: case it's not remembered.
+        self.params = {}
+        #: the leftover arguments.
+        self.args = []
+        #: protected arguments.  These are arguments that are prepended
+        #: to `args` when certain parsing scenarios are encountered but
+        #: must be never propagated to another arguments.  This is used
+        #: to implement nested parsing.
+        self.protected_args = []
+        if obj is None and parent is not None:
+            obj = parent.obj
+        #: the user object stored.
+        self.obj = obj
+        self._meta = getattr(parent, "meta", {})
+
+        #: A dictionary (-like object) with defaults for parameters.
+        if (
+            default_map is None
+            and parent is not None
+            and parent.default_map is not None
+        ):
+            default_map = parent.default_map.get(info_name)
+        self.default_map = default_map
+
+        #: This flag indicates if a subcommand is going to be executed. A
+        #: group callback can use this information to figure out if it's
+        #: being executed directly or because the execution flow passes
+        #: onwards to a subcommand. By default it's None, but it can be
+        #: the name of the subcommand to execute.
+        #:
+        #: If chaining is enabled this will be set to ``'*'`` in case
+        #: any commands are executed.  It is however not possible to
+        #: figure out which ones.  If you require this knowledge you
+        #: should use a :func:`resultcallback`.
+        self.invoked_subcommand = None
+
+        if terminal_width is None and parent is not None:
+            terminal_width = parent.terminal_width
+        #: The width of the terminal (None is autodetection).
+        self.terminal_width = terminal_width
+
+        if max_content_width is None and parent is not None:
+            max_content_width = parent.max_content_width
+        #: The maximum width of formatted content (None implies a sensible
+        #: default which is 80 for most things).
+        self.max_content_width = max_content_width
+
+        if allow_extra_args is None:
+            allow_extra_args = command.allow_extra_args
+        #: Indicates if the context allows extra args or if it should
+        #: fail on parsing.
+        #:
+        #: .. versionadded:: 3.0
+        self.allow_extra_args = allow_extra_args
+
+        if allow_interspersed_args is None:
+            allow_interspersed_args = command.allow_interspersed_args
+        #: Indicates if the context allows mixing of arguments and
+        #: options or not.
+        #:
+        #: .. versionadded:: 3.0
+        self.allow_interspersed_args = allow_interspersed_args
+
+        if ignore_unknown_options is None:
+            ignore_unknown_options = command.ignore_unknown_options
+        #: Instructs click to ignore options that a command does not
+        #: understand and will store it on the context for later
+        #: processing.  This is primarily useful for situations where you
+        #: want to call into external programs.  Generally this pattern is
+        #: strongly discouraged because it's not possibly to losslessly
+        #: forward all arguments.
+        #:
+        #: .. versionadded:: 4.0
+        self.ignore_unknown_options = ignore_unknown_options
+
+        if help_option_names is None:
+            if parent is not None:
+                help_option_names = parent.help_option_names
+            else:
+                help_option_names = ["--help"]
+
+        #: The names for the help options.
+        self.help_option_names = help_option_names
+
+        if token_normalize_func is None and parent is not None:
+            token_normalize_func = parent.token_normalize_func
+
+        #: An optional normalization function for tokens.  This is
+        #: options, choices, commands etc.
+        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.
+        self.resilient_parsing = resilient_parsing
+
+        # 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.
+        if auto_envvar_prefix is None:
+            if (
+                parent is not None
+                and parent.auto_envvar_prefix is not None
+                and self.info_name is not None
+            ):
+                auto_envvar_prefix = "{}_{}".format(
+                    parent.auto_envvar_prefix, self.info_name.upper()
+                )
+        else:
+            auto_envvar_prefix = auto_envvar_prefix.upper()
+        if auto_envvar_prefix is not None:
+            auto_envvar_prefix = auto_envvar_prefix.replace("-", "_")
+        self.auto_envvar_prefix = auto_envvar_prefix
+
+        if color is None and parent is not None:
+            color = parent.color
+
+        #: Controls if styling output is wanted or not.
+        self.color = color
+
+        self.show_default = show_default
+
+        self._close_callbacks = []
+        self._depth = 0
+
+    def __enter__(self):
+        self._depth += 1
+        push_context(self)
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        self._depth -= 1
+        if self._depth == 0:
+            self.close()
+        pop_context()
+
+    @contextmanager
+    def scope(self, cleanup=True):
+        """This helper method can be used with the context object to promote
+        it to the current thread local (see :func:`get_current_context`).
+        The default behavior of this is to invoke the cleanup functions which
+        can be disabled by setting `cleanup` to `False`.  The cleanup
+        functions are typically used for things such as closing file handles.
+
+        If the cleanup is intended the context object can also be directly
+        used as a context manager.
+
+        Example usage::
+
+            with ctx.scope():
+                assert get_current_context() is ctx
+
+        This is equivalent::
+
+            with ctx:
+                assert get_current_context() is ctx
+
+        .. versionadded:: 5.0
+
+        :param cleanup: controls if the cleanup functions should be run or
+                        not.  The default is to run these functions.  In
+                        some situations the context only wants to be
+                        temporarily pushed in which case this can be disabled.
+                        Nested pushes automatically defer the cleanup.
+        """
+        if not cleanup:
+            self._depth += 1
+        try:
+            with self as rv:
+                yield rv
+        finally:
+            if not cleanup:
+                self._depth -= 1
+
+    @property
+    def meta(self):
+        """This is a dictionary which is shared with all the contexts
+        that are nested.  It exists so that click utilities can store some
+        state here if they need to.  It is however the responsibility of
+        that code to manage this dictionary well.
+
+        The keys are supposed to be unique dotted strings.  For instance
+        module paths are a good choice for it.  What is stored in there is
+        irrelevant for the operation of click.  However what is important is
+        that code that places data here adheres to the general semantics of
+        the system.
+
+        Example usage::
+
+            LANG_KEY = f'{__name__}.lang'
+
+            def set_language(value):
+                ctx = get_current_context()
+                ctx.meta[LANG_KEY] = value
+
+            def get_language():
+                return get_current_context().meta.get(LANG_KEY, 'en_US')
+
+        .. versionadded:: 5.0
+        """
+        return self._meta
+
+    def make_formatter(self):
+        """Creates the formatter for the help and usage output."""
+        return HelpFormatter(
+            width=self.terminal_width, max_width=self.max_content_width
+        )
+
+    def call_on_close(self, f):
+        """This decorator remembers a function as callback that should be
+        executed when the context tears down.  This is most useful to bind
+        resource handling to the script execution.  For instance, file objects
+        opened by the :class:`File` type will register their close callbacks
+        here.
+
+        :param f: the function to execute on teardown.
+        """
+        self._close_callbacks.append(f)
+        return f
+
+    def close(self):
+        """Invokes all close callbacks."""
+        for cb in self._close_callbacks:
+            cb()
+        self._close_callbacks = []
+
+    @property
+    def command_path(self):
+        """The computed command path.  This is used for the ``usage``
+        information on the help page.  It's automatically created by
+        combining the info names of the chain of contexts to the root.
+        """
+        rv = ""
+        if self.info_name is not None:
+            rv = self.info_name
+        if self.parent is not None:
+            rv = "{} {}".format(self.parent.command_path, rv)
+        return rv.lstrip()
+
+    def find_root(self):
+        """Finds the outermost context."""
+        node = self
+        while node.parent is not None:
+            node = node.parent
+        return node
+
+    def find_object(self, object_type):
+        """Finds the closest object of a given type."""
+        node = self
+        while node is not None:
+            if isinstance(node.obj, object_type):
+                return node.obj
+            node = node.parent
+
+    def ensure_object(self, object_type):
+        """Like :meth:`find_object` but sets the innermost object to a
+        new instance of `object_type` if it does not exist.
+        """
+        rv = self.find_object(object_type)
+        if rv is None:
+            self.obj = rv = object_type()
+        return rv
+
+    def lookup_default(self, name):
+        """Looks up the default for a parameter name.  This by default
+        looks into the :attr:`default_map` if available.
+        """
+        if self.default_map is not None:
+            rv = self.default_map.get(name)
+            if callable(rv):
+                rv = rv()
+            return rv
+
+    def fail(self, message):
+        """Aborts the execution of the program with a specific error
+        message.
+
+        :param message: the error message to fail with.
+        """
+        raise UsageError(message, self)
+
+    def abort(self):
+        """Aborts the script."""
+        raise Abort()
+
+    def exit(self, code=0):
+        """Exits the application with a given exit code."""
+        raise Exit(code)
+
+    def get_usage(self):
+        """Helper method to get formatted usage string for the current
+        context and command.
+        """
+        return self.command.get_usage(self)
+
+    def get_help(self):
+        """Helper method to get formatted help page for the current
+        context and command.
+        """
+        return self.command.get_help(self)
+
+    def invoke(*args, **kwargs):  # noqa: B902
+        """Invokes a command callback in exactly the way it expects.  There
+        are two ways to invoke this method:
+
+        1.  the first argument can be a callback and all other arguments and
+            keyword arguments are forwarded directly to the function.
+        2.  the first argument is a click command object.  In that case all
+            arguments are forwarded as well but proper click parameters
+            (options and click arguments) must be keyword arguments and Click
+            will fill in defaults.
+
+        Note that before Click 3.2 keyword arguments were not properly filled
+        in against the intention of this code and no context was created.  For
+        more information about this change and why it was done in a bugfix
+        release see :ref:`upgrade-to-3.2`.
+        """
+        self, callback = args[:2]
+        ctx = self
+
+        # It's also possible to invoke another command which might or
+        # might not have a callback.  In that case we also fill
+        # in defaults and make a new context for this command.
+        if isinstance(callback, Command):
+            other_cmd = callback
+            callback = other_cmd.callback
+            ctx = Context(other_cmd, info_name=other_cmd.name, parent=self)
+            if callback is None:
+                raise TypeError(
+                    "The given command does not have a callback that can be invoked."
+                )
+
+            for param in other_cmd.params:
+                if param.name not in kwargs and param.expose_value:
+                    kwargs[param.name] = param.get_default(ctx)
+
+        args = args[2:]
+        with augment_usage_errors(self):
+            with ctx:
+                return callback(*args, **kwargs)
+
+    def forward(*args, **kwargs):  # noqa: B902
+        """Similar to :meth:`invoke` but fills in default keyword
+        arguments from the current context if the other command expects
+        it.  This cannot invoke callbacks directly, only other commands.
+        """
+        self, cmd = args[:2]
+
+        # It's also possible to invoke another command which might or
+        # might not have a callback.
+        if not isinstance(cmd, Command):
+            raise TypeError("Callback is not a command.")
+
+        for param in self.params:
+            if param not in kwargs:
+                kwargs[param] = self.params[param]
+
+        return self.invoke(cmd, **kwargs)
+
+
+class BaseCommand(object):
+    """The base command implements the minimal API contract of commands.
+    Most code will never use this as it does not implement a lot of useful
+    functionality but it can act as the direct subclass of alternative
+    parsing methods that do not depend on the Click parser.
+
+    For instance, this can be used to bridge Click and other systems like
+    argparse or docopt.
+
+    Because base commands do not implement a lot of the API that other
+    parts of Click take for granted, they are not supported for all
+    operations.  For instance, they cannot be used with the decorators
+    usually and they have no built-in callback system.
+
+    .. versionchanged:: 2.0
+       Added the `context_settings` parameter.
+
+    :param name: the name of the command to use unless a group overrides it.
+    :param context_settings: an optional dictionary with defaults that are
+                             passed to the context object.
+    """
+
+    #: the default for the :attr:`Context.allow_extra_args` flag.
+    allow_extra_args = False
+    #: the default for the :attr:`Context.allow_interspersed_args` flag.
+    allow_interspersed_args = True
+    #: the default for the :attr:`Context.ignore_unknown_options` flag.
+    ignore_unknown_options = False
+
+    def __init__(self, name, context_settings=None):
+        #: the name the command thinks it has.  Upon registering a command
+        #: on a :class:`Group` the group will default the command name
+        #: with this information.  You should instead use the
+        #: :class:`Context`\'s :attr:`~Context.info_name` attribute.
+        self.name = name
+        if context_settings is None:
+            context_settings = {}
+        #: an optional dictionary with defaults passed to the context.
+        self.context_settings = context_settings
+
+    def __repr__(self):
+        return "<{} {}>".format(self.__class__.__name__, self.name)
+
+    def get_usage(self, ctx):
+        raise NotImplementedError("Base commands cannot get usage")
+
+    def get_help(self, ctx):
+        raise NotImplementedError("Base commands cannot get help")
+
+    def make_context(self, info_name, args, parent=None, **extra):
+        """This function when given an info name and arguments will kick
+        off the parsing and create a new :class:`Context`.  It does not
+        invoke the actual command callback though.
+
+        :param info_name: the info name for this invokation.  Generally this
+                          is the most descriptive name for the script or
+                          command.  For the toplevel script it's usually
+                          the name of the script, for commands below it it's
+                          the name of the script.
+        :param args: the arguments to parse as list of strings.
+        :param parent: the parent context if available.
+        :param extra: extra keyword arguments forwarded to the context
+                      constructor.
+        """
+        for key, value in iteritems(self.context_settings):
+            if key not in extra:
+                extra[key] = value
+        ctx = Context(self, info_name=info_name, parent=parent, **extra)
+        with ctx.scope(cleanup=False):
+            self.parse_args(ctx, args)
+        return ctx
+
+    def parse_args(self, ctx, args):
+        """Given a context and a list of arguments this creates the parser
+        and parses the arguments, then modifies the context as necessary.
+        This is automatically invoked by :meth:`make_context`.
+        """
+        raise NotImplementedError("Base commands do not know how to parse arguments.")
+
+    def invoke(self, ctx):
+        """Given a context, this invokes the command.  The default
+        implementation is raising a not implemented error.
+        """
+        raise NotImplementedError("Base commands are not invokable by default")
+
+    def main(
+        self,
+        args=None,
+        prog_name=None,
+        complete_var=None,
+        standalone_mode=True,
+        **extra
+    ):
+        """This is the way to invoke a script with all the bells and
+        whistles as a command line application.  This will always terminate
+        the application after a call.  If this is not wanted, ``SystemExit``
+        needs to be caught.
+
+        This method is also available by directly calling the instance of
+        a :class:`Command`.
+
+        .. versionadded:: 3.0
+           Added the `standalone_mode` flag to control the standalone mode.
+
+        :param args: the arguments that should be used for parsing.  If not
+                     provided, ``sys.argv[1:]`` is used.
+        :param prog_name: the program name that should be used.  By default
+                          the program name is constructed by taking the file
+                          name from ``sys.argv[0]``.
+        :param complete_var: the environment variable that controls the
+                             bash completion support.  The default is
+                             ``"_<prog_name>_COMPLETE"`` with prog_name in
+                             uppercase.
+        :param standalone_mode: the default behavior is to invoke the script
+                                in standalone mode.  Click will then
+                                handle exceptions and convert them into
+                                error messages and the function will never
+                                return but shut down the interpreter.  If
+                                this is set to `False` they will be
+                                propagated to the caller and the return
+                                value of this function is the return value
+                                of :meth:`invoke`.
+        :param extra: extra keyword arguments are forwarded to the context
+                      constructor.  See :class:`Context` for more information.
+        """
+        # If we are in Python 3, we will verify that the environment is
+        # sane at this point or reject further execution to avoid a
+        # broken script.
+        if not PY2:
+            _verify_python3_env()
+        else:
+            _check_for_unicode_literals()
+
+        if args is None:
+            args = get_os_args()
+        else:
+            args = list(args)
+
+        if prog_name is None:
+            prog_name = make_str(
+                os.path.basename(sys.argv[0] if sys.argv else __file__)
+            )
+
+        # Hook for the Bash completion.  This only activates if the Bash
+        # completion is actually enabled, otherwise this is quite a fast
+        # noop.
+        _bashcomplete(self, prog_name, complete_var)
+
+        try:
+            try:
+                with self.make_context(prog_name, args, **extra) as ctx:
+                    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)
+                raise Abort()
+            except ClickException as e:
+                if not standalone_mode:
+                    raise
+                e.show()
+                sys.exit(e.exit_code)
+            except IOError as e:
+                if e.errno == errno.EPIPE:
+                    sys.stdout = PacifyFlushWrapper(sys.stdout)
+                    sys.stderr = PacifyFlushWrapper(sys.stderr)
+                    sys.exit(1)
+                else:
+                    raise
+        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
+            echo("Aborted!", file=sys.stderr)
+            sys.exit(1)
+
+    def __call__(self, *args, **kwargs):
+        """Alias for :meth:`main`."""
+        return self.main(*args, **kwargs)
+
+
+class Command(BaseCommand):
+    """Commands are the basic building block of command line interfaces in
+    Click.  A basic command handles command line parsing and might dispatch
+    more parsing to commands nested below it.
+
+    .. versionchanged:: 2.0
+       Added the `context_settings` parameter.
+    .. versionchanged:: 7.1
+       Added the `no_args_is_help` parameter.
+
+    :param name: the name of the command to use unless a group overrides it.
+    :param context_settings: an optional dictionary with defaults that are
+                             passed to the context object.
+    :param callback: the callback to invoke.  This is optional.
+    :param params: the parameters to register with this command.  This can
+                   be either :class:`Option` or :class:`Argument` objects.
+    :param help: the help string to use for this command.
+    :param epilog: like the help string but it's printed at the end of the
+                   help page after everything else.
+    :param short_help: the short help to use for this command.  This is
+                       shown on the command listing of the parent command.
+    :param add_help_option: by default each command registers a ``--help``
+                            option.  This can be disabled by this parameter.
+    :param no_args_is_help: this controls what happens if no arguments are
+                            provided.  This option is disabled by default.
+                            If enabled this will add ``--help`` as argument
+                            if no arguments are passed
+    :param hidden: hide this command from help outputs.
+
+    :param deprecated: issues a message indicating that
+                             the command is deprecated.
+    """
+
+    def __init__(
+        self,
+        name,
+        context_settings=None,
+        callback=None,
+        params=None,
+        help=None,
+        epilog=None,
+        short_help=None,
+        options_metavar="[OPTIONS]",
+        add_help_option=True,
+        no_args_is_help=False,
+        hidden=False,
+        deprecated=False,
+    ):
+        BaseCommand.__init__(self, name, context_settings)
+        #: the callback to execute when the command fires.  This might be
+        #: `None` in which case nothing happens.
+        self.callback = callback
+        #: the list of parameters for this command in the order they
+        #: 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
+        self.short_help = short_help
+        self.add_help_option = add_help_option
+        self.no_args_is_help = no_args_is_help
+        self.hidden = hidden
+        self.deprecated = deprecated
+
+    def get_usage(self, ctx):
+        """Formats the usage line into a string and returns it.
+
+        Calls :meth:`format_usage` internally.
+        """
+        formatter = ctx.make_formatter()
+        self.format_usage(ctx, formatter)
+        return formatter.getvalue().rstrip("\n")
+
+    def get_params(self, ctx):
+        rv = self.params
+        help_option = self.get_help_option(ctx)
+        if help_option is not None:
+            rv = rv + [help_option]
+        return rv
+
+    def format_usage(self, ctx, formatter):
+        """Writes the usage line into the formatter.
+
+        This is a low-level method called by :meth:`get_usage`.
+        """
+        pieces = self.collect_usage_pieces(ctx)
+        formatter.write_usage(ctx.command_path, " ".join(pieces))
+
+    def collect_usage_pieces(self, ctx):
+        """Returns all the pieces that go into the usage line and returns
+        it as a list of strings.
+        """
+        rv = [self.options_metavar]
+        for param in self.get_params(ctx):
+            rv.extend(param.get_usage_pieces(ctx))
+        return rv
+
+    def get_help_option_names(self, ctx):
+        """Returns the names for the help option."""
+        all_names = set(ctx.help_option_names)
+        for param in self.params:
+            all_names.difference_update(param.opts)
+            all_names.difference_update(param.secondary_opts)
+        return all_names
+
+    def get_help_option(self, ctx):
+        """Returns the help option object."""
+        help_options = self.get_help_option_names(ctx)
+        if not help_options or not self.add_help_option:
+            return
+
+        def show_help(ctx, param, value):
+            if value and not ctx.resilient_parsing:
+                echo(ctx.get_help(), color=ctx.color)
+                ctx.exit()
+
+        return Option(
+            help_options,
+            is_flag=True,
+            is_eager=True,
+            expose_value=False,
+            callback=show_help,
+            help="Show this message and exit.",
+        )
+
+    def make_parser(self, ctx):
+        """Creates the underlying option parser for this command."""
+        parser = OptionParser(ctx)
+        for param in self.get_params(ctx):
+            param.add_to_parser(parser, ctx)
+        return parser
+
+    def get_help(self, ctx):
+        """Formats the help into a string and returns it.
+
+        Calls :meth:`format_help` internally.
+        """
+        formatter = ctx.make_formatter()
+        self.format_help(ctx, formatter)
+        return formatter.getvalue().rstrip("\n")
+
+    def get_short_help_str(self, limit=45):
+        """Gets short help for the command or makes it by shortening the
+        long help string.
+        """
+        return (
+            self.short_help
+            or self.help
+            and make_default_short_help(self.help, limit)
+            or ""
+        )
+
+    def format_help(self, ctx, formatter):
+        """Writes the help into the formatter if it exists.
+
+        This is a low-level method called by :meth:`get_help`.
+
+        This calls the following methods:
+
+        -   :meth:`format_usage`
+        -   :meth:`format_help_text`
+        -   :meth:`format_options`
+        -   :meth:`format_epilog`
+        """
+        self.format_usage(ctx, formatter)
+        self.format_help_text(ctx, formatter)
+        self.format_options(ctx, formatter)
+        self.format_epilog(ctx, formatter)
+
+    def format_help_text(self, ctx, formatter):
+        """Writes the help text to the formatter if it exists."""
+        if self.help:
+            formatter.write_paragraph()
+            with formatter.indentation():
+                help_text = self.help
+                if self.deprecated:
+                    help_text += DEPRECATED_HELP_NOTICE
+                formatter.write_text(help_text)
+        elif self.deprecated:
+            formatter.write_paragraph()
+            with formatter.indentation():
+                formatter.write_text(DEPRECATED_HELP_NOTICE)
+
+    def format_options(self, ctx, formatter):
+        """Writes all the options into the formatter if they exist."""
+        opts = []
+        for param in self.get_params(ctx):
+            rv = param.get_help_record(ctx)
+            if rv is not None:
+                opts.append(rv)
+
+        if opts:
+            with formatter.section("Options"):
+                formatter.write_dl(opts)
+
+    def format_epilog(self, ctx, formatter):
+        """Writes the epilog into the formatter if it exists."""
+        if self.epilog:
+            formatter.write_paragraph()
+            with formatter.indentation():
+                formatter.write_text(self.epilog)
+
+    def parse_args(self, ctx, args):
+        if not args and self.no_args_is_help and not ctx.resilient_parsing:
+            echo(ctx.get_help(), color=ctx.color)
+            ctx.exit()
+
+        parser = self.make_parser(ctx)
+        opts, args, param_order = parser.parse_args(args=args)
+
+        for param in iter_params_for_processing(param_order, self.get_params(ctx)):
+            value, args = param.handle_parse_result(ctx, opts, args)
+
+        if args and not ctx.allow_extra_args and not ctx.resilient_parsing:
+            ctx.fail(
+                "Got unexpected extra argument{} ({})".format(
+                    "s" if len(args) != 1 else "", " ".join(map(make_str, args))
+                )
+            )
+
+        ctx.args = args
+        return args
+
+    def invoke(self, ctx):
+        """Given a context, this invokes the attached callback (if it exists)
+        in the right way.
+        """
+        _maybe_show_deprecated_notice(self)
+        if self.callback is not None:
+            return ctx.invoke(self.callback, **ctx.params)
+
+
+class MultiCommand(Command):
+    """A multi command is the basic implementation of a command that
+    dispatches to subcommands.  The most common version is the
+    :class:`Group`.
+
+    :param invoke_without_command: this controls how the multi command itself
+                                   is invoked.  By default it's only invoked
+                                   if a subcommand is provided.
+    :param no_args_is_help: this controls what happens if no arguments are
+                            provided.  This option is enabled by default if
+                            `invoke_without_command` is disabled or disabled
+                            if it's enabled.  If enabled this will add
+                            ``--help`` as argument if no arguments are
+                            passed.
+    :param subcommand_metavar: the string that is used in the documentation
+                               to indicate the subcommand place.
+    :param chain: if this is set to `True` chaining of multiple subcommands
+                  is enabled.  This restricts the form of commands in that
+                  they cannot have optional arguments but it allows
+                  multiple commands to be chained together.
+    :param result_callback: the result callback to attach to this multi
+                            command.
+    """
+
+    allow_extra_args = True
+    allow_interspersed_args = False
+
+    def __init__(
+        self,
+        name=None,
+        invoke_without_command=False,
+        no_args_is_help=None,
+        subcommand_metavar=None,
+        chain=False,
+        result_callback=None,
+        **attrs
+    ):
+        Command.__init__(self, name, **attrs)
+        if no_args_is_help is None:
+            no_args_is_help = not invoke_without_command
+        self.no_args_is_help = no_args_is_help
+        self.invoke_without_command = invoke_without_command
+        if subcommand_metavar is None:
+            if chain:
+                subcommand_metavar = SUBCOMMANDS_METAVAR
+            else:
+                subcommand_metavar = SUBCOMMAND_METAVAR
+        self.subcommand_metavar = subcommand_metavar
+        self.chain = chain
+        #: The result callback that is stored.  This can be set or
+        #: overridden with the :func:`resultcallback` decorator.
+        self.result_callback = result_callback
+
+        if self.chain:
+            for param in self.params:
+                if isinstance(param, Argument) and not param.required:
+                    raise RuntimeError(
+                        "Multi commands in chain mode cannot have"
+                        " optional arguments."
+                    )
+
+    def collect_usage_pieces(self, ctx):
+        rv = Command.collect_usage_pieces(self, ctx)
+        rv.append(self.subcommand_metavar)
+        return rv
+
+    def format_options(self, ctx, formatter):
+        Command.format_options(self, ctx, formatter)
+        self.format_commands(ctx, formatter)
+
+    def resultcallback(self, replace=False):
+        """Adds a result callback to the chain command.  By default if a
+        result callback is already registered this will chain them but
+        this can be disabled with the `replace` parameter.  The result
+        callback is invoked with the return value of the subcommand
+        (or the list of return values from all subcommands if chaining
+        is enabled) as well as the parameters as they would be passed
+        to the main callback.
+
+        Example::
+
+            @click.group()
+            @click.option('-i', '--input', default=23)
+            def cli(input):
+                return 42
+
+            @cli.resultcallback()
+            def process_result(result, input):
+                return result + input
+
+        .. versionadded:: 3.0
+
+        :param replace: if set to `True` an already existing result
+                        callback will be removed.
+        """
+
+        def decorator(f):
+            old_callback = self.result_callback
+            if old_callback is None or replace:
+                self.result_callback = f
+                return f
+
+            def function(__value, *args, **kwargs):
+                return f(old_callback(__value, *args, **kwargs), *args, **kwargs)
+
+            self.result_callback = rv = update_wrapper(function, f)
+            return rv
+
+        return decorator
+
+    def format_commands(self, ctx, formatter):
+        """Extra format methods for multi methods that adds all the commands
+        after the options.
+        """
+        commands = []
+        for subcommand in self.list_commands(ctx):
+            cmd = self.get_command(ctx, subcommand)
+            # What is this, the tool lied about a command.  Ignore it
+            if cmd is None:
+                continue
+            if cmd.hidden:
+                continue
+
+            commands.append((subcommand, cmd))
+
+        # allow for 3 times the default spacing
+        if len(commands):
+            limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands)
+
+            rows = []
+            for subcommand, cmd in commands:
+                help = cmd.get_short_help_str(limit)
+                rows.append((subcommand, help))
+
+            if rows:
+                with formatter.section("Commands"):
+                    formatter.write_dl(rows)
+
+    def parse_args(self, ctx, args):
+        if not args and self.no_args_is_help and not ctx.resilient_parsing:
+            echo(ctx.get_help(), color=ctx.color)
+            ctx.exit()
+
+        rest = Command.parse_args(self, ctx, args)
+        if self.chain:
+            ctx.protected_args = rest
+            ctx.args = []
+        elif rest:
+            ctx.protected_args, ctx.args = rest[:1], rest[1:]
+
+        return ctx.args
+
+    def invoke(self, ctx):
+        def _process_result(value):
+            if self.result_callback is not None:
+                value = ctx.invoke(self.result_callback, value, **ctx.params)
+            return value
+
+        if not ctx.protected_args:
+            # If we are invoked without command the chain flag controls
+            # how this happens.  If we are not in chain mode, the return
+            # value here is the return value of the command.
+            # If however we are in chain mode, the return value is the
+            # return value of the result processor invoked with an empty
+            # list (which means that no subcommand actually was executed).
+            if self.invoke_without_command:
+                if not self.chain:
+                    return Command.invoke(self, ctx)
+                with ctx:
+                    Command.invoke(self, ctx)
+                    return _process_result([])
+            ctx.fail("Missing command.")
+
+        # Fetch args back out
+        args = ctx.protected_args + ctx.args
+        ctx.args = []
+        ctx.protected_args = []
+
+        # If we're not in chain mode, we only allow the invocation of a
+        # single command but we also inform the current context about the
+        # name of the command to invoke.
+        if not self.chain:
+            # Make sure the context is entered so we do not clean up
+            # resources until the result processor has worked.
+            with ctx:
+                cmd_name, cmd, args = self.resolve_command(ctx, args)
+                ctx.invoked_subcommand = cmd_name
+                Command.invoke(self, ctx)
+                sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)
+                with sub_ctx:
+                    return _process_result(sub_ctx.command.invoke(sub_ctx))
+
+        # In chain mode we create the contexts step by step, but after the
+        # base command has been invoked.  Because at that point we do not
+        # know the subcommands yet, the invoked subcommand attribute is
+        # set to ``*`` to inform the command that subcommands are executed
+        # but nothing else.
+        with ctx:
+            ctx.invoked_subcommand = "*" if args else None
+            Command.invoke(self, ctx)
+
+            # Otherwise we make every single context and invoke them in a
+            # chain.  In that case the return value to the result processor
+            # is the list of all invoked subcommand's results.
+            contexts = []
+            while args:
+                cmd_name, cmd, args = self.resolve_command(ctx, args)
+                sub_ctx = cmd.make_context(
+                    cmd_name,
+                    args,
+                    parent=ctx,
+                    allow_extra_args=True,
+                    allow_interspersed_args=False,
+                )
+                contexts.append(sub_ctx)
+                args, sub_ctx.args = sub_ctx.args, []
+
+            rv = []
+            for sub_ctx in contexts:
+                with sub_ctx:
+                    rv.append(sub_ctx.command.invoke(sub_ctx))
+            return _process_result(rv)
+
+    def resolve_command(self, ctx, args):
+        cmd_name = make_str(args[0])
+        original_cmd_name = cmd_name
+
+        # Get the command
+        cmd = self.get_command(ctx, cmd_name)
+
+        # If we can't find the command but there is a normalization
+        # function available, we try with that one.
+        if cmd is None and ctx.token_normalize_func is not None:
+            cmd_name = ctx.token_normalize_func(cmd_name)
+            cmd = self.get_command(ctx, cmd_name)
+
+        # If we don't find the command we want to show an error message
+        # to the user that it was not provided.  However, there is
+        # something else we should do: if the first argument looks like
+        # 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 split_opt(cmd_name)[0]:
+                self.parse_args(ctx, ctx.args)
+            ctx.fail("No such command '{}'.".format(original_cmd_name))
+
+        return cmd_name, cmd, args[1:]
+
+    def get_command(self, ctx, cmd_name):
+        """Given a context and a command name, this returns a
+        :class:`Command` object if it exists or returns `None`.
+        """
+        raise NotImplementedError()
+
+    def list_commands(self, ctx):
+        """Returns a list of subcommand names in the order they should
+        appear.
+        """
+        return []
+
+
+class Group(MultiCommand):
+    """A group allows a command to have subcommands attached.  This is the
+    most common way to implement nesting in Click.
+
+    :param commands: a dictionary of commands.
+    """
+
+    def __init__(self, name=None, commands=None, **attrs):
+        MultiCommand.__init__(self, name, **attrs)
+        #: the registered subcommands by their exported names.
+        self.commands = commands or {}
+
+    def add_command(self, cmd, name=None):
+        """Registers another :class:`Command` with this group.  If the name
+        is not provided, the name of the command is used.
+        """
+        name = name or cmd.name
+        if name is None:
+            raise TypeError("Command has no name.")
+        _check_multicommand(self, name, cmd, register=True)
+        self.commands[name] = cmd
+
+    def command(self, *args, **kwargs):
+        """A shortcut decorator for declaring and attaching a command to
+        the group.  This takes the same arguments as :func:`command` but
+        immediately registers the created command with this instance by
+        calling into :meth:`add_command`.
+        """
+        from .decorators import command
+
+        def decorator(f):
+            cmd = command(*args, **kwargs)(f)
+            self.add_command(cmd)
+            return cmd
+
+        return decorator
+
+    def group(self, *args, **kwargs):
+        """A shortcut decorator for declaring and attaching a group to
+        the group.  This takes the same arguments as :func:`group` but
+        immediately registers the created command with this instance by
+        calling into :meth:`add_command`.
+        """
+        from .decorators import group
+
+        def decorator(f):
+            cmd = group(*args, **kwargs)(f)
+            self.add_command(cmd)
+            return cmd
+
+        return decorator
+
+    def get_command(self, ctx, cmd_name):
+        return self.commands.get(cmd_name)
+
+    def list_commands(self, ctx):
+        return sorted(self.commands)
+
+
+class CommandCollection(MultiCommand):
+    """A command collection is a multi command that merges multiple multi
+    commands together into one.  This is a straightforward implementation
+    that accepts a list of different multi commands as sources and
+    provides all the commands for each of them.
+    """
+
+    def __init__(self, name=None, sources=None, **attrs):
+        MultiCommand.__init__(self, name, **attrs)
+        #: The list of registered multi commands.
+        self.sources = sources or []
+
+    def add_source(self, multi_cmd):
+        """Adds a new multi command to the chain dispatcher."""
+        self.sources.append(multi_cmd)
+
+    def get_command(self, ctx, cmd_name):
+        for source in self.sources:
+            rv = source.get_command(ctx, cmd_name)
+            if rv is not None:
+                if self.chain:
+                    _check_multicommand(self, cmd_name, rv)
+                return rv
+
+    def list_commands(self, ctx):
+        rv = set()
+        for source in self.sources:
+            rv.update(source.list_commands(ctx))
+        return sorted(rv)
+
+
+class Parameter(object):
+    r"""A parameter to a command comes in two versions: they are either
+    :class:`Option`\s or :class:`Argument`\s.  Other subclasses are currently
+    not supported by design as some of the internals for parsing are
+    intentionally not finalized.
+
+    Some settings are supported by both options and arguments.
+
+    :param param_decls: the parameter declarations for this option or
+                        argument.  This is a list of flags or argument
+                        names.
+    :param type: the type that should be used.  Either a :class:`ParamType`
+                 or a Python type.  The later is converted into the former
+                 automatically if supported.
+    :param required: controls if this is optional or not.
+    :param default: the default value if omitted.  This can also be a callable,
+                    in which case it's invoked when the default is needed
+                    without any arguments.
+    :param callback: a callback that should be executed after the parameter
+                     was matched.  This is called as ``fn(ctx, param,
+                     value)`` and needs to return the value.
+    :param nargs: the number of arguments to match.  If not ``1`` the return
+                  value is a tuple instead of single value.  The default for
+                  nargs is ``1`` (except if the type is a tuple, then it's
+                  the arity of the tuple).
+    :param metavar: how the value is represented in the help page.
+    :param expose_value: if this is `True` then the value is passed onwards
+                         to the command callback and stored on the context,
+                         otherwise it's skipped.
+    :param is_eager: eager values are processed before non eager ones.  This
+                     should not be set for arguments or it will inverse the
+                     order of processing.
+    :param envvar: a string or list of strings that are environment variables
+                   that should be checked.
+
+    .. versionchanged:: 7.1
+        Empty environment variables are ignored rather than taking the
+        empty string value. This makes it possible for scripts to clear
+        variables if they can't unset them.
+
+    .. versionchanged:: 2.0
+        Changed signature for parameter callback to also be passed the
+        parameter. The old callback format will still work, but it will
+        raise a warning to give you a chance to migrate the code easier.
+    """
+    param_type_name = "parameter"
+
+    def __init__(
+        self,
+        param_decls=None,
+        type=None,
+        required=False,
+        default=None,
+        callback=None,
+        nargs=None,
+        metavar=None,
+        expose_value=True,
+        is_eager=False,
+        envvar=None,
+        autocompletion=None,
+    ):
+        self.name, self.opts, self.secondary_opts = self._parse_decls(
+            param_decls or (), expose_value
+        )
+
+        self.type = convert_type(type, default)
+
+        # Default nargs to what the type tells us if we have that
+        # information available.
+        if nargs is None:
+            if self.type.is_composite:
+                nargs = self.type.arity
+            else:
+                nargs = 1
+
+        self.required = required
+        self.callback = callback
+        self.nargs = nargs
+        self.multiple = False
+        self.expose_value = expose_value
+        self.default = default
+        self.is_eager = is_eager
+        self.metavar = metavar
+        self.envvar = envvar
+        self.autocompletion = autocompletion
+
+    def __repr__(self):
+        return "<{} {}>".format(self.__class__.__name__, self.name)
+
+    @property
+    def human_readable_name(self):
+        """Returns the human readable name of this parameter.  This is the
+        same as the name for options, but the metavar for arguments.
+        """
+        return self.name
+
+    def make_metavar(self):
+        if self.metavar is not None:
+            return self.metavar
+        metavar = self.type.get_metavar(self)
+        if metavar is None:
+            metavar = self.type.name.upper()
+        if self.nargs != 1:
+            metavar += "..."
+        return metavar
+
+    def get_default(self, ctx):
+        """Given a context variable this calculates the default value."""
+        # Otherwise go with the regular default.
+        if callable(self.default):
+            rv = self.default()
+        else:
+            rv = self.default
+        return self.type_cast_value(ctx, rv)
+
+    def add_to_parser(self, parser, ctx):
+        pass
+
+    def consume_value(self, ctx, opts):
+        value = opts.get(self.name)
+        if value is None:
+            value = self.value_from_envvar(ctx)
+        if value is None:
+            value = ctx.lookup_default(self.name)
+        return value
+
+    def type_cast_value(self, ctx, value):
+        """Given a value this runs it properly through the type system.
+        This automatically handles things like `nargs` and `multiple` as
+        well as composite types.
+        """
+        if self.type.is_composite:
+            if self.nargs <= 1:
+                raise TypeError(
+                    "Attempted to invoke composite type but nargs has"
+                    " been set to {}. This is not supported; nargs"
+                    " needs to be set to a fixed value > 1.".format(self.nargs)
+                )
+            if self.multiple:
+                return tuple(self.type(x or (), self, ctx) for x in value or ())
+            return self.type(value or (), self, ctx)
+
+        def _convert(value, level):
+            if level == 0:
+                return self.type(value, self, ctx)
+            return tuple(_convert(x, level - 1) for x in value or ())
+
+        return _convert(value, (self.nargs != 1) + bool(self.multiple))
+
+    def process_value(self, ctx, value):
+        """Given a value and context this runs the logic to convert the
+        value as necessary.
+        """
+        # If the value we were given is None we do nothing.  This way
+        # code that calls this can easily figure out if something was
+        # not provided.  Otherwise it would be converted into an empty
+        # tuple for multiple invocations which is inconvenient.
+        if value is not None:
+            return self.type_cast_value(ctx, value)
+
+    def value_is_missing(self, value):
+        if value is None:
+            return True
+        if (self.nargs != 1 or self.multiple) and value == ():
+            return True
+        return False
+
+    def full_process_value(self, ctx, value):
+        value = self.process_value(ctx, value)
+
+        if value is None and not ctx.resilient_parsing:
+            value = self.get_default(ctx)
+
+        if self.required and self.value_is_missing(value):
+            raise MissingParameter(ctx=ctx, param=self)
+
+        return value
+
+    def resolve_envvar_value(self, ctx):
+        if self.envvar is None:
+            return
+        if isinstance(self.envvar, (tuple, list)):
+            for envvar in self.envvar:
+                rv = os.environ.get(envvar)
+                if rv is not None:
+                    return rv
+        else:
+            rv = os.environ.get(self.envvar)
+
+            if rv != "":
+                return rv
+
+    def value_from_envvar(self, ctx):
+        rv = self.resolve_envvar_value(ctx)
+        if rv is not None and self.nargs != 1:
+            rv = self.type.split_envvar_value(rv)
+        return rv
+
+    def handle_parse_result(self, ctx, opts, args):
+        with augment_usage_errors(ctx, param=self):
+            value = self.consume_value(ctx, opts)
+            try:
+                value = self.full_process_value(ctx, value)
+            except Exception:
+                if not ctx.resilient_parsing:
+                    raise
+                value = None
+            if self.callback is not None:
+                try:
+                    value = invoke_param_callback(self.callback, ctx, self, value)
+                except Exception:
+                    if not ctx.resilient_parsing:
+                        raise
+
+        if self.expose_value:
+            ctx.params[self.name] = value
+        return value, args
+
+    def get_help_record(self, ctx):
+        pass
+
+    def get_usage_pieces(self, ctx):
+        return []
+
+    def get_error_hint(self, ctx):
+        """Get a stringified version of the param for use in error messages to
+        indicate which param caused the error.
+        """
+        hint_list = self.opts or [self.human_readable_name]
+        return " / ".join(repr(x) for x in hint_list)
+
+
+class Option(Parameter):
+    """Options are usually optional values on the command line and
+    have some extra features that arguments don't have.
+
+    All other parameters are passed onwards to the parameter constructor.
+
+    :param show_default: controls if the default value should be shown on the
+                         help page. Normally, defaults are not shown. If this
+                         value is a string, it shows the string instead of the
+                         value. This is particularly useful for dynamic options.
+    :param show_envvar: controls if an environment variable should be shown on
+                        the help page.  Normally, environment variables
+                        are not shown.
+    :param prompt: if set to `True` or a non empty string then the user will be
+                   prompted for input.  If set to `True` the prompt will be the
+                   option name capitalized.
+    :param confirmation_prompt: if set then the value will need to be confirmed
+                                if it was prompted for.
+    :param hide_input: if this is `True` then the input on the prompt will be
+                       hidden from the user.  This is useful for password
+                       input.
+    :param is_flag: forces this option to act as a flag.  The default is
+                    auto detection.
+    :param flag_value: which value should be used for this flag if it's
+                       enabled.  This is set to a boolean automatically if
+                       the option string contains a slash to mark two options.
+    :param multiple: if this is set to `True` then the argument is accepted
+                     multiple times and recorded.  This is similar to ``nargs``
+                     in how it works but supports arbitrary number of
+                     arguments.
+    :param count: this flag makes an option increment an integer.
+    :param allow_from_autoenv: if this is enabled then the value of this
+                               parameter will be pulled from an environment
+                               variable in case a prefix is defined on the
+                               context.
+    :param help: the help string.
+    :param hidden: hide this option from help outputs.
+    """
+
+    param_type_name = "option"
+
+    def __init__(
+        self,
+        param_decls=None,
+        show_default=False,
+        prompt=False,
+        confirmation_prompt=False,
+        hide_input=False,
+        is_flag=None,
+        flag_value=None,
+        multiple=False,
+        count=False,
+        allow_from_autoenv=True,
+        type=None,
+        help=None,
+        hidden=False,
+        show_choices=True,
+        show_envvar=False,
+        **attrs
+    ):
+        default_is_missing = attrs.get("default", _missing) is _missing
+        Parameter.__init__(self, param_decls, type=type, **attrs)
+
+        if prompt is True:
+            prompt_text = self.name.replace("_", " ").capitalize()
+        elif prompt is False:
+            prompt_text = None
+        else:
+            prompt_text = prompt
+        self.prompt = prompt_text
+        self.confirmation_prompt = confirmation_prompt
+        self.hide_input = hide_input
+        self.hidden = hidden
+
+        # Flags
+        if is_flag is None:
+            if flag_value is not None:
+                is_flag = True
+            else:
+                is_flag = bool(self.secondary_opts)
+        if is_flag and default_is_missing:
+            self.default = False
+        if flag_value is None:
+            flag_value = not self.default
+        self.is_flag = is_flag
+        self.flag_value = flag_value
+        if self.is_flag and isinstance(self.flag_value, bool) and type in [None, bool]:
+            self.type = BOOL
+            self.is_bool_flag = True
+        else:
+            self.is_bool_flag = False
+
+        # Counting
+        self.count = count
+        if count:
+            if type is None:
+                self.type = IntRange(min=0)
+            if default_is_missing:
+                self.default = 0
+
+        self.multiple = multiple
+        self.allow_from_autoenv = allow_from_autoenv
+        self.help = help
+        self.show_default = show_default
+        self.show_choices = show_choices
+        self.show_envvar = show_envvar
+
+        # Sanity check for stuff we don't support
+        if __debug__:
+            if self.nargs < 0:
+                raise TypeError("Options cannot have nargs < 0")
+            if self.prompt and self.is_flag and not self.is_bool_flag:
+                raise TypeError("Cannot prompt for flags that are not bools.")
+            if not self.is_bool_flag and self.secondary_opts:
+                raise TypeError("Got secondary option for non boolean flag.")
+            if self.is_bool_flag and self.hide_input and self.prompt is not None:
+                raise TypeError("Hidden input does not work with boolean flag prompts.")
+            if self.count:
+                if self.multiple:
+                    raise TypeError(
+                        "Options cannot be multiple and count at the same time."
+                    )
+                elif self.is_flag:
+                    raise TypeError(
+                        "Options cannot be count and flags at the same time."
+                    )
+
+    def _parse_decls(self, decls, expose_value):
+        opts = []
+        secondary_opts = []
+        name = None
+        possible_names = []
+
+        for decl in decls:
+            if isidentifier(decl):
+                if name is not None:
+                    raise TypeError("Name defined twice")
+                name = decl
+            else:
+                split_char = ";" if decl[:1] == "/" else "/"
+                if split_char in decl:
+                    first, second = decl.split(split_char, 1)
+                    first = first.rstrip()
+                    if first:
+                        possible_names.append(split_opt(first))
+                        opts.append(first)
+                    second = second.lstrip()
+                    if second:
+                        secondary_opts.append(second.lstrip())
+                else:
+                    possible_names.append(split_opt(decl))
+                    opts.append(decl)
+
+        if name is None and possible_names:
+            possible_names.sort(key=lambda x: -len(x[0]))  # group long options first
+            name = possible_names[0][1].replace("-", "_").lower()
+            if not isidentifier(name):
+                name = None
+
+        if name is None:
+            if not expose_value:
+                return None, opts, secondary_opts
+            raise TypeError("Could not determine name for option")
+
+        if not opts and not secondary_opts:
+            raise TypeError(
+                "No options defined but a name was passed ({}). Did you"
+                " mean to declare an argument instead of an option?".format(name)
+            )
+
+        return name, opts, secondary_opts
+
+    def add_to_parser(self, parser, ctx):
+        kwargs = {
+            "dest": self.name,
+            "nargs": self.nargs,
+            "obj": self,
+        }
+
+        if self.multiple:
+            action = "append"
+        elif self.count:
+            action = "count"
+        else:
+            action = "store"
+
+        if self.is_flag:
+            kwargs.pop("nargs", None)
+            action_const = "{}_const".format(action)
+            if self.is_bool_flag and self.secondary_opts:
+                parser.add_option(self.opts, action=action_const, const=True, **kwargs)
+                parser.add_option(
+                    self.secondary_opts, action=action_const, const=False, **kwargs
+                )
+            else:
+                parser.add_option(
+                    self.opts, action=action_const, const=self.flag_value, **kwargs
+                )
+        else:
+            kwargs["action"] = action
+            parser.add_option(self.opts, **kwargs)
+
+    def get_help_record(self, ctx):
+        if self.hidden:
+            return
+        any_prefix_is_slash = []
+
+        def _write_opts(opts):
+            rv, any_slashes = join_options(opts)
+            if any_slashes:
+                any_prefix_is_slash[:] = [True]
+            if not self.is_flag and not self.count:
+                rv += " {}".format(self.make_metavar())
+            return rv
+
+        rv = [_write_opts(self.opts)]
+        if self.secondary_opts:
+            rv.append(_write_opts(self.secondary_opts))
+
+        help = self.help or ""
+        extra = []
+        if self.show_envvar:
+            envvar = self.envvar
+            if envvar is None:
+                if self.allow_from_autoenv and ctx.auto_envvar_prefix is not None:
+                    envvar = "{}_{}".format(ctx.auto_envvar_prefix, self.name.upper())
+            if envvar is not None:
+                extra.append(
+                    "env var: {}".format(
+                        ", ".join(str(d) for d in envvar)
+                        if isinstance(envvar, (list, tuple))
+                        else envvar
+                    )
+                )
+        if self.default is not None and (self.show_default or ctx.show_default):
+            if isinstance(self.show_default, string_types):
+                default_string = "({})".format(self.show_default)
+            elif isinstance(self.default, (list, tuple)):
+                default_string = ", ".join(str(d) for d in self.default)
+            elif inspect.isfunction(self.default):
+                default_string = "(dynamic)"
+            else:
+                default_string = self.default
+            extra.append("default: {}".format(default_string))
+
+        if self.required:
+            extra.append("required")
+        if extra:
+            help = "{}[{}]".format(
+                "{}  ".format(help) if help else "", "; ".join(extra)
+            )
+
+        return ("; " if any_prefix_is_slash else " / ").join(rv), help
+
+    def get_default(self, ctx):
+        # If we're a non boolean flag our default is more complex because
+        # we need to look at all flags in the same group to figure out
+        # if we're the the default one in which case we return the flag
+        # value as default.
+        if self.is_flag and not self.is_bool_flag:
+            for param in ctx.command.params:
+                if param.name == self.name and param.default:
+                    return param.flag_value
+            return None
+        return Parameter.get_default(self, ctx)
+
+    def prompt_for_value(self, ctx):
+        """This is an alternative flow that can be activated in the full
+        value processing if a value does not exist.  It will prompt the
+        user until a valid value exists and then returns the processed
+        value as result.
+        """
+        # Calculate the default before prompting anything to be stable.
+        default = self.get_default(ctx)
+
+        # If this is a prompt for a flag we need to handle this
+        # differently.
+        if self.is_bool_flag:
+            return confirm(self.prompt, default)
+
+        return prompt(
+            self.prompt,
+            default=default,
+            type=self.type,
+            hide_input=self.hide_input,
+            show_choices=self.show_choices,
+            confirmation_prompt=self.confirmation_prompt,
+            value_proc=lambda x: self.process_value(ctx, x),
+        )
+
+    def resolve_envvar_value(self, ctx):
+        rv = Parameter.resolve_envvar_value(self, ctx)
+        if rv is not None:
+            return rv
+        if self.allow_from_autoenv and ctx.auto_envvar_prefix is not None:
+            envvar = "{}_{}".format(ctx.auto_envvar_prefix, self.name.upper())
+            return os.environ.get(envvar)
+
+    def value_from_envvar(self, ctx):
+        rv = self.resolve_envvar_value(ctx)
+        if rv is None:
+            return None
+        value_depth = (self.nargs != 1) + bool(self.multiple)
+        if value_depth > 0 and rv is not None:
+            rv = self.type.split_envvar_value(rv)
+            if self.multiple and self.nargs != 1:
+                rv = batch(rv, self.nargs)
+        return rv
+
+    def full_process_value(self, ctx, value):
+        if value is None and self.prompt is not None and not ctx.resilient_parsing:
+            return self.prompt_for_value(ctx)
+        return Parameter.full_process_value(self, ctx, value)
+
+
+class Argument(Parameter):
+    """Arguments are positional parameters to a command.  They generally
+    provide fewer features than options but can have infinite ``nargs``
+    and are required by default.
+
+    All parameters are passed onwards to the parameter constructor.
+    """
+
+    param_type_name = "argument"
+
+    def __init__(self, param_decls, required=None, **attrs):
+        if required is None:
+            if attrs.get("default") is not None:
+                required = False
+            else:
+                required = attrs.get("nargs", 1) > 0
+        Parameter.__init__(self, param_decls, required=required, **attrs)
+        if self.default is not None and self.nargs < 0:
+            raise TypeError(
+                "nargs=-1 in combination with a default value is not supported."
+            )
+
+    @property
+    def human_readable_name(self):
+        if self.metavar is not None:
+            return self.metavar
+        return self.name.upper()
+
+    def make_metavar(self):
+        if self.metavar is not None:
+            return self.metavar
+        var = self.type.get_metavar(self)
+        if not var:
+            var = self.name.upper()
+        if not self.required:
+            var = "[{}]".format(var)
+        if self.nargs != 1:
+            var += "..."
+        return var
+
+    def _parse_decls(self, decls, expose_value):
+        if not decls:
+            if not expose_value:
+                return None, [], []
+            raise TypeError("Could not determine name for argument")
+        if len(decls) == 1:
+            name = arg = decls[0]
+            name = name.replace("-", "_").lower()
+        else:
+            raise TypeError(
+                "Arguments take exactly one parameter declaration, got"
+                " {}".format(len(decls))
+            )
+        return name, [arg], []
+
+    def get_usage_pieces(self, ctx):
+        return [self.make_metavar()]
+
+    def get_error_hint(self, ctx):
+        return repr(self.make_metavar())
+
+    def add_to_parser(self, parser, ctx):
+        parser.add_argument(dest=self.name, nargs=self.nargs, obj=self)