diff options
-rw-r--r-- | ipalib/parameters.py | 79 | ||||
-rw-r--r-- | ipalib/plugins/dns.py | 4 | ||||
-rw-r--r-- | ipalib/plugins/passwd.py | 2 | ||||
-rw-r--r-- | ipaserver/plugins/join.py | 4 | ||||
-rwxr-xr-x | make-lint | 6 | ||||
-rwxr-xr-x | makeapi | 1 | ||||
-rw-r--r-- | tests/test_ipalib/test_parameters.py | 49 |
7 files changed, 30 insertions, 115 deletions
diff --git a/ipalib/parameters.py b/ipalib/parameters.py index ec6020e52..5040234a9 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -198,6 +198,8 @@ class DefaultFrom(ReadOnly): self.callback = callback if len(keys) == 0: fc = callback.func_code + if fc.co_flags & 0x0c: + raise ValueError("callback: variable-length argument list not allowed") self.keys = fc.co_varnames[:fc.co_argcount] else: self.keys = keys @@ -308,13 +310,9 @@ class Param(ReadOnly): encoder - default_from: a custom function for generating default values of parameter instance - - create_default: a custom function for generating default values of - parameter instance. Unlike default_from attribute, this function - is not wrapped. `Param.get_default()` documentation provides further - details - autofill: by default, only `required` parameters get a default value - from default_from or create_default functions. When autofill is - enabled, optional attributes get the default value filled too + from the default_from function. When autofill is enabled, optional + attributes get the default value filled too - query: this attribute is controlled by framework. When the `query` is enabled, framework assumes that the value is only queried and not inserted in the LDAP. Validation is then relaxed - custom @@ -379,7 +377,6 @@ class Param(ReadOnly): ('normalizer', callable, None), ('encoder', callable, None), ('default_from', DefaultFrom, None), - ('create_default', callable, None), ('autofill', bool, False), ('query', bool, False), ('attribute', bool, False), @@ -481,20 +478,6 @@ class Param(ReadOnly): class_rules.append(getattr(self, rule_name)) check_name(self.cli_name) - # Check that only default_from or create_default was provided: - assert not hasattr(self, '_get_default'), self.nice - if callable(self.default_from): - if callable(self.create_default): - raise ValueError( - '%s: cannot have both %r and %r' % ( - self.nice, 'default_from', 'create_default') - ) - self._get_default = self.default_from - elif callable(self.create_default): - self._get_default = self.create_default - else: - self._get_default = None - # Check that only 'include' or 'exclude' was provided: if None not in (self.include, self.exclude): raise ValueError( @@ -990,59 +973,9 @@ class Param(ReadOnly): >>> kw = dict(first=u'John', department=u'Engineering') >>> login.get_default(**kw) u'my-static-login-default' - - The second, less common way to construct a dynamic default is to provide - a callback via the ``create_default`` keyword argument. Unlike a - ``default_from`` callback, your ``create_default`` callback will not get - wrapped in any dispatcher. Instead, it will be called directly, which - means your callback must accept arbitrary keyword arguments, although - whether your callback utilises these values is up to your - implementation. For example: - - >>> def make_csr(**kw): - ... print ' make_csr(%r)' % (kw,) # Note output below - ... return 'Certificate Signing Request' - ... - >>> csr = Bytes('csr', create_default=make_csr) - - Your ``create_default`` callback will be called with whatever keyword - arguments are passed to `Param.get_default()`. For example: - - >>> kw = dict(arbitrary='Keyword', arguments='Here') - >>> csr.get_default(**kw) - make_csr({'arguments': 'Here', 'arbitrary': 'Keyword'}) - 'Certificate Signing Request' - - And your ``create_default`` callback is called even if - `Param.get_default()` is called with *zero* keyword arguments. - For example: - - >>> csr.get_default() - make_csr({}) - 'Certificate Signing Request' - - The ``create_default`` callback will most likely be used as a - pre-execute hook to perform some special client-side operation. For - example, the ``csr`` parameter above might make a call to - ``/usr/bin/openssl``. However, often a ``create_default`` callback - could also be implemented as a ``default_from`` callback. When this is - the case, a ``default_from`` callback should be used as they are more - structured and therefore less error-prone. - - The ``default_from`` and ``create_default`` keyword arguments are - mutually exclusive. If you provide both, a ``ValueError`` will be - raised. For example: - - >>> homedir = Str('home', - ... default_from=lambda login: '/home/%s' % login, - ... create_default=lambda **kw: '/lets/use/this', - ... ) - Traceback (most recent call last): - ... - ValueError: Str('home'): cannot have both 'default_from' and 'create_default' """ - if self._get_default is not None: - default = self._get_default(**kw) + if self.default_from is not None: + default = self.default_from(**kw) if default is not None: try: return self.convert(self.normalize(default)) diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py index 24b8357a4..b7069fb7a 100644 --- a/ipalib/plugins/dns.py +++ b/ipalib/plugins/dns.py @@ -234,7 +234,7 @@ def _rname_validator(ugettext, zonemgr): return unicode(e) return None -def _create_zone_serial(**kwargs): +def _create_zone_serial(): """ Generate serial number for zones. The format follows RFC 1912 """ return int('%s01' % time.strftime('%Y%m%d')) @@ -1554,7 +1554,7 @@ class dnszone(LDAPObject): label=_('SOA serial'), doc=_('SOA record serial number'), minvalue=1, - create_default=_create_zone_serial, + default_from=_create_zone_serial, autofill=True, ), Int('idnssoarefresh', diff --git a/ipalib/plugins/passwd.py b/ipalib/plugins/passwd.py index b26f7e9fd..9bee314ec 100644 --- a/ipalib/plugins/passwd.py +++ b/ipalib/plugins/passwd.py @@ -69,7 +69,7 @@ class passwd(Command): label=_('User name'), primary_key=True, autofill=True, - create_default=lambda **kw: util.get_current_principal(), + default_from=lambda: util.get_current_principal(), normalizer=lambda value: normalize_principal(value), ), Password('password', diff --git a/ipaserver/plugins/join.py b/ipaserver/plugins/join.py index 81c336b27..007336387 100644 --- a/ipaserver/plugins/join.py +++ b/ipaserver/plugins/join.py @@ -52,7 +52,7 @@ class join(Command): validate_host, cli_name='hostname', doc=_("The hostname to register as"), - create_default=lambda **kw: unicode(util.get_fqdn()), + default_from=lambda: unicode(util.get_fqdn()), autofill=True, #normalizer=lamda value: value.lower(), ), @@ -60,7 +60,7 @@ class join(Command): takes_options= ( Str('realm', doc=_("The IPA realm"), - create_default=lambda **kw: get_realm(), + default_from=lambda: get_realm(), autofill=True, ), Str('nshardwareplatform?', @@ -56,9 +56,9 @@ class IPATypeChecker(TypeChecker): 'ipalib.plugins.misc.env': ['env'], 'ipalib.parameters.Param': ['cli_name', 'cli_short_name', 'label', 'doc', 'required', 'multivalue', 'primary_key', 'normalizer', - 'default', 'default_from', 'create_default', 'autofill', 'query', - 'attribute', 'include', 'exclude', 'flags', 'hint', 'alwaysask', - 'sortorder', 'csv', 'csv_separator', 'csv_skipspace'], + 'default', 'default_from', 'autofill', 'query', 'attribute', + 'include', 'exclude', 'flags', 'hint', 'alwaysask', 'sortorder', + 'csv', 'csv_separator', 'csv_skipspace'], 'ipalib.parameters.Bool': ['truths', 'falsehoods'], 'ipalib.parameters.Int': ['minvalue', 'maxvalue'], 'ipalib.parameters.Decimal': ['minvalue', 'maxvalue', 'precision'], @@ -45,7 +45,6 @@ PARAM_IGNORED_KW_ATTRIBUTES = ('label', 'normalizer', 'encoder', 'default_from', - 'create_default', 'hint', 'flags', 'sortorder',) diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py index 83c33ddfc..fc9569e73 100644 --- a/tests/test_ipalib/test_parameters.py +++ b/tests/test_ipalib/test_parameters.py @@ -64,6 +64,16 @@ class test_DefaultFrom(ClassChecker): e = raises(TypeError, self.cls, callback, 'givenname', 17) assert str(e) == TYPE_ERROR % ('keys', str, 17, int) + # Test that ValueError is raised when inferring keys from a callback + # which has *args: + e = raises(ValueError, self.cls, lambda foo, *args: None) + assert str(e) == "callback: variable-length argument list not allowed" + + # Test that ValueError is raised when inferring keys from a callback + # which has **kwargs: + e = raises(ValueError, self.cls, lambda foo, **kwargs: None) + assert str(e) == "callback: variable-length argument list not allowed" + def test_repr(self): """ Test the `ipalib.parameters.DefaultFrom.__repr__` method. @@ -185,8 +195,6 @@ class test_Param(ClassChecker): assert o.normalizer is None assert o.default is None assert o.default_from is None - assert o.create_default is None - assert o._get_default is None assert o.autofill is False assert o.query is False assert o.attribute is False @@ -250,16 +258,6 @@ class test_Param(ClassChecker): assert str(e) == \ "Param('my_param'): takes no such kwargs: 'ape', 'great'" - # Test that ValueError is raised if you provide both default_from and - # create_default: - e = raises(ValueError, self.cls, 'my_param', - default_from=lambda first, last: first[0] + last, - create_default=lambda **kw: 'The Default' - ) - assert str(e) == '%s: cannot have both %r and %r' % ( - "Param('my_param')", 'default_from', 'create_default', - ) - # Test that ValueError is raised if you provide both include and # exclude: e = raises(ValueError, self.cls, 'my_param', @@ -276,15 +274,11 @@ class test_Param(ClassChecker): e = raises(ValueError, self.cls, 'my_param', csv=True) assert str(e) == '%s: cannot have csv without multivalue' % "Param('my_param')" - # Test that _get_default gets set: - call1 = lambda first, last: first[0] + last - call2 = lambda **kw: 'The Default' - o = self.cls('my_param', default_from=call1) - assert o.default_from.callback is call1 - assert o._get_default is o.default_from - o = self.cls('my_param', create_default=call2) - assert o.create_default is call2 - assert o._get_default is call2 + # Test that default_from gets set: + call = lambda first, last: first[0] + last + o = self.cls('my_param', default_from=call) + assert type(o.default_from) is parameters.DefaultFrom + assert o.default_from.callback is call def test_repr(self): """ @@ -579,7 +573,7 @@ class test_Param(ClassChecker): def test_get_default(self): """ - Test the `ipalib.parameters.Param._get_default` method. + Test the `ipalib.parameters.Param.get_default` method. """ class PassThrough(object): value = None @@ -624,17 +618,6 @@ class test_Param(ClassChecker): assert o._convert_scalar.value is default assert o.normalizer.value is default - # Test with create_default: - o = Str('my_str', - normalizer=PassThrough(), - default=u'Static Default', - create_default=lambda **kw: u'The created default', - ) - default = o.get_default(first=u'john', last='doe') - assert_equal(default, u'The created default') - assert o._convert_scalar.value is default - assert o.normalizer.value is default - def test_split_csv(self): """ Test the `ipalib.parameters.Param.split_csv` method with csv. |