<s> """<STR_LIT>""" <EOL> from collections import OrderedDict , Sequence <EOL> from functools import wraps <EOL> from itertools import compress <EOL> from weakref import WeakKeyDictionary , ref <EOL> from six . moves . _thread import allocate_lock as Lock <EOL> from toolz . sandbox import unzip <EOL> class lazyval ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , get ) : <EOL> self . _get = get <EOL> self . _cache = WeakKeyDictionary ( ) <EOL> def __get__ ( self , instance , owner ) : <EOL> if instance is None : <EOL> return self <EOL> try : <EOL> return self . _cache [ instance ] <EOL> except KeyError : <EOL> self . _cache [ instance ] = val = self . _get ( instance ) <EOL> return val <EOL> def __set__ ( self , instance , value ) : <EOL> raise AttributeError ( "<STR_LIT>" ) <EOL> def __delitem__ ( self , instance ) : <EOL> del self . _cache [ instance ] <EOL> class classlazyval ( lazyval ) : <EOL> """<STR_LIT>""" <EOL> def __get__ ( self , instance , owner ) : <EOL> return super ( classlazyval , self ) . __get__ ( owner , owner ) <EOL> def _weak_lru_cache ( maxsize = <NUM_LIT:100> ) : <EOL> """<STR_LIT>""" <EOL> def decorating_function ( <EOL> user_function , tuple = tuple , sorted = sorted , len = len , <EOL> KeyError = KeyError ) : <EOL> hits , misses = [ <NUM_LIT:0> ] , [ <NUM_LIT:0> ] <EOL> kwd_mark = ( object ( ) , ) <EOL> lock = Lock ( ) <EOL> if maxsize is None : <EOL> cache = _WeakArgsDict ( ) <EOL> @ wraps ( user_function ) <EOL> def wrapper ( * args , ** kwds ) : <EOL> key = args <EOL> if kwds : <EOL> key += kwd_mark + tuple ( sorted ( kwds . items ( ) ) ) <EOL> try : <EOL> result = cache [ key ] <EOL> hits [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> return result <EOL> except KeyError : <EOL> pass <EOL> result = user_function ( * args , ** kwds ) <EOL> cache [ key ] = result <EOL> misses [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> return result <EOL> else : <EOL> cache = _WeakArgsOrderedDict ( ) <EOL> cache_popitem = cache . popitem <EOL> cache_renew = cache . move_to_end <EOL> @ wraps ( user_function ) <EOL> def wrapper ( * args , ** kwds ) : <EOL> key = args <EOL> if kwds : <EOL> key += kwd_mark + tuple ( sorted ( kwds . items ( ) ) ) <EOL> with lock : <EOL> try : <EOL> result = cache [ key ] <EOL> cache_renew ( key ) <EOL> hits [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> return result <EOL> except KeyError : <EOL> pass <EOL> result = user_function ( * args , ** kwds ) <EOL> with lock : <EOL> cache [ key ] = result <EOL> misses [ <NUM_LIT:0> ] += <NUM_LIT:1> <EOL> if len ( cache ) > maxsize : <EOL> cache_popitem ( False ) <EOL> return result <EOL> def cache_info ( ) : <EOL> """<STR_LIT>""" <EOL> with lock : <EOL> return hits [ <NUM_LIT:0> ] , misses [ <NUM_LIT:0> ] , maxsize , len ( cache ) <EOL> def cache_clear ( ) : <EOL> """<STR_LIT>""" <EOL> with lock : <EOL> cache . clear ( ) <EOL> hits [ <NUM_LIT:0> ] = misses [ <NUM_LIT:0> ] = <NUM_LIT:0> <EOL> wrapper . cache_info = cache_info <EOL> wrapper . cache_clear = cache_clear <EOL> return wrapper <EOL> return decorating_function <EOL> class _WeakArgs ( Sequence ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , items , dict_remove = None ) : <EOL> def remove ( k , selfref = ref ( self ) , dict_remove = dict_remove ) : <EOL> self = selfref ( ) <EOL> if self is not None and dict_remove is not None : <EOL> dict_remove ( self ) <EOL> self . _items , self . _selectors = unzip ( self . _try_ref ( item , remove ) <EOL> for item in items ) <EOL> self . _items = tuple ( self . _items ) <EOL> self . _selectors = tuple ( self . _selectors ) <EOL> def __getitem__ ( self , index ) : <EOL> return self . _items [ index ] <EOL> def __len__ ( self ) : <EOL> return len ( self . _items ) <EOL> @ staticmethod <EOL> def _try_ref ( item , callback ) : <EOL> try : <EOL> return ref ( item , callback ) , True <EOL> except TypeError : <EOL> return item , False <EOL> @ property <EOL> def alive ( self ) : <EOL> return all ( item ( ) is not None <EOL> for item in compress ( self . _items , self . _selectors ) ) <EOL> def __eq__ ( self , other ) : <EOL> return self . _items == other . _items <EOL> def __hash__ ( self ) : <EOL> try : <EOL> return self . __hash <EOL> except AttributeError : <EOL> h = self . __hash = hash ( self . _items ) <EOL> return h <EOL> class _WeakArgsDict ( WeakKeyDictionary , object ) : <EOL> def __delitem__ ( self , key ) : <EOL> del self . data [ _WeakArgs ( key ) ] <EOL> def __getitem__ ( self , key ) : <EOL> return self . data [ _WeakArgs ( key ) ] <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( type ( self ) . __name__ , self . data ) <EOL> def __setitem__ ( self , key , value ) : <EOL> self . data [ _WeakArgs ( key , self . _remove ) ] = value <EOL> def __contains__ ( self , key ) : <EOL> try : <EOL> wr = _WeakArgs ( key ) <EOL> except TypeError : <EOL> return False <EOL> return wr in self . data <EOL> def pop ( self , key , * args ) : <EOL> return self . data . pop ( _WeakArgs ( key ) , * args ) <EOL> class _WeakArgsOrderedDict ( _WeakArgsDict , object ) : <EOL> def __init__ ( self ) : <EOL> super ( _WeakArgsOrderedDict , self ) . __init__ ( ) <EOL> self . data = OrderedDict ( ) <EOL> def popitem ( self , last = True ) : <EOL> while True : <EOL> key , value = self . data . popitem ( last ) <EOL> if key . alive : <EOL> return tuple ( key ) , value <EOL> def move_to_end ( self , key ) : <EOL> """<STR_LIT>""" <EOL> self [ key ] = self . pop ( key ) <EOL> def weak_lru_cache ( maxsize = <NUM_LIT:100> ) : <EOL> """<STR_LIT>""" <EOL> class desc ( lazyval ) : <EOL> def __get__ ( self , instance , owner ) : <EOL> if instance is None : <EOL> return self <EOL> try : <EOL> return self . _cache [ instance ] <EOL> except KeyError : <EOL> inst = ref ( instance ) <EOL> @ _weak_lru_cache ( maxsize ) <EOL> @ wraps ( self . _get ) <EOL> def wrapper ( * args , ** kwargs ) : <EOL> return self . _get ( inst ( ) , * args , ** kwargs ) <EOL> self . _cache [ instance ] = wrapper <EOL> return wrapper <EOL> @ _weak_lru_cache ( maxsize ) <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> return self . _get ( * args , ** kwargs ) <EOL> return desc <EOL> remember_last = weak_lru_cache ( <NUM_LIT:1> ) </s>
