Python 3: Add support in webkitpy.tool (Follow-up, part 1)
https://bugs.webkit.org/show_bug.cgi?id=204838

Reviewed by Stephanie Lewis.

As I've been using webkit-patch with Python 3, I've encountered a handful of other
compatibility bugs.

* Scripts/webkit-patch:
(ForgivingUTF8Writer): Only apple the ForgivingUTF8Writer when our string type isn't unicode.
(ForgivingUTF8Writer.write): Use standardized decoding functions.
* Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
(Bugzilla.authenticate): Use byte regex.
* Scripts/webkitpy/tool/steps/editchangelog.py:
(EditChangeLog.run): Convert map to list.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253222 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index c6888d7..be92c0c 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,5 +1,23 @@
 2019-12-06  Jonathan Bedard  <jbedard@apple.com>
 
+        Python 3: Add support in webkitpy.tool (Follow-up, part 1)
+        https://bugs.webkit.org/show_bug.cgi?id=204838
+
+        Reviewed by Stephanie Lewis.
+
+        As I've been using webkit-patch with Python 3, I've encountered a handful of other
+        compatibility bugs.
+
+        * Scripts/webkit-patch:
+        (ForgivingUTF8Writer): Only apple the ForgivingUTF8Writer when our string type isn't unicode.
+        (ForgivingUTF8Writer.write): Use standardized decoding functions.
+        * Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
+        (Bugzilla.authenticate): Use byte regex.
+        * Scripts/webkitpy/tool/steps/editchangelog.py:
+        (EditChangeLog.run): Convert map to list.
+
+2019-12-06  Jonathan Bedard  <jbedard@apple.com>
+
         Python 3: Add support in webkitpy.test
         https://bugs.webkit.org/show_bug.cgi?id=204952
 
diff --git a/Tools/Scripts/webkit-patch b/Tools/Scripts/webkit-patch
index 1635ca1..22fe748 100755
--- a/Tools/Scripts/webkit-patch
+++ b/Tools/Scripts/webkit-patch
@@ -39,29 +39,27 @@
 import codecs
 
 from webkitpy.common.system.logutils import configure_logging
+from webkitpy.common.unicode_compatibility import decode_if_necessary, unicode
 from webkitpy.tool.main import WebKitPatch
 
-# A StreamWriter will by default try to encode all objects passed
-# to write(), so when passed a raw string already encoded as utf8,
-# it will blow up with an UnicodeDecodeError. This does not match
-# the default behaviour of writing to sys.stdout, so we intercept
-# the case of writing raw strings and make sure StreamWriter gets
-# input that it can handle.
-class ForgivingUTF8Writer(codecs.lookup('utf-8')[-1]):
-    def write(self, object):
-        if isinstance(object, str):
-            # Assume raw strings are utf-8 encoded. If this line
-            # fails with an UnicodeDecodeError, our assumption was
-            # wrong, and the stacktrace should show you where we
-            # write non-Unicode/UTF-8 data (which we shouldn't).
-            object = object.decode('utf-8')
-        return codecs.StreamWriter.write(self, object)
+# If our str type isn't unicode, we need to standardize output format
+if str != unicode:
 
-# By default, sys.stdout assumes ascii encoding.  Since our messages can
-# contain unicode strings (as with some peoples' names) we need to apply
-# the utf-8 codec to prevent throwing and exception.
-# Not having this was the cause of https://bugs.webkit.org/show_bug.cgi?id=63452.
-sys.stdout = ForgivingUTF8Writer(sys.stdout)
+    # A StreamWriter will by default try to encode all objects passed
+    # to write(), so when passed a raw string already encoded as utf8,
+    # it will blow up with an UnicodeDecodeError. This does not match
+    # the default behaviour of writing to sys.stdout, so we intercept
+    # the case of writing raw strings and make sure StreamWriter gets
+    # input that it can handle.
+    class ForgivingUTF8Writer(codecs.lookup('utf-8')[-1]):
+        def write(self, value):
+            return codecs.StreamWriter.write(self, decode_if_necessary(value))
+
+    # By default, sys.stdout assumes ascii encoding.  Since our messages can
+    # contain unicode strings (as with some peoples' names) we need to apply
+    # the utf-8 codec to prevent throwing and exception.
+    # Not having this was the cause of https://bugs.webkit.org/show_bug.cgi?id=63452.
+    sys.stdout = ForgivingUTF8Writer(sys.stdout)
 
 _log = logging.getLogger("webkit-patch")
 
diff --git a/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py b/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
index 9237ac5..234824f 100644
--- a/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
+++ b/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py
@@ -585,10 +585,10 @@
             self.browser.find_control("Bugzilla_restrictlogin").items[0].selected = False
             response = self.browser.submit()
 
-            match = re.search("<title>(.+?)</title>", response.read())
+            match = re.search(b'<title>(.+?)</title>', response.read())
             # If the resulting page has a title, and it contains the word
             # "invalid" assume it's the login failure page.
-            if match and re.search("Invalid", match.group(1), re.IGNORECASE):
+            if match and re.search(b'Invalid', match.group(1), re.IGNORECASE):
                 errorMessage = "Bugzilla login failed: %s" % match.group(1)
                 # raise an exception only if this was the last attempt
                 if attempts < 5:
@@ -665,7 +665,7 @@
 
     @staticmethod
     def _parse_attachment_id_from_add_patch_to_bug_response(response_html):
-        match = re.search('<title>Attachment (?P<attachment_id>\d+) added to Bug \d+</title>', response_html)
+        match = re.search(b'<title>Attachment (?P<attachment_id>\d+) added to Bug \d+</title>', response_html)
         if match:
             return match.group('attachment_id')
         _log.warning('Unable to parse attachment id')
diff --git a/Tools/Scripts/webkitpy/tool/steps/editchangelog.py b/Tools/Scripts/webkitpy/tool/steps/editchangelog.py
index ba909e4..da5a81e 100644
--- a/Tools/Scripts/webkitpy/tool/steps/editchangelog.py
+++ b/Tools/Scripts/webkitpy/tool/steps/editchangelog.py
@@ -31,6 +31,6 @@
 
 class EditChangeLog(AbstractStep):
     def run(self, state):
-        absolute_paths = map(self._tool.scm().absolute_path, self.cached_lookup(state, "changelogs"))
+        absolute_paths = list(map(self._tool.scm().absolute_path, self.cached_lookup(state, "changelogs")))
         self._tool.user.edit_changelog(absolute_paths)
         self.did_modify_checkout(state)