Python 3: avoid "except ..., e:" in module_utils/basic.py

Make the code compatible with Pythons 2.4 through 3.5 by using
sys.exc_info()[1] instead.

This is necessary but not sufficient for Python 3 compatibility.
pull/12487/head
Marius Gedminas 9 years ago
parent 65630d2ce1
commit d2bec7f81f

@ -162,6 +162,22 @@ except ImportError:
raise ValueError('malformed string') raise ValueError('malformed string')
return _convert(node_or_string) return _convert(node_or_string)
def get_exception():
"""Get the current exception.
This code needs to work on Python 2.4 through 3.x, so we cannot use
"except Exception, e:" (SyntaxError on Python 3.x) nor
"except Exception as e:" (SyntaxError on Python 2.4-2.5).
Instead we must use ::
except Exception:
e = get_exception()
"""
return sys.exc_info()[1]
FILE_COMMON_ARGUMENTS=dict( FILE_COMMON_ARGUMENTS=dict(
src = dict(), src = dict(),
mode = dict(), mode = dict(),
@ -527,7 +543,8 @@ class AnsibleModule(object):
return context return context
try: try:
ret = selinux.lgetfilecon_raw(self._to_filesystem_str(path)) ret = selinux.lgetfilecon_raw(self._to_filesystem_str(path))
except OSError, e: except OSError:
e = get_exception()
if e.errno == errno.ENOENT: if e.errno == errno.ENOENT:
self.fail_json(path=path, msg='path %s does not exist' % path) self.fail_json(path=path, msg='path %s does not exist' % path)
else: else:
@ -607,7 +624,8 @@ class AnsibleModule(object):
return True return True
rc = selinux.lsetfilecon(self._to_filesystem_str(path), rc = selinux.lsetfilecon(self._to_filesystem_str(path),
str(':'.join(new_context))) str(':'.join(new_context)))
except OSError, e: except OSError:
e = get_exception()
self.fail_json(path=path, msg='invalid selinux context: %s' % str(e), new_context=new_context, cur_context=cur_context, input_was=context) self.fail_json(path=path, msg='invalid selinux context: %s' % str(e), new_context=new_context, cur_context=cur_context, input_was=context)
if rc != 0: if rc != 0:
self.fail_json(path=path, msg='set selinux context failed') self.fail_json(path=path, msg='set selinux context failed')
@ -671,7 +689,8 @@ class AnsibleModule(object):
except Exception: except Exception:
try: try:
mode = self._symbolic_mode_to_octal(path_stat, mode) mode = self._symbolic_mode_to_octal(path_stat, mode)
except Exception, e: except Exception:
e = get_exception()
self.fail_json(path=path, self.fail_json(path=path,
msg="mode must be in octal or symbolic form", msg="mode must be in octal or symbolic form",
details=str(e)) details=str(e))
@ -698,14 +717,16 @@ class AnsibleModule(object):
new_underlying_stat = os.stat(path) new_underlying_stat = os.stat(path)
if underlying_stat.st_mode != new_underlying_stat.st_mode: if underlying_stat.st_mode != new_underlying_stat.st_mode:
os.chmod(path, stat.S_IMODE(underlying_stat.st_mode)) os.chmod(path, stat.S_IMODE(underlying_stat.st_mode))
except OSError, e: except OSError:
e = get_exception()
if os.path.islink(path) and e.errno == errno.EPERM: # Can't set mode on symbolic links if os.path.islink(path) and e.errno == errno.EPERM: # Can't set mode on symbolic links
pass pass
elif e.errno in (errno.ENOENT, errno.ELOOP): # Can't set mode on broken symbolic links elif e.errno in (errno.ENOENT, errno.ELOOP): # Can't set mode on broken symbolic links
pass pass
else: else:
raise e raise e
except Exception, e: except Exception:
e = get_exception()
self.fail_json(path=path, msg='chmod failed', details=str(e)) self.fail_json(path=path, msg='chmod failed', details=str(e))
path_stat = os.lstat(path) path_stat = os.lstat(path)
@ -882,7 +903,8 @@ class AnsibleModule(object):
# setting the locale to '' uses the default locale # setting the locale to '' uses the default locale
# as it would be returned by locale.getdefaultlocale() # as it would be returned by locale.getdefaultlocale()
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
except locale.Error, e: except locale.Error:
e = get_exception()
# fallback to the 'C' locale, which may cause unicode # fallback to the 'C' locale, which may cause unicode
# issues but is preferable to simply failing because # issues but is preferable to simply failing because
# of an unknown locale # of an unknown locale
@ -890,7 +912,8 @@ class AnsibleModule(object):
os.environ['LANG'] = 'C' os.environ['LANG'] = 'C'
os.environ['LC_CTYPE'] = 'C' os.environ['LC_CTYPE'] = 'C'
os.environ['LC_MESSAGES'] = 'C' os.environ['LC_MESSAGES'] = 'C'
except Exception, e: except Exception:
e = get_exception()
self.fail_json(msg="An unknown error was encountered while attempting to validate the locale: %s" % e) self.fail_json(msg="An unknown error was encountered while attempting to validate the locale: %s" % e)
def _handle_aliases(self): def _handle_aliases(self):
@ -1035,7 +1058,8 @@ class AnsibleModule(object):
return (result, None) return (result, None)
else: else:
return result return result
except Exception, e: except Exception:
e = get_exception()
if include_exceptions: if include_exceptions:
return (str, e) return (str, e)
return str return str
@ -1403,7 +1427,8 @@ class AnsibleModule(object):
try: try:
shutil.copy2(fn, backupdest) shutil.copy2(fn, backupdest)
except (shutil.Error, IOError), e: except (shutil.Error, IOError):
e = get_exception()
self.fail_json(msg='Could not make backup of %s to %s: %s' % (fn, backupdest, e)) self.fail_json(msg='Could not make backup of %s to %s: %s' % (fn, backupdest, e))
return backupdest return backupdest
@ -1412,7 +1437,8 @@ class AnsibleModule(object):
if os.path.exists(tmpfile): if os.path.exists(tmpfile):
try: try:
os.unlink(tmpfile) os.unlink(tmpfile)
except OSError, e: except OSError:
e = get_exception()
sys.stderr.write("could not cleanup %s: %s" % (tmpfile, e)) sys.stderr.write("could not cleanup %s: %s" % (tmpfile, e))
def atomic_move(self, src, dest): def atomic_move(self, src, dest):
@ -1426,7 +1452,8 @@ class AnsibleModule(object):
dest_stat = os.stat(dest) dest_stat = os.stat(dest)
os.chmod(src, dest_stat.st_mode & 07777) os.chmod(src, dest_stat.st_mode & 07777)
os.chown(src, dest_stat.st_uid, dest_stat.st_gid) os.chown(src, dest_stat.st_uid, dest_stat.st_gid)
except OSError, e: except OSError:
e = get_exception()
if e.errno != errno.EPERM: if e.errno != errno.EPERM:
raise raise
if self.selinux_enabled(): if self.selinux_enabled():
@ -1452,7 +1479,8 @@ class AnsibleModule(object):
try: try:
# Optimistically try a rename, solves some corner cases and can avoid useless work, throws exception if not atomic. # Optimistically try a rename, solves some corner cases and can avoid useless work, throws exception if not atomic.
os.rename(src, dest) os.rename(src, dest)
except (IOError,OSError), e: except (IOError, OSError):
e = get_exception()
# only try workarounds for errno 18 (cross device), 1 (not permitted), 13 (permission denied) # only try workarounds for errno 18 (cross device), 1 (not permitted), 13 (permission denied)
# and 26 (text file busy) which happens on vagrant synced folders # and 26 (text file busy) which happens on vagrant synced folders
if e.errno not in [errno.EPERM, errno.EXDEV, errno.EACCES, errno.ETXTBSY]: if e.errno not in [errno.EPERM, errno.EXDEV, errno.EACCES, errno.ETXTBSY]:
@ -1463,7 +1491,8 @@ class AnsibleModule(object):
try: try:
tmp_dest = tempfile.NamedTemporaryFile( tmp_dest = tempfile.NamedTemporaryFile(
prefix=".ansible_tmp", dir=dest_dir, suffix=dest_file) prefix=".ansible_tmp", dir=dest_dir, suffix=dest_file)
except (OSError, IOError), e: except (OSError, IOError):
e = get_exception()
self.fail_json(msg='The destination directory (%s) is not writable by the current user.' % dest_dir) self.fail_json(msg='The destination directory (%s) is not writable by the current user.' % dest_dir)
try: # leaves tmp file behind when sudo and not root try: # leaves tmp file behind when sudo and not root
@ -1480,11 +1509,13 @@ class AnsibleModule(object):
tmp_stat = os.stat(tmp_dest.name) tmp_stat = os.stat(tmp_dest.name)
if dest_stat and (tmp_stat.st_uid != dest_stat.st_uid or tmp_stat.st_gid != dest_stat.st_gid): if dest_stat and (tmp_stat.st_uid != dest_stat.st_uid or tmp_stat.st_gid != dest_stat.st_gid):
os.chown(tmp_dest.name, dest_stat.st_uid, dest_stat.st_gid) os.chown(tmp_dest.name, dest_stat.st_uid, dest_stat.st_gid)
except OSError, e: except OSError:
e = get_exception()
if e.errno != errno.EPERM: if e.errno != errno.EPERM:
raise raise
os.rename(tmp_dest.name, dest) os.rename(tmp_dest.name, dest)
except (shutil.Error, OSError, IOError), e: except (shutil.Error, OSError, IOError):
e = get_exception()
self.cleanup(tmp_dest.name) self.cleanup(tmp_dest.name)
self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e)) self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, e))
@ -1609,7 +1640,8 @@ class AnsibleModule(object):
if cwd and os.path.isdir(cwd): if cwd and os.path.isdir(cwd):
try: try:
os.chdir(cwd) os.chdir(cwd)
except (OSError, IOError), e: except (OSError, IOError):
e = get_exception()
self.fail_json(rc=e.errno, msg="Could not open %s, %s" % (cwd, str(e))) self.fail_json(rc=e.errno, msg="Could not open %s, %s" % (cwd, str(e)))
try: try:
@ -1662,7 +1694,8 @@ class AnsibleModule(object):
cmd.stderr.close() cmd.stderr.close()
rc = cmd.returncode rc = cmd.returncode
except (OSError, IOError), e: except (OSError, IOError):
e = get_exception()
self.fail_json(rc=e.errno, msg=str(e), cmd=clean_args) self.fail_json(rc=e.errno, msg=str(e), cmd=clean_args)
except: except:
self.fail_json(rc=257, msg=traceback.format_exc(), cmd=clean_args) self.fail_json(rc=257, msg=traceback.format_exc(), cmd=clean_args)

Loading…
Cancel
Save