<s> import abc <EOL> import enum <EOL> import six <EOL> from taskflow import atom <EOL> from taskflow import exceptions as exc <EOL> from taskflow . utils import misc <EOL> @ enum . unique <EOL> class Decision ( misc . StrEnum ) : <EOL> """<STR_LIT>""" <EOL> REVERT = "<STR_LIT>" <EOL> """<STR_LIT>""" <EOL> REVERT_ALL = "<STR_LIT>" <EOL> """<STR_LIT>""" <EOL> RETRY = "<STR_LIT>" <EOL> REVERT = Decision . REVERT <EOL> REVERT_ALL = Decision . REVERT_ALL <EOL> RETRY = Decision . RETRY <EOL> EXECUTE_REVERT_HISTORY = '<STR_LIT>' <EOL> REVERT_FLOW_FAILURES = '<STR_LIT>' <EOL> class History ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , contents , failure = None ) : <EOL> self . _contents = contents <EOL> self . _failure = failure <EOL> @ property <EOL> def failure ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _failure <EOL> def outcomes_iter ( self , index = None ) : <EOL> """<STR_LIT>""" <EOL> if index is None : <EOL> contents = self . _contents <EOL> else : <EOL> contents = [ <EOL> self . _contents [ index ] , <EOL> ] <EOL> for ( provided , outcomes ) in contents : <EOL> for ( owner , outcome ) in six . iteritems ( outcomes ) : <EOL> yield ( owner , outcome ) <EOL> def __len__ ( self ) : <EOL> return len ( self . _contents ) <EOL> def provided_iter ( self ) : <EOL> """<STR_LIT>""" <EOL> for ( provided , outcomes ) in self . _contents : <EOL> yield provided <EOL> def __getitem__ ( self , index ) : <EOL> return self . _contents [ index ] <EOL> def caused_by ( self , exception_cls , index = None , include_retry = False ) : <EOL> """<STR_LIT>""" <EOL> for ( name , failure ) in self . outcomes_iter ( index = index ) : <EOL> if failure . check ( exception_cls ) : <EOL> return True <EOL> if include_retry and self . _failure is not None : <EOL> if self . _failure . check ( exception_cls ) : <EOL> return True <EOL> return False <EOL> def __iter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return iter ( self . _contents ) <EOL> @ six . add_metaclass ( abc . ABCMeta ) <EOL> class Retry ( atom . Atom ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name = None , provides = None , requires = None , <EOL> auto_extract = True , rebind = None ) : <EOL> super ( Retry , self ) . __init__ ( name = name , provides = provides , <EOL> requires = requires , rebind = rebind , <EOL> auto_extract = auto_extract , <EOL> ignore_list = [ EXECUTE_REVERT_HISTORY ] ) <EOL> @ property <EOL> def name ( self ) : <EOL> return self . _name <EOL> @ name . setter <EOL> def name ( self , name ) : <EOL> self . _name = name <EOL> @ abc . abstractmethod <EOL> def execute ( self , history , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> def revert ( self , history , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> @ abc . abstractmethod <EOL> def on_failure ( self , history , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> class AlwaysRevert ( Retry ) : <EOL> """<STR_LIT>""" <EOL> def on_failure ( self , * args , ** kwargs ) : <EOL> return REVERT <EOL> def execute ( self , * args , ** kwargs ) : <EOL> pass <EOL> class AlwaysRevertAll ( Retry ) : <EOL> """<STR_LIT>""" <EOL> def on_failure ( self , ** kwargs ) : <EOL> return REVERT_ALL <EOL> def execute ( self , ** kwargs ) : <EOL> pass <EOL> class Times ( Retry ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , attempts = <NUM_LIT:1> , name = None , provides = None , requires = None , <EOL> auto_extract = True , rebind = None , revert_all = False ) : <EOL> super ( Times , self ) . __init__ ( name , provides , requires , <EOL> auto_extract , rebind ) <EOL> self . _attempts = attempts <EOL> if revert_all : <EOL> self . _revert_action = REVERT_ALL <EOL> else : <EOL> self . _revert_action = REVERT <EOL> def on_failure ( self , history , * args , ** kwargs ) : <EOL> if len ( history ) < self . _attempts : <EOL> return RETRY <EOL> return self . _revert_action <EOL> def execute ( self , history , * args , ** kwargs ) : <EOL> return len ( history ) + <NUM_LIT:1> <EOL> class ForEachBase ( Retry ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name = None , provides = None , requires = None , <EOL> auto_extract = True , rebind = None , revert_all = False ) : <EOL> super ( ForEachBase , self ) . __init__ ( name , provides , requires , <EOL> auto_extract , rebind ) <EOL> if revert_all : <EOL> self . _revert_action = REVERT_ALL <EOL> else : <EOL> self . _revert_action = REVERT <EOL> def _get_next_value ( self , values , history ) : <EOL> remaining = misc . sequence_minus ( values , history . provided_iter ( ) ) <EOL> if not remaining : <EOL> raise exc . NotFound ( "<STR_LIT>" <EOL> "<STR_LIT>" % self . name ) <EOL> return remaining [ <NUM_LIT:0> ] <EOL> def _on_failure ( self , values , history ) : <EOL> try : <EOL> self . _get_next_value ( values , history ) <EOL> except exc . NotFound : <EOL> return self . _revert_action <EOL> else : <EOL> return RETRY <EOL> class ForEach ( ForEachBase ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , values , name = None , provides = None , requires = None , <EOL> auto_extract = True , rebind = None , revert_all = False ) : <EOL> super ( ForEach , self ) . __init__ ( name , provides , requires , <EOL> auto_extract , rebind , revert_all ) <EOL> self . _values = values <EOL> def on_failure ( self , history , * args , ** kwargs ) : <EOL> return self . _on_failure ( self . _values , history ) <EOL> def execute ( self , history , * args , ** kwargs ) : <EOL> return self . _get_next_value ( self . _values , history ) <EOL> class ParameterizedForEach ( ForEachBase ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , name = None , provides = None , requires = None , <EOL> auto_extract = True , rebind = None , revert_all = False ) : <EOL> super ( ParameterizedForEach , self ) . __init__ ( name , provides , requires , <EOL> auto_extract , rebind , <EOL> revert_all ) <EOL> def on_failure ( self , values , history , * args , ** kwargs ) : <EOL> return self . _on_failure ( values , history ) <EOL> def execute ( self , values , history , * args , ** kwargs ) : <EOL> return self . _get_next_value ( values , history ) </s>
