[PATCH 1/3] Round sizes in humanReadable instead of flooring them

Vratislav Podzimek vpodzime at redhat.com
Wed Apr 16 18:48:55 UTC 2014


humanReadable representation of a Size instance can round the values instead of
flooring them because it should never be passed to any code requiring the
precise size. And it's much nicer to give user '9.98 GiB' instead of '9.97 GiB'
when they enter '9.98 GiB'

Also get rid of the unnecessary _trimEnd() method, the Decimal() constructor can
do the same for us.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 blivet/size.py | 48 ++++++++++++++++++------------------------------
 1 file changed, 18 insertions(+), 30 deletions(-)

diff --git a/blivet/size.py b/blivet/size.py
index 405a1b9..f0212f2 100644
--- a/blivet/size.py
+++ b/blivet/size.py
@@ -241,14 +241,6 @@ class Size(Decimal):
     def __mod__(self, other, context=None):
         return Size(bytes=Decimal.__mod__(self, other, context=context))
 
-    def _trimEnd(self, val):
-        """ Internal method to trim trailing zeros. """
-        val = re.sub(r'(\.\d*?)0+$', '\\1', val)
-        while val.endswith('.'):
-            val = val[:-1]
-
-        return val
-
     def convertTo(self, spec="b"):
         """ Return the size in the units indicated by the specifier.  The
             specifier can be prefixes from the _decimalPrefix and
@@ -280,10 +272,9 @@ class Size(Decimal):
         if max_places is not None and max_places < 0:
             raise SizePlacesError("max_places= must be >=0 or None")
 
-        check = self._trimEnd("%d" % self)
-
-        if abs(Decimal(check)) < 1000:
-            return "%s %s" % (check, _("B"))
+        in_bytes = int(Decimal(self))
+        if abs(in_bytes) < 1000:
+            return "%d %s" % (in_bytes, _("B"))
 
         for factor, prefix, abbr in _xlated_prefixes():
             newcheck = super(Size, self).__div__(Decimal(factor))
@@ -291,35 +282,32 @@ class Size(Decimal):
             if abs(newcheck) < 1000:
                 # nice value, use this factor, prefix and abbr
                 break
+        else:
+            # no nice value found, just return size in bytes
+            return "%s %s" % (in_bytes, _("B"))
 
-        # Format the value with '.' as the decimal separator
-        # If necessary, substitute with a localized separator before returning
         if places is not None:
-            newcheck_str = str(newcheck)
-            retval = newcheck_str
-            if "." in newcheck_str:
-                dot_idx = newcheck_str.index(".")
-                retval = newcheck_str[:dot_idx+places+1]
-        else:
-            retval = self._trimEnd(str(newcheck))
+            retval = round(newcheck, places)
 
         if max_places is not None:
-            (whole, point, fraction) = retval.partition(".")
-            if point and len(fraction) > max_places:
-                if max_places == 0:
-                    retval = whole
-                else:
-                    retval = "%s%s%s" % (whole, point, fraction[:max_places])
+            if places is not None:
+                limit = min((places, max_places))
+            else:
+                limit = max_places
+            retval = round(newcheck, limit)
 
+        # Format the value with '.' as the decimal separator
+        # If necessary, substitute with a localized separator before returning
+        retval_str = str(retval)
         radix = locale.nl_langinfo(locale.RADIXCHAR)
         if radix != '.':
-            retval = retval.replace('.', radix)
+            retval_str = retval_str.replace('.', radix)
 
         # abbr and prefix are unicode objects so that lower/upper work correctly
         # Convert them to str before concatenating so that the return type is
         # str.
         # pylint: disable=W0631
         if abbr:
-            return retval + " " + abbr.encode("utf-8") + _("B")
+            return retval_str + " " + abbr.encode("utf-8") + _("B")
         else:
-            return retval + " " + prefix.encode("utf-8") + P_("byte", "bytes", newcheck)
+            return retval_str + " " + prefix.encode("utf-8") + P_("byte", "bytes", newcheck)
-- 
1.9.0



More information about the anaconda-patches mailing list