summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-12-12 03:13:58 -0700
committerJason Gerard DeRose <jderose@redhat.com>2008-12-12 03:13:58 -0700
commit5272949bfd01b9648902fd9dea77762d06d52832 (patch)
tree33107b83a31f0e069eeeb4dc706acbe623033d0a
parent079721da2cfdd9bc040f7fe6e2842a4775e0e964 (diff)
downloadfreeipa-5272949bfd01b9648902fd9dea77762d06d52832.tar.gz
freeipa-5272949bfd01b9648902fd9dea77762d06d52832.tar.xz
freeipa-5272949bfd01b9648902fd9dea77762d06d52832.zip
New Param: added all logic for minlength, maxlength, and length in Bytes class (which Str inherits)
-rw-r--r--ipalib/parameter.py70
-rw-r--r--tests/test_ipalib/test_parameter.py57
2 files changed, 112 insertions, 15 deletions
diff --git a/ipalib/parameter.py b/ipalib/parameter.py
index 6acf04830..82be8feec 100644
--- a/ipalib/parameter.py
+++ b/ipalib/parameter.py
@@ -203,19 +203,27 @@ class Param(ReadOnly):
def __init__(self, name, **kw):
assert type(self.type) is type
+ self.kwargs += (('default', self.type, None),)
self.param_spec = name
self.__kw = dict(kw)
if not ('required' in kw or 'multivalue' in kw):
(name, kw_from_spec) = parse_param_spec(name)
kw.update(kw_from_spec)
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:
kw['cli_name'] = self.name
df = kw.get('default_from', None)
if callable(df) and not isinstance(df, DefaultFrom):
kw['default_from'] = DefaultFrom(df)
self.__clonekw = kw
- self.kwargs += (('default', self.type, None),)
for (key, kind, default) in self.kwargs:
value = kw.get(key, default)
if value is not None:
@@ -245,14 +253,12 @@ class Param(ReadOnly):
For example:
- >>> param = Str('telephone',
+ >>> param = Param('telephone',
... normalizer=lambda value: value.replace('.', '-')
... )
>>> param.normalize(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
``value`` is a unicode instance, the normalizer callback is called and
*its* return value is returned.
@@ -293,8 +299,8 @@ class Param(ReadOnly):
if self.multivalue:
if type(value) in (tuple, list):
values = filter(
- lambda val: val not in NULLS,
- (self._convert_scalar(v, i) for (i, v) in enumerate(value))
+ lambda val: val not in NULLS,
+ (self._convert_scalar(v, i) for (i, v) in enumerate(value))
)
if len(values) == 0:
return
@@ -336,23 +342,59 @@ class Bytes(Param):
type = str
- def __init__(self, name, **kw):
- kwargs = dict(
- minlength=(int, None),
- maxlength=(int, None),
- length=(int, None),
- pattern=(str, None),
- )
+ kwargs = Param.kwargs + (
+ ('minlength', int, None),
+ ('maxlength', int, None),
+ ('length', int, None),
+ ('pattern', str, None),
+ )
+ def __init__(self, name, **kw):
+ super(Bytes, self).__init__(name, **kw)
+
+ if not (
+ self.length is None or
+ (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(Param):
+
+class Str(Bytes):
"""
"""
type = unicode
+ kwargs = Bytes.kwargs[:-1] + (
+ ('pattern', unicode, None),
+ )
+
def __init__(self, name, **kw):
super(Str, self).__init__(name, **kw)
diff --git a/tests/test_ipalib/test_parameter.py b/tests/test_ipalib/test_parameter.py
index f72c4e627..ddc938d47 100644
--- a/tests/test_ipalib/test_parameter.py
+++ b/tests/test_ipalib/test_parameter.py
@@ -149,11 +149,12 @@ class test_Param(ClassChecker):
assert str(e) == CALLABLE_ERROR % (key, value, type(value))
else:
assert str(e) == TYPE_ERROR % (key, kind, value, type(value))
-
# Test with None:
kw = {key: None}
Subclass('my_param', **kw)
+ # Test when using unknown kwargs:
+
def test_convert_scalar(self):
"""
Test the `ipalib.parameter.Param._convert_scalar` method.
@@ -168,6 +169,56 @@ class test_Param(ClassChecker):
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):
"""
Test the `ipalib.parameter.Str` class.
@@ -180,6 +231,10 @@ class test_Str(ClassChecker):
"""
o = self.cls('my_str')
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):
"""