Remove support for Python 2.6 (#27256)
Modifications: - [x] Removed `centos:6` unit test, adjusted vermin checks - [x] Removed backport of `collections.OrderedDict` - [x] Removed backport of `functools.total_ordering` - [x] Removed Python 2.6 specific skip markers in unit tests - [x] Fixed a few minor Python 2.6 related TODOs in code Updating the vendored dependencies will be done in separate PRs
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							812663de62
						
					
				
				
					commit
					fa7189b480
				
			
							
								
								
									
										19
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								lib/spack/external/__init__.py
									
									
									
									
										vendored
									
									
								
							@@ -17,7 +17,7 @@
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
* Homepage: https://pypi.python.org/pypi/argparse
 | 
			
		||||
* Usage: We include our own version to be Python 2.6 compatible.
 | 
			
		||||
* Usage: We include our own version to be Python 3.X compatible.
 | 
			
		||||
* Version: 1.4.0
 | 
			
		||||
* Note: This package has been slightly modified to improve
 | 
			
		||||
  error message formatting. See the following commit if the
 | 
			
		||||
@@ -39,15 +39,6 @@
 | 
			
		||||
* Usage: Provides a more stable linux distribution detection.
 | 
			
		||||
* Version: 1.0.4 (last version supporting Python 2.6)
 | 
			
		||||
 | 
			
		||||
functools
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
* Homepage: https://github.com/python/cpython/blob/2.7/Lib/functools.py
 | 
			
		||||
* Usage: Used for implementation of total_ordering.
 | 
			
		||||
* Version: Unversioned
 | 
			
		||||
* Note: This is the functools.total_ordering implementation
 | 
			
		||||
  from Python 2.7 backported so we can run on Python 2.6.
 | 
			
		||||
 | 
			
		||||
jinja2
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
@@ -73,14 +64,6 @@
 | 
			
		||||
* Usage: Implements a XML/HTML/XHTML Markup safe string for Python.
 | 
			
		||||
* Version: 1.0
 | 
			
		||||
 | 
			
		||||
orderddict
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
* Homepage: https://pypi.org/project/ordereddict/
 | 
			
		||||
* Usage: A drop-in substitute for Py2.7's new collections.OrderedDict
 | 
			
		||||
  that works in Python 2.4-2.6.
 | 
			
		||||
* Version: 1.1
 | 
			
		||||
 | 
			
		||||
py
 | 
			
		||||
--
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								lib/spack/external/functools_backport.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								lib/spack/external/functools_backport.py
									
									
									
									
										vendored
									
									
								
							@@ -1,47 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# Backport of Python 2.7's total_ordering.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
def total_ordering(cls):
 | 
			
		||||
    """Class decorator that fills in missing ordering methods"""
 | 
			
		||||
    convert = {
 | 
			
		||||
        '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)),
 | 
			
		||||
                   ('__le__', lambda self, other: self < other or self == other),
 | 
			
		||||
                   ('__ge__', lambda self, other: not self < other)],
 | 
			
		||||
        '__le__': [('__ge__', lambda self, other: not self <= other or self == other),
 | 
			
		||||
                   ('__lt__', lambda self, other: self <= other and not self == other),
 | 
			
		||||
                   ('__gt__', lambda self, other: not self <= other)],
 | 
			
		||||
        '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)),
 | 
			
		||||
                   ('__ge__', lambda self, other: self > other or self == other),
 | 
			
		||||
                   ('__le__', lambda self, other: not self > other)],
 | 
			
		||||
        '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other),
 | 
			
		||||
                   ('__gt__', lambda self, other: self >= other and not self == other),
 | 
			
		||||
                   ('__lt__', lambda self, other: not self >= other)]
 | 
			
		||||
    }
 | 
			
		||||
    roots = set(dir(cls)) & set(convert)
 | 
			
		||||
    if not roots:
 | 
			
		||||
        raise ValueError('must define at least one ordering operation: < > <= >=')
 | 
			
		||||
    root = max(roots)       # prefer __lt__ to __le__ to __gt__ to __ge__
 | 
			
		||||
    for opname, opfunc in convert[root]:
 | 
			
		||||
        if opname not in roots:
 | 
			
		||||
            opfunc.__name__ = opname
 | 
			
		||||
            opfunc.__doc__ = getattr(int, opname).__doc__
 | 
			
		||||
            setattr(cls, opname, opfunc)
 | 
			
		||||
    return cls
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@total_ordering
 | 
			
		||||
