diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index 87e5660e2b..a786cbea2b 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -1401,12 +1401,24 @@ def make_module_pythonpath(self): candidate_paths = (os.path.relpath(path, self.installdir) for path in glob.glob(python_subdir_pattern)) python_paths = [path for path in candidate_paths if re.match(r'lib/python\d+\.\d+/site-packages', path)] + # determine whether Python is a runtime dependency; + # if so, we assume it was installed with EasyBuild, and hence is aware of $EBPYTHONPREFIXES runtime_deps = [dep['name'] for dep in self.cfg.dependencies(runtime_only=True)] - use_ebpythonprefixes = all([ - 'Python' in runtime_deps, - build_option('prefer_python_search_path') == EBPYTHONPREFIXES, - not self.cfg['force_pythonpath'] - ]) + + # don't use $EBPYTHONPREFIXES unless we can and it's preferred or necesary (due to use of multi_deps) + use_ebpythonprefixes = False + multi_deps = self.cfg['multi_deps'] + + if 'Python' in runtime_deps: + self.log.info("Found Python runtime dependency, so considering $EBPYTHONPREFIXES...") + + if build_option('prefer_python_search_path') == EBPYTHONPREFIXES: + self.log.info("Preferred Python search path is $EBPYTHONPREFIXES, so using that") + use_ebpythonprefixes = True + + elif multi_deps and 'Python' in multi_deps: + self.log.info("Python is listed in 'multi_deps', so using $EBPYTHONPREFIXES instead of $PYTHONPATH") + use_ebpythonprefixes = True if python_paths: # add paths unless they were already added diff --git a/easybuild/framework/easyconfig/default.py b/easybuild/framework/easyconfig/default.py index db1e12c324..438bcea4e1 100644 --- a/easybuild/framework/easyconfig/default.py +++ b/easybuild/framework/easyconfig/default.py @@ -115,7 +115,6 @@ 'patches': [[], "List of patches to apply", BUILD], 'prebuildopts': ['', 'Extra options pre-passed to build command.', BUILD], 'preconfigopts': ['', 'Extra options pre-passed to configure.', BUILD], - 'force_pythonpath': [False, "Force use of PYTHONPATH for python seearch path when possible.", BUILD], 'preinstallopts': ['', 'Extra prefix options for installation.', BUILD], 'pretestopts': ['', 'Extra prefix options for test.', BUILD], 'postinstallcmds': [[], 'Commands to run after the install step.', BUILD], diff --git a/test/framework/toy_build.py b/test/framework/toy_build.py index 76ef640b29..edd9e94fcc 100644 --- a/test/framework/toy_build.py +++ b/test/framework/toy_build.py @@ -4242,15 +4242,16 @@ def test_toy_python(self): """ Test whether $PYTHONPATH or $EBPYTHONPREFIXES are set correctly. """ - # generate fake Python module that we can use as runtime dependency for toy + # generate fake Python modules that we can use as runtime dependency for toy # (required condition for use of $EBPYTHONPREFIXES) fake_mods_path = os.path.join(self.test_prefix, 'modules') - fake_python_mod = os.path.join(fake_mods_path, 'Python', '3.6') - if get_module_syntax() == 'Lua': - fake_python_mod += '.lua' - write_file(fake_python_mod, '') - else: - write_file(fake_python_mod, '#%Module') + for pyver in ('2.7', '3.6'): + fake_python_mod = os.path.join(fake_mods_path, 'Python', pyver) + if get_module_syntax() == 'Lua': + fake_python_mod += '.lua' + write_file(fake_python_mod, '') + else: + write_file(fake_python_mod, '#%Module') self.modtool.use(fake_mods_path) test_ecs = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'test_ecs') @@ -4284,8 +4285,8 @@ def test_toy_python(self): self.assertTrue(pythonpath_regex.search(toy_mod_txt), f"Pattern '{pythonpath_regex.pattern}' found in: {toy_mod_txt}") - test_ec_txt += "\ndependencies = [('Python', '3.6', '', SYSTEM)]" - write_file(test_ec, test_ec_txt) + # if Python is listed as runtime dependency, then $EBPYTHONPREFIXES is used if it's preferred + write_file(test_ec, test_ec_txt + "\ndependencies = [('Python', '3.6', '', SYSTEM)]") self.run_test_toy_build_with_output(ec_file=test_ec, extra_args=args) toy_mod_txt = read_file(toy_mod) @@ -4293,13 +4294,13 @@ def test_toy_python(self): self.assertTrue(ebpythonprefixes_regex.search(toy_mod_txt), f"Pattern '{ebpythonprefixes_regex.pattern}' found in: {toy_mod_txt}") - test_ec_txt += "\nforce_pythonpath = True" - write_file(test_ec, test_ec_txt) + # if Python is listed in multi_deps, then $EBPYTHONPREFIXES is used, even if it's not explicitely preferred + write_file(test_ec, test_ec_txt + "\nmulti_deps = {'Python': ['2.7', '3.6']}") self.run_test_toy_build_with_output(ec_file=test_ec) toy_mod_txt = read_file(toy_mod) - self.assertTrue(pythonpath_regex.search(toy_mod_txt), - f"Pattern '{pythonpath_regex.pattern}' found in: {toy_mod_txt}") + self.assertTrue(ebpythonprefixes_regex.search(toy_mod_txt), + f"Pattern '{ebpythonprefixes_regex.pattern}' found in: {toy_mod_txt}") def suite():