66import functools
77import inspect
88
9- import reframe .utility as util
9+
10+ def is_hook (func ):
11+ return hasattr (func , '_rfm_attach' )
12+
13+
14+ def is_dep_hook (func ):
15+ return hasattr (func , '_rfm_resolve_deps' )
1016
1117
1218def attach_to (phase ):
@@ -15,7 +21,7 @@ def attach_to(phase):
1521 :meta private:
1622 '''
1723 def deco (func ):
18- if hasattr (func , '_rfm_attach' ):
24+ if is_hook (func ):
1925 func ._rfm_attach .append (phase )
2026 else :
2127 func ._rfm_attach = [phase ]
@@ -118,7 +124,7 @@ class Hook:
118124
119125 def __init__ (self , fn ):
120126 self .__fn = fn
121- if not hasattr (fn , '_rfm_attach' ):
127+ if not is_hook (fn ):
122128 raise ValueError (f'{ fn .__name__ } is not a hook' )
123129
124130 @property
@@ -152,7 +158,7 @@ class HookRegistry:
152158 '''Global hook registry.'''
153159
154160 def __init__ (self , hooks = None ):
155- self .__hooks = util . OrderedSet ()
161+ self .__hooks = []
156162 if hooks is not None :
157163 self .update (hooks )
158164
@@ -172,30 +178,36 @@ def add(self, v):
172178 of the pipeline where they must be attached. Dependencies will be
173179 resolved first in the post-setup phase if not assigned elsewhere.
174180 '''
175-
176- if hasattr (v , '_rfm_attach' ):
181+ if is_hook (v ):
177182 # Always override hooks with the same name
178183 h = Hook (v )
179- self .__hooks .discard (h )
180- self .__hooks .add (h )
181- elif hasattr (v , '_rfm_resolve_deps' ):
184+ try :
185+ pos = self .__hooks .index (h )
186+ except ValueError :
187+ self .__hooks .append (h )
188+ else :
189+ self .__hooks [pos ] = h
190+ elif is_dep_hook (v ):
182191 v ._rfm_attach = ['post_setup' ]
183- self .__hooks .add (Hook (v ))
184-
185- def update (self , other , * , denied_hooks = None ):
186- '''Update the hook registry with the hooks from another hook registry.
192+ self .__hooks .append (Hook (v ))
187193
188- The optional ``denied_hooks`` argument takes a set of disallowed
189- hook names, preventing their inclusion into the current hook registry.
190- '''
194+ def update ( self , other , * , forbidden_names = None ):
195+ '''Update the hook registry with the hooks from another hook
196+ registry. '''
191197
192198 assert isinstance (other , HookRegistry )
193- denied_hooks = denied_hooks or set ()
199+ forbidden_names = forbidden_names or {}
194200 for h in other :
195- if h .__name__ not in denied_hooks :
196- # Hooks in `other` override ours
197- self .__hooks .discard (h )
198- self .__hooks .add (h )
201+ if (h .__name__ in forbidden_names and
202+ not is_hook (forbidden_names [h .__name__ ])):
203+ continue
204+
205+ try :
206+ pos = self .__hooks .index (h )
207+ except ValueError :
208+ self .__hooks .append (h )
209+ else :
210+ self .__hooks [pos ] = h
199211
200212 def __repr__ (self ):
201213 return repr (self .__hooks )
0 commit comments