{"id":1476,"library":"expiringdict","title":"expiringdict","description":"expiringdict is a Python library that provides a dictionary-like object whose values automatically expire after a specified time-to-live (TTL). It's commonly used for caching purposes where stale data needs to be automatically removed. The current version is 1.2.2. The project appears to be stable with infrequent updates, indicating a maintenance phase rather than active feature development.","status":"maintenance","version":"1.2.2","language":"python","source_language":"en","source_url":"https://github.com/akhmerov/expiringdict","tags":["cache","dictionary","expiration","ttl","key-value"],"install":[{"cmd":"pip install expiringdict","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"ExpiringDict","correct":"from expiringdict import ExpiringDict"}],"quickstart":{"code":"from expiringdict import ExpiringDict\nimport time\n\n# Create an expiring dictionary with max 100 items, and items expire after 2 seconds\ncache = ExpiringDict(max_len=100, max_age_seconds=2)\n\nprint(\"Adding 'data' to cache...\")\ncache['my_key'] = 'data_value'\nprint(f\"Retrieved immediately: {cache.get('my_key', 'Not found')}\")\n\nprint(\"Waiting 3 seconds for expiration...\")\ntime.sleep(3)\n\nprint(f\"Retrieved after expiration: {cache.get('my_key', 'Not found')}\")\n# Direct access would raise KeyError: print(cache['my_key'])","lang":"python","description":"Initialize an ExpiringDict with a maximum length and item age, then demonstrate adding an item, retrieving it, and verifying its expiration after the TTL."},"warnings":[{"fix":"Ensure external locking mechanisms (e.g., threading.Lock) are used when accessing ExpiringDict from multiple threads, or use it in single-threaded contexts only.","message":"expiringdict is explicitly not thread-safe. Concurrent access from multiple threads without external locking will lead to unpredictable behavior and potential data corruption.","severity":"gotcha","affected_versions":"All versions"},{"fix":"To have items expire based on time, set `max_age_seconds` to a positive integer. If immediate removal is desired, manually delete the key or set a very small positive `max_age_seconds`.","message":"Setting `max_age_seconds` to 0 does not mean items expire immediately; it means items will *never* expire based on age. Only `max_len` will trigger eviction.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If iteration is required, convert the dictionary items to a list first (e.g., `list(exp_dict.items())`) or acquire a lock around the iteration if in a multithreaded context and ensure no other threads modify the dictionary.","message":"Iterating over an ExpiringDict while items are expiring (or being added/removed) can lead to a `RuntimeError` ('dictionary changed size during iteration') or inconsistent results, as the underlying dictionary is being modified.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.2.2':45 'activ':61 'appear':48 'automat':16,39 'cach':31,64 'common':28 'current':42 'data':35 'develop':63 'dictionari':11,65 'dictionary-lik':10 'expir':17,66 'expiringdict':1,2 'featur':62 'indic':55 'infrequ':53 'key':69 'key-valu':68 'librari':6 'like':12 'live':24 'mainten':57 'need':36 'object':13 'phase':58 'project':47 'provid':8 'purpos':32 'python':5 'rather':59 'remov':40 'specifi':20 'stabl':51 'stale':34 'time':22 'time-to-l':21 'ttl':25,67 'updat':54 'use':29 'valu':15,70 'version':43 'whose':14","created_at":"2026-04-09T03:49:34.946833+00:00","updated_at":"2026-04-16T14:53:30.130912+00:00","problems":[{"fix":"Ensure the library is installed in your active Python environment by running: `pip install expiringdict`","cause":"The Python interpreter cannot find the 'expiringdict' package, likely because it has not been installed or is installed in a different Python environment than the one being used.","error":"ModuleNotFoundError: No module named 'expiringdict'"},{"fix":"Before accessing a key, check for its presence using `key in expiring_dict` or use the `.get()` method with a default value to avoid the error. Example: `value = cache.get('foo')` or `if 'foo' in cache: value = cache['foo']`","cause":"When a key's value expires in ExpiringDict, accessing that key directly will raise a KeyError because the entry is removed from the dictionary upon access or when its `max_age_seconds` has passed, or if `max_len` is exceeded. Iterating over keys() or items() does not automatically remove expired values; expiration and removal happen on access or dictionary modification.","error":"KeyError: 'foo' (when accessing an expired item from expiringdict)"},{"fix":"To make an ExpiringDict picklable, convert it to a standard `OrderedDict` or `dict` before pickling, and then reconstruct the `ExpiringDict` upon unpickling. Example: `import dill; from expiringdict import ExpiringDict; cache = ExpiringDict(max_len=10, max_age_seconds=60); cache['test'] = 1; picklable_cache = dict(cache); pickled_object = dill.dumps(picklable_cache); original_dict = dill.loads(pickled_object); new_cache = ExpiringDict(max_len=10, max_age_seconds=60, items=original_dict)`","cause":"ExpiringDict objects, due to their custom `__init__` signature, do not pickle/unpickle correctly by default using standard `pickle` or `dill` because the constructor expects `max_len` and `max_age_seconds` arguments which are not automatically supplied during deserialization.","error":"TypeError: __init__() missing 2 required positional arguments: 'max_len' and 'max_age_seconds' (during pickling/unpickling expiringdict)"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.2.2","cli_name":"","cli_version":null,"type":"library","homepage":"https://www.mailgun.com/","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/expiringdict/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}