summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HACKING.rst19
-rw-r--r--nova/api/ec2/__init__.py2
-rw-r--r--nova/api/openstack/compute/contrib/admin_actions.py2
-rw-r--r--nova/api/openstack/compute/contrib/attach_interfaces.py4
-rw-r--r--nova/api/openstack/compute/contrib/flavor_access.py2
-rw-r--r--nova/api/openstack/compute/contrib/flavormanage.py2
-rw-r--r--nova/cmd/baremetal_deploy_helper.py2
-rwxr-xr-xnova/compute/manager.py6
-rw-r--r--nova/console/xvp.py2
-rw-r--r--nova/db/sqlalchemy/api.py4
-rw-r--r--nova/exception.py2
-rw-r--r--nova/hacking/checks.py24
-rw-r--r--nova/image/s3.py6
-rw-r--r--nova/openstack/common/processutils.py2
-rw-r--r--nova/scheduler/scheduler_options.py4
-rw-r--r--nova/tests/api/openstack/compute/test_limits.py2
-rw-r--r--nova/tests/test_api.py2
-rw-r--r--nova/tests/test_migrations.py2
-rw-r--r--nova/tests/test_notifications.py2
-rw-r--r--nova/tests/virt/libvirt/test_fakelibvirt.py6
-rw-r--r--nova/tests/virt/libvirt/test_libvirt.py2
-rw-r--r--nova/utils.py6
-rw-r--r--nova/virt/xenapi/vmops.py2
-rw-r--r--smoketests/base.py2
-rw-r--r--tools/conf/extract_opts.py6
25 files changed, 79 insertions, 36 deletions
diff --git a/HACKING.rst b/HACKING.rst
index 307d7477c9..b29361a8d1 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -211,6 +211,25 @@ Example::
LOG.error(msg % {"s_id": "1234", "m_key": "imageId"})
+Python 3.x compatibility
+------------------------
+Nova code should stay Python 3.x compatible. That means all Python 2.x-only
+constructs should be avoided. An example is
+
+ except x,y:
+
+Use
+
+ except x as y:
+
+instead. Other Python 3.x compatility issues, like e.g. print operator
+can be avoided in new code by using
+
+ from __future__ import print_function
+
+at the top of your module.
+
+
Creating Unit Tests
-------------------
For every new feature, unit tests should be created that both test and
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index dfe015456f..12ea5f6152 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -251,7 +251,7 @@ class EC2KeystoneAuth(wsgi.Middleware):
project_name = result['access']['token']['tenant'].get('name')
roles = [role['name'] for role
in result['access']['user']['roles']]
- except (AttributeError, KeyError), e:
+ except (AttributeError, KeyError) as e:
LOG.exception(_("Keystone failure: %s") % e)
msg = _("Failure communicating with keystone")
return ec2_error(req, request_id, "Unauthorized", msg)
diff --git a/nova/api/openstack/compute/contrib/admin_actions.py b/nova/api/openstack/compute/contrib/admin_actions.py
index 3452136c03..10a3182947 100644
--- a/nova/api/openstack/compute/contrib/admin_actions.py
+++ b/nova/api/openstack/compute/contrib/admin_actions.py
@@ -123,7 +123,7 @@ class AdminActionsController(wsgi.Controller):
except exception.InstanceInvalidState as state_error:
common.raise_http_conflict_for_instance_invalid_state(state_error,
'migrate')
- except Exception, e:
+ except Exception as e:
LOG.exception(_("Error in migrate %s"), e)
raise exc.HTTPBadRequest()
return webob.Response(status_int=202)
diff --git a/nova/api/openstack/compute/contrib/attach_interfaces.py b/nova/api/openstack/compute/contrib/attach_interfaces.py
index dfaa284fa9..ec565a0d12 100644
--- a/nova/api/openstack/compute/contrib/attach_interfaces.py
+++ b/nova/api/openstack/compute/contrib/attach_interfaces.py
@@ -102,13 +102,13 @@ class InterfaceAttachmentController(object):
LOG.audit(_("Attach interface"), instance=instance)
network_info = self.compute_api.attach_interface(context,
instance, network_id, port_id, req_ip)
- except exception.NotFound, e:
+ except exception.NotFound as e:
LOG.exception(e)
raise exc.HTTPNotFound()
except NotImplementedError:
msg = _("Network driver does not support this function.")
raise webob.exc.HTTPNotImplemented(explanation=msg)
- except exception.InterfaceAttachFailed, e:
+ except exception.InterfaceAttachFailed as e:
LOG.exception(e)
msg = _("Failed to attach interface")
raise webob.exc.HTTPInternalServerError(explanation=msg)
diff --git a/nova/api/openstack/compute/contrib/flavor_access.py b/nova/api/openstack/compute/contrib/flavor_access.py
index 566eb64727..47d7e07e28 100644
--- a/nova/api/openstack/compute/contrib/flavor_access.py
+++ b/nova/api/openstack/compute/contrib/flavor_access.py
@@ -191,7 +191,7 @@ class FlavorActionController(wsgi.Controller):
try:
flavors.remove_instance_type_access(id, tenant, context)
- except exception.FlavorAccessNotFound, e:
+ except exception.FlavorAccessNotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
return _marshall_flavor_access(id)
diff --git a/nova/api/openstack/compute/contrib/flavormanage.py b/nova/api/openstack/compute/contrib/flavormanage.py
index 086c541dcc..8dc942f18a 100644
--- a/nova/api/openstack/compute/contrib/flavormanage.py
+++ b/nova/api/openstack/compute/contrib/flavormanage.py
@@ -42,7 +42,7 @@ class FlavorManageController(wsgi.Controller):
try:
flavor = flavors.get_instance_type_by_flavor_id(
id, read_deleted="no")
- except exception.NotFound, e:
+ except exception.NotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.format_message())
flavors.destroy(flavor['name'])
diff --git a/nova/cmd/baremetal_deploy_helper.py b/nova/cmd/baremetal_deploy_helper.py
index 765af8f31a..d63d06ee9d 100644
--- a/nova/cmd/baremetal_deploy_helper.py
+++ b/nova/cmd/baremetal_deploy_helper.py
@@ -201,7 +201,7 @@ def deploy(address, port, iqn, lun, image_path, pxe_config_path,
login_iscsi(address, port, iqn)
try:
root_uuid = work_on_disk(dev, root_mb, swap_mb, image_path)
- except processutils.ProcessExecutionError, err:
+ except processutils.ProcessExecutionError as err:
# Log output if there was a error
LOG.error("Cmd : %s" % err.cmd)
LOG.error("StdOut : %s" % err.stdout)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index f9a1cc94dc..8a2ddf8770 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1774,7 +1774,7 @@ class ComputeManager(manager.SchedulerDependentManager):
reboot_type,
block_device_info=block_device_info,
bad_volumes_callback=bad_volumes_callback)
- except Exception, exc:
+ except Exception as exc:
LOG.error(_('Cannot reboot instance: %(exc)s'), locals(),
context=context, instance=instance)
compute_utils.add_instance_fault_from_exc(context,
@@ -4114,7 +4114,7 @@ class ComputeManager(manager.SchedulerDependentManager):
reservations=None):
try:
yield
- except exception.InstanceFaultRollback, error:
+ except exception.InstanceFaultRollback as error:
self._quota_rollback(context, reservations)
msg = _("Setting instance back to ACTIVE after: %s")
LOG.info(msg % error, instance_uuid=instance_uuid)
@@ -4122,7 +4122,7 @@ class ComputeManager(manager.SchedulerDependentManager):
vm_state=vm_states.ACTIVE,
task_state=None)
raise error.inner_exception
- except Exception, error:
+ except Exception as error:
with excutils.save_and_reraise_exception():
self._quota_rollback(context, reservations)
msg = _('%s. Setting instance vm_state to ERROR')
diff --git a/nova/console/xvp.py b/nova/console/xvp.py
index be3a41c1dc..b281014990 100644
--- a/nova/console/xvp.py
+++ b/nova/console/xvp.py
@@ -143,7 +143,7 @@ class XVPConsoleProxy(object):
'-p', CONF.console_xvp_pid,
'-c', CONF.console_xvp_conf,
'-l', CONF.console_xvp_log)
- except processutils.ProcessExecutionError, err:
+ except processutils.ProcessExecutionError as err:
LOG.error(_('Error starting xvp: %s') % err)
def _xvp_restart(self):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 18aa185ab8..d3f53dc275 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -3739,7 +3739,7 @@ def instance_type_create(context, values):
if 'flavorid' in e.columns:
raise exception.InstanceTypeIdExists(flavor_id=values['flavorid'])
raise exception.InstanceTypeExists(name=values['name'])
- except Exception, e:
+ except Exception as e:
raise db_exc.DBError(e)
return _dict_with_extra_specs(instance_type_ref)
@@ -4505,7 +4505,7 @@ def s3_image_create(context, image_uuid):
s3_image_ref = models.S3Image()
s3_image_ref.update({'uuid': image_uuid})
s3_image_ref.save()
- except Exception, e:
+ except Exception as e:
raise db_exc.DBError(e)
return s3_image_ref
diff --git a/nova/exception.py b/nova/exception.py
index 94394d5f75..bbe5442f1d 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -73,7 +73,7 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
# contain confidential information.
try:
return f(self, context, *args, **kw)
- except Exception, e:
+ except Exception as e:
with excutils.save_and_reraise_exception():
if notifier:
payload = dict(exception=e)
diff --git a/nova/hacking/checks.py b/nova/hacking/checks.py
index 49fbf15f41..89ad7c554e 100644
--- a/nova/hacking/checks.py
+++ b/nova/hacking/checks.py
@@ -27,5 +27,29 @@ def import_no_db_in_virt(logical_line, filename):
yield (0, "N307: nova.db import not allowed in nova/virt/*")
+def except_python3x_compatible(logical_line, filename):
+ """Check for except statements to be Python 3.x compatible
+
+ As of Python 3.x, the construct "except x,y:" has been removed.
+
+ N308
+ """
+
+ def is_old_style_except(logical_line):
+ # Should match:
+ # except ProcessExecutionError, exn:
+ # Should not match:
+ # except UncodeError:
+ # except (x,y):
+ return (',' in logical_line
+ and ')' not in logical_line.rpartition(',')[2])
+
+ if ("except " in logical_line
+ and logical_line.endswith(':')
+ and is_old_style_except(logical_line)):
+ yield(0, "N308: Python 3.x incompatible 'except x,y:' construct")
+
+
def factory(register):
register(import_no_db_in_virt)
+ register(except_python3x_compatible)
diff --git a/nova/image/s3.py b/nova/image/s3.py
index f08cbcdcbd..4a5660a6c3 100644
--- a/nova/image/s3.py
+++ b/nova/image/s3.py
@@ -392,14 +392,14 @@ class S3ImageService(object):
key = self.cert_rpcapi.decrypt_text(elevated,
project_id=context.project_id,
text=base64.b64encode(encrypted_key))
- except Exception, exc:
+ except Exception as exc:
msg = _('Failed to decrypt private key: %s') % exc
raise exception.NovaException(msg)
try:
iv = self.cert_rpcapi.decrypt_text(elevated,
project_id=context.project_id,
text=base64.b64encode(encrypted_iv))
- except Exception, exc:
+ except Exception as exc:
raise exception.NovaException(_('Failed to decrypt initialization '
'vector: %s') % exc)
@@ -410,7 +410,7 @@ class S3ImageService(object):
'-K', '%s' % (key,),
'-iv', '%s' % (iv,),
'-out', '%s' % (decrypted_filename,))
- except processutils.ProcessExecutionError, exc:
+ except processutils.ProcessExecutionError as exc:
raise exception.NovaException(_('Failed to decrypt image file '
'%(image_file)s: %(err)s') %
{'image_file': encrypted_filename,
diff --git a/nova/openstack/common/processutils.py b/nova/openstack/common/processutils.py
index de6179602c..87d89b490a 100644
--- a/nova/openstack/common/processutils.py
+++ b/nova/openstack/common/processutils.py
@@ -203,7 +203,7 @@ def trycmd(*args, **kwargs):
try:
out, err = execute(*args, **kwargs)
failed = False
- except ProcessExecutionError, exn:
+ except ProcessExecutionError as exn:
out, err = '', str(exn)
failed = True
diff --git a/nova/scheduler/scheduler_options.py b/nova/scheduler/scheduler_options.py
index f7aa911550..bae470d1b1 100644
--- a/nova/scheduler/scheduler_options.py
+++ b/nova/scheduler/scheduler_options.py
@@ -66,7 +66,7 @@ class SchedulerOptions(object):
"""Get the last modified datetime. Broken out for testing."""
try:
return os.path.getmtime(filename)
- except os.error, e:
+ except os.error as e:
with excutils.save_and_reraise_exception():
LOG.exception(_("Could not stat scheduler options file "
"%(filename)s: '%(e)s'"), locals())
@@ -75,7 +75,7 @@ class SchedulerOptions(object):
"""Decode the JSON file. Broken out for testing."""
try:
return json.load(handle)
- except ValueError, e:
+ except ValueError as e:
LOG.exception(_("Could not decode scheduler options: "
"'%(e)s'") % locals())
return {}
diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py
index e51601e315..79bb97d2a2 100644
--- a/nova/tests/api/openstack/compute/test_limits.py
+++ b/nova/tests/api/openstack/compute/test_limits.py
@@ -462,7 +462,7 @@ class ParseLimitsTest(BaseLimitTestSuite):
'(PUT, /foo*, /foo.*, 10, hour);'
'(POST, /bar*, /bar.*, 5, second);'
'(Say, /derp*, /derp.*, 1, day)')
- except ValueError, e:
+ except ValueError as e:
assert False, str(e)
# Make sure the number of returned limits are correct
diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py
index 949f54512b..3c3ac6c6cd 100644
--- a/nova/tests/test_api.py
+++ b/nova/tests/test_api.py
@@ -309,7 +309,7 @@ class ApiEc2TestCase(test.TestCase):
try:
self.ec2.create_key_pair('test')
- except boto_exc.EC2ResponseError, e:
+ except boto_exc.EC2ResponseError as e:
if e.code == 'InvalidKeyPair.Duplicate':
pass
else:
diff --git a/nova/tests/test_migrations.py b/nova/tests/test_migrations.py
index 00cfdbf6c8..9baf9eb6a5 100644
--- a/nova/tests/test_migrations.py
+++ b/nova/tests/test_migrations.py
@@ -219,7 +219,7 @@ class BaseMigrationTestCase(test.TestCase):
for key, value in defaults.items():
self.test_databases[key] = value
self.snake_walk = cp.getboolean('walk_style', 'snake_walk')
- except ConfigParser.ParsingError, e:
+ except ConfigParser.ParsingError as e:
self.fail("Failed to read test_migrations.conf config "
"file. Got error: %s" % e)
else:
diff --git a/nova/tests/test_notifications.py b/nova/tests/test_notifications.py
index 71b85b3757..988ce983d4 100644
--- a/nova/tests/test_notifications.py
+++ b/nova/tests/test_notifications.py
@@ -99,7 +99,7 @@ class NotificationsTestCase(test.TestCase):
try:
# Get a real exception with a call stack.
raise test.TestingException("junk")
- except test.TestingException, e:
+ except test.TestingException as e:
exception = e
notifications.send_api_fault("http://example.com/foo", 500, exception)
diff --git a/nova/tests/virt/libvirt/test_fakelibvirt.py b/nova/tests/virt/libvirt/test_fakelibvirt.py
index 52183ab5fc..8fa2ffc63f 100644
--- a/nova/tests/virt/libvirt/test_fakelibvirt.py
+++ b/nova/tests/virt/libvirt/test_fakelibvirt.py
@@ -136,7 +136,7 @@ class FakeLibvirtTests(test.TestCase):
conn = self.get_openAuth_curry_func()('qemu:///system')
try:
getattr(conn, xmlfunc_name)("this is not valid </xml>", *args)
- except libvirt.libvirtError, e:
+ except libvirt.libvirtError as e:
self.assertEqual(e.get_error_code(), libvirt.VIR_ERR_XML_DETAIL)
self.assertEqual(e.get_error_domain(), libvirt.VIR_FROM_DOMAIN)
return
@@ -242,7 +242,7 @@ class FakeLibvirtTests(test.TestCase):
dom_id = conn.listDomainsID()[0]
try:
conn.lookupByID(dom_id + 1)
- except libvirt.libvirtError, e:
+ except libvirt.libvirtError as e:
self.assertEqual(e.get_error_code(), libvirt.VIR_ERR_NO_DOMAIN)
self.assertEqual(e.get_error_domain(), libvirt.VIR_FROM_QEMU)
return
@@ -315,7 +315,7 @@ class FakeLibvirtTests(test.TestCase):
nwfilter.undefine()
try:
conn.nwfilterLookupByName('nova-instance-instance-789320334')
- except libvirt.libvirtError, e:
+ except libvirt.libvirtError as e:
self.assertEqual(e.get_error_code(), libvirt.VIR_ERR_NO_NWFILTER)
self.assertEqual(e.get_error_domain(), libvirt.VIR_FROM_NWFILTER)
return
diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
index 6b70fe1c69..d246c32b75 100644
--- a/nova/tests/virt/libvirt/test_libvirt.py
+++ b/nova/tests/virt/libvirt/test_libvirt.py
@@ -2153,7 +2153,7 @@ class LibvirtConnTestCase(test.TestCase):
conn.ensure_filtering_rules_for_instance(instance_ref,
network_info,
time_module=fake_timer)
- except exception.NovaException, e:
+ except exception.NovaException as e:
msg = ('The firewall filter for %s does not exist' %
instance_ref['name'])
c1 = (0 <= str(e).find(msg))
diff --git a/nova/utils.py b/nova/utils.py
index 97551e8eb9..de843dff49 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -927,7 +927,7 @@ def tempdir(**kwargs):
finally:
try:
shutil.rmtree(tmpdir)
- except OSError, e:
+ except OSError as e:
LOG.error(_('Could not remove tmpdir: %s'), str(e))
@@ -1007,7 +1007,7 @@ def last_bytes(file_like_object, num):
try:
file_like_object.seek(-num, os.SEEK_END)
- except IOError, e:
+ except IOError as e:
if e.errno == 22:
file_like_object.seek(0, os.SEEK_SET)
else:
@@ -1074,7 +1074,7 @@ class ExceptionHelper(object):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
- except rpc_common.ClientException, e:
+ except rpc_common.ClientException as e:
raise (e._exc_info[1], None, e._exc_info[2])
return wrapper
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 332f3b88cc..e178d08fd8 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -877,7 +877,7 @@ class VMOps(object):
new_vdi_ref, new_vdi_uuid = create_copy_vdi_and_resize(
undo_mgr, old_vdi_ref)
transfer_vhd_to_dest(new_vdi_ref, new_vdi_uuid)
- except Exception, error:
+ except Exception as error:
msg = _("_migrate_disk_resizing_down failed. "
"Restoring orig vm due_to: %{exception}.")
LOG.exception(msg, instance=instance)
diff --git a/smoketests/base.py b/smoketests/base.py
index c90da102c8..1ecb5a92ed 100644
--- a/smoketests/base.py
+++ b/smoketests/base.py
@@ -98,7 +98,7 @@ class SmokeTestCase(unittest.TestCase):
try:
conn = self.connect_ssh(ip, key_name)
conn.close()
- except Exception, e:
+ except Exception as e:
time.sleep(wait)
else:
return True
diff --git a/tools/conf/extract_opts.py b/tools/conf/extract_opts.py
index 89f335d9b4..deb49f7a91 100644
--- a/tools/conf/extract_opts.py
+++ b/tools/conf/extract_opts.py
@@ -104,12 +104,12 @@ def _import_module(mod_str):
return sys.modules[mod_str[4:]]
else:
return importutils.import_module(mod_str)
- except (ValueError, AttributeError), err:
+ except (ValueError, AttributeError) as err:
return None
- except ImportError, ie:
+ except ImportError as ie:
sys.stderr.write("%s\n" % str(ie))
return None
- except Exception, e:
+ except Exception as e:
return None