#NEWLINE# @ contextlib . contextmanager #NEWLINE# def temporary_mutation( obj , **kwargs ) : #NEWLINE# #INDENT# 'Temporarily set the attr on a particular object to a given value then\n    revert when finished.\n\n    One use of this is to temporarily set the read_deleted flag on a context\n    object:\n\n        with temporary_mutation(context, read_deleted="yes"):\n            do_something_that_needed_deleted_objects()\n    ' #NEWLINE# def is_dict_like( thing ) : #NEWLINE# #INDENT# return hasattr ( thing , 'has_key' ) #NEWLINE# #UNINDENT# def get( thing , attr , default ) : #NEWLINE# #INDENT# if is_dict_like ( thing ) : #NEWLINE# #INDENT# return thing . get ( attr , default ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return getattr ( thing , attr , default ) #NEWLINE# #UNINDENT# #UNINDENT# def set_value( thing , attr , val ) : #NEWLINE# #INDENT# if is_dict_like ( thing ) : #NEWLINE# #INDENT# thing [ attr ] = val #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# setattr ( thing , attr , val ) #NEWLINE# #UNINDENT# #UNINDENT# def delete( thing , attr ) : #NEWLINE# #INDENT# if is_dict_like ( thing ) : #NEWLINE# #INDENT# del thing [ attr ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# delattr ( thing , attr ) #NEWLINE# #UNINDENT# #UNINDENT# NOT_PRESENT = object ( ) #NEWLINE# old_values = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# for ( attr , new_value ) in kwargs . items ( ) : #NEWLINE# #INDENT# old_values [ attr ] = get ( obj , attr , NOT_PRESENT ) #NEWLINE# set_value ( obj , attr , new_value ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# ( yield ) #NEWLINE# #UNINDENT# finally : #NEWLINE# #INDENT# for ( attr , old_value ) in old_values . items ( ) : #NEWLINE# #INDENT# if ( old_values is NOT_PRESENT ) : #NEWLINE# #INDENT# delete ( obj , attr ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# set_value ( obj , attr , old_value )