aboutsummaryrefslogtreecommitdiffstats
path: root/python/click/decorators.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/click/decorators.py')
-rw-r--r--python/click/decorators.py311
1 files changed, 0 insertions, 311 deletions
diff --git a/python/click/decorators.py b/python/click/decorators.py
deleted file mode 100644
index c57c530..0000000
--- a/python/click/decorators.py
+++ /dev/null
@@ -1,311 +0,0 @@
-import sys
-import inspect
-
-from functools import update_wrapper
-
-from ._compat import iteritems
-from ._unicodefun import _check_for_unicode_literals
-from .utils import echo
-from .globals import get_current_context
-
-
-def pass_context(f):
- """Marks a callback as wanting to receive the current context
- object as first argument.
- """
- def new_func(*args, **kwargs):
- return f(get_current_context(), *args, **kwargs)
- return update_wrapper(new_func, f)
-
-
-def pass_obj(f):
- """Similar to :func:`pass_context`, but only pass the object on the
- context onwards (:attr:`Context.obj`). This is useful if that object
- represents the state of a nested system.
- """
- def new_func(*args, **kwargs):
- return f(get_current_context().obj, *args, **kwargs)
- return update_wrapper(new_func, f)
-
-
-def make_pass_decorator(object_type, ensure=False):
- """Given an object type this creates a decorator that will work
- similar to :func:`pass_obj` but instead of passing the object of the
- current context, it will find the innermost context of type
- :func:`object_type`.
-
- This generates a decorator that works roughly like this::
-
- from functools import update_wrapper
-
- def decorator(f):
- @pass_context
- def new_func(ctx, *args, **kwargs):
- obj = ctx.find_object(object_type)
- return ctx.invoke(f, obj, *args, **kwargs)
- return update_wrapper(new_func, f)
- return decorator
-
- :param object_type: the type of the object to pass.
- :param ensure: if set to `True`, a new object will be created and
- remembered on the context if it's not there yet.
- """
- def decorator(f):
- def new_func(*args, **kwargs):
- ctx = get_current_context()
- if ensure:
- obj = ctx.ensure_object(object_type)
- else:
- obj = ctx.find_object(object_type)
- if obj is None:
- raise RuntimeError('Managed to invoke callback without a '
- 'context object of type %r existing'
- % object_type.__name__)
- return ctx.invoke(f, obj, *args, **kwargs)
- return update_wrapper(new_func, f)
- return decorator
-
-
-def _make_command(f, name, attrs, cls):
- if isinstance(f, Command):
- raise TypeError('Attempted to convert a callback into a '
- 'command twice.')
- try:
- params = f.__click_params__
- params.reverse()
- del f.__click_params__
- except AttributeError:
- params = []
- help = attrs.get('help')
- if help is None:
- help = inspect.getdoc(f)
- if isinstance(help, bytes):
- help = help.decode('utf-8')
- else:
- help = inspect.cleandoc(help)
- attrs['help'] = help
- _check_for_unicode_literals()
- return cls(name=name or f.__name__.lower().replace('_', '-'),
- callback=f, params=params, **attrs)
-
-
-def command(name=None, cls=None, **attrs):
- r"""Creates a new :class:`Command` and uses the decorated function as
- callback. This will also automatically attach all decorated
- :func:`option`\s and :func:`argument`\s as parameters to the command.
-
- The name of the command defaults to the name of the function. If you
- want to change that, you can pass the intended name as the first
- argument.
-
- All keyword arguments are forwarded to the underlying command class.
-
- Once decorated the function turns into a :class:`Command` instance
- that can be invoked as a command line utility or be attached to a
- command :class:`Group`.
-
- :param name: the name of the command. This defaults to the function
- name with underscores replaced by dashes.
- :param cls: the command class to instantiate. This defaults to
- :class:`Command`.
- """
- if cls is None:
- cls = Command
- def decorator(f):
- cmd = _make_command(f, name, attrs, cls)
- cmd.__doc__ = f.__doc__
- return cmd
- return decorator
-
-
-def group(name=None, **attrs):
- """Creates a new :class:`Group` with a function as callback. This
- works otherwise the same as :func:`command` just that the `cls`
- parameter is set to :class:`Group`.
- """
- attrs.setdefault('cls', Group)
- return command(name, **attrs)
-
-
-def _param_memo(f, param):
- if isinstance(f, Command):
- f.params.append(param)
- else:
- if not hasattr(f, '__click_params__'):
- f.__click_params__ = []
- f.__click_params__.append(param)
-
-
-def argument(*param_decls, **attrs):
- """Attaches an argument to the command. All positional arguments are
- passed as parameter declarations to :class:`Argument`; all keyword
- arguments are forwarded unchanged (except ``cls``).
- This is equivalent to creating an :class:`Argument` instance manually
- and attaching it to the :attr:`Command.params` list.
-
- :param cls: the argument class to instantiate. This defaults to
- :class:`Argument`.
- """
- def decorator(f):
- ArgumentClass = attrs.pop('cls', Argument)
- _param_memo(f, ArgumentClass(param_decls, **attrs))
- return f
- return decorator
-
-
-def option(*param_decls, **attrs):
- """Attaches an option to the command. All positional arguments are
- passed as parameter declarations to :class:`Option`; all keyword
- arguments are forwarded unchanged (except ``cls``).
- This is equivalent to creating an :class:`Option` instance manually
- and attaching it to the :attr:`Command.params` list.
-
- :param cls: the option class to instantiate. This defaults to
- :class:`Option`.
- """
- def decorator(f):
- # Issue 926, copy attrs, so pre-defined options can re-use the same cls=
- option_attrs = attrs.copy()
-
- if 'help' in option_attrs:
- option_attrs['help'] = inspect.cleandoc(option_attrs['help'])
- OptionClass = option_attrs.pop('cls', Option)
- _param_memo(f, OptionClass(param_decls, **option_attrs))
- return f
- return decorator
-
-
-def confirmation_option(*param_decls, **attrs):
- """Shortcut for confirmation prompts that can be ignored by passing
- ``--yes`` as parameter.
-
- This is equivalent to decorating a function with :func:`option` with
- the following parameters::
-
- def callback(ctx, param, value):
- if not value:
- ctx.abort()
-
- @click.command()
- @click.option('--yes', is_flag=True, callback=callback,
- expose_value=False, prompt='Do you want to continue?')
- def dropdb():
- pass
- """
- def decorator(f):
- def callback(ctx, param, value):
- if not value:
- ctx.abort()
- attrs.setdefault('is_flag', True)
- attrs.setdefault('callback', callback)
- attrs.setdefault('expose_value', False)
- attrs.setdefault('prompt', 'Do you want to continue?')
- attrs.setdefault('help', 'Confirm the action without prompting.')
- return option(*(param_decls or ('--yes',)), **attrs)(f)
- return decorator
-
-
-def password_option(*param_decls, **attrs):
- """Shortcut for password prompts.
-
- This is equivalent to decorating a function with :func:`option` with
- the following parameters::
-
- @click.command()
- @click.option('--password', prompt=True, confirmation_prompt=True,
- hide_input=True)
- def changeadmin(password):
- pass
- """
- def decorator(f):
- attrs.setdefault('prompt', True)
- attrs.setdefault('confirmation_prompt', True)
- attrs.setdefault('hide_input', True)
- return option(*(param_decls or ('--password',)), **attrs)(f)
- return decorator
-
-
-def version_option(version=None, *param_decls, **attrs):
- """Adds a ``--version`` option which immediately ends the program
- printing out the version number. This is implemented as an eager
- option that prints the version and exits the program in the callback.
-
- :param version: the version number to show. If not provided Click
- attempts an auto discovery via setuptools.
- :param prog_name: the name of the program (defaults to autodetection)
- :param message: custom message to show instead of the default
- (``'%(prog)s, version %(version)s'``)
- :param others: everything else is forwarded to :func:`option`.
- """
- if version is None:
- if hasattr(sys, '_getframe'):
- module = sys._getframe(1).f_globals.get('__name__')
- else:
- module = ''
-
- def decorator(f):
- prog_name = attrs.pop('prog_name', None)
- message = attrs.pop('message', '%(prog)s, version %(version)s')
-
- def callback(ctx, param, value):
- if not value or ctx.resilient_parsing:
- return
- prog = prog_name
- if prog is None:
- prog = ctx.find_root().info_name
- ver = version
- if ver is None:
- try:
- import pkg_resources
- except ImportError:
- pass
- else:
- for dist in pkg_resources.working_set:
- scripts = dist.get_entry_map().get('console_scripts') or {}
- for script_name, entry_point in iteritems(scripts):
- if entry_point.module_name == module:
- ver = dist.version
- break
- if ver is None:
- raise RuntimeError('Could not determine version')
- echo(message % {
- 'prog': prog,
- 'version': ver,
- }, color=ctx.color)
- ctx.exit()
-
- attrs.setdefault('is_flag', True)
- attrs.setdefault('expose_value', False)
- attrs.setdefault('is_eager', True)
- attrs.setdefault('help', 'Show the version and exit.')
- attrs['callback'] = callback
- return option(*(param_decls or ('--version',)), **attrs)(f)
- return decorator
-
-
-def help_option(*param_decls, **attrs):
- """Adds a ``--help`` option which immediately ends the program
- printing out the help page. This is usually unnecessary to add as
- this is added by default to all commands unless suppressed.
-
- Like :func:`version_option`, this is implemented as eager option that
- prints in the callback and exits.
-
- All arguments are forwarded to :func:`option`.
- """
- def decorator(f):
- def callback(ctx, param, value):
- if value and not ctx.resilient_parsing:
- echo(ctx.get_help(), color=ctx.color)
- ctx.exit()
- attrs.setdefault('is_flag', True)
- attrs.setdefault('expose_value', False)
- attrs.setdefault('help', 'Show this message and exit.')
- attrs.setdefault('is_eager', True)
- attrs['callback'] = callback
- return option(*(param_decls or ('--help',)), **attrs)(f)
- return decorator
-
-
-# Circular dependencies between core and decorators
-from .core import Command, Group, Argument, Option