diff --git a/aliBuild b/aliBuild index 5f269195..ce9923c4 100755 --- a/aliBuild +++ b/aliBuild @@ -115,10 +115,7 @@ if __name__ == "__main__": if profiler: print("profiler started") import cProfile, pstats - try: - from StringIO import StringIO - except ImportError: - from io import StringIO + from io import StringIO pr = cProfile.Profile() pr.enable() def profiler(): diff --git a/alibuild_helpers/analytics.py b/alibuild_helpers/analytics.py index 63ee6dbb..2ecd83e3 100644 --- a/alibuild_helpers/analytics.py +++ b/alibuild_helpers/analytics.py @@ -22,10 +22,7 @@ def askForAnalytics(): banner("In order to improve user experience, aliBuild would like to gather " "analytics about your builds.\nYou can find all the details at:\n\n" " https://github.com/alisw/alibuild/blob/master/ANALYTICS.md\n") - # raw_input and input are different between python 2 and 3 - try: _input = raw_input - except NameError: _input = input - a = _input("Is that ok for you [YES/no]? ") + a = input("Is that ok for you [YES/no]? ") if a.strip() and a.strip().lower().startswith("n"): debug("User requsted disabling analytics.") return disable_analytics() diff --git a/alibuild_helpers/build.py b/alibuild_helpers/build.py index 2716bf14..fccc30bb 100644 --- a/alibuild_helpers/build.py +++ b/alibuild_helpers/build.py @@ -17,13 +17,12 @@ from alibuild_helpers.sl import Sapling from alibuild_helpers.scm import SCMError from alibuild_helpers.sync import remote_from_url -import yaml from alibuild_helpers.workarea import logged_scm, updateReferenceRepoSpec, checkout_sources from alibuild_helpers.log import ProgressPrint, log_current_package from glob import glob from textwrap import dedent from collections import OrderedDict -from shlex import quote # Python 3.3+ +from shlex import quote import concurrent.futures import importlib @@ -187,10 +186,7 @@ def h_all(data): # pylint: disable=function-redefined hasher(data) for key in ("env", "append_path", "prepend_path"): - if sys.version_info[0] < 3 and key in spec and isinstance(spec[key], OrderedDict): - # Python 2: use YAML dict order to prevent changing hashes - h_all(str(yaml.safe_load(yamlDump(spec[key])))) - elif key not in spec: + if key not in spec: h_all("none") else: # spec["env"] is of type OrderedDict[str, str]. @@ -480,7 +476,7 @@ def doBuild(args, parser): checkedOutCommitName = scm.checkedOutCommitName(directory=args.configDir) except SCMError: dieOnError(True, "Cannot find SCM directory in %s." % args.configDir) - os.environ["ALIBUILD_ALIDIST_HASH"] = checkedOutCommitName + os.environ["ALIBUILD_ALIDIST_HASH"] = checkedOutCommitName # type: ignore debug("Building for architecture %s", args.architecture) debug("Number of parallel builds: %d", args.jobs) diff --git a/alibuild_helpers/cmd.py b/alibuild_helpers/cmd.py index 9d73c821..a0ea2db5 100644 --- a/alibuild_helpers/cmd.py +++ b/alibuild_helpers/cmd.py @@ -1,68 +1,37 @@ import os import os.path -import sys import time from subprocess import Popen, PIPE, STDOUT from textwrap import dedent -try: - from subprocess import TimeoutExpired -except ImportError: - class TimeoutExpired(Exception): - """Stub exception for Python 2.""" -try: - from shlex import quote # Python 3.3+ -except ImportError: - from pipes import quote # Python 2.7 +from subprocess import TimeoutExpired +from shlex import quote from alibuild_helpers.log import debug, warning, dieOnError -# Keep the linter happy -if sys.version_info[0] >= 3: - basestring = str - unicode = None - - -def is_string(s): - if sys.version_info[0] >= 3: - return isinstance(s, str) - return isinstance(s, basestring) - - def decode_with_fallback(data): """Try to decode DATA as utf-8; if that doesn't work, fall back to latin-1. This combination should cover every possible byte string, as latin-1 covers every possible single byte. """ - if sys.version_info[0] >= 3: - if isinstance(data, bytes): - try: - return data.decode("utf-8") - except UnicodeDecodeError: - return data.decode("latin-1") - else: - return str(data) - elif isinstance(data, str): - return unicode(data, "utf-8") # utf-8 is a safe assumption - elif not isinstance(data, unicode): - return unicode(str(data)) - return data + if isinstance(data, bytes): + try: + return data.decode("utf-8") + except UnicodeDecodeError: + return data.decode("latin-1") + else: + return str(data) def getoutput(command, timeout=None): """Run command, check it succeeded, and return its stdout as a string.""" - proc = Popen(command, shell=is_string(command), stdout=PIPE, stderr=PIPE) + proc = Popen(command, shell=isinstance(command, str), stdout=PIPE, stderr=PIPE) try: stdout, stderr = proc.communicate(timeout=timeout) except TimeoutExpired: warning("Process %r timed out; terminated", command) proc.terminate() stdout, stderr = proc.communicate() - except TypeError: - # On Python 2, we don't have the timeout= parameter. However, "regular" - # users shouldn't be running under Python 2 any more, so just don't timeout - # there and let the admins handle it manually. - stdout, stderr = proc.communicate() dieOnError(proc.returncode, "Command %s failed with code %d: %s" % (command, proc.returncode, decode_with_fallback(stderr))) return decode_with_fallback(stdout) @@ -70,18 +39,13 @@ def getoutput(command, timeout=None): def getstatusoutput(command, timeout=None): """Run command and return its return code and output (stdout and stderr).""" - proc = Popen(command, shell=is_string(command), stdout=PIPE, stderr=STDOUT) + proc = Popen(command, shell=isinstance(command, str), stdout=PIPE, stderr=STDOUT) try: merged_output, _ = proc.communicate(timeout=timeout) except TimeoutExpired: warning("Process %r timed out; terminated", command) proc.terminate() merged_output, _ = proc.communicate() - except TypeError: - # On Python 2, we don't have the timeout= parameter. However, "regular" - # users shouldn't be running under Python 2 any more, so just don't timeout - # there and let the admins handle it manually. - merged_output, _ = proc.communicate() merged_output = decode_with_fallback(merged_output) # Strip a single trailing newline, if one exists, to match the behaviour of # subprocess.getstatusoutput. @@ -91,7 +55,7 @@ def getstatusoutput(command, timeout=None): def execute(command, printer=debug, timeout=None): - popen = Popen(command, shell=is_string(command), stdout=PIPE, stderr=STDOUT) + popen = Popen(command, shell=isinstance(command, str), stdout=PIPE, stderr=STDOUT) start_time = time.time() for line in iter(popen.stdout.readline, b""): printer("%s", decode_with_fallback(line).strip("\n")) diff --git a/alibuild_helpers/git.py b/alibuild_helpers/git.py index 5f12312e..4bf5c34a 100644 --- a/alibuild_helpers/git.py +++ b/alibuild_helpers/git.py @@ -46,8 +46,8 @@ def parseRefs(self, output): def listRefsCmd(self, repository): return ["ls-remote", "--heads", "--tags", repository] - def cloneReferenceCmd(self, source, referenceRepo, usePartialClone): - cmd = ["clone", "--bare", source, referenceRepo] + def cloneReferenceCmd(self, spec, referenceRepo, usePartialClone): + cmd = ["clone", "--bare", spec, referenceRepo] if usePartialClone: cmd.extend(clone_speedup_options()) return cmd @@ -64,11 +64,11 @@ def cloneSourceCmd(self, source, destination, referenceRepo, usePartialClone): cmd.extend(clone_speedup_options()) return cmd - def checkoutCmd(self, ref): - return ["checkout", "-f", ref] + def checkoutCmd(self, tag): + return ["checkout", "-f", tag] - def fetchCmd(self, source, *refs): - return ["fetch", "-f"] + clone_speedup_options() + [source, *refs] + def fetchCmd(self, remote, *refs): + return ["fetch", "-f"] + clone_speedup_options() + [remote, *refs] def setWriteUrlCmd(self, url): return ["remote", "set-url", "--push", "origin", url] diff --git a/alibuild_helpers/scm.py b/alibuild_helpers/scm.py index ac90e460..7f00ca41 100644 --- a/alibuild_helpers/scm.py +++ b/alibuild_helpers/scm.py @@ -21,7 +21,7 @@ def fetchCmd(self, remote, *refs): raise NotImplementedError def cloneReferenceCmd(self, spec, referenceRepo, usePartialClone): raise NotImplementedError - def cloneSourceCmd(self, spec, referenceRepo, usePartialClone): + def cloneSourceCmd(self, source, destination, referenceRepo, usePartialClone): raise NotImplementedError def setWriteUrlCmd(self, url): raise NotImplementedError diff --git a/alibuild_helpers/utilities.py b/alibuild_helpers/utilities.py index b15d45a0..04bd1430 100644 --- a/alibuild_helpers/utilities.py +++ b/alibuild_helpers/utilities.py @@ -10,14 +10,8 @@ import platform from datetime import datetime -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict -try: - from shlex import quote # Python 3.3+ -except ImportError: - from pipes import quote # Python 2.7 +from collections import OrderedDict +from shlex import quote from alibuild_helpers.cmd import getoutput from alibuild_helpers.git import git diff --git a/alibuild_helpers/workarea.py b/alibuild_helpers/workarea.py index 8be3f985..07d4dfb4 100644 --- a/alibuild_helpers/workarea.py +++ b/alibuild_helpers/workarea.py @@ -4,10 +4,7 @@ import os.path import shutil import tempfile -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from collections import OrderedDict from alibuild_helpers.log import dieOnError, debug, error from alibuild_helpers.utilities import call_ignoring_oserrors, symlink, short_commit_hash diff --git a/setup.py b/setup.py index 47db05a8..9688b1e6 100644 --- a/setup.py +++ b/setup.py @@ -76,8 +76,6 @@ # aliBuild was built from. use_scm_version={'write_to': 'alibuild_helpers/_version.py'}, setup_requires=[ - # The 6.* series removed support for Python 2.7. - 'setuptools_scm<6.0.0' if sys.version_info < (3, 0) else # The 7.* series removed support for Python 3.6. 'setuptools_scm<7.0.0' if sys.version_info < (3, 7) else 'setuptools_scm' diff --git a/tests/test_args.py b/tests/test_args.py index 3d07562b..c70dd762 100644 --- a/tests/test_args.py +++ b/tests/test_args.py @@ -1,11 +1,7 @@ from __future__ import print_function # Assuming you are using the mock library to ... mock things -try: - from unittest import mock - from unittest.mock import patch, call # In Python 3, mock is built-in -except ImportError: - import mock - from mock import patch, call # Python 2 +from unittest import mock +from unittest.mock import patch, call import alibuild_helpers.args from alibuild_helpers.args import doParseArgs, matchValidArch, finaliseArgs, DEFAULT_WORK_DIR, DEFAULT_CHDIR, ARCHITECTURE_TABLE @@ -16,12 +12,8 @@ import unittest import shlex -if (sys.version_info[0] >= 3): - BUILD_MISSING_PKG_ERROR = "the following arguments are required: PACKAGE" - ANALYTICS_MISSING_STATE_ERROR = "the following arguments are required: state" -else: - BUILD_MISSING_PKG_ERROR = "too few arguments" - ANALYTICS_MISSING_STATE_ERROR = "too few arguments" +BUILD_MISSING_PKG_ERROR = "the following arguments are required: PACKAGE" +ANALYTICS_MISSING_STATE_ERROR = "the following arguments are required: state" # A few errors we should handle, together with the expected result ARCHITECTURE_ERROR = [call(u"Unknown / unsupported architecture: foo.\n\n{table}Alternatively, you can use the `--force-unknown-architecture' option.".format(table=ARCHITECTURE_TABLE))] diff --git a/tests/test_build.py b/tests/test_build.py index a4b48358..246f00fb 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -6,16 +6,9 @@ import sys import unittest # Assuming you are using the mock library to ... mock things -try: - from unittest.mock import call, patch, MagicMock, DEFAULT # In Python 3, mock is built-in - from io import StringIO -except ImportError: - from mock import call, patch, MagicMock, DEFAULT # Python 2 - from StringIO import StringIO -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from unittest.mock import call, patch, MagicMock, DEFAULT +from io import StringIO +from collections import OrderedDict from alibuild_helpers.utilities import parseRecipe, resolve_tag from alibuild_helpers.build import doBuild, storeHashes, generate_initdotsh @@ -79,8 +72,7 @@ 87b87c4322d2a3fad315c919cb2e2dd73f2154dc\trefs/heads/master f7b336611753f1f4aaa94222b0d620748ae230c0\trefs/heads/v6-08-00-patches f7b336611753f1f4aaa94222b0d620748ae230c0\trefs/tags/test-tag""" -TEST_ROOT_BUILD_HASH = ("96cf657d1a5e2d41f16dfe42ced8c3522ab4e413" if sys.version_info.major < 3 else - "8ec3f41b6b585ef86a02e9c595eed67f34d63f08") +TEST_ROOT_BUILD_HASH = ("8ec3f41b6b585ef86a02e9c595eed67f34d63f08") TEST_EXTRA_RECIPE = """\ @@ -97,8 +89,7 @@ ba22\trefs/tags/v1 ba22\trefs/tags/v2 baad\trefs/tags/v3""" -TEST_EXTRA_BUILD_HASH = ("9f9eb8696b7722df52c4703f5fe7acc4b8000ba2" if sys.version_info.major < 3 else - "5afae57bfc6a374e74c1c4427698ab5edebce0bc") +TEST_EXTRA_BUILD_HASH = ("5afae57bfc6a374e74c1c4427698ab5edebce0bc") GIT_CLONE_REF_ZLIB_ARGS = ("clone", "--bare", "https://github.com/star-externals/zlib", diff --git a/tests/test_clean.py b/tests/test_clean.py index e83538fa..2738ed4b 100644 --- a/tests/test_clean.py +++ b/tests/test_clean.py @@ -1,10 +1,7 @@ from __future__ import print_function from textwrap import dedent # Assuming you are using the mock library to ... mock things -try: - from unittest.mock import patch, call # In Python 3, mock is built-in -except ImportError: - from mock import patch, call # Python 2 +from unittest.mock import patch, call from alibuild_helpers.clean import decideClean, doClean diff --git a/tests/test_cmd.py b/tests/test_cmd.py index 770fd7a5..9077892b 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -1,9 +1,6 @@ from __future__ import print_function # Assuming you are using the mock library to ... mock things -try: - from unittest import mock # In Python 3, mock is built-in -except ImportError: - import mock # Python 2 +from unittest import mock from alibuild_helpers.cmd import execute, DockerRunner diff --git a/tests/test_deps.py b/tests/test_deps.py index 8fdecbf4..3e6cbac2 100644 --- a/tests/test_deps.py +++ b/tests/test_deps.py @@ -1,13 +1,5 @@ -try: - from unittest.mock import patch, call, MagicMock # In Python 3, mock is built-in - from io import StringIO -except ImportError: - from mock import patch, call, MagicMock # Python 2 - from StringIO import StringIO -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from unittest.mock import patch, MagicMock +from io import StringIO from alibuild_helpers.deps import doDeps from argparse import Namespace diff --git a/tests/test_doctor.py b/tests/test_doctor.py index d2061401..33c69feb 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -1,14 +1,6 @@ from __future__ import print_function -try: - from unittest.mock import patch, call, MagicMock # In Python 3, mock is built-in - from io import StringIO -except ImportError: - from mock import patch, call, MagicMock # Python 2 - from StringIO import StringIO -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from unittest.mock import patch, MagicMock +from io import StringIO from alibuild_helpers.doctor import doDoctor from argparse import Namespace diff --git a/tests/test_hashing.py b/tests/test_hashing.py index b0057516..e0e09573 100644 --- a/tests/test_hashing.py +++ b/tests/test_hashing.py @@ -3,10 +3,7 @@ import re import unittest -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from collections import OrderedDict from alibuild_helpers.build import storeHashes diff --git a/tests/test_init.py b/tests/test_init.py index c4894d74..97b968c4 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,16 +1,9 @@ from argparse import Namespace import os.path as path import unittest -try: - from unittest.mock import MagicMock, call, patch # In Python 3, mock is built-in - from io import StringIO -except ImportError: - from mock import MagicMock, call, patch # Python 2 - from StringIO import StringIO -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from unittest.mock import call, patch # In Python 3, mock is built-in +from io import StringIO +from collections import OrderedDict from alibuild_helpers.init import doInit, parsePackagesDefinition diff --git a/tests/test_log.py b/tests/test_log.py index 3d4180fc..06553f1b 100644 --- a/tests/test_log.py +++ b/tests/test_log.py @@ -1,8 +1,5 @@ import unittest -try: - from unittest.mock import MagicMock, patch # In Python 3, mock is built-in -except ImportError: - from mock import MagicMock, patch # Python 2 +from unittest.mock import MagicMock, patch from alibuild_helpers.log import dieOnError, ProgressPrint diff --git a/tests/test_packagelist.py b/tests/test_packagelist.py index 1453672b..d46346bf 100644 --- a/tests/test_packagelist.py +++ b/tests/test_packagelist.py @@ -1,10 +1,7 @@ from __future__ import print_function from textwrap import dedent import unittest -try: # Python 3 - from unittest import mock -except ImportError: # Python 2 - import mock +from unittest import mock from alibuild_helpers.cmd import getstatusoutput from alibuild_helpers.utilities import getPackageList diff --git a/tests/test_parseRecipe.py b/tests/test_parseRecipe.py index e5fc5c04..82edbb0c 100644 --- a/tests/test_parseRecipe.py +++ b/tests/test_parseRecipe.py @@ -1,12 +1,8 @@ import unittest -import platform from alibuild_helpers.utilities import parseRecipe, getRecipeReader, parseDefaults from alibuild_helpers.utilities import FileReader, GitReader -from alibuild_helpers.utilities import validateDefaults, SpecError -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from alibuild_helpers.utilities import validateDefaults +from collections import OrderedDict TEST1="""package: foo version: bar diff --git a/tests/test_sync.py b/tests/test_sync.py index 62acdfb8..76103742 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -4,10 +4,7 @@ import unittest from io import BytesIO -try: - from unittest.mock import patch, MagicMock # In Python 3, mock is built-in -except ImportError: - from mock import patch, MagicMock # Python 2 +from unittest.mock import patch, MagicMock from alibuild_helpers import sync from alibuild_helpers.utilities import resolve_links_path, resolve_store_path diff --git a/tests/test_utilities.py b/tests/test_utilities.py index 040fb5a3..3fc2beef 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -3,10 +3,7 @@ import unittest # Assuming you are using the mock library to ... mock things -try: - from unittest.mock import patch # In Python 3, mock is built-in -except ImportError: - from mock import patch # Python 2 +from unittest.mock import patch from alibuild_helpers.utilities import doDetectArch, filterByArchitecture from alibuild_helpers.utilities import Hasher diff --git a/tests/test_workarea.py b/tests/test_workarea.py index 8d208c35..5be094a2 100644 --- a/tests/test_workarea.py +++ b/tests/test_workarea.py @@ -1,13 +1,7 @@ from os import getcwd import unittest -try: - from unittest.mock import patch, MagicMock # In Python 3, mock is built-in -except ImportError: - from mock import patch, MagicMock # Python 2 -try: - from collections import OrderedDict -except ImportError: - from ordereddict import OrderedDict +from unittest.mock import patch, MagicMock # In Python 3, mock is built-in +from collections import OrderedDict from alibuild_helpers.workarea import updateReferenceRepoSpec from alibuild_helpers.git import Git diff --git a/tox.ini b/tox.ini index f28ac90a..a008003a 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,6 @@ envlist = lint, py{27, 36, 37, 38, 39, 310, 311, 312, 313}, darwin [gh-actions] # The "lint" job is run separately. python = - 2.7: py27 3.6: py36 3.7: py37 3.8: py38 @@ -45,19 +44,12 @@ allowlist_externals = sl rm deps = - py27: mock coverage distro setenv = # `aliBuild analytics` puts preference files under $HOME. HOME = {envtmpdir} - # On Python2, dictionary order depends on PYTHONHASHSEED, but we dump plain - # dictionaries (not OrderedDicts!) straight into the package hashing - # algorithm. Therefore, disable tox's hash seed randomisation on py27 to - # ensure our dicts always have the same order. See also: - # https://tox.wiki/en/latest/example/basic.html#special-handling-of-pythonhashseed - py27: PYTHONHASHSEED = 0 # Keep coverage info for later upload, if needed. Files in {envtmpdir} are # deleted after each run. COVERAGE_FILE = {toxworkdir}/coverage.{envname}