Python 3: Add support in webkitpy.test
https://bugs.webkit.org/show_bug.cgi?id=204952

Reviewed by Stephanie Lewis.

Source/WebKit:

Tested by test-webkitpy.

* Scripts/webkit/messages_unittest.py: Use Python 2/3 compatible StringIO.

Tools:

* Scripts/test-webkitpy-python3: Add webkitpy.tool.
* Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py: Use Python 2/3
compatible StringIO objects.
* Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: Ditto.
* Scripts/webkitpy/performance_tests/perftest_unittest.py: Ditto.
* Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py: Ditto.
* Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py: Ditto.
* Scripts/webkitpy/test/finder.py:
(Finder._exclude): Convert filter to list.
* Scripts/webkitpy/test/main.py:
(Tester._log_exception): Use Python 2/3 compatible StringIO object.
(_Loader.getTestCaseNames): Convert filter to list.
* Scripts/webkitpy/test/main_unittest.py:
(TesterTest.test_no_tests_found): Use Python 2/3 compatible StringIO.
(TesterTest.test_integration_tests_are_found): Sort serial tests before comparing.
* Scripts/webkitpy/test/printer.py: Use Python 2/3 compatible StringIO.
* Scripts/webkitpy/test/runner_unittest.py: Ditto.
* Scripts/webkitpy/test/skip.py:
(_skipped_method._skip): Fix class inspection on instance method.
* Scripts/webkitpy/test/skip_unittest.py: Use Python 2/3 compatible StringIO.
* Scripts/webkitpy/w3c/test_converter.py: Use Python 2/3 compatible HTMLParser.
* Scripts/webkitpy/w3c/wpt_runner.py:
(main): Fix Python 3 syntax errors.
* lldb/dump_class_layout_unittest.py:
(TestDumpClassLayout.setUpClass): Fix Python 3 syntax errors.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253219 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index e206359..dcfee81 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,14 @@
+2019-12-06  Jonathan Bedard  <jbedard@apple.com>
+
+        Python 3: Add support in webkitpy.test
+        https://bugs.webkit.org/show_bug.cgi?id=204952
+
+        Reviewed by Stephanie Lewis.
+
+        Tested by test-webkitpy.
+
+        * Scripts/webkit/messages_unittest.py: Use Python 2/3 compatible StringIO.
+
 2019-12-06  Keith Miller  <keith_miller@apple.com>
 
         Remove various .order files.
diff --git a/Source/WebKit/Scripts/webkit/messages_unittest.py b/Source/WebKit/Scripts/webkit/messages_unittest.py
index 8c6af8c..56032b2 100644
--- a/Source/WebKit/Scripts/webkit/messages_unittest.py
+++ b/Source/WebKit/Scripts/webkit/messages_unittest.py
@@ -24,7 +24,11 @@
 import re
 import sys
 import unittest
-from StringIO import StringIO
+
+if sys.version_info > (3, 0):
+    from io import StringIO
+else:
+    from StringIO import StringIO
 
 sys.path.append(os.path.dirname(os.path.dirname(__file__)))
 from webkit import messages
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 4343826..c6888d7 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,36 @@
+2019-12-06  Jonathan Bedard  <jbedard@apple.com>
+
+        Python 3: Add support in webkitpy.test
+        https://bugs.webkit.org/show_bug.cgi?id=204952
+
+        Reviewed by Stephanie Lewis.
+
+        * Scripts/test-webkitpy-python3: Add webkitpy.tool.
+        * Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py: Use Python 2/3
+        compatible StringIO objects.
+        * Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py: Ditto.
+        * Scripts/webkitpy/performance_tests/perftest_unittest.py: Ditto.
+        * Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py: Ditto.
+        * Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py: Ditto.
+        * Scripts/webkitpy/test/finder.py:
+        (Finder._exclude): Convert filter to list.
+        * Scripts/webkitpy/test/main.py:
+        (Tester._log_exception): Use Python 2/3 compatible StringIO object.
+        (_Loader.getTestCaseNames): Convert filter to list.
+        * Scripts/webkitpy/test/main_unittest.py:
+        (TesterTest.test_no_tests_found): Use Python 2/3 compatible StringIO.
+        (TesterTest.test_integration_tests_are_found): Sort serial tests before comparing.
+        * Scripts/webkitpy/test/printer.py: Use Python 2/3 compatible StringIO.
+        * Scripts/webkitpy/test/runner_unittest.py: Ditto.
+        * Scripts/webkitpy/test/skip.py:
+        (_skipped_method._skip): Fix class inspection on instance method.
+        * Scripts/webkitpy/test/skip_unittest.py: Use Python 2/3 compatible StringIO.
+        * Scripts/webkitpy/w3c/test_converter.py: Use Python 2/3 compatible HTMLParser.
+        * Scripts/webkitpy/w3c/wpt_runner.py:
+        (main): Fix Python 3 syntax errors.
+        * lldb/dump_class_layout_unittest.py:
+        (TestDumpClassLayout.setUpClass): Fix Python 3 syntax errors.
+
 2019-12-05  Jonathan Bedard  <jbedard@apple.com>
 
         Python 3: Add support to webkitpy.browserperfdash
