mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-24 14:17:41 -05:00
New Param: added all logic for minlength, maxlength, and length in Bytes class (which Str inherits)
This commit is contained in:
1 parent
079721da2c
commit
5272949bfd
2 files changed
+112
-15
No files matched your search
+56
-14
@@ -203,19 +203,27 @@ class Param(ReadOnly):
|
|||||||
|
|
||||||
def __init__(self, name, **kw):
|
def __init__(self, name, **kw):
|
||||||
assert type(self.type) is type
|
assert type(self.type) is type
|
||||||
|
self.kwargs += (('default', self.type, None),)
|
||||||
self.param_spec = name
|
self.param_spec = name
|
||||||
self.__kw = dict(kw)
|
self.__kw = dict(kw)
|
||||||
if not ('required' in kw or 'multivalue' in kw):
|
if not ('required' in kw or 'multivalue' in kw):
|
||||||
(name, kw_from_spec) = parse_param_spec(name)
|
(name, kw_from_spec) = parse_param_spec(name)
|
||||||
kw.update(kw_from_spec)
|
kw.update(kw_from_spec)
|
||||||
self.name = check_name(name)
|
self.name = check_name(name)
|
||||||
|
self.nice = '%s(%r)' % (self.__class__.__name__, self.name)
|
||||||
|
if not set(t[0] for t in self.kwargs).issuperset(self.__kw):
|
||||||
|
extra = set(kw) - set(t[0] for t in self.kwargs)
|
||||||
|
raise TypeError(
|
||||||
|
'%s: no such kwargs: %s' % (self.nice,
|
||||||
|
', '.join(repr(k) for k in sorted(extra))
|
||||||
|
)
|
||||||
|
)
|
||||||
if kw.get('cli_name', None) is None:
|
if kw.get('cli_name', None) is None:
|
||||||
kw['cli_name'] = self.name
|
kw['cli_name'] = self.name
|
||||||
df = kw.get('default_from', None)
|
df = kw.get('default_from', None)
|
||||||
if callable(df) and not isinstance(df, DefaultFrom):
|
if callable(df) and not isinstance(df, DefaultFrom):
|
||||||
kw['default_from'] = DefaultFrom(df)
|
kw['default_from'] = DefaultFrom(df)
|
||||||
self.__clonekw = kw
|
self.__clonekw = kw
|
||||||
self.kwargs += (('default', self.type, None),)
|
|
||||||
for (key, kind, default) in self.kwargs:
|
for (key, kind, default) in self.kwargs:
|
||||||
value = kw.get(key, default)
|
value = kw.get(key, default)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
@@ -245,14 +253,12 @@ class Param(ReadOnly):
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
>>> param = Str('telephone',
|
>>> param = Param('telephone',
|
||||||
... normalizer=lambda value: value.replace('.', '-')
|
... normalizer=lambda value: value.replace('.', '-')
|
||||||
... )
|
... )
|
||||||
>>> param.normalize(u'800.123.4567')
|
>>> param.normalize(u'800.123.4567')
|
||||||
u'800-123-4567'
|
u'800-123-4567'
|
||||||
|
|
||||||
(Note that `Str` is a subclass of `Param`.)
|
|
||||||
|
|
||||||
If this `Param` instance was created with a normalizer callback and
|
If this `Param` instance was created with a normalizer callback and
|
||||||
``value`` is a unicode instance, the normalizer callback is called and
|
``value`` is a unicode instance, the normalizer callback is called and
|
||||||
*its* return value is returned.
|
*its* return value is returned.
|
||||||
@@ -293,8 +299,8 @@ class Param(ReadOnly):
|
|||||||
if self.multivalue:
|
if self.multivalue:
|
||||||
if type(value) in (tuple, list):
|
if type(value) in (tuple, list):
|
||||||
values = filter(
|
values = filter(
|
||||||
lambda val: val not in NULLS,
|
lambda val: val not in NULLS,
|
||||||
(self._convert_scalar(v, i) for (i, v) in enumerate(value))
|
(self._convert_scalar(v, i) for (i, v) in enumerate(value))
|
||||||
)
|
)
|
||||||
if len(values) == 0:
|
if len(values) == 0:
|
||||||
return
|
return
|
||||||
@@ -336,23 +342,59 @@ class Bytes(Param):
|
|||||||
|
|
||||||
type = str
|
type = str
|
||||||
|
|
||||||
|
kwargs = Param.kwargs + (
|
||||||
|
('minlength', int, None),
|
||||||
|
('maxlength', int, None),
|
||||||
|
('length', int, None),
|
||||||
|
('pattern', str, None),
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, name, **kw):
|
def __init__(self, name, **kw):
|
||||||
kwargs = dict(
|
super(Bytes, self).__init__(name, **kw)
|
||||||
minlength=(int, None),
|
|
||||||
maxlength=(int, None),
|
if not (
|
||||||
length=(int, None),
|
self.length is None or
|
||||||
pattern=(str, None),
|
(self.minlength is None and self.maxlength is None)
|
||||||
)
|
):
|
||||||
|
raise ValueError(
|
||||||
|
'%s: cannot mix length with minlength or maxlength' % self.nice
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.minlength is not None and self.minlength < 1:
|
||||||
|
raise ValueError(
|
||||||
|
'%s: minlength must be >= 1; got %r' % (self.nice, self.minlength)
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.maxlength is not None and self.maxlength < 1:
|
||||||
|
raise ValueError(
|
||||||
|
'%s: maxlength must be >= 1; got %r' % (self.nice, self.maxlength)
|
||||||
|
)
|
||||||
|
|
||||||
|
if None not in (self.minlength, self.maxlength):
|
||||||
|
if self.minlength > self.maxlength:
|
||||||
|
raise ValueError(
|
||||||
|
'%s: minlength > maxlength (minlength=%r, maxlength=%r)' % (
|
||||||
|
self.nice, self.minlength, self.maxlength)
|
||||||
|
)
|
||||||
|
elif self.minlength == self.maxlength:
|
||||||
|
raise ValueError(
|
||||||
|
'%s: minlength == maxlength; use length=%d instead' % (
|
||||||
|
self.nice, self.minlength)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Str(Bytes):
|
||||||
class Str(Param):
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type = unicode
|
type = unicode
|
||||||
|
|
||||||
|
kwargs = Bytes.kwargs[:-1] + (
|
||||||
|
('pattern', unicode, None),
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, name, **kw):
|
def __init__(self, name, **kw):
|
||||||
super(Str, self).__init__(name, **kw)
|
super(Str, self).__init__(name, **kw)
|
||||||
|
|
||||||
|
|||||||
@@ -149,11 +149,12 @@ class test_Param(ClassChecker):
|
|||||||
assert str(e) == CALLABLE_ERROR % (key, value, type(value))
|
assert str(e) == CALLABLE_ERROR % (key, value, type(value))
|
||||||
else:
|
else:
|
||||||
assert str(e) == TYPE_ERROR % (key, kind, value, type(value))
|
assert str(e) == TYPE_ERROR % (key, kind, value, type(value))
|
||||||
|
|
||||||
# Test with None:
|
# Test with None:
|
||||||
kw = {key: None}
|
kw = {key: None}
|
||||||
Subclass('my_param', **kw)
|
Subclass('my_param', **kw)
|
||||||
|
|
||||||
|
# Test when using unknown kwargs:
|
||||||
|
|
||||||
def test_convert_scalar(self):
|
def test_convert_scalar(self):
|
||||||
"""
|
"""
|
||||||
Test the `ipalib.parameter.Param._convert_scalar` method.
|
Test the `ipalib.parameter.Param._convert_scalar` method.
|
||||||
@@ -168,6 +169,56 @@ class test_Param(ClassChecker):
|
|||||||
assert str(e) == 'Subclass._convert_scalar()'
|
assert str(e) == 'Subclass._convert_scalar()'
|
||||||
|
|
||||||
|
|
||||||
|
class test_Bytes(ClassChecker):
|
||||||
|
"""
|
||||||
|
Test the `ipalib.parameter.Bytes` class.
|
||||||
|
"""
|
||||||
|
_cls = parameter.Bytes
|
||||||
|
|
||||||
|
def test_init(self):
|
||||||
|
"""
|
||||||
|
Test the `ipalib.parameter.Bytes.__init__` method.
|
||||||
|
"""
|
||||||
|
o = self.cls('my_bytes')
|
||||||
|
assert o.type is str
|
||||||
|
assert o.minlength is None
|
||||||
|
assert o.maxlength is None
|
||||||
|
assert o.length is None
|
||||||
|
assert o.pattern is None
|
||||||
|
|
||||||
|
# Test mixing length with minlength or maxlength:
|
||||||
|
o = self.cls('my_bytes', length=5)
|
||||||
|
assert o.length == 5
|
||||||
|
permutations = [
|
||||||
|
dict(minlength=3),
|
||||||
|
dict(maxlength=7),
|
||||||
|
dict(minlength=3, maxlength=7),
|
||||||
|
]
|
||||||
|
for kw in permutations:
|
||||||
|
o = self.cls('my_bytes', **kw)
|
||||||
|
for (key, value) in kw.iteritems():
|
||||||
|
assert getattr(o, key) == value
|
||||||
|
e = raises(ValueError, self.cls, 'my_bytes', length=5, **kw)
|
||||||
|
assert str(e) == \
|
||||||
|
"Bytes('my_bytes'): cannot mix length with minlength or maxlength"
|
||||||
|
|
||||||
|
# Test when minlength or maxlength are less than 1:
|
||||||
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=0)
|
||||||
|
assert str(e) == "Bytes('my_bytes'): minlength must be >= 1; got 0"
|
||||||
|
e = raises(ValueError, self.cls, 'my_bytes', maxlength=0)
|
||||||
|
assert str(e) == "Bytes('my_bytes'): maxlength must be >= 1; got 0"
|
||||||
|
|
||||||
|
# Test when minlength > maxlength:
|
||||||
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=22, maxlength=15)
|
||||||
|
assert str(e) == \
|
||||||
|
"Bytes('my_bytes'): minlength > maxlength (minlength=22, maxlength=15)"
|
||||||
|
|
||||||
|
# Test when minlength == maxlength
|
||||||
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=7, maxlength=7)
|
||||||
|
assert str(e) == \
|
||||||
|
"Bytes('my_bytes'): minlength == maxlength; use length=7 instead"
|
||||||
|
|
||||||
|
|
||||||
class test_Str(ClassChecker):
|
class test_Str(ClassChecker):
|
||||||
"""
|
"""
|
||||||
Test the `ipalib.parameter.Str` class.
|
Test the `ipalib.parameter.Str` class.
|
||||||
@@ -180,6 +231,10 @@ class test_Str(ClassChecker):
|
|||||||
"""
|
"""
|
||||||
o = self.cls('my_str')
|
o = self.cls('my_str')
|
||||||
assert o.type is unicode
|
assert o.type is unicode
|
||||||
|
assert o.minlength is None
|
||||||
|
assert o.maxlength is None
|
||||||
|
assert o.length is None
|
||||||
|
assert o.pattern is None
|
||||||
|
|
||||||
def test_convert_scalar(self):
|
def test_convert_scalar(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in new issue
Block a user