<s> '''<STR_LIT>''' <EOL> import datetime as datetime_module <EOL> from python_toolbox import misc_tools <EOL> from python_toolbox import binary_search <EOL> from python_toolbox import decorator_tools <EOL> from python_toolbox . sleek_reffing import SleekCallArgs <EOL> infinity = float ( '<STR_LIT>' ) <EOL> class CLEAR_ENTIRE_CACHE ( misc_tools . NonInstantiable ) : <EOL> '''<STR_LIT>''' <EOL> def _get_now ( ) : <EOL> '''<STR_LIT>''' <EOL> return datetime_module . datetime . now ( ) <EOL> @ decorator_tools . helpful_decorator_builder <EOL> def cache ( max_size = infinity , time_to_keep = None ) : <EOL> '''<STR_LIT>''' <EOL> from python_toolbox . nifty_collections import OrderedDict <EOL> if time_to_keep is not None : <EOL> if max_size != infinity : <EOL> raise NotImplementedError <EOL> if not isinstance ( time_to_keep , datetime_module . timedelta ) : <EOL> try : <EOL> time_to_keep = datetime_module . timedelta ( ** time_to_keep ) <EOL> except Exception : <EOL> raise TypeError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> ) <EOL> assert isinstance ( time_to_keep , datetime_module . timedelta ) <EOL> def decorator ( function ) : <EOL> if getattr ( function , '<STR_LIT>' , False ) : return function <EOL> if max_size == infinity : <EOL> if time_to_keep : <EOL> sorting_key_function = lambda sleek_call_args : cached . _cache [ sleek_call_args ] [ <NUM_LIT:1> ] <EOL> def remove_expired_entries ( ) : <EOL> almost_cutting_point = binary_search . binary_search_by_index ( <EOL> list ( cached . _cache . keys ( ) ) , <EOL> _get_now ( ) , <EOL> sorting_key_function , <EOL> rounding = binary_search . LOW <EOL> ) <EOL> if almost_cutting_point is not None : <EOL> cutting_point = almost_cutting_point + <NUM_LIT:1> <EOL> for key in cached . _cache . keys ( ) [ : cutting_point ] : <EOL> del cached . _cache [ key ] <EOL> @ misc_tools . set_attributes ( _cache = OrderedDict ( ) ) <EOL> def cached ( function , * args , ** kwargs ) : <EOL> remove_expired_entries ( ) <EOL> sleek_call_args = SleekCallArgs ( cached . _cache , function , * args , ** kwargs ) <EOL> try : <EOL> return cached . _cache [ sleek_call_args ] [ <NUM_LIT:0> ] <EOL> except KeyError : <EOL> value = function ( * args , ** kwargs ) <EOL> cached . _cache [ sleek_call_args ] = ( <EOL> value , <EOL> _get_now ( ) + time_to_keep <EOL> ) <EOL> cached . _cache . sort ( key = sorting_key_function ) <EOL> return value <EOL> else : <EOL> @ misc_tools . set_attributes ( _cache = { } ) <EOL> def cached ( function , * args , ** kwargs ) : <EOL> sleek_call_args = SleekCallArgs ( cached . _cache , function , * args , ** kwargs ) <EOL> try : <EOL> return cached . _cache [ sleek_call_args ] <EOL> except KeyError : <EOL> cached . _cache [ sleek_call_args ] = value = function ( * args , ** kwargs ) <EOL> return value <EOL> else : <EOL> @ misc_tools . set_attributes ( _cache = OrderedDict ( ) ) <EOL> def cached ( function , * args , ** kwargs ) : <EOL> sleek_call_args = SleekCallArgs ( cached . _cache , function , * args , ** kwargs ) <EOL> try : <EOL> result = cached . _cache [ sleek_call_args ] <EOL> cached . _cache . move_to_end ( sleek_call_args ) <EOL> return result <EOL> except KeyError : <EOL> cached . _cache [ sleek_call_args ] = value = function ( * args , ** kwargs ) <EOL> if len ( cached . _cache ) > max_size : <EOL> cached . _cache . popitem ( last = False ) <EOL> return value <EOL> result = decorator_tools . decorator ( cached , function ) <EOL> def cache_clear ( key = CLEAR_ENTIRE_CACHE ) : <EOL> if key is CLEAR_ENTIRE_CACHE : <EOL> cached . _cache . clear ( ) <EOL> else : <EOL> try : <EOL> del cached . _cache [ key ] <EOL> except KeyError : <EOL> pass <EOL> result . cache_clear = cache_clear <EOL> result . is_cached = True <EOL> return result <EOL> return decorator </s>
