[blivet f20/master 4/5] Add parameters for untranslated Size specs.

David Shea dshea at redhat.com
Fri Nov 22 18:19:03 UTC 2013


Add en_spec parameters to Size.__init__ and Size.convertTo. spec=
strings passed to these functions will be treated as strings in the
current language, while the en_spec strings will always be treated as
English.
---
 blivet/__init__.py      |  14 +++---
 blivet/devicefactory.py |   2 +-
 blivet/size.py          | 118 +++++++++++++++++++++++++++++++++---------------
 tests/size_test.py      |  14 +++---
 4 files changed, 96 insertions(+), 52 deletions(-)

diff --git a/blivet/__init__.py b/blivet/__init__.py
index 29e7036..0a7a614 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -874,7 +874,7 @@ class Blivet(object):
             should_clear = self.shouldClear(disk, clearPartType=clearPartType,
                                             clearPartDisks=[disk.name])
             if should_clear:
-                free[disk.name] = (Size(spec="%f mb" % disk.size), 0)
+                free[disk.name] = (Size(en_spec="%f mb" % disk.size), 0)
                 continue
 
             disk_free = 0
@@ -897,8 +897,8 @@ class Blivet(object):
             elif disk.format.type is None:
                 disk_free = disk.size
 
-            free[disk.name] = (Size(spec="%f mb" % disk_free),
-                               Size(spec="%f mb" % fs_free))
+            free[disk.name] = (Size(en_spec="%f mb" % disk_free),
+                               Size(en_spec="%f mb" % fs_free))
 
         return free
 
@@ -1593,15 +1593,15 @@ class Blivet(object):
                                     "'biosboot' type partition."))
 
         if not swaps:
