Mercurial > hg-stable
changeset 33708:1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Our exception types implement __bytes__(), which should be tried first. Do
lossy encoding conversion as a last resort.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 03 Aug 2017 23:02:32 +0900 |
parents | 8626b44516c1 |
children | 7dcb517122f9 |
files | mercurial/bundle2.py mercurial/extensions.py mercurial/util.py |
diffstat | 3 files changed, 14 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/bundle2.py Thu Aug 03 20:08:31 2017 -0700 +++ b/mercurial/bundle2.py Thu Aug 03 23:02:32 2017 +0900 @@ -1045,7 +1045,7 @@ ui.debug('bundle2-generatorexit\n') raise except BaseException as exc: - bexc = pycompat.bytestr(exc) + bexc = util.forcebytestr(exc) # backup exception data for later ui.debug('bundle2-input-stream-interrupt: encoding exception %s' % bexc)
--- a/mercurial/extensions.py Thu Aug 03 20:08:31 2017 -0700 +++ b/mercurial/extensions.py Thu Aug 03 23:02:32 2017 +0900 @@ -19,7 +19,6 @@ from . import ( cmdutil, configitems, - encoding, error, pycompat, util, @@ -114,16 +113,11 @@ mod = _importh(name) return mod -def _forbytes(inst): - """Portably format an import error into a form suitable for - %-formatting into bytestrings.""" - return encoding.strtolocal(str(inst)) - def _reportimporterror(ui, err, failed, next): # note: this ui.debug happens before --debug is processed, # Use --config ui.debug=1 to see them. ui.debug('could not import %s (%s): trying %s\n' - % (failed, _forbytes(err), next)) + % (failed, util.forcebytestr(err), next)) if ui.debugflag: ui.traceback() @@ -180,7 +174,7 @@ uisetup(ui) except Exception as inst: ui.traceback() - msg = _forbytes(inst) + msg = util.forcebytestr(inst) ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg)) return False return True @@ -197,7 +191,7 @@ extsetup() # old extsetup with no ui argument except Exception as inst: ui.traceback() - msg = _forbytes(inst) + msg = util.forcebytestr(inst) ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg)) return False return True @@ -215,7 +209,7 @@ try: load(ui, name, path) except Exception as inst: - msg = _forbytes(inst) + msg = util.forcebytestr(inst) if path: ui.warn(_("*** failed to import extension %s from %s: %s\n") % (name, path, msg))
--- a/mercurial/util.py Thu Aug 03 20:08:31 2017 -0700 +++ b/mercurial/util.py Thu Aug 03 23:02:32 2017 +0900 @@ -2268,6 +2268,15 @@ def unescapestr(s): return codecs.escape_decode(s)[0] +def forcebytestr(obj): + """Portably format an arbitrary object (e.g. exception) into a byte + string.""" + try: + return pycompat.bytestr(obj) + except UnicodeEncodeError: + # non-ascii string, may be lossy + return pycompat.bytestr(encoding.strtolocal(str(obj))) + def uirepr(s): # Avoid double backslash in Windows path repr() return repr(s).replace('\\\\', '\\')