Repository: docker/docker-py

Issue:
Handle floats for memory and swap limits
```
 build_pkg.build_pkg_handler() from build_queue
5f9134eb-9e13-4adc-80ea-115e86038811
Failed 29 minutes ago
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/rq/worker.py", line 568, in perform_job
    rv = job.perform()
  File "/usr/local/lib/python2.7/dist-packages/rq/job.py", line 495, in perform
    self._result = self.func(*self.args, **self.kwargs)
  File "./build_pkg.py", line 324, in build_pkg_handler
    build_result = build_pkgs(pkgobj)
  File "./build_pkg.py", line 637, in build_pkgs
    hconfig = docker_utils.create_pkgs_host_config(cache, pkgbuild_dir, result)
  File "./utils/docker_util.py", line 117, in create_pkgs_host_config
    }, privileged=True, cap_add=['ALL'], mem_limit='2.5G', memswap_limit='-1')
  File "/usr/local/lib/python2.7/dist-packages/docker/api/container.py", line 138, in create_host_config
    return utils.create_host_config(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/docker/utils/utils.py", line 493, in create_host_config
    mem_limit = parse_bytes(mem_limit)
  File "/usr/local/lib/python2.7/dist-packages/docker/utils/utils.py", line 459, in parse_bytes
    raise errors.DockerException(formatted_message)
DockerException: Failed converting the string value formemory (2.5) to a number.
```



Discussion:

Resolving patch:
diff --git a/docker/utils/utils.py b/docker/utils/utils.py
--- a/docker/utils/utils.py
+++ b/docker/utils/utils.py
@@ -486,6 +486,12 @@ def datetime_to_timestamp(dt):
     return delta.seconds + delta.days * 24 * 3600
 
 
+def longint(n):
+    if six.PY3:
+        return int(n)
+    return long(n)
+
+
 def parse_bytes(s):
     if len(s) == 0:
         s = 0
@@ -506,20 +512,21 @@ def parse_bytes(s):
 
         if suffix in units.keys() or suffix.isdigit():
             try:
-                digits = int(digits_part)
+                digits = longint(digits_part)
             except ValueError:
-                message = ('Failed converting the string value for'
-                           'memory ({0}) to a number.')
-                formatted_message = message.format(digits_part)
-                raise errors.DockerException(formatted_message)
+                raise errors.DockerException(
+                    'Failed converting the string value for memory ({0}) to'
+                    ' an integer.'.format(digits_part)
+                )
 
-            s = digits * units[suffix]
+            # Reconvert to long for the final result
+            s = longint(digits * units[suffix])
         else:
-            message = ('The specified value for memory'
-                       ' ({0}) should specify the units. The postfix'
-                       ' should be one of the `b` `k` `m` `g`'
-                       ' characters')
-            raise errors.DockerException(message.format(s))
+            raise errors.DockerException(
+                'The specified value for memory ({0}) should specify the'
+                ' units. The postfix should be one of the `b` `k` `m` `g`'
+                ' characters'.format(s)
+            )
 
     return s
 


Test patch:
diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py
--- a/tests/unit/utils_test.py
+++ b/tests/unit/utils_test.py
@@ -5,6 +5,7 @@
 import os
 import os.path
 import shutil
+import sys
 import tarfile
 import tempfile
 
@@ -465,14 +466,28 @@ def test_hybrid_list(self):
         })
 
 
-class UtilsTest(base.BaseTestCase):
-    longMessage = True
+class ParseBytesTest(base.BaseTestCase):
+    def test_parse_bytes_valid(self):
+        self.assertEqual(parse_bytes("512MB"), 536870912)
+        self.assertEqual(parse_bytes("512M"), 536870912)
+        self.assertEqual(parse_bytes("512m"), 536870912)
 
-    def test_parse_bytes(self):
-        self.assertEqual(parse_bytes("512MB"), (536870912))
-        self.assertEqual(parse_bytes("512M"), (536870912))
+    def test_parse_bytes_invalid(self):
         self.assertRaises(DockerException, parse_bytes, "512MK")
         self.assertRaises(DockerException, parse_bytes, "512L")
+        self.assertRaises(DockerException, parse_bytes, "127.0.0.1K")
+
+    def test_parse_bytes_float(self):
+        self.assertRaises(DockerException, parse_bytes, "1.5k")
+
+    def test_parse_bytes_maxint(self):
+        self.assertEqual(
+            parse_bytes("{0}k".format(sys.maxsize)), sys.maxsize * 1024
+        )
+
+
+class UtilsTest(base.BaseTestCase):
+    longMessage = True
 
     def test_convert_filters(self):
         tests = [