<s> """<STR_LIT>""" <EOL> import sys <EOL> import types <EOL> import time <EOL> from functools import wraps <EOL> from concurrent import futures <EOL> from . tasks import Task , MultiTask , ProcessTask , MultiProcessTask <EOL> try : <EOL> from . gevent_tasks import GTask , MultiGTask <EOL> except ImportError : <EOL> GTask = MultiGTask = None <EOL> POOL_TIMEOUT = <NUM_LIT> <EOL> class ReturnResult ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , result ) : <EOL> super ( ReturnResult , self ) . __init__ ( ) <EOL> self . result = result <EOL> class Engine ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , pool_timeout = POOL_TIMEOUT ) : <EOL> """<STR_LIT>""" <EOL> self . pool_timeout = pool_timeout <EOL> self . main_app = None <EOL> def async ( self , func ) : <EOL> """<STR_LIT>""" <EOL> @ wraps ( func ) <EOL> def wrapper ( * args , ** kwargs ) : <EOL> gen = func ( * args , ** kwargs ) <EOL> if isinstance ( gen , types . GeneratorType ) : <EOL> return self . create_runner ( gen ) . run ( ) <EOL> return wrapper <EOL> def create_runner ( self , gen ) : <EOL> """<STR_LIT>""" <EOL> return Runner ( self , gen ) <EOL> def update_gui ( self ) : <EOL> """<STR_LIT>""" <EOL> time . sleep ( self . pool_timeout ) <EOL> class Runner ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , engine , gen ) : <EOL> """<STR_LIT>""" <EOL> self . engine = engine <EOL> self . gen = gen <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> gen = self . gen <EOL> try : <EOL> task = next ( gen ) <EOL> except StopIteration : <EOL> return <EOL> while True : <EOL> try : <EOL> if isinstance ( task , ( list , tuple ) ) : <EOL> assert len ( task ) , "<STR_LIT>" <EOL> first_task = task [ <NUM_LIT:0> ] <EOL> if isinstance ( first_task , ProcessTask ) : <EOL> task = MultiProcessTask ( task ) <EOL> elif GTask and isinstance ( first_task , GTask ) : <EOL> task = MultiGTask ( task ) <EOL> else : <EOL> task = MultiTask ( task ) <EOL> with task . executor_class ( task . max_workers ) as executor : <EOL> if isinstance ( task , MultiTask ) : <EOL> task = self . _execute_multi_task ( gen , executor , task ) <EOL> else : <EOL> task = self . _execute_single_task ( gen , executor , task ) <EOL> except StopIteration : <EOL> break <EOL> except ReturnResult as e : <EOL> gen . close ( ) <EOL> return e . result <EOL> def _execute_single_task ( self , gen , executor , task ) : <EOL> future = executor . submit ( task ) <EOL> while True : <EOL> try : <EOL> result = future . result ( self . engine . pool_timeout ) <EOL> except futures . TimeoutError : <EOL> self . engine . update_gui ( ) <EOL> except Exception : <EOL> return gen . throw ( * sys . exc_info ( ) ) <EOL> else : <EOL> return gen . send ( result ) <EOL> def _execute_multi_task ( self , gen , executor , task ) : <EOL> if task . unordered : <EOL> results_gen = self . _execute_multi_gen_task ( gen , executor , task ) <EOL> return gen . send ( results_gen ) <EOL> future_tasks = [ executor . submit ( t ) for t in task . tasks ] <EOL> while True : <EOL> if not task . wait ( executor , future_tasks , self . engine . pool_timeout ) : <EOL> self . engine . update_gui ( ) <EOL> else : <EOL> break <EOL> if task . skip_errors : <EOL> results = [ ] <EOL> for f in future_tasks : <EOL> try : <EOL> results . append ( f . result ( ) ) <EOL> except Exception : <EOL> pass <EOL> else : <EOL> try : <EOL> results = [ f . result ( ) for f in future_tasks ] <EOL> except Exception : <EOL> return gen . throw ( * sys . exc_info ( ) ) <EOL> return gen . send ( results ) <EOL> def _execute_multi_gen_task ( self , gen , executor , task ) : <EOL> unfinished = set ( executor . submit ( t ) for t in task . tasks ) <EOL> while unfinished : <EOL> if not task . wait ( executor , unfinished , self . engine . pool_timeout ) : <EOL> self . engine . update_gui ( ) <EOL> done = set ( f for f in unfinished if f . done ( ) ) <EOL> for f in done : <EOL> try : <EOL> result = f . result ( ) <EOL> except Exception : <EOL> if not task . skip_errors : <EOL> raise <EOL> else : <EOL> yield result <EOL> unfinished . difference_update ( done ) <EOL> def return_result ( result ) : <EOL> """<STR_LIT>""" <EOL> raise ReturnResult ( result ) </s>
