Skip to content

Commit 9bd98ce

Browse files
author
Vasileios Karakasis
authored
Merge pull request #2287 from vkarak/bugfix/hook-exec-order-same-class
[bugfix] Fix hook execution order for hooks in the same class
2 parents 30346e0 + bd4c5ae commit 9bd98ce

File tree

4 files changed

+17
-12
lines changed

4 files changed

+17
-12
lines changed

reframe/core/hooks.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,19 @@ def add(self, v):
156156
v._rfm_attach = ['post_setup']
157157
self.__hooks.add(Hook(v))
158158

159-
def update(self, hooks, *, denied_hooks=None):
159+
def update(self, other, *, denied_hooks=None):
160160
'''Update the hook registry with the hooks from another hook registry.
161161
162162
The optional ``denied_hooks`` argument takes a set of disallowed
163163
hook names, preventing their inclusion into the current hook registry.
164164
'''
165+
166+
assert isinstance(other, HookRegistry)
165167
denied_hooks = denied_hooks or set()
166-
for h in hooks:
168+
for h in other:
167169
if h.__name__ not in denied_hooks:
170+
# Hooks in `other` override ours
171+
self.__hooks.discard(h)
168172
self.__hooks.add(h)
169173

170174
def __repr__(self):

reframe/core/meta.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,15 @@ def __init__(cls, name, bases, namespace, **kwargs):
411411
cls._rfm_dir.update(cls.__dict__)
412412

413413
# Populate the global hook registry with the hook registries of the
414-
# parent classes in MRO order
415-
cls._rfm_hook_registry.update(cls._rfm_local_hook_registry)
416-
for c in cls.mro()[1:]:
414+
# parent classes in reverse MRO order
415+
for c in list(reversed(cls.mro()))[:-1]:
417416
if hasattr(c, '_rfm_local_hook_registry'):
418417
cls._rfm_hook_registry.update(
419418
c._rfm_local_hook_registry, denied_hooks=namespace
420419
)
421420

421+
cls._rfm_hook_registry.update(cls._rfm_local_hook_registry)
422+
422423
# Search the bases if no local sanity functions exist.
423424
if '_rfm_sanity' not in namespace:
424425
for base in cls._rfm_bases:

reframe/core/pipeline.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,11 @@ def disable_hook(self, hook_name):
197197

198198
@classmethod
199199
def pipeline_hooks(cls):
200-
# The hook registry stores hooks in MRO order, but we want to attach
201-
# the hooks in reverse order so that the more specialized hooks (those
202-
# at the beginning of the MRO list) will be executed last
203-
204200
ret = {}
205201
for hook in cls._rfm_hook_registry:
206202
for stage in hook.stages:
207203
try:
208-
ret[stage].insert(0, hook.fn)
204+
ret[stage].append(hook.fn)
209205
except KeyError:
210206
ret[stage] = [hook.fn]
211207

unittests/test_pipeline.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,15 +753,19 @@ class DerivedTest(BaseTest, C):
753753
def z(self):
754754
self.var += 1
755755

756+
@run_after('setup')
757+
def w(self):
758+
self.var += 1
759+
756760
class MyTest(DerivedTest):
757761
pass
758762

759763
test = MyTest()
760764
_run(test, *local_exec_ctx)
761-
assert test.var == 2
765+
assert test.var == 3
762766
assert test.foo == 1
763767
assert test.pipeline_hooks() == {
764-
'post_setup': [BaseTest.x, DerivedTest.z],
768+
'post_setup': [BaseTest.x, DerivedTest.z, DerivedTest.w],
765769
'pre_run': [C.y],
766770
}
767771

0 commit comments

Comments
 (0)