[Piglit] [PATCH 3/5] Convert from python2 to python3

Dylan Baker baker.dylan.c at gmail.com
Mon Feb 24 11:42:40 PST 2014


This is one big ugly patch, but I don't really see a way to make a
working transition without this ugliness, since any splitting of these
changes would cause the framework to raise a runtime exception.

This is the output of the 2to3 tool provided by python, with a few
manual edits for style and to replace list(iterator) with plain
iterators, which are fine for our use

It also does the following:
- replace #!/usr/bin/python with #!/usr/bin/python3
- Fix changes to hanging indents
- fix slots operator in status.py:
  - In python3 __slots__ behaves slightly differently than in python2,
    in that a class attribute does not fulfill a slot, but actually
    conflicts with it. For more information see:
    http://bugs.python.org/issue12766
- Fix bytes, strings and unicode
  - In python2 regex strings are usually of the raw type: r'(foo|bar)',
    but in python3 they need to be of the same type as the strings they
    are to be applied to. In dmesg this is bytes, so b'(foo|bar)'
  - One of the huge advantages to moving to python3 is that there is no
    ambiguity between unicode and byte strings. Bytes are explicitly
    marked as such and everything else is unicode.
- Fix functions that have moved from modules or been renamed
  - A number of types have been moved into the global namespace in
    python3, among them types.IntType and types.LongType have been
    replaced with int and types.FloatType have been replaced with float.

What it doesn't fix:
- junit
---
 framework/core.py               | 22 ++++++------
 framework/dmesg.py              |  6 ++--
 framework/exectest.py           | 30 +++--------------
 framework/glsl_parser_test.py   | 10 +++---
 framework/junit.py              | 10 +++---
 framework/log.py                |  4 +--
 framework/opencv.py             |  1 -
 framework/shader_test.py        |  3 +-
 framework/status.py             | 74 +++++++++++++++++------------------------
 framework/summary.py            | 57 ++++++++++++++++---------------
 framework/tests/dmesg_tests.py  | 20 +++++------
 framework/tests/log_tests.py    |  7 ++--
 framework/tests/status_tests.py |  2 +-
 generate-glean-tests.py         |  3 +-
 piglit-merge-results.py         |  2 +-
 piglit-print-commands.py        |  3 +-
 piglit-resume.py                |  7 ++--
 piglit-run.py                   |  3 +-
 piglit-summary-html.py          |  2 +-
 piglit-summary-junit.py         |  2 +-
 piglit-summary.py               |  2 +-
 templates/index.mako            |  2 +-
 tests/igt.py                    | 12 +++----
 23 files changed, 119 insertions(+), 165 deletions(-)

diff --git a/framework/core.py b/framework/core.py
index 2863860..c8be811 100644
--- a/framework/core.py
+++ b/framework/core.py
@@ -22,7 +22,6 @@
 
 # Piglit core
 
-from __future__ import print_function
 import errno
 import os
 import platform
@@ -31,12 +30,11 @@ import subprocess
 import sys
 import time
 import traceback
-from cStringIO import StringIO
+from io import StringIO
 import multiprocessing
 import multiprocessing.dummy
 import importlib
-# TODO: ConfigParser is known as configparser in python3
-import ConfigParser
+import configparser
 try:
     import simplejson as json
 except ImportError:
@@ -59,7 +57,7 @@ __all__ = ['PIGLIT_CONFIG',
            'testBinDir']
 
 
-PIGLIT_CONFIG = ConfigParser.SafeConfigParser()
+PIGLIT_CONFIG = configparser.SafeConfigParser()
 
 class PiglitJSONEncoder(json.JSONEncoder):
     def default(self, o):
@@ -378,7 +376,7 @@ class Environment:
             self.exclude_filter.append(re.compile(each))
 
     def __iter__(self):
-        for key, values in self.__dict__.iteritems():
+        for key, values in self.__dict__.items():
             # If the values are regex compiled then yield their pattern
             # attribute, which is the original plaintext they were compiled
             # from, otherwise yield them normally.