diff --git a/Tools/Scripts/test-webkitpy-python3 b/Tools/Scripts/test-webkitpy-python3
index 825f791..adb6c5c 100755
--- a/Tools/Scripts/test-webkitpy-python3
+++ b/Tools/Scripts/test-webkitpy-python3
@@ -43,9 +43,10 @@
   'webkitpy.layout_tests.servers',
   'webkitpy.layout_tests.views',
   'webkitpy.port',
-  'webkitpy.tool',
   'webkitpy.results',
   'webkitpy.style',
+  'webkitpy.test',
+  'webkitpy.tool',
   'webkitpy.xcode',
 ]
 SLOW_TESTS = [
diff --git a/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py b/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py
index dfb1a6f..a98c36f 100644
--- a/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py
@@ -26,11 +26,11 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import optparse
 import unittest
 
 from webkitpy.common.host_mock import MockHost
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.layout_tests import lint_test_expectations
 
 
@@ -85,14 +85,14 @@
                                                FakePort(host, 'b', 'path-to-b'),
                                                FakePort(host, 'b-win', 'path-to-b')))
 
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
         options = optparse.Values({'platform': None})
         res = lint_test_expectations.lint(host, options, logging_stream)
         self.assertEqual(res, 0)
         self.assertEqual(host.ports_parsed, ['a', 'b', 'b-win'])
 
     def test_lint_test_files(self):
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
         options = optparse.Values({'platform': 'test-mac-leopard'})
         host = MockHost()
 
@@ -116,7 +116,7 @@
         host.port_factory.get = lambda platform, options=None: port
         host.port_factory.all_port_names = lambda platform=None: [port.name()]
 
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
 
         res = lint_test_expectations.lint(host, options, logging_stream)
 
@@ -140,8 +140,8 @@
         def exception_raising_lint(host, options, logging_stream):
             assert False
 
-        stdout = StringIO.StringIO()
-        stderr = StringIO.StringIO()
+        stdout = StringIO()
+        stderr = StringIO()
         try:
             lint_test_expectations.lint = interrupting_lint
             res = lint_test_expectations.main([], stdout, stderr)
diff --git a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
index 84c939f..1c0c6c8 100644
--- a/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py
@@ -29,7 +29,6 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 import json
-import StringIO
 import unittest
 
 from webkitpy.common.system import outputcapture, path
@@ -37,6 +36,7 @@
 from webkitpy.common.system.systemhost import SystemHost
 from webkitpy.common.host import Host
 from webkitpy.common.host_mock import MockHost
+from webkitpy.common.unicode_compatibility import StringIO
 
 from webkitpy.layout_tests import run_webkit_tests
 from webkitpy.layout_tests.models.test_run_results import INTERRUPTED_EXIT_STATUS
@@ -77,7 +77,7 @@
     if shared_port:
         port_obj.host.port_factory.get = lambda *args, **kwargs: port_obj
 
-    logging_stream = StringIO.StringIO()
+    logging_stream = StringIO()
     run_details = run_webkit_tests.run(port_obj, options, parsed_args, logging_stream=logging_stream)
     return run_details.exit_code == 0
 
