Skip to content

Commit b035a04

Browse files
committed
deprecate running EasyBuild with Python 2.6 via new check_python_version() function
1 parent 825e22f commit b035a04

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

easybuild/tools/options.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@
9393
from easybuild.tools.package.utilities import avail_package_naming_schemes
9494
from easybuild.tools.toolchain.compiler import DEFAULT_OPT_LEVEL, OPTARCH_MAP_CHAR, OPTARCH_SEP, Compiler
9595
from easybuild.tools.repository.repository import avail_repositories
96-
from easybuild.tools.systemtools import get_cpu_architecture, get_cpu_family, get_cpu_features, get_system_info
96+
from easybuild.tools.systemtools import check_python_version, get_cpu_architecture, get_cpu_family, get_cpu_features
97+
from easybuild.tools.systemtools import get_system_info
9798
from easybuild.tools.version import this_is_easybuild
9899

99100

@@ -1302,6 +1303,7 @@ def set_up_configuration(args=None, logfile=None, testing=False, silent=False):
13021303
:param testing: enable testing mode
13031304
:param silent: stay silent (no printing)
13041305
"""
1306+
check_python_version()
13051307

13061308
# set up fake 'vsc' Python package, to catch easyblocks/scripts that still import from vsc.* namespace
13071309
# this must be done early on, to catch imports from the vsc namespace in modules included via --include-*

easybuild/tools/systemtools.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,3 +802,29 @@ def det_terminal_size():
802802
height, width = 25, 80
803803

804804
return height, width
805+
806+
807+
def check_python_version():
808+
"""Check currently used Python version."""
809+
python_maj_ver = sys.version_info[0]
810+
python_min_ver = sys.version_info[1]
811+
python_ver = '%d.%d' % (python_maj_ver, python_min_ver)
812+
_log.info("Found Python version %s", python_ver)
813+
814+
if python_maj_ver == 2:
815+
if python_min_ver < 6:
816+
raise EasyBuildError("Python 2.6 or higher is required when using Python 2, found Python %s", python_ver)
817+
elif python_min_ver == 6:
818+
_log.deprecated("Running EasyBuild with Python 2.6 is deprecated", '5.0')
819+
else:
820+
_log.info("Running EasyBuild with Python 2 (version %s)", python_ver)
821+
822+
elif python_maj_ver == 3:
823+
if python_min_ver < 5:
824+
raise EasyBuildError("Python 3.5 or higher is required when using Python 3, found Python %s", python_ver)
825+
else:
826+
_log.info("Running EasyBuild with Python 3 (version %s)", python_ver)
827+
else:
828+
raise EasyBuildError("EasyBuild is not compatible (yet) with Python %s", python_ver)
829+
830+
return (python_maj_ver, python_min_ver)

test/framework/systemtools.py

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,19 @@
3535
from unittest import TextTestRunner
3636

3737
import easybuild.tools.systemtools as st
38+
from easybuild.tools.build_log import EasyBuildError
3839
from easybuild.tools.filetools import read_file
3940
from easybuild.tools.py2vs3 import string_type
4041
from easybuild.tools.run import run_cmd
4142
from easybuild.tools.systemtools import CPU_ARCHITECTURES, AARCH32, AARCH64, POWER, X86_64
4243
from easybuild.tools.systemtools import CPU_FAMILIES, POWER_LE, DARWIN, LINUX, UNKNOWN
4344
from easybuild.tools.systemtools import CPU_VENDORS, AMD, APM, ARM, CAVIUM, IBM, INTEL
4445
from easybuild.tools.systemtools import MAX_FREQ_FP, PROC_CPUINFO_FP, PROC_MEMINFO_FP
46+
from easybuild.tools.systemtools import check_python_version
4547
from easybuild.tools.systemtools import det_parallelism, get_avail_core_count, get_cpu_architecture, get_cpu_family
4648
from easybuild.tools.systemtools import get_cpu_features, get_cpu_model, get_cpu_speed, get_cpu_vendor
47-
from easybuild.tools.systemtools import get_glibc_version, get_os_type, get_os_name, get_os_version, get_platform_name
48-
from easybuild.tools.systemtools import get_shared_lib_ext, get_system_info, get_total_memory, get_gcc_version
49+
from easybuild.tools.systemtools import get_gcc_version, get_glibc_version, get_os_type, get_os_name, get_os_version
50+
from easybuild.tools.systemtools import get_platform_name, get_shared_lib_ext, get_system_info, get_total_memory
4951

5052

5153
PROC_CPUINFO_TXT = None
@@ -335,6 +337,7 @@ def setUp(self):
335337
self.orig_run_cmd = st.run_cmd
336338
self.orig_platform_uname = st.platform.uname
337339
self.orig_get_tool_version = st.get_tool_version
340+
self.orig_sys_version_info = st.sys.version_info
338341

339342
def tearDown(self):
340343
"""Cleanup after systemtools test."""
@@ -345,6 +348,7 @@ def tearDown(self):
345348
st.run_cmd = self.orig_run_cmd
346349
st.platform.uname = self.orig_platform_uname
347350
st.get_tool_version = self.orig_get_tool_version
351+
st.sys.version_info = self.orig_sys_version_info
348352
super(SystemToolsTest, self).tearDown()
349353

350354
def test_avail_core_count_native(self):
@@ -767,6 +771,70 @@ def test_det_terminal_size(self):
767771
self.assertTrue(isinstance(height, int) and height >= 0)
768772
self.assertTrue(isinstance(width, int) and width >= 0)
769773

774+
def test_check_python_version(self):
775+
"""Test check_python_version function."""
776+
777+
def mock_python_ver(py_maj_ver, py_min_ver):
778+
"""Helper function to mock a particular Python version."""
779+
st.sys.version_info = (py_maj_ver, py_min_ver) + sys.version_info[2:]
780+
781+
# mock running with different Python versions
782+
mock_python_ver(1, 4)
783+
error_pattern = r"EasyBuild is not compatible \(yet\) with Python 1.4"
784+
self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version)
785+
786+
mock_python_ver(4, 0)
787+
error_pattern = r"EasyBuild is not compatible \(yet\) with Python 4.0"
788+
self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version)
789+
790+
mock_python_ver(2, 5)
791+
error_pattern = r"Python 2.6 or higher is required when using Python 2, found Python 2.5"
792+
self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version)
793+
794+
# no problems when running with a supported Python version
795+
for pyver in [(2, 7), (3, 5), (3, 6), (3, 7)]:
796+
mock_python_ver(*pyver)
797+
self.assertEqual(check_python_version(), pyver)
798+
799+
mock_python_ver(2, 6)
800+
# deprecation warning triggers an error in test environment
801+
error_pattern = r"Running EasyBuild with Python 2.6 is deprecated"
802+
self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version)
803+
804+
# we may trigger a deprecation warning below (when testing with Python 2.6)
805+
py26_depr_warning = "\nWARNING: Deprecated functionality, will no longer work in v5.0: "
806+
py26_depr_warning += "Running EasyBuild with Python 2.6 is deprecated"
807+
808+
self.allow_deprecated_behaviour()
809+
810+
# first test with mocked Python 2.6
811+
self.mock_stderr(True)
812+
check_python_version()
813+
stderr = self.get_stderr()
814+
self.mock_stderr(False)
815+
816+
# we should always get a deprecation warning here
817+
self.assertTrue(stderr.startswith(py26_depr_warning))
818+
819+
# restore Python version info to check with Python version used to run tests
820+
st.sys.version_info = self.orig_sys_version_info
821+
822+
# shouldn't raise any errors, since Python version used to run tests should be supported;
823+
self.mock_stderr(True)
824+
(py_maj_ver, py_min_ver) = check_python_version()
825+
stderr = self.get_stderr()
826+
self.mock_stderr(False)
827+
828+
self.assertTrue(py_maj_ver in [2, 3])
829+
if py_maj_ver == 2:
830+
self.assertTrue(py_min_ver in [6, 7])
831+
else:
832+
self.assertTrue(py_min_ver >= 5)
833+
834+
# only deprecation warning when actually testing with Python 2.6
835+
if sys.version_info[:2] == (2, 6):
836+
self.assertTrue(stderr.startswith(py26_depr_warning))
837+
770838

771839
def suite():
772840
""" returns all the testcases in this module """

0 commit comments

Comments
 (0)