@@ -531,7 +529,7 @@ class TestProfile(object):
         self.flatten_group_hierarchy()
 
         def matches_any_regexp(x, re_list):
-            return True in map(lambda r: r.search(x) is not None, re_list)
+            return any((r.search(x) for r in re_list))
 
         def test_matches(path, test):
             """Filter for user-specified restrictions"""
@@ -548,7 +546,7 @@ class TestProfile(object):
             return True
 
         # Filter out unwanted tests
-        self.test_list = dict(item for item in self.test_list.iteritems()
+        self.test_list = dict(item for item in self.test_list.items()
                               if check_all(item))
 
     def run(self, env, json_writer):
@@ -579,15 +577,15 @@ class TestProfile(object):
         chunksize = 1
 
         if env.concurrent == "all":
-            multi.imap(test, self.test_list.iteritems(), chunksize)
+            multi.imap(test, self.test_list.items(), chunksize)
         elif env.concurrent == "none":
-            single.imap(test, self.test_list.iteritems(), chunksize)
+            single.imap(test, self.test_list.items(), chunksize)
         else:
             # Filter and return only thread safe tests to the threaded pool
-            multi.imap(test, (x for x in self.test_list.iteritems() if
+            multi.imap(test, (x for x in self.test_list.items() if
                               x[1].runConcurrent), chunksize)
             # Filter and return the non thread safe tests to the single pool
-            single.imap(test, (x for x in self.test_list.iteritems() if not
+            single.imap(test, (x for x in self.test_list.items() if not
                                x[1].runConcurrent), chunksize)
 
         # Close and join the pools
diff --git a/framework/dmesg.py b/framework/dmesg.py
index 3af8496..0d56c7e 100644
--- a/framework/dmesg.py
+++ b/framework/dmesg.py
@@ -64,7 +64,7 @@ class LinuxDmesg(object):
             warnings.warn("Cannot check dmesg for timestamp support. If you "
                           "do not have timestamps enabled in your kernel you "
                           "get incomplete dmesg captures", RuntimeWarning)
-        elif not re.match(r'\[\s*\d+\.\d+\]', self._last_message):
+        elif not re.match(b'\[\s*\d+\.\d+\]', self._last_message):
             # Do an initial check to ensure that dmesg has timestamps, we need
             # timestamps to work correctly. A proper linux dmesg timestamp
             # looks like this: [    0.00000]
@@ -105,11 +105,11 @@ class LinuxDmesg(object):
 
             # Replace any subtests
             if 'subtest' in result:
-                for key, value in result['subtest'].iteritems():
+                for key, value in result['subtest'].items():
                     result['subtest'][key] = replace(value)
 
             # Add the dmesg values to the result
-            result['dmesg'] = "\n".join(self._new_messages)
+            result['dmesg'] = str(b"\n".join(self._new_messages))
 
         return result
 
diff --git a/framework/exectest.py b/framework/exectest.py
index 4f88dbc..ef70c19 100644
--- a/framework/exectest.py
+++ b/framework/exectest.py
@@ -52,7 +52,7 @@ class ExecTest(Test):
 
     @command.setter
     def command(self, value):
-        if isinstance(value, basestring):
+        if isinstance(value, str):
             self._command = shlex.split(str(value))
             return
         self._command = value
@@ -102,23 +102,6 @@ class ExecTest(Test):
                 else:
                     break
 
-            # proc.communicate() returns 8-bit strings, but we need
-            # unicode strings.  In Python 2.x, this is because we
-            # will eventually be serializing the strings as JSON,
-            # and the JSON library expects unicode.  In Python 3.x,
-            # this is because all string operations require
-            # unicode.  So translate the strings into unicode,
-            # assuming they are using UTF-8 encoding.
-            #
-            # If the subprocess output wasn't properly UTF-8
-            # encoded, we don't want to raise an exception, so
-            # translate the strings using 'replace' mode, which
-            # replaces erroneous charcters with the Unicode
-            # "replacement character" (a white question mark inside
-            # a black diamond).
-            out = out.decode('utf-8', 'replace')
-            err = err.decode('utf-8', 'replace')
-
             results = TestResult()
 
             if self.skip_test:
@@ -164,9 +147,8 @@ class ExecTest(Test):
             if env:
                 results['environment'] = env
 
-            results['info'] = unicode("Returncode: {0}\n\nErrors:\n{1}\n\n"
-                                      "Output:\n{2}").format(returncode,
-                                                             err, out)
+            results['info'] = str("Returncode: {0}\n\nErrors:\n{1}\n\n"
+                                  "Output:\n{2}").format(returncode, err, out)
             results['returncode'] = returncode
             results['command'] = ' '.join(self.command)
 
@@ -225,8 +207,7 @@ class PlainExecTest(ExecTest):
 
     def interpretResult(self, out, returncode, results):
         outlines = out.split('\n')
-        outpiglit = map(lambda s: s[7:],
-                        filter(lambda s: s.startswith('PIGLIT:'), outlines))
+        outpiglit = [s[7:] for s in [s for s in outlines if s.startswith('PIGLIT:')]]
 
         if len(outpiglit) > 0:
             try:
@@ -237,8 +218,7 @@ class PlainExecTest(ExecTest):
                         results['subtest'].update(eval(piglit[7:]))
                     else:
                         results.update(eval(piglit))
-                out = '\n'.join(filter(lambda s: not s.startswith('PIGLIT:'),
-                                       outlines))
+                out = '\n'.join([s for s in outlines if not s.startswith('PIGLIT:')])
             except:
                 results['result'] = 'fail'
                 results['note'] = 'Failed to parse result string'
diff --git a/framework/glsl_parser_test.py b/framework/glsl_parser_test.py
index 82292b5..7e9c5fc 100755
--- a/framework/glsl_parser_test.py
+++ b/framework/glsl_parser_test.py
@@ -31,13 +31,13 @@ standalone tests on the command line. To add a test to a Piglit group, us
 
 usage_message = "usage: glsl_parser_test.py TEST_FILE"
 
-import ConfigParser
+import configparser
 import os
 import os.path as path
 import re
 import subprocess
 import sys
-from cStringIO import StringIO
+from io import StringIO
 
 from .core import Test, testBinDir, TestResult
 from .exectest import PlainExecTest
@@ -76,7 +76,7 @@ def import_glsl_parser_tests(group, basepath, subdirectories):
                     testname = os.path.relpath(filepath, basepath)
                     if os.path.sep != '/':
                         testname = testname.replace(os.path.sep, '/', -1)
-                    assert isinstance(testname, basestring)
+                    assert isinstance(testname, str)
                     add_glsl_parser_test(group, filepath, testname)
 
 
@@ -300,12 +300,12 @@ class GLSLParserTest(PlainExecTest):
         else:
             assert(False)
 
-        config = ConfigParser.SafeConfigParser(cls.__config_defaults)
+        config = configparser.SafeConfigParser(cls.__config_defaults)
         try:
             text = text_io.getvalue()
             text_io.close()
             config.readfp(StringIO(text))
-        except ConfigParser.Error as e:
+        except configparser.Error as e:
             self.result = TestResult()
             self.result['result'] = 'fail'
             self.result['errors'] = ['Errors exist in config section of test '
diff --git a/framework/junit.py b/framework/junit.py
index 7916731..4713b34 100644
--- a/framework/junit.py
+++ b/framework/junit.py
@@ -68,7 +68,7 @@ del _c
 
 def escape(s):
     '''Escape and encode a XML string.'''
-    if isinstance(s, unicode):
+    if isinstance(s, str):
         s = s.translate(_validXmlUnicode)
     else:
         #s = s.decode(locale.getpreferredencoding(), 'replace')
@@ -245,7 +245,7 @@ class Report:
         shutil.copy2(path, attach_dir)
 
     def addWorkspaceURL(self, path):
-        import urlparse
+        import urllib.parse
         try:
             workspace_path = os.environ['WORKSPACE']
             job_url = os.environ['JOB_URL']
@@ -253,8 +253,8 @@ class Report:
             self.addStdout(path + '\n')
         else:
             rel_path = os.path.relpath(path, workspace_path)
-            workspace_url = urlparse.urljoin(job_url, 'ws/')
-            url = urlparse.urljoin(workspace_url, rel_path)
+            workspace_url = urllib.parse.urljoin(job_url, 'ws/')
+            url = urllib.parse.urljoin(workspace_url, rel_path)
             if os.path.isdir(path):
                 url += '/'
             self.addStdout(url + '\n')
@@ -327,7 +327,7 @@ class Test(BaseTest):
             except KeyboardInterrupt:
                 raise
             except:
-                report.addError(str(sys.exc_value))
+                report.addError(str(sys.exc_info()[1]))
         finally:
             report.stopCase()
 
diff --git a/framework/log.py b/framework/log.py
index 2835f1e..5f6d035 100644
--- a/framework/log.py
+++ b/framework/log.py
@@ -36,7 +36,7 @@ class Log(object):
         self.__total = total
         self.__complete = 0
         self.__running = []
-        self.__generator = (x for x in xrange(self.__total))
+        self.__generator = (x for x in range(self.__total))
         self.__pad = len(str(self.__total))
         self.__summary_keys = set(['pass', 'fail', 'warn', 'crash', 'skip',
                                    'dmesg-warn', 'dmesg-fail', 'dry-run'])
@@ -119,6 +119,6 @@ class Log(object):
         if running:
             self.__print(running, 'running')
 
-        x = self.__generator.next()
+        x = next(self.__generator)
         self.__running.append(x)
         return x
diff --git a/framework/opencv.py b/framework/opencv.py
index 3e333c2..3d84664 100644
--- a/framework/opencv.py
+++ b/framework/opencv.py
@@ -24,7 +24,6 @@
 # Authors: Tom Stellard <thomas.stellard at amd.com>
 #
 
-from __future__ import print_function
 import re
 import subprocess
 from os import path
diff --git a/framework/shader_test.py b/framework/shader_test.py
index e7b33d3..a99e715 100755
--- a/framework/shader_test.py
+++ b/framework/shader_test.py
@@ -23,7 +23,6 @@
 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
-from __future__ import print_function
 import os
 import os.path as path
 import re
@@ -131,7 +130,7 @@ class ShaderTest(PlainExecTest):
 
         assert(isinstance(shader_runner_args, list))
         assert(isinstance(shader_runner_args[0], str) or
-               isinstance(shader_runner_args[0], unicode))
+               isinstance(shader_runner_args[0], str))
 
         self.__run_standalone = run_standalone
         self.__shader_runner_args = shader_runner_args
diff --git a/framework/status.py b/framework/status.py
index 98e11d2..7876ccf 100644
--- a/framework/status.py
+++ b/framework/status.py
@@ -48,6 +48,8 @@ The formula for determining fixes is:
 
 """
 
+from abc import ABCMeta
+
 
 def status_lookup(status):
     """ Provided a string return a status object instance
@@ -86,7 +88,7 @@ class StatusException(LookupError):
     pass
 
 
-class Status(object):
+class Status(metaclass=ABCMeta):
     """
     A simple class for representing the output values of tests.
 
@@ -99,12 +101,10 @@ class Status(object):
     # the memory consumed for creating tens of thousands of these objects.
     __slots__ = ['name', 'value', 'fraction']
 
-    name = None
-    value = None
-    fraction = (0, 1)
-
     def __init__(self):
-        raise NotImplementedError
+        self.name = None
+        self.value = None
+        self.fraction = (0, 1)
 
     def __repr__(self):
         return self.name
@@ -112,9 +112,6 @@ class Status(object):
     def __str__(self):
         return str(self.name)
 
-    def __unicode__(self):
-        return unicode(self.name)
-
     def __lt__(self, other):
         return int(self) < int(other)
 
@@ -138,67 +135,56 @@ class Status(object):
 
 
 class NotRun(Status):
-    name = 'Not Run'
-    value = 0
-    fraction = (0, 0)
-
     def __init__(self):
-        pass
+        self.name = 'Not Run'
+        self.value = 0
+        self.fraction = (0, 0)
 
 
 class Skip(Status):
-    name = 'skip'
-    value = 5
-    fraction = (0, 0)
-
     def __init__(self):
-        pass
+        self.name = 'skip'
+        self.value = 5
+        self.fraction = (0, 0)
 
 
 class Pass(Status):
-    name = 'pass'
-    value = 10
-    fraction = (1, 1)
-
     def __init__(self):
-        pass
+        self.name = 'pass'
+        self.value = 10
+        self.fraction = (1, 1)
 
 
 class DmesgWarn(Status):
-    name = 'dmesg-warn'
-    value = 20
-
     def __init__(self):
-        pass
+        self.name = 'dmesg-warn'
+        self.value = 20
+        self.fraction = (0, 1)
 
 
 class Warn(Status):
-    name = 'warn'
-    value = 25
-
     def __init__(self):
-        pass
+        self.name = 'warn'
+        self.value = 25
+        self.fraction = (0, 1)
 
 
 class DmesgFail(Status):
-    name = 'dmesg-fail'
-    value = 30
-
     def __init__(self):
-        pass
+        self.name = 'dmesg-fail'
+        self.value = 30
+        self.fraction = (0, 1)
 
 
 class Fail(Status):
-    name = 'fail'
-    value = 35
-
     def __init__(self):
-        pass
+        self.name = 'fail'
+        self.value = 35
+        self.fraction = (0, 1)
 
 
 class Crash(Status):
-    name = 'crash'
-    value = 40
-
     def __init__(self):
-        pass
+        self.name = 'crash'
+        self.value = 40
+        self.fraction = (0, 1)
diff --git a/framework/summary.py b/framework/summary.py
index 924fb2f..fd8b62e 100644
--- a/framework/summary.py
+++ b/framework/summary.py
@@ -19,7 +19,6 @@
 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
  
-from __future__ import print_function
 import os
 import os.path as path
 import itertools
@@ -41,8 +40,7 @@ __all__ = [
 
 class HTMLIndex(list):
     """
-    Builds HTML output to be passed to the index mako template, which will be
-    rendered into HTML pages. It does this by parsing the lists provided by the
+    Builds HTML output to be passed to the index mako template, which will be rendered into HTML pages. It does this by parsing the lists provided by the
     Summary object, and returns itself, an object with one accessor, a list of
     html strings that will be printed by the mako template.
     """
@@ -79,7 +77,7 @@ class HTMLIndex(list):
             if open == close:
                 return [], []
             else:
-                for i, j in itertools.izip_longest(open, close):
+                for i, j in itertools.zip_longest(open, close):
                     if i != j:
                         for k in common:
                             open.remove(k)
@@ -281,7 +279,7 @@ class Summary:
             fraction = self.fractions[results.name]
             status = self.status[results.name]
 
-            for key, value in results.tests.iteritems():
+            for key, value in results.tests.items():
                 # if the first character of key is a / then our while loop will
                 # become an infinite loop. Beyond that / should never be the
                 # leading character, if it is then there is a bug in one of the
@@ -321,7 +319,7 @@ class Summary:
                 self.tests['skipped'].add(test)
 
             # find fixes, regressions, and changes
-            for i in xrange(len(status) - 1):
+            for i in range(len(status) - 1):
                 first = status[i]
                 last = status[i + 1]
                 if max(first, so.Pass()) < last:
@@ -341,7 +339,7 @@ class Summary:
         self.totals = {'pass': 0, 'fail': 0, 'crash': 0, 'skip': 0, 'warn': 0,
                        'dmesg-warn': 0, 'dmesg-fail': 0}
 
-        for test in self.results[-1].tests.itervalues():
+        for test in self.results[-1].tests.values():
             self.totals[str(test['result'])] += 1
 
     def generate_html(self, destination, exclude):
@@ -379,14 +377,15 @@ class Summary:
             os.mkdir(path.join(destination, each.name))
 
             with open(path.join(destination, each.name, "index.html"), 'w') as out:
-                out.write(testindex.render(name=each.name,
-                                           time=each.time_elapsed,
-                                           options=each.options,
-                                           glxinfo=each.glxinfo,
-                                           lspci=each.lspci))
+                out.write(testindex.render_unicode(
+                    name=each.name,
+                    time=each.time_elapsed,
+                    options=each.options,
+                    glxinfo=each.glxinfo,
+                    lspci=each.lspci))
 
             # Then build the individual test results
-            for key, value in each.tests.iteritems():
+            for key, value in each.tests.items():
                 temp_path = path.join(destination, each.name, path.dirname(key))
 
                 if value['result'] not in exclude:
@@ -402,7 +401,7 @@ class Summary:
 
                     with open(path.join(destination, each.name, key + ".html"),
                               'w') as out:
-                        out.write(testfile.render(
+                        out.write(testfile.render_unicode(
                             testname=key,
                             status=value.get('result', 'None'),
                             # Returning a NoneType (instaed of 'None') prevents
@@ -434,26 +433,27 @@ class Summary:
         # alltests, where the other pages all use the same name. ie,
         # changes.html, self.changes, and page=changes.
         with open(path.join(destination, "index.html"), 'w') as out:
-            out.write(index.render(results=HTMLIndex(self, self.tests['all']),
-                                   page='all',
-                                   pages=pages,
-                                   colnum=len(self.results),
-                                   exclude=exclude))
+            out.write(index.render_unicode(
+                results=HTMLIndex(self, self.tests['all']),
+                page='all',
+                pages=pages,
+                colnum=len(self.results),
+                exclude=exclude))
 
         # Generate the rest of the pages
         for page in pages:
             with open(path.join(destination, page + '.html'), 'w') as out:
             # If there is information to display display it
                 if self.tests[page]:
-                    out.write(index.render(results=HTMLIndex(self,
-                                                             self.tests[page]),
-                                           pages=pages,
-                                           page=page,
-                                           colnum=len(self.results),
-                                           exclude=exclude))
+                    out.write(index.render_unicode(
+                        results=HTMLIndex(self, self.tests[page]),
+                        pages=pages,
+                        page=page,
+                        colnum=len(self.results),
+                        exclude=exclude))
                 # otherwise provide an empty page
                 else:
-                    out.write(empty_status.render(page=page, pages=pages))
+                    out.write(empty_status.render_unicode(page=page, pages=pages))
 
     def generate_text(self, diff, summary):
         """ Write summary information to the console """
@@ -485,6 +485,5 @@ class Summary:
             print("    changes: {changes}\n"
                   "      fixes: {fixes}\n"
                   "regressions: {regressions}".format(
-                      **{k: len(v) for k, v in self.tests.iteritems()}))
-
-        print("      total: {}".format(sum(self.totals.itervalues())))
+                      **{k: len(v) for k, v in self.tests.items()}))
+        print("      total: {}".format(sum(self.totals.values())))
diff --git a/framework/tests/dmesg_tests.py b/framework/tests/dmesg_tests.py
index 287cf74..5123ca3 100644
--- a/framework/tests/dmesg_tests.py
+++ b/framework/tests/dmesg_tests.py
@@ -113,17 +113,17 @@ def test_dmesg_wrap_partial():
     # instead we set it as a class instance and manually clear the
     # _last_messages attribute
     dmesg = LinuxDmesg()
-    dmesg.DMESG_COMMAND = ['echo', 'a\nb\nc\n']
+    dmesg.DMESG_COMMAND = ['echo', b'a\nb\nc\n']
     dmesg.update_dmesg()
 
     # Update the DMESG_COMMAND to add d\n and remove a\n, this simluates the
     # wrap
-    dmesg.DMESG_COMMAND = ['echo', 'b\nc\nd\n']
+    dmesg.DMESG_COMMAND = ['echo', b'b\nc\nd\n']
     dmesg.update_dmesg()
 
-    nt.assert_items_equal(dmesg._new_messages, ['d'],
-                          msg="_new_messages should be equal to ['d'], but is "
-                              "{} instead.".format(dmesg._new_messages))
+    nt.assert_equal(dmesg._new_messages, [b'd'],
+                    msg="_new_messages should be equal to ['d'], but is "
+                        "{} instead.".format(dmesg._new_messages))
 
 
 def test_dmesg_wrap_complete():
@@ -136,16 +136,16 @@ def test_dmesg_wrap_complete():
     # instead we set it as a class instance and manually clear the
     # _last_messages attribute
     dmesg = LinuxDmesg()
-    dmesg.DMESG_COMMAND = ['echo', 'a\nb\nc\n']
+    dmesg.DMESG_COMMAND = ['echo', b'a\nb\nc\n']
     dmesg.update_dmesg()
 
     # Udamte the DMESG_COMMAND to add d\n and remove a\n, this simluates the
     # wrap
-    dmesg.DMESG_COMMAND = ['echo', '1\n2\n3\n']
+    dmesg.DMESG_COMMAND = ['echo', b'1\n2\n3\n']
     dmesg.update_dmesg()
 
-    nt.assert_items_equal(dmesg._new_messages, ['1', '2', '3'],
-                          msg="_new_messages should be equal to "
+    nt.assert_equal(dmesg._new_messages, [b'1', b'2', b'3'],
+                    msg="_new_messages should be equal to "
                               "['1', '2', '3'], but is {} instead".format(
                                   dmesg._new_messages))
 
@@ -288,7 +288,7 @@ def test_dmesg_performance():
     # 7000 is an arbitrary big number
     length = 7000 - len(dmesg._new_messages)
     # make new messages really big
-    dmesg._new_messages = ["piglit test {}".format(x) for x in xrange(length)] + dmesg._new_messages
+    dmesg._new_messages = ["piglit test {}".format(x) for x in range(length)] + dmesg._new_messages
 
     result = TestResult()
     result['result'] = 'pass'
diff --git a/framework/tests/log_tests.py b/framework/tests/log_tests.py
index e53b95b..7979c96 100644
--- a/framework/tests/log_tests.py
+++ b/framework/tests/log_tests.py
@@ -20,9 +20,6 @@
 
 """ Module provides tests for log.py module """
 
-import sys
-import itertools
-from types import *  # This is a special * safe module
 import nose.tools as nt
 from framework.log import Log
 
@@ -46,7 +43,7 @@ def test_pre_log_return():
     log = Log(100, False)
 
     ret = log.pre_log()
-    nt.assert_true(isinstance(ret, (IntType, FloatType, LongType)),
+    nt.assert_true(isinstance(ret, (int, float)),
                    msg="Log.pre_log() didn't return a numeric type!")
 
 
@@ -65,7 +62,7 @@ def check_post_log_increment_summary(stat):
     log = Log(100, False)
     ret = log.pre_log()
     log.post_log(ret, stat)
-    print log._Log__summary
+    print(log._Log__summary)
     nt.assert_equal(log._Log__summary[stat], 1,
                     msg="Log.__summary[{}] was not properly "
                         "incremented".format(stat))
diff --git a/framework/tests/status_tests.py b/framework/tests/status_tests.py
index cdc9989..6e1927f 100644
--- a/framework/tests/status_tests.py
+++ b/framework/tests/status_tests.py
@@ -79,7 +79,7 @@ def test_is_fix():
 def test_is_equivalent():
     # test the assertion that NotRun, Pass and Skip should be considered
     # equivalent for regression testing.
-    for x, y in itertools.izip(STATUSES, STATUSES):
+    for x, y in zip(STATUSES, STATUSES):
         yield is_equivalent, x, y
 
 
diff --git a/generate-glean-tests.py b/generate-glean-tests.py
index df08ede..8137c17 100755
--- a/generate-glean-tests.py
+++ b/generate-glean-tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 #
 # Copyright © 2010 Intel Corporation
@@ -25,7 +25,6 @@
 # Authors:
 #    Eric Anholt <eric at anholt.net>
 
-from __future__ import print_function
 from getopt import getopt, GetoptError
 
 import re
diff --git a/piglit-merge-results.py b/piglit-merge-results.py
index e78a5d0..d9ad458 100755
--- a/piglit-merge-results.py
+++ b/piglit-merge-results.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/piglit-print-commands.py b/piglit-print-commands.py
index 4529608..29f24e6 100755
--- a/piglit-print-commands.py
+++ b/piglit-print-commands.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -22,7 +22,6 @@
 # DEALINGS IN THE SOFTWARE.
 
 
-from __future__ import print_function
 import argparse
 import sys
 import os
diff --git a/piglit-resume.py b/piglit-resume.py
index c9cb72b..fa464c4 100755
--- a/piglit-resume.py
+++ b/piglit-resume.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -21,7 +21,6 @@
 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
-from __future__ import print_function
 import sys
 import os
 import os.path as path
@@ -62,7 +61,7 @@ def main():
     json_writer.open_dict()
     json_writer.write_dict_key("options")
     json_writer.open_dict()
-    for key, value in results.options.iteritems():
+    for key, value in results.options.items():
         json_writer.write_dict_item(key, value)
     json_writer.close_dict()
 
@@ -72,7 +71,7 @@ def main():
 
     json_writer.write_dict_key('tests')
     json_writer.open_dict()
-    for key, value in results.tests.iteritems():
+    for key, value in results.tests.items():
         json_writer.write_dict_item(key, value)
         env.exclude_tests.add(key)
     
diff --git a/piglit-run.py b/piglit-run.py
index d57abd7..15c532e 100755
--- a/piglit-run.py
+++ b/piglit-run.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -22,7 +22,6 @@
 # DEALINGS IN THE SOFTWARE.
 
 
-from __future__ import print_function
 import argparse
 import sys
 import os
diff --git a/piglit-summary-html.py b/piglit-summary-html.py
index a37b337..f303484 100755
--- a/piglit-summary-html.py
+++ b/piglit-summary-html.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/piglit-summary-junit.py b/piglit-summary-junit.py
index da73e88..107ba0d 100755
--- a/piglit-summary-junit.py
+++ b/piglit-summary-junit.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2010-2011 VMware, Inc.
 # All Rights Reserved.
diff --git a/piglit-summary.py b/piglit-summary.py
index fe58e40..02c7806 100755
--- a/piglit-summary.py
+++ b/piglit-summary.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/templates/index.mako b/templates/index.mako
index e959a27..fb4ddf1 100644
--- a/templates/index.mako
+++ b/templates/index.mako
@@ -31,7 +31,7 @@
 
         ## Status columns
         ## Create an additional column for each summary
-        % for _ in xrange(colnum):
+        % for _ in range(colnum):
         <col />
         % endfor
       </colgroup>
diff --git a/tests/igt.py b/tests/igt.py
index f80a6c4..b17e144 100644
--- a/tests/igt.py
+++ b/tests/igt.py
@@ -44,23 +44,23 @@ __all__ = ['profile']
 def checkEnvironment():
     debugfs_path = "/sys/kernel/debug/dri"
     if os.getuid() != 0:
-        print "Test Environment check: not root!"
+        print("Test Environment check: not root!")
         return False
     if not os.path.isdir(debugfs_path):
-        print "Test Environment check: debugfs not mounted properly!"
+        print("Test Environment check: debugfs not mounted properly!")
         return False
     for subdir in os.listdir(debugfs_path):
         clients = open(os.path.join(debugfs_path, subdir, "clients"), 'r')
         lines = clients.readlines()
         if len(lines) > 2:
-            print "Test Environment check: other drm clients running!"
+            print("Test Environment check: other drm clients running!")
             return False
 
-    print "Test Environment check: Succeeded."
+    print("Test Environment check: Succeeded.")
     return True
 
 if not os.path.exists(os.path.join(testBinDir, 'igt')):
-    print "igt symlink not found!"
+    print("igt symlink not found!")
     sys.exit(0)
 
 # Chase the piglit/bin/igt symlink to find where the tests really live.
@@ -90,7 +90,7 @@ class IGTTest(ExecTest):
         if not igtEnvironmentOk:
             results = TestResult()
             results['result'] = 'fail'
-            results['info'] = unicode("Test Environment isn't OK")
+            results['info'] = str("Test Environment isn't OK")
 
             return results
 
-- 
1.9.0



More information about the Piglit mailing list