Improve Python 3.x compatibility

Mechanical translation of the deprecated
except x,y: construct with except x as y:
The latter works with any Python >= 2.6.
Add Hacking check.

Change-Id: I845829d97d379c1cd9b3a77e7e5786586f263b64
This commit is contained in:
Dirk Mueller 2013-05-18 00:18:18 +02:00
parent 5a510518d9
commit bf68a9592d
25 changed files with 79 additions and 36 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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'])

View File

@ -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)

View File

@ -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')

View File

@ -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):

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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 {}

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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