]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Python 3: Use six.moves.range
authorAdrien Vergé <adrienverge@gmail.com>
Tue, 19 May 2015 09:05:27 +0000 (11:05 +0200)
committerAdrien Vergé <adrienverge@gmail.com>
Tue, 19 May 2015 15:32:17 +0000 (17:32 +0200)
The function `xrange` was renamed to `range` in Python 3.

* Remove `xrange` occurences so that Python 3 tests can pass. Use
  `six.moves.range` instead to get the right function in both cases.
* Generalize the use of the efficient `range` (ex-`xrange`) in
  critical sections (when iterating over large lists).
* Simplify code.
* Add a hacking check to prevent future usage of `xrange`.

Change-Id: I080acaaa1d4753619fbbb76dddba6d946d84e73f
Partially implements: blueprint neutron-python3

19 files changed:
HACKING.rst
neutron/db/sqlalchemyutils.py
neutron/hacking/checks.py
neutron/plugins/brocade/vlanbm.py
neutron/plugins/linuxbridge/agent/linuxbridge_neutron_agent.py
neutron/plugins/ml2/drivers/type_gre.py
neutron/plugins/ml2/drivers/type_vlan.py
neutron/plugins/ml2/drivers/type_vxlan.py
neutron/plugins/openvswitch/agent/ovs_neutron_agent.py
neutron/tests/functional/agent/linux/test_async_process.py
neutron/tests/functional/agent/linux/test_process_monitor.py
neutron/tests/tempest/common/glance_http.py
neutron/tests/unit/agent/l3/test_agent.py
neutron/tests/unit/api/v2/test_base.py
neutron/tests/unit/hacking/test_checks.py
neutron/tests/unit/plugins/cisco/n1kv/test_n1kv_db.py
neutron/tests/unit/plugins/ml2/drivers/base_type_tunnel.py
neutron/tests/unit/plugins/oneconvergence/test_nvsd_agent.py
neutron/tests/unit/tests/test_post_mortem_debug.py

index 35281536c7cfc75d478a07818557ec073a570a78..ce05f7f15b424d1b86f516f52c60b763ab7bde14 100644 (file)
@@ -14,6 +14,7 @@ Neutron Specific Commandments
 - [N322] Detect common errors with assert_called_once_with
 - [N323] Enforce namespace-less imports for oslo libraries
 - [N324] Prevent use of deprecated contextlib.nested.
+- [N325] Python 3: Do not use xrange.
 
 Creating Unit Tests
 -------------------
index f3df78fceb15303711c3c36fd493508d6e8befc4..466cb3fd961b44142394360a4f20cfbe5a8c3ab8 100644 (file)
@@ -88,7 +88,7 @@ def paginate_query(query, model, limit, sorts, marker_obj=None):
         criteria_list = []
         for i, sort in enumerate(sorts):
             crit_attrs = [(getattr(model, sorts[j][0]) == marker_values[j])
-                          for j in moves.xrange(i)]
+                          for j in moves.range(i)]
             model_attr = getattr(model, sort[0])
             if sort[1]:
                 crit_attrs.append((model_attr > marker_values[i]))
index 062f83961670a6888f5579c448820cb3a9a2faaa..10b26050f2a31a4ddf168a00efad78d14f384dcb 100644 (file)
@@ -160,6 +160,12 @@ def check_no_contextlib_nested(logical_line, filename):
         yield(0, msg)
 
 
+def check_python3_xrange(logical_line):
+    if re.search(r"\bxrange\s*\(", logical_line):
+        yield(0, "N325: Do not use xrange. Use range, or six.moves.range for "
+                 "large loops.")
+
+
 def factory(register):
     register(validate_log_translations)
     register(use_jsonutils)
@@ -167,3 +173,4 @@ def factory(register):
     register(no_translate_debug_logs)
     register(check_oslo_namespace_imports)
     register(check_no_contextlib_nested)
+    register(check_python3_xrange)
index fb3aeba20ad90926bc34febad780d68a2c8a123b..3323044c49eff9eb487d22e378a569665ad3ae89 100644 (file)
@@ -42,7 +42,7 @@ class VlanBitmap(object):
         min_vlan_search = vlan_id or MIN_VLAN
         max_vlan_search = (vlan_id + 1) if vlan_id else MAX_VLAN
 
-        for vlan in moves.xrange(min_vlan_search, max_vlan_search):
+        for vlan in moves.range(min_vlan_search, max_vlan_search):
             if vlan not in self.vlans:
                 self.vlans.add(vlan)
                 return vlan
