### README - Quick Start Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Contains introductory code examples for quickly getting started with cachetools, demonstrating basic usage of caches and decorators. ```python from cachetools import cached, LRUCache @cached(cache=LRUCache(maxsize=10)) def expensive_function(n): print(f"Computing for {n}...") time.sleep(0.1) return n * 2 print(expensive_function(5)) # Computes print(expensive_function(5)) # Returns cached value print(expensive_function(6)) # Computes ``` -------------------------------- ### Decorator Quick Start Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Provides quick examples of using the `@cached` and `@cachedmethod` decorators to memoize function and method calls, respectively. These decorators automatically manage caching based on arguments. ```python from cachetools import cached import time @cached(maxsize=128) def expensive_computation(num): time.sleep(0.1) return num * 2 print(expensive_computation(4)) # First call, takes time print(expensive_computation(4)) # Second call, uses cache ``` ```python from cachetools import cachedmethod class MyClass: @cachedmethod(lambda self: id(self)) def expensive_method(self, num): time.sleep(0.1) return num * 2 instance = MyClass() print(instance.expensive_method(4)) # First call print(instance.expensive_method(4)) # Second call, uses cache ``` -------------------------------- ### Install cachetools Source: https://github.com/tkem/cachetools/blob/master/_autodocs/README.md Install the cachetools library using pip. ```bash pip install cachetools ``` -------------------------------- ### Cache Class Creation Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Demonstrates the instantiation of different cache classes provided by the cachetools library. These examples show how to create caches with default settings. ```python from cachetools import FIFOCache, LRUCache, LFUCache, RRCache, TTLCache, TLRUCache # Default cache instances fifo = FIFOCache() lru = LRUCache() lfu = LFUCache() rr = RRCache() ttl = TTLCache() tlru = TLRUCache() ``` -------------------------------- ### Quick Reference - TTL Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Concise examples illustrating the use of `TTLCache` and the `ttl` parameter for time-based expiration. ```python from cachetools import TTLCache short_lived_cache = TTLCache(maxsize=10, ttl=60) # Expires in 60 seconds ``` -------------------------------- ### Quick Reference - Cache Class Creation Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Provides concise examples of creating instances of various cache classes with default settings. ```python from cachetools import LRUCache, TTLCache lru = LRUCache(maxsize=100) ttl = TTLCache(maxsize=50, ttl=300) ``` -------------------------------- ### Size Management Quick Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Demonstrates how to configure cache size limits using the `maxsize` parameter for various cache types and decorators. ```python from cachetools import LRUCache # Cache with a maximum size of 5 items sized_cache = LRUCache(maxsize=5) # Decorator with a maximum size of 100 @cached(maxsize=100) def limited_function(arg): return arg ``` -------------------------------- ### FIFOCache Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Demonstrates the usage of FIFOCache. Items are evicted in the order they were inserted when the cache reaches its maximum size. ```python fifo = FIFOCache(maxsize=100) fifo['first'] = 'value1' fifo['second'] = 'value2' fifo['third'] = 'value3' # Cache is full, adding another triggers eviction ifo['fourth'] = 'value4' # 'first' is evicted (first in, first out) ``` -------------------------------- ### envkey function example Source: https://github.com/tkem/cachetools/blob/master/docs/index.md Example of a custom key function that handles a dictionary argument specially for caching. ```APIDOC ## envkey function ### Description A custom key function that can be used with caching decorators to handle non-hashable arguments like dictionaries by serializing their items. ### Usage ```python def envkey(*args, env={}, **kwargs): key = hashkey(*args, **kwargs) key += tuple(sorted(env.items())) return key @cached(LRUCache(maxsize=128), key=envkey) def foo(x, y, z, env={}): pass foo(1, 2, 3, env=dict(a='a', b='b')) ``` ``` -------------------------------- ### TLRUCache Example with Key-Dependent TTL Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Illustrates setting up a TLRUCache where the TTL for an item can vary based on its key. ```python # Key-dependent TTL def priority_ttu(key, value, now): if key.startswith('priority:'): ttl = 600 # Priority items cached longer else: ttl = 60 return now + ttl tlru3 = TLRUCache(maxsize=100, ttu=priority_ttu) ``` -------------------------------- ### TLRUCache Initialization Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of initializing TLRUCache with a custom expiration function. ```python TLRUCache(ttu=func) ``` -------------------------------- ### Quick Reference - Basic Operations Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Shows fundamental cache operations like setting, getting, and checking for item existence using dictionary-like syntax. ```python cache = LRUCache(maxsize=5) cache['key1'] = 'value1' print(cache['key1']) print('key1' in cache) ``` -------------------------------- ### Example: typedkey with Different Types in Multiplication Source: https://github.com/tkem/cachetools/blob/master/_autodocs/key-functions.md Demonstrates how `typedkey` differentiates cache entries when argument types vary, even if the values are the same or the operation is identical. This example shows distinct caching for integer and string multiplication. ```python from cachetools import cached, LRUCache, keys @cached(cache=LRUCache(maxsize=128), key=keys.typedkey) def multiply(a, b): return a * b result1 = multiply(3, 4) # 12 result2 = multiply("a", 3) # "aaa" result3 = multiply(3, 4) # Uses cached result1 ``` -------------------------------- ### TLRUCache Example with Uniform TTL Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Demonstrates creating a TLRUCache with a uniform Time-To-Live (TTL) for all items using a simple TTU function. ```python from cachetools import TLRUCache import time # Uniform TTL def uniform_ttu(key, value, now): return now + 60 # 60 second TTL tlru1 = TLRUCache(maxsize=100, ttu=uniform_ttu) ``` -------------------------------- ### Decorator Configuration Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Demonstrates configuring `@cached` and `@cachedmethod` decorators with various parameters, including specifying a custom cache instance, TTL, and key function. ```python from cachetools import cached, LRUCache, ttl_cache from cachetools.keys import typedkey my_cache = LRUCache(maxsize=50) @cached(cache=my_cache, key=typedkey, ttl=300) def process_with_custom_config(a: int, b: str): return f"{b}-{a}" # Example using ttl_cache decorator @ttl_cache(maxsize=128, ttl=60) def get_data_with_ttl(url): # Fetch data from url return f"Data from {url}" ``` -------------------------------- ### FIFOCache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of using the @fifo_cache decorator with default parameters. ```python @fifo_cache() ``` -------------------------------- ### LFUCache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of using the @lfu_cache decorator with default parameters. ```python @lfu_cache() ``` -------------------------------- ### TTL Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Illustrates the use of `TTLCache` and `ttl` decorator parameter for time-based expiration of cached items. ```python from cachetools import TTLCache import time # Cache items expire after 30 seconds expiring_cache = TTLCache(maxsize=100, ttl=30) @ttl_cache(ttl=60) def fetch_resource(resource_id): # Fetch resource from external source return f"Data for {resource_id}" print(fetch_resource('A')) # Fetched time.sleep(1) print(fetch_resource('A')) # Cached time.sleep(61) print(fetch_resource('A')) # Fetched again ``` -------------------------------- ### Basic cachedmethod Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-decorators.md Demonstrates basic usage of the cachedmethod decorator with an LRUCache. The decorated method's results are stored in the instance's cache. ```python from cachetools import cachedmethod, LRUCache class DataProcessor: def __init__(self): self._cache = LRUCache(maxsize=32) @cachedmethod(cache=lambda self: self._cache) def process(self, value): # Expensive operation return value ** 2 processor = DataProcessor() result = processor.process(10) ``` -------------------------------- ### LFUCache Usage Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Demonstrates adding items to an LFUCache and how eviction occurs based on frequency of access. The least frequently accessed item is removed when the cache is full. ```python lfu = LFUCache(maxsize=100) lfu['a'] = 1 lfu['b'] = 2 lfu['c'] = 3 # Access 'a' multiple times _ = lfu['a'] _ = lfu['a'] _ = lfu['a'] # Cache is full, adding another triggers eviction lfu['d'] = 4 # 'b' is evicted (accessed only once) ``` -------------------------------- ### MutableMapping Protocol Example with LRUCache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/types.md Illustrates how to use standard dictionary-like operations (getitem, setitem, delitem, iteration, etc.) on cache classes that implement the MutableMapping protocol. ```python from cachetools import LRUCache cache = LRUCache(maxsize=100) # MutableMapping methods work on all cache classes cache['key1'] = 'value1' value = cache['key1'] del cache['key1'] if 'key2' in cache: print(cache['key2']) for key in cache: print(key) for key, value in cache.items(): print(f"{key}: {value}") cache.clear() ``` -------------------------------- ### API Reference - Convenience Decorators Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Provides examples of using convenience decorators like `@fifo_cache`, `@lru_cache`, `@ttl_cache`, etc., as shortcuts for applying specific cache policies. ```python from cachetools import lru_cache, ttl_cache @lru_cache(maxsize=128) def get_data(key): # Fetch data return f"Data for {key}" @ttl_cache(maxsize=64, ttl=300) def get_config(setting): # Load configuration return f"Config for {setting}" ``` -------------------------------- ### get Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Safely retrieve a value, returning a default if the key is not found. ```APIDOC ## get (key: Any, default: Any = None) ### Description Safely retrieve a value, returning a default if the key is not found. ### Parameters #### Path Parameters - **key** (Any) - Required - Cache key to retrieve - **default** (Any) - Optional - Value to return if key not found ### Returns Cached value or default. ### Example ```python cache = Cache(maxsize=100) value = cache.get('nonexistent', 'default_value') # 'default_value' ``` ``` -------------------------------- ### RRCache Usage Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Demonstrates adding items to an RRCache. When the cache is full, adding a new item results in a random eviction of one of the existing items. ```python rr = RRCache(maxsize=100) r['a'] = 1 r['b'] = 2 r['c'] = 3 r['d'] = 4 # Add fifth item, random eviction happens r['e'] = 5 # One of the previous items is randomly evicted ``` -------------------------------- ### TTLCache and TLRUCache Management Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Illustrates Time-To-Live (TTL) cache configurations: TTLCache for fixed TTL and TLRUCache for adaptive TTL based on a custom function. Includes an example of using a custom timer for testing. ```python from cachetools import TTLCache, TLRUCache import time # Fixed TTL (all items expire same time after insertion) ttl_cache = TTLCache(maxsize=100, ttl=60) ``` ```python # Adaptive TTL (per-item expiration) def ttu(key, value, now): # Expire based on value type if isinstance(value, dict) and value.get('type') == 'config': return now + 3600 # 1 hour else: return now + 60 # 1 minute tlru_cache = TLRUCache(maxsize=100, ttu=ttu) ``` ```python # Custom timer for testing class MockTimer: def __init__(self): self.time = 0.0 def __call__(self): return self.time def advance(self, seconds): self.time += seconds timer = MockTimer() ttl_cache = TTLCache(maxsize=100, ttl=60, timer=timer) # Test expiration ttl_cache['key'] = 'value' timer.advance(61) 'key' in ttl_cache # False (expired) ``` -------------------------------- ### Cache Mapping Signature Examples Source: https://github.com/tkem/cachetools/blob/master/_autodocs/types.md Demonstrates using different mapping types as caches. Supports standard dict, Cache, and any MutableMapping. Ensure the chosen mapping supports __getitem__, __setitem__, __contains__, __delitem__, and clear(). ```python from cachetools import cached # Can use dict, Cache, or any MutableMapping @cached(cache={}) # Regular dict def func1(x): return x ** 2 ``` ```python @cached(cache=dict()) # Empty dict def func2(x): return x ** 2 ``` ```python from collections import OrderedDict @cached(cache=OrderedDict()) # OrderedDict def func3(x): return x ** 2 ``` -------------------------------- ### Advanced Patterns - Custom Cache Key Functions Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Provides examples of creating and using custom key functions to control how cache keys are generated, allowing for flexible caching strategies. ```python from cachetools import cached, LRUCache from cachetools.keys import hashkey def custom_key_ignore_kwargs(func, *args, **kwargs): # Create a key based only on positional arguments return hashkey(*args) @cached(cache=LRUCache(maxsize=10), key=custom_key_ignore_kwargs) def process_items(item1, item2, option=None): print(f"Processing {item1}, {item2} with option {option}") return item1 + item2 process_items(1, 2, option='A') # Key: (1, 2) process_items(1, 2, option='B') # Uses cached result for (1, 2) process_items(1, 3) # Key: (1, 3) ``` -------------------------------- ### Basic Cache Operations Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Illustrates fundamental operations on cache objects, including setting items, getting items, and checking for existence. These operations are common across all cache types. ```python cache = LRUCache(maxsize=2) cache['key1'] = 'value1' cache['key2'] = 'value2' print(cache['key1']) # Output: 'value1' print('key1' in cache) # Output: True print(len(cache)) # Output: 2 ``` -------------------------------- ### Cache Statistics and Clearing Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Demonstrates how to retrieve cache statistics (hits, misses, size) and clear the cache for a function decorated with lru_cache. Also shows how to get statistics for method caching. ```python from cachetools import lru_cache @lru_cache(maxsize=128) def func(x): return x ** 2 # Get statistics info = func.cache_info() print(f"Hits: {info.hits}") print(f"Misses: {info.misses}") print(f"Maxsize: {info.maxsize}") print(f"Current size: {info.currsize}") # Clear cache func.cache_clear() # For method caching class MyClass: def __init__(self): self._cache = LRUCache(maxsize=128) @cachedmethod(cache=lambda self: self._cache, info=True) def compute(self, x): return x ** 2 obj = MyClass() obj.compute(5) info = obj.compute.cache_info() ``` -------------------------------- ### Example Usage of LRU Cache with CacheInfo Source: https://github.com/tkem/cachetools/blob/master/_autodocs/types.md Demonstrates using the lru_cache decorator and accessing cache statistics via the cache_info() method. The hit ratio and occupancy are calculated from the returned CacheInfo object. ```python from cachetools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2) fibonacci(5) fibonacci(5) fibonacci(5) fibonacci(3) info = fibonacci.cache_info() # CacheInfo(hits=2, misses=6, maxsize=128, currsize=6) print(f"Hit ratio: {info.hits / (info.hits + info.misses)}") # 0.25 print(f"Cache occupancy: {info.currsize / info.maxsize}") # 0.047 ``` -------------------------------- ### Get Decorator Parameters with cache_parameters() Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-decorators.md Returns a dictionary containing the configuration parameters used when applying the decorator, such as 'maxsize' and 'typed'. This is useful for inspecting the decorator's setup. ```python from cachetools import lru_cache @lru_cache(maxsize=256, typed=True) def compute(x): return x ** 2 params = compute.cache_parameters() # {'maxsize': 256, 'typed': True} ``` -------------------------------- ### Cache Type Comparison Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt This section would typically contain a table comparing different cache types (FIFO, LRU, LFU, RR, TTL, TLRU) based on their eviction policies and characteristics. No code example provided here, but it guides selection. -------------------------------- ### Example of using a custom key function with LRUCache Source: https://github.com/tkem/cachetools/blob/master/docs/index.md Demonstrates how to define and use a custom key function to handle non-hashable arguments like dictionaries in a cached function. The custom key function ensures that dictionary items are included in the cache key. ```python from cachetools import cached, LRUCache from cachetools.keys import hashkey @cached(LRUCache(maxsize=128)) def foo(x, y, z, env={}): pass ``` ```python def envkey(*args, env={}, **kwargs): key = hashkey(*args, **kwargs) key += tuple(sorted(env.items())) return key ``` ```python @cached(LRUCache(maxsize=128), key=envkey) def foo(x, y, z, env={}): pass foo(1, 2, 3, env=dict(a='a', b='b')) ``` -------------------------------- ### TTLCache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of using the @ttl_cache decorator with a specified TTL. ```python @ttl_cache(ttl=600) ``` -------------------------------- ### RRCache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of using the @rr_cache decorator with default parameters. ```python @rr_cache() ``` -------------------------------- ### LRUCache Size Management Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Demonstrates LRUCache initialization with different size constraints: count-based, byte-based using sys.getsizeof, and custom sizing functions. Also shows how to check current and maximum size. ```python # Count-based (default) cache = LRUCache(maxsize=100) # Max 100 items ``` ```python # Byte-based import sys cache = LRUCache(maxsize=1000000, getsizeof=sys.getsizeof) # ~1MB ``` ```python # Custom sizing def custom_size(value): if isinstance(value, str): return len(value) elif isinstance(value, list): return len(value) * 8 return 1 cache = LRUCache(maxsize=10000, getsizeof=custom_size) ``` ```python # Check current size print(f"Current: {cache.currsize}, Max: {cache.maxsize}") print(f"Items: {len(cache)}") ``` -------------------------------- ### Cache Class Initialization Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Shows how to initialize the 7 different cache classes with their respective parameters like `maxsize`, `ttl`, and `timer`. ```python from cachetools import FIFOCache, LRUCache, LFUCache, RRCache, TTLCache, TLRUCache # Example with maxsize fifo_cache = FIFOCache(maxsize=100) lru_cache = LRUCache(maxsize=50) lfu_cache = LFUCache(maxsize=200) rr_cache = RRCache(maxsize=75) # Example with ttl and timer def current_time(): return time.time() ttl_cache = TTLCache(maxsize=100, ttl=300, timer=current_time) tlru_cache = TLRUCache(maxsize=50, ttl=600, timer=current_time) ``` -------------------------------- ### LRUCache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Example of using the @lru_cache decorator with default parameters. ```python @lru_cache() ``` -------------------------------- ### Using LRUCache Class Directly Source: https://github.com/tkem/cachetools/blob/master/_autodocs/README.md Shows how to instantiate and use the `LRUCache` class for manual cache management. ```python from cachetools import LRUCache cache = LRUCache(maxsize=100) cache['key'] = 'value' value = cache['key'] ``` -------------------------------- ### Using cachetools key functions Source: https://github.com/tkem/cachetools/blob/master/_autodocs/module-overview.md Demonstrates the usage of various key generation functions like hashkey, methodkey, typedkey, and typedmethodkey from cachetools.keys. ```python from cachetools import keys key = keys.hashkey(1, 2, 3) key = keys.methodkey(self, 1, 2, 3) key = keys.typedkey(1, 2, 3) key = keys.typedmethodkey(self, 1, 2, 3) ``` -------------------------------- ### Quick Reference - Statistics and Monitoring Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Shows how to access cache statistics like hits and misses using the `cache_info()` method. ```python from cachetools import cached, LRUCache @cached(cache=LRUCache(maxsize=10)) def process(x): return x * 2 process(1) process(1) # Hit print(process.cache_info()) ``` -------------------------------- ### Cache Stampede Problem Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/advanced-patterns.md Illustrates the cache stampede problem where multiple threads requesting the same uncached value simultaneously can lead to redundant computations. This example uses `threading.Lock`. ```python from cachetools import cached, LRUCache from threading import Lock import time @cached(cache=LRUCache(maxsize=128), lock=Lock()) def fetch_data(url): time.sleep(5) # Expensive operation return requests.get(url).json() # If 10 threads call fetch_data("same_url") simultaneously: # All 10 threads may compute the value (9 wasted computations) ``` -------------------------------- ### Initialize FIFOCache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Create a First-In, First-Out cache. You can specify a custom size function to control eviction based on value size rather than just item count. ```python from cachetools import FIFOCache fifo = FIFOCache(maxsize=100) fifo = FIFOCache(maxsize=1000, getsizeof=len) # Size by length ``` -------------------------------- ### __len__ Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Get the number of items currently in the cache. ```APIDOC ## __len__ () ### Description Get the number of items currently in the cache. ### Returns Number of cached items. ``` -------------------------------- ### Performance Tips: Sizing and Typed Caching Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Advises on appropriate cache sizing to balance memory usage and eviction frequency. Using typed=True can significantly slow down caching. ```python # Size cache appropriately # Too small: frequent evictions # Too large: memory waste cache = LRUCache(maxsize=256) # Start here, tune based on hit rate # Use typed=True only when needed @lru_cache(maxsize=128, typed=True) # 3x slower than typed=False def func(x): return x ** 2 ``` -------------------------------- ### setdefault Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Get a value from the cache, storing it first if not present. ```APIDOC ## setdefault (key: Any, default: Any = None) ### Description Get a value from the cache, storing it first if not present. ### Parameters #### Path Parameters - **key** (Any) - Required - Cache key - **default** (Any) - Optional - Value to cache if key not found ### Returns Cached value (existing or newly set). ### Example ```python cache = Cache(maxsize=100) value = cache.setdefault('key1', 'value1') # 'value1' value = cache.setdefault('key1', 'value2') # 'value1' (unchanged) ``` ``` -------------------------------- ### Initialize Cache with Default Sizing Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Use this to create a cache with default count-based sizing. The maxsize parameter determines the maximum number of items. ```python from cachetools import Cache # Default sizing (count-based) cache1 = Cache(maxsize=100) ``` -------------------------------- ### Configuration - Size Function Customization Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Illustrates how to customize cache size calculation beyond simple item count, although direct support in cachetools is limited and often requires subclassing. ```python # cachetools primarily uses 'maxsize' as the number of items. # Custom size logic often requires subclassing or manual management. # Conceptual example of a custom size function: def custom_size_logic(key, value): # Calculate size based on memory footprint, for example return sys.getsizeof(key) + sys.getsizeof(value) # To use this, you might subclass a cache and override methods # to track and enforce the custom size. ``` -------------------------------- ### Get Number of Items in Cache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Use `__len__` to retrieve the current number of items stored in the cache. ```python cache = Cache(maxsize=100) cache['key1'] = 'value1' len(cache) # 1 ``` -------------------------------- ### Iterate Over Cache Keys Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Use `__iter__` to get an iterator that yields all keys currently stored in the cache. ```python cache = Cache(maxsize=100) cache['key1'] = 'value1' for key in cache: print(key) # key1 ``` -------------------------------- ### Quick Reference - Common Usage Patterns Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Presents typical scenarios where cachetools is applied, such as memoizing expensive computations or caching API responses. ```python from cachetools import ttl_cache @ttl_cache(ttl=60) def fetch_external_resource(resource_id): # Simulate fetching resource return f"Resource {resource_id} data" print(fetch_external_resource(1)) # Fetched time.sleep(1) print(fetch_external_resource(1)) # Cached time.sleep(60) print(fetch_external_resource(1)) # Fetched again ``` -------------------------------- ### TLRUCache Example with Value-Dependent TTL Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Shows how to configure a TLRUCache to have different TTLs based on the type or content of the cached value. ```python # Value-dependent TTL def adaptive_ttu(key, value, now): if isinstance(value, int): ttl = 120 elif isinstance(value, str): ttl = 300 else: ttl = 60 return now + ttl tlru2 = TLRUCache(maxsize=100, ttu=adaptive_ttu) ``` -------------------------------- ### Handle KeyError on Cache Miss Source: https://github.com/tkem/cachetools/blob/master/_autodocs/module-overview.md Accessing a non-existent key in a dictionary-like cache raises a KeyError. This example demonstrates how to catch this exception. ```python cache = {} try: value = cache['missing'] except KeyError: print("Not found") ``` -------------------------------- ### Common Usage Scenarios Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Illustrates practical applications of cachetools, such as memoizing expensive function calls, caching results of I/O operations, and implementing rate limiting. ```python # Example: Caching results of a network request import requests from cachetools import cached, TTLCache @cached(cache=TTLCache(maxsize=100, ttl=600)) def get_api_data(url): response = requests.get(url) response.raise_for_status() return response.json() data = get_api_data('https://api.example.com/data') # Subsequent calls within 10 minutes will use the cached data ``` -------------------------------- ### Performance Tips: Cache Types Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Illustrates choosing the right cache type (LRUCache, LFUCache, RRCache) based on access patterns. LRU is suitable for most use cases. ```python # Choose right cache type for your access pattern from cachetools import LRUCache, LFUCache, RRCache # LRU for most use cases (most frequently accessed patterns) cache1 = LRUCache(maxsize=1000) # LFU for frequency-biased access cache2 = LFUCache(maxsize=1000) # RR for unpredictable access patterns cache3 = RRCache(maxsize=1000) ``` -------------------------------- ### LRU Cache Decorator Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/00-START-HERE.txt Demonstrates the basic usage of the @lru_cache decorator to cache function results. Includes clearing the cache. ```python from cachetools import lru_cache @lru_cache(maxsize=128) def expensive_function(x): return x ** 2 result = expensive_function(10) info = expensive_function.cache_info() expensive_function.cache_clear() ``` -------------------------------- ### LRUCache Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Illustrates the LRUCache. The least recently accessed item is evicted when the cache is full. Accessing an item marks it as recently used. ```python lru = LRUCache(maxsize=100) lru['a'] = 1 lru['b'] = 2 lru['c'] = 3 # Access 'a' to mark it as recently used _ = lru['a'] # Cache is full, adding another triggers eviction lru['d'] = 4 # 'b' is evicted (least recently used) ``` -------------------------------- ### Configuration - Decorator Factory Functions Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Shows how to use factory functions like `lru_cache()`, `ttl_cache()`, etc., to create decorators with pre-defined cache policies and parameters. ```python from cachetools import lru_cache, ttl_cache @lru_cache(maxsize=256) def get_user_info(user_id): # Fetch user info return {'id': user_id, 'name': 'User'} @ttl_cache(maxsize=128, ttl=900) def get_settings(section): # Load settings return {'setting': 'value'} ``` -------------------------------- ### Using hashkey for Cache Keys Source: https://github.com/tkem/cachetools/blob/master/_autodocs/key-functions.md Demonstrates how to use the hashkey function to create cache keys from positional and keyword arguments. The _HashedTuple object returned caches its hash value for subsequent calls, optimizing performance. ```python from cachetools import keys key = keys.hashkey(1, 2, a=3) # First call to hash computes it hash1 = hash(key) # Subsequent calls use cached value (very fast) hash2 = hash(key) hash3 = hash(key) assert hash1 == hash2 == hash3 ``` -------------------------------- ### Per-Instance Caching Patterns Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Demonstrates how to implement caching that is specific to each instance of a class, often using `cachedmethod` with a key function that returns `self` or `id(self)`. ```python from cachetools import cachedmethod, LRUCache class ExpensiveService: def __init__(self): self.cache = LRUCache(maxsize=100) @cachedmethod(lambda self: self.cache) def get_expensive_result(self, param): # Simulate a calculation that depends on instance state and param print(f"Calculating for instance {id(self)} with param {param}") time.sleep(0.5) return f"Result for {id(self)}-{param}" service1 = ExpensiveService() service2 = ExpensiveService() print(service1.get_expensive_result('A')) # Calculates print(service1.get_expensive_result('A')) # Cached for service1 print(service2.get_expensive_result('A')) # Calculates for service2 ``` -------------------------------- ### Get Size of Cache Element Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md The static method `getsizeof` returns the size of a cache element's value. The default implementation returns 1. ```python @staticmethod def getsizeof(value: Any) -> int: return 1 ``` -------------------------------- ### Cache Initialization Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md All cache classes accept configuration parameters at initialization. This section covers the base `Cache` class. ```APIDOC ## Cache ### Constructor Parameters ```python Cache(maxsize: int, getsizeof: Optional[Callable[[Any], int]] = None) ``` | Parameter | Type | Required | Default | Valid Range | Description | |-----------|------|----------|---------|-------------|-------------| | maxsize | int | Yes | — | > 0 | Maximum total size of the cache. Items are evicted when size exceeds this value. | | getsizeof | Callable | No | None | — | Custom function to compute the size of cache values. Default behavior: every item has size 1. | ### Request Example ```python from cachetools import Cache # Default sizing (count-based) cache1 = Cache(maxsize=100) # Custom size function (bytes) import sys cache2 = Cache(maxsize=10000, getsizeof=sys.getsizeof) # Custom size function (custom logic) def string_size(value): return len(value) if isinstance(value, str) else 1 cache3 = Cache(maxsize=1000, getsizeof=string_size) ``` ``` -------------------------------- ### Safely Retrieve Value with Default Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Use `get` to retrieve a value by key, returning a specified default if the key is not found. This avoids raising a KeyError. ```python cache = Cache(maxsize=100) value = cache.get('nonexistent', 'default_value') # 'default_value' ``` -------------------------------- ### Thread Safety Patterns Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Discusses how cachetools handles thread safety, often by using locks internally. Examples might show usage in multi-threaded applications. ```python from cachetools import cached, LRUCache from threading import Thread @cached(cache=LRUCache(maxsize=10)) def thread_safe_task(x): # Simulate work time.sleep(0.1) return x * x def worker(val): print(f'Result for {val}: {thread_safe_task(val)}') threads = [Thread(target=worker, args=(i,)) for i in range(5)] for t in threads: t.start() for t in threads: t.join() ``` -------------------------------- ### System Size Function with LRUCache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Utilize `sys.getsizeof()` for memory-aware caching by passing it as the `getsizeof` argument to `LRUCache`. This example creates a cache with a maximum size of approximately 1MB. ```python from cachetools import LRUCache import sys cache = LRUCache(maxsize=1000000, getsizeof=sys.getsizeof) # ~1MB cache ``` -------------------------------- ### Avoiding Ambiguities with Default Arguments Source: https://github.com/tkem/cachetools/blob/master/docs/index.md Demonstrates how default function arguments and the use of positional vs. keyword arguments can lead to different cache entries. A helper function can ensure consistent behavior. ```python from cachetools import cached, TTLCache cache = TTLCache(maxsize=100, ttl=300) @cached(cache=cache) def foo(a, b=1): return a + b # foo(), foo(1), and foo(a=1) are treated as different invocations def _foo_impl(a, b=1): return a + b foo_consistent = cached(cache=cache)(_foo_impl) ``` -------------------------------- ### Configuration - Cache Class Initialization Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Details the parameters available when initializing cache classes like `FIFOCache`, `LRUCache`, `TTLCache`, etc., including `maxsize`, `ttl`, and `timer`. ```python from cachetools import TTLCache import time # Initialize TTLCache with maxsize and ttl ttl_cache = TTLCache(maxsize=100, ttl=600) # Initialize LRUCache with maxsize lru_cache = LRUCache(maxsize=50) # Using a custom timer function def custom_timer(): return time.time() * 1000 # milliseconds ttl_cache_custom_timer = TTLCache(maxsize=200, ttl=300, timer=custom_timer) ``` -------------------------------- ### Instantiate TTLCache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Create a TTLCache instance with a specified maximum size and time-to-live (TTL) for items. The timer function can be customized. ```python import time from typing import Callable, Optional, Any # Assuming TTLCache is imported from cachetools # from cachetools import TTLCache # Placeholder for TTLCache class definition if not imported class TTLCache: def __init__(self, maxsize: int, ttl: float, timer: Callable[[], float] = time.monotonic, getsizeof: Optional[Callable[[Any], int]] = None): pass ttl = TTLCache(maxsize=100, ttl=10) ``` -------------------------------- ### Basic Usage of @cachetools.cached Source: https://github.com/tkem/cachetools/blob/master/docs/index.md A simple example of using the @cachetools.cached decorator to memoize a function. This decorator stores results in a cache, reducing computation for repeated calls with the same arguments. ```python from cachetools import cached, TTLCache cache = TTLCache(maxsize=100, ttl=300) @cached(cache=cache) def expensive_computation(x): return x * 2 ``` -------------------------------- ### Import Key Functions Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Import functions for generating cache keys. ```python from cachetools.keys import hashkey, methodkey, typedkey, typedmethodkey ``` -------------------------------- ### Custom Cache Key Functions Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Shows how to define and use custom functions to generate cache keys, allowing for more complex or specific caching logic based on function arguments. ```python from cachetools import cached, LRUCache from cachetools.keys import hashkey def custom_key_func(*args, **kwargs): # Example: only use positional arguments for key, ignore kwargs return hashkey(*args) @cached(cache=LRUCache(maxsize=10), key=custom_key_func) def process_data(a, b, c=1): print(f"Processing {a}, {b}, {c}") return a + b + c process_data(1, 2, c=3) # Uses key (1, 2) process_data(1, 2, c=4) # Uses key (1, 2) - result from previous call is returned process_data(1, 3) # Uses key (1, 3) ``` -------------------------------- ### Initialize TTLCache with Custom Timer Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Use a custom timer function with TTLCache, for example, a MockTimer for testing purposes. This allows precise control over time measurement for TTL expiration. ```python from cachetools import TTLCache # Custom timer (e.g., for testing) class MockTimer: def __init__(self): self.time = 0.0 def __call__(self): return self.time timer = MockTimer() tl3 = TTLCache(maxsize=100, ttl=10, timer=timer) ``` -------------------------------- ### TTLCache with Custom Mock Timer for Testing Source: https://github.com/tkem/cachetools/blob/master/_autodocs/configuration.md Demonstrates using a custom MockTimer class to control time progression for testing TTL expiration behavior in TTLCache. ```python class MockTimer: """Controllable timer for testing TTL behavior.""" def __init__(self): self.time = 0.0 def __call__(self): return self.time def advance(self, seconds): """Fast-forward time.""" self.time += seconds from cachetools import TTLCache timer = MockTimer() cache = TTLCache(maxsize=100, ttl=60, timer=timer) cache['key'] = 'value' # Stored at time 0 # Fast-forward 61 seconds timer.advance(61) # Item is now expired print('key' in cache) # False ``` -------------------------------- ### API Reference - FIFOCache Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Documentation for `FIFOCache`, a cache implementation that evicts the oldest items first (First-In, First-Out). ```python from cachetools import FIFOCache fifo = FIFOCache(maxsize=3) fifo['a'] = 1 fifo['b'] = 2 fifo['c'] = 3 fifo['d'] = 4 # 'a' is evicted print(list(fifo.keys())) # Output: ['b', 'c', 'd'] ``` -------------------------------- ### Memoizing Collections and Decorators Source: https://github.com/tkem/cachetools/blob/master/README.rst Demonstrates how to use cachetools decorators for dynamic programming, LRU caching of PEPs, and TTL caching of weather data. Requires importing necessary classes from cachetools. ```python from cachetools import cached, LRUCache, TTLCache # speed up calculating Fibonacci numbers with dynamic programming @cached(cache={}) def fib(n): return n if n < 2 else fib(n - 1) + fib(n - 2) # cache least recently used Python Enhancement Proposals @cached(cache=LRUCache(maxsize=32)) def get_pep(num): url = 'http://www.python.org/dev/peps/pep-%04d/' % num with urllib.request.urlopen(url) as s: return s.read() # cache weather data for no longer than ten minutes @cached(cache=TTLCache(maxsize=1024, ttl=600)) def get_weather(place): return owm.weather_at_place(place).get_weather() ``` -------------------------------- ### Cache Function with LRU Decorator Source: https://github.com/tkem/cachetools/blob/master/_autodocs/quick-reference.md Apply the `lru_cache` decorator to a function to automatically cache its results based on arguments. Use `cache_clear` to clear the cache and `cache_info` to get cache statistics. ```python from cachetools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2) result = fibonacci(10) fibonacci.cache_clear() info = fibonacci.cache_info() ``` -------------------------------- ### Advanced Patterns - Conditional Caching Source: https://github.com/tkem/cachetools/blob/master/_autodocs/MANIFEST.txt Illustrates how to apply caching selectively based on certain conditions, using custom key functions or wrapper logic. ```python from cachetools import cached, LRUCache cache_enabled = True def conditional_decorator(cache_obj, key_func): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): if not cache_enabled: return func(*args, **kwargs) key = key_func(func, *args, **kwargs) if key is None: # Custom key func can return None to disable caching return func(*args, **kwargs) if key in cache_obj: return cache_obj[key] else: result = func(*args, **kwargs) cache_obj[key] = result return result wrapper.cache = cache_obj # Expose cache for inspection/invalidation wrapper.cache_clear = cache_obj.clear return wrapper return decorator my_cache = LRUCache(maxsize=10) @conditional_decorator(my_cache, hashkey) def sensitive_operation(data): print(f"Performing sensitive operation on {data}") return data.upper() print(sensitive_operation('test')) cache_enabled = False print(sensitive_operation('test')) # Operation performed again cache_enabled = True print(sensitive_operation('test')) # Cached ``` -------------------------------- ### Cache by Argument Length Source: https://github.com/tkem/cachetools/blob/master/_autodocs/key-functions.md Implement a custom key function to cache results based on the lengths of the arguments passed. This example uses `length_key` to create a tuple of argument lengths as the cache key. ```python from cachetools import cached, LRUCache def length_key(*args, **kwargs): """Cache key based on argument lengths.""" arg_lengths = tuple(len(arg) if hasattr(arg, '__len__') else None for arg in args) return arg_lengths @cached(cache=LRUCache(maxsize=32), key=length_key) def process_list(items): return sum(items) result1 = process_list([1, 2, 3]) # Cached as key (3,) result2 = process_list([4, 5, 6]) # Same key, returns cached result! result3 = process_list([1, 2, 3, 4]) # Different key (4,) ``` -------------------------------- ### Using cachetools LRU Cache as a functools.lru_cache replacement Source: https://github.com/tkem/cachetools/blob/master/_autodocs/module-overview.md Demonstrates replacing functools.lru_cache with cachetools.lru_cache for drop-in compatibility. ```python from cachetools import lru_cache # instead of functools.lru_cache @lru_cache(maxsize=128) def fibonacci(n): return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2) ``` -------------------------------- ### Get Cache Statistics with cache_info() Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-decorators.md Retrieve cache statistics including hits, misses, maxsize, and current size. Use this to monitor cache performance and state. The cache is cleared using cache_clear(). ```python from cachetools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2) fibonacci(5) info = fibonacci.cache_info() # CacheInfo(hits=8, misses=6, maxsize=128, currsize=6) fibonacci.cache_clear() info = fibonacci.cache_info() # CacheInfo(hits=0, misses=0, maxsize=128, currsize=0) ``` -------------------------------- ### TLRUCache popitem Method Example Source: https://github.com/tkem/cachetools/blob/master/_autodocs/api-reference-cache-classes.md Use the popitem method to remove and return the least recently used item that has not expired. This is useful when the cache reaches its maximum size and a new item needs to be added. ```python import time def ttu(key, value, now): return now + 10 tlru = TLRUCache(maxsize=100, ttu=ttu) tlru['a'] = 1 tlru['b'] = 2 tlru['c'] = 3 # Cache full, popitem removes LRU non-expired item tlru['d'] = 4 # 'a' is evicted (least recently used) ```