Commit 19eb8323 authored by Dylan Baker's avatar Dylan Baker Committed by Marge Bot

drop python2 support

This removes all of the python code for handling python 2.x vs 3.x, now
only 3.6+ is supported. This also drops all uses of the six module, as
its no longer needed.

Python 2.x and <= 3.5 are all EOL, it doesn't make sense to continue to
support version of python that are at the end of their lives and are
being removed from operating systems.
Acked-by: Eric Engestrom's avatarEric Engestrom <eric@engestrom.ch>
Part-of: <!223>
parent 740649ea
......@@ -227,20 +227,12 @@ IF(PIGLIT_BUILD_GLX_TESTS)
ENDIF()
if (NOT Python_ADDITIONAL_VERSIONS)
set(Python_ADDITIONAL_VERSIONS 3.8 3.7 3.6 3.5 2.7)
set(Python_ADDITIONAL_VERSIONS 3.8 3.7 3.6)
endif()
find_package(PythonInterp REQUIRED)
find_package(PythonSix 1.5.2 REQUIRED)
find_package(PythonNumpy 1.7.0 REQUIRED)
# CMake doesn't have a VERSION_GREATER_EQUAL function, at least as of 3.0,
# And mako 1.0.2 contains bug fixes required for python 3.5 to work, so
# the only solution (short of having a series of "OR" statements, is this)
if (PYTHON_VERSION_STRING VERSION_GREATER 3.4.999999)
find_package(PythonMako 1.0.2 REQUIRED)
else ()
find_package(PythonMako 0.8.0 REQUIRED)
endif (PYTHON_VERSION_STRING VERSION_GREATER 3.4.999999)
find_package(PythonMako 1.0.2 REQUIRED)
find_package(bash-completion NO_MODULE)
......
......@@ -28,15 +28,13 @@ The original tests have been taken from
First of all, you need to make sure that the following are installed:
- Python 2.7.x or >=3.5
- Python >=3.6
- Python Mako module
- numpy (http://www.numpy.org)
- six (https://pypi.python.org/pypi/six)
- cmake (http://www.cmake.org)
- GL, glu and glut libraries and development packages (i.e. headers)
- X11 libraries and development packages (i.e. headers)
- waffle (http://www.waffle-gl.org)
- mako
Optionally, you can install the following:
......@@ -48,14 +46,6 @@ Optionally, you can install the following:
- VkRunner. A shader script testing tool for Vulkan.
(https://github.com/igalia/vkrunner)
For Python 2.x you can install the following to add features, these are
unnecessary for python3:
- backports.lzma. A backport of python3's lzma module to python2,
this enables fast native xz (de)compression in piglit for results files
(https://github.com/peterjc/backports.lzma)
- subprocess32. A backport of the subprocess from python3.2, which includes
timeout support. This only works for Linux
For testing the python framework using `py.test unittests/framework`
- py.test. A python test framework, used for running the python framework
test suite.
......
# coding=utf-8
# Copyright (c) 2014-2016 Intel Corporation
# Copyright (c) 2014-2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -42,14 +42,9 @@ that a user actually wants.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import os
import importlib
import six
from .register import Registry
from .compression import COMPRESSION_SUFFIXES
......@@ -165,7 +160,7 @@ def load(file_path):
extension, compression = get_extension(file_path)
for backend in six.itervalues(BACKENDS):
for backend in BACKENDS.values():
if extension in backend.extensions:
loader = backend.load
......
# coding=utf-8
# Copyright (c) 2014, 2016 Intel Corporation
# Copyright (c) 2014, 2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -26,17 +26,12 @@ This module provides mixins and base classes for backend modules.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import abc
import contextlib
import itertools
import os
import shutil
import six
from framework import options
from . import compression
from framework.results import TestResult
......@@ -66,8 +61,7 @@ def write_compressed(filename):
yield f
@six.add_metaclass(abc.ABCMeta)
class Backend(object):
class Backend(metaclass=abc.ABCMeta):
""" Abstract base class for summary backends
This class provides an abstract ancestor for classes implementing backends,
......
# coding=utf-8
# Copyright (c) 2015-2016 Intel Corporation
# Copyright (c) 2015-2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -38,21 +38,17 @@ the best way to get a compressor.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import bz2
import contextlib
import errno
import functools
import gzip
import io
import lzma
import os
import subprocess
import contextlib
import six
from six.moves import cStringIO as StringIO
from framework import exceptions, compat
from framework import exceptions
from framework.core import PIGLIT_CONFIG
__all__ = [
......@@ -63,139 +59,33 @@ __all__ = [
]
@compat.python_2_unicode_compatible
class UnsupportedCompressor(exceptions.PiglitInternalError):
def __init__(self, method, *args, **kwargs):
super(UnsupportedCompressor, self).__init__(*args, **kwargs)
self.__method = method
def __str__(self):
return u'unsupported compression method {}'.format(self.__method)
return 'unsupported compression method {}'.format(self.__method)
DEFAULT = 'bz2'
if six.PY2:
COMPRESSION_SUFFIXES = ['.gz', '.bz2']
COMPRESSORS = {
'bz2': functools.partial(bz2.BZ2File, mode='w'),
'gz': functools.partial(gzip.open, mode='w'),
'none': functools.partial(open, mode='w'),
}
DECOMPRESSORS = {
'bz2': functools.partial(bz2.BZ2File, mode='r'),
'gz': functools.partial(gzip.open, mode='r'),
'none': functools.partial(open, mode='r'),
}
# First try to use backports.lzma, that's the easiest solution. If that
# fails then go to trying the shell. If that fails then piglit won't have
# xz support, and will raise an error if xz is used
try:
import backports.lzma # pylint: disable=wrong-import-position
COMPRESSORS['xz'] = functools.partial(backports.lzma.open, mode='w')
DECOMPRESSORS['xz'] = functools.partial(backports.lzma.open, mode='r')
COMPRESSION_SUFFIXES += ['.xz']
except ImportError:
try:
with open(os.devnull, 'w') as d:
subprocess.check_call(['xz', '--help'], stdout=d, stderr=d)
except OSError:
pass
else:
@contextlib.contextmanager
def _compress_xz(filename):
"""Emulates an open function in write mode for xz.
Python 2.x doesn't support xz, but it's dang useful. This
function calls out to the shell and tries to use xz from the
environment to get xz compression.
This obviously won't work without a working xz binary.
This function tries to emulate the default values of the lzma
module in python3 as much as possible
"""
if filename.endswith('.xz'):
filename = filename[:-3]
with open(filename, 'w') as f:
yield f
try:
with open(os.devnull, 'w') as null:
subprocess.check_call(
['xz', '--compress', '-9', '--force', filename],
stderr=null)
except OSError as e:
if e.errno == errno.ENOENT:
raise exceptions.PiglitFatalError(
'No xz binary available')
raise
@contextlib.contextmanager
def _decompress_xz(filename):
"""Eumlates an option function in read mode for xz.
See the comment in _compress_xz for more information.
This function tries to emulate the lzma module as much as
possible
"""
if not filename.endswith('.xz'):
filename = '{}.xz'.format(filename)
try:
with open(os.devnull, 'w') as null:
string = subprocess.check_output(
['xz', '--decompress', '--stdout', filename],
stderr=null)
except OSError as e:
if e.errno == errno.ENOENT:
raise exceptions.PiglitFatalError(
'No xz binary available')
raise
# We need a file-like object, so the contents must be placed in
# a StringIO object.
io = StringIO()
io.write(string)
io.seek(0)
yield io
io.close()
COMPRESSORS['xz'] = _compress_xz
DECOMPRESSORS['xz'] = _decompress_xz
COMPRESSION_SUFFIXES += ['.xz']
else:
# In the case of python 3 this all just works, no monkeying around with
# imports and fallbacks. just import the right modules and go
import lzma # pylint: disable=wrong-import-position,wrong-import-order
COMPRESSION_SUFFIXES = ['.gz', '.bz2', '.xz']
COMPRESSORS = {
'bz2': functools.partial(bz2.open, mode='wt'),
'gz': functools.partial(gzip.open, mode='wt'),
'none': functools.partial(open, mode='w'),
'xz': functools.partial(lzma.open, mode='wt'),
}
DECOMPRESSORS = {
'bz2': functools.partial(bz2.open, mode='rt'),
'gz': functools.partial(gzip.open, mode='rt'),
'none': functools.partial(open, mode='r'),
'xz': functools.partial(lzma.open, mode='rt'),
}
COMPRESSION_SUFFIXES = ['.gz', '.bz2', '.xz']
COMPRESSORS = {
'bz2': functools.partial(bz2.open, mode='wt'),
'gz': functools.partial(gzip.open, mode='wt'),
'none': functools.partial(open, mode='w'),
'xz': functools.partial(lzma.open, mode='wt'),
}
DECOMPRESSORS = {
'bz2': functools.partial(bz2.open, mode='rt'),
'gz': functools.partial(gzip.open, mode='rt'),
'none': functools.partial(open, mode='r'),
'xz': functools.partial(lzma.open, mode='rt'),
}
def get_mode():
......
# coding=utf-8
# Copyright (c) 2014, 2016-2017 Intel Corporation
# Copyright (c) 2014, 2016-2017, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -21,9 +21,6 @@
""" Module providing json backend for piglit """
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import collections
import functools
import os
......@@ -36,14 +33,13 @@ try:
except ImportError:
import json
import six
try:
import jsonstreams
_STREAMS = True
except ImportError:
_STREAMS = False
from framework import status, results, exceptions, compat
from framework import status, results, exceptions
from .abstract import FileBackend, write_compressed
from .register import Registry
from . import compression
......@@ -70,7 +66,7 @@ def piglit_encoder(obj):
"""
if isinstance(obj, status.Status):
return six.text_type(obj)
return str(obj)
elif isinstance(obj, set):
return list(obj)
elif hasattr(obj, 'to_json'):
......@@ -182,10 +178,10 @@ class JSONBackend(FileBackend):
s.write('__type__', 'TestrunResult')
with open(os.path.join(self._dest, 'metadata.json'),
'r') as n:
s.iterwrite(six.iteritems(json.load(n, object_pairs_hook=collections.OrderedDict)))
s.iterwrite(json.load(n, object_pairs_hook=collections.OrderedDict).items())
if metadata:
s.iterwrite(six.iteritems(metadata))
s.iterwrite(metadata.items())
with s.subobject('tests') as t:
for test in file_list:
......@@ -197,7 +193,7 @@ class JSONBackend(FileBackend):
except ValueError:
continue
t.iterwrite(six.iteritems(a))
t.iterwrite(a.items())
# Delete the temporary files
......@@ -267,7 +263,7 @@ def _load(results_file):
raise exceptions.PiglitFatalError(
'While loading json results file: "{}",\n'
'the following error occurred:\n{}'.format(results_file.name,
six.text_type(e)))
str(e)))
return result
......@@ -371,7 +367,7 @@ def _update_seven_to_eight(result):
This value is used for both TestResult.time and TestrunResult.time_elapsed.
"""
for test in compat.viewvalues(result['tests']):
for test in result['tests'].values():
test['time'] = {'start': 0.0, 'end': float(test['time']),
'__type__': 'TimeAttribute'}
......@@ -391,7 +387,7 @@ def _update_eight_to_nine(result):
null rather than a single integer or null.
"""
for test in compat.viewvalues(result['tests']):
for test in result['tests'].values():
if 'pid' in test:
test['pid'] = [test['pid']]
else:
......
# coding=utf-8
# Copyright (c) 2014-2016 Intel Corporation
# Copyright (c) 2014-2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -21,9 +21,6 @@
""" Module implementing a JUnitBackend for piglit """
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import os.path
import shutil
try:
......@@ -35,8 +32,6 @@ try:
except ImportError:
import json
import six
from framework import grouptools, results, exceptions
from framework.core import PIGLIT_CONFIG
from .abstract import FileBackend
......@@ -146,7 +141,7 @@ class JUnitWriter(object):
# Add the piglit type to the failure result
if res is not None:
res.attrib['type'] = six.text_type(result)
res.attrib['type'] = str(result)
def _make_root(self, testname, classname, data):
"""Creates and returns the root element."""
......@@ -202,7 +197,7 @@ class JUnitWriter(object):
self._make_result(element, data.result, expected_result)
f.write(six.text_type(etree.tostring(element).decode('utf-8')))
f.write(str(etree.tostring(element).decode('utf-8')))
class JUnitSubtestWriter(JUnitWriter):
......@@ -220,13 +215,13 @@ class JUnitSubtestWriter(JUnitWriter):
element = etree.Element('testsuite',
name=testname,
time=str(data.time.total),
tests=six.text_type(len(data.subtests)))
for test, result in six.iteritems(data.subtests):
tests=str(len(data.subtests)))
for test, result in data.subtests.items():
etree.SubElement(element,
'testcase',
name=self._make_full_test_name(test),
classname=testname,
status=six.text_type(result))
status=str(result))
else:
element = super(JUnitSubtestWriter, self)._make_root(
......@@ -249,7 +244,7 @@ class JUnitSubtestWriter(JUnitWriter):
out.text = data.command + '\n' + out.text
if data.subtests:
for subname, result in six.iteritems(data.subtests):
for subname, result in data.subtests.items():
# replace special characters and make case insensitive
elem = element.find('.//testcase[@name="{}"]'.format(
self._make_full_test_name(subname)))
......@@ -267,7 +262,7 @@ class JUnitSubtestWriter(JUnitWriter):
self._expected_result('{}.{}'.format(
classname, testname).lower()))
f.write(six.text_type(etree.tostring(element).decode('utf-8')))
f.write(str(etree.tostring(element).decode('utf-8')))
class JUnitBackend(FileBackend):
......
# coding=utf-8
# Copyright (c) 2015-2016 Intel Corporation
# Copyright (c) 2015-2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -21,9 +21,6 @@
"""An object for registering backends."""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import collections
Registry = collections.namedtuple(
......
# coding=utf-8
# Copyright (c) 2016 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""A small library that contains libraries equivalent to six
This function is pending upstreaming in six.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import six
def python_2_bool_compatible(class_):
"""A decorator to fix __bool__/__nonzero__ name changes."""
if six.PY2:
try:
class_.__nonzero__ = class_.__bool__
except AttributeError:
raise ValueError(
"@python_2_bool_compatible cannot be applied to {} because "
"it doesn't define __bool__().".format(class_.__name__))
return class_
# Some version of six don't have this function
try:
from six import python_2_unicode_compatible
except ImportError:
def python_2_unicode_compatible(class_):
"""A decorator to fix __str/__bytes__/__unicode__ name changes."""
if six.PY2:
failed = False
try:
class_.__unicode__ = class_.__str__
except AttributeError:
failed = True
try:
class_.__str__ = class_.__bytes__
except AttributeError:
if failed:
raise ValueError(
"@python_2_unicode_compatible cannot be applied to {} "
"because it doesn't define __str__() "
"or __bytes__().".format(class_.__name__))
return class_
try:
from six import viewvalues
except ImportError:
if six.PY2:
viewvalues = lambda d: d.viewvalues()
elif six.PY3:
viewvalues = lambda d: d.values()
# coding=utf-8
# Copyright (c) 2014-2016 Intel Corporation
# Copyright (c) 2014-2016, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -26,15 +26,11 @@ historically reasons is called "core" in piglit.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import configparser
import errno
import os
import subprocess
from six.moves import configparser
from framework import exceptions
__all__ = [
......
# coding=utf-8
# Copyright (c) 2013-2016 Intel Corporation
# Copyright (c) 2013-2016, 2019 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
......@@ -36,9 +36,6 @@ dmesg implementation for their OS.
"""
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import abc
import gzip
import re
......@@ -46,8 +43,6 @@ import subprocess
import sys
import warnings
import six
from framework import exceptions
__all__ = [
......@@ -58,8 +53,7 @@ __all__ = [
]
@six.add_metaclass(abc.ABCMeta)
class BaseDmesg(object):
class BaseDmesg(metaclass=abc.ABCMeta):
""" Abstract base class for Dmesg derived objects
This provides the bases of the constructor, and most subclasses should call
......@@ -144,7 +138,7 @@ class BaseDmesg(object):
result.result = replace(result.result)
# Replace the results of any subtests
for key, value in six.iteritems(result.subtests):
for key, value in result.subtests.items():
result.subtests[key] = replace(value)
# Add the dmesg values to the result
......
# coding=utf-8
# Copyright © 2019 Intel Corporation
# Copyright (c) 2016 Broadcom
#
# Permission is hereby granted, free of charge, to any person obtaining a
......@@ -20,9 +21,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from __future__ import (
absolute_import, division, print_function, unicode_literals
)
import errno
import re
import subprocess
......
# coding=utf-8
# Copyright (c) 2015 Intel Corporation
# Copyright (c) 2015, 2019 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
......@@ -21,12 +21,9 @@
"""Exception and error classes for piglit, and exception handlers."""
from __future__ import print_function, absolute_import, division
import sys