summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2022-11-15 10:07:54 +0100
committerGitHub <noreply@github.com>2022-11-15 10:07:54 +0100
commitb3124bff7c08d0f9ae8f0754c91ef72a025bd574 (patch)
tree9dd90f611ccfd054a1499d7168210014798356f0
parent5c4137baf19b9e271a2f13e886d6b875aab067dd (diff)
downloadspack-b3124bff7c08d0f9ae8f0754c91ef72a025bd574.tar.gz
spack-b3124bff7c08d0f9ae8f0754c91ef72a025bd574.tar.bz2
spack-b3124bff7c08d0f9ae8f0754c91ef72a025bd574.tar.xz
spack-b3124bff7c08d0f9ae8f0754c91ef72a025bd574.zip
Stop using `six` in Spack (#33905)
Since we dropped support for Python 2.7, there's no need so use `six` anymore. We still need to vendor it until we update our vendored dependencies.
-rw-r--r--lib/spack/external/ctest_log_parser.py7
-rw-r--r--lib/spack/llnl/util/argparsewriter.py5
-rw-r--r--lib/spack/llnl/util/filesystem.py18
-rw-r--r--lib/spack/llnl/util/lang.py16
-rw-r--r--lib/spack/llnl/util/tty/__init__.py23
-rw-r--r--lib/spack/llnl/util/tty/colify.py7
-rw-r--r--lib/spack/llnl/util/tty/color.py4
-rw-r--r--lib/spack/llnl/util/tty/log.py10
-rw-r--r--lib/spack/spack/audit.py3
-rw-r--r--lib/spack/spack/binary_distribution.py2
-rw-r--r--lib/spack/spack/bootstrap.py8
-rw-r--r--lib/spack/spack/build_environment.py5
-rw-r--r--lib/spack/spack/build_systems/_checks.py4
-rw-r--r--lib/spack/spack/build_systems/cmake.py6
-rw-r--r--lib/spack/spack/builder.py6
-rw-r--r--lib/spack/spack/ci.py12
-rw-r--r--lib/spack/spack/cmd/__init__.py3
-rw-r--r--lib/spack/spack/cmd/compiler.py6
-rw-r--r--lib/spack/spack/cmd/env.py5
-rw-r--r--lib/spack/spack/cmd/info.py3
-rw-r--r--lib/spack/spack/cmd/providers.py5
-rw-r--r--lib/spack/spack/cmd/tags.py8
-rw-r--r--lib/spack/spack/cmd/unit_test.py5
-rw-r--r--lib/spack/spack/cmd/url.py5
-rw-r--r--lib/spack/spack/compilers/__init__.py10
-rw-r--r--lib/spack/spack/config.py8
-rw-r--r--lib/spack/spack/cray_manifest.py8
-rw-r--r--lib/spack/spack/database.py7
-rw-r--r--lib/spack/spack/dependency.py8
-rw-r--r--lib/spack/spack/detection/common.py4
-rw-r--r--lib/spack/spack/directives.py6
-rw-r--r--lib/spack/spack/directory_layout.py6
-rw-r--r--lib/spack/spack/environment/environment.py13
-rw-r--r--lib/spack/spack/fetch_strategy.py10
-rw-r--r--lib/spack/spack/gcs_handler.py5
-rw-r--r--lib/spack/spack/install_test.py7
-rw-r--r--lib/spack/spack/installer.py6
-rw-r--r--lib/spack/spack/main.py5
-rw-r--r--lib/spack/spack/mirror.py25
-rw-r--r--lib/spack/spack/package_base.py22
-rw-r--r--lib/spack/spack/package_prefs.py4
-rw-r--r--lib/spack/spack/parse.py4
-rw-r--r--lib/spack/spack/provider_index.py8
-rw-r--r--lib/spack/spack/repo.py6
-rw-r--r--lib/spack/spack/reporters/cdash.py12
-rw-r--r--lib/spack/spack/s3_handler.py22
-rw-r--r--lib/spack/spack/schema/__init__.py5
-rw-r--r--lib/spack/spack/schema/config.py6
-rw-r--r--lib/spack/spack/solver/asp.py8
-rw-r--r--lib/spack/spack/spec.py42
-rw-r--r--lib/spack/spack/spec_list.py8
-rw-r--r--lib/spack/spack/stage.py10
-rw-r--r--lib/spack/spack/store.py6
-rw-r--r--lib/spack/spack/target.py6
-rw-r--r--lib/spack/spack/tengine.py4
-rw-r--r--lib/spack/spack/test/cmd/build_env.py4
-rw-r--r--lib/spack/spack/test/cmd/env.py36
-rw-r--r--lib/spack/spack/test/cmd/install.py3
-rw-r--r--lib/spack/spack/test/compilers/basics.py3
-rw-r--r--lib/spack/spack/test/config.py4
-rw-r--r--lib/spack/spack/test/env.py7
-rw-r--r--lib/spack/spack/test/graph.py8
-rw-r--r--lib/spack/spack/test/llnl/util/file_list.py3
-rw-r--r--lib/spack/spack/test/provider_index.py6
-rw-r--r--lib/spack/spack/test/tag.py22
-rw-r--r--lib/spack/spack/test/util/unparse/unparse.py54
-rw-r--r--lib/spack/spack/url.py7
-rw-r--r--lib/spack/spack/util/environment.py14
-rw-r--r--lib/spack/spack/util/executable.py17
-rw-r--r--lib/spack/spack/util/log_parse.py4
-rw-r--r--lib/spack/spack/util/naming.py5
-rw-r--r--lib/spack/spack/util/path.py3
-rw-r--r--lib/spack/spack/util/py2.py16
-rw-r--r--lib/spack/spack/util/s3.py6
-rw-r--r--lib/spack/spack/util/spack_json.py25
-rw-r--r--lib/spack/spack/util/spack_yaml.py10
-rw-r--r--lib/spack/spack/util/unparse/__init__.py8
-rw-r--r--lib/spack/spack/util/unparse/unparser.py141
-rw-r--r--lib/spack/spack/util/url.py31
-rw-r--r--lib/spack/spack/util/web.py8
-rw-r--r--lib/spack/spack/variant.py10
-rw-r--r--lib/spack/spack/verify.py5
-rw-r--r--lib/spack/spack/version.py10
83 files changed, 329 insertions, 618 deletions
diff --git a/lib/spack/external/ctest_log_parser.py b/lib/spack/external/ctest_log_parser.py
index d1c8db16c8..0bb31e01b1 100644
--- a/lib/spack/external/ctest_log_parser.py
+++ b/lib/spack/external/ctest_log_parser.py
@@ -71,13 +71,12 @@ from __future__ import division
import re
import math
import multiprocessing
+import io
import sys
import threading
import time
from contextlib import contextmanager
-from six import StringIO
-from six import string_types
_error_matches = [
"^FAIL: ",
@@ -246,7 +245,7 @@ class LogEvent(object):
def __str__(self):
"""Returns event lines and context."""
- out = StringIO()
+ out = io.StringIO()
for i in range(self.start, self.end):
if i == self.line_no:
out.write(' >> %-6d%s' % (i, self[i]))
@@ -386,7 +385,7 @@ class CTestLogParser(object):
(tuple): two lists containing ``BuildError`` and
``BuildWarning`` objects.
"""
- if isinstance(stream, string_types):
+ if isinstance(stream, str):
with open(stream) as f:
return self.parse(f, context, jobs)
diff --git a/lib/spack/llnl/util/argparsewriter.py b/lib/spack/llnl/util/argparsewriter.py
index a8db508c2f..ad5bf3e83d 100644
--- a/lib/spack/llnl/util/argparsewriter.py
+++ b/lib/spack/llnl/util/argparsewriter.py
@@ -7,11 +7,10 @@ from __future__ import print_function
import argparse
import errno
+import io
import re
import sys
-from six import StringIO
-
class Command(object):
"""Parsed representation of a command from argparse.
@@ -181,7 +180,7 @@ class ArgparseRstWriter(ArgparseWriter):
self.rst_levels = rst_levels
def format(self, cmd):
- string = StringIO()
+ string = io.StringIO()
string.write(self.begin_command(cmd.prog))
if cmd.description:
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 30ecc1ebc8..db83cea6fc 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -18,8 +18,6 @@ import tempfile
from contextlib import contextmanager
from sys import platform as _platform
-import six
-
from llnl.util import tty
from llnl.util.lang import dedupe, memoized
from llnl.util.symlink import islink, symlink
@@ -520,7 +518,7 @@ def chgrp(path, group, follow_symlinks=True):
if is_windows:
raise OSError("Function 'chgrp' is not supported on Windows")
- if isinstance(group, six.string_types):
+ if isinstance(group, str):
gid = grp.getgrnam(group).gr_gid
else:
gid = group
@@ -1017,7 +1015,7 @@ def open_if_filename(str_or_file, mode="r"):
If it's a file object, just yields the file object.
"""
- if isinstance(str_or_file, six.string_types):
+ if isinstance(str_or_file, str):
with open(str_or_file, mode) as f:
yield f
else:
@@ -1602,7 +1600,7 @@ def find(root, files, recursive=True):
Returns:
list: The files that have been found
"""
- if isinstance(files, six.string_types):
+ if isinstance(files, str):
files = [files]
if recursive:
@@ -1666,7 +1664,7 @@ class FileList(collections.abc.Sequence):
"""
def __init__(self, files):
- if isinstance(files, six.string_types):
+ if isinstance(files, str):
files = [files]
self.files = list(dedupe(files))
@@ -1762,7 +1760,7 @@ class HeaderList(FileList):
def directories(self, value):
value = value or []
# Accept a single directory as input
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
value = [value]
self._directories = [path_to_os_path(os.path.normpath(x))[0] for x in value]
@@ -1898,7 +1896,7 @@ def find_headers(headers, root, recursive=False):
Returns:
HeaderList: The headers that have been found
"""
- if isinstance(headers, six.string_types):
+ if isinstance(headers, str):
headers = [headers]
elif not isinstance(headers, collections.abc.Sequence):
message = "{0} expects a string or sequence of strings as the "
@@ -2064,7 +2062,7 @@ def find_system_libraries(libraries, shared=True):
Returns:
LibraryList: The libraries that have been found
"""
- if isinstance(libraries, six.string_types):
+ if isinstance(libraries, str):
libraries = [libraries]
elif not isinstance(libraries, collections.abc.Sequence):
message = "{0} expects a string or sequence of strings as the "
@@ -2121,7 +2119,7 @@ def find_libraries(libraries, root, shared=True, recursive=False, runtime=True):
Returns:
LibraryList: The libraries that have been found
"""
- if isinstance(libraries, six.string_types):
+ if isinstance(libraries, str):
libraries = [libraries]
elif not isinstance(libraries, collections.abc.Sequence):
message = "{0} expects a string or sequence of strings as the "
diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py
index d8f3cc9b9b..6deb224d70 100644
--- a/lib/spack/llnl/util/lang.py
+++ b/lib/spack/llnl/util/lang.py
@@ -17,9 +17,6 @@ import traceback
from datetime import datetime, timedelta
from typing import Any, Callable, Iterable, List, Tuple
-import six
-from six import string_types
-
# Ignore emacs backups when listing modules
ignore_modules = [r"^\.#", "~$"]
@@ -200,14 +197,9 @@ def memoized(func):
return ret
except TypeError as e:
# TypeError is raised when indexing into a dict if the key is unhashable.
- raise six.raise_from(
- UnhashableArguments(
- "args + kwargs '{}' was not hashable for function '{}'".format(
- key, func.__name__
- ),
- ),
- e,
- )
+ raise UnhashableArguments(
+ "args + kwargs '{}' was not hashable for function '{}'".format(key, func.__name__),
+ ) from e
return _memoized_function
@@ -574,7 +566,7 @@ def match_predicate(*args):
def match(string):
for arg in args:
- if isinstance(arg, string_types):
+ if isinstance(arg, str):
if re.search(arg, string):
return True
elif isinstance(arg, list) or isinstance(arg, tuple):
diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py
index 7c86411dbe..4b289438fa 100644
--- a/lib/spack/llnl/util/tty/__init__.py
+++ b/lib/spack/llnl/util/tty/__init__.py
@@ -6,6 +6,7 @@
from __future__ import unicode_literals
import contextlib
+import io
import os
import struct
import sys
@@ -14,10 +15,6 @@ import traceback
from datetime import datetime
from sys import platform as _platform
-import six
-from six import StringIO
-from six.moves import input
-
if _platform != "win32":
import fcntl
import termios
@@ -183,7 +180,7 @@ def msg(message, *args, **kwargs):
else:
cwrite("@*b{%s==>} %s%s" % (st_text, get_timestamp(), cescape(_output_filter(message))))
for arg in args:
- print(indent + _output_filter(six.text_type(arg)))
+ print(indent + _output_filter(str(arg)))
def info(message, *args, **kwargs):
@@ -201,13 +198,13 @@ def info(message, *args, **kwargs):
st_text = process_stacktrace(st_countback)
cprint(
"@%s{%s==>} %s%s"
- % (format, st_text, get_timestamp(), cescape(_output_filter(six.text_type(message)))),
+ % (format, st_text, get_timestamp(), cescape(_output_filter(str(message)))),
stream=stream,
)
for arg in args:
if wrap:
lines = textwrap.wrap(
- _output_filter(six.text_type(arg)),
+ _output_filter(str(arg)),
initial_indent=indent,
subsequent_indent=indent,
break_long_words=break_long_words,
@@ -215,7 +212,7 @@ def info(message, *args, **kwargs):
for line in lines:
stream.write(line + "\n")
else:
- stream.write(indent + _output_filter(six.text_type(arg)) + "\n")
+ stream.write(indent + _output_filter(str(arg)) + "\n")
def verbose(message, *args, **kwargs):
@@ -238,7 +235,7 @@ def error(message, *args, **kwargs):
kwargs.setdefault("format", "*r")
kwargs.setdefault("stream", sys.stderr)
- info("Error: " + six.text_type(message), *args, **kwargs)
+ info("Error: " + str(message), *args, **kwargs)
def warn(message, *args, **kwargs):
@@ -247,7 +244,7 @@ def warn(message, *args, **kwargs):
kwargs.setdefault("format", "*Y")
kwargs.setdefault("stream", sys.stderr)
- info("Warning: " + six.text_type(message), *args, **kwargs)
+ info("Warning: " + str(message), *args, **kwargs)
def die(message, *args, **kwargs):
@@ -271,7 +268,7 @@ def get_number(prompt, **kwargs):
while number is None:
msg(prompt, newline=False)
ans = input()
- if ans == six.text_type(abort):
+ if ans == str(abort):
return None
if ans:
@@ -336,11 +333,11 @@ def hline(label=None, **kwargs):
cols -= 2
cols = min(max_width, cols)
- label = six.text_type(label)
+ label = str(label)
prefix = char * 2 + " "
suffix = " " + (cols - len(prefix) - clen(label)) * char
- out = StringIO()
+ out = io.StringIO()
out.write(prefix)
out.write(label)
out.write(suffix)
diff --git a/lib/spack/llnl/util/tty/colify.py b/lib/spack/llnl/util/tty/colify.py
index 73c1daf0d5..4520aad38f 100644
--- a/lib/spack/llnl/util/tty/colify.py
+++ b/lib/spack/llnl/util/tty/colify.py
@@ -8,11 +8,10 @@ Routines for printing columnar output. See ``colify()`` for more information.
"""
from __future__ import division, unicode_literals
+import io
import os
import sys
-from six import StringIO, text_type
-
from llnl.util.tty import terminal_size
from llnl.util.tty.color import cextra, clen
@@ -134,7 +133,7 @@ def colify(elts, **options):
)
# elts needs to be an array of strings so we can count the elements
- elts = [text_type(elt) for elt in elts]
+ elts = [str(elt) for elt in elts]
if not elts:
return (0, ())
@@ -232,7 +231,7 @@ def colify_table(table, **options):
def colified(elts, **options):
"""Invokes the ``colify()`` function but returns the result as a string
instead of writing it to an output string."""
- sio = StringIO()
+ sio = io.StringIO()
options["output"] = sio
colify(elts, **options)
return sio.getvalue()
diff --git a/lib/spack/llnl/util/tty/color.py b/lib/spack/llnl/util/tty/color.py
index ad6862fc28..83e8316914 100644
--- a/lib/spack/llnl/util/tty/color.py
+++ b/lib/spack/llnl/util/tty/color.py
@@ -65,8 +65,6 @@ import re
import sys
from contextlib import contextmanager
-import six
-
class ColorParseError(Exception):
"""Raised when a color format fails to parse."""
@@ -259,7 +257,7 @@ def cescape(string):
Returns:
(str): the string with color codes escaped
"""
- string = six.text_type(string)
+ string = str(string)
string = string.replace("@", "@@")
string = string.replace("}", "}}")
return string
diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py
index 2d6609c390..0b79dd01ac 100644
--- a/lib/spack/llnl/util/tty/log.py
+++ b/lib/spack/llnl/util/tty/log.py
@@ -24,8 +24,6 @@ from threading import Thread
from types import ModuleType # novm
from typing import Optional # novm
-from six import StringIO, string_types
-
import llnl.util.tty as tty
termios = None # type: Optional[ModuleType]
@@ -308,7 +306,7 @@ class FileWrapper(object):
self.file_like = file_like
- if isinstance(file_like, string_types):
+ if isinstance(file_like, str):
self.open = True
elif _file_descriptors_work(file_like):
self.open = False
@@ -324,7 +322,7 @@ class FileWrapper(object):
if self.file_like:
self.file = open(self.file_like, "w", encoding="utf-8")
else:
- self.file = StringIO()
+ self.file = io.StringIO()
return self.file
else:
# We were handed an already-open file object. In this case we also
@@ -787,7 +785,7 @@ class winlog(object):
raise RuntimeError("file argument must be set by __init__ ")
# Open both write and reading on logfile
- if type(self.logfile) == StringIO:
+ if type(self.logfile) == io.StringIO:
self._ioflag = True
# cannot have two streams on tempfile, so we must make our own
sys.stdout = self.logfile
@@ -1013,7 +1011,7 @@ def _writer_daemon(
finally:
# send written data back to parent if we used a StringIO
- if isinstance(log_file, StringIO):
+ if isinstance(log_file, io.StringIO):
control_pipe.send(log_file.getvalue())
log_file_wrapper.close()
close_connection_and_file(read_multiprocess_fd, in_pipe)
diff --git a/lib/spack/spack/audit.py b/lib/spack/spack/audit.py
index 5187961930..4bc85dac46 100644
--- a/lib/spack/spack/audit.py
+++ b/lib/spack/spack/audit.py
@@ -42,8 +42,7 @@ import inspect
import itertools
import pickle
import re
-
-from six.moves.urllib.request import urlopen
+from urllib.request import urlopen
import llnl.util.lang
diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index 1e9843c473..4fbf6e5ec3 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -17,9 +17,9 @@ import time
import traceback
import warnings
from contextlib import closing
+from urllib.error import HTTPError, URLError
import ruamel.yaml as yaml
-from six.moves.urllib.error import HTTPError, URLError
import llnl.util.filesystem as fsys
import llnl.util.lang
diff --git a/lib/spack/spack/bootstrap.py b/lib/spack/spack/bootstrap.py
index 1715eeaafd..e92a1fb6a1 100644
--- a/lib/spack/spack/bootstrap.py
+++ b/lib/spack/spack/bootstrap.py
@@ -17,8 +17,6 @@ import sys
import sysconfig
import uuid
-import six
-
import archspec.cpu
import llnl.util.filesystem as fs
@@ -78,7 +76,7 @@ def _try_import_from_store(module, query_spec, query_info=None):
command found and the concrete spec providing it
"""
# If it is a string assume it's one of the root specs by this module
- if isinstance(query_spec, six.string_types):
+ if isinstance(query_spec, str):
# We have to run as part of this python interpreter
query_spec += " ^" + spec_for_current_python()
@@ -923,7 +921,7 @@ def _missing(name, purpose, system_only=True):
def _required_system_executable(exes, msg):
"""Search for an executable is the system path only."""
- if isinstance(exes, six.string_types):
+ if isinstance(exes, str):
exes = (exes,)
if spack.util.executable.which_string(*exes):
return True, None
@@ -941,7 +939,7 @@ def _required_python_module(module, query_spec, msg):
def _required_executable(exes, query_spec, msg):
"""Search for an executable in the system path or in the bootstrap store."""
- if isinstance(exes, six.string_types):
+ if isinstance(exes, str):
exes = (exes,)
if spack.util.executable.which_string(*exes) or _executables_in_store(exes, query_spec):
return True, None
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index f1a1ce3dc8..5b9120d2ff 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -33,6 +33,7 @@ Skimming this module is a nice way to get acquainted with the types of
calls you can make from within the install() function.
"""
import inspect
+import io
import multiprocessing
import os
import re
@@ -41,8 +42,6 @@ import sys
import traceback
import types
-from six import StringIO
-
import llnl.util.tty as tty
from llnl.util.filesystem import install, install_tree, mkdirp
from llnl.util.lang import dedupe
@@ -1352,7 +1351,7 @@ class ChildError(InstallError):
@property
def long_message(self):
- out = StringIO()
+ out = io.StringIO()
out.write(self._long_message if self._long_message else "")
have_log = self.log_name and os.path.exists(self.log_name)
diff --git a/lib/spack/spack/build_systems/_checks.py b/lib/spack/spack/build_systems/_checks.py
index 73d5bbdb93..658362902b 100644
--- a/lib/spack/spack/build_systems/_checks.py
+++ b/lib/spack/spack/build_systems/_checks.py
@@ -4,8 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
-import six
-
import llnl.util.lang
import spack.builder
@@ -26,7 +24,7 @@ def sanity_check_prefix(builder):
pkg = builder.pkg
def check_paths(path_list, filetype, predicate):
- if isinstance(path_list, six.string_types):
+ if isinstance(path_list, str):
path_list = [path_list]
for path in path_list:
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index 9456726d3e..6210db9d4a 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -10,8 +10,6 @@ import re
import sys
from typing import List, Tuple
-import six
-
import llnl.util.filesystem as fs
import spack.build_environment
@@ -302,9 +300,7 @@ class CMakeBuilder(BaseBuilder):
value = "ON" if value else "OFF"
else:
kind = "STRING"
- if isinstance(value, collections.abc.Sequence) and not isinstance(
- value, six.string_types
- ):
+ if isinstance(value, collections.abc.Sequence) and not isinstance(value, str):
value = ";".join(str(v) for v in value)
else:
value = str(value)
diff --git a/lib/spack/spack/builder.py b/lib/spack/spack/builder.py
index 063a7f0611..4308206d52 100644
--- a/lib/spack/spack/builder.py
+++ b/lib/spack/spack/builder.py
@@ -9,8 +9,6 @@ import functools
import inspect
from typing import List, Optional, Tuple
-import six
-
import spack.build_environment
#: Builder classes, as registered by the "builder" decorator
@@ -167,7 +165,7 @@ def _create(pkg):
property(forward_property_to_getattr(attribute_name)),
)
- class Adapter(six.with_metaclass(_PackageAdapterMeta, base_cls)):
+ class Adapter(base_cls, metaclass=_PackageAdapterMeta):
def __init__(self, pkg):
# Deal with custom phases in packages here
if hasattr(pkg, "phases"):
@@ -456,7 +454,7 @@ class InstallationPhase(object):
return copy.deepcopy(self)
-class Builder(six.with_metaclass(BuilderMeta, collections.abc.Sequence)):
+class Builder(collections.abc.Sequence, metaclass=BuilderMeta):
"""A builder is a class that, given a package object (i.e. associated with
concrete spec), knows how to install it.
diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index d6113c0dc9..522c7d8b78 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -16,11 +16,9 @@ import sys
import tempfile
import time
import zipfile
-
-from six import iteritems, string_types
-from six.moves.urllib.error import HTTPError, URLError
-from six.moves.urllib.parse import urlencode
-from six.moves.urllib.request import HTTPHandler, Request, build_opener
+from urllib.error import HTTPError, URLError
+from urllib.parse import urlencode
+from urllib.request import HTTPHandler, Request, build_opener
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@@ -216,7 +214,7 @@ def stage_spec_jobs(specs, check_index_only=False, mirrors_to_check=None):
def _remove_satisfied_deps(deps, satisfied_list):
new_deps = {}
- for key, value in iteritems(deps):
+ for key, value in deps.items():
new_value = set([v for v in value if v not in satisfied_list])
if new_value:
new_deps[key] = new_value
@@ -1970,7 +1968,7 @@ def process_command(name, commands, repro_dir):
"""
tty.debug("spack {0} arguments: {1}".format(name, commands))
- if len(commands) == 0 or isinstance(commands[0], string_types):
+ if len(commands) == 0 or isinstance(commands[0], str):
commands = [commands]
# Create a string [command 1] && [command 2] && ... && [command n] with commands
diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
index ef02e8f9e4..f847bf9be4 100644
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -14,7 +14,6 @@ from textwrap import dedent
from typing import List, Tuple
import ruamel.yaml as yaml
-import six
from ruamel.yaml.error import MarkedYAMLError
import llnl.util.tty as tty
@@ -217,7 +216,7 @@ def parse_specs(args, **kwargs):
tests = kwargs.get("tests", False)
sargs = args
- if not isinstance(args, six.string_types):
+ if not isinstance(args, str):
sargs = " ".join(args)
unquoted_flags = _UnquotedFlags.extract(sargs)
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py
index 75c5f05d0f..2929db3ad6 100644
--- a/lib/spack/spack/cmd/compiler.py
+++ b/lib/spack/spack/cmd/compiler.py
@@ -8,8 +8,6 @@ from __future__ import print_function
import argparse
import sys
-from six import iteritems
-
import llnl.util.tty as tty
from llnl.util.lang import index_by
from llnl.util.tty.colify import colify
@@ -138,13 +136,13 @@ def compiler_info(args):
print("\t\t%s = %s" % (cpath, getattr(c, cpath, None)))
if c.flags:
print("\tflags:")
- for flag, flag_value in iteritems(c.flags):
+ for flag, flag_value in c.flags.items():
print("\t\t%s = %s" % (flag, flag_value))
if len(c.environment) != 0:
if len(c.environment.get("set", {})) != 0:
print("\tenvironment:")
print("\t set:")
- for key, value in iteritems(c.environment["set"]):
+ for key, value in c.environment["set"].items():
print("\t %s = %s" % (key, value))
if c.extra_rpaths:
print("\tExtra rpaths:")
diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py
index 558b6bead4..5510c7443a 100644
--- a/lib/spack/spack/cmd/env.py
+++ b/lib/spack/spack/cmd/env.py
@@ -4,13 +4,12 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import argparse
+import io
import os
import shutil
import sys
import tempfile
-import six
-
import llnl.util.filesystem as fs
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
@@ -737,7 +736,7 @@ def env_depfile(args):
[get_install_deps_target(h) for h, _, _, _ in make_targets.adjacency_list]
)
- buf = six.StringIO()
+ buf = io.StringIO()
template = spack.tengine.make_environment().get_template(os.path.join("depfile", "Makefile"))
diff --git a/lib/spack/spack/cmd/info.py b/lib/spack/spack/cmd/info.py
index 6a16a153ea..5076ff9261 100644
--- a/lib/spack/spack/cmd/info.py
+++ b/lib/spack/spack/cmd/info.py
@@ -7,8 +7,7 @@ from __future__ import print_function
import inspect
import textwrap
-
-from six.moves import zip_longest
+from itertools import zip_longest
import llnl.util.tty as tty
import llnl.util.tty.color as color
diff --git a/lib/spack/spack/cmd/providers.py b/lib/spack/spack/cmd/providers.py
index 2c1b146f6a..73a960a708 100644
--- a/lib/spack/spack/cmd/providers.py
+++ b/lib/spack/spack/cmd/providers.py
@@ -3,10 +3,9 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import io
import sys
-import six
-
import llnl.util.tty.colify as colify
import spack.cmd
@@ -29,7 +28,7 @@ def setup_parser(subparser):
def providers(parser, args):
valid_virtuals = sorted(spack.repo.path.provider_index.providers.keys())
- buffer = six.StringIO()
+ buffer = io.StringIO()
isatty = sys.stdout.isatty()
if isatty:
buffer.write("Virtual packages:\n")
diff --git a/lib/spack/spack/cmd/tags.py b/lib/spack/spack/cmd/tags.py
index 6ba9717784..b720055a15 100644
--- a/lib/spack/spack/cmd/tags.py
+++ b/lib/spack/spack/cmd/tags.py
@@ -2,11 +2,9 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
+import io
import sys
-import six
-
import llnl.util.tty as tty
import llnl.util.tty.colify as colify
@@ -20,7 +18,7 @@ level = "long"
def report_tags(category, tags):
- buffer = six.StringIO()
+ buffer = io.StringIO()
isatty = sys.stdout.isatty()
if isatty:
@@ -88,7 +86,7 @@ def tags(parser, args):
return
# Report packages associated with tags
- buffer = six.StringIO()
+ buffer = io.StringIO()
isatty = sys.stdout.isatty()
tags = args.tag if args.tag else available_tags
diff --git a/lib/spack/spack/cmd/unit_test.py b/lib/spack/spack/cmd/unit_test.py
index d1d0c790f8..55c8b17f9c 100644
--- a/lib/spack/spack/cmd/unit_test.py
+++ b/lib/spack/spack/cmd/unit_test.py
@@ -7,6 +7,7 @@ from __future__ import division, print_function
import argparse
import collections
+import io
import os.path
import re
import sys
@@ -16,8 +17,6 @@ try:
except ImportError:
pytest = None # type: ignore
-from six import StringIO
-
import llnl.util.filesystem
import llnl.util.tty.color as color
from llnl.util.tty.colify import colify
@@ -126,7 +125,7 @@ def do_list(args, extra_args):
old_output = sys.stdout
try:
- sys.stdout = output = StringIO()
+ sys.stdout = output = io.StringIO()
pytest.main(["--collect-only"] + extra_args)
finally:
sys.stdout = old_output
diff --git a/lib/spack/spack/cmd/url.py b/lib/spack/spack/cmd/url.py
index 452bd059da..1c9b5aea53 100644
--- a/lib/spack/spack/cmd/url.py
+++ b/lib/spack/spack/cmd/url.py
@@ -5,10 +5,9 @@
from __future__ import division, print_function
+import urllib.parse
from collections import defaultdict
-import six.moves.urllib.parse as urllib_parse
-
import llnl.util.tty.color as color
from llnl.util import tty
@@ -323,7 +322,7 @@ def url_stats(args):
md5_hashes[pkg_name].append(fetcher.url)
# parse out the URL scheme (https/http/ftp/etc.)
- urlinfo = urllib_parse.urlparse(fetcher.url)
+ urlinfo = urllib.parse.urlparse(fetcher.url)
self.schemes[urlinfo.scheme] += 1
if urlinfo.scheme == "http":
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index e54f8dc96c..b7c8cd2232 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -12,8 +12,6 @@ import multiprocessing.pool
import os
from typing import Dict # novm
-import six
-
import archspec.cpu
import llnl.util.filesystem as fs
@@ -427,7 +425,7 @@ def compiler_from_dict(items):
environment,
extra_rpaths,
enable_implicit_rpaths=implicit_rpaths,
- **compiler_flags
+ **compiler_flags,
)
@@ -677,18 +675,18 @@ def detect_version(detect_version_args):
try:
version = callback(path)
- if version and six.text_type(version).strip() and version != "unknown":
+ if version and str(version).strip() and version != "unknown":
value = fn_args._replace(id=compiler_id._replace(version=version))
return value, None
error = "Couldn't get version for compiler {0}".format(path)
except spack.util.executable.ProcessError as e:
- error = "Couldn't get version for compiler {0}\n".format(path) + six.text_type(e)
+ error = "Couldn't get version for compiler {0}\n".format(path) + str(e)
except Exception as e:
# Catching "Exception" here is fine because it just
# means something went wrong running a candidate executable.
error = "Error while executing candidate compiler {0}" "\n{1}: {2}".format(
- path, e.__class__.__name__, six.text_type(e)
+ path, e.__class__.__name__, str(e)
)
return None, error
diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py
index e9a3b1d956..c3165d1c9c 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -39,9 +39,7 @@ from contextlib import contextmanager
from typing import List # novm
import ruamel.yaml as yaml
-import six
from ruamel.yaml.error import MarkedYAMLError
-from six import iteritems
import llnl.util.lang
import llnl.util.tty as tty
@@ -358,7 +356,7 @@ class InternalConfigScope(ConfigScope):
def _process_dict_keyname_overrides(data):
"""Turn a trailing `:' in a key name into an override attribute."""
result = {}
- for sk, sv in iteritems(data):
+ for sk, sv in data.items():
if sk.endswith(":"):
key = syaml.syaml_str(sk[:-1])
key.override = True
@@ -973,7 +971,7 @@ def validate(data, schema, filename=None):
line_number = e.instance.lc.line + 1
else:
line_number = None
- raise six.raise_from(ConfigFormatError(e, data, filename, line_number), e)
+ raise ConfigFormatError(e, data, filename, line_number) from e
# return the validated data so that we can access the raw data
# mostly relevant for environments
return test_data
@@ -1140,7 +1138,7 @@ def merge_yaml(dest, source):
# come *before* dest in OrderdDicts
dest_keys = [dk for dk in dest.keys() if dk not in source]
- for sk, sv in iteritems(source):
+ for sk, sv in source.items():
# always remove the dest items. Python dicts do not overwrite
# keys on insert, so this ensures that source keys are copied
# into dest along with mark provenance (i.e., file/line info).
diff --git a/lib/spack/spack/cray_manifest.py b/lib/spack/spack/cray_manifest.py
index 631280c473..66dd33ce7c 100644
--- a/lib/spack/spack/cray_manifest.py
+++ b/lib/spack/spack/cray_manifest.py
@@ -7,7 +7,6 @@ import json
import jsonschema
import jsonschema.exceptions
-import six
import llnl.util.tty as tty
@@ -97,7 +96,7 @@ def spec_from_entry(entry):
continue
# Value could be a list (of strings), boolean, or string
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
variant_strs.append("{0}={1}".format(name, value))
else:
try:
@@ -169,10 +168,7 @@ def read(path, apply_updates):
jsonschema.validate(json_data, manifest_schema)
except (jsonschema.exceptions.ValidationError, decode_exception_type) as e:
- raise six.raise_from(
- ManifestValidationError("error parsing manifest JSON:", str(e)),
- e,
- )
+ raise ManifestValidationError("error parsing manifest JSON:", str(e)) from e
specs = entries_to_specs(json_data["specs"])
tty.debug("{0}: {1} specs read from manifest".format(path, str(len(specs))))
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 74e2ec98c3..f74008e8f3 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -28,8 +28,6 @@ import sys
import time
from typing import Dict # novm
-import six
-
try:
import uuid
@@ -770,10 +768,7 @@ class Database(object):
with open(filename, "r") as f:
fdata = sjson.load(f)
except Exception as e:
- raise six.raise_from(
- CorruptDatabaseError("error parsing database:", str(e)),
- e,
- )
+ raise CorruptDatabaseError("error parsing database:", str(e)) from e
if fdata is None:
return
diff --git a/lib/spack/spack/dependency.py b/lib/spack/spack/dependency.py
index 1b38cd5092..bdf660fd1d 100644
--- a/lib/spack/spack/dependency.py
+++ b/lib/spack/spack/dependency.py
@@ -2,11 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-"""Data structures that represent Spack's dependency relationships.
-"""
-from six import string_types
-
+"""Data structures that represent Spack's dependency relationships."""
import spack.spec
#: The types of dependency relationships that Spack understands.
@@ -48,7 +44,7 @@ def canonical_deptype(deptype):
if deptype in ("all", all):
return all_deptypes
- elif isinstance(deptype, string_types):
+ elif isinstance(deptype, str):
if deptype not in all_deptypes:
raise ValueError("Invalid dependency type: %s" % deptype)
return (deptype,)
diff --git a/lib/spack/spack/detection/common.py b/lib/spack/spack/detection/common.py
index b9cd871fc2..8233f47eb8 100644
--- a/lib/spack/spack/detection/common.py
+++ b/lib/spack/spack/detection/common.py
@@ -20,8 +20,6 @@ import os.path
import re
import sys
-import six
-
import llnl.util.tty
import spack.config
@@ -115,7 +113,7 @@ def _convert_to_iterable(single_val_or_multiple):
x = single_val_or_multiple
if x is None:
return []
- elif isinstance(x, six.string_types):
+ elif isinstance(x, str):
return [x]
elif isinstance(x, spack.spec.Spec):
# Specs are iterable, but a single spec should be converted to a list
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 412e34bf05..cfaeeec9ab 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -34,8 +34,6 @@ import os.path
import re
from typing import List, Set # novm
-import six
-
import llnl.util.lang
import llnl.util.tty.color
@@ -234,7 +232,7 @@ class DirectiveMeta(type):
"""
global directive_names
- if isinstance(dicts, six.string_types):
+ if isinstance(dicts, str):
dicts = (dicts,)
if not isinstance(dicts, collections.abc.Sequence):
@@ -391,7 +389,7 @@ def _depends_on(pkg, spec, when=None, type=default_deptype, patches=None):
patches = [patches]
# auto-call patch() directive on any strings in patch list
- patches = [patch(p) if isinstance(p, six.string_types) else p for p in patches]
+ patches = [patch(p) if isinstance(p, str) else p for p in patches]
assert all(callable(p) for p in patches)
# this is where we actually add the dependency to this package
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 607f8bc39d..34ebb7d93d 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -12,8 +12,6 @@ import shutil
import sys
from contextlib import contextmanager
-import six
-
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@@ -363,12 +361,12 @@ class DirectoryLayout(object):
os.unlink(path)
os.remove(metapath)
except OSError as e:
- raise six.raise_from(RemoveFailedError(spec, path, e), e)
+ raise RemoveFailedError(spec, path, e) from e
elif os.path.exists(path):
try:
shutil.rmtree(path, **kwargs)
except OSError as e:
- raise six.raise_from(RemoveFailedError(spec, path, e), e)
+ raise RemoveFailedError(spec, path, e) from e
path = os.path.dirname(path)
while path != self.root:
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index f0598e5a83..6ac6908ff3 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -13,7 +13,6 @@ import sys
import time
import ruamel.yaml as yaml
-import six
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@@ -679,7 +678,7 @@ class Environment(object):
self.views = {}
elif with_view is True:
self.views = {default_view_name: ViewDescriptor(self.path, self.view_path_default)}
- elif isinstance(with_view, six.string_types):
+ elif isinstance(with_view, str):
self.views = {default_view_name: ViewDescriptor(self.path, with_view)}
# If with_view is None, then defer to the view settings determined by
# the manifest file
@@ -776,7 +775,7 @@ class Environment(object):
# enable_view can be boolean, string, or None
if enable_view is True or enable_view is None:
self.views = {default_view_name: ViewDescriptor(self.path, self.view_path_default)}
- elif isinstance(enable_view, six.string_types):
+ elif isinstance(enable_view, str):
self.views = {default_view_name: ViewDescriptor(self.path, enable_view)}
elif enable_view:
path = self.path
@@ -2096,16 +2095,14 @@ class Environment(object):
ayl[name][:] = [
s
for s in ayl.setdefault(name, [])
- if (not isinstance(s, six.string_types))
- or s.startswith("$")
- or Spec(s) in speclist.specs
+ if (not isinstance(s, str)) or s.startswith("$") or Spec(s) in speclist.specs
]
# Put the new specs into the first active list from the yaml
new_specs = [
entry
for entry in speclist.yaml_list
- if isinstance(entry, six.string_types)
+ if isinstance(entry, str)
and not any(entry in ayl[name] for ayl in active_yaml_lists)
]
list_for_new_specs = active_yaml_lists[0].setdefault(name, [])
@@ -2181,7 +2178,7 @@ def yaml_equivalent(first, second):
elif isinstance(first, list):
return isinstance(second, list) and _equiv_list(first, second)
else: # it's a string
- return isinstance(second, six.string_types) and first == second
+ return isinstance(second, str) and first == second
def _equiv_list(first, second):
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index df993978af..3b908054e3 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -29,11 +29,9 @@ import os.path
import re
import shutil
import sys
+import urllib.parse
from typing import List, Optional # novm
-import six
-import six.moves.urllib.parse as urllib_parse
-
import llnl.util
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@@ -322,7 +320,7 @@ class URLFetchStrategy(FetchStrategy):
# This must be skipped on Windows due to URL encoding
# of ':' characters on filepaths on Windows
if sys.platform != "win32" and url.startswith("file://"):
- path = urllib_parse.quote(url[len("file://") :])
+ path = urllib.parse.quote(url[len("file://") :])
url = "file://" + path
urls.append(url)
@@ -620,7 +618,7 @@ class VCSFetchStrategy(FetchStrategy):
patterns = kwargs.get("exclude", None)
if patterns is not None:
- if isinstance(patterns, six.string_types):
+ if isinstance(patterns, str):
patterns = [patterns]
for p in patterns:
tar.add_default_arg("--exclude=%s" % p)
@@ -1607,7 +1605,7 @@ def from_url_scheme(url, *args, **kwargs):
in the given url."""
url = kwargs.get("url", url)
- parsed_url = urllib_parse.urlparse(url, scheme="file")
+ parsed_url = urllib.parse.urlparse(url, scheme="file")
scheme_mapping = kwargs.get("scheme_mapping") or {
"file": "url",
diff --git a/lib/spack/spack/gcs_handler.py b/lib/spack/spack/gcs_handler.py
index 13121be603..4b547a78dc 100644
--- a/lib/spack/spack/gcs_handler.py
+++ b/lib/spack/spack/gcs_handler.py
@@ -2,8 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-import six.moves.urllib.response as urllib_response
+import urllib.response
import spack.util.url as url_util
import spack.util.web as web_util
@@ -21,4 +20,4 @@ def gcs_open(req, *args, **kwargs):
stream = gcsblob.get_blob_byte_stream()
headers = gcsblob.get_blob_headers()
- return urllib_response.addinfourl(stream, headers, url)
+ return urllib.response.addinfourl(stream, headers, url)
diff --git a/lib/spack/spack/install_test.py b/lib/spack/spack/install_test.py
index 130dca088a..24764a28c9 100644
--- a/lib/spack/spack/install_test.py
+++ b/lib/spack/spack/install_test.py
@@ -8,8 +8,6 @@ import os
import re
import shutil
-import six
-
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@@ -434,10 +432,7 @@ class TestSuite(object):
test_suite._hash = content_hash
return test_suite
except Exception as e:
- raise six.raise_from(
- sjson.SpackJSONError("error parsing JSON TestSuite:", str(e)),
- e,
- )
+ raise sjson.SpackJSONError("error parsing JSON TestSuite:", str(e)) from e
def _add_msg_to_file(filename, msg):
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 252c799304..41860ced19 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -2,7 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
"""
This module encapsulates package installation functionality.
@@ -30,6 +29,7 @@ installations of packages in a Spack instance.
import copy
import glob
import heapq
+import io
import itertools
import os
import shutil
@@ -37,8 +37,6 @@ import sys
import time
from collections import defaultdict
-import six
-
import llnl.util.filesystem as fs
import llnl.util.lock as lk
import llnl.util.tty as tty
@@ -594,7 +592,7 @@ def log(pkg):
# Finally, archive files that are specific to each package
with fs.working_dir(pkg.stage.path):
- errors = six.StringIO()
+ errors = io.StringIO()
target_dir = os.path.join(spack.store.layout.metadata_path(pkg.spec), "archived-files")
for glob_expr in pkg.builder.archive_files:
diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py
index 58785d8390..2ef78e07f9 100644
--- a/lib/spack/spack/main.py
+++ b/lib/spack/spack/main.py
@@ -12,6 +12,7 @@ from __future__ import print_function
import argparse
import inspect
+import io
import operator
import os
import os.path
@@ -23,8 +24,6 @@ import sys
import traceback
import warnings
-from six import StringIO
-
import archspec.cpu
import llnl.util.lang
@@ -700,7 +699,7 @@ class SpackCommand(object):
prepend + [self.command_name] + list(argv)
)
- out = StringIO()
+ out = io.StringIO()
try:
with log_output(out):
self.returncode = _invoke_command(self.command, self.parser, args, unknown)
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index 41853c39b9..8e914306e0 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -19,7 +19,6 @@ import sys
import traceback
import ruamel.yaml.error as yaml_error
-import six
import llnl.util.tty as tty
from llnl.util.filesystem import mkdirp
@@ -37,7 +36,7 @@ from spack.version import VersionList
def _is_string(url):
- return isinstance(url, six.string_types)
+ return isinstance(url, str)
def _display_mirror_entry(size, name, url, type_=None):
@@ -78,10 +77,7 @@ class Mirror(object):
data = syaml.load(stream)
return Mirror.from_dict(data, name)
except yaml_error.MarkedYAMLError as e:
- raise six.raise_from(
- syaml.SpackYAMLError("error parsing YAML mirror:", str(e)),
- e,
- )
+ raise syaml.SpackYAMLError("error parsing YAML mirror:", str(e)) from e
@staticmethod
def from_json(stream, name=None):
@@ -89,10 +85,7 @@ class Mirror(object):
d = sjson.load(stream)
return Mirror.from_dict(d, name)
except Exception as e:
- raise six.raise_from(
- sjson.SpackJSONError("error parsing JSON mirror:", str(e)),
- e,
- )
+ raise sjson.SpackJSONError("error parsing JSON mirror:", str(e)) from e
def to_dict(self):
if self._push_url is None:
@@ -102,7 +95,7 @@ class Mirror(object):
@staticmethod
def from_dict(d, name=None):
- if isinstance(d, six.string_types):
+ if isinstance(d, str):
return Mirror(d, name=name)
else:
return Mirror(d["fetch"], d["push"], name=name)
@@ -257,10 +250,7 @@ class MirrorCollection(collections.abc.Mapping):
data = syaml.load(stream)
return MirrorCollection(data)
except yaml_error.MarkedYAMLError as e:
- raise six.raise_from(
- syaml.SpackYAMLError("error parsing YAML mirror collection:", str(e)),
- e,
- )
+ raise syaml.SpackYAMLError("error parsing YAML mirror collection:", str(e)) from e
@staticmethod
def from_json(stream, name=None):
@@ -268,10 +258,7 @@ class MirrorCollection(collections.abc.Mapping):
d = sjson.load(stream)
return MirrorCollection(d)
except Exception as e:
- raise six.raise_from(
- sjson.SpackJSONError("error parsing JSON mirror collection:", str(e)),
- e,
- )
+ raise sjson.SpackJSONError("error parsing JSON mirror collection:", str(e)) from e
def to_dict(self, recursive=False):
return syaml_dict(
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index 957b947f79..81fbe86ee0 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -2,7 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
"""This is where most of the action happens in Spack.
The spack package class structure is based strongly on Homebrew
@@ -18,6 +17,7 @@ import functools
import glob
import hashlib
import inspect
+import io
import os
import re
import shutil
@@ -29,8 +29,6 @@ import types
import warnings
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type # novm
-import six
-
import llnl.util.filesystem as fsys
import llnl.util.tty as tty
from llnl.util.lang import classproperty, memoized, nullcontext
@@ -130,7 +128,7 @@ def preferred_version(pkg):
return sorted(pkg.versions, key=key_fn).pop()
-class WindowsRPathMeta(object):
+class WindowsRPath(object):
"""Collection of functionality surrounding Windows RPATH specific features
This is essentially meaningless for all other platforms
@@ -256,7 +254,7 @@ class DetectablePackageMeta(object):
variants = [variants]
for variant in variants:
- if isinstance(variant, six.string_types):
+ if isinstance(variant, str):
variant = (variant, {})
variant_str, extra_attributes = variant
spec_str = "{0}@{1} {2}".format(cls.name, version_str, variant_str)
@@ -443,7 +441,7 @@ def test_log_pathname(test_stage, spec):
return os.path.join(test_stage, "test-{0}-out.txt".format(TestSuite.test_pkg_id(spec)))
-class PackageBase(six.with_metaclass(PackageMeta, WindowsRPathMeta, PackageViewMixin, object)):
+class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
"""This is the superclass for all spack packages.
***The Package class***
@@ -1870,7 +1868,7 @@ class PackageBase(six.with_metaclass(PackageMeta, WindowsRPathMeta, PackageViewM
be copied to the corresponding location(s) under the install
testing directory.
"""
- paths = [srcs] if isinstance(srcs, six.string_types) else srcs
+ paths = [srcs] if isinstance(srcs, str) else srcs
for path in paths:
src_path = os.path.join(self.stage.source_path, path)
@@ -2000,7 +1998,7 @@ class PackageBase(six.with_metaclass(PackageMeta, WindowsRPathMeta, PackageViewM
print(line.rstrip("\n"))
if exc_type is spack.util.executable.ProcessError:
- out = six.StringIO()
+ out = io.StringIO()
spack.build_environment.write_log_summary(
out, "test", self.test_log_file, last=1
)
@@ -2022,9 +2020,9 @@ class PackageBase(six.with_metaclass(PackageMeta, WindowsRPathMeta, PackageViewM
return False
def _run_test_helper(self, runner, options, expected, status, installed, purpose):
- status = [status] if isinstance(status, six.integer_types) else status
- expected = [expected] if isinstance(expected, six.string_types) else expected
- options = [options] if isinstance(options, six.string_types) else options
+ status = [status] if isinstance(status, int) else status
+ expected = [expected] if isinstance(expected, str) else expected
+ options = [options] if isinstance(options, str) else options
if purpose:
tty.msg(purpose)
@@ -2365,7 +2363,7 @@ class PackageBase(six.with_metaclass(PackageMeta, WindowsRPathMeta, PackageViewM
doc = re.sub(r"\s+", " ", cls.__doc__)
lines = textwrap.wrap(doc, 72)
- results = six.StringIO()
+ results = io.StringIO()
for line in lines:
results.write((" " * indent) + line + "\n")
return results.getvalue()
diff --git a/lib/spack/spack/package_prefs.py b/lib/spack/spack/package_prefs.py
index 48d1ca129d..79beaba492 100644
--- a/lib/spack/spack/package_prefs.py
+++ b/lib/spack/spack/package_prefs.py
@@ -4,8 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import stat
-from six import string_types
-
import spack.error
import spack.repo
from spack.config import ConfigError
@@ -144,7 +142,7 @@ class PackagePrefs(object):
break
# allow variants to be list or string
- if not isinstance(variants, string_types):
+ if not isinstance(variants, str):
variants = " ".join(variants)
# Only return variants that are actually supported by the package
diff --git a/lib/spack/spack/parse.py b/lib/spack/spack/parse.py
index 61260bc837..c967dc709d 100644
--- a/lib/spack/spack/parse.py
+++ b/lib/spack/spack/parse.py
@@ -8,8 +8,6 @@ import re
import shlex
import sys
-from six import string_types
-
import spack.error
import spack.util.path as sp
@@ -147,7 +145,7 @@ class Parser(object):
sys.exit(1)
def setup(self, text):
- if isinstance(text, string_types):
+ if isinstance(text, str):
# shlex does not handle Windows path
# separators, so we must normalize to posix
text = sp.convert_to_posix_path(text)
diff --git a/lib/spack/spack/provider_index.py b/lib/spack/spack/provider_index.py
index 254492fc21..1ffd19236b 100644
--- a/lib/spack/spack/provider_index.py
+++ b/lib/spack/spack/provider_index.py
@@ -5,8 +5,6 @@
"""Classes and functions to manage providers of virtual dependencies"""
import itertools
-import six
-
import spack.error
import spack.util.spack_json as sjson
@@ -66,7 +64,7 @@ class _IndexBase(object):
"""
result = set()
# Allow string names to be passed as input, as well as specs
- if isinstance(virtual_spec, six.string_types):
+ if isinstance(virtual_spec, str):
virtual_spec = spack.spec.Spec(virtual_spec)
# Add all the providers that satisfy the vpkg spec.
@@ -174,7 +172,7 @@ class ProviderIndex(_IndexBase):
assert not self.repository.is_virtual_safe(spec.name), msg
pkg_provided = self.repository.get_pkg_class(spec.name).provided
- for provided_spec, provider_specs in six.iteritems(pkg_provided):
+ for provided_spec, provider_specs in pkg_provided.items():
for provider_spec_readonly in provider_specs:
# TODO: fix this comment.
# We want satisfaction other than flags
@@ -310,7 +308,7 @@ def _transform(providers, transform_fun, out_mapping_type=dict):
def mapiter(mappings):
if isinstance(mappings, dict):
- return six.iteritems(mappings)
+ return mappings.items()
else:
return iter(mappings)
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py
index e8c593f948..78b9f62b96 100644
--- a/lib/spack/spack/repo.py
+++ b/lib/spack/spack/repo.py
@@ -27,7 +27,6 @@ import uuid
from typing import Dict # novm
import ruamel.yaml as yaml
-import six
import llnl.util.filesystem as fs
import llnl.util.lang
@@ -450,8 +449,7 @@ class FastPackageChecker(collections.abc.Mapping):
return len(self._packages_to_stats)
-@six.add_metaclass(abc.ABCMeta)
-class Indexer(object):
+class Indexer(metaclass=abc.ABCMeta):
"""Adaptor for indexes that need to be generated when repos are updated."""
def __init__(self, repository):
@@ -678,7 +676,7 @@ class RepoPath(object):
# Add each repo to this path.
for repo in repos:
try:
- if isinstance(repo, six.string_types):
+ if isinstance(repo, str):
repo = Repo(repo, cache=cache)
self.put_last(repo)
except RepoError as e:
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
index 2c57306412..413fc0626b 100644
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -12,10 +12,8 @@ import re
import socket
import time
import xml.sax.saxutils
-
-from six import iteritems, text_type
-from six.moves.urllib.parse import urlencode
-from six.moves.urllib.request import HTTPHandler, Request, build_opener
+from urllib.parse import urlencode
+from urllib.request import HTTPHandler, Request, build_opener
import llnl.util.tty as tty
from llnl.util.filesystem import working_dir
@@ -158,7 +156,7 @@ class CDash(Reporter):
if cdash_phase not in phases_encountered:
phases_encountered.append(cdash_phase)
report_data[cdash_phase]["loglines"].append(
- text_type("{0} output for {1}:".format(cdash_phase, package["name"]))
+ str("{0} output for {1}:".format(cdash_phase, package["name"]))
)
elif cdash_phase:
report_data[cdash_phase]["loglines"].append(xml.sax.saxutils.escape(line))
@@ -289,7 +287,7 @@ class CDash(Reporter):
# Generate a report for this package.
# The first line just says "Testing package name-hash"
report_data["test"]["loglines"].append(
- text_type("{0} output for {1}:".format("test", package["name"]))
+ str("{0} output for {1}:".format("test", package["name"]))
)
for line in package["stdout"].splitlines()[1:]:
report_data["test"]["loglines"].append(xml.sax.saxutils.escape(line))
@@ -502,7 +500,7 @@ class CDash(Reporter):
def finalize_report(self):
if self.buildIds:
tty.msg("View your build results here:")
- for package_name, buildid in iteritems(self.buildIds):
+ for package_name, buildid in self.buildIds.items():
# Construct and display a helpful link if CDash responded with
# a buildId.
build_url = self.cdash_upload_url
diff --git a/lib/spack/spack/s3_handler.py b/lib/spack/spack/s3_handler.py
index c867642603..74eb8466ce 100644
--- a/lib/spack/spack/s3_handler.py
+++ b/lib/spack/spack/s3_handler.py
@@ -3,13 +3,11 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import urllib.error
+import urllib.request
+import urllib.response
from io import BufferedReader, IOBase
-import six
-import six.moves.urllib.error as urllib_error
-import six.moves.urllib.request as urllib_request
-import six.moves.urllib.response as urllib_response
-
import spack.util.s3 as s3_util
import spack.util.url as url_util
@@ -63,32 +61,32 @@ def _s3_open(url):
return url, headers, stream
-class UrllibS3Handler(urllib_request.HTTPSHandler):
+class UrllibS3Handler(urllib.request.HTTPSHandler):
def s3_open(self, req):
orig_url = req.get_full_url()
from botocore.exceptions import ClientError # type: ignore[import]
try:
url, headers, stream = _s3_open(orig_url)
- return urllib_response.addinfourl(stream, headers, url)
+ return urllib.response.addinfourl(stream, headers, url)
except ClientError as err:
# if no such [KEY], but [KEY]/index.html exists,
# return that, instead.
if err.response["Error"]["Code"] == "NoSuchKey":
try:
_, headers, stream = _s3_open(url_util.join(orig_url, "index.html"))
- return urllib_response.addinfourl(stream, headers, orig_url)
+ return urllib.response.addinfourl(stream, headers, orig_url)
except ClientError as err2:
if err.response["Error"]["Code"] == "NoSuchKey":
# raise original error
- raise six.raise_from(urllib_error.URLError(err), err)
+ raise urllib.error.URLError(err) from err
- raise six.raise_from(urllib_error.URLError(err2), err2)
+ raise urllib.error.URLError(err2) from err2
- raise six.raise_from(urllib_error.URLError(err), err)
+ raise urllib.error.URLError(err) from err
-S3OpenerDirector = urllib_request.build_opener(UrllibS3Handler())
+S3OpenerDirector = urllib.request.build_opener(UrllibS3Handler())
open = S3OpenerDirector.open
diff --git a/lib/spack/spack/schema/__init__.py b/lib/spack/spack/schema/__init__.py
index 54f645fd5c..33d930e2c6 100644
--- a/lib/spack/spack/schema/__init__.py
+++ b/lib/spack/spack/schema/__init__.py
@@ -3,11 +3,8 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""This module contains jsonschema files for all of Spack's YAML formats."""
-
import warnings
-import six
-
import llnl.util.lang
import llnl.util.tty
@@ -45,7 +42,7 @@ def _make_validator():
# Retrieve the template message
msg_str_or_func = deprecated["message"]
- if isinstance(msg_str_or_func, six.string_types):
+ if isinstance(msg_str_or_func, str):
msg = msg_str_or_func.format(properties=deprecated_properties)
else:
msg = msg_str_or_func(instance, deprecated_properties)
diff --git a/lib/spack/spack/schema/config.py b/lib/spack/spack/schema/config.py
index 96e34a051a..240f99e8b0 100644
--- a/lib/spack/spack/schema/config.py
+++ b/lib/spack/spack/schema/config.py
@@ -2,13 +2,11 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
"""Schema for config.yaml configuration file.
.. literalinclude:: _spack_root/lib/spack/spack/schema/config.py
:lines: 13-
"""
-import six
from llnl.util.lang import union_dicts
@@ -124,7 +122,7 @@ def update(data):
changed = False
install_tree = data.get("install_tree", None)
- if isinstance(install_tree, six.string_types):
+ if isinstance(install_tree, str):
# deprecated short-form install tree
# add value as `root` in updated install_tree
data["install_tree"] = {"root": install_tree}
@@ -148,7 +146,7 @@ def update(data):
changed = True
shared_linking = data.get("shared_linking", None)
- if isinstance(shared_linking, six.string_types):
+ if isinstance(shared_linking, str):
# deprecated short-form shared_linking: rpath/runpath
# add value as `type` in updated shared_linking
data["shared_linking"] = {"type": shared_linking, "bind": False}
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 844252c97b..c070741c2c 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -14,8 +14,6 @@ import re
import types
import warnings
-from six import string_types
-
import archspec.cpu
try:
@@ -213,7 +211,7 @@ def build_criteria_names(costs, tuples):
def issequence(obj):
- if isinstance(obj, string_types):
+ if isinstance(obj, str):
return False
return isinstance(obj, (collections.abc.Sequence, types.GeneratorType))
@@ -225,7 +223,7 @@ def listify(args):
def packagize(pkg):
- if isinstance(pkg, string_types):
+ if isinstance(pkg, str):
return spack.repo.path.get_pkg_class(pkg)
else:
return pkg
@@ -949,7 +947,7 @@ class SpackSolverSetup(object):
"""Manipulate requirements from packages.yaml, and return a list of tuples
with a uniform structure (name, policy, requirements).
"""
- if isinstance(requirements, string_types):
+ if isinstance(requirements, str):
rules = [(pkg_name, "one_of", [requirements])]
else:
rules = []
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 015c5b8061..401be97858 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -81,6 +81,7 @@ expansion when it is the first character in an id typed on the command line.
"""
import collections
import collections.abc
+import io
import itertools
import os
import re
@@ -88,7 +89,6 @@ import sys
import warnings
import ruamel.yaml as yaml
-import six
import llnl.util.filesystem as fs
import llnl.util.lang as lang
@@ -274,11 +274,11 @@ class ArchSpec(object):
other = spec_or_platform_tuple
platform_tuple = other.platform, other.os, other.target
- elif isinstance(spec_or_platform_tuple, (six.string_types, tuple)):
+ elif isinstance(spec_or_platform_tuple, (str, tuple)):
spec_fields = spec_or_platform_tuple
# Normalize the string to a tuple
- if isinstance(spec_or_platform_tuple, six.string_types):
+ if isinstance(spec_or_platform_tuple, str):
spec_fields = spec_or_platform_tuple.split("-")
if len(spec_fields) != 3:
msg = "cannot construct an ArchSpec from {0!s}"
@@ -534,7 +534,6 @@ class ArchSpec(object):
@property
def concrete(self):
"""True if the spec is concrete, False otherwise"""
- # return all(v for k, v in six.iteritems(self.to_cmp_dict()))
return self.platform and self.os and self.target and self.target_concrete
@property
@@ -584,7 +583,7 @@ class CompilerSpec(object):
arg = args[0]
# If there is one argument, it's either another CompilerSpec
# to copy or a string to parse
- if isinstance(arg, six.string_types):
+ if isinstance(arg, str):
c = SpecParser().parse_compiler(arg)
self.name = c.name
self.versions = c.versions
@@ -1335,7 +1334,7 @@ class Spec(object):
# Build spec should be the actual build spec unless marked dirty.
self._build_spec = None
- if isinstance(spec_like, six.string_types):
+ if isinstance(spec_like, str):
spec_list = SpecParser(self).parse(spec_like)
if len(spec_list) > 1:
raise ValueError("More than one spec in string: " + spec_like)
@@ -1538,7 +1537,7 @@ class Spec(object):
new_vals = tuple(kwargs.get(arg, None) for arg in arch_attrs)
self.architecture = ArchSpec(new_vals)
else:
- new_attrvals = [(a, v) for a, v in six.iteritems(kwargs) if a in arch_attrs]
+ new_attrvals = [(a, v) for a, v in kwargs.items() if a in arch_attrs]
for new_attr, new_value in new_attrvals:
if getattr(self.architecture, new_attr):
raise DuplicateArchitectureError(
@@ -1932,9 +1931,7 @@ class Spec(object):
package_hash = self._package_hash
# Full hashes are in bytes
- if not isinstance(package_hash, six.text_type) and isinstance(
- package_hash, six.binary_type
- ):
+ if not isinstance(package_hash, str) and isinstance(package_hash, bytes):
package_hash = package_hash.decode("utf-8")
d["package_hash"] = package_hash
@@ -2204,7 +2201,7 @@ class Spec(object):
else:
elt = dep
dep_name = dep["name"]
- if isinstance(elt, six.string_types):
+ if isinstance(elt, str):
# original format, elt is just the dependency hash.
dep_hash, deptypes = elt, ["build", "link"]
elif isinstance(elt, tuple):
@@ -2390,7 +2387,7 @@ class Spec(object):
# Recurse on dependencies
for s, s_dependencies in dep_like.items():
- if isinstance(s, six.string_types):
+ if isinstance(s, str):
dag_node, dependency_types = name_and_dependency_types(s)
else:
dag_node, dependency_types = spec_and_dependency_types(s)
@@ -2469,10 +2466,7 @@ class Spec(object):
data = yaml.load(stream)
return Spec.from_dict(data)
except yaml.error.MarkedYAMLError as e:
- raise six.raise_from(
- syaml.SpackYAMLError("error parsing YAML spec:", str(e)),
- e,
- )
+ raise syaml.SpackYAMLError("error parsing YAML spec:", str(e)) from e
@staticmethod
def from_json(stream):
@@ -2485,10 +2479,7 @@ class Spec(object):
data = sjson.load(stream)
return Spec.from_dict(data)
except Exception as e:
- raise six.raise_from(
- sjson.SpackJSONError("error parsing JSON spec:", str(e)),
- e,
- )
+ raise sjson.SpackJSONError("error parsing JSON spec:", str(e)) from e
@staticmethod
def extract_json_from_clearsig(data):
@@ -3112,10 +3103,7 @@ class Spec(object):
# with inconsistent constraints. Users cannot produce
# inconsistent specs like this on the command line: the
# parser doesn't allow it. Spack must be broken!
- raise six.raise_from(
- InconsistentSpecError("Invalid Spec DAG: %s" % e.message),
- e,
- )
+ raise InconsistentSpecError("Invalid Spec DAG: %s" % e.message) from e
def index(self, deptype="all"):
"""Return a dictionary that points to all the dependencies in this
@@ -4214,7 +4202,7 @@ class Spec(object):
color = kwargs.get("color", False)
transform = kwargs.get("transform", {})
- out = six.StringIO()
+ out = io.StringIO()
def write(s, c=None):
f = clr.cescape(s)
@@ -4437,7 +4425,7 @@ class Spec(object):
token_transforms = dict((k.upper(), v) for k, v in kwargs.get("transform", {}).items())
length = len(format_string)
- out = six.StringIO()
+ out = io.StringIO()
named = escape = compiler = False
named_str = fmt = ""
@@ -5153,7 +5141,7 @@ class SpecParser(spack.parse.Parser):
self.unexpected_token()
except spack.parse.ParseError as e:
- raise six.raise_from(SpecParseError(e), e)
+ raise SpecParseError(e) from e
# Generate lookups for git-commit-based versions
for spec in specs:
diff --git a/lib/spack/spack/spec_list.py b/lib/spack/spack/spec_list.py
index ffbf2bfaf9..cdc7796dcc 100644
--- a/lib/spack/spack/spec_list.py
+++ b/lib/spack/spack/spec_list.py
@@ -4,8 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import itertools
-from six import string_types
-
import spack.variant
from spack.error import SpackError
from spack.spec import Spec
@@ -21,7 +19,7 @@ class SpecList(object):
self._reference = reference # TODO: Do we need defensive copy here?
# Validate yaml_list before assigning
- if not all(isinstance(s, string_types) or isinstance(s, (list, dict)) for s in yaml_list):
+ if not all(isinstance(s, str) or isinstance(s, (list, dict)) for s in yaml_list):
raise ValueError(
"yaml_list can contain only valid YAML types! Found:\n %s"
% [type(s) for s in yaml_list]
@@ -91,7 +89,7 @@ class SpecList(object):
remove = [
s
for s in self.yaml_list
- if (isinstance(s, string_types) and not s.startswith("$")) and Spec(s) == Spec(spec)
+ if (isinstance(s, str) and not s.startswith("$")) and Spec(s) == Spec(spec)
]
if not remove:
msg = "Cannot remove %s from SpecList %s\n" % (spec, self.name)
@@ -145,7 +143,7 @@ class SpecList(object):
for item in yaml:
# if it's a reference, expand it
- if isinstance(item, string_types) and item.startswith("$"):
+ if isinstance(item, str) and item.startswith("$"):
# replace the reference and apply the sigil if needed
name, sigil = self._parse_reference(item)
referent = [
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index 62e05d504e..ee9f8a122b 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -16,8 +16,6 @@ import sys
import tempfile
from typing import Dict # novm
-from six import iteritems, string_types
-
import llnl.util.lang
import llnl.util.tty as tty
from llnl.util.filesystem import (
@@ -171,7 +169,7 @@ def get_stage_root():
if _stage_root is None:
candidates = spack.config.get("config:build_stage")
- if isinstance(candidates, string_types):
+ if isinstance(candidates, str):
candidates = [candidates]
resolved_candidates = _resolve_paths(candidates)
@@ -288,7 +286,7 @@ class Stage(object):
"""
# TODO: fetch/stage coupling needs to be reworked -- the logic
# TODO: here is convoluted and not modular enough.
- if isinstance(url_or_fetch_strategy, string_types):
+ if isinstance(url_or_fetch_strategy, str):
self.fetcher = fs.from_url_scheme(url_or_fetch_strategy)
elif isinstance(url_or_fetch_strategy, fs.FetchStrategy):
self.fetcher = url_or_fetch_strategy
@@ -709,7 +707,7 @@ class ResourceStage(Stage):
else:
raise
- for key, value in iteritems(placement):
+ for key, value in placement.items():
destination_path = os.path.join(target_path, value)
source_path = os.path.join(self.source_path, key)
@@ -903,7 +901,7 @@ def get_checksums_for_versions(url_dict, name, **kwargs):
"",
*llnl.util.lang.elide_list(
["{0:{1}} {2}".format(str(v), max_len, url_dict[v]) for v in sorted_versions]
- )
+ ),
)
print()
diff --git a/lib/spack/spack/store.py b/lib/spack/spack/store.py
index 4e38d0c634..d9440f2aed 100644
--- a/lib/spack/spack/store.py
+++ b/lib/spack/spack/store.py
@@ -21,8 +21,6 @@ import contextlib
import os
import re
-import six
-
import llnl.util.lang
import llnl.util.tty as tty
@@ -69,7 +67,7 @@ def parse_install_tree(config_dict):
install_tree = config_dict.get("install_tree", {})
padded_length = False
- if isinstance(install_tree, six.string_types):
+ if isinstance(install_tree, str):
tty.warn("Using deprecated format for configuring install_tree")
unpadded_root = install_tree
unpadded_root = spack.util.path.canonicalize_path(unpadded_root)
@@ -309,7 +307,7 @@ def find(constraints, multiple=False, query_fn=None, **kwargs):
List of matching specs
"""
# Normalize input to list of specs
- if isinstance(constraints, six.string_types):
+ if isinstance(constraints, str):
constraints = [spack.spec.Spec(constraints)]
matching_specs, errors = [], []
diff --git a/lib/spack/spack/target.py b/lib/spack/spack/target.py
index d51ca3aa99..fd8830fffd 100644
--- a/lib/spack/spack/target.py
+++ b/lib/spack/spack/target.py
@@ -5,8 +5,6 @@
import functools
import warnings
-import six
-
import archspec.cpu
import llnl.util.tty as tty
@@ -24,7 +22,7 @@ def _ensure_other_is_target(method):
@functools.wraps(method)
def _impl(self, other):
- if isinstance(other, six.string_types):
+ if isinstance(other, str):
other = Target(other)
if not isinstance(other, Target):
@@ -95,7 +93,7 @@ class Target(object):
def from_dict_or_value(dict_or_value):
# A string here represents a generic target (like x86_64 or ppc64) or
# a custom micro-architecture
- if isinstance(dict_or_value, six.string_types):
+ if isinstance(dict_or_value, str):
return Target(dict_or_value)
# TODO: From a dict we actually retrieve much more information than
diff --git a/lib/spack/spack/tengine.py b/lib/spack/spack/tengine.py
index 75dae5c9c1..0965dc0179 100644
--- a/lib/spack/spack/tengine.py
+++ b/lib/spack/spack/tengine.py
@@ -6,8 +6,6 @@ import itertools
import textwrap
from typing import List # novm
-import six
-
import llnl.util.lang
import spack.config
@@ -57,7 +55,7 @@ class ContextMeta(type):
context_property = ContextMeta.context_property
-class Context(six.with_metaclass(ContextMeta, object)):
+class Context(metaclass=ContextMeta):
"""Base class for context classes that are used with the template
engine.
"""
diff --git a/lib/spack/spack/test/cmd/build_env.py b/lib/spack/spack/test/cmd/build_env.py
index 16d363eff4..2ba9a008dc 100644
--- a/lib/spack/spack/test/cmd/build_env.py
+++ b/lib/spack/spack/test/cmd/build_env.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 pickle
import pytest
-from six.moves import cPickle
from spack.main import SpackCommand
@@ -52,6 +52,6 @@ def test_dump(tmpdir):
def test_pickle(tmpdir):
with tmpdir.as_cwd():
build_env("--pickle", _out_file, "zlib")
- environment = cPickle.load(open(_out_file, "rb"))
+ environment = pickle.load(open(_out_file, "rb"))
assert type(environment) == dict
assert "PATH" in environment
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index 9611ae5748..64aaf3c225 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -4,13 +4,13 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import filecmp
import glob
+import io
import os
import shutil
import sys
from argparse import Namespace
import pytest
-from six import StringIO
import llnl.util.filesystem as fs
import llnl.util.link_tree
@@ -507,7 +507,7 @@ def test_env_repo():
def test_user_removed_spec():
"""Ensure a user can remove from any position in the spack.yaml file."""
- initial_yaml = StringIO(
+ initial_yaml = io.StringIO(
"""\
env:
specs:
@@ -545,7 +545,7 @@ env:
def test_init_from_lockfile(tmpdir):
"""Test that an environment can be instantiated from a lockfile."""
- initial_yaml = StringIO(
+ initial_yaml = io.StringIO(
"""\
env:
specs:
@@ -573,7 +573,7 @@ env:
def test_init_from_yaml(tmpdir):
"""Test that an environment can be instantiated from a lockfile."""
- initial_yaml = StringIO(
+ initial_yaml = io.StringIO(
"""\
env:
specs:
@@ -602,7 +602,7 @@ def test_env_view_external_prefix(tmpdir_factory, mutable_database, mock_package
fake_bin = fake_prefix.join("bin")
fake_bin.ensure(dir=True)
- initial_yaml = StringIO(
+ initial_yaml = io.StringIO(
"""\
env:
specs:
@@ -611,7 +611,7 @@ env:
"""
)
- external_config = StringIO(
+ external_config = io.StringIO(
"""\
packages:
a:
@@ -682,7 +682,7 @@ env:
mpileaks:
version: [2.2]
"""
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
with e:
@@ -699,7 +699,7 @@ spack:
- /no/such/directory
- no/such/file.yaml
"""
- _env_create(env_name, StringIO(test_config))
+ _env_create(env_name, io.StringIO(test_config))
e = ev.read(env_name)
with pytest.raises(spack.config.ConfigFileError) as exc:
@@ -723,7 +723,7 @@ def test_env_with_include_config_files_same_basename():
[libelf, mpileaks]
"""
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
fs.mkdirp(os.path.join(e.path, "path", "to"))
@@ -788,7 +788,7 @@ def test_env_with_included_config_file(packages_file):
include_filename = "included-config.yaml"
test_config = mpileaks_env_config(os.path.join(".", include_filename))
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
included_path = os.path.join(e.path, include_filename)
@@ -842,7 +842,7 @@ def test_env_with_included_config_scope(tmpdir, packages_file):
test_config = mpileaks_env_config(config_scope_path)
# Create the environment
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
@@ -868,7 +868,7 @@ def test_env_with_included_config_var_path(packages_file):
config_var_path = os.path.join("$tempdir", "included-config.yaml")
test_config = mpileaks_env_config(config_var_path)
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
config_real_path = substitute_path_variables(config_var_path)
@@ -893,7 +893,7 @@ env:
specs:
- mpileaks
"""
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
with open(os.path.join(e.path, "included-config.yaml"), "w") as f:
@@ -926,7 +926,7 @@ env:
specs:
- mpileaks
"""
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
e = ev.read("test")
with open(os.path.join(e.path, "high-config.yaml"), "w") as f:
@@ -1263,7 +1263,7 @@ env:
specs:
- mpileaks
"""
- _env_create("test", StringIO(test_config))
+ _env_create("test", io.StringIO(test_config))
with ev.read("test"):
install("--fake")
@@ -2672,7 +2672,7 @@ spack:
roots:
tcl: modules
"""
- _env_create("test", StringIO(spack_yaml))
+ _env_create("test", io.StringIO(spack_yaml))
with ev.read("test") as e:
install()
@@ -2707,7 +2707,7 @@ spack:
roots:
tcl: full_modules
"""
- _env_create("test", StringIO(spack_yaml))
+ _env_create("test", io.StringIO(spack_yaml))
with ev.read("test") as e:
install()
@@ -3116,7 +3116,7 @@ def test_environment_depfile_makefile(depfile_flags, expected_installs, tmpdir,
makefile,
"--make-disable-jobserver",
"--make-target-prefix=prefix",
- *depfile_flags
+ *depfile_flags,
)
# Do make dry run.
diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py
index 67e0dd3f80..d1993be777 100644
--- a/lib/spack/spack/test/cmd/install.py
+++ b/lib/spack/spack/test/cmd/install.py
@@ -2,8 +2,8 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
import argparse
+import builtins
import filecmp
import itertools
import os
@@ -12,7 +12,6 @@ import sys
import time
import pytest
-from six.moves import builtins
import llnl.util.filesystem as fs
import llnl.util.tty as tty
diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py
index 4e03c9a288..598e44f4fc 100644
--- a/lib/spack/spack/test/compilers/basics.py
+++ b/lib/spack/spack/test/compilers/basics.py
@@ -9,7 +9,6 @@ import sys
from copy import copy
import pytest
-from six import iteritems
import llnl.util.filesystem as fs
@@ -73,7 +72,7 @@ def test_get_compiler_duplicates(config):
)
assert len(cfg_file_to_duplicates) == 1
- cfg_file, duplicates = next(iteritems(cfg_file_to_duplicates))
+ cfg_file, duplicates = next(iter(cfg_file_to_duplicates.items()))
assert len(duplicates) == 1
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index f8b1e44547..e310519afd 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -5,13 +5,13 @@
import collections
import getpass
+import io
import os
import sys
import tempfile
from datetime import date
import pytest
-from six import StringIO
import llnl.util.tty as tty
from llnl.util.filesystem import getuid, join_path, mkdirp, touch, touchp
@@ -1012,7 +1012,7 @@ def test_write_empty_single_file_scope(tmpdir):
def check_schema(name, file_contents):
"""Check a Spack YAML schema against some data"""
- f = StringIO(file_contents)
+ f = io.StringIO(file_contents)
data = syaml.load_config(f)
spack.config.validate(data, name)
diff --git a/lib/spack/spack/test/env.py b/lib/spack/spack/test/env.py
index 60056e397a..2de80c43e3 100644
--- a/lib/spack/spack/test/env.py
+++ b/lib/spack/spack/test/env.py
@@ -2,12 +2,11 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
"""Test environment internals without CLI"""
+import io
import sys
import pytest
-from six import StringIO
import spack.environment as ev
import spack.spec
@@ -79,7 +78,7 @@ env:
def test_env_change_spec_in_definition(tmpdir, mock_packages, config, mutable_mock_env_path):
- initial_yaml = StringIO(_test_matrix_yaml)
+ initial_yaml = io.StringIO(_test_matrix_yaml)
e = ev.create("test", initial_yaml)
e.concretize()
e.write()
@@ -96,7 +95,7 @@ def test_env_change_spec_in_definition(tmpdir, mock_packages, config, mutable_mo
def test_env_change_spec_in_matrix_raises_error(
tmpdir, mock_packages, config, mutable_mock_env_path
):
- initial_yaml = StringIO(_test_matrix_yaml)
+ initial_yaml = io.StringIO(_test_matrix_yaml)
e = ev.create("test", initial_yaml)
e.concretize()
e.write()
diff --git a/lib/spack/spack/test/graph.py b/lib/spack/spack/test/graph.py
index dc7181538e..b906548d7f 100644
--- a/lib/spack/spack/test/graph.py
+++ b/lib/spack/spack/test/graph.py
@@ -2,10 +2,10 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import io
import sys
import pytest
-import six
import spack.graph
import spack.repo
@@ -25,7 +25,7 @@ def test_static_graph_mpileaks(config, mock_packages):
"""Test a static spack graph for a simple package."""
s = spack.spec.Spec("mpileaks").normalized()
- stream = six.StringIO()
+ stream = io.StringIO()
spack.graph.graph_dot([s], static=True, out=stream)
dot = stream.getvalue()
@@ -52,7 +52,7 @@ def test_static_graph_mpileaks(config, mock_packages):
def test_dynamic_dot_graph_mpileaks(mock_packages, config):
"""Test dynamically graphing the mpileaks package."""
s = spack.spec.Spec("mpileaks").concretized()
- stream = six.StringIO()
+ stream = io.StringIO()
spack.graph.graph_dot([s], static=False, out=stream)
dot = stream.getvalue()
@@ -83,7 +83,7 @@ def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch):
monkeypatch.setattr(spack.graph.AsciiGraph, "_node_label", lambda self, node: node.name)
s = spack.spec.Spec("mpileaks").concretized()
- stream = six.StringIO()
+ stream = io.StringIO()
graph = spack.graph.AsciiGraph()
graph.write(s, out=stream, color=False)
graph_str = stream.getvalue()
diff --git a/lib/spack/spack/test/llnl/util/file_list.py b/lib/spack/spack/test/llnl/util/file_list.py
index a6a7ef3fa9..682dbc6e86 100644
--- a/lib/spack/spack/test/llnl/util/file_list.py
+++ b/lib/spack/spack/test/llnl/util/file_list.py
@@ -8,7 +8,6 @@ import os.path
import sys
import pytest
-import six
from llnl.util.filesystem import (
HeaderList,
@@ -320,7 +319,7 @@ def test_searching_order(search_fn, search_list, root, kwargs):
rlist = list(reversed(result))
# At this point make sure the search list is a sequence
- if isinstance(search_list, six.string_types):
+ if isinstance(search_list, str):
search_list = [search_list]
# Discard entries in the order they appear in search list
diff --git a/lib/spack/spack/test/provider_index.py b/lib/spack/spack/test/provider_index.py
index c698a7b87e..f840056798 100644
--- a/lib/spack/spack/test/provider_index.py
+++ b/lib/spack/spack/test/provider_index.py
@@ -18,7 +18,7 @@ Tests assume that mock packages provide this::
mpi@:10.0: set([zmpi])},
'stuff': {stuff: set([externalvirtual])}}
"""
-from six import StringIO
+import io
import spack.repo
from spack.provider_index import ProviderIndex
@@ -28,10 +28,10 @@ from spack.spec import Spec
def test_provider_index_round_trip(mock_packages):
p = ProviderIndex(specs=spack.repo.all_package_names(), repository=spack.repo.path)
- ostream = StringIO()
+ ostream = io.StringIO()
p.to_json(ostream)
- istream = StringIO(ostream.getvalue())
+ istream = io.StringIO(ostream.getvalue())
q = ProviderIndex.from_json(istream, repository=spack.repo.path)
assert p == q
diff --git a/lib/spack/spack/test/tag.py b/lib/spack/spack/test/tag.py
index 68414c1288..91d1418207 100644
--- a/lib/spack/spack/test/tag.py
+++ b/lib/spack/spack/test/tag.py
@@ -3,9 +3,9 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Tests for tag index cache files."""
+import io
import pytest
-from six import StringIO
import spack.cmd.install
import spack.tag
@@ -40,7 +40,7 @@ more_tags_json = """
def test_tag_copy(mock_packages):
- index = spack.tag.TagIndex.from_json(StringIO(tags_json), repository=mock_packages)
+ index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
new_index = index.copy()
assert index.tags == new_index.tags
@@ -100,25 +100,27 @@ def test_tag_index_round_trip(mock_packages):
mock_index = spack.repo.path.tag_index
assert mock_index.tags
- ostream = StringIO()
+ ostream = io.StringIO()
mock_index.to_json(ostream)
- istream = StringIO(ostream.getvalue())
+ istream = io.StringIO(ostream.getvalue())
new_index = spack.tag.TagIndex.from_json(istream, repository=mock_packages)
assert mock_index == new_index
def test_tag_equal(mock_packages):
- first_index = spack.tag.TagIndex.from_json(StringIO(tags_json), repository=mock_packages)
- second_index = spack.tag.TagIndex.from_json(StringIO(tags_json), repository=mock_packages)
+ first_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
+ second_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
assert first_index == second_index
def test_tag_merge(mock_packages):
- first_index = spack.tag.TagIndex.from_json(StringIO(tags_json), repository=mock_packages)
- second_index = spack.tag.TagIndex.from_json(StringIO(more_tags_json), repository=mock_packages)
+ first_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
+ second_index = spack.tag.TagIndex.from_json(
+ io.StringIO(more_tags_json), repository=mock_packages
+ )
assert first_index != second_index
@@ -139,14 +141,14 @@ def test_tag_merge(mock_packages):
def test_tag_not_dict(mock_packages):
list_json = "[]"
with pytest.raises(spack.tag.TagIndexError) as e:
- spack.tag.TagIndex.from_json(StringIO(list_json), repository=mock_packages)
+ spack.tag.TagIndex.from_json(io.StringIO(list_json), repository=mock_packages)
assert "not a dict" in str(e)
def test_tag_no_tags(mock_packages):
pkg_json = '{"packages": []}'
with pytest.raises(spack.tag.TagIndexError) as e:
- spack.tag.TagIndex.from_json(StringIO(pkg_json), repository=mock_packages)
+ spack.tag.TagIndex.from_json(io.StringIO(pkg_json), repository=mock_packages)
assert "does not start with" in str(e)
diff --git a/lib/spack/spack/test/util/unparse/unparse.py b/lib/spack/spack/test/util/unparse/unparse.py
index 82148c9dc8..986ba7e262 100644
--- a/lib/spack/spack/test/util/unparse/unparse.py
+++ b/lib/spack/spack/test/util/unparse/unparse.py
@@ -6,14 +6,9 @@ import ast
import codecs
import os
import sys
+import tokenize
import pytest
-import six
-
-if six.PY3:
- import tokenize
-else:
- from lib2to3.pgen2 import tokenize
import spack.util.unparse
@@ -25,14 +20,10 @@ pytestmark = pytest.mark.skipif(
def read_pyfile(filename):
"""Read and return the contents of a Python source file (as a
string), taking into account the file encoding."""
- if six.PY3:
- with open(filename, "rb") as pyfile:
- encoding = tokenize.detect_encoding(pyfile.readline)[0]
- with codecs.open(filename, "r", encoding=encoding) as pyfile:
- source = pyfile.read()
- else:
- with open(filename, "r") as pyfile:
- source = pyfile.read()
+ with open(filename, "rb") as pyfile:
+ encoding = tokenize.detect_encoding(pyfile.readline)[0]
+ with codecs.open(filename, "r", encoding=encoding) as pyfile:
+ source = pyfile.read()
return source
@@ -341,16 +332,9 @@ def test_huge_float():
check_ast_roundtrip("-1e1000j")
-@pytest.mark.skipif(not six.PY2, reason="Only works for Python 2")
-def test_min_int27():
- check_ast_roundtrip(str(-sys.maxint - 1))
- check_ast_roundtrip("-(%s)" % (sys.maxint + 1))
-
-
-@pytest.mark.skipif(not six.PY3, reason="Only works for Python 3")
def test_min_int30():
- check_ast_roundtrip(str(-(2 ** 31)))
- check_ast_roundtrip(str(-(2 ** 63)))
+ check_ast_roundtrip(str(-(2**31)))
+ check_ast_roundtrip(str(-(2**63)))
def test_imaginary_literals():
@@ -358,9 +342,6 @@ def test_imaginary_literals():
check_ast_roundtrip("-7j")
check_ast_roundtrip("0j")
check_ast_roundtrip("-0j")
- if six.PY2:
- check_ast_roundtrip("-(7j)")
- check_ast_roundtrip("-(0j)")
def test_negative_zero():
@@ -391,12 +372,11 @@ def test_function_arguments():
check_ast_roundtrip("def f(a, b = 2): pass")
check_ast_roundtrip("def f(a = 5, b = 2): pass")
check_ast_roundtrip("def f(*args, **kwargs): pass")
- if six.PY3:
- check_ast_roundtrip("def f(*, a = 1, b = 2): pass")
- check_ast_roundtrip("def f(*, a = 1, b): pass")
- check_ast_roundtrip("def f(*, a, b = 2): pass")
- check_ast_roundtrip("def f(a, b = None, *, c, **kwds): pass")
- check_ast_roundtrip("def f(a=2, *args, c=5, d, **kwds): pass")
+ check_ast_roundtrip("def f(*, a = 1, b = 2): pass")
+ check_ast_roundtrip("def f(*, a = 1, b): pass")
+ check_ast_roundtrip("def f(*, a, b = 2): pass")
+ check_ast_roundtrip("def f(a, b = None, *, c, **kwds): pass")
+ check_ast_roundtrip("def f(a=2, *args, c=5, d, **kwds): pass")
def test_relative_import():
@@ -407,12 +387,10 @@ def test_import_many():
check_ast_roundtrip(import_many)
-@pytest.mark.skipif(not six.PY3, reason="Only for Python 3")
def test_nonlocal():
check_ast_roundtrip(nonlocal_ex)
-@pytest.mark.skipif(not six.PY3, reason="Only for Python 3")
def test_raise_from():
check_ast_roundtrip(raise_from)
@@ -449,17 +427,11 @@ def test_joined_str_361():
check_ast_roundtrip('f"{key:4}={value!a:#06x}"')
-@pytest.mark.skipif(not six.PY2, reason="Only for Python 2")
-def test_repr():
- check_ast_roundtrip(a_repr)
-
-
@pytest.mark.skipif(sys.version_info[:2] < (3, 6), reason="Only for Python 3.6 or greater")
def test_complex_f_string():
check_ast_roundtrip(complex_f_string)
-@pytest.mark.skipif(not six.PY3, reason="Only for Python 3")
def test_annotations():
check_ast_roundtrip("def f(a : int): pass")
check_ast_roundtrip("def f(a: int = 5): pass")
@@ -511,7 +483,6 @@ def test_class_decorators():
check_ast_roundtrip(class_decorator)
-@pytest.mark.skipif(not six.PY3, reason="Only for Python 3")
def test_class_definition():
check_ast_roundtrip("class A(metaclass=type, *[], **{}): pass")
@@ -525,7 +496,6 @@ def test_try_except_finally():
check_ast_roundtrip(try_except_finally)
-@pytest.mark.skipif(not six.PY3, reason="Only for Python 3")
def test_starred_assignment():
check_ast_roundtrip("a, *b, c = seq")
check_ast_roundtrip("a, (*b, c) = seq")
diff --git a/lib/spack/spack/url.py b/lib/spack/spack/url.py
index 08eef72e93..972a964d25 100644
--- a/lib/spack/spack/url.py
+++ b/lib/spack/spack/url.py
@@ -25,11 +25,10 @@ This is useful if a user asks for a package at a particular version number;
spack doesn't need anyone to tell it where to get the tarball even though
it's never been told about that version before.
"""
+import io
import os
import re
-
-from six import StringIO
-from six.moves.urllib.parse import urlsplit, urlunsplit
+from urllib.parse import urlsplit, urlunsplit
import llnl.util.tty as tty
from llnl.util.tty.color import cescape, colorize
@@ -874,7 +873,7 @@ def color_url(path, **kwargs):
vends = [vo + vl - 1 for vo in voffs]
nerr = verr = 0
- out = StringIO()
+ out = io.StringIO()
for i in range(len(path)):
if i == vs:
out.write("@c")
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index 5f3fb7a61a..f46b2508e0 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -9,15 +9,13 @@ import inspect
import json
import os
import os.path
+import pickle
import platform
import re
+import shlex
import socket
import sys
-import six
-from six.moves import cPickle
-from six.moves import shlex_quote as cmd_quote
-
import llnl.util.tty as tty
from llnl.util.lang import dedupe
@@ -131,7 +129,7 @@ def env_var_to_source_line(var, val):
fname=bash_function_finder.sub(r"\1", var), decl=val
)
else:
- source_line = "{var}={val}; export {var}".format(var=var, val=cmd_quote(val))
+ source_line = "{var}={val}; export {var}".format(var=var, val=shlex.quote(val))
return source_line
@@ -154,7 +152,7 @@ def dump_environment(path, environment=None):
@system_path_filter(arg_slice=slice(1))
def pickle_environment(path, environment=None):
"""Pickle an environment dictionary to a file."""
- cPickle.dump(dict(environment if environment else os.environ), open(path, "wb"), protocol=2)
+ pickle.dump(dict(environment if environment else os.environ), open(path, "wb"), protocol=2)
def get_host_environment_metadata():
@@ -627,7 +625,7 @@ class EnvironmentModifications(object):
cmds += _shell_unset_strings[shell].format(name)
else:
if sys.platform != "win32":
- cmd = _shell_set_strings[shell].format(name, cmd_quote(new_env[name]))
+ cmd = _shell_set_strings[shell].format(name, shlex.quote(new_env[name]))
else:
cmd = _shell_set_strings[shell].format(name, new_env[name])
cmds += cmd
@@ -1024,7 +1022,7 @@ def environment_after_sourcing_files(*files, **kwargs):
current_environment = kwargs.get("env", dict(os.environ))
for f in files:
# Normalize the input to the helper function
- if isinstance(f, six.string_types):
+ if isinstance(f, str):
f = [f]
current_environment = _source_single_file(f, environment=current_environment)
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 6160b95266..e1e359ed0c 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -9,9 +9,6 @@ import shlex
import subprocess
import sys
-from six import string_types, text_type
-from six.moves import shlex_quote
-
import llnl.util.tty as tty
import spack.error
@@ -168,7 +165,7 @@ class Executable(object):
raise ValueError("Cannot use `str` as input stream.")
def streamify(arg, mode):
- if isinstance(arg, string_types):
+ if isinstance(arg, str):
return open(arg, mode), True
elif arg in (str, str.split):
return subprocess.PIPE, False
@@ -213,17 +210,17 @@ class Executable(object):
result = ""
if output in (str, str.split):
if sys.platform == "win32":
- outstr = text_type(out.decode("ISO-8859-1"))
+ outstr = str(out.decode("ISO-8859-1"))
else:
- outstr = text_type(out.decode("utf-8"))
+ outstr = str(out.decode("utf-8"))
result += outstr
if output is str.split:
sys.stdout.write(outstr)
if error in (str, str.split):
if sys.platform == "win32":
- errstr = text_type(err.decode("ISO-8859-1"))
+ errstr = str(err.decode("ISO-8859-1"))
else:
- errstr = text_type(err.decode("utf-8"))
+ errstr = str(err.decode("utf-8"))
result += errstr
if error is str.split:
sys.stderr.write(errstr)
@@ -283,7 +280,7 @@ def which_string(*args, **kwargs):
path = kwargs.get("path", os.environ.get("PATH", ""))
required = kwargs.get("required", False)
- if isinstance(path, string_types):
+ if isinstance(path, str):
path = path.split(os.pathsep)
for name in args:
@@ -334,7 +331,7 @@ def which(*args, **kwargs):
Executable: The first executable that is found in the path
"""
exe = which_string(*args, **kwargs)
- return Executable(shlex_quote(exe)) if exe else None
+ return Executable(shlex.quote(exe)) if exe else None
class ProcessError(spack.error.SpackError):
diff --git a/lib/spack/spack/util/log_parse.py b/lib/spack/spack/util/log_parse.py
index e498a41bdf..a84a806aca 100644
--- a/lib/spack/spack/util/log_parse.py
+++ b/lib/spack/spack/util/log_parse.py
@@ -5,10 +5,10 @@
from __future__ import print_function
+import io
import sys
from ctest_log_parser import BuildError, BuildWarning, CTestLogParser
-from six import StringIO
import llnl.util.tty as tty
from llnl.util.tty.color import cescape, colorize
@@ -86,7 +86,7 @@ def make_log_context(log_events, width=None):
width = sys.maxsize
wrap_width = width - num_width - 6
- out = StringIO()
+ out = io.StringIO()
next_line = 1
for event in log_events:
start = event.start
diff --git a/lib/spack/spack/util/naming.py b/lib/spack/spack/util/naming.py
index 46a2f3528c..b0a693738e 100644
--- a/lib/spack/spack/util/naming.py
+++ b/lib/spack/spack/util/naming.py
@@ -6,12 +6,11 @@
# Need this because of spack.util.string
from __future__ import absolute_import
+import io
import itertools
import re
import string
-from six import StringIO
-
import spack.error
__all__ = [
@@ -261,6 +260,6 @@ class NamespaceTrie(object):
stream.write(self._subspaces[name]._str_helper(stream, level + 1))
def __str__(self):
- stream = StringIO()
+ stream = io.StringIO()
self._str_helper(stream)
return stream.getvalue()
diff --git a/lib/spack/spack/util/path.py b/lib/spack/spack/util/path.py
index 49794429d3..2dc646418e 100644
--- a/lib/spack/spack/util/path.py
+++ b/lib/spack/spack/util/path.py
@@ -15,8 +15,7 @@ import subprocess
import sys
import tempfile
from datetime import date
-
-from six.moves.urllib.parse import urlparse
+from urllib.parse import urlparse
import llnl.util.tty as tty
from llnl.util.lang import memoized
diff --git a/lib/spack/spack/util/py2.py b/lib/spack/spack/util/py2.py
deleted file mode 100644
index b92a6d66d9..0000000000
--- a/lib/spack/spack/util/py2.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013-2022 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)
-
-import base64
-
-from six import PY3, binary_type, text_type
-
-
-def b32encode(digest):
- # type: (binary_type) -> text_type
- b32 = base64.b32encode(digest)
- if PY3:
- return b32.decode()
- return b32
diff --git a/lib/spack/spack/util/s3.py b/lib/spack/spack/util/s3.py
index 9945ae5e5f..06eeab3936 100644
--- a/lib/spack/spack/util/s3.py
+++ b/lib/spack/spack/util/s3.py
@@ -2,10 +2,8 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
import os
-
-import six.moves.urllib.parse as urllib_parse
+import urllib.parse
import spack
import spack.util.url as url_util
@@ -30,7 +28,7 @@ def get_mirror_connection(url, url_type="push"):
def _parse_s3_endpoint_url(endpoint_url):
- if not urllib_parse.urlparse(endpoint_url, scheme="").scheme:
+ if not urllib.parse.urlparse(endpoint_url, scheme="").scheme:
endpoint_url = "://".join(("https", endpoint_url))
return endpoint_url
diff --git a/lib/spack/spack/util/spack_json.py b/lib/spack/spack/util/spack_json.py
index 305af820aa..a6bef3ea0d 100644
--- a/lib/spack/spack/util/spack_json.py
+++ b/lib/spack/spack/util/spack_json.py
@@ -4,12 +4,9 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Simple wrapper around JSON to guarantee consistent use of load/dump. """
-import collections
import json
from typing import Any, Dict, Optional # novm
-from six import PY3, iteritems, string_types
-
import spack.error
__all__ = ["load", "dump", "SpackJSONError", "encode_json_dict", "decode_json_dict"]
@@ -20,7 +17,7 @@ _json_dump_args = {"indent": 2, "separators": (",", ": ")}
def load(stream):
# type: (Any) -> Dict
"""Spack JSON needs to be ordered to support specs."""
- if isinstance(stream, string_types):
+ if isinstance(stream, str):
load = json.loads # type: ignore[assignment]
else:
load = json.load # type: ignore[assignment]
@@ -56,26 +53,6 @@ def _strify(data, ignore_dicts=False):
Converts python 2 unicodes to str in JSON data, or the other way around."""
# this is a no-op in python 3
- if PY3:
- return data
-
- # if this is a unicode string in python 2, return its string representation
- if isinstance(data, string_types):
- return data.encode("utf-8")
-
- # if this is a list of values, return list of byteified values
- if isinstance(data, list):
- return [_strify(item, ignore_dicts=True) for item in data]
-
- # if this is a dictionary, return dictionary of byteified keys and values
- # but only if we haven't already byteified it
- if isinstance(data, dict) and not ignore_dicts:
- return collections.OrderedDict(
- (_strify(key, ignore_dicts=True), _strify(value, ignore_dicts=True))
- for key, value in iteritems(data)
- )
-
- # if it's anything else, return it in its original form
return data
diff --git a/lib/spack/spack/util/spack_yaml.py b/lib/spack/spack/util/spack_yaml.py
index 88bd4b45a6..6e27adee1c 100644
--- a/lib/spack/spack/util/spack_yaml.py
+++ b/lib/spack/spack/util/spack_yaml.py
@@ -15,12 +15,12 @@
import collections
import collections.abc
import ctypes
+import io
import re
from typing import List # novm
import ruamel.yaml as yaml
from ruamel.yaml import RoundTripDumper, RoundTripLoader
-from six import StringIO, string_types
from llnl.util.tty.color import cextra, clen, colorize
@@ -52,7 +52,7 @@ class syaml_int(int):
#: mapping from syaml type -> primitive type
syaml_types = {
- syaml_str: string_types,
+ syaml_str: str,
syaml_int: int,
syaml_dict: dict,
syaml_list: list,
@@ -263,7 +263,7 @@ class LineAnnotationDumper(OrderedLineDumper):
result = super(LineAnnotationDumper, self).represent_data(data)
if data is None:
result.value = syaml_str("null")
- elif isinstance(result.value, string_types):
+ elif isinstance(result.value, str):
result.value = syaml_str(data)
if markable(result.value):
mark(result.value, data)
@@ -318,7 +318,7 @@ def dump_config(*args, **kwargs):
def dump_annotated(data, stream=None, *args, **kwargs):
kwargs["Dumper"] = LineAnnotationDumper
- sio = StringIO()
+ sio = io.StringIO()
yaml.dump(data, sio, *args, **kwargs)
# write_line_break() is not called by YAML for empty lines, so we
@@ -327,7 +327,7 @@ def dump_annotated(data, stream=None, *args, **kwargs):
getvalue = None
if stream is None:
- stream = StringIO()
+ stream = io.StringIO()
getvalue = stream.getvalue
# write out annotations and lines, accounting for color
diff --git a/lib/spack/spack/util/unparse/__init__.py b/lib/spack/spack/util/unparse/__init__.py
index 3469443105..73f7d106c6 100644
--- a/lib/spack/spack/util/unparse/__init__.py
+++ b/lib/spack/spack/util/unparse/__init__.py
@@ -2,10 +2,9 @@
#
# SPDX-License-Identifier: Python-2.0
# coding: utf-8
-
from __future__ import absolute_import
-from six.moves import cStringIO
+import io
from .unparser import Unparser
@@ -13,7 +12,6 @@ __version__ = "1.6.3"
def unparse(tree, py_ver_consistent=False):
- v = cStringIO()
- unparser = Unparser(py_ver_consistent=py_ver_consistent)
- unparser.visit(tree, v)
+ v = io.StringIO()
+ Unparser(py_ver_consistent=py_ver_consistent).visit(tree, v)
return v.getvalue().strip() + "\n"
diff --git a/lib/spack/spack/util/unparse/unparser.py b/lib/spack/spack/util/unparse/unparser.py
index c204aea25a..c24cf8ee1a 100644
--- a/lib/spack/spack/util/unparse/unparser.py
+++ b/lib/spack/spack/util/unparse/unparser.py
@@ -1,16 +1,13 @@
# Copyright (c) 2014-2021, Simon Percivall and Spack Project Developers.
#
# SPDX-License-Identifier: Python-2.0
-
"Usage: unparse.py <path to source file>"
from __future__ import print_function, unicode_literals
import ast
import sys
from contextlib import contextmanager
-
-import six
-from six import StringIO
+from io import StringIO
# TODO: if we require Python 3.7, use its `nullcontext()`
@@ -76,11 +73,7 @@ def is_simple_tuple(slice_value):
return (
isinstance(slice_value, ast.Tuple)
and slice_value.elts
- and (
- # Python 2 doesn't allow starred elements in tuples like Python 3
- six.PY2
- or not any(isinstance(elt, ast.Starred) for elt in slice_value.elts)
- )
+ and not any(isinstance(elt, ast.Starred) for elt in slice_value.elts)
)
@@ -145,7 +138,7 @@ class Unparser:
def write(self, text):
"Append a piece of text to the current line."
- self.f.write(six.text_type(text))
+ self.f.write(str(text))
class _Block:
"""A context manager for preparing the source for blocks. It adds
@@ -395,25 +388,14 @@ class Unparser:
def visit_Raise(self, node):
self.fill("raise")
- if six.PY3:
- if not node.exc:
- assert not node.cause
- return
- self.write(" ")
- self.dispatch(node.exc)
- if node.cause:
- self.write(" from ")
- self.dispatch(node.cause)
- else:
- self.write(" ")
- if node.type:
- self.dispatch(node.type)
- if node.inst:
- self.write(", ")
- self.dispatch(node.inst)
- if node.tback:
- self.write(", ")
- self.dispatch(node.tback)
+ if not node.exc:
+ assert not node.cause
+ return
+ self.write(" ")
+ self.dispatch(node.exc)
+ if node.cause:
+ self.write(" from ")
+ self.dispatch(node.cause)
def visit_Try(self, node):
self.fill("try")
@@ -462,10 +444,7 @@ class Unparser:
self.dispatch(node.type)
if node.name:
self.write(" as ")
- if six.PY3:
- self.write(node.name)
- else:
- self.dispatch(node.name)
+ self.write(node.name)
with self.block():
self.dispatch(node.body)
@@ -475,42 +454,35 @@ class Unparser:
self.fill("@")
self.dispatch(deco)
self.fill("class " + node.name)
- if six.PY3:
- with self.delimit_if("(", ")", condition=node.bases or node.keywords):
- comma = False
- for e in node.bases:
+ with self.delimit_if("(", ")", condition=node.bases or node.keywords):
+ comma = False
+ for e in node.bases:
+ if comma:
+ self.write(", ")
+ else:
+ comma = True
+ self.dispatch(e)
+ for e in node.keywords:
+ if comma:
+ self.write(", ")
+ else:
+ comma = True
+ self.dispatch(e)
+ if sys.version_info[:2] < (3, 5):
+ if node.starargs:
if comma:
self.write(", ")
else:
comma = True
- self.dispatch(e)
- for e in node.keywords:
+ self.write("*")
+ self.dispatch(node.starargs)
+ if node.kwargs:
if comma:
self.write(", ")
else:
comma = True
- self.dispatch(e)
- if sys.version_info[:2] < (3, 5):
- if node.starargs:
- if comma:
- self.write(", ")
- else:
- comma = True
- self.write("*")
- self.dispatch(node.starargs)
- if node.kwargs:
- if comma:
- self.write(", ")
- else:
- comma = True
- self.write("**")
- self.dispatch(node.kwargs)
- elif node.bases:
- with self.delimit("(", ")"):
- for a in node.bases[:-1]:
- self.dispatch(a)
- self.write(", ")
- self.dispatch(node.bases[-1])
+ self.write("**")
+ self.dispatch(node.kwargs)
with self.block():
self.dispatch(node.body)
@@ -654,26 +626,11 @@ class Unparser:
self.write(repr(node.s))
def visit_Str(self, tree):
- if six.PY3:
- # Python 3.5, 3.6, and 3.7 can't tell if something was written as a
- # unicode constant. Try to make that consistent with 'u' for '\u- literals
- if self._py_ver_consistent and repr(tree.s).startswith("'\\u"):
- self.write("u")
- self._write_constant(tree.s)
- elif self._py_ver_consistent:
- self.write(repr(tree.s)) # just do a python 2 repr for consistency
- else:
- # if from __future__ import unicode_literals is in effect,
- # then we want to output string literals using a 'b' prefix
- # and unicode literals with no prefix.
- if "unicode_literals" not in self.future_imports:
- self.write(repr(tree.s))
- elif isinstance(tree.s, str):
- self.write("b" + repr(tree.s))
- elif isinstance(tree.s, unicode): # noqa: F821
- self.write(repr(tree.s).lstrip("u"))
- else:
- assert False, "shouldn't get here"
+ # Python 3.5, 3.6, and 3.7 can't tell if something was written as a
+ # unicode constant. Try to make that consistent with 'u' for '\u- literals
+ if self._py_ver_consistent and repr(tree.s).startswith("'\\u"):
+ self.write("u")
+ self._write_constant(tree.s)
def visit_JoinedStr(self, node):
# JoinedStr(expr* values)
@@ -805,15 +762,7 @@ class Unparser:
def visit_Num(self, node):
repr_n = repr(node.n)
- if six.PY3:
- self.write(repr_n.replace("inf", INFSTR))
- else:
- # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2.
- with self.require_parens(pnext(_Precedence.FACTOR), node):
- if "inf" in repr_n and repr_n.endswith("*j"):
- repr_n = repr_n.replace("*j", "j")
- # Substitute overflowing decimal literal for AST infinities.
- self.write(repr_n.replace("inf", INFSTR))
+ self.write(repr_n.replace("inf", INFSTR))
def visit_List(self, node):
with self.delimit("[", "]"):
@@ -917,17 +866,7 @@ class Unparser:
if operator_precedence != _Precedence.FACTOR:
self.write(" ")
self.set_precedence(operator_precedence, node.operand)
-
- if six.PY2 and isinstance(node.op, ast.USub) and isinstance(node.operand, ast.Num):
- # If we're applying unary minus to a number, parenthesize the number.
- # This is necessary: -2147483648 is different from -(2147483648) on
- # a 32-bit machine (the first is an int, the second a long), and
- # -7j is different from -(7j). (The first has real part 0.0, the second
- # has real part -0.0.)
- with self.delimit("(", ")"):
- self.dispatch(node.operand)
- else:
- self.dispatch(node.operand)
+ self.dispatch(node.operand)
binop = {
"Add": "+",
diff --git a/lib/spack/spack/util/url.py b/lib/spack/spack/util/url.py
index c9c7343585..d0f9ef7393 100644
--- a/lib/spack/spack/util/url.py
+++ b/lib/spack/spack/util/url.py
@@ -11,9 +11,7 @@ import itertools
import posixpath
import re
import sys
-
-import six.moves.urllib.parse
-from six import string_types
+import urllib.parse
from spack.util.path import (
canonicalize_path,
@@ -50,7 +48,7 @@ def local_file_path(url):
If url is a file:// URL, return the absolute path to the local
file or directory referenced by it. Otherwise, return None.
"""
- if isinstance(url, string_types):
+ if isinstance(url, str):
url = parse(url)
if url.scheme == "file":
@@ -75,23 +73,23 @@ def parse(url, scheme="file"):
url (str): URL to be parsed
scheme (str): associated URL scheme
Returns:
- (six.moves.urllib.parse.ParseResult): For file scheme URLs, the
+ (urllib.parse.ParseResult): For file scheme URLs, the
netloc and path components are concatenated and passed through
spack.util.path.canoncalize_path(). Otherwise, the returned value
is the same as urllib's urlparse() with allow_fragments=False.
"""
# guarantee a value passed in is of proper url format. Guarantee
# allows for easier string manipulation accross platforms
- if isinstance(url, string_types):
+ if isinstance(url, str):
require_url_format(url)
url = escape_file_url(url)
url_obj = (
- six.moves.urllib.parse.urlparse(
+ urllib.parse.urlparse(
url,
scheme=scheme,
allow_fragments=False,
)
- if isinstance(url, string_types)
+ if isinstance(url, str)
else url
)
@@ -119,7 +117,7 @@ def parse(url, scheme="file"):
if sys.platform == "win32":
path = convert_to_posix_path(path)
- return six.moves.urllib.parse.ParseResult(
+ return urllib.parse.ParseResult(
scheme=scheme,
netloc=netloc,
path=path,
@@ -134,7 +132,7 @@ def format(parsed_url):
Returns a canonicalized format of the given URL as a string.
"""
- if isinstance(parsed_url, string_types):
+ if isinstance(parsed_url, str):
parsed_url = parse(parsed_url)
return parsed_url.geturl()
@@ -195,8 +193,7 @@ def join(base_url, path, *extra, **kwargs):
'file:///opt/spack'
"""
paths = [
- (x) if isinstance(x, string_types) else x.geturl()
- for x in itertools.chain((base_url, path), extra)
+ (x) if isinstance(x, str) else x.geturl() for x in itertools.chain((base_url, path), extra)
]
paths = [convert_to_posix_path(x) for x in paths]
@@ -204,7 +201,7 @@ def join(base_url, path, *extra, **kwargs):
last_abs_component = None
scheme = ""
for i in range(n - 1, -1, -1):
- obj = six.moves.urllib.parse.urlparse(
+ obj = urllib.parse.urlparse(
paths[i],
scheme="",
allow_fragments=False,
@@ -218,7 +215,7 @@ def join(base_url, path, *extra, **kwargs):
# Without a scheme, we have to go back looking for the
# next-last component that specifies a scheme.
for j in range(i - 1, -1, -1):
- obj = six.moves.urllib.parse.urlparse(
+ obj = urllib.parse.urlparse(
paths[j],
scheme="",
allow_fragments=False,
@@ -238,7 +235,7 @@ def join(base_url, path, *extra, **kwargs):
if last_abs_component is not None:
paths = paths[last_abs_component:]
if len(paths) == 1:
- result = six.moves.urllib.parse.urlparse(
+ result = urllib.parse.urlparse(
paths[0],
scheme="file",
allow_fragments=False,
@@ -248,7 +245,7 @@ def join(base_url, path, *extra, **kwargs):
# file:// URL component with a relative path, the relative path
# needs to be resolved.
if result.scheme == "file" and result.netloc:
- result = six.moves.urllib.parse.ParseResult(
+ result = urllib.parse.ParseResult(
scheme=result.scheme,
netloc="",
path=posixpath.abspath(result.netloc + result.path),
@@ -306,7 +303,7 @@ def _join(base_url, path, *extra, **kwargs):
base_path = convert_to_posix_path(base_path)
return format(
- six.moves.urllib.parse.ParseResult(
+ urllib.parse.ParseResult(
scheme=scheme,
netloc=netloc,
path=base_path,
diff --git a/lib/spack/spack/util/web.py b/lib/spack/spack/util/web.py
index 9d8588c2b9..543bb43c5c 100644
--- a/lib/spack/spack/util/web.py
+++ b/lib/spack/spack/util/web.py
@@ -16,10 +16,8 @@ import ssl
import sys
import traceback
from html.parser import HTMLParser
-
-import six
-from six.moves.urllib.error import URLError
-from six.moves.urllib.request import Request, urlopen
+from urllib.error import URLError
+from urllib.request import Request, urlopen
import llnl.util.lang
import llnl.util.tty as tty
@@ -683,7 +681,7 @@ def spider(root_urls, depth=0, concurrency=32):
return pages, links, subcalls
- if isinstance(root_urls, six.string_types):
+ if isinstance(root_urls, str):
root_urls = [root_urls]
# Clear the local cache of visited pages before starting the search
diff --git a/lib/spack/spack/variant.py b/lib/spack/spack/variant.py
index b006ae985e..1e646fa3b4 100644
--- a/lib/spack/spack/variant.py
+++ b/lib/spack/spack/variant.py
@@ -9,12 +9,10 @@ variants both in packages and in specs.
import collections.abc
import functools
import inspect
+import io
import itertools
import re
-import six
-from six import StringIO
-
import llnl.util.lang as lang
import llnl.util.tty.color
@@ -665,7 +663,7 @@ class VariantMap(lang.HashableMap):
bool_keys.append(key) if isinstance(self[key].value, bool) else kv_keys.append(key)
# add spaces before and after key/value variants.
- string = StringIO()
+ string = io.StringIO()
for key in bool_keys:
string.write(str(self[key]))
@@ -895,12 +893,12 @@ class Value(object):
return hash(self.value)
def __eq__(self, other):
- if isinstance(other, (six.string_types, bool)):
+ if isinstance(other, (str, bool)):
return self.value == other
return self.value == other.value
def __lt__(self, other):
- if isinstance(other, six.string_types):
+ if isinstance(other, str):
return self.value < other
return self.value < other.value
diff --git a/lib/spack/spack/verify.py b/lib/spack/spack/verify.py
index e18c98373d..82e187dd47 100644
--- a/lib/spack/spack/verify.py
+++ b/lib/spack/spack/verify.py
@@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import base64
import hashlib
import os
@@ -10,14 +11,14 @@ import llnl.util.tty as tty
import spack.filesystem_view
import spack.store
import spack.util.file_permissions as fp
-import spack.util.py2 as compat
import spack.util.spack_json as sjson
def compute_hash(path):
with open(path, "rb") as f:
sha1 = hashlib.sha1(f.read()).digest()
- return compat.b32encode(sha1)
+ b32 = base64.b32encode(sha1)
+ return b32.decode()
def create_manifest_entry(path):
diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py
index f4f08d8c77..20f0c13d1c 100644
--- a/lib/spack/spack/version.py
+++ b/lib/spack/spack/version.py
@@ -30,8 +30,6 @@ import re
from bisect import bisect_left
from functools import wraps
-from six import string_types
-
import llnl.util.tty as tty
from llnl.util.filesystem import mkdirp, working_dir
@@ -721,9 +719,9 @@ class GitVersion(VersionBase):
class VersionRange(object):
def __init__(self, start, end):
- if isinstance(start, string_types):
+ if isinstance(start, str):
start = Version(start)
- if isinstance(end, string_types):
+ if isinstance(end, str):
end = Version(end)
self.start = start
@@ -939,7 +937,7 @@ class VersionList(object):
def __init__(self, vlist=None):
self.versions = []
if vlist is not None:
- if isinstance(vlist, string_types):
+ if isinstance(vlist, str):
vlist = _string_to_version(vlist)
if type(vlist) == VersionList:
self.versions = vlist.versions
@@ -1193,7 +1191,7 @@ def ver(obj):
"""
if isinstance(obj, (list, tuple)):
return VersionList(obj)
- elif isinstance(obj, string_types):
+ elif isinstance(obj, str):
return _string_to_version(obj)
elif isinstance(obj, (int, float)):
return _string_to_version(str(obj))