diff options
-rw-r--r-- | ipalib/parameters.py | 29 | ||||
-rw-r--r-- | tests/test_ipalib/test_parameters.py | 27 |
2 files changed, 56 insertions, 0 deletions
diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 227757d63..8a1aede96 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -909,6 +909,35 @@ class Int(Number): self.nice, self.minvalue, self.maxvalue) ) + def _convert_scalar(self, value, index=None): + """ + Convert a single scalar value. + """ + if type(value) in (int, long): + return value + if type(value) is unicode: + # permit floating point strings + if value.find(u'.') >= 0: + try: + return int(float(value)) + except ValueError: + pass + else: + try: + # 2nd arg is radix base, 2nd arg only accepted for strings. + # Zero means determine radix base from prefix (e.g. 0x for hex) + return int(value, 0) + except ValueError: + pass + if type(value) is float: + try: + return int(value) + except ValueError: + pass + raise ConversionError(name=self.name, index=index, + error=ugettext(self.type_error), + ) + def _rule_minvalue(self, _, value): """ Check min constraint. diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py index f6bc66f4e..d1c5f7f92 100644 --- a/tests/test_ipalib/test_parameters.py +++ b/tests/test_ipalib/test_parameters.py @@ -22,6 +22,7 @@ Test the `ipalib.parameters` module. """ import re +import sys from types import NoneType from inspect import isclass from tests.util import raises, ClassChecker, read_only @@ -1225,6 +1226,32 @@ class test_Int(ClassChecker): assert dummy.called() is True dummy.reset() + def test_convert_scalar(self): + """ + Test the `ipalib.parameters.Int._convert_scalar` method. + Assure radix prefixes work, str objects fail, + floats (native & string) are truncated, + large magnitude values are promoted to long, + empty strings & invalid numerical representations fail + """ + o = self.cls('my_number') + # Assure invalid inputs raise error + for bad in ['hello', u'hello', True, None, '10', u'', u'.']: + e = raises(errors.ConversionError, o._convert_scalar, bad) + assert e.name == 'my_number' + assert e.index is None + # Assure large magnatude values are handled correctly + assert type(o._convert_scalar(sys.maxint*2)) == long + assert o._convert_scalar(sys.maxint*2) == sys.maxint*2 + assert o._convert_scalar(unicode(sys.maxint*2)) == sys.maxint*2 + assert o._convert_scalar(long(16)) == 16 + # Assure normal conversions produce expected result + assert o._convert_scalar(u'16.99') == 16 + assert o._convert_scalar(16.99) == 16 + assert o._convert_scalar(u'16') == 16 + assert o._convert_scalar(u'0x10') == 16 + assert o._convert_scalar(u'020') == 16 + class test_Float(ClassChecker): """ Test the `ipalib.parameters.Float` class. |