#NEWLINE# @ contextlib . contextmanager #NEWLINE# def swap_attr( obj , attr , new_val ) : #NEWLINE# #INDENT# 'Temporary swap out an attribute with a new object.\n\n    Usage:\n        with swap_attr(obj, "attr", 5):\n            ...\n\n        This will set obj.attr to 5 for the duration of the with: block,\n        restoring the old value at the end of the block. If `attr` doesn\'t\n        exist on `obj`, it will be created and then deleted at the end of the\n        block.\n    ' #NEWLINE# if hasattr ( obj , attr ) : #NEWLINE# #INDENT# real_val = getattr ( obj , attr ) #NEWLINE# setattr ( obj , attr , new_val ) #NEWLINE# try : #NEWLINE# #INDENT# ( yield ) #NEWLINE# #UNINDENT# finally : #NEWLINE# #INDENT# setattr ( obj , attr , obj ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# setattr ( obj , attr , new_val ) #NEWLINE# try : #NEWLINE# #INDENT# ( yield ) #NEWLINE# #UNINDENT# finally : #NEWLINE# #INDENT# delattr ( obj , attr )