@@ -100,7 +100,7 @@
     oc = outputcapture.OutputCapture()
     try:
         oc.capture_output()
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
         run_details = run_webkit_tests.run(port_obj, options, parsed_args, logging_stream=logging_stream)
     finally:
         oc.restore_output()
@@ -135,7 +135,7 @@
 
     oc = outputcapture.OutputCapture()
     oc.capture_output()
-    logging_stream = StringIO.StringIO()
+    logging_stream = StringIO()
     try:
         run_details = run_webkit_tests.run(port_obj, options, parsed_args, logging_stream=logging_stream)
     finally:
@@ -180,7 +180,7 @@
 
     def test_basic(self):
         options, args = parse_args(tests_included=True)
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
         host = MockHost()
         port_obj = host.port_factory.get(options.platform, options)
         details = run_webkit_tests.run(port_obj, options, args, logging_stream)
@@ -798,8 +798,8 @@
         self.assertEqual(full_results['has_pretty_patch'], False)
 
     def test_unsupported_platform(self):
-        stdout = StringIO.StringIO()
-        stderr = StringIO.StringIO()
+        stdout = StringIO()
+        stderr = StringIO()
         res = run_webkit_tests.main(['--platform', 'foo'], stdout, stderr)
 
         self.assertEqual(res, run_webkit_tests.EXCEPTIONAL_EXIT_STATUS)
@@ -819,7 +819,7 @@
         options, parsed_args = parse_args(['--verbose', '--fully-parallel', '--child-processes', '2', 'passes/text.html', 'passes/image.html'], tests_included=True, print_nothing=False)
         host = MockHost()
         port_obj = host.port_factory.get(port_name=options.platform, options=options)
-        logging_stream = StringIO.StringIO()
+        logging_stream = StringIO()
         run_webkit_tests.run(port_obj, options, parsed_args, logging_stream=logging_stream)
         self.assertTrue('text.html passed' in logging_stream.getvalue())
         self.assertTrue('image.html passed' in logging_stream.getvalue())
@@ -836,7 +836,7 @@
         oc = outputcapture.OutputCapture()
         try:
             oc.capture_output()
-            logging = StringIO.StringIO()
+            logging = StringIO()
             run_webkit_tests.run(port, run_webkit_tests.parse_args(['--debug-rwt-logging', '-n', '--no-build', '--root', '/build'])[0], [], logging_stream=logging)
         finally:
             output, err, _ = oc.restore_output()
@@ -860,7 +860,7 @@
         oc = outputcapture.OutputCapture()
         try:
             oc.capture_output()
-            logging = StringIO.StringIO()
+            logging = StringIO()
             run_webkit_tests._print_expectations(port, run_webkit_tests.parse_args([])[0], [], logging_stream=logging)
         finally:
             output, _, _ = oc.restore_output()
@@ -894,7 +894,7 @@
         oc = outputcapture.OutputCapture()
         try:
             oc.capture_output()
-            logging = StringIO.StringIO()
+            logging = StringIO()
             run_webkit_tests.run(port, run_webkit_tests.parse_args(['--debug-rwt-logging', '-n', '--no-build', '--root', '/build'])[0], [], logging_stream=logging)
         finally:
             output, err, _ = oc.restore_output()
@@ -915,7 +915,7 @@
         oc = outputcapture.OutputCapture()
         try:
             oc.capture_output()
-            logging = StringIO.StringIO()
+            logging = StringIO()
             run_webkit_tests._print_expectations(port, run_webkit_tests.parse_args([])[0], [], logging_stream=logging)
         finally:
             output, _, _ = oc.restore_output()
@@ -1040,8 +1040,8 @@
         def exception_raising_run(port, options, args, stderr):
             assert False
 
-        stdout = StringIO.StringIO()
-        stderr = StringIO.StringIO()
+        stdout = StringIO()
+        stderr = StringIO()
         try:
             run_webkit_tests.run = interrupting_run
             res = run_webkit_tests.main([], stdout, stderr)