index fa7c4b906261784b5972a944dd03dbc71c2754c5..604cf73c43855631d588347c318f509cb79b8128 100644 (file)
@@ -531,7 +531,7 @@ class LinuxBridgeManager(object):
             return False
 
         test_iface = None
-        for seg_id in moves.xrange(1, p_const.MAX_VXLAN_VNI + 1):
+        for seg_id in moves.range(1, p_const.MAX_VXLAN_VNI + 1):
             if not ip_lib.device_exists(
                     self.get_vxlan_device_name(seg_id)):
                 test_iface = self.ensure_vxlan(seg_id)
index fe9b87a76832088a1eb61e584ab138f980446296..134348b0697aea7692f4e82479e992d47e205128 100644 (file)
@@ -93,7 +93,7 @@ class GreTypeDriver(type_tunnel.TunnelTypeDriver):
                               "%(tun_min)s:%(tun_max)s"),
                           {'tun_min': tun_min, 'tun_max': tun_max})
             else:
-                gre_ids |= set(moves.xrange(tun_min, tun_max + 1))
+                gre_ids |= set(moves.range(tun_min, tun_max + 1))
 
         session = db_api.get_session()
         try:
index d2459e785e633315f131ae2ccf2bf516ab2dc216..451e80187ae8dbd481c81ccd8a5e93e3de2bb31b 100644 (file)
@@ -115,7 +115,7 @@ class VlanTypeDriver(helpers.SegmentTypeDriver):
                 # this physical network
                 vlan_ids = set()
                 for vlan_min, vlan_max in vlan_ranges:
-                    vlan_ids |= set(moves.xrange(vlan_min, vlan_max + 1))
+                    vlan_ids |= set(moves.range(vlan_min, vlan_max + 1))
 
                 # remove from table unallocated vlans not currently
                 # allocatable
index 5b7dbdc383a5116d2c9ffc73c5b3a8418b577f5c..51125701c226d4a0ea69715d879906096f108721 100644 (file)
@@ -96,7 +96,7 @@ class VxlanTypeDriver(type_tunnel.TunnelTypeDriver):
                               "%(tun_min)s:%(tun_max)s"),
                           {'tun_min': tun_min, 'tun_max': tun_max})
             else:
-                vxlan_vnis |= set(moves.xrange(tun_min, tun_max + 1))
+                vxlan_vnis |= set(moves.range(tun_min, tun_max + 1))
 
         session = db_api.get_session()
         with session.begin(subtransactions=True):
index 182a8fd8c59f262240dce80052a71e636d7900c5..bc42cd85f4c88c5545b9fa1efb42b5871acc1253 100644 (file)
@@ -161,8 +161,8 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         super(OVSNeutronAgent, self).__init__()
         self.use_veth_interconnection = use_veth_interconnection
         self.veth_mtu = veth_mtu
-        self.available_local_vlans = set(moves.xrange(p_const.MIN_VLAN_TAG,
-                                                      p_const.MAX_VLAN_TAG))
+        self.available_local_vlans = set(moves.range(p_const.MIN_VLAN_TAG,
+                                                     p_const.MAX_VLAN_TAG))
         self.use_call = True
         self.tunnel_types = tunnel_types or []
         self.l2_pop = l2_population
index 8fddb6d4b39b74ee468410dcc12f8b1fd3d05b69..89c2bec890f254c428a6830faa47b623d5af914c 100644 (file)
@@ -14,8 +14,6 @@
 
 import eventlet
 
-from six import moves
-
 from neutron.agent.linux import async_process
 from neutron.tests import base
 
@@ -25,7 +23,7 @@ class AsyncProcessTestFramework(base.BaseTestCase):
     def setUp(self):
         super(AsyncProcessTestFramework, self).setUp()
         self.test_file_path = self.get_temp_file_path('test_async_process.tmp')
-        self.data = [str(x) for x in moves.xrange(4)]
+        self.data = [str(x) for x in range(4)]
         with file(self.test_file_path, 'w') as f:
             f.writelines('%s\n' % item for item in self.data)
 
index 51bf796682e41ce8f1aa32b2ee21ab4c0206b1e8..0802c3a45891b87248f682a9b62bc5fdbf2bb708 100644 (file)
@@ -56,7 +56,7 @@ class BaseTestProcessMonitor(base.BaseTestCase):
 
     def spawn_n_children(self, n, service=None):
         self._child_processes = []
