[Freeipa-devel] [PATCH] [Resend] Reading INT parameter class should respect radix prefix

John Dennis jdennis at redhat.com
Fri Nov 20 18:41:44 UTC 2009


This modifies the original patch by including a unit test, handling floats
when passed as unicode, and handling large magnitude values beyond maxint.

The INT parameter class was not respecting any radix prefix (e.g. 0x) the user
may have supplied. This patch implements _convert_scalar method for the Int
class so that we can pass the special radix base of zero to the int constructor
telling it to determine the radix from the prefix (if present).
---
From: John Dennis <jdennis at redhat.com>
Subject: [PATCH] Reading INT parameter class should respect radix prefix


 ipalib/parameters.py                 |   29 +++++++++++++++++++++++++++++
 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 227757d..8a1aede 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 f6bc66f..d1c5f7f 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.




More information about the Freeipa-devel mailing list