99import reframe .utility as util
1010
1111
12+ def is_hook (func ):
13+ return hasattr (func , '_rfm_attach' )
14+
15+
16+ def is_dep_hook (func ):
17+ return hasattr (func , '_rfm_resolve_deps' )
18+
19+
1220def attach_to (phase ):
1321 '''Backend function to attach a hook to a given phase.
1422
1523 :meta private:
1624 '''
1725 def deco (func ):
18- if hasattr (func , '_rfm_attach' ):
26+ if is_hook (func ):
1927 func ._rfm_attach .append (phase )
2028 else :
2129 func ._rfm_attach = [phase ]
@@ -118,7 +126,7 @@ class Hook:
118126
119127 def __init__ (self , fn ):
120128 self .__fn = fn
121- if not hasattr (fn , '_rfm_attach' ):
129+ if not is_hook (fn ):
122130 raise ValueError (f'{ fn .__name__ } is not a hook' )
123131
124132 @property
@@ -152,7 +160,7 @@ class HookRegistry:
152160 '''Global hook registry.'''
153161
154162 def __init__ (self , hooks = None ):
155- self .__hooks = util . OrderedSet ()
163+ self .__hooks = []
156164 if hooks is not None :
157165 self .update (hooks )
158166
@@ -172,30 +180,36 @@ def add(self, v):
172180 of the pipeline where they must be attached. Dependencies will be
173181 resolved first in the post-setup phase if not assigned elsewhere.
174182 '''
175-
176- if hasattr (v , '_rfm_attach' ):
183+ if is_hook (v ):
177184 # Always override hooks with the same name
178185 h = Hook (v )
179- self .__hooks .discard (h )
180- self .__hooks .add (h )
181- elif hasattr (v , '_rfm_resolve_deps' ):
186+ try :
187+ pos = self .__hooks .index (h )
188+ except ValueError :
189+ self .__hooks .append (h )
190+ else :
191+ self .__hooks [pos ] = h
192+ elif is_dep_hook (v ):
182193 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.
194+ self .__hooks .append (Hook (v ))
187195
188- The optional ``denied_hooks`` argument takes a set of disallowed
189- hook names, preventing their inclusion into the current hook registry.
190- '''
196+ def update ( self , other , * , forbidden_names = None ):
197+ '''Update the hook registry with the hooks from another hook
198+ registry. '''
191199
192200 assert isinstance (other , HookRegistry )
193- denied_hooks = denied_hooks or set ()
201+ forbidden_names = forbidden_names or {}
194202 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 )
203+ if (h .__name__ in forbidden_names and
204+ not is_hook (forbidden_names [h .__name__ ])):
205+ continue
206+
207+ try :
208+ pos = self .__hooks .index (h )
209+ except ValueError :
210+ self .__hooks .append (h )
211+ else :
212+ self .__hooks [pos ] = h
199213
200214 def __repr__ (self ):
201215 return repr (self .__hooks )
0 commit comments