Skip to content

Commit b514905

Browse files
authored
Merge pull request #3076 from boegel/depr_py26
deprecate running EasyBuild with Python 2.6 via new check_python_version() function
2 parents d6fd2ec + 950b06a commit b514905

File tree

4 files changed

+111
-5
lines changed

4 files changed

+111
-5
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ matrix:
1919
include:
2020
# also test default configuration with Python 2.6
2121
- python: 2.6
22-
env: LMOD_VERSION=7.8.22
22+
env: LMOD_VERSION=7.8.22 TEST_EASYBUILD_SILENCE_DEPRECATION_WARNINGS=Python26
2323
dist: trusty
2424
# single configuration to test with Lmod 6 and Python 2.7
2525
- python: 2.7

easybuild/tools/options.py

Lines changed: 4 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

@@ -1369,6 +1370,8 @@ def set_up_configuration(args=None, logfile=None, testing=False, silent=False):
13691370
init(options, config_options_dict)
13701371
init_build_options(build_options=build_options, cmdline_options=options)
13711372

1373+
check_python_version()
1374+
13721375
# move directory containing fake vsc namespace into temporary directory used for this session
13731376
# (to ensure it gets cleaned up properly)
13741377
new_fake_vsc_path = os.path.join(tmpdir, os.path.basename(fake_vsc_path))

easybuild/tools/systemtools.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
from easybuild.base import fancylogger
4545
from easybuild.tools.build_log import EasyBuildError
46+
from easybuild.tools.config import build_option
4647
from easybuild.tools.filetools import is_readable, read_file, which
4748
from easybuild.tools.run import run_cmd
4849

@@ -831,3 +832,35 @@ def det_terminal_size():
831832
height, width = 25, 80
832833

833834
return height, width
835+
836+
837+
def check_python_version():
838+
"""Check currently used Python version."""
839+
python_maj_ver = sys.version_info[0]
840+
python_min_ver = sys.version_info[1]
841+
python_ver = '%d.%d' % (python_maj_ver, python_min_ver)
842+
_log.info("Found Python version %s", python_ver)
843+
844+
silence_deprecation_warnings = build_option('silence_deprecation_warnings') or []
845+
846+
if python_maj_ver == 2:
847+
if python_min_ver < 6:
848+
raise EasyBuildError("Python 2.6 or higher is required when using Python 2, found Python %s", python_ver)
849+
elif python_min_ver == 6:
850+
depr_msg = "Running EasyBuild with Python 2.6 is deprecated"
851+
if 'Python26' in silence_deprecation_warnings:
852+
_log.warning(depr_msg)
853+
else:
854+
_log.deprecated(depr_msg, '5.0')
855+
else:
856+
_log.info("Running EasyBuild with Python 2 (version %s)", python_ver)
857+
858+
elif python_maj_ver == 3:
859+
if python_min_ver < 5:
860+
raise EasyBuildError("Python 3.5 or higher is required when using Python 3, found Python %s", python_ver)
861+
else:
862+
_log.info("Running EasyBuild with Python 3 (version %s)", python_ver)
863+
else:
864+
raise EasyBuildError("EasyBuild is not compatible (yet) with Python %s", python_ver)
865+
866+
return (python_maj_ver, python_min_ver)

test/framework/systemtools.py

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,23 @@
3131
import re
3232
import sys
3333

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

771841
def suite():
772842
""" returns all the testcases in this module """

0 commit comments

Comments
 (0)