<s> """<STR_LIT>""" <EOL> import bz2 <EOL> from copy import deepcopy <EOL> from glob import glob <EOL> import hashlib <EOL> import inspect <EOL> import os <EOL> try : <EOL> import cPickle as pickle <EOL> except ImportError : <EOL> import pickle <EOL> import six <EOL> class Cache ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cache_path ) : <EOL> self . _cache_path = cache_path <EOL> self . _data = None <EOL> def check ( self ) : <EOL> """<STR_LIT>""" <EOL> return os . path . exists ( self . _cache_path ) <EOL> def get ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _data is None : <EOL> f = bz2 . BZ2File ( self . _cache_path ) <EOL> self . _data = pickle . loads ( f . read ( ) ) <EOL> f . close ( ) <EOL> return deepcopy ( self . _data ) <EOL> def set ( self , data ) : <EOL> """<STR_LIT>""" <EOL> self . _data = data <EOL> f = bz2 . BZ2File ( self . _cache_path , '<STR_LIT:w>' ) <EOL> f . write ( pickle . dumps ( self . _data ) ) <EOL> f . close ( ) <EOL> def never_cache ( func ) : <EOL> """<STR_LIT>""" <EOL> func . never_cache = True <EOL> return func <EOL> class Analysis ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , func , cache_dir = '<STR_LIT>' , _trace = [ ] ) : <EOL> self . _name = func . __name__ <EOL> self . _func = func <EOL> self . _cache_dir = cache_dir <EOL> self . _trace = _trace + [ self ] <EOL> self . _child_analyses = [ ] <EOL> self . _cache_path = os . path . join ( self . _cache_dir , '<STR_LIT>' % self . _fingerprint ( ) ) <EOL> self . _cache = Cache ( self . _cache_path ) <EOL> self . _registered_cache_paths = [ ] <EOL> self . _trace [ <NUM_LIT:0> ] . _registered_cache_paths . append ( self . _cache_path ) <EOL> def _fingerprint ( self ) : <EOL> """<STR_LIT>""" <EOL> hasher = hashlib . md5 ( ) <EOL> history = '<STR_LIT:\n>' . join ( [ analysis . _name for analysis in self . _trace ] ) <EOL> if six . PY3 : <EOL> history = history . encode ( '<STR_LIT:utf-8>' ) <EOL> hasher . update ( history ) <EOL> source = inspect . getsource ( self . _func ) <EOL> if six . PY3 : <EOL> source = source . encode ( '<STR_LIT:utf-8>' ) <EOL> hasher . update ( source ) <EOL> return hasher . hexdigest ( ) <EOL> def _cleanup_cache_files ( self ) : <EOL> """<STR_LIT>""" <EOL> for path in glob ( os . path . join ( self . _cache_dir , '<STR_LIT>' ) ) : <EOL> if path not in self . _registered_cache_paths : <EOL> os . remove ( path ) <EOL> def then ( self , child_func ) : <EOL> """<STR_LIT>""" <EOL> analysis = Analysis ( <EOL> child_func , <EOL> cache_dir = self . _cache_dir , <EOL> _trace = self . _trace <EOL> ) <EOL> self . _child_analyses . append ( analysis ) <EOL> return analysis <EOL> def run ( self , refresh = False , _parent_cache = None ) : <EOL> """<STR_LIT>""" <EOL> if not os . path . exists ( self . _cache_dir ) : <EOL> os . makedirs ( self . _cache_dir ) <EOL> do_not_cache = getattr ( self . _func , '<STR_LIT>' , False ) <EOL> if refresh is True : <EOL> print ( '<STR_LIT>' % self . _name ) <EOL> elif do_not_cache : <EOL> refresh = True <EOL> print ( '<STR_LIT>' % self . _name ) <EOL> elif not self . _cache . check ( ) : <EOL> refresh = True <EOL> print ( '<STR_LIT>' % self . _name ) <EOL> if refresh : <EOL> if _parent_cache : <EOL> local_data = _parent_cache . get ( ) <EOL> else : <EOL> local_data = { } <EOL> self . _func ( local_data ) <EOL> if not do_not_cache : <EOL> self . _cache . set ( local_data ) <EOL> else : <EOL> print ( '<STR_LIT>' % self . _name ) <EOL> for analysis in self . _child_analyses : <EOL> analysis . run ( refresh = refresh , _parent_cache = self . _cache ) <EOL> if self . _trace [ <NUM_LIT:0> ] is self : <EOL> self . _cleanup_cache_files ( ) </s>
