Skip to content

Commit fc9cd40

Browse files
committed
Make specifying exts_defaultclass optional
It is NOT required when all extensions have either custom easyblocks or an `easyblock` key in their option dict. In those cases `exts_defaultclass` is redundant making it harder to write the EasyConfig. Check for a missing easyblock when actually using it so the error will be just a bit later but still (almost) the same.
1 parent b74ab1f commit fc9cd40

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

easybuild/framework/easyblock.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,8 +3086,10 @@ def init_ext_instances(self):
30863086
# proper way: derive module path from specified class name
30873087
default_class = exts_defaultclass
30883088
default_class_modpath = get_module_path(default_class, generic=True)
3089+
elif exts_defaultclass is None:
3090+
default_class = default_class_modpath = None
30893091
else:
3090-
error_msg = "Improper default extension class specification, should be string: %s (%s)"
3092+
error_msg = "Improper default extension class specification, should be string or None: %s (%s)"
30913093
raise EasyBuildError(error_msg, exts_defaultclass, type(exts_defaultclass))
30923094

30933095
exts_cnt = len(self.exts)
@@ -3139,8 +3141,11 @@ def init_ext_instances(self):
31393141
"for extension %s: %s",
31403142
class_name, mod_path, ext_name, err)
31413143

3142-
# fallback attempt: use default class
3144+
# fallback attempt: use default class if any
31433145
if inst is None:
3146+
if not default_class:
3147+
raise EasyBuildError("ERROR: No default extension class set for %s and no explicit or custom "
3148+
"easyblock found for extension %s", self.name, ext_name)
31443149
try:
31453150
cls = get_class_for(default_class_modpath, default_class)
31463151
self.log.debug("Obtained class %s for installing extension %s", cls, ext_name)
@@ -3176,10 +3181,6 @@ def extensions_step(self, fetch=False, install=True):
31763181
self.log.debug("No extensions in exts_list")
31773182
return
31783183

3179-
# we really need a default class
3180-
if not self.cfg['exts_defaultclass'] and install:
3181-
raise EasyBuildError("ERROR: No default extension class set for %s", self.name)
3182-
31833184
start_progress_bar(PROGRESS_BAR_EXTENSIONS, len(self.cfg.get_ref('exts_list')))
31843185

31853186
self.prepare_for_extensions()

test/framework/easyconfig.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,46 @@ def test_exts_list(self):
540540
regex = re.compile('EBEXTSLISTPI.*"ext1-1.0,ext2-2.0,ext-PI-3.14,ext-pi-3.0')
541541
self.assertTrue(regex.search(modtxt), "Pattern '%s' found in: %s" % (regex.pattern, modtxt))
542542

543+
def test_extensions_default_class(self):
544+
"""Test that exts_defaultclass doesn't need to be specified if explicit one is present."""
545+
546+
init_config(build_options={'silent': True})
547+
548+
self.contents = textwrap.dedent("""
549+
easyblock = "ConfigureMake"
550+
name = "PI"
551+
version = "3.14"
552+
homepage = "http://example.com"
553+
description = "test easyconfig"
554+
toolchain = SYSTEM
555+
exts_list = [
556+
("toy", "0.0"), # Custom block by name
557+
("bar", "0.0", { # Explicit
558+
'easyblock': 'EB_toy',
559+
'sources': ['toy-%(version)s.tar.gz'],
560+
}),
561+
]
562+
""")
563+
self.prep()
564+
# Ensure source is found
565+
toy_tar_gz = os.path.join(self.test_sourcepath, 'toy', 'toy-0.0.tar.gz')
566+
copy_file(toy_tar_gz, self.test_prefix)
567+
os.environ['EASYBUILD_SOURCEPATH'] = self.test_prefix
568+
init_config(build_options={'silent': True})
569+
570+
ec = EasyConfig(self.eb_file)
571+
eb = EasyBlock(ec)
572+
eb.fetch_step()
573+
with self.mocked_stdout_stderr():
574+
eb.extensions_step()
575+
576+
pi_installdir = os.path.join(self.test_installpath, 'software', 'PI', '3.14')
577+
578+
# check whether files expected to be installed for both extensions are in place
579+
self.assertExists(os.path.join(pi_installdir, 'bin', 'toy'))
580+
self.assertExists(os.path.join(pi_installdir, 'lib', 'libtoy.a'))
581+
self.assertExists(os.path.join(pi_installdir, 'lib', 'libbar.a'))
582+
543583
def test_extensions_templates(self):
544584
"""Test whether templates used in exts_list are resolved properly."""
545585

@@ -562,7 +602,6 @@ def test_extensions_templates(self):
562602
'description = "test easyconfig"',
563603
'toolchain = SYSTEM',
564604
'dependencies = [("Python", "3.6.6")]',
565-
'exts_defaultclass = "EB_Toy"',
566605
# bogus, but useful to check whether this get resolved
567606
'exts_default_options = {"source_urls": [PYPI_SOURCE]}',
568607
'exts_list = [',

0 commit comments

Comments
 (0)