From 2b2e73e7df90d38175e035d6ada4d752120dc0ec Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 11:39:29 -0700 Subject: Removed depreciated code from frontend.py; frontend.py no longer imports ipa_types --- ipalib/frontend.py | 453 +---------------------------------------------------- 1 file changed, 3 insertions(+), 450 deletions(-) (limited to 'ipalib/frontend.py') diff --git a/ipalib/frontend.py b/ipalib/frontend.py index c614e5479..baa37b176 100644 --- a/ipalib/frontend.py +++ b/ipalib/frontend.py @@ -27,7 +27,7 @@ import plugable from plugable import lock, check_name import errors from errors import check_type, check_isinstance, raise_TypeError -import ipa_types +import parameters from util import make_repr @@ -42,453 +42,6 @@ def is_rule(obj): return callable(obj) and getattr(obj, RULE_FLAG, False) is True -class DefaultFrom(plugable.ReadOnly): - """ - Derive a default value from other supplied values. - - For example, say you wanted to create a default for the user's login from - the user's first and last names. It could be implemented like this: - - >>> login = DefaultFrom(lambda first, last: first[0] + last) - >>> login(first='John', last='Doe') - 'JDoe' - - If you do not explicitly provide keys when you create a DefaultFrom - instance, the keys are implicitly derived from your callback by - inspecting ``callback.func_code.co_varnames``. The keys are available - through the ``DefaultFrom.keys`` instance attribute, like this: - - >>> login.keys - ('first', 'last') - - The callback is available through the ``DefaultFrom.callback`` instance - attribute, like this: - - >>> login.callback # doctest:+ELLIPSIS - at 0x...> - >>> login.callback.func_code.co_varnames # The keys - ('first', 'last') - - The keys can be explicitly provided as optional positional arguments after - the callback. For example, this is equivalent to the ``login`` instance - above: - - >>> login2 = DefaultFrom(lambda a, b: a[0] + b, 'first', 'last') - >>> login2.keys - ('first', 'last') - >>> login2.callback.func_code.co_varnames # Not the keys - ('a', 'b') - >>> login2(first='John', last='Doe') - 'JDoe' - - If any keys are missing when calling your DefaultFrom instance, your - callback is not called and None is returned. For example: - - >>> login(first='John', lastname='Doe') is None - True - >>> login() is None - True - - Any additional keys are simply ignored, like this: - - >>> login(last='Doe', first='John', middle='Whatever') - 'JDoe' - - As above, because `DefaultFrom.__call__` takes only pure keyword - arguments, they can be supplied in any order. - - Of course, the callback need not be a lambda expression. This third - example is equivalent to both the ``login`` and ``login2`` instances - above: - - >>> def get_login(first, last): - ... return first[0] + last - ... - >>> login3 = DefaultFrom(get_login) - >>> login3.keys - ('first', 'last') - >>> login3.callback.func_code.co_varnames - ('first', 'last') - >>> login3(first='John', last='Doe') - 'JDoe' - """ - - def __init__(self, callback, *keys): - """ - :param callback: The callable to call when all keys are present. - :param keys: Optional keys used for source values. - """ - if not callable(callback): - raise TypeError('callback must be callable; got %r' % callback) - self.callback = callback - if len(keys) == 0: - fc = callback.func_code - self.keys = fc.co_varnames[:fc.co_argcount] - else: - self.keys = keys - for key in self.keys: - if type(key) is not str: - raise_TypeError(key, str, 'keys') - lock(self) - - def __call__(self, **kw): - """ - If all keys are present, calls the callback; otherwise returns None. - - :param kw: The keyword arguments. - """ - vals = tuple(kw.get(k, None) for k in self.keys) - if None in vals: - return - try: - return self.callback(*vals) - except StandardError: - pass - - -def parse_param_spec(spec): - """ - Parse a param spec into to (name, kw). - - The ``spec`` string determines the param name, whether the param is - required, and whether the param is multivalue according the following - syntax: - - ====== ===== ======== ========== - Spec Name Required Multivalue - ====== ===== ======== ========== - 'var' 'var' True False - 'var?' 'var' False False - 'var*' 'var' False True - 'var+' 'var' True True - ====== ===== ======== ========== - - For example, - - >>> parse_param_spec('login') - ('login', {'required': True, 'multivalue': False}) - >>> parse_param_spec('gecos?') - ('gecos', {'required': False, 'multivalue': False}) - >>> parse_param_spec('telephone_numbers*') - ('telephone_numbers', {'required': False, 'multivalue': True}) - >>> parse_param_spec('group+') - ('group', {'required': True, 'multivalue': True}) - - :param spec: A spec string. - """ - if type(spec) is not str: - raise_TypeError(spec, str, 'spec') - if len(spec) < 2: - raise ValueError( - 'param spec must be at least 2 characters; got %r' % spec - ) - _map = { - '?': dict(required=False, multivalue=False), - '*': dict(required=False, multivalue=True), - '+': dict(required=True, multivalue=True), - } - end = spec[-1] - if end in _map: - return (spec[:-1], _map[end]) - return (spec, dict(required=True, multivalue=False)) - - -class Param(plugable.ReadOnly): - """ - A parameter accepted by a `Command`. - - ============ ================= ================== - Keyword Type Default - ============ ================= ================== - cli_name str defaults to name - type ipa_type.Type ipa_type.Unicode() - doc str "" - required bool True - multivalue bool False - primary_key bool False - normalize callable None - default same as type.type None - default_from callable None - flags frozenset frozenset() - ============ ================= ================== - """ - __nones = (None, '', tuple(), []) - __defaults = dict( - cli_name=None, - type=ipa_types.Unicode(), - doc='', - required=True, - multivalue=False, - primary_key=False, - normalize=None, - default=None, - default_from=None, - flags=frozenset(), - rules=tuple(), - ) - - def __init__(self, name, **override): - self.__param_spec = name - self.__override = override - self.__kw = dict(self.__defaults) - if not ('required' in override or 'multivalue' in override): - (name, kw_from_spec) = parse_param_spec(name) - self.__kw.update(kw_from_spec) - self.__kw['cli_name'] = name - if not set(self.__kw).issuperset(override): - extra = sorted(set(override) - set(self.__kw)) - raise TypeError( - 'Param.__init__() takes no such kwargs: %s' % ', '.join(extra) - ) - self.__kw.update(override) - self.name = check_name(name) - self.cli_name = check_name(self.__kw.get('cli_name', name)) - self.type = self.__check_isinstance(ipa_types.Type, 'type') - self.doc = self.__check_type(str, 'doc') - self.required = self.__check_type(bool, 'required') - self.multivalue = self.__check_type(bool, 'multivalue') - self.default = self.__kw['default'] - df = self.__kw['default_from'] - if callable(df) and not isinstance(df, DefaultFrom): - df = DefaultFrom(df) - self.default_from = check_type(df, DefaultFrom, 'default_from', - allow_none=True - ) - self.flags = frozenset(self.__kw['flags']) - self.__normalize = self.__kw['normalize'] - self.rules = self.__check_type(tuple, 'rules') - self.all_rules = (self.type.validate,) + self.rules - self.primary_key = self.__check_type(bool, 'primary_key') - lock(self) - - def ispassword(self): - """ - Return ``True`` is this Param is a password. - """ - return 'password' in self.flags - - def __clone__(self, **override): - """ - Return a new `Param` instance similar to this one. - """ - kw = dict(self.__kw) - kw.update(override) - return self.__class__(self.name, **kw) - - def __check_type(self, type_, name, allow_none=False): - value = self.__kw[name] - return check_type(value, type_, name, allow_none) - - def __check_isinstance(self, type_, name, allow_none=False): - value = self.__kw[name] - return check_isinstance(value, type_, name, allow_none) - - def __dispatch(self, value, scalar): - """ - Helper method used by `normalize` and `convert`. - """ - if value in self.__nones: - return - if self.multivalue: - if type(value) in (tuple, list): - return tuple( - scalar(v, i) for (i, v) in enumerate(value) - ) - return (scalar(value, 0),) # tuple - return scalar(value) - - def __normalize_scalar(self, value, index=None): - """ - Normalize a scalar value. - - This method is called once with each value in multivalue. - """ - if not isinstance(value, basestring): - return value - try: - return self.__normalize(value) - except StandardError: - return value - - def normalize(self, value): - """ - Normalize ``value`` using normalize callback. - - For example: - - >>> param = Param('telephone', - ... normalize=lambda value: value.replace('.', '-') - ... ) - >>> param.normalize('800.123.4567') - '800-123-4567' - - If this `Param` instance does not have a normalize callback, - ``value`` is returned unchanged. - - If this `Param` instance has a normalize callback and ``value`` is - a basestring, the normalize callback is called and its return value - is returned. - - If ``value`` is not a basestring, or if an exception is caught - when calling the normalize callback, ``value`` is returned unchanged. - - :param value: A proposed value for this parameter. - """ - if self.__normalize is None: - return value - return self.__dispatch(value, self.__normalize_scalar) - - def __convert_scalar(self, value, index=None): - """ - Convert a scalar value. - - This method is called once with each value in multivalue. - """ - if value in self.__nones: - return - converted = self.type(value) - if converted is None: - raise errors.ConversionError( - self.name, value, self.type, index=index - ) - return converted - - def convert(self, value): - """ - Convert/coerce ``value`` to Python type for this `Param`. - - For example: - - >>> param = Param('an_int', type=ipa_types.Int()) - >>> param.convert(7.2) - 7 - >>> param.convert(" 7 ") - 7 - - If ``value`` can not be converted, ConversionError is raised, which - is as subclass of ValidationError. - - If ``value`` is None, conversion is not attempted and None is - returned. - - :param value: A proposed value for this parameter. - """ - return self.__dispatch(value, self.__convert_scalar) - - def __validate_scalar(self, value, index=None): - """ - Validate a scalar value. - - This method is called once with each value in multivalue. - """ - if type(value) is not self.type.type: - raise_TypeError(value, self.type.type, 'value') - for rule in self.rules: - error = rule(value) - if error is not None: - raise errors.RuleError( - self.name, value, error, rule, index=index - ) - - def validate(self, value): - """ - Check validity of a value. - - Each validation rule is called in turn and if any returns and error, - RuleError is raised, which is a subclass of ValidationError. - - :param value: A proposed value for this parameter. - """ - if value is None: - if self.required: - raise errors.RequirementError(self.name) - return - if self.multivalue: - if type(value) is not tuple: - raise_TypeError(value, tuple, 'value') - for (i, v) in enumerate(value): - self.__validate_scalar(v, i) - else: - self.__validate_scalar(value) - - def get_default(self, **kw): - """ - Return a default value for this parameter. - - If this `Param` instance does not have a default_from() callback, this - method always returns the static Param.default instance attribute. - - On the other hand, if this `Param` instance has a default_from() - callback, the callback is called and its return value is returned - (assuming that value is not None). - - If the default_from() callback returns None, or if an exception is - caught when calling the default_from() callback, the static - Param.default instance attribute is returned. - - :param kw: Optional keyword arguments to pass to default_from(). - """ - if self.default_from is not None: - default = self.default_from(**kw) - if default is not None: - try: - return self.convert(self.normalize(default)) - except errors.ValidationError: - return None - return self.default - - def get_values(self): - """ - Return a tuple of possible values. - - For enumerable types, a tuple containing the possible values is - returned. For all other types, an empty tuple is returned. - """ - if self.type.name in ('Enum', 'CallbackEnum'): - return self.type.values - return tuple() - - def __call__(self, value, **kw): - if value in self.__nones: - value = self.get_default(**kw) - else: - value = self.convert(self.normalize(value)) - self.validate(value) - return value - - def __repr__(self): - """ - Return an expresion that could construct this `Param` instance. - """ - return make_repr( - self.__class__.__name__, - self.__param_spec, - **self.__override - ) - - -def create_param(spec): - """ - Create a `Param` instance from a param spec. - - If ``spec`` is a `Param` instance, ``spec`` is returned unchanged. - - If ``spec`` is an str instance, then ``spec`` is parsed and an - appropriate `Param` instance is created and returned. - - See `parse_param_spec` for the definition of the spec syntax. - - :param spec: A spec string or a `Param` instance. - """ - if type(spec) is Param: - return spec - if type(spec) is not str: - raise TypeError( - 'create_param() takes %r or %r; got %r' % (str, Param, spec) - ) - return Param(spec) - - class Command(plugable.Plugin): """ A public IPA atomic operation. @@ -810,7 +363,7 @@ class LocalOrRemote(Command): """ takes_options = ( - Param('server?', type=ipa_types.Bool(), default=False, + parameters.Flag('server?', doc='Forward to server instead of running locally', ), ) @@ -1064,7 +617,7 @@ class Property(Attribute): 'type', )).union(Attribute.__public__) - type = ipa_types.Unicode() + type = parameters.Str required = False multivalue = False default = None -- cgit