diff --git a/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py b/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py
index 889f432..0e7cac5 100644
--- a/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py
+++ b/Tools/Scripts/webkitpy/performance_tests/perftest_unittest.py
@@ -26,13 +26,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import json
 import math
 import unittest
 
 from webkitpy.common.host_mock import MockHost
 from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.port.driver import DriverOutput
 from webkitpy.port.test import TestDriver
 from webkitpy.port.test import TestPort
diff --git a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
index ffe2a8d..e22b498 100644
--- a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
+++ b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_integrationtest.py
@@ -28,7 +28,6 @@
 
 """Integration tests for run_perf_tests."""
 
-import StringIO
 import datetime
 import json
 import re
@@ -36,6 +35,7 @@
 
 from webkitpy.common.host_mock import MockHost
 from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.port.driver import DriverOutput
 from webkitpy.port.test import TestPort
 from webkitpy.performance_tests.perftest import PerfTest
diff --git a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py
index e209c65..6c0575c 100644
--- a/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py
+++ b/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py
@@ -28,13 +28,13 @@
 
 """Unit tests for run_perf_tests."""
 
-import StringIO
 import json
 import re
 import unittest
 
 from webkitpy.common.host_mock import MockHost
 from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.port.test import TestPort
 from webkitpy.performance_tests.perftest import DEFAULT_TEST_RUNNER_COUNT
 from webkitpy.performance_tests.perftestsrunner import PerfTestsRunner
@@ -201,16 +201,16 @@
                     raise Exception
                 return mock.upload_single_text_file_return_value
 
-        MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('OK')
+        MockFileUploader.upload_single_text_file_return_value = StringIO('OK')
         self.assertTrue(runner._upload_json('https://some.host', 'some.json', '/some/path', MockFileUploader))
         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
 
         MockFileUploader.reset()
-        MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('OK')
+        MockFileUploader.upload_single_text_file_return_value = StringIO('OK')
         self.assertTrue(runner._upload_json('some.host', 'some.json', '/some/path', MockFileUploader))
 
         MockFileUploader.reset()
-        MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('Some error')
+        MockFileUploader.upload_single_text_file_return_value = StringIO('Some error')
         output = OutputCapture()
         output.capture_output()
         self.assertFalse(runner._upload_json('https://some.host', 'some.json', '/some/path', MockFileUploader))
@@ -224,12 +224,12 @@
         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
 
         MockFileUploader.reset()
-        MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('{"status": "OK"}')
+        MockFileUploader.upload_single_text_file_return_value = StringIO('{"status": "OK"}')
         self.assertTrue(runner._upload_json('https://some.host', 'some.json', '/some/path', MockFileUploader))
         self.assertEqual(MockFileUploader.called, ['FileUploader', 'upload_single_text_file'])
 
         MockFileUploader.reset()
-        MockFileUploader.upload_single_text_file_return_value = StringIO.StringIO('{"status": "SomethingHasFailed", "failureStored": false}')
+        MockFileUploader.upload_single_text_file_return_value = StringIO('{"status": "SomethingHasFailed", "failureStored": false}')
         output = OutputCapture()
         output.capture_output()
         self.assertFalse(runner._upload_json('https://some.host', 'some.json', '/some/path', MockFileUploader))
diff --git a/Tools/Scripts/webkitpy/test/finder.py b/Tools/Scripts/webkitpy/test/finder.py
index 21eceac..d227663 100644
--- a/Tools/Scripts/webkitpy/test/finder.py
+++ b/Tools/Scripts/webkitpy/test/finder.py
@@ -164,7 +164,7 @@
         _log.info('Skipping tests in the following modules or packages because they %s:' % reason)
         for prefix in module_prefixes:
             _log.info('    %s' % prefix)
-            modules_to_exclude = filter(lambda m: m.startswith(prefix), modules)
+            modules_to_exclude = list(filter(lambda m: m.startswith(prefix), modules))
             for m in modules_to_exclude:
                 if len(modules_to_exclude) > 1:
                     _log.debug('        %s' % m)
diff --git a/Tools/Scripts/webkitpy/test/main.py b/Tools/Scripts/webkitpy/test/main.py
index 7162d33..3f4db8d 100644
--- a/Tools/Scripts/webkitpy/test/main.py
+++ b/Tools/Scripts/webkitpy/test/main.py
@@ -24,7 +24,6 @@
 
 """unit testing code for webkitpy."""
 
