This patch fixes RHEL 6.2 build issue.
----
Having float type as a base type for floating point parameter in
ipalib introduces several issues, e.g. problem with representation
or value comparison. Python language provides Decimal type which
help overcome these issue.

This patch replaces a float type with Decimal type in Float
parameter. A precision attribute was added to Float parameter that
can be used to limit a number of decimal places in parameter
representation. This approach fixes a problem with API.txt
validation where comparison of float values may fail on different
architectures due to float representation error.

In order to safely transfer the parameter value over RPC it is
being converted to string which is then converted back to Decimal
number on server side.

https://fedorahosted.org/freeipa/ticket/2260

>From 54df268197ba3440edd4e71a6885ccffeed19894 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Fri, 13 Jan 2012 20:45:32 +0100
Subject: [PATCH] Replace float with Decimal

Having float type as a base type for floating point parameter in
ipalib introduces several issues, e.g. problem with representation
or value comparison. Python language provides Decimal type which
help overcome these issue.

This patch replaces a float type with Decimal type in Float
parameter. A precision attribute was added to Float parameter that
can be used to limit a number of decimal places in parameter
representation. This approach fixes a problem with API.txt
validation where comparison of float values may fail on different
architectures due to float representation error.

In order to safely transfer the parameter value over RPC it is
being converted to string which is then converted back to Decimal
number on server side.

https://fedorahosted.org/freeipa/ticket/2260
---
 API.txt                              |   36 ++++++++++----------
 ipalib/parameters.py                 |   61 +++++++++++++++++++++++++++-------
 ipalib/plugins/dns.py                |   38 ++++++++++++++-------
 ipalib/rpc.py                        |    4 ++
 tests/test_ipalib/test_parameters.py |   31 +++++++++--------
 tests/test_xmlrpc/test_dns_plugin.py |    2 +-
 6 files changed, 113 insertions(+), 59 deletions(-)