-            installed = Size(spec="%s kb" % util.total_memory())
-            required = Size(spec="%s kb" % isys.EARLY_SWAP_RAM)
+            installed = Size(en_spec="%s kb" % util.total_memory())
+            required = Size(en_spec="%s kb" % isys.EARLY_SWAP_RAM)
 
             if installed < required:
                 errors.append(_("You have not specified a swap partition.  "
                                 "%(requiredMem)s MB of memory is required to continue installation "
                                 "without a swap partition, but you only have %(installedMem)s MB.")
-                              % {"requiredMem": int(required.convertTo(spec="MB")),
-                                 "installedMem": int(installed.convertTo(spec="MB"))})
+                              % {"requiredMem": int(required.convertTo(en_spec="MB")),
+                                 "installedMem": int(installed.convertTo(en_spec="MB"))})
             else:
                 warnings.append(_("You have not specified a swap partition.  "
                                   "Although not strictly required in all cases, "
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index 134e1ee..32a4ab5 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -291,7 +291,7 @@ class DeviceFactory(object):
     def _get_free_disk_space(self):
         free_info = self.storage.getFreeSpace(disks=self.disks)
         free = sum(d[0] for d in free_info.values())
-        return int(free.convertTo(spec="mb"))
+        return int(free.convertTo(en_spec="mb"))
 
     def _handle_no_size(self):
         """ Set device size so that it grows to the largest size possible. """
diff --git a/blivet/size.py b/blivet/size.py
index 5fb3cc4..b097c66 100644
--- a/blivet/size.py
+++ b/blivet/size.py
@@ -53,21 +53,28 @@ _binaryPrefix = [(1024, N_("kibi"), N_("Ki")),
 _bytes = [N_('b'), N_('byte'), N_('bytes')]
 _prefixes = _decimalPrefix + _binaryPrefix
 
-def _makeSpecs(prefix, abbr):
+def _makeSpecs(prefix, abbr, xlate):
     """ Internal method used to generate a list of specifiers. """
     specs = []
 
     if prefix:
-        specs.append(prefix.lower() + _("byte"))
-        specs.append(prefix.lower() + _("bytes"))
+        if xlate:
+            specs.append(prefix.lower() + _("byte"))
+            specs.append(prefix.lower() + _("bytes"))
+        else:
+            specs.append(prefix.lower() + "byte")
+            specs.append(prefix.lower() + "bytes")
 
     if abbr:
-        specs.append(abbr.lower() + _("b"))
+        if xlate:
+            specs.append(abbr.lower() + _("b"))
+        else:
+            specs.append(abbr.lower() + "b")
         specs.append(abbr.lower())
 
     return specs
 
-def _parseSpec(spec):
+def _parseSpec(spec, xlate):
     """ Parse string representation of size. """
     if not spec:
         raise ValueError("invalid size specification", spec)
@@ -89,13 +96,19 @@ def _parseSpec(spec):
         raise SizeNotPositiveError("spec= param must be >=0")
 
     specifier = m.groups()[1].lower()
-    bytes_xlated = [_(b) for b in _bytes]
-    if not specifier or specifier in bytes_xlated:
+    if xlate:
+        bytes = [_(b) for b in _bytes]
+    else:
+        bytes = _bytes
+    if not specifier or specifier in bytes:
         return size
 
-    prefixes_xlated = [_(p) for p in _prefixes]
-    for factor, prefix, abbr in prefixes_xlated:
-        check = _makeSpecs(prefix, abbr)
+    if xlate:
+        prefixes = [_(p) for p in _prefixes]
+    else:
+        prefixes = _prefixes
+    for factor, prefix, abbr in prefixes:
+        check = _makeSpecs(prefix, abbr, xlate)
 
         if specifier in check:
             return size * factor
@@ -110,26 +123,34 @@ class Size(Decimal):
         decimal places.
     """
 
-    def __new__(cls, bytes=None,  spec=None):
-        """ Initialize a new Size object.  Must pass either bytes or spec,
-            but not both.  The bytes parameter is a numerical value for
-            the size this object represents, in bytes.  The spec parameter
-            is a string specification of the size using any of the size
+    def __new__(cls, bytes=None, spec=None, en_spec=None):
+        """ Initialize a new Size object.  Must pass only one of bytes, spec,
+            or en_spec.  The bytes parameter is a numerical value for the size
+            this object represents, in bytes.  The spec and en_spec parameters
+            are string specifications of the size using any of the size
             specifiers in the _decimalPrefix or _binaryPrefix lists combined
-            with a 'b' or 'B'.  For example, to specify 640 kilobytes, you
-            could pass any of these parameter:
+            with the abbreviation for "byte" in the current locale ('b' or 'B'
+            in English).  For example, to specify 640 kilobytes, you could pass
+            any of these parameter:
 
-                spec="640kb"
-                spec="640 kb"
-                spec="640KB"
-                spec="640 KB"
-                spec="640 kilobytes"
+                en_spec="640kb"
+                en_spec="640 kb"
+                en_spec="640KB"
+                en_spec="640 KB"
+                en_spec="640 kilobytes"
 
-            If you want to use spec to pass a bytes value, you can use the
-            letter 'b' or 'B' or simply leave the specifier off and bytes
-            will be assumed.
+            en_spec strings are in English, while spec strings are in the
+            language for the current locale. So Size objects initialized with
+            constant strings should use something like Size(en_spec="3000 MB"),
+            while Size objects created from user input should use 
+            Size(spec=input).
+
+            If you want to use spec or en_spec to pass a bytes value, you can
+            use the localized version of the letter 'b' or 'B' or simply leave
+            the specifier off and bytes will be assumed.
         """
-        if bytes and spec:
+        if (bytes and (spec or en_spec)) or (spec and (bytes or en_spec)) or \
+                (en_spec and (bytes or spec)):
             raise SizeParamsError("only specify one parameter")
 
         if bytes is not None:
@@ -138,9 +159,11 @@ class Size(Decimal):
             else:
                 raise SizeNotPositiveError("bytes= param must be >=0")
         elif spec:
-            self = Decimal.__new__(cls, value=_parseSpec(spec))
+            self = Decimal.__new__(cls, value=_parseSpec(spec, True))
+        elif en_spec:
+            self = Decimal.__new__(cls, value=_parseSpec(en_spec, False))
         else:
-            raise SizeParamsError("missing bytes= or spec=")
+            raise SizeParamsError("missing bytes=, spec=, or en_spec=")
 
         return self
 
@@ -176,22 +199,43 @@ class Size(Decimal):
 
         return val
 
-    def convertTo(self, spec="b"):
+    def convertTo(self, spec=None, en_spec=None):
         """ Return the size in the units indicated by the specifier.  The
             specifier can be prefixes from the _decimalPrefix and
-            _binaryPrefix lists combined with 'b' or 'B' for abbreviations)
-            or 'bytes' (for prefixes like kilo or mega).  The size is
-            returned as a Decimal.
+            _binaryPrefix lists combined with the localized version of 'b' or
+            'B' for abbreviations) or 'bytes' (for prefixes like kilo or mega).
+            The size is returned as a Decimal.
+
+            en_spec strings are treated as English, while spec strings are in
+            language for the current locale.
         """
+        if spec and en_spec:
+            raise SizeParamsError("only specify one of spec= or en_spec=")
+
+        if not (spec or en_spec):
+            en_spec = "b"
+
+        if spec:
+            xlate = True
+        else:
+            spec = en_spec
+            xlate = False
+
         spec = spec.lower()
 
-        bytes_xlated = [_(b) for b in _bytes]
-        if spec in bytes_xlated:
+        if xlate:
+            bytes = [_(b) for b in _bytes]
+        else:
+            bytes = _bytes
+        if spec in bytes:
             return self
 
-        prefixes_xlated = [_(p) for p in _prefixes]
-        for factor, prefix, abbr in prefixes_xlated:
-            check = _makeSpecs(prefix, abbr)
+        if xlate:
+            prefixes = [_(p) for p in _prefixes]
+        else:
+            prefixes = _prefixes
+        for factor, prefix, abbr in _prefixes:
+            check = _makeSpecs(prefix, abbr, xlate)
 
             if spec in check:
                 return Decimal(self / Decimal(factor))
diff --git a/tests/size_test.py b/tests/size_test.py
index 547035b..2b1ef64 100644
--- a/tests/size_test.py
+++ b/tests/size_test.py
@@ -29,15 +29,15 @@ from blivet.size import Size, _prefixes
 class SizeTestCase(unittest.TestCase):
     def testExceptions(self):
         self.assertRaises(SizeParamsError, Size)
-        self.assertRaises(SizeParamsError, Size, bytes=500, spec="45GB")
+        self.assertRaises(SizeParamsError, Size, bytes=500, en_spec="45GB")
 
         self.assertRaises(SizeNotPositiveError, Size, bytes=-1)
 
         zero = Size(bytes=0)
         self.assertEqual(zero, 0.0)
 
-        self.assertRaises(SizeNotPositiveError, Size, spec="-1 TB")
-        self.assertRaises(SizeNotPositiveError, Size, spec="-47kb")
+        self.assertRaises(SizeNotPositiveError, Size, en_spec="-1 TB")
+        self.assertRaises(SizeNotPositiveError, Size, en_spec="-47kb")
 
         s = Size(bytes=500)
         self.assertRaises(SizePlacesError, s.humanReadable, places=-1)
@@ -52,15 +52,15 @@ class SizeTestCase(unittest.TestCase):
 
         if prefix:
             u = "%sbytes" % prefix
-            s = Size(spec="%ld %s" % (bytes, u))
+            s = Size(en_spec="%ld %s" % (bytes, u))
             self.assertEquals(s, c)
-            self.assertEquals(s.convertTo(spec=u), bytes)
+            self.assertEquals(s.convertTo(en_spec=u), bytes)
 
         if abbr:
             u = "%sb" % abbr
-            s = Size(spec="%ld %s" % (bytes, u))
+            s = Size(en_spec="%ld %s" % (bytes, u))
             self.assertEquals(s, c)
-            self.assertEquals(s.convertTo(spec=u), bytes)
+            self.assertEquals(s.convertTo(en_spec=u), bytes)
 
         if not prefix and not abbr:
             s = Size(spec="%ld" % bytes)
-- 
1.8.3.1



More information about the anaconda-patches mailing list