3131 # from .errors:
3232 'InvalidKeywordOption' , 'KeywordNotDefined' ]
3333
34+ import sys
35+ from six import reraise
3436from itertools import chain
3537from textwrap import dedent
3638
@@ -147,19 +149,20 @@ def __call__(self, *args, **kwargs):
147149 except KeyError :
148150 pass
149151 else :
150- current_sessions [identifier , plural_identifier ] = getattr (
151- self .libinstance , identifier )
152+ previous = getattr (self .libinstance , identifier )
152153 switch = getattr (self .libinstance , 'switch_' + identifier )
153154 try :
154155 switch (sname )
155156 except hcls .SessionError :
156157 error = sys .exc_info ()
157158 # don't switch any more sessions
158159 break
160+ # store previous session for switching back later
161+ current_sessions [identifier , plural_identifier ] = previous
159162 # only perform explicit context switching
160163 # if explicit session switching didn't raise any error
164+ current_contexts = {}
161165 if error is None :
162- current_contexts = {}
163166 for hcls in self .context_handlers :
164167 if not getattr (hcls , 'auto_explicit' , False ):
165168 continue
@@ -169,8 +172,7 @@ def __call__(self, *args, **kwargs):
169172 except KeyError :
170173 pass
171174 else :
172- current_contexts [identifier ] = getattr (
173- self .libinstance , identifier )
175+ previous = getattr (self .libinstance , identifier )
174176 switch = getattr (self .libinstance ,
175177 'switch_' + identifier )
176178 try :
@@ -179,6 +181,10 @@ def __call__(self, *args, **kwargs):
179181 error = sys .exc_info ()
180182 # don't switch any more contexts
181183 break
184+ # store previous context for switching back later
185+ current_contexts [identifier ] = previous
186+ # only call the acutal keyword func
187+ # if explicit session and context switching didn't raise any error
182188 if error is None :
183189 # Look for arg type specs:
184190 if func .argtypes :
@@ -216,17 +222,27 @@ def __call__(self, *args, **kwargs):
216222 ** kwargs )
217223 except :
218224 error = sys .exc_info ()
219- # Switch back contexts and sessions (reverse order):
225+ # finally try to switch back contexts and sessions (in reverse order)
226+ # before either returning result or reraising any error catched above
220227 for identifier , ctxname in dictitems (current_contexts ):
221- getattr (self .libinstance , 'switch_' + identifier )(ctxname )
228+ switch = getattr (self .libinstance , 'switch_' + identifier )
229+ # don't catch anything here. just step out on error
230+ switch (ctxname )
222231 for (identifier , plural_identifier ), session in dictitems (
223232 current_sessions
224233 ):
225234 for sname , sinstance in dictitems (getattr (
226235 self .libinstance , plural_identifier
227236 )):
228237 if sinstance is session :
229- getattr (self .libinstance , 'switch_' + identifier )(sname )
238+ switch = getattr (self .libinstance , 'switch_' + identifier )
239+ # don't catch anything here. just step out on error
240+ switch (sname )
241+ # was an error catched on initial session or context switching
242+ # or on calling the actual keyword func?
243+ if error is not None :
244+ reraise (* error )
245+ # great! everything went fine :)
230246 return result
231247
232248 def __repr__ (self ):
0 commit comments