diff --git a/API.txt b/API.txt
index 6e256fadc57d892b9c8eca28546c17ef28e02584..be1dd8093d33469ee1a964c29044325f02557153 100644
--- a/API.txt
+++ b/API.txt
@@ -652,16 +652,16 @@ option: Str('kx_part_exchanger', attribute=False, cli_name='kx_exchanger', multi
 option: LOCRecord('locrecord', attribute=True, cli_name='loc_rec', csv=True, multivalue=True, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lat_deg', attribute=False, cli_name='loc_lat_deg', maxvalue=90, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lat_min', attribute=False, cli_name='loc_lat_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_lat_sec', attribute=False, cli_name='loc_lat_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_lat_sec', attribute=False, cli_name='loc_lat_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, required=False)
 option: StrEnum('loc_part_lat_dir', attribute=False, cli_name='loc_lat_dir', multivalue=False, option_group=u'LOC Record', required=False, values=(u'N', u'S'))
 option: Int('loc_part_lon_deg', attribute=False, cli_name='loc_lon_deg', maxvalue=180, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lon_min', attribute=False, cli_name='loc_lon_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_lon_sec', attribute=False, cli_name='loc_lon_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_lon_sec', attribute=False, cli_name='loc_lon_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, required=False)
 option: StrEnum('loc_part_lon_dir', attribute=False, cli_name='loc_lon_dir', multivalue=False, option_group=u'LOC Record', required=False, values=(u'E', u'W'))
-option: Float('loc_part_altitude', attribute=False, cli_name='loc_altitude', maxvalue=42849672.95, minvalue=-100000.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_size', attribute=False, cli_name='loc_size', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_h_precision', attribute=False, cli_name='loc_h_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_v_precision', attribute=False, cli_name='loc_v_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_altitude', attribute=False, cli_name='loc_altitude', maxvalue=Decimal('42849672.95'), minvalue=Decimal('-100000.00'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_size', attribute=False, cli_name='loc_size', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_h_precision', attribute=False, cli_name='loc_h_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_v_precision', attribute=False, cli_name='loc_v_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
 option: MXRecord('mxrecord', attribute=True, cli_name='mx_rec', csv=True, multivalue=True, option_group=u'MX Record', required=False)
 option: Int('mx_part_preference', attribute=False, cli_name='mx_preference', maxvalue=65535, minvalue=0, multivalue=False, option_group=u'MX Record', required=False)
 option: Str('mx_part_exchanger', attribute=False, cli_name='mx_exchanger', multivalue=False, option_group=u'MX Record', required=False)
@@ -829,16 +829,16 @@ option: Str('kx_part_exchanger', attribute=False, autofill=False, cli_name='kx_e
 option: LOCRecord('locrecord', attribute=True, autofill=False, cli_name='loc_rec', csv=True, multivalue=True, option_group=u'LOC Record', query=True, required=False)
 option: Int('loc_part_lat_deg', attribute=False, autofill=False, cli_name='loc_lat_deg', maxvalue=90, minvalue=0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
 option: Int('loc_part_lat_min', attribute=False, autofill=False, cli_name='loc_lat_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
-option: Float('loc_part_lat_sec', attribute=False, autofill=False, cli_name='loc_lat_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
+option: Float('loc_part_lat_sec', attribute=False, autofill=False, cli_name='loc_lat_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, query=True, required=False)
 option: StrEnum('loc_part_lat_dir', attribute=False, autofill=False, cli_name='loc_lat_dir', multivalue=False, option_group=u'LOC Record', query=True, required=False, values=(u'N', u'S'))
 option: Int('loc_part_lon_deg', attribute=False, autofill=False, cli_name='loc_lon_deg', maxvalue=180, minvalue=0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
 option: Int('loc_part_lon_min', attribute=False, autofill=False, cli_name='loc_lon_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
-option: Float('loc_part_lon_sec', attribute=False, autofill=False, cli_name='loc_lon_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
+option: Float('loc_part_lon_sec', attribute=False, autofill=False, cli_name='loc_lon_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, query=True, required=False)
 option: StrEnum('loc_part_lon_dir', attribute=False, autofill=False, cli_name='loc_lon_dir', multivalue=False, option_group=u'LOC Record', query=True, required=False, values=(u'E', u'W'))
-option: Float('loc_part_altitude', attribute=False, autofill=False, cli_name='loc_altitude', maxvalue=42849672.95, minvalue=-100000.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
-option: Float('loc_part_size', attribute=False, autofill=False, cli_name='loc_size', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
-option: Float('loc_part_h_precision', attribute=False, autofill=False, cli_name='loc_h_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
-option: Float('loc_part_v_precision', attribute=False, autofill=False, cli_name='loc_v_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', query=True, required=False)
+option: Float('loc_part_altitude', attribute=False, autofill=False, cli_name='loc_altitude', maxvalue=Decimal('42849672.95'), minvalue=Decimal('-100000.00'), multivalue=False, option_group=u'LOC Record', precision=2, query=True, required=False)
+option: Float('loc_part_size', attribute=False, autofill=False, cli_name='loc_size', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, query=True, required=False)
+option: Float('loc_part_h_precision', attribute=False, autofill=False, cli_name='loc_h_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, query=True, required=False)
+option: Float('loc_part_v_precision', attribute=False, autofill=False, cli_name='loc_v_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, query=True, required=False)
 option: MXRecord('mxrecord', attribute=True, autofill=False, cli_name='mx_rec', csv=True, multivalue=True, option_group=u'MX Record', query=True, required=False)
 option: Int('mx_part_preference', attribute=False, autofill=False, cli_name='mx_preference', maxvalue=65535, minvalue=0, multivalue=False, option_group=u'MX Record', query=True, required=False)
 option: Str('mx_part_exchanger', attribute=False, autofill=False, cli_name='mx_exchanger', multivalue=False, option_group=u'MX Record', query=True, required=False)
@@ -950,16 +950,16 @@ option: Str('kx_part_exchanger', attribute=False, autofill=False, cli_name='kx_e
 option: LOCRecord('locrecord', attribute=True, autofill=False, cli_name='loc_rec', csv=True, multivalue=True, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lat_deg', attribute=False, autofill=False, cli_name='loc_lat_deg', maxvalue=90, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lat_min', attribute=False, autofill=False, cli_name='loc_lat_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_lat_sec', attribute=False, autofill=False, cli_name='loc_lat_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_lat_sec', attribute=False, autofill=False, cli_name='loc_lat_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, required=False)
 option: StrEnum('loc_part_lat_dir', attribute=False, autofill=False, cli_name='loc_lat_dir', multivalue=False, option_group=u'LOC Record', required=False, values=(u'N', u'S'))
 option: Int('loc_part_lon_deg', attribute=False, autofill=False, cli_name='loc_lon_deg', maxvalue=180, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
 option: Int('loc_part_lon_min', attribute=False, autofill=False, cli_name='loc_lon_min', maxvalue=59, minvalue=0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_lon_sec', attribute=False, autofill=False, cli_name='loc_lon_sec', maxvalue=59.999, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_lon_sec', attribute=False, autofill=False, cli_name='loc_lon_sec', maxvalue=Decimal('59.999'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=3, required=False)
 option: StrEnum('loc_part_lon_dir', attribute=False, autofill=False, cli_name='loc_lon_dir', multivalue=False, option_group=u'LOC Record', required=False, values=(u'E', u'W'))
-option: Float('loc_part_altitude', attribute=False, autofill=False, cli_name='loc_altitude', maxvalue=42849672.95, minvalue=-100000.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_size', attribute=False, autofill=False, cli_name='loc_size', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_h_precision', attribute=False, autofill=False, cli_name='loc_h_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
-option: Float('loc_part_v_precision', attribute=False, autofill=False, cli_name='loc_v_precision', maxvalue=90000000.0, minvalue=0.0, multivalue=False, option_group=u'LOC Record', required=False)
+option: Float('loc_part_altitude', attribute=False, autofill=False, cli_name='loc_altitude', maxvalue=Decimal('42849672.95'), minvalue=Decimal('-100000.00'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_size', attribute=False, autofill=False, cli_name='loc_size', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_h_precision', attribute=False, autofill=False, cli_name='loc_h_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
+option: Float('loc_part_v_precision', attribute=False, autofill=False, cli_name='loc_v_precision', maxvalue=Decimal('90000000.00'), minvalue=Decimal('0.0'), multivalue=False, option_group=u'LOC Record', precision=2, required=False)
 option: MXRecord('mxrecord', attribute=True, autofill=False, cli_name='mx_rec', csv=True, multivalue=True, option_group=u'MX Record', required=False)
 option: Int('mx_part_preference', attribute=False, autofill=False, cli_name='mx_preference', maxvalue=65535, minvalue=0, multivalue=False, option_group=u'MX Record', required=False)
 option: Str('mx_part_exchanger', attribute=False, autofill=False, cli_name='mx_exchanger', multivalue=False, option_group=u'MX Record', required=False)
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index be210864f465668f5cd5fdb107838efd9a66ad41..936e57e88a7cf127c31760ea89081d1a3e775f6a 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -100,6 +100,7 @@ a more detailed description for clarity.
 """
 
 import re
+from decimal import Decimal
 from types import NoneType
 from util import make_repr
 from text import _ as ugettext
@@ -723,8 +724,6 @@ class Param(ReadOnly):
                     else:
                         newval += (v,)
                 value = newval
-        if self.normalizer is None:
-            return value
         if self.multivalue:
             return tuple(
                 self._normalize_scalar(v) for v in value
@@ -740,6 +739,8 @@ class Param(ReadOnly):
         """
         if type(value) is not unicode:
             return value
+        if self.normalizer is None:
+            return value
         try:
             return self.normalizer(value)
         except StandardError:
@@ -1227,15 +1228,21 @@ class Int(Number):
 
 class Float(Number):
     """
-    A parameter for floating-point values (stored in the ``float`` type).
+    A parameter for floating-point values (stored in the ``Decimal`` type).
+
+    Python Decimal type helps overcome problems tied to plain "float" type,
+    e.g. problem with representation or value comparison. In order to safely
+    transfer the value over RPC libraries, it is being converted to string
+    which is then converted back to Decimal number.
     """
 
-    type = float
+    type = Decimal
     type_error = _('must be a decimal number')
 
     kwargs = Param.kwargs + (
-        ('minvalue', float, None),
-        ('maxvalue', float, None),
+        ('minvalue', Decimal, None),
+        ('maxvalue', Decimal, None),
+        ('precision', int, 2),
     )
 
     def __init__(self, name, *rules, **kw):
@@ -1244,17 +1251,20 @@ class Float(Number):
 
         if (self.minvalue > self.maxvalue) and (self.minvalue is not None and self.maxvalue is not None):
             raise ValueError(
-                '%s: minvalue > maxvalue (minvalue=%r, maxvalue=%r)' % (
+                '%s: minvalue > maxvalue (minvalue=%s, maxvalue=%s)' % (
                     self.nice, self.minvalue, self.maxvalue)
             )
 
+        if self.precision < 0: #pylint: disable=E1101
+            raise ValueError('%s: precision must be at least 0' % self.nice)
+
     def _rule_minvalue(self, _, value):
         """
         Check min constraint.
         """
-        assert type(value) is float
+        assert type(value) is Decimal
         if value < self.minvalue:
-            return _('must be at least %(minvalue)f') % dict(
+            return _('must be at least %(minvalue)s') % dict(
                 minvalue=self.minvalue,
             )
 
@@ -1262,12 +1272,39 @@ class Float(Number):
         """
         Check max constraint.
         """
-        assert type(value) is float
+        assert type(value) is Decimal
         if value > self.maxvalue:
-            return _('can be at most %(maxvalue)f') % dict(
+            return _('can be at most %(maxvalue)s') % dict(
                 maxvalue=self.maxvalue,
             )
 
+    def _enforce_precision(self, value):
+        assert type(value) is Decimal
+        if self.precision is not None:  #pylint: disable=E1101
+            quantize_exp = Decimal(10) ** -self.precision #pylint: disable=E1101
+            return value.quantize(quantize_exp)
+
+        return value
+
+    def _convert_scalar(self, value, index=None):
+        if isinstance(value, (basestring, float)):
+            try:
+                value = Decimal(value)
+            except Exception, e:
+                raise ConversionError(name=self.name, index=index,
+                                      error=unicode(e))
+
+        if isinstance(value, Decimal):
+            x = self._enforce_precision(value)
+            return x
+
+        return super(Float, self)._convert_scalar(value, index)
+
+    def _normalize_scalar(self, value):
+        if isinstance(value, Decimal):
+            value = self._enforce_precision(value)
+
+        return super(Float, self)._normalize_scalar(value)
 
 class Data(Param):
     """
@@ -1423,7 +1460,7 @@ class Str(Data):
         """
         if type(value) is self.type:
             return value
-        if type(value) in (int, float):
+        if type(value) in (int, float, Decimal):
             return self.type(value)
         if type(value) in (tuple, list):
             raise ConversionError(name=self.name, index=index,
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 8042c3a1b3e6bd4517930411f9eeabb877f2998f..07caec846d3e1e94b820ab63aeabb26e46df46ae 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -21,6 +21,7 @@
 import netaddr
 import time
 import re
+from decimal import Decimal
 
 from ipalib.request import context
 from ipalib import api, errors, output
@@ -345,7 +346,12 @@ class DNSRecord(Str):
             if not values:
                 return value
 
-            new_values = [ part.normalize(values[part_id]) \
+            converted_values = [ part._convert_scalar(values[part_id]) \
+                                 if values[part_id] is not None else None
+                                 for part_id, part in enumerate(self.parts)
+                               ]
+
+            new_values = [ part.normalize(converted_values[part_id]) \
                             for part_id, part in enumerate(self.parts) ]
 
             value = self._convert_scalar(new_values)
@@ -628,8 +634,9 @@ class LOCRecord(DNSRecord):
         ),
         Float('lat_sec?',
             label=_('Seconds Latitude'),
-            minvalue=0.0,
-            maxvalue=59.999,
+            minvalue=Decimal('0.0'),
+            maxvalue=Decimal('59.999'),
+            precision=3,
         ),
         StrEnum('lat_dir',
             label=_('Direction Latitude'),
@@ -647,8 +654,9 @@ class LOCRecord(DNSRecord):
         ),
         Float('lon_sec?',
             label=_('Seconds Longtitude'),
-            minvalue=0.0,
-            maxvalue=59.999,
+            minvalue=Decimal('0.0'),
+            maxvalue=Decimal('59.999'),
+            precision=3,
         ),
         StrEnum('lon_dir',
             label=_('Direction Longtitude'),
@@ -656,23 +664,27 @@ class LOCRecord(DNSRecord):
         ),
         Float('altitude',
             label=_('Altitude'),
-            minvalue=-100000.00,
-            maxvalue=42849672.95,
+            minvalue=Decimal('-100000.00'),
+            maxvalue=Decimal('42849672.95'),
+            precision=2,
         ),
         Float('size?',
             label=_('Size'),
-            minvalue=0.0,
-            maxvalue=90000000.00,
+            minvalue=Decimal('0.0'),
+            maxvalue=Decimal('90000000.00'),
+            precision=2,
         ),
         Float('h_precision?',
             label=_('Horizontal Precision'),
-            minvalue=0.0,
-            maxvalue=90000000.00,
+            minvalue=Decimal('0.0'),
+            maxvalue=Decimal('90000000.00'),
+            precision=2,
         ),
         Float('v_precision?',
             label=_('Vertical Precision'),
-            minvalue=0.0,
-            maxvalue=90000000.00,
+            minvalue=Decimal('0.0'),
+            maxvalue=Decimal('90000000.00'),
+            precision=2,
         ),
     )
 
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 8ec3a2f2706f6a18216ea8cfc74bc50b21159d31..5a59ae654496e356b35e9d82bca8d81088683972 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -31,6 +31,7 @@ Also see the `ipaserver.rpcserver` module.
 """
 
 from types import NoneType
+from decimal import Decimal
 import threading
 import sys
 import os
@@ -86,6 +87,9 @@ def xml_wrap(value):
         )
     if type(value) is str:
         return Binary(value)
+    if type(value) is Decimal:
+        # transfer Decimal as a string
+        return unicode(value)
     assert type(value) in (unicode, int, float, bool, NoneType)
     return value
 
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py
index 5cb7abf2a09f5d97d6046e56732dd204a1c6ae8c..2b17e44997c7da8d5f73aa8cd30efb65c36569a0 100644
--- a/tests/test_ipalib/test_parameters.py
+++ b/tests/test_ipalib/test_parameters.py
@@ -25,6 +25,7 @@ Test the `ipalib.parameters` module.
 import re
 import sys
 from types import NoneType
+from decimal import Decimal
 from inspect import isclass
 from tests.util import raises, ClassChecker, read_only
 from tests.util import dummy_ugettext, assert_equal
@@ -1312,13 +1313,13 @@ class test_Float(ClassChecker):
         """
         # Test with no kwargs:
         o = self.cls('my_number')
-        assert o.type is float
+        assert o.type is Decimal
         assert isinstance(o, parameters.Float)
         assert o.minvalue is None
         assert o.maxvalue is None
 
         # Test when min > max:
-        e = raises(ValueError, self.cls, 'my_number', minvalue=22.5, maxvalue=15.1)
+        e = raises(ValueError, self.cls, 'my_number', minvalue=Decimal('22.5'), maxvalue=Decimal('15.1'))
         assert str(e) == \
             "Float('my_number'): minvalue > maxvalue (minvalue=22.5, maxvalue=15.1)"
 
@@ -1326,25 +1327,25 @@ class test_Float(ClassChecker):
         """
         Test the `ipalib.parameters.Float._rule_minvalue` method.
         """
-        o = self.cls('my_number', minvalue=3.1)
-        assert o.minvalue == 3.1
+        o = self.cls('my_number', minvalue=Decimal('3.1'))
+        assert o.minvalue == Decimal('3.1')
         rule = o._rule_minvalue
-        translation = u'minvalue=%(minvalue)r'
+        translation = u'minvalue=%(minvalue)s'
         dummy = dummy_ugettext(translation)
         assert dummy.translation is translation
 
         # Test with passing values:
-        for value in (3.2, 99.0):
+        for value in (Decimal('3.2'), Decimal('99.0')):
             assert rule(dummy, value) is None
             assert dummy.called() is False
 
         # Test with failing values:
-        for value in (-1.2, 0.0, 3.0):
+        for value in (Decimal('-1.2'), Decimal('0.0'), Decimal('3.0')):
             assert_equal(
                 rule(dummy, value),
-                translation % dict(minvalue=3.1)
+                translation % dict(minvalue=Decimal('3.1'))
             )
-            assert dummy.message == 'must be at least %(minvalue)f'
+            assert dummy.message == 'must be at least %(minvalue)s'
             assert dummy.called() is True
             dummy.reset()
 
@@ -1352,25 +1353,25 @@ class test_Float(ClassChecker):
         """
         Test the `ipalib.parameters.Float._rule_maxvalue` method.
         """
-        o = self.cls('my_number', maxvalue=4.7)
-        assert o.maxvalue == 4.7
+        o = self.cls('my_number', maxvalue=Decimal('4.7'))
+        assert o.maxvalue == Decimal('4.7')
         rule = o._rule_maxvalue
         translation = u'maxvalue=%(maxvalue)r'
         dummy = dummy_ugettext(translation)
         assert dummy.translation is translation
 
         # Test with passing values:
-        for value in (-1.0, 0.1, 4.2):
+        for value in (Decimal('-1.0'), Decimal('0.1'), Decimal('4.2')):
             assert rule(dummy, value) is None
             assert dummy.called() is False
 
         # Test with failing values:
-        for value in (5.3, 99.9):
+        for value in (Decimal('5.3'), Decimal('99.9')):
             assert_equal(
                 rule(dummy, value),
-                translation % dict(maxvalue=4.7)
+                translation % dict(maxvalue=Decimal('4.7'))
             )
-            assert dummy.message == 'can be at most %(maxvalue)f'
+            assert dummy.message == 'can be at most %(maxvalue)s'
             assert dummy.called() is True
             dummy.reset()
 
diff --git a/tests/test_xmlrpc/test_dns_plugin.py b/tests/test_xmlrpc/test_dns_plugin.py
index 00d4f9b7dbd0c401cce891b0bc054c6bf85d7d8c..bded2ad42f1813cf101faf9ba5895bdf78f6699c 100644
--- a/tests/test_xmlrpc/test_dns_plugin.py
+++ b/tests/test_xmlrpc/test_dns_plugin.py
@@ -598,7 +598,7 @@ class test_dns(Declarative):
                     'idnsname': [dnszone1],
                     'mxrecord': [u"0 %s" % dnszone1_mname],
                     'nsrecord': [dnszone1_mname],
-                    'locrecord': [u"49 11 42.4 N 16 36 29.6 E 227.64"],
+                    'locrecord': [u"49 11 42.400 N 16 36 29.600 E 227.64"],
                 },
             },
         ),
-- 
1.7.7.5

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to