-        for child_number in moves.xrange(n):
+        for child_number in moves.range(n):
             uuid = self._child_uuid(child_number)
             _callback = self._make_cmdline_callback(uuid)
             pm = external_process.ProcessManager(
index 66504773965835845d770cad1020331e4cc0cd76..6cdbadc3bab6c4bd2dffb72a057f1e43b0007922 100644 (file)
@@ -17,7 +17,6 @@
 
 import copy
 import hashlib
-from six.moves import http_client as httplib
 import json
 import posixpath
 import re
@@ -30,6 +29,7 @@ import urlparse
 import OpenSSL
 from oslo_log import log as logging
 from six import moves
+from six.moves import http_client as httplib
 from tempest_lib import exceptions as lib_exc
 
 from neutron.tests.tempest import exceptions as exc
@@ -260,7 +260,7 @@ class VerifiedHTTPSConnection(httplib.HTTPSConnection):
 
         # Also try Subject Alternative Names for a match
         san_list = None
-        for i in moves.xrange(x509.get_extension_count()):
+        for i in moves.range(x509.get_extension_count()):
             ext = x509.get_extension(i)
             if ext.get_short_name() == 'subjectAltName':
                 san_list = str(ext)
index 5f0852b2e88ede5c9b2b716fa97da605263815ae..e628cd465c7e3e2c347bf51b262d85fd32165a52 100644 (file)
@@ -22,6 +22,7 @@ import mock
 import netaddr
 from oslo_log import log
 import oslo_messaging
+from six import moves
 from testtools import matchers
 
 from neutron.agent.common import config as agent_config
@@ -115,7 +116,8 @@ def router_append_subnet(router, count=1, ip_version=4,
             ipv6_subnet_modes = [subnet_mode_none] * count
         elif len(ipv6_subnet_modes) != count:
             ipv6_subnet_modes.extend([subnet_mode_none for i in
-                                      xrange(len(ipv6_subnet_modes), count)])
+                                      moves.range(len(ipv6_subnet_modes),
+                                                  count)])
 
     if ip_version == 4:
         ip_pool = '35.4.%i.4'
@@ -144,7 +146,7 @@ def router_append_subnet(router, count=1, ip_version=4,
         fixed_ips, subnets = [], []
 
     num_existing_subnets = len(subnets)
-    for i in xrange(count):
+    for i in moves.range(count):
         subnet_id = _uuid()
         fixed_ips.append(
                 {'ip_address': ip_pool % (i + num_existing_subnets),
index fb7828b7b3e869c6b14f85f79bda75494d5303de..60201e40f66378011ad3ac192eb9a0b20bf84176 100644 (file)
@@ -17,6 +17,7 @@ import os
 
 import mock
 from oslo_config import cfg
+from six import moves
 import six.moves.urllib.parse as urlparse
 import webob
 from webob import exc
@@ -1302,7 +1303,7 @@ class DHCPNotificationTest(APIv2TestBase):
                 resource += 's'
             num = len(initial_input[resource]) if initial_input and isinstance(
                 initial_input[resource], list) else 1
-            expected = [expected_item for x in xrange(num)]
+            expected = [expected_item for x in moves.range(num)]
             self.assertEqual(expected, dhcp_notifier.call_args_list)
             self.assertEqual(num, dhcp_notifier.call_count)
         self.assertEqual(expected_code, res.status_int)
index b87ad18bcb616c76ec7aa811b6070d1003ecb3ce..1445923b916034769e14d40a82880aa9b9546653 100644 (file)
@@ -18,6 +18,13 @@ from neutron.tests import base
 
 class HackingTestCase(base.BaseTestCase):
 
+    def assertLinePasses(self, func, line):
+        with testtools.ExpectedException(StopIteration):
+            next(func(line))
+
+    def assertLineFails(self, func, line):
+        self.assertIsInstance(next(func(line)), tuple)
+
     def test_log_translations(self):
         expected_marks = {
             'error': '_LE',
@@ -108,16 +115,17 @@ class HackingTestCase(base.BaseTestCase):
                                             "neutron/tests/test_assert.py"))))
 
     def test_check_oslo_namespace_imports(self):
