Bug 1526585 [wpt PR 15141] - Use print() function in both Python 2 and Python 3, a=testonly
authorcclauss <cclauss@me.com>
Mon, 18 Feb 2019 19:24:40 +0000
changeset 519166 279b6fb55b9237377c7e857d584dee387efbd5e1
parent 519165 186ecc82160b10a9a8054bc9107613200a134090
child 519167 e6028ae2bf9e8f3b48f066a8ad274871e4c0a7c4
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1526585, 15141
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1526585 [wpt PR 15141] - Use print() function in both Python 2 and Python 3, a=testonly Automatic update from web-platform-tests Use print() function in both Python 2 and Python 3 (#15141) -- wpt-commits: 99b96dc0569ede4e842ec7f9c55a792df9092d9c wpt-pr: 15141
testing/web-platform/tests/css/css-fonts/support/fonts/makegsubfonts.py
testing/web-platform/tests/css/tools/w3ctestlib/Sources.py
testing/web-platform/tests/tools/pywebsocket/example/echo_client.py
testing/web-platform/tests/tools/pywebsocket/test/test_msgutil.py
testing/web-platform/tests/tools/pywebsocket/test/test_util.py
testing/web-platform/tests/tools/wptrunner/setup.py
testing/web-platform/tests/tools/wptrunner/test/test.py
testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/edge.py
testing/web-platform/tests/tools/wptrunner/wptrunner/executors/executorservo.py
testing/web-platform/tests/tools/wptrunner/wptrunner/manifestupdate.py
testing/web-platform/tests/tools/wptrunner/wptrunner/metadata.py
testing/web-platform/tests/tools/wptrunner/wptrunner/wptcommandline.py
testing/web-platform/tests/tools/wptrunner/wptrunner/wptrunner.py
--- a/testing/web-platform/tests/css/css-fonts/support/fonts/makegsubfonts.py
+++ b/testing/web-platform/tests/css/css-fonts/support/fonts/makegsubfonts.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 
 import os
 import textwrap
 from xml.etree import ElementTree
 from fontTools.ttLib import TTFont, newTable
 from fontTools.misc.psCharStrings import T2CharString
 from fontTools.ttLib.tables.otTables import GSUB,\
     ScriptList, ScriptRecord, Script, DefaultLangSys,\
@@ -469,18 +470,18 @@ def makeJavascriptData():
 
     f = open(javascriptData, "wb")
     f.write("\n".join(outStr))
     f.close()
 
 
 # build fonts
 
-print "Making lookup type 1 font..."
+print("Making lookup type 1 font...")
 makeLookup1()
 
-print "Making lookup type 3 font..."
+print("Making lookup type 3 font...")
 makeLookup3()
 
 # output javascript data
 
-print "Making javascript data file..."
+print("Making javascript data file...")
 makeJavascriptData()
--- a/testing/web-platform/tests/css/tools/w3ctestlib/Sources.py
+++ b/testing/web-platform/tests/css/tools/w3ctestlib/Sources.py
@@ -1,13 +1,14 @@
 #!/usr/bin/python
 # CSS Test Source Manipulation Library
 # Initial code by fantasai, joint copyright 2010 W3C and Microsoft
 # Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license>
 
+from __future__ import print_function
 from os.path import basename, exists, join
 import os
 import filecmp
 import shutil
 import re
 import codecs
 import collections
 from xml import dom
@@ -964,17 +965,17 @@ class XMLSource(FileSource):
         self.tree = None
         self.errors = ['Empty source file']
         self.encoding = 'utf-8'
 
       FileSource.loadMetadata(self)
       if ((not self.metadata) and self.tree and (not self.errors)):
         self.extractMetadata(self.tree)
     except etree.ParseError as e:
-      print "PARSE ERROR: " + self.sourcepath
+      print("PARSE ERROR: " + self.sourcepath)
       self.cacheAsParseError(self.sourcepath, e)
       e.W3CTestLibErrorLocation = self.sourcepath
       self.errors = [str(e)]
       self.encoding = 'utf-8'
 
   def validate(self):
     """Parse file if not parsed, and store any parse errors in self.errors"""
     if self.tree is None:
@@ -1381,17 +1382,17 @@ class HTMLSource(XMLSource):
         self.tree = None
         self.errors = ['Empty source file']
         self.encoding = 'utf-8'
 
       FileSource.loadMetadata(self)
       if ((not self.metadata) and self.tree and (not self.errors)):
         self.extractMetadata(self.tree)
     except Exception as e:
-      print "PARSE ERROR: " + self.sourcepath
+      print("PARSE ERROR: " + self.sourcepath)
       e.W3CTestLibErrorLocation = self.sourcepath
       self.errors = [str(e)]
       self.encoding = 'utf-8'
 
   def _injectXLinks(self, element, nodeList):
     injected = False
 
     xlinkAttrs = ['href', 'type', 'role', 'arcrole', 'title', 'show', 'actuate']
--- a/testing/web-platform/tests/tools/pywebsocket/example/echo_client.py
+++ b/testing/web-platform/tests/tools/pywebsocket/example/echo_client.py
@@ -46,16 +46,17 @@ Example Usage:
      -s localhost \
      -o http://localhost -r /echo -m test
 
 or
 
 # run echo client to test IETF HyBi 00 protocol
  run with --protocol-version=hybi00
 """
+from __future__ import print_function
 
 
 import base64
 import codecs
 import logging
 from optparse import OptionParser
 import os
 import random
@@ -935,49 +936,49 @@ class EchoClient(object):
 
                 self._stream = Stream(request, stream_option)
             elif version == _PROTOCOL_VERSION_HYBI00:
                 self._stream = StreamHixie75(request, True)
 
             for line in self._options.message.split(','):
                 self._stream.send_message(line)
                 if self._options.verbose:
-                    print 'Send: %s' % line
+                    print('Send: %s' % line)
                 try:
                     received = self._stream.receive_message()
 
                     if self._options.verbose:
-                        print 'Recv: %s' % received
+                        print('Recv: %s' % received)
                 except Exception, e:
                     if self._options.verbose:
-                        print 'Error: %s' % e
+                        print('Error: %s' % e)
                     raise
 
             self._do_closing_handshake()
         finally:
             self._socket.close()
 
     def _do_closing_handshake(self):
         """Perform closing handshake using the specified closing frame."""
 
         if self._options.message.split(',')[-1] == _GOODBYE_MESSAGE:
             # requested server initiated closing handshake, so
             # expecting closing handshake message from server.
             self._logger.info('Wait for server-initiated closing handshake')
             message = self._stream.receive_message()
             if message is None:
-                print 'Recv close'
-                print 'Send ack'
+                print('Recv close')
+                print('Send ack')
                 self._logger.info(
                     'Received closing handshake and sent ack')
                 return
-        print 'Send close'
+        print('Send close')
         self._stream.close_connection()
         self._logger.info('Sent closing handshake')
-        print 'Recv ack'
+        print('Recv ack')
         self._logger.info('Received ack')
 
 
 def main():
     sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
 
     parser = OptionParser()
     # We accept --command_line_flag style flags which is the same as Google
--- a/testing/web-platform/tests/tools/pywebsocket/test/test_msgutil.py
+++ b/testing/web-platform/tests/tools/pywebsocket/test/test_msgutil.py
@@ -26,16 +26,17 @@
 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
 
 
 """Tests for msgutil module."""
+from __future__ import print_function
 
 
 import array
 import Queue
 import random
 import struct
 import unittest
 import zlib
@@ -879,17 +880,17 @@ class PerMessageDeflateTest(unittest.Tes
         compressed_hello += compress.flush(zlib.Z_SYNC_FLUSH)
         expected = '\x41%c' % len(compressed_hello)
         expected += compressed_hello
         compressed_empty = compress.compress('Hello')
         compressed_empty += compress.flush(zlib.Z_SYNC_FLUSH)
         compressed_empty = compressed_empty[:-4]
         expected += '\x80%c' % len(compressed_empty)
         expected += compressed_empty
-        print '%r' % expected
+        print('%r' % expected)
         self.assertEqual(expected, request.connection.written_data())
 
     def test_send_message_fragmented_empty_last_frame(self):
         extension = common.ExtensionParameter(
                 common.PERMESSAGE_DEFLATE_EXTENSION)
         request = _create_request_from_rawdata(
                 '', permessage_deflate_request=extension)
         msgutil.send_message(request, 'Hello', end=False)
@@ -1059,17 +1060,17 @@ class PerMessageDeflateTest(unittest.Tes
             if bytes_chunked == len(compressed_payload):
                 first_octet = first_octet | 0x80
 
             data += '%c%c' % (first_octet, chunk_size | 0x80)
             data += _mask_hybi(chunk)
 
             frame_count += 1
 
-        print "Chunk sizes: %r" % chunk_sizes
+        print("Chunk sizes: %r" % chunk_sizes)
         self.assertTrue(len(chunk_sizes) > 10)
 
         # Close frame
         data += '\x88\x8a' + _mask_hybi(struct.pack('!H', 1000) + 'Good bye')
 
         extension = common.ExtensionParameter(
             common.PERMESSAGE_DEFLATE_EXTENSION)
         request = _create_request_from_rawdata(
@@ -1162,19 +1163,19 @@ class PerMessageDeflateTest(unittest.Tes
                     compressed_payload += compress.flush(zlib.Z_SYNC_FLUSH)
                     sync_used = True
                 else:
                     compressed_payload += compress.compress(chunk)
                     compressed_payload += compress.flush(zlib.Z_FINISH)
                     compress = None
                     finish_used = True
 
-        print "Chunk sizes: %r" % chunk_sizes
+        print("Chunk sizes: %r" % chunk_sizes)
         self.assertTrue(len(chunk_sizes) > 10)
-        print "Methods: %r" % methods
+        print("Methods: %r" % methods)
         self.assertTrue(sync_used)
         self.assertTrue(finish_used)
 
         self.assertTrue(125 < len(compressed_payload))
         self.assertTrue(len(compressed_payload) < 65536)
         data = '\xc2\xfe' + struct.pack('!H', len(compressed_payload))
         data += _mask_hybi(compressed_payload)
 
--- a/testing/web-platform/tests/tools/pywebsocket/test/test_util.py
+++ b/testing/web-platform/tests/tools/pywebsocket/test/test_util.py
@@ -26,16 +26,17 @@
 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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.
 
 
 """Tests for util module."""
+from __future__ import print_function
 
 
 import os
 import random
 import sys
 import unittest
 
 import set_sys_path  # Update sys.path to locate mod_pywebsocket module.
@@ -167,17 +168,17 @@ class InflaterDeflaterTest(unittest.Test
         self.assertEqual(input, inflater8.decompress(-1))
 
     def test_random_section(self):
         random.seed(a=0)
         source = ''.join(
             [chr(random.randint(0, 255)) for i in xrange(100 * 1024)])
 
         chunked_input = get_random_section(source, 10)
-        print "Input chunk sizes: %r" % [len(c) for c in chunked_input]
+        print("Input chunk sizes: %r" % [len(c) for c in chunked_input])
 
         deflater = util._Deflater(15)
         compressed = []
         for chunk in chunked_input:
             compressed.append(deflater.compress(chunk))
         compressed.append(deflater.compress_and_finish(''))
 
         chunked_expectation = get_random_section(source, 10)
--- a/testing/web-platform/tests/tools/wptrunner/setup.py
+++ b/testing/web-platform/tests/tools/wptrunner/setup.py
@@ -1,12 +1,14 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
+from __future__ import print_function
+
 import glob
 import os
 import sys
 import textwrap
 
 from setuptools import setup, find_packages
 
 here = os.path.split(__file__)[0]
@@ -55,17 +57,17 @@ setup(name=PACKAGE_NAME,
                                   "prefs/*"]},
       include_package_data=True,
       data_files=[("requirements", requirements_files)],
       install_requires=deps
       )
 
 if "install" in sys.argv:
     path = os.path.relpath(os.path.join(sys.prefix, "requirements"), os.curdir)
-    print textwrap.fill("""In order to use with one of the built-in browser
+    print(textwrap.fill("""In order to use with one of the built-in browser
 products, you will need to install the extra dependencies. These are provided
 as requirements_[name].txt in the %s directory and can be installed using
-e.g.""" % path, 80)
+e.g.""" % path, 80))
 
-    print """
+    print("""
 
 pip install -r %s/requirements_firefox.txt
-""" % path
+""" % path)
--- a/testing/web-platform/tests/tools/wptrunner/test/test.py
+++ b/testing/web-platform/tests/tools/wptrunner/test/test.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 import ConfigParser
 import argparse
 import os
 import sys
 
 from mozlog import structuredlog
 from mozlog.handlers import BaseHandler, StreamHandler
 from mozlog.formatters import MachFormatter
@@ -148,15 +149,15 @@ def main():
     args = get_parser().parse_args()
 
     try:
         run(config, args)
     except Exception:
         if args.pdb:
             import pdb
             import traceback
-            print traceback.format_exc()
+            print(traceback.format_exc())
             pdb.post_mortem()
         else:
             raise
 
 if __name__ == "__main__":
     main()
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/edge.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/edge.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 from .base import Browser, ExecutorBrowser, require_arg
 from ..webdriver_server import EdgeDriverServer
 from ..executors import executor_kwargs as base_executor_kwargs
 from ..executors.executorselenium import (SeleniumTestharnessExecutor,  # noqa: F401
                                           SeleniumRefTestExecutor)  # noqa: F401
 from ..executors.executoredge import EdgeDriverWdspecExecutor  # noqa: F401
 
 __wptrunner__ = {"product": "edge",
@@ -71,17 +72,17 @@ class EdgeBrowser(Browser):
                                        args=webdriver_args)
         self.webdriver_host = "localhost"
         self.webdriver_port = self.server.port
         if timeout_multiplier:
             self.init_timeout = self.init_timeout * timeout_multiplier
 
 
     def start(self, **kwargs):
-        print self.server.url
+        print(self.server.url)
         self.server.start()
 
     def stop(self, force=False):
         self.server.stop(force=force)
 
     def pid(self):
         return self.server.pid
 
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/executors/executorservo.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/executors/executorservo.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 import base64
 import json
 import os
 import subprocess
 import tempfile
 import threading
 import uuid
 
@@ -133,17 +134,17 @@ class ServoTestharnessExecutor(ProcessTe
     def on_output(self, line):
         prefix = "ALERT: RESULT: "
         line = line.decode("utf8", "replace")
         if line.startswith(prefix):
             self.result_data = json.loads(line[len(prefix):])
             self.result_flag.set()
         else:
             if self.interactive:
-                print line
+                print(line)
             else:
                 self.logger.process_output(self.proc.pid,
                                            line,
                                            " ".join(self.command))
 
     def on_finish(self):
         self.result_flag.set()
 
@@ -264,17 +265,17 @@ class ServoRefTestExecutor(ProcessTestEx
     def do_test(self, test):
         result = self.implementation.run_test(test)
 
         return self.convert_result(test, result)
 
     def on_output(self, line):
         line = line.decode("utf8", "replace")
         if self.interactive:
-            print line
+            print(line)
         else:
             self.logger.process_output(self.proc.pid,
                                        line,
                                        " ".join(self.command))
 
 
 class ServoDriverProtocol(WebDriverProtocol):
     server_cls = ServoDriverServer
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestupdate.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestupdate.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 import itertools
 import os
 import urlparse
 from collections import namedtuple, defaultdict
 from math import ceil
 
 from wptmanifest.node import (DataNode, ConditionalNode, BinaryExpressionNode,
                               BinaryOperatorNode, VariableNode, StringNode, NumberNode,
@@ -84,17 +85,17 @@ class ExpectedManifest(ManifestItem):
             "lsan": LsanUpdate(self),
             "leak-object": LeakObjectUpdate(self),
             "leak-threshold": LeakThresholdUpdate(self),
         }
 
     def append(self, child):
         ManifestItem.append(self, child)
         if child.id in self.child_map:
-            print "Warning: Duplicate heading %s" % child.id
+            print("Warning: Duplicate heading %s" % child.id)
         self.child_map[child.id] = child
 
     def _remove_child(self, child):
         del self.child_map[child.id]
         ManifestItem._remove_child(self, child)
 
     def get_test(self, test_id):
         """Return a TestNode by test id, or None if no test matches
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/metadata.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/metadata.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 import array
 import os
 import shutil
 import tempfile
 import uuid
 from collections import defaultdict, namedtuple
 
 from mozlog import structuredlog
@@ -44,19 +45,19 @@ def update_expected(test_paths, serve_ro
                                                        boolean_properties=boolean_properties,
                                                        stability=stability):
 
         write_new_expected(metadata_path, updated_ini)
         if stability:
             for test in updated_ini.iterchildren():
                 for subtest in test.iterchildren():
                     if subtest.new_disabled:
-                        print "disabled: %s" % os.path.dirname(subtest.root.test_path) + "/" + subtest.name
+                        print("disabled: %s" % os.path.dirname(subtest.root.test_path) + "/" + subtest.name)
                     if test.new_disabled:
-                        print "disabled: %s" % test.root.test_path
+                        print("disabled: %s" % test.root.test_path)
 
 
 def do_delayed_imports(serve_root):
     global manifest, manifestitem
     from manifest import manifest, item as manifestitem
 
 
 def files_in_repo(repo_root):
@@ -354,17 +355,17 @@ class ExpectedUpdater(object):
     def suite_start(self, data):
         self.run_info = run_info_intern.store(data["run_info"])
 
     def test_start(self, data):
         test_id = intern(data["test"].encode("utf8"))
         try:
             test_data = self.id_test_map[test_id]
         except KeyError:
-            print "Test not found %s, skipping" % test_id
+            print("Test not found %s, skipping" % test_id)
             return
 
         if self.ignore_existing:
             test_data.set_requires_update()
             test_data.clear.add("expected")
         self.tests_visited[test_id] = set()
 
     def test_status(self, data):
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/wptcommandline.py
@@ -1,8 +1,9 @@
+from __future__ import print_function
 import argparse
 import os
 import sys
 from collections import OrderedDict
 from distutils.spawn import find_executable
 from datetime import timedelta
 
 import config
@@ -24,17 +25,17 @@ def url_or_path(path):
         return abs_path(path)
 
 
 def require_arg(kwargs, name, value_func=None):
     if value_func is None:
         value_func = lambda x: x is not None
 
     if name not in kwargs or not value_func(kwargs[name]):
-        print >> sys.stderr, "Missing required argument %s" % name
+        print("Missing required argument %s" % name, file=sys.stderr)
         sys.exit(1)
 
 
 def create_parser(product_choices=None):
     from mozlog import commandline
 
     import products
 
@@ -412,35 +413,35 @@ def exe_path(name):
     else:
         return None
 
 
 def check_paths(kwargs):
     for test_paths in kwargs["test_paths"].itervalues():
         if not ("tests_path" in test_paths and
                 "metadata_path" in test_paths):
-            print "Fatal: must specify both a test path and metadata path"
+            print("Fatal: must specify both a test path and metadata path")
             sys.exit(1)
         if "manifest_path" not in test_paths:
             test_paths["manifest_path"] = os.path.join(test_paths["metadata_path"],
                                                        "MANIFEST.json")
         for key, path in test_paths.iteritems():
             name = key.split("_", 1)[0]
 
             if name == "manifest":
                 # For the manifest we can create it later, so just check the path
                 # actually exists
                 path = os.path.dirname(path)
 
             if not os.path.exists(path):
-                print "Fatal: %s path %s does not exist" % (name, path)
+                print("Fatal: %s path %s does not exist" % (name, path))
                 sys.exit(1)
 
             if not os.path.isdir(path):
-                print "Fatal: %s path %s is not a directory" % (name, path)
+                print("Fatal: %s path %s is not a directory" % (name, path))
                 sys.exit(1)
 
 
 def check_args(kwargs):
     set_from_config(kwargs)
 
     if kwargs["product"] is None:
         kwargs["product"] = "firefox"
@@ -483,17 +484,17 @@ def check_args(kwargs):
                 kwargs["processes"] = 1
             kwargs["no_capture_stdio"] = True
         kwargs["debug_info"] = debug_info
     else:
         kwargs["debug_info"] = None
 
     if kwargs["binary"] is not None:
         if not os.path.exists(kwargs["binary"]):
-            print >> sys.stderr, "Binary path %s does not exist" % kwargs["binary"]
+            print("Binary path %s does not exist" % kwargs["binary"], file=sys.stderr)
             sys.exit(1)
 
     if kwargs["ssl_type"] is None:
         if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"], kwargs["host_key_path"]):
             kwargs["ssl_type"] = "pregenerated"
         elif exe_path(kwargs["openssl_binary"]) is not None:
             kwargs["ssl_type"] = "openssl"
         else:
@@ -502,34 +503,34 @@ def check_args(kwargs):
     if kwargs["ssl_type"] == "pregenerated":
         require_arg(kwargs, "ca_cert_path", lambda x:os.path.exists(x))
         require_arg(kwargs, "host_cert_path", lambda x:os.path.exists(x))
         require_arg(kwargs, "host_key_path", lambda x:os.path.exists(x))
 
     elif kwargs["ssl_type"] == "openssl":
         path = exe_path(kwargs["openssl_binary"])
         if path is None:
-            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
+            print("openssl-binary argument missing or not a valid executable", file=sys.stderr)
             sys.exit(1)
         kwargs["openssl_binary"] = path
 
     if kwargs["ssl_type"] != "none" and kwargs["product"] == "firefox" and kwargs["certutil_binary"]:
         path = exe_path(kwargs["certutil_binary"])
         if path is None:
-            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
+            print("certutil-binary argument missing or not a valid executable", file=sys.stderr)
             sys.exit(1)
         kwargs["certutil_binary"] = path
 
     if kwargs['extra_prefs']:
         # If a single pref is passed in as a string, make it a list
         if type(kwargs['extra_prefs']) in (str, unicode):
             kwargs['extra_prefs'] = [kwargs['extra_prefs']]
         missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
         if missing:
-            print >> sys.stderr, "Preferences via --setpref must be in key=value format"
+            print("Preferences via --setpref must be in key=value format", file=sys.stderr)
             sys.exit(1)
         kwargs['extra_prefs'] = [tuple(prefarg.split('=', 1)) for prefarg in
                                  kwargs['extra_prefs']]
 
     if kwargs["reftest_internal"] is None:
         kwargs["reftest_internal"] = True
 
     if kwargs["lsan_dir"] is None:
@@ -546,17 +547,17 @@ def check_args_update(kwargs):
 
     if kwargs["product"] is None:
         kwargs["product"] = "firefox"
     if kwargs["patch"] is None:
         kwargs["patch"] = kwargs["sync"]
 
     for item in kwargs["run_log"]:
         if os.path.isdir(item):
-            print >> sys.stderr, "Log file %s is a directory" % item
+            print("Log file %s is a directory" % item, file=sys.stderr)
             sys.exit(1)
 
     return kwargs
 
 
 def create_parser_update(product_choices=None):
     from mozlog.structured import commandline
 
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/wptrunner.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/wptrunner.py
@@ -1,9 +1,9 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import json
 import os
 import sys
 
 from wptserve import sslutils
 
 import environment as env
@@ -82,45 +82,45 @@ def list_test_groups(test_paths, product
     env.do_delayed_imports(logger, test_paths)
 
     run_info_extras = products.load_product(kwargs["config"], product)[-1](**kwargs)
 
     run_info, test_loader = get_loader(test_paths, product,
                                        run_info_extras=run_info_extras, **kwargs)
 
     for item in sorted(test_loader.groups(kwargs["test_types"])):
-        print item
+        print(item)
 
 
 def list_disabled(test_paths, product, **kwargs):
     env.do_delayed_imports(logger, test_paths)
 
     rv = []
 
     run_info_extras = products.load_product(kwargs["config"], product)[-1](**kwargs)
 
     run_info, test_loader = get_loader(test_paths, product,
                                        run_info_extras=run_info_extras, **kwargs)
 
     for test_type, tests in test_loader.disabled_tests.iteritems():
         for test in tests:
             rv.append({"test": test.id, "reason": test.disabled()})
-    print json.dumps(rv, indent=2)
+    print(json.dumps(rv, indent=2))
 
 
 def list_tests(test_paths, product, **kwargs):
     env.do_delayed_imports(logger, test_paths)
 
     run_info_extras = products.load_product(kwargs["config"], product)[-1](**kwargs)
 
     run_info, test_loader = get_loader(test_paths, product,
                                        run_info_extras=run_info_extras, **kwargs)
 
     for test in test_loader.test_ids:
-        print test
+        print(test)
 
 
 def get_pause_after_test(test_loader, **kwargs):
     total_tests = sum(len(item) for item in test_loader.tests.itervalues())
     if kwargs["pause_after_test"] is None:
         if kwargs["repeat_until_unexpected"]:
             return False
         if kwargs["headless"]:
@@ -352,12 +352,12 @@ def main():
 
         setup_logging(kwargs, {"raw": sys.stdout})
 
         return start(**kwargs)
     except Exception:
         if kwargs["pdb"]:
             import pdb
             import traceback
-            print traceback.format_exc()
+            print(traceback.format_exc())
             pdb.post_mortem()
         else:
             raise