summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/parameters.py29
-rw-r--r--tests/test_ipalib/test_parameters.py27
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.