Skip to content

Commit f9fb262

Browse files
committed
run pip check only once for PythonBundle
1 parent 3ca1f1a commit f9fb262

File tree

2 files changed

+192
-157
lines changed

2 files changed

+192
-157
lines changed

easybuild/easyblocks/generic/pythonbundle.py

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@
2828
@author: Kenneth Hoste (Ghent University)
2929
"""
3030
import os
31-
import sys
3231

3332
from easybuild.easyblocks.generic.bundle import Bundle
3433
from easybuild.easyblocks.generic.pythonpackage import EBPYTHONPREFIXES, EXTS_FILTER_PYTHON_PACKAGES
35-
from easybuild.easyblocks.generic.pythonpackage import PythonPackage, get_pylibdirs, pick_python_cmd
34+
from easybuild.easyblocks.generic.pythonpackage import PythonPackage, get_pylibdirs, find_python_cmd, run_pip_check
3635
from easybuild.tools.build_log import EasyBuildError
37-
from easybuild.tools.filetools import which
3836
from easybuild.tools.modules import get_software_root
3937
import easybuild.tools.environment as env
4038

@@ -74,49 +72,33 @@ def __init__(self, *args, **kwargs):
7472

7573
self.log.info("exts_default_options: %s", self.cfg['exts_default_options'])
7674

75+
self.python_cmd = None
7776
self.pylibdir = None
78-
self.all_pylibdirs = []
77+
self.all_pylibdirs = None
7978

8079
# figure out whether this bundle of Python packages is being installed for multiple Python versions
8180
self.multi_python = 'Python' in self.cfg['multi_deps']
8281

83-
def prepare_step(self, *args, **kwargs):
84-
"""Prepare for installing bundle of Python packages."""
85-
super(Bundle, self).prepare_step(*args, **kwargs)
82+
def prepare_python(self):
83+
"""Python-specific preparations."""
8684

87-
python_root = get_software_root('Python')
88-
if python_root is None:
85+
if get_software_root('Python') is None:
8986
raise EasyBuildError("Python not included as dependency!")
87+
self.python_cmd = find_python_cmd(self.log, self.cfg['req_py_majver'], self.cfg['req_py_minver'], required=True)
9088

91-
# when system Python is used, the first 'python' command in $PATH will not be $EBROOTPYTHON/bin/python,
92-
# since $EBROOTPYTHON is set to just 'Python' in that case
93-
# (see handling of allow_system_deps in EasyBlock.prepare_step)
94-
if which('python') == os.path.join(python_root, 'bin', 'python'):
95-
# if we're using a proper Python dependency, let det_pylibdir use 'python' like it does by default
96-
python_cmd = None
97-
else:
98-
# since det_pylibdir will use 'python' by default as command to determine Python lib directory,
99-
# we need to intervene when the system Python is used, by specifying version requirements
100-
# to pick_python_cmd so the right 'python' command is used;
101-
# if we're using the system Python and no Python version requirements are specified,
102-
# use major/minor version of Python being used in this EasyBuild session (as we also do in PythonPackage)
103-
req_py_majver = self.cfg['req_py_majver']
104-
if req_py_majver is None:
105-
req_py_majver = sys.version_info[0]
106-
req_py_minver = self.cfg['req_py_minver']
107-
if req_py_minver is None:
108-
req_py_minver = sys.version_info[1]
109-
110-
python_cmd = pick_python_cmd(req_maj_ver=req_py_majver, req_min_ver=req_py_minver)
111-
112-
self.all_pylibdirs = get_pylibdirs(python_cmd=python_cmd)
89+
self.all_pylibdirs = get_pylibdirs(python_cmd=self.python_cmd)
11390
self.pylibdir = self.all_pylibdirs[0]
11491

11592
# if 'python' is not used, we need to take that into account in the extensions filter
11693
# (which is also used during the sanity check)
117-
if python_cmd:
94+
if self.python_cmd != 'python':
11895
orig_exts_filter = EXTS_FILTER_PYTHON_PACKAGES
119-
self.cfg['exts_filter'] = (orig_exts_filter[0].replace('python', python_cmd), orig_exts_filter[1])
96+
self.cfg['exts_filter'] = (orig_exts_filter[0].replace('python', self.python_cmd), orig_exts_filter[1])
97+
98+
def prepare_step(self, *args, **kwargs):
99+
"""Prepare for installing bundle of Python packages."""
100+
super(Bundle, self).prepare_step(*args, **kwargs)
101+
self.prepare_python()
120102

121103
def extensions_step(self, *args, **kwargs):
122104
"""Install extensions (usually PythonPackages)"""
@@ -158,6 +140,13 @@ def make_module_extra(self, *args, **kwargs):
158140
def sanity_check_step(self, *args, **kwargs):
159141
"""Custom sanity check for bundle of Python package."""
160142

143+
if self.pylibdir is None:
144+
# Python attributes not set up yet, happens e.g. with --sanity-check-only
145+
# Load module first to get the right python command
146+
self.fake_mod_data = self.sanity_check_load_module(extension=kwargs.get('extension', False),
147+
extra_modules=kwargs.get('extra_modules', None))
148+
self.prepare_python()
149+
161150
# inject directory path that uses %(pyshortver)s template into default value for sanity_check_paths
162151
# this is relevant for installations of Python bundles for multiple Python versions (via multi_deps)
163152
# (we can not pass this via custom_paths, since then the %(pyshortver)s template value will not be resolved)
@@ -168,3 +157,24 @@ def sanity_check_step(self, *args, **kwargs):
168157
}
169158

170159
super(Bundle, self).sanity_check_step(*args, **kwargs)
160+
161+
# After the super-call self.ext_instances is initialized, so we can check the extensions
162+
sanity_pip_check = self.cfg['sanity_pip_check']
163+
unversioned_packages = set(self.cfg['unversioned_packages'])
164+
has_sanity_pip_check_mismatch = False
165+
all_unversioned_packages = unversioned_packages.copy()
166+
for ext in self.ext_instances:
167+
if isinstance(ext, PythonPackage):
168+
if ext.cfg['sanity_pip_check'] != sanity_pip_check:
169+
has_sanity_pip_check_mismatch = True
170+
all_unversioned_packages.update(ext.cfg['unversioned_packages'])
171+
172+
if has_sanity_pip_check_mismatch:
173+
self.log.deprecated('For bundles of PythonPackage the sanity_pip_check option '
174+
'in the main EasyConfig must be used', '5.0')
175+
sanity_pip_check = True # Either the main set it or any extension enabled it
176+
if all_unversioned_packages != unversioned_packages:
177+
self.log.deprecated('For bundles of PythonPackage the unversioned_packages option '
178+
'in the main EasyConfig must be used', '5.0')
179+
if sanity_pip_check:
180+
run_pip_check(self.log, self.python_cmd, all_unversioned_packages)

0 commit comments

Comments
 (0)