-import StringIO
 import itertools
 import json
 import logging
@@ -41,6 +40,7 @@
 from webkitpy.common.system.executive import ScriptError
 from webkitpy.common.system.filesystem import FileSystem
 from webkitpy.common.host import Host
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.port.config import Config
 from webkitpy.test.finder import Finder
 from webkitpy.test.printer import Printer
@@ -353,9 +353,9 @@
         return names
 
     def _log_exception(self):
-        s = StringIO.StringIO()
+        s = StringIO()
         traceback.print_exc(file=s)
-        for l in s.buflist:
+        for l in s.getvalue().splitlines():
             _log.error('  ' + l.rstrip())
 
 
@@ -373,9 +373,8 @@
             if not hasattr(getattr(testCaseClass, attrname), '__call__'):
                 return False
             return (any(attrname.startswith(prefix) for prefix in self.test_method_prefixes))
-        testFnNames = filter(isTestMethod, dir(testCaseClass))
-        testFnNames.sort()
-        return testFnNames
+
+        return sorted(filter(isTestMethod, dir(testCaseClass)))
 
 
 if __name__ == '__main__':
diff --git a/Tools/Scripts/webkitpy/test/main_unittest.py b/Tools/Scripts/webkitpy/test/main_unittest.py
index 2a48243..2fb52e6 100644
--- a/Tools/Scripts/webkitpy/test/main_unittest.py
+++ b/Tools/Scripts/webkitpy/test/main_unittest.py
@@ -20,11 +20,11 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import logging
 import sys
 import unittest
 
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.common.system.filesystem import FileSystem
 from webkitpy.common.system.executive import Executive
 from webkitpy.common.system.outputcapture import OutputCapture
@@ -52,7 +52,7 @@
 
     def test_no_tests_found(self):
         tester = Tester()
-        errors = StringIO.StringIO()
+        errors = StringIO()
 
         # Here we need to remove any existing log handlers so that they
         # don't log the messages webkitpy.test while we're testing it.
@@ -99,7 +99,7 @@
             STUBS_CLASS + '.integration_test_empty',
             STUBS_CLASS + '.test_empty',
             ])
