<s> '''<STR_LIT>''' <EOL> import os <EOL> import imp <EOL> import sys <EOL> import inspect <EOL> from collections import defaultdict <EOL> from shovel import logger <EOL> from shovel . args import Args <EOL> def task ( func ) : <EOL> '''<STR_LIT>''' <EOL> Task . make ( func ) <EOL> return func <EOL> class Shovel ( object ) : <EOL> '''<STR_LIT>''' <EOL> @ classmethod <EOL> def load ( cls , path , base = None ) : <EOL> '''<STR_LIT>''' <EOL> obj = cls ( ) <EOL> obj . read ( path , base ) <EOL> return obj <EOL> def __init__ ( self , tasks = None ) : <EOL> self . overrides = None <EOL> self . _tasks = tasks or [ ] <EOL> self . map = defaultdict ( Shovel ) <EOL> self . extend ( tasks or [ ] ) <EOL> def extend ( self , tasks ) : <EOL> '''<STR_LIT>''' <EOL> self . _tasks . extend ( tasks ) <EOL> for task in tasks : <EOL> current = self . map <EOL> modules = task . fullname . split ( '<STR_LIT:.>' ) <EOL> for module in modules [ : - <NUM_LIT:1> ] : <EOL> if not isinstance ( current [ module ] , Shovel ) : <EOL> logger . warn ( '<STR_LIT>' % <EOL> current [ module ] . file ) <EOL> shovel = Shovel ( ) <EOL> shovel . overrides = current [ module ] <EOL> current [ module ] = shovel <EOL> current = current [ module ] . map <EOL> name = modules [ - <NUM_LIT:1> ] <EOL> if name in current : <EOL> logger . warn ( '<STR_LIT>' % ( <EOL> '<STR_LIT:.>' . join ( modules ) , task . file ) ) <EOL> task . overrides = current [ name ] <EOL> current [ name ] = task <EOL> def read ( self , path , base = None ) : <EOL> '''<STR_LIT>''' <EOL> if base == None : <EOL> base = os . getcwd ( ) <EOL> absolute = os . path . abspath ( path ) <EOL> if os . path . isfile ( absolute ) : <EOL> logger . info ( '<STR_LIT>' % absolute ) <EOL> self . extend ( Task . load ( path , base ) ) <EOL> elif os . path . isdir ( absolute ) : <EOL> tasks = [ ] <EOL> for root , _ , files in os . walk ( absolute ) : <EOL> files = [ f for f in files if f . endswith ( '<STR_LIT>' ) ] <EOL> for child in files : <EOL> absolute = os . path . join ( root , child ) <EOL> logger . info ( '<STR_LIT>' % absolute ) <EOL> tasks . extend ( Task . load ( absolute , base ) ) <EOL> self . extend ( tasks ) <EOL> def __getitem__ ( self , key ) : <EOL> '''<STR_LIT>''' <EOL> current = self . map <EOL> split = key . split ( '<STR_LIT:.>' ) <EOL> for module in split [ : - <NUM_LIT:1> ] : <EOL> if module not in current : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> current = current [ module ] . map <EOL> if split [ - <NUM_LIT:1> ] not in current : <EOL> raise KeyError ( '<STR_LIT>' ) <EOL> return current [ split [ - <NUM_LIT:1> ] ] <EOL> def __contains__ ( self , key ) : <EOL> try : <EOL> return bool ( self . __getitem__ ( key ) ) <EOL> except KeyError : <EOL> return False <EOL> def keys ( self ) : <EOL> '''<STR_LIT>''' <EOL> keys = [ ] <EOL> for key , value in self . map . items ( ) : <EOL> if isinstance ( value , Shovel ) : <EOL> keys . extend ( [ key + '<STR_LIT:.>' + k for k in value . keys ( ) ] ) <EOL> else : <EOL> keys . append ( key ) <EOL> return sorted ( keys ) <EOL> def items ( self ) : <EOL> '''<STR_LIT>''' <EOL> pairs = [ ] <EOL> for key , value in self . map . items ( ) : <EOL> if isinstance ( value , Shovel ) : <EOL> pairs . extend ( [ ( key + '<STR_LIT:.>' + k , v ) for k , v in value . items ( ) ] ) <EOL> else : <EOL> pairs . append ( ( key , value ) ) <EOL> return sorted ( pairs ) <EOL> def tasks ( self , name ) : <EOL> '''<STR_LIT>''' <EOL> found = self [ name ] <EOL> if isinstance ( found , Shovel ) : <EOL> return [ v for _ , v in found . items ( ) ] <EOL> return [ found ] <EOL> class Task ( object ) : <EOL> '''<STR_LIT>''' <EOL> _cache = [ ] <EOL> _tasks = { } <EOL> @ classmethod <EOL> def make ( cls , obj ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> cls . _cache . append ( Task ( obj ) ) <EOL> except Exception : <EOL> logger . exception ( '<STR_LIT>' % repr ( obj ) ) <EOL> @ classmethod <EOL> def load ( cls , path , base = None ) : <EOL> '''<STR_LIT>''' <EOL> base = base or os . getcwd ( ) <EOL> absolute = os . path . abspath ( path ) <EOL> parent = os . path . dirname ( absolute ) <EOL> name , _ , _ = os . path . basename ( absolute ) . rpartition ( '<STR_LIT>' ) <EOL> fobj , path , description = imp . find_module ( name , [ parent ] ) <EOL> try : <EOL> imp . load_module ( name , fobj , path , description ) <EOL> finally : <EOL> if fobj : <EOL> fobj . close ( ) <EOL> relative , _ , _ = os . path . relpath ( path , base ) . rpartition ( '<STR_LIT>' ) <EOL> for task in cls . _cache : <EOL> parts = relative . split ( os . path . sep ) <EOL> parts . append ( task . name ) <EOL> parts = [ part . strip ( '<STR_LIT:.>' ) for part in parts if part not in <EOL> ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:.>' , '<STR_LIT:..>' , '<STR_LIT>' ) ] <EOL> task . fullname = '<STR_LIT:.>' . join ( parts ) <EOL> logger . debug ( '<STR_LIT>' % ( task . fullname , task . module ) ) <EOL> return cls . clear ( ) <EOL> @ classmethod <EOL> def clear ( cls ) : <EOL> '''<STR_LIT>''' <EOL> cached = cls . _cache <EOL> cls . _cache = [ ] <EOL> return cached <EOL> def __init__ ( self , obj ) : <EOL> if not callable ( obj ) : <EOL> raise TypeError ( '<STR_LIT>' % obj ) <EOL> self . name = obj . __name__ <EOL> self . doc = inspect . getdoc ( obj ) or '<STR_LIT>' <EOL> if isinstance ( obj , type ) : <EOL> try : <EOL> self . _obj = obj ( ) <EOL> except : <EOL> raise TypeError ( <EOL> '<STR_LIT>' % self . name ) <EOL> self . spec = inspect . getargspec ( self . _obj . __call__ ) <EOL> self . doc = inspect . getdoc ( self . _obj . __call__ ) or self . doc <EOL> self . line = '<STR_LIT>' <EOL> self . file = '<STR_LIT>' <EOL> else : <EOL> self . spec = inspect . getargspec ( obj ) <EOL> self . _obj = obj <EOL> self . line = obj . __code__ . co_firstlineno <EOL> self . file = obj . __code__ . co_filename <EOL> self . module = self . _obj . __module__ <EOL> self . fullname = self . name <EOL> self . overrides = None <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> return self . _obj ( * args , ** kwargs ) <EOL> except Exception as exc : <EOL> logger . exception ( '<STR_LIT>' % self . name ) <EOL> raise ( exc ) <EOL> def capture ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> import traceback <EOL> try : <EOL> from StringIO import StringIO <EOL> except ImportError : <EOL> from io import StringIO <EOL> stdout , stderr = sys . stdout , sys . stderr <EOL> sys . stdout = out = StringIO ( ) <EOL> sys . stderr = err = StringIO ( ) <EOL> result = { <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None <EOL> } <EOL> try : <EOL> result [ '<STR_LIT>' ] = self . __call__ ( * args , ** kwargs ) <EOL> except Exception : <EOL> result [ '<STR_LIT>' ] = traceback . format_exc ( ) <EOL> sys . stdout , sys . stderr = stdout , stderr <EOL> result [ '<STR_LIT>' ] = err . getvalue ( ) <EOL> result [ '<STR_LIT>' ] = out . getvalue ( ) <EOL> return result <EOL> def dry ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> return '<STR_LIT>' % ( <EOL> self . name , Args ( self . spec ) . explain ( * args , ** kwargs ) ) <EOL> def help ( self ) : <EOL> '''<STR_LIT>''' <EOL> result = [ <EOL> '<STR_LIT:=>' * <NUM_LIT:50> , <EOL> self . name <EOL> ] <EOL> if self . doc : <EOL> result . extend ( [ <EOL> '<STR_LIT:=>' * <NUM_LIT:30> , <EOL> self . doc <EOL> ] ) <EOL> override = self . overrides <EOL> while override : <EOL> if isinstance ( override , Shovel ) : <EOL> result . append ( '<STR_LIT>' ) <EOL> else : <EOL> result . append ( '<STR_LIT>' % override . file ) <EOL> override = override . overrides <EOL> result . extend ( [ <EOL> '<STR_LIT:=>' * <NUM_LIT:30> , <EOL> '<STR_LIT>' % ( self . file , self . line ) , <EOL> '<STR_LIT:=>' * <NUM_LIT:30> , <EOL> '<STR_LIT>' % ( self . name , str ( Args ( self . spec ) ) ) <EOL> ] ) <EOL> return os . linesep . join ( result ) </s>
