B s `@sdZddlmZddlmZddlmZddlZddlZddlmZej Z ddZ e fd d Z e fd d Z d dZ GdddeZddZdS)agDecorator and context manager for saving and restoring flag values. There are many ways to save and restore. Always use the most convenient method for a given use case. Here are examples of each method. They all call do_stuff() while FLAGS.someflag is temporarily set to 'foo'. from absl.testing import flagsaver # Use a decorator which can optionally override flags via arguments. @flagsaver.flagsaver(someflag='foo') def some_func(): do_stuff() # Use a decorator which does not override flags itself. @flagsaver.flagsaver def some_func(): FLAGS.someflag = 'foo' do_stuff() # Use a context manager which can optionally override flags via arguments. with flagsaver.flagsaver(someflag='foo'): do_stuff() # Save and restore the flag values yourself. saved_flag_values = flagsaver.save_flag_values() try: FLAGS.someflag = 'foo' do_stuff() finally: flagsaver.restore_flag_values(saved_flag_values) We save and restore a shallow copy of each Flag object's __dict__ attribute. This preserves all attributes of the flag, such as whether or not it was overridden from its default value. WARNING: Currently a flag that is saved and then deleted cannot be restored. An exception will be raised. However if you *add* a flag after saving flag values, and then restore flag values, the added flag will be deleted with no errors. )absolute_import)division)print_functionN)flagscOsV|stf|St|dkrJ|r&td|d}t|r@tdt|iStddS)z7The main flagsaver interface. See module doc for usage.z?It's invalid to specify both positional and keyword parameters.rz2@flagsaver.flagsaver cannot be applied to a class.z`sz$save_flag_values..r)rr)rrsave_flag_valuesVs rcCsbt|}xT|D]L}||}|dkr0t||q||j|dkrP|d||_|||_qWdS)aRestores flag values based on the dictionary of flag values. Args: saved_flag_values: {'flag_name': value_dict, ...} flag_values: FlagValues, the FlagValues instance from which the flag will be restored. This should almost never need to be overridden. N_value)listgetdelattrvalue__dict__)Zsaved_flag_valuesrZnew_flag_namesrZsavedrrrrestore_flag_valuescs   r cstfdd}|S)a[Creates a wrapper function that saves/restores flag values. Args: func: function object - This will be called between saving flags and restoring flags. overrides: {str: object} - Flag names mapped to their values. These flags will be set after saving the original flag state. Returns: return value from func() c s tf ||SQRXdS)z/Wrapper function that saves and restores flags.N)r)rr)r overridesrr_flagsaver_wrappers z!_wrap.._flagsaver_wrapper) functoolswraps)rr!r"r)rr!rr ws r c@s0eZdZdZddZddZddZdd Zd S) rzOverrides flags for the duration of the decorated function call. It also restores all original values of flags after decorated method completes. cKs||_d|_dS)N) _overrides_saved_flag_values)selfr!rrr__init__sz_FlagOverrider.__init__cCst|rtdt||jS)Nz'flagsaver cannot be applied to a class.)r r r r r%)r'rrrr__call__s z_FlagOverrider.__call__cCs<tt|_ytjf|jWnt|jtYnXdS)N)rFLAGSr&Z_set_attributesr%r )r'rrr __enter__s   z_FlagOverrider.__enter__cCst|jtdS)N)r r&r*)r'exc_type exc_value tracebackrrr__exit__sz_FlagOverrider.__exit__N)__name__ __module__ __qualname____doc__r(r)r+r/rrrrrs  rcCs&|j}|j|d<t|j|d<|S)aReturns a copy of the flag object's __dict__. It's mostly a shallow copy of the __dict__, except it also does a shallow copy of the validator list. Args: flag: flags.Flag, the flag to copy. Returns: A copy of the flag object's __dict__. r validators)rcopyrrr4)flagr5rrrrs  r)r3 __future__rrrr#r Zabslrr*rrr r objectrrrrrr7s