From fa7189b480d48407bbfafbbf67b1910430a4dc54 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Tue, 23 Nov 2021 18:06:17 +0100 Subject: [PATCH] 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 --- .github/workflows/unit_tests.yaml | 37 +---- bin/spack | 6 +- lib/spack/docs/contribution_guide.rst | 2 +- .../docs/tables/system_prerequisites.csv | 2 +- lib/spack/external/__init__.py | 19 +-- lib/spack/external/functools_backport.py | 47 ------- lib/spack/external/ordereddict_backport.py | 22 --- lib/spack/external/py26/ordereddict.py | 127 ------------------ .../pytest-fallback/_pytest/fixtures.py | 8 +- lib/spack/llnl/util/multiproc.py | 2 +- lib/spack/spack/binary_distribution.py | 6 +- lib/spack/spack/bootstrap.py | 7 +- lib/spack/spack/cmd/license.py | 3 +- lib/spack/spack/concretize.py | 30 ++++- lib/spack/spack/config.py | 3 +- lib/spack/spack/environment/environment.py | 9 +- lib/spack/spack/extensions.py | 5 +- lib/spack/spack/filesystem_view.py | 5 +- lib/spack/spack/mirror.py | 4 +- lib/spack/spack/package.py | 3 +- lib/spack/spack/relocate.py | 9 +- lib/spack/spack/reporters/cdash.py | 6 +- lib/spack/spack/test/cmd/url.py | 11 -- lib/spack/spack/test/llnl/util/tty/log.py | 4 - lib/spack/spack/test/web.py | 6 +- lib/spack/spack/util/mock_package.py | 6 +- lib/spack/spack/util/spack_yaml.py | 4 +- 27 files changed, 66 insertions(+), 327 deletions(-) delete mode 100644 lib/spack/external/functools_backport.py delete mode 100644 lib/spack/external/ordereddict_backport.py delete mode 100644 lib/spack/external/py26/ordereddict.py diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index 2e8f9deef6..585271e04c 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -24,9 +24,9 @@ jobs: pip install --upgrade pip pip install --upgrade vermin - name: vermin (Spack's Core) - run: vermin --backport argparse --violations --backport typing -t=2.6- -t=3.5- -vvv lib/spack/spack/ lib/spack/llnl/ bin/ + run: vermin --backport argparse --violations --backport typing -t=2.7- -t=3.5- -vvv lib/spack/spack/ lib/spack/llnl/ bin/ - name: vermin (Repositories) - run: vermin --backport argparse --violations --backport typing -t=2.6- -t=3.5- -vvv var/spack/repos + run: vermin --backport argparse --violations --backport typing -t=2.7- -t=3.5- -vvv var/spack/repos # Run style checks on the files that have been changed style: runs-on: ubuntu-latest @@ -193,39 +193,6 @@ jobs: if: ${{ needs.changes.outputs.with_coverage == 'true' }} with: flags: shelltests,linux - # Test for Python2.6 run on Centos 6 - centos6: - needs: [ validate, style, changes ] - runs-on: ubuntu-latest - container: spack/github-actions:centos6 - steps: - - name: Run unit tests (full test-suite) - # The CentOS 6 container doesn't run with coverage, but - # under the same conditions it runs the full test suite - if: ${{ needs.changes.outputs.with_coverage == 'true' }} - env: - HOME: /home/spack-test - SPACK_TEST_SOLVER: original - run: | - whoami && echo $HOME && cd $HOME - git clone "${{ github.server_url }}/${{ github.repository }}.git" && cd spack - git fetch origin "${{ github.ref }}:test-branch" - git checkout test-branch - . .github/workflows/setup_git.sh - bin/spack unit-test -x - - name: Run unit tests (only package tests) - if: ${{ needs.changes.outputs.with_coverage == 'false' }} - env: - HOME: /home/spack-test - ONLY_PACKAGES: true - SPACK_TEST_SOLVER: original - run: | - whoami && echo $HOME && cd $HOME - git clone "${{ github.server_url }}/${{ github.repository }}.git" && cd spack - git fetch origin "${{ github.ref }}:test-branch" - git checkout test-branch - . .github/workflows/setup_git.sh - bin/spack unit-test -x -m "not maybeslow" -k "package_sanity" # Test RHEL8 UBI with platform Python. This job is run # only on PRs modifying core Spack diff --git a/bin/spack b/bin/spack index dffcbd2026..3b4f782d1c 100755 --- a/bin/spack +++ b/bin/spack @@ -33,11 +33,11 @@ import sys min_python3 = (3, 5) -if sys.version_info[:2] < (2, 6) or ( +if sys.version_info[:2] < (2, 7) or ( sys.version_info[:2] >= (3, 0) and sys.version_info[:2] < min_python3 ): v_info = sys.version_info[:3] - msg = "Spack requires Python 2.6, 2.7 or %d.%d or higher " % min_python3 + msg = "Spack requires Python 2.7 or %d.%d or higher " % min_python3 msg += "You are running spack with Python %d.%d.%d." % v_info sys.exit(msg) @@ -54,8 +54,6 @@ spack_external_libs = os.path.join(spack_lib_path, "external") if sys.version_info[:2] <= (2, 7): sys.path.insert(0, os.path.join(spack_external_libs, "py2")) -if sys.version_info[:2] == (2, 6): - sys.path.insert(0, os.path.join(spack_external_libs, "py26")) sys.path.insert(0, spack_external_libs) diff --git a/lib/spack/docs/contribution_guide.rst b/lib/spack/docs/contribution_guide.rst index 17e24b816e..4d639a1c9b 100644 --- a/lib/spack/docs/contribution_guide.rst +++ b/lib/spack/docs/contribution_guide.rst @@ -71,7 +71,7 @@ locally to speed up the review process. new release that is causing problems. If this is the case, please file an issue. -We currently test against Python 2.6, 2.7, and 3.5-3.7 on both macOS and Linux and +We currently test against Python 2.7 and 3.5-3.9 on both macOS and Linux and perform 3 types of tests: .. _cmd-spack-unit-test: diff --git a/lib/spack/docs/tables/system_prerequisites.csv b/lib/spack/docs/tables/system_prerequisites.csv index 074be4bffb..980aea77f6 100644 --- a/lib/spack/docs/tables/system_prerequisites.csv +++ b/lib/spack/docs/tables/system_prerequisites.csv @@ -1,5 +1,5 @@ Name, Supported Versions, Notes, Requirement Reason -Python, 2.6/2.7/3.5-3.9, , Interpreter for Spack +Python, 2.7/3.5-3.9, , Interpreter for Spack C/C++ Compilers, , , Building software make, , , Build software patch, , , Build software diff --git a/lib/spack/external/__init__.py b/lib/spack/external/__init__.py index be4b9fbf14..995b98146d 100644 --- a/lib/spack/external/__init__.py +++ b/lib/spack/external/__init__.py @@ -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 -- diff --git a/lib/spack/external/functools_backport.py b/lib/spack/external/functools_backport.py deleted file mode 100644 index b3c913ffd7..0000000000 --- a/lib/spack/external/functools_backport.py +++ /dev/null @@ -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 diff --git a/lib/spack/external/ordereddict_backport.py b/lib/spack/external/ordereddict_backport.py deleted file mode 100644 index 3c7f012e9e..0000000000 --- a/lib/spack/external/ordereddict_backport.py +++ /dev/null @@ -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 diff --git a/lib/spack/external/py26/ordereddict.py b/lib/spack/external/py26/ordereddict.py deleted file mode 100644 index 7242b5060d..0000000000 --- a/lib/spack/external/py26/ordereddict.py +++ /dev/null @@ -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 diff --git a/lib/spack/external/pytest-fallback/_pytest/fixtures.py b/lib/spack/external/pytest-fallback/_pytest/fixtures.py index 98317a4889..7ad495615e 100644 --- a/lib/spack/external/pytest-fallback/_pytest/fixtures.py +++ b/lib/spack/external/pytest-fallback/_pytest/fixtures.py @@ -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] diff --git a/lib/spack/llnl/util/multiproc.py b/lib/spack/llnl/util/multiproc.py index c73ebaed20..2a261d143e 100644 --- a/lib/spack/llnl/util/multiproc.py +++ b/lib/spack/llnl/util/multiproc.py @@ -16,7 +16,7 @@ class Barrier: """Simple reusable semaphore barrier. - Python 2.6 doesn't have multiprocessing barriers so we implement this. + Python 2 doesn't have multiprocessing barriers so we implement this. See http://greenteapress.com/semaphores/downey08semaphores.pdf, p. 41. """ diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py index 0a23896b8f..99566a23ae 100644 --- a/lib/spack/spack/binary_distribution.py +++ b/lib/spack/spack/binary_distribution.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import codecs +import collections import hashlib import json import os @@ -15,7 +16,6 @@ from contextlib import closing import ruamel.yaml as yaml -from ordereddict_backport import OrderedDict from six.moves.urllib.error import HTTPError, URLError import llnl.util.lang @@ -1278,8 +1278,8 @@ def relocate_package(spec, allow_root): # Spurious replacements (e.g. sbang) will cause issues with binaries # For example, the new sbang can be longer than the old one. # Hence 2 dictionaries are maintained here. - prefix_to_prefix_text = OrderedDict({}) - prefix_to_prefix_bin = OrderedDict({}) + prefix_to_prefix_text = collections.OrderedDict() + prefix_to_prefix_bin = collections.OrderedDict() if old_sbang_install_path: install_path = spack.hooks.sbang.sbang_install_path() diff --git a/lib/spack/spack/bootstrap.py b/lib/spack/spack/bootstrap.py index f7e555bea8..f046a34a19 100644 --- a/lib/spack/spack/bootstrap.py +++ b/lib/spack/spack/bootstrap.py @@ -12,15 +12,10 @@ import os.path import re import sys +import sysconfig import six -try: - import sysconfig # novm -except ImportError: - # Not supported on Python 2.6 - pass - import archspec.cpu import llnl.util.filesystem as fs diff --git a/lib/spack/spack/cmd/license.py b/lib/spack/spack/cmd/license.py index 3627b35391..82cbc3b2a7 100644 --- a/lib/spack/spack/cmd/license.py +++ b/lib/spack/spack/cmd/license.py @@ -46,9 +46,8 @@ r'^lib/spack/docs/.*\.py$', r'^lib/spack/docs/spack.yaml$', - # 2 files in external + # 1 file in external r'^lib/spack/external/__init__.py$', - r'^lib/spack/external/ordereddict_backport.py$', # shell scripts in share r'^share/spack/.*\.sh$', diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py index f3572cfdcf..90b4c5b669 100644 --- a/lib/spack/spack/concretize.py +++ b/lib/spack/spack/concretize.py @@ -16,14 +16,13 @@ """ from __future__ import print_function +import functools import os.path import platform import tempfile from contextlib import contextmanager from itertools import chain -from functools_backport import reverse_order - import archspec.cpu import llnl.util.filesystem as fs @@ -48,6 +47,23 @@ _abi = llnl.util.lang.Singleton(lambda: spack.abi.ABI()) +@functools.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 + + class Concretizer(object): """You can subclass this class to override some of the default concretization strategies, or you can override all of them. @@ -130,11 +146,11 @@ def _valid_virtuals_and_externals(self, spec): # Use a sort key to order the results return sorted(usable, key=lambda spec: ( - not spec.external, # prefer externals - pref_key(spec), # respect prefs - spec.name, # group by name - reverse_order(spec.versions), # latest version - spec # natural order + not spec.external, # prefer externals + pref_key(spec), # respect prefs + spec.name, # group by name + reverse_order(spec.versions), # latest version + spec # natural order )) def choose_virtual_or_external(self, spec): diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index f3fc73e4b4..d967fef122 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -39,7 +39,6 @@ from typing import List # novm import ruamel.yaml as yaml -from ordereddict_backport import OrderedDict from ruamel.yaml.error import MarkedYAMLError from six import iteritems @@ -401,7 +400,7 @@ def __init__(self, *scopes): Configuration, ordered from lowest to highest precedence """ - self.scopes = OrderedDict() + self.scopes = collections.OrderedDict() for scope in scopes: self.push_scope(scope) self.format_updates = collections.defaultdict(list) diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py index a6be5d1c50..e876d014dd 100644 --- a/lib/spack/spack/environment/environment.py +++ b/lib/spack/spack/environment/environment.py @@ -13,7 +13,6 @@ import ruamel.yaml as yaml import six -from ordereddict_backport import OrderedDict import llnl.util.filesystem as fs import llnl.util.tty as tty @@ -318,7 +317,11 @@ def to_dict(self): # projections guaranteed to be ordered dict if true-ish # for python2.6, may be syaml or ruamel.yaml implementation # so we have to check for both - types = (OrderedDict, syaml.syaml_dict, yaml.comments.CommentedMap) + types = ( + collections.OrderedDict, + syaml.syaml_dict, + yaml.comments.CommentedMap + ) assert isinstance(self.projections, types) ret['projections'] = self.projections if self.select: @@ -638,7 +641,7 @@ def _read_manifest(self, f, raw_yaml=None): else: self.raw_yaml, self.yaml = _read_yaml(f) - self.spec_lists = OrderedDict() + self.spec_lists = collections.OrderedDict() for item in config_dict(self.yaml).get('definitions', []): entry = copy.deepcopy(item) diff --git a/lib/spack/spack/extensions.py b/lib/spack/spack/extensions.py index 69a287fe85..0a1a056819 100644 --- a/lib/spack/spack/extensions.py +++ b/lib/spack/spack/extensions.py @@ -5,6 +5,7 @@ """Service functions and classes to implement the hooks for Spack's command extensions. """ +import importlib import os import re import sys @@ -98,9 +99,7 @@ def ensure_package_creation(name): ensure_package_creation(extension) ensure_package_creation(extension + '.cmd') - # TODO: Upon removal of support for Python 2.6 substitute the call - # TODO: below with importlib.import_module(module_name) - module = llnl.util.lang.load_module_from_file(module_name, cmd_path) + module = importlib.import_module(module_name) sys.modules[module_name] = module return module diff --git a/lib/spack/spack/filesystem_view.py b/lib/spack/spack/filesystem_view.py index 659ae550ae..741e38490a 100644 --- a/lib/spack/spack/filesystem_view.py +++ b/lib/spack/spack/filesystem_view.py @@ -3,14 +3,13 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import collections import functools as ft import os import re import shutil import sys -from ordereddict_backport import OrderedDict - from llnl.util import tty from llnl.util.filesystem import mkdirp, remove_dead_links, remove_empty_directories from llnl.util.lang import index_by, match_predicate @@ -79,7 +78,7 @@ def view_copy(src, dst, view, spec=None): orig_sbang = '#!/bin/bash {0}/bin/sbang'.format(spack.paths.spack_root) new_sbang = sbang.sbang_shebang_line() - prefix_to_projection = OrderedDict({ + prefix_to_projection = collections.OrderedDict({ spec.prefix: view.get_projection_for_spec(spec)}) for dep in spec.traverse(): diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py index 2d1a3e819e..0d51c26ce2 100644 --- a/lib/spack/spack/mirror.py +++ b/lib/spack/spack/mirror.py @@ -11,6 +11,7 @@ where spack is run is not connected to the internet, it allows spack to download packages directly from a mirror (e.g., on an intranet). """ +import collections import operator import os import os.path @@ -19,7 +20,6 @@ import ruamel.yaml.error as yaml_error import six -from ordereddict_backport import OrderedDict if sys.version_info >= (3, 5): from collections.abc import Mapping # novm @@ -230,7 +230,7 @@ class MirrorCollection(Mapping): """A mapping of mirror names to mirrors.""" def __init__(self, mirrors=None, scope=None): - self._mirrors = OrderedDict( + self._mirrors = collections.OrderedDict( (name, Mirror.from_dict(mirror, name)) for name, mirror in ( mirrors.items() if mirrors is not None else diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index 8e1e81c124..77a881c442 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -29,7 +29,6 @@ from typing import Any, Callable, Dict, List, Optional # novm import six -from ordereddict_backport import OrderedDict import llnl.util.filesystem as fsys import llnl.util.tty as tty @@ -902,7 +901,7 @@ def version_urls(self): explicitly defined ``url`` argument. So, this list may be empty if a package only defines ``url`` at the top level. """ - version_urls = OrderedDict() + version_urls = collections.OrderedDict() for v, args in sorted(self.versions.items()): if 'url' in args: version_urls[v] = args['url'] diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py index 14bc0e1953..08ec1a18ee 100644 --- a/lib/spack/spack/relocate.py +++ b/lib/spack/spack/relocate.py @@ -2,15 +2,14 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import collections import multiprocessing.pool import os import re import shutil -from collections import defaultdict import macholib.mach_o import macholib.MachO -from ordereddict_backport import OrderedDict import llnl.util.lang import llnl.util.tty as tty @@ -807,7 +806,7 @@ def relocate_text(files, prefixes, concurrency=32): # orig_sbang = '#!/bin/bash {0}/bin/sbang'.format(orig_spack) # new_sbang = '#!/bin/bash {0}/bin/sbang'.format(new_spack) - compiled_prefixes = OrderedDict({}) + compiled_prefixes = collections.OrderedDict({}) for orig_prefix, new_prefix in prefixes.items(): if orig_prefix != new_prefix: @@ -845,7 +844,7 @@ def relocate_text_bin(binaries, prefixes, concurrency=32): Raises: BinaryTextReplaceError: when the new path is longer than the old path """ - byte_prefixes = OrderedDict({}) + byte_prefixes = collections.OrderedDict({}) for orig_prefix, new_prefix in prefixes.items(): if orig_prefix != new_prefix: @@ -1032,7 +1031,7 @@ def fixup_macos_rpath(root, filename): # Convert rpaths list to (name -> number of occurrences) add_rpaths = set() del_rpaths = set() - rpaths = defaultdict(int) + rpaths = collections.defaultdict(int) for rpath in rpath_list: rpaths[rpath] += 1 diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py index 19721fc676..73c75a1e18 100644 --- a/lib/spack/spack/reporters/cdash.py +++ b/lib/spack/spack/reporters/cdash.py @@ -2,9 +2,8 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - - import codecs +import collections import hashlib import os.path import platform @@ -13,7 +12,6 @@ import time import xml.sax.saxutils -from ordereddict_backport import OrderedDict from six import iteritems, text_type from six.moves.urllib.parse import urlencode from six.moves.urllib.request import HTTPHandler, Request, build_opener @@ -96,7 +94,7 @@ def __init__(self, args): buildstamp_format = "%Y%m%d-%H%M-{0}".format(args.cdash_track) self.buildstamp = time.strftime(buildstamp_format, time.localtime(self.endtime)) - self.buildIds = OrderedDict() + self.buildIds = collections.OrderedDict() self.revision = '' git = which('git') with working_dir(spack.paths.spack_root): diff --git a/lib/spack/spack/test/cmd/url.py b/lib/spack/spack/test/cmd/url.py index f9179720b1..249ea6ec57 100644 --- a/lib/spack/spack/test/cmd/url.py +++ b/lib/spack/spack/test/cmd/url.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import re -import sys import pytest @@ -69,14 +68,6 @@ def test_url_with_no_version_fails(): url('parse', 'http://www.netlib.org/voronoi/triangle.zip') -skip_python_26 = pytest.mark.skipif( - sys.version_info < (2, 7), - reason="Python 2.6 tests are run in a container, where " - "networking is super slow" -) - - -@skip_python_26 def test_url_list(mock_packages): out = url('list') total_urls = len(out.split('\n')) @@ -106,7 +97,6 @@ def test_url_list(mock_packages): assert 0 < correct_version_urls < total_urls -@skip_python_26 def test_url_summary(mock_packages): """Test the URL summary command.""" # test url_summary, the internal function that does the work @@ -133,7 +123,6 @@ def test_url_summary(mock_packages): assert out_correct_versions == correct_versions -@skip_python_26 def test_url_stats(capfd, mock_packages): with capfd.disabled(): output = url('stats') diff --git a/lib/spack/spack/test/llnl/util/tty/log.py b/lib/spack/spack/test/llnl/util/tty/log.py index 78d4e24fa4..983dea9c0b 100644 --- a/lib/spack/spack/test/llnl/util/tty/log.py +++ b/lib/spack/spack/test/llnl/util/tty/log.py @@ -429,10 +429,6 @@ def mock_shell_v_v_no_termios(proc, ctl, **kwargs): (mock_shell_v_v, nullcontext), (mock_shell_v_v_no_termios, no_termios), ]) -@pytest.mark.skipif( - sys.version_info < (2, 7), - reason="Python 2.6 tests are run in a container, where this fails often" -) def test_foreground_background_output( test_fn, capfd, termios_on_or_off, tmpdir): """Tests hitting 'v' toggles output, and that force_echo works.""" diff --git a/lib/spack/spack/test/web.py b/lib/spack/spack/test/web.py index b940fe6055..4ac0da162b 100644 --- a/lib/spack/spack/test/web.py +++ b/lib/spack/spack/test/web.py @@ -2,9 +2,9 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import collections import os -import ordereddict_backport import pytest import llnl.util.tty as tty @@ -152,7 +152,7 @@ def test_get_header(): # If lookup has to fallback to fuzzy matching and there are more than one # fuzzy match, the result depends on the internal ordering of the given # mapping - headers = ordereddict_backport.OrderedDict() + headers = collections.OrderedDict() headers['Content-type'] = 'text/plain' headers['contentType'] = 'text/html' @@ -161,7 +161,7 @@ def test_get_header(): assert(spack.util.web.get_header(headers, 'CONTENT_TYPE') == 'text/html') # Same as above, but different ordering - headers = ordereddict_backport.OrderedDict() + headers = collections.OrderedDict() headers['contentType'] = 'text/html' headers['Content-type'] = 'text/plain' diff --git a/lib/spack/spack/util/mock_package.py b/lib/spack/spack/util/mock_package.py index d8b3ec468b..ab7b8439e5 100644 --- a/lib/spack/spack/util/mock_package.py +++ b/lib/spack/spack/util/mock_package.py @@ -2,10 +2,8 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - """Infrastructure used by tests for mocking packages and repos.""" - -import ordereddict_backport +import collections import spack.provider_index import spack.util.naming @@ -149,7 +147,7 @@ class MockPackage(MockPackageBase): MockPackage._repo = self # set up dependencies - MockPackage.dependencies = ordereddict_backport.OrderedDict() + MockPackage.dependencies = collections.OrderedDict() for dep, dtype in zip(dependencies, dependency_types): d = Dependency(MockPackage, Spec(dep.name), type=dtype) if not conditions or dep.name not in conditions: diff --git a/lib/spack/spack/util/spack_yaml.py b/lib/spack/spack/util/spack_yaml.py index a67b6491f8..9812943a79 100644 --- a/lib/spack/spack/util/spack_yaml.py +++ b/lib/spack/spack/util/spack_yaml.py @@ -12,13 +12,13 @@ default unorderd dict. """ +import collections import ctypes import re import sys from typing import List # novm import ruamel.yaml as yaml -from ordereddict_backport import OrderedDict from ruamel.yaml import RoundTripDumper, RoundTripLoader from six import StringIO, string_types @@ -39,7 +39,7 @@ # Also, use OrderedDict instead of just dict. -class syaml_dict(OrderedDict): +class syaml_dict(collections.OrderedDict): def __repr__(self): mappings = ('%r: %r' % (k, v) for k, v in self.items()) return '{%s}' % ', '.join(mappings)