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:
parent
5a510518d9
commit
bf68a9592d
19
HACKING.rst
19
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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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'])
|
||||
|
@ -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)
|
||||
|
@ -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')
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user