<s> """<STR_LIT>""" <EOL> import inspect <EOL> NO_DEFAULT = object ( ) <EOL> def memoize_default ( default = NO_DEFAULT , evaluator_is_first_arg = False , second_arg_is_evaluator = False ) : <EOL> """<STR_LIT>""" <EOL> def func ( function ) : <EOL> def wrapper ( obj , * args , ** kwargs ) : <EOL> if evaluator_is_first_arg : <EOL> cache = obj . memoize_cache <EOL> elif second_arg_is_evaluator : <EOL> cache = args [ <NUM_LIT:0> ] . memoize_cache <EOL> else : <EOL> cache = obj . _evaluator . memoize_cache <EOL> try : <EOL> memo = cache [ function ] <EOL> except KeyError : <EOL> memo = { } <EOL> cache [ function ] = memo <EOL> key = ( obj , args , frozenset ( kwargs . items ( ) ) ) <EOL> if key in memo : <EOL> return memo [ key ] <EOL> else : <EOL> if default is not NO_DEFAULT : <EOL> memo [ key ] = default <EOL> rv = function ( obj , * args , ** kwargs ) <EOL> if inspect . isgenerator ( rv ) : <EOL> rv = list ( rv ) <EOL> memo [ key ] = rv <EOL> return rv <EOL> return wrapper <EOL> return func <EOL> class CachedMetaClass ( type ) : <EOL> """<STR_LIT>""" <EOL> @ memoize_default ( None , second_arg_is_evaluator = True ) <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> return super ( CachedMetaClass , self ) . __call__ ( * args , ** kwargs ) </s>