class reverse_order(object):
 | 
			
		||||
    """Helper for creating key functions.
 | 
			
		||||
 | 
			
		||||
       This is a wrapper that inverts the sense of the natural
 | 
			
		||||
       comparisons on the object.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, value):
 | 
			
		||||
        self.value = value
 | 
			
		||||
 | 
			
		||||
    def __eq__(self, other):
 | 
			
		||||
        return other.value == self.value
 | 
			
		||||
 | 
			
		||||
    def __lt__(self, other):
 | 
			
		||||
        return other.value < self.value
 | 
			
		||||
							
								
								
									
										22
									
								
								lib/spack/external/ordereddict_backport.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								lib/spack/external/ordereddict_backport.py
									
									
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
			
		||||
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
 | 
			
		||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
 | 
			
		||||
 | 
			
		||||
"""This file dispatches to the correct implementation of OrderedDict."""
 | 
			
		||||
 | 
			
		||||
# TODO: this file, along with py26/ordereddict.py, can be removed when
 | 
			
		||||
# TODO: support for python 2.6 will be dropped
 | 
			
		||||
 | 
			
		||||
# Removing this import will make python 2.6
 | 
			
		||||
# fail on import of ordereddict
 | 
			
		||||
from __future__ import absolute_import
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
if sys.version_info[:2] == (2, 6):
 | 
			
		||||
    import ordereddict
 | 
			
		||||
    OrderedDict = ordereddict.OrderedDict
 | 
			
		||||
else:
 | 
			
		||||
    import collections
 | 
			
		||||
    OrderedDict = collections.OrderedDict
 | 
			
		||||
							
								
								
									
										127
									
								
								lib/spack/external/py26/ordereddict.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										127
									
								
								lib/spack/external/py26/ordereddict.py
									
									
									
									
										vendored
									
									
								
							@@ -1,127 +0,0 @@
 | 
			
		||||
# Copyright (c) 2009 Raymond Hettinger
 | 
			
		||||
#
 | 
			
		||||
# 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.
 | 
			
		||||
 | 
			
		||||
from UserDict import DictMixin
 | 
			
		||||
 | 
			
		||||
class OrderedDict(dict, DictMixin):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwds):
 | 
			
		||||
        if len(args) > 1:
 | 
			
		||||
            raise TypeError('expected at most 1 arguments, got %d' % len(args))
 | 
			
		||||
        try:
 | 
			
		||||
            self.__end
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            self.clear()
 | 
			
		||||
        self.update(*args, **kwds)
 | 
			
		||||
 | 
			
		||||
    def clear(self):
 | 
			
		||||
        self.__end = end = []
 | 
			
		||||
        end += [None, end, end]         # sentinel node for doubly linked list
 | 
			
		||||
        self.__map = {}                 # key --> [key, prev, next]
 | 
			
		||||
        dict.clear(self)
 | 
			
		||||
 | 
			
		||||
    def __setitem__(self, key, value):
 | 
			
		||||
        if key not in self:
 | 
			
		||||
            end = self.__end
 | 
			
		||||
            curr = end[1]
 | 
			
		||||
            curr[2] = end[1] = self.__map[key] = [key, curr, end]
 | 
			
		||||
        dict.__setitem__(self, key, value)
 | 
			
		||||
 | 
			
		||||
    def __delitem__(self, key):
 | 
			
		||||
        dict.__delitem__(self, key)
 | 
			
		||||
        key, prev, next = self.__map.pop(key)
 | 
			
		||||
        prev[2] = next
 | 
			
		||||
        next[1] = prev
 | 
			
		||||
 | 
			
		||||
    def __iter__(self):
 | 
			
		||||
        end = self.__end
 | 
			
		||||
        curr = end[2]
 | 
			
		||||
        while curr is not end:
 | 
			
		||||
            yield curr[0]
 | 
			
		||||
            curr = curr[2]
 | 
			
		||||
 | 
			
		||||
    def __reversed__(self):
 | 
			
		||||
        end = self.__end
 | 
			
		||||
        curr = end[1]
 | 
			
		||||
        while curr is not end:
 | 
			
		||||
            yield curr[0]
 | 
			
		||||
            curr = curr[1]
 | 
			
		||||
 | 
			
		||||
    def popitem(self, last=True):
 | 
			
		||||
        if not self:
 | 
			
		||||
            raise KeyError('dictionary is empty')
 | 
			
		||||
        if last:
 | 
			
		||||
            key = reversed(self).next()
 | 
			
		||||
        else:
 | 
			
		||||
            key = iter(self).next()
 | 
			
		||||
        value = self.pop(key)
 | 
			
		||||
        return key, value
 | 
			
		||||
 | 
			
		||||
    def __reduce__(self):
 | 
			
		||||
        items = [[k, self[k]] for k in self]
 | 
			
		||||
        tmp = self.__map, self.__end
 | 
			
		||||
        del self.__map, self.__end
 | 
			
		||||
        inst_dict = vars(self).copy()
 | 
			
		||||
        self.__map, self.__end = tmp
 | 
			
		||||
        if inst_dict:
 | 
			
		||||
            return (self.__class__, (items,), inst_dict)
 | 
			
		||||
        return self.__class__, (items,)
 | 
			
		||||
 | 
			
		||||
    def keys(self):
 | 
			
		||||
        return list(self)
 | 
			
		||||
 | 
			
		||||
    setdefault = DictMixin.setdefault
 | 
			
		||||
    update = DictMixin.update
 | 
			
		||||
    pop = DictMixin.pop
 | 
			
		||||
    values = DictMixin.values
 | 
			
		||||
    items = DictMixin.items
 | 
			
		||||
    iterkeys = DictMixin.iterkeys
 | 
			
		||||
    itervalues = DictMixin.itervalues
 | 
			
		||||
    iteritems = DictMixin.iteritems
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        if not self:
 | 
			
		||||
            return '%s()' % (self.__class__.__name__,)
 | 
			
		||||
        return '%s(%r)' % (self.__class__.__name__, self.items())
 | 
			
		||||
 | 
			
		||||
    def copy(self):
 | 
			
		||||
        return self.__class__(self)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def fromkeys(cls, iterable, value=None):
 | 
			
		||||
        d = cls()
 | 
			
		||||
        for key in iterable:
 | 
			
		||||
            d[key] = value
 | 
			
		||||
        return d
 | 
			
		||||
 | 
			
		||||
    def __eq__(self, other):
 | 
			
		||||
        if isinstance(other, OrderedDict):
 | 
			
		||||
            if len(self) != len(other):
 | 
			
		||||
                return False
 | 
			
		||||
            for p, q in  zip(self.items(), other.items()):
 | 
			
		||||
                if p != q:
 | 
			
		||||
                    return False
 | 
			
		||||
            return True
 | 
			
		||||
        return dict.__eq__(self, other)
 | 
			
		||||
 | 
			
		||||
    def __ne__(self, other):
 | 
			
		||||
        return not self == other
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
from __future__ import absolute_import, division, print_function
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import inspect
 | 
			
		||||
import sys
 | 
			
		||||
import warnings
 | 
			
		||||
@@ -21,9 +22,6 @@
 | 
			
		||||
from _pytest.outcomes import fail, TEST_OUTCOME
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from ordereddict_backport import OrderedDict
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def pytest_sessionstart(session):
 | 
			
		||||
    import _pytest.python
 | 
			
		||||
    scopename2class.update({
 | 
			
		||||
@@ -165,7 +163,7 @@ def reorder_items(items):
 | 
			
		||||
    for scopenum in range(0, scopenum_function):
 | 
			
		||||
        argkeys_cache[scopenum] = d = {}
 | 
			
		||||
        for item in items:
 | 
			
		||||
            keys = OrderedDict.fromkeys(get_parametrized_fixture_keys(item, scopenum))
 | 
			
		||||
            keys = collections.OrderedDict.fromkeys(get_parametrized_fixture_keys(item, scopenum))
 | 
			
		||||
            if keys:
 | 
			
		||||
                d[item] = keys
 | 
			
		||||
    return reorder_items_atscope(items, set(), argkeys_cache, 0)
 | 
			
		||||
@@ -200,7 +198,7 @@ def slice_items(items, ignore, scoped_argkeys_cache):
 | 
			
		||||
        for i, item in enumerate(it):
 | 
			
		||||
            argkeys = scoped_argkeys_cache.get(item)
 | 
			
		||||
            if argkeys is not None:
 | 
			
		||||
                newargkeys = OrderedDict.fromkeys(k for k in argkeys if k not in ignore)
 | 
			
		||||
                newargkeys = collections.OrderedDict.fromkeys(k for k in argkeys if k not in ignore)
 | 
			
		||||
                if newargkeys:  # found a slicing key
 | 
			
		||||
                    slicing_argkey, _ = newargkeys.popitem()
 | 
			
		||||
                    items_before = items[:i]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user