Skip to content

Commit f979cad

Browse files
committed
Fix reporting of step name
The step method is a method returning the actual method. The `Bundle` easyblock uses a `getattr` call there instead of the method name. As the reflection looks at local name(s) it will find the `getattr` instead of the actual method. Access the `__name__` property of the returned function instead so we will always get the right name no matter how the lambda/method is defined.
1 parent 87b3d9d commit f979cad

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

easybuild/framework/easyblock.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4662,18 +4662,19 @@ def run_step(self, step, step_methods):
46624662
run_hook(step, self.hooks, pre_step_hook=True, args=[self])
46634663

46644664
for step_method in step_methods:
4665+
# step_method is a lambda function that takes an EasyBlock instance as an argument,
4666+
# and returns the actual method
4667+
current_method = step_method(self)
46654668
# Remove leading underscore from e.g. "_test_step"
4666-
method_name = '_'.join(step_method.__code__.co_names).lstrip('_')
4669+
method_name = current_method.__name__.lstrip('_')
46674670
self.log.info("Running method %s part of step %s", method_name, step)
46684671

46694672
if self.dry_run:
46704673
self.dry_run_msg("[%s method]", method_name)
46714674

46724675
# if an known possible error occurs, just report it and continue
46734676
try:
4674-
# step_method is a lambda function that takes an EasyBlock instance as an argument,
4675-
# and returns the actual method, so use () to execute it
4676-
step_method(self)()
4677+
current_method()
46774678
except Exception as err:
46784679
if build_option('extended_dry_run_ignore_errors'):
46794680
dry_run_warning("ignoring error %s" % err, silent=self.silent)
@@ -4682,9 +4683,7 @@ def run_step(self, step, step_methods):
46824683
raise
46834684
self.dry_run_msg('')
46844685
else:
4685-
# step_method is a lambda function that takes an EasyBlock instance as an argument,
4686-
# and returns the actual method, so use () to execute it
4687-
step_method(self)()
4686+
current_method()
46884687

46894688
run_hook(step, self.hooks, post_step_hook=True, args=[self])
46904689

test/framework/easyblock.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
import easybuild.tools.systemtools as st
4444
from easybuild.base import fancylogger
45-
from easybuild.framework.easyblock import EasyBlock, get_easyblock_instance
45+
from easybuild.framework.easyblock import EasyBlock, get_easyblock_instance, BUILD_STEP
4646
from easybuild.framework.easyconfig import CUSTOM
4747
from easybuild.framework.easyconfig.easyconfig import EasyConfig, ITERATE_OPTIONS
4848
from easybuild.framework.easyconfig.tools import avail_easyblocks, process_easyconfig
@@ -3555,6 +3555,43 @@ def test_create_easyblock_without_logfile(self):
35553555

35563556
os.remove(eb.logfile)
35573557

3558+
def test_report_current_step_method(self):
3559+
testdir = os.path.abspath(os.path.dirname(__file__))
3560+
toy_ec = os.path.join(testdir, 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
3561+
3562+
class MockEasyBlock(EasyBlock):
3563+
# Mock methods
3564+
def build_step(self):
3565+
self.log.info('Ran build')
3566+
3567+
def test_step(self):
3568+
self.log.info('Ran test')
3569+
3570+
# New method for easy detection
3571+
def custom_step(self):
3572+
self.log.info('Ran custom')
3573+
3574+
eb = MockEasyBlock(EasyConfig(toy_ec))
3575+
# Part of run_all_steps
3576+
steps = [step for step in eb.get_steps() if step[0] == BUILD_STEP]
3577+
for step_name, _, step_methods, _ in steps:
3578+
with self.log_to_testlogfile():
3579+
eb.run_step(step_name, step_methods)
3580+
logtxt = read_file(self.logfile)
3581+
self.assertIn('Running method build_step', logtxt)
3582+
self.assertIn('Ran build', logtxt)
3583+
3584+
method_name = 'custom_step'
3585+
step_name = 'new name'
3586+
# Run multiple methods in one step, the custom step uses getattr similar to the Bundle easyblock
3587+
with self.log_to_testlogfile():
3588+
eb.run_step(step_name, [lambda x: x.test_step, lambda x: getattr(x, method_name)])
3589+
logtxt = read_file(self.logfile)
3590+
self.assertRegex(logtxt, f'Running method test_step .* {step_name}')
3591+
self.assertIn('Ran test', logtxt)
3592+
self.assertRegex(logtxt, f'Running method {method_name} .* {step_name}')
3593+
self.assertIn('Ran custom', logtxt)
3594+
35583595

35593596
def suite():
35603597
""" return all the tests in this file """

0 commit comments

Comments
 (0)