-        self.assertEqual(serial_tests, [
+        self.assertEqual(sorted(serial_tests), [
             STUBS_CLASS + '.serial_integration_test_empty',
             STUBS_CLASS + '.serial_test_empty',
             ])
diff --git a/Tools/Scripts/webkitpy/test/printer.py b/Tools/Scripts/webkitpy/test/printer.py
index d036428..f9707ba 100644
--- a/Tools/Scripts/webkitpy/test/printer.py
+++ b/Tools/Scripts/webkitpy/test/printer.py
@@ -21,11 +21,11 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import logging
 
 from webkitpy.common.system import outputcapture
 from webkitpy.common.system.systemhost import SystemHost
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.layout_tests.views.metered_stream import MeteredStream
 from webkitpy.tool.grammar import pluralize
 
@@ -187,7 +187,7 @@
 
 class _CaptureAndPassThroughStream(object):
     def __init__(self, stream):
-        self._buffer = StringIO.StringIO()
+        self._buffer = StringIO()
         self._stream = stream
 
     def write(self, msg):
diff --git a/Tools/Scripts/webkitpy/test/runner_unittest.py b/Tools/Scripts/webkitpy/test/runner_unittest.py
index 79f3fb3..9cb1824 100644
--- a/Tools/Scripts/webkitpy/test/runner_unittest.py
+++ b/Tools/Scripts/webkitpy/test/runner_unittest.py
@@ -20,11 +20,11 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import logging
 import re
 import unittest
 
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.tool.mocktool import MockOptions
 from webkitpy.test.printer import Printer
 from webkitpy.test.runner import Runner
@@ -86,7 +86,7 @@
 
     def test_run(self, verbose=0, timing=False, child_processes=1, quiet=False):
         options = MockOptions(verbose=verbose, timing=timing, child_processes=child_processes, quiet=quiet, pass_through=False)
-        stream = StringIO.StringIO()
+        stream = StringIO()
         loader = FakeLoader(('test1 (Foo)', '.', ''),
                             ('test2 (Foo)', 'F', 'test2\nfailed'),
                             ('test3 (Foo)', 'E', 'test3\nerred'))
diff --git a/Tools/Scripts/webkitpy/test/skip.py b/Tools/Scripts/webkitpy/test/skip.py
index 8587d56..83b634d 100644
--- a/Tools/Scripts/webkitpy/test/skip.py
+++ b/Tools/Scripts/webkitpy/test/skip.py
@@ -44,9 +44,9 @@
 
 
 def _skipped_method(method, message, logger):
-    def _skip(*args):
-        if method.im_class._printed_skipped_message:
+    def _skip(self, *args):
+        if self._printed_skipped_message:
             return
-        method.im_class._printed_skipped_message = True
-        logger.info('Skipping %s.%s: %s' % (method.__module__, method.im_class.__name__, message))
+        self._printed_skipped_message = True
+        logger.info('Skipping %s.%s: %s' % (method.__module__, type(self).__name__, message))
     return _skip
diff --git a/Tools/Scripts/webkitpy/test/skip_unittest.py b/Tools/Scripts/webkitpy/test/skip_unittest.py
index 2f847d6..baac471 100644
--- a/Tools/Scripts/webkitpy/test/skip_unittest.py
+++ b/Tools/Scripts/webkitpy/test/skip_unittest.py
@@ -20,10 +20,10 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import StringIO
 import logging
 import unittest
 
+from webkitpy.common.unicode_compatibility import StringIO
 from webkitpy.test.skip import skip_if
 
 
@@ -37,7 +37,7 @@
         self.old_propagate = self.logger.propagate
         self.logger.propagate = False
 
-        self.log_stream = StringIO.StringIO()
+        self.log_stream = StringIO()
         self.handler = logging.StreamHandler(self.log_stream)
         self.logger.addHandler(self.handler)
 
diff --git a/Tools/Scripts/webkitpy/w3c/test_converter.py b/Tools/Scripts/webkitpy/w3c/test_converter.py
index 5274a29..f1aac46 100644
--- a/Tools/Scripts/webkitpy/w3c/test_converter.py
+++ b/Tools/Scripts/webkitpy/w3c/test_converter.py
@@ -30,10 +30,15 @@
 import json
 import logging
 import re
+import sys
 
 from webkitpy.common.host import Host
 from webkitpy.common.webkit_finder import WebKitFinder
-from HTMLParser import HTMLParser
+
+if sys.version_info > (3, 0):
+    from html.parser import HTMLParser
+else:
+    from HTMLParser import HTMLParser
 
 _log = logging.getLogger(__name__)
 
diff --git a/Tools/Scripts/webkitpy/w3c/wpt_runner.py b/Tools/Scripts/webkitpy/w3c/wpt_runner.py
index 421773e..14ef6de 100644
--- a/Tools/Scripts/webkitpy/w3c/wpt_runner.py
+++ b/Tools/Scripts/webkitpy/w3c/wpt_runner.py
@@ -46,7 +46,7 @@
     host = Host()
     try:
         port = host.port_factory.get(options.platform, options)
-    except NotImplementedError, e:
+    except NotImplementedError as e:
         _log.error(str(e))
         sys.exit(-1)
 
diff --git a/Tools/lldb/dump_class_layout_unittest.py b/Tools/lldb/dump_class_layout_unittest.py
index c2aded8..2a45f7d 100755
--- a/Tools/lldb/dump_class_layout_unittest.py
+++ b/Tools/lldb/dump_class_layout_unittest.py
@@ -59,7 +59,7 @@
             architecture = 'x86_64'
             debugger_instance = LLDBDebuggerInstance(lldbWebKitTesterExecutable, architecture)
             if not debugger_instance:
-                print 'Failed to create lldb debugger instance for %s' % (lldbWebKitTesterExecutable)
+                print('Failed to create lldb debugger instance for %s' % (lldbWebKitTesterExecutable))
 
     def setUp(self):
         super(TestDumpClassLayout, self).setUp()