Bug 1285703 - Re-encode the response from server to utf-8 byte-stream. r?gps draft
authorKilik Kuo <kikuo@mozilla.com>
Tue, 19 Jul 2016 18:10:13 +0800
changeset 8954 62e97140e11e7ed8cee3b7927753f83bdac47d27
parent 8952 b2434cbfec7cb7c878aa5d211276087f8f1faad4
push id1032
push userkikuo@mozilla.com
push dateTue, 19 Jul 2016 10:10:30 +0000
reviewersgps
bugs1285703
Bug 1285703 - Re-encode the response from server to utf-8 byte-stream. r?gps MozReview-Commit-ID: IwNkpQbuU21
hgext/reviewboard/client.py
hgext/reviewboard/hgrb/util.py
--- a/hgext/reviewboard/client.py
+++ b/hgext/reviewboard/client.py
@@ -61,16 +61,17 @@ except ImportError:
     sys.path.insert(0, OUR_DIR)
 
     import hgrb.proto
 demandimport.enable()
 
 from hgrb.util import (
     addcommitid,
     ReviewID,
+    reencoderesponseinplace,
 )
 
 from mozautomation.commitparser import (
     parse_bugs,
     parse_commit_id,
 )
 from mozhg.auth import (
     getbugzillaauth,
@@ -571,16 +572,21 @@ def doreview(repo, ui, remote, nodes):
             'node': hex(node),
             'precursors': precursors,
         })
 
     ui.write(_('submitting %d changesets for review\n') % len(nodes))
 
     res = calljsoncommand(ui, remote, 'pushreview', data=req, httpcap='submithttp',
                           httpcommand='mozreviewsubmitseries')
+
+    # Re-encode all items in res from u'' to utf-8 byte str to avoid
+    # exceptions during str operations.
+    reencoderesponseinplace(res)
+
     if 'error' in res:
         raise error.Abort(res['error'])
 
     for w in res['display']:
         ui.write('%s\n' % w)
 
     reviews.baseurl = res['rburl']
     newparentid = res['parentrrid']
--- a/hgext/reviewboard/hgrb/util.py
+++ b/hgext/reviewboard/hgrb/util.py
@@ -149,8 +149,34 @@ def addcommitid(msg, repo=None, fakeidpa
     # whitespaces.
     if not re.match('^[a-zA-Z-]+: \S+$', lines[-1]) or len(lines) == 1:
         lines.append('')
 
     cid = genid(repo=repo, fakeidpath=fakeidpath)
     lines.append('MozReview-Commit-ID: %s' % cid)
 
     return '\n'.join(lines), True
+
+def reencoderesponseinplace(response):
+    """
+    tuple is not handled by now.
+    """
+    def dicthandler(dictresponse):
+        for k, v in dictresponse.items():
+            nk = k.encode('utf-8') if isinstance(k, unicode) else k
+            dictresponse[nk] = dictresponse.pop(k)
+
+            if isinstance(v, unicode):
+                dictresponse[nk] = v.encode('utf-8')
+            else:
+                reencoderesponseinplace(v)
+
+    def listhandler(listresponse):
+        for idx in xrange(len(listresponse)):
+            if isinstance(listresponse[idx], unicode):
+                listresponse[idx] = listresponse[idx].encode('utf-8')
+            else:
+                reencoderesponseinplace(listresponse[idx])
+
+    if isinstance(response, dict):
+        dicthandler(response)
+    elif isinstance(response, list):
+        listhandler(response)