-        def check(s, fail=True):
-            func = checks.check_oslo_namespace_imports
-            if fail:
-                self.assertIsInstance(next(func(s)), tuple)
-            else:
-                with testtools.ExpectedException(StopIteration):
-                    next(func(s))
-
-        check('from oslo_utils import importutils', fail=False)
-        check('import oslo_messaging', fail=False)
-        check('from oslo.utils import importutils')
-        check('from oslo import messaging')
-        check('import oslo.messaging')
+        f = checks.check_oslo_namespace_imports
+        self.assertLinePasses(f, 'from oslo_utils import importutils')
+        self.assertLinePasses(f, 'import oslo_messaging')
+        self.assertLineFails(f, 'from oslo.utils import importutils')
+        self.assertLineFails(f, 'from oslo import messaging')
+        self.assertLineFails(f, 'import oslo.messaging')
+
+    def test_check_python3_xrange(self):
+        f = checks.check_python3_xrange
+        self.assertLineFails(f, 'a = xrange(1000)')
+        self.assertLineFails(f, 'b =xrange   (   42 )')
+        self.assertLineFails(f, 'c = xrange(1, 10, 2)')
+        self.assertLinePasses(f, 'd = range(1000)')
+        self.assertLinePasses(f, 'e = six.moves.range(1337)')
index eadc4b4a3d0bd3657dfff763a84ebfd8be3e8c0a..fbe3223308b63f0fc6eeedd836fa53c845fc5210 100644 (file)
@@ -140,7 +140,7 @@ class VlanAllocationsTest(testlib_api.SqlTestCase):
 
     def test_vlan_pool(self):
         vlan_ids = set()
-        for x in moves.xrange(VLAN_MIN, VLAN_MAX + 1):
+        for x in moves.range(VLAN_MIN, VLAN_MAX + 1):
             (physical_network, seg_type,
              vlan_id, m_ip) = n1kv_db_v2.reserve_vlan(self.session, self.net_p)
             self.assertEqual(physical_network, PHYS_NET)
@@ -233,7 +233,7 @@ class VxlanAllocationsTest(testlib_api.SqlTestCase,
 
     def test_vxlan_pool(self):
         vxlan_ids = set()
-        for x in moves.xrange(VXLAN_MIN, VXLAN_MAX + 1):
+        for x in moves.range(VXLAN_MIN, VXLAN_MAX + 1):
             vxlan = n1kv_db_v2.reserve_vxlan(self.session, self.net_p)
             vxlan_id = vxlan[2]
             self.assertThat(vxlan_id, matchers.GreaterThan(VXLAN_MIN - 1))
index 6637c6035b209161cb3c6b9259ea01830f3e7f47..cd5469fd001281db80e115fb56824308b877a8f4 100644 (file)
@@ -139,7 +139,7 @@ class TunnelTypeTestMixin(object):
                  api.PHYSICAL_NETWORK: 'None',
                  api.SEGMENTATION_ID: None}
 
-        for x in moves.xrange(TUN_MIN, TUN_MAX + 1):
+        for x in moves.range(TUN_MIN, TUN_MAX + 1):
             segment = self.driver.reserve_provider_segment(self.session,
                                                            specs)
             self.assertEqual(self.TYPE, segment[api.NETWORK_TYPE])
@@ -170,7 +170,7 @@ class TunnelTypeTestMixin(object):
 
     def test_allocate_tenant_segment(self):
         tunnel_ids = set()
-        for x in moves.xrange(TUN_MIN, TUN_MAX + 1):
+        for x in moves.range(TUN_MIN, TUN_MAX + 1):
             segment = self.driver.allocate_tenant_segment(self.session)
             self.assertThat(segment[api.SEGMENTATION_ID],
                             matchers.GreaterThan(TUN_MIN - 1))
index 6cd2615e141e27bca1de323fdadf713f74f74ce7..5835d89a7fd90c66afb2024dbb83d223e54152b1 100644 (file)
@@ -17,6 +17,7 @@ import time
 
 import mock
 from oslo_config import cfg
+from six import moves
 import testtools
 
 from neutron.agent.common import ovs_lib
@@ -125,8 +126,8 @@ class TestNVSDAgent(TestOneConvergenceAgentBase):
         # Ensure vif_ports_scenario is longer than DAEMON_LOOP_COUNT
         if len(self.vif_ports_scenario) < DAEMON_LOOP_COUNT:
             self.vif_ports_scenario.extend(
-                [] for _i in xrange(DAEMON_LOOP_COUNT -
-                                    len(self.vif_ports_scenario)))
+                [] for _i in moves.range(DAEMON_LOOP_COUNT -
+                                         len(self.vif_ports_scenario)))
 
         with contextlib.nested(
             mock.patch.object(time, 'sleep', side_effect=sleep_mock),
index 1d940f4fadde1f5d07a35adacbc8e65f050bdd5e..652bdee6bfd0745e6714e28dda97858651e914b2 100644 (file)
@@ -77,7 +77,7 @@ class TestGetIgnoredTraceback(base.BaseTestCase):
 
         tb = root_tb
         tracebacks = [tb]
-        for x in moves.xrange(len(ignored_bit_array) - 1):
+        for x in moves.range(len(ignored_bit_array) - 1):
             tb.tb_next = mock.Mock()
             tb = tb.tb_next
             tracebacks.append(tb)