We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
split_port() does not properly handle ":80" or "127.0.0.1:" properly
Initially reported as https://github.com/docker/compose/issues/1887 

Example:

``` python
    def test_port_only_with_colon(self):
        self.assertRaises(ValueError,
                          lambda: split_port(":80"))

    def test_host_only_with_colon(self):
        self.assertRaises(ValueError,
                          lambda: split_port("localhost:"))
```

Results:

```
======================================================================
ERROR: test_host_only_with_colon (__main__.UtilsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests/utils_test.py", line 428, in test_host_only_with_colon
    lambda: split_port("localhost:"))
  File "/usr/lib/python2.7/unittest/case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "tests/utils_test.py", line 428, in <lambda>
    lambda: split_port("localhost:"))
  File "/home/mark/Projects/docker-py/docker/utils/ports/ports.py", line 77, in split_port
    if len(internal_range) != len(external_range):
TypeError: object of type 'NoneType' has no len()

======================================================================
ERROR: test_port_only_with_colon (__main__.UtilsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests/utils_test.py", line 424, in test_port_only_with_colon
    lambda: split_port(":80"))
  File "/usr/lib/python2.7/unittest/case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "tests/utils_test.py", line 424, in <lambda>
    lambda: split_port(":80"))
  File "/home/mark/Projects/docker-py/docker/utils/ports/ports.py", line 77, in split_port
    if len(internal_range) != len(external_range):
TypeError: object of type 'NoneType' has no len()
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docker/utils/ports/ports.py`
Content:
```
1 
2 
3 def add_port_mapping(port_bindings, internal_port, external):
4     if internal_port in port_bindings:
5         port_bindings[internal_port].append(external)
6     else:
7         port_bindings[internal_port] = [external]
8 
9 
10 def add_port(port_bindings, internal_port_range, external_range):
11     if external_range is None:
12         for internal_port in internal_port_range:
13             add_port_mapping(port_bindings, internal_port, None)
14     else:
15         ports = zip(internal_port_range, external_range)
16         for internal_port, external_port in ports:
17             add_port_mapping(port_bindings, internal_port, external_port)
18 
19 
20 def build_port_bindings(ports):
21     port_bindings = {}
22     for port in ports:
23         internal_port_range, external_range = split_port(port)
24         add_port(port_bindings, internal_port_range, external_range)
25     return port_bindings
26 
27 
28 def to_port_range(port):
29     if not port:
30         return None
31 
32     protocol = ""
33     if "/" in port:
34         parts = port.split("/")
35         if len(parts) != 2:
36             raise ValueError('Invalid port "%s", should be '
37                              '[[remote_ip:]remote_port[-remote_port]:]'
38                              'port[/protocol]' % port)
39         port, protocol = parts
40         protocol = "/" + protocol
41 
42     parts = str(port).split('-')
43 
44     if len(parts) == 1:
45         return ["%s%s" % (port, protocol)]
46 
47     if len(parts) == 2:
48         full_port_range = range(int(parts[0]), int(parts[1]) + 1)
49         return ["%s%s" % (p, protocol) for p in full_port_range]
50 
51     raise ValueError('Invalid port range "%s", should be '
52                      'port or startport-endport' % port)
53 
54 
55 def split_port(port):
56     parts = str(port).split(':')
57     if not 1 <= len(parts) <= 3:
58         raise ValueError('Invalid port "%s", should be '
59                          '[[remote_ip:]remote_port:]port[/protocol]' % port)
60 
61     if len(parts) == 1:
62         internal_port, = parts
63         return to_port_range(internal_port), None
64     if len(parts) == 2:
65         external_port, internal_port = parts
66 
67         internal_range = to_port_range(internal_port)
68         external_range = to_port_range(external_port)
69         if len(internal_range) != len(external_range):
70             raise ValueError('Port ranges don\'t match in length')
71 
72         return internal_range, external_range
73 
74     external_ip, external_port, internal_port = parts
75     internal_range = to_port_range(internal_port)
76     external_range = to_port_range(external_port)
77     if not external_range:
78         external_range = [None] * len(internal_range)
79 
80     if len(internal_range) != len(external_range):
81         raise ValueError('Port ranges don\'t match in length')
82 
83     return internal_range, [(external_ip, ex_port or None)
84                             for ex_port in external_range]
85
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/docker/utils/ports/ports.py b/docker/utils/ports/ports.py
--- a/docker/utils/ports/ports.py
+++ b/docker/utils/ports/ports.py
@@ -1,5 +1,4 @@
 
-
 def add_port_mapping(port_bindings, internal_port, external):
     if internal_port in port_bindings:
         port_bindings[internal_port].append(external)
@@ -33,9 +32,8 @@
     if "/" in port:
         parts = port.split("/")
         if len(parts) != 2:
-            raise ValueError('Invalid port "%s", should be '
-                             '[[remote_ip:]remote_port[-remote_port]:]'
-                             'port[/protocol]' % port)
+            _raise_invalid_port(port)
+
         port, protocol = parts
         protocol = "/" + protocol
 
@@ -52,11 +50,17 @@
                      'port or startport-endport' % port)
 
 
+def _raise_invalid_port(port):
+    raise ValueError('Invalid port "%s", should be '
+                     '[[remote_ip:]remote_port[-remote_port]:]'
+                     'port[/protocol]' % port)
+
+
 def split_port(port):
     parts = str(port).split(':')
+
     if not 1 <= len(parts) <= 3:
-        raise ValueError('Invalid port "%s", should be '
-                         '[[remote_ip:]remote_port:]port[/protocol]' % port)
+        _raise_invalid_port(port)
 
     if len(parts) == 1:
         internal_port, = parts
@@ -66,6 +70,10 @@
 
         internal_range = to_port_range(internal_port)
         external_range = to_port_range(external_port)
+
+        if internal_range is None or external_range is None:
+            _raise_invalid_port(port)
+
         if len(internal_range) != len(external_range):
             raise ValueError('Port ranges don\'t match in length')

{"golden_diff": "diff --git a/docker/utils/ports/ports.py b/docker/utils/ports/ports.py\n--- a/docker/utils/ports/ports.py\n+++ b/docker/utils/ports/ports.py\n@@ -1,5 +1,4 @@\n \n-\n def add_port_mapping(port_bindings, internal_port, external):\n     if internal_port in port_bindings:\n         port_bindings[internal_port].append(external)\n@@ -33,9 +32,8 @@\n     if \"/\" in port:\n         parts = port.split(\"/\")\n         if len(parts) != 2:\n-            raise ValueError('Invalid port \"%s\", should be '\n-                             '[[remote_ip:]remote_port[-remote_port]:]'\n-                             'port[/protocol]' % port)\n+            _raise_invalid_port(port)\n+\n         port, protocol = parts\n         protocol = \"/\" + protocol\n \n@@ -52,11 +50,17 @@\n                      'port or startport-endport' % port)\n \n \n+def _raise_invalid_port(port):\n+    raise ValueError('Invalid port \"%s\", should be '\n+                     '[[remote_ip:]remote_port[-remote_port]:]'\n+                     'port[/protocol]' % port)\n+\n+\n def split_port(port):\n     parts = str(port).split(':')\n+\n     if not 1 <= len(parts) <= 3:\n-        raise ValueError('Invalid port \"%s\", should be '\n-                         '[[remote_ip:]remote_port:]port[/protocol]' % port)\n+        _raise_invalid_port(port)\n \n     if len(parts) == 1:\n         internal_port, = parts\n@@ -66,6 +70,10 @@\n \n         internal_range = to_port_range(internal_port)\n         external_range = to_port_range(external_port)\n+\n+        if internal_range is None or external_range is None:\n+            _raise_invalid_port(port)\n+\n         if len(internal_range) != len(external_range):\n             raise ValueError('Port ranges don\\'t match in length')\n", "issue": "split_port() does not properly handle \":80\" or \"127.0.0.1:\" properly\nInitially reported as https://github.com/docker/compose/issues/1887 \n\nExample:\n\n``` python\n    def test_port_only_with_colon(self):\n        self.assertRaises(ValueError,\n                          lambda: split_port(\":80\"))\n\n    def test_host_only_with_colon(self):\n        self.assertRaises(ValueError,\n                          lambda: split_port(\"localhost:\"))\n```\n\nResults:\n\n```\n======================================================================\nERROR: test_host_only_with_colon (__main__.UtilsTest)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n  File \"tests/utils_test.py\", line 428, in test_host_only_with_colon\n    lambda: split_port(\"localhost:\"))\n  File \"/usr/lib/python2.7/unittest/case.py\", line 473, in assertRaises\n    callableObj(*args, **kwargs)\n  File \"tests/utils_test.py\", line 428, in <lambda>\n    lambda: split_port(\"localhost:\"))\n  File \"/home/mark/Projects/docker-py/docker/utils/ports/ports.py\", line 77, in split_port\n    if len(internal_range) != len(external_range):\nTypeError: object of type 'NoneType' has no len()\n\n======================================================================\nERROR: test_port_only_with_colon (__main__.UtilsTest)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n  File \"tests/utils_test.py\", line 424, in test_port_only_with_colon\n    lambda: split_port(\":80\"))\n  File \"/usr/lib/python2.7/unittest/case.py\", line 473, in assertRaises\n    callableObj(*args, **kwargs)\n  File \"tests/utils_test.py\", line 424, in <lambda>\n    lambda: split_port(\":80\"))\n  File \"/home/mark/Projects/docker-py/docker/utils/ports/ports.py\", line 77, in split_port\n    if len(internal_range) != len(external_range):\nTypeError: object of type 'NoneType' has no len()\n```\n\n", "before_files": [{"content": "\n\ndef add_port_mapping(port_bindings, internal_port, external):\n    if internal_port in port_bindings:\n        port_bindings[internal_port].append(external)\n    else:\n        port_bindings[internal_port] = [external]\n\n\ndef add_port(port_bindings, internal_port_range, external_range):\n    if external_range is None:\n        for internal_port in internal_port_range:\n            add_port_mapping(port_bindings, internal_port, None)\n    else:\n        ports = zip(internal_port_range, external_range)\n        for internal_port, external_port in ports:\n            add_port_mapping(port_bindings, internal_port, external_port)\n\n\ndef build_port_bindings(ports):\n    port_bindings = {}\n    for port in ports:\n        internal_port_range, external_range = split_port(port)\n        add_port(port_bindings, internal_port_range, external_range)\n    return port_bindings\n\n\ndef to_port_range(port):\n    if not port:\n        return None\n\n    protocol = \"\"\n    if \"/\" in port:\n        parts = port.split(\"/\")\n        if len(parts) != 2:\n            raise ValueError('Invalid port \"%s\", should be '\n                             '[[remote_ip:]remote_port[-remote_port]:]'\n                             'port[/protocol]' % port)\n        port, protocol = parts\n        protocol = \"/\" + protocol\n\n    parts = str(port).split('-')\n\n    if len(parts) == 1:\n        return [\"%s%s\" % (port, protocol)]\n\n    if len(parts) == 2:\n        full_port_range = range(int(parts[0]), int(parts[1]) + 1)\n        return [\"%s%s\" % (p, protocol) for p in full_port_range]\n\n    raise ValueError('Invalid port range \"%s\", should be '\n                     'port or startport-endport' % port)\n\n\ndef split_port(port):\n    parts = str(port).split(':')\n    if not 1 <= len(parts) <= 3:\n        raise ValueError('Invalid port \"%s\", should be '\n                         '[[remote_ip:]remote_port:]port[/protocol]' % port)\n\n    if len(parts) == 1:\n        internal_port, = parts\n        return to_port_range(internal_port), None\n    if len(parts) == 2:\n        external_port, internal_port = parts\n\n        internal_range = to_port_range(internal_port)\n        external_range = to_port_range(external_port)\n        if len(internal_range) != len(external_range):\n            raise ValueError('Port ranges don\\'t match in length')\n\n        return internal_range, external_range\n\n    external_ip, external_port, internal_port = parts\n    internal_range = to_port_range(internal_port)\n    external_range = to_port_range(external_port)\n    if not external_range:\n        external_range = [None] * len(internal_range)\n\n    if len(internal_range) != len(external_range):\n        raise ValueError('Port ranges don\\'t match in length')\n\n    return internal_range, [(external_ip, ex_port or None)\n                            for ex_port in external_range]\n", "path": "docker/utils/ports/ports.py"}], "after_files": [{"content": "\ndef add_port_mapping(port_bindings, internal_port, external):\n    if internal_port in port_bindings:\n        port_bindings[internal_port].append(external)\n    else:\n        port_bindings[internal_port] = [external]\n\n\ndef add_port(port_bindings, internal_port_range, external_range):\n    if external_range is None:\n        for internal_port in internal_port_range:\n            add_port_mapping(port_bindings, internal_port, None)\n    else:\n        ports = zip(internal_port_range, external_range)\n        for internal_port, external_port in ports:\n            add_port_mapping(port_bindings, internal_port, external_port)\n\n\ndef build_port_bindings(ports):\n    port_bindings = {}\n    for port in ports:\n        internal_port_range, external_range = split_port(port)\n        add_port(port_bindings, internal_port_range, external_range)\n    return port_bindings\n\n\ndef to_port_range(port):\n    if not port:\n        return None\n\n    protocol = \"\"\n    if \"/\" in port:\n        parts = port.split(\"/\")\n        if len(parts) != 2:\n            _raise_invalid_port(port)\n\n        port, protocol = parts\n        protocol = \"/\" + protocol\n\n    parts = str(port).split('-')\n\n    if len(parts) == 1:\n        return [\"%s%s\" % (port, protocol)]\n\n    if len(parts) == 2:\n        full_port_range = range(int(parts[0]), int(parts[1]) + 1)\n        return [\"%s%s\" % (p, protocol) for p in full_port_range]\n\n    raise ValueError('Invalid port range \"%s\", should be '\n                     'port or startport-endport' % port)\n\n\ndef _raise_invalid_port(port):\n    raise ValueError('Invalid port \"%s\", should be '\n                     '[[remote_ip:]remote_port[-remote_port]:]'\n                     'port[/protocol]' % port)\n\n\ndef split_port(port):\n    parts = str(port).split(':')\n\n    if not 1 <= len(parts) <= 3:\n        _raise_invalid_port(port)\n\n    if len(parts) == 1:\n        internal_port, = parts\n        return to_port_range(internal_port), None\n    if len(parts) == 2:\n        external_port, internal_port = parts\n\n        internal_range = to_port_range(internal_port)\n        external_range = to_port_range(external_port)\n\n        if internal_range is None or external_range is None:\n            _raise_invalid_port(port)\n\n        if len(internal_range) != len(external_range):\n            raise ValueError('Port ranges don\\'t match in length')\n\n        return internal_range, external_range\n\n    external_ip, external_port, internal_port = parts\n    internal_range = to_port_range(internal_port)\n    external_range = to_port_range(external_port)\n    if not external_range:\n        external_range = [None] * len(internal_range)\n\n    if len(internal_range) != len(external_range):\n        raise ValueError('Port ranges don\\'t match in length')\n\n    return internal_range, [(external_ip, ex_port or None)\n                            for ex_port in external_range]\n", "path": "docker/utils/ports/ports.py"}]}