{"id":4474,"library":"circular-dict","title":"CircularDict","description":"CircularDict is a high-performance Python data structure (version 1.9) that combines the functionality of dictionaries and circular buffers. It allows defining constraints on size (number of items) and memory usage, automatically removing the oldest entries when limits are exceeded. This makes it ideal for caching large data structures while maintaining control over the memory footprint. The library appears to be actively maintained, with regular updates.","status":"active","version":"1.9","language":"python","source_language":"en","source_url":"https://github.com/Eric-Canas/CircularDict","tags":["data-structure","dictionary","circular-buffer","cache","memory-management","high-performance"],"install":[{"cmd":"pip install circular-dict","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required Python version","package":"python","version":">=3.6","optional":false}],"imports":[{"symbol":"CircularDict","correct":"from circular_dict import CircularDict"}],"quickstart":{"code":"import os\nfrom circular_dict import CircularDict\n\n# Initialize a CircularDict with a maximum length of 3 items\nmy_dict_maxlen = CircularDict(maxlen=3)\nmy_dict_maxlen['key1'] = 'value1'\nmy_dict_maxlen['key2'] = 'value2'\nmy_dict_maxlen['key3'] = 'value3'\nprint(f\"Initial maxlen dict: {list(my_dict_maxlen.keys())}\")\nmy_dict_maxlen['key4'] = 'value4' # 'key1' is automatically removed\nprint(f\"After adding key4 (key1 removed): {list(my_dict_maxlen.keys())}\")\n\n# Initialize a CircularDict with a maximum memory usage of 4MB\n# Note: actual memory usage depends on content; this is an example.\n# For demonstration, we'll use a smaller, illustrative byte size.\n# Real-world usage requires careful calculation of object sizes.\n# Using a small maxsize_bytes for demonstration of its behavior.\nmy_dict_maxsize = CircularDict(maxsize_bytes=100) # 100 bytes approx\nmy_dict_maxsize['a'] = '1234567890' # ~10 bytes for value + key overhead\nmy_dict_maxsize['b'] = 'abcdefghij' # ~10 bytes for value + key overhead\n# Adding more items will cause older ones to be removed to stay under 100 bytes.\n# This is illustrative; actual byte size calculations are complex.\nprint(f\"\\nInitial maxsize dict: {list(my_dict_maxsize.keys())}\")\nmy_dict_maxsize['c'] = 'klmnopqrst' * 5 # A larger string\nprint(f\"After adding larger key 'c': {list(my_dict_maxsize.keys())}\")\n# Depending on exact memory model, 'a' and 'b' might be removed.","lang":"python","description":"Demonstrates initializing CircularDict with `maxlen` to limit item count and `maxsize_bytes` to limit memory. Shows how older items are automatically removed when limits are exceeded. Note that `maxsize_bytes` behavior is sensitive to the actual memory footprint of keys and values."},"warnings":[{"fix":"Ensure that the `maxsize_bytes` parameter is large enough to accommodate the largest single item you intend to store. Consider using `sys.getsizeof()` to estimate object sizes, though actual dictionary overhead adds complexity.","message":"If you attempt to add a single item (key-value pair) whose memory footprint alone exceeds the `maxsize_bytes` limit, a `MemoryError` will be raised. This means `maxsize_bytes` applies to individual items as well as the total.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Avoid iterating over a `CircularDict` simultaneously with operations that might trigger item removal (e.g., adding new items when at capacity). If iteration is necessary, consider iterating over a copy of the keys (`list(my_dict.keys())`) or values.","message":"While CircularDict inherits from Python's OrderedDict and maintains insertion order, its core functionality involves automatically removing the 'oldest' items when size or memory limits are hit. This modification can lead to a `RuntimeError` if you iterate over the dictionary while it is being modified by this automatic removal process.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Perform careful testing with representative data to determine appropriate `maxsize_bytes` values. Consider adding a buffer to your calculated `maxsize_bytes` to account for potential overheads or variations in object sizing.","message":"The `maxsize_bytes` parameter accounts for the total memory footprint, including both keys and values, and the internal overhead of the dictionary structure itself. Predicting exact memory usage can be challenging due to Python's object model and varying overheads, which might lead to unexpected removals if not carefully estimated.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.9':12 'activ':64 'allow':23 'appear':61 'automat':34 'buffer':21,75 'cach':48,76 'circular':20,74 'circular-buff':73 'circulardict':1,2 'combin':14 'constraint':25 'control':54 'data':9,50,70 'data-structur':69 'defin':24 'dictionari':18,72 'entri':38 'exceed':42 'footprint':58 'function':16 'high':6,81 'high-perform':5,80 'ideal':46 'item':30 'larg':49 'librari':60 'limit':40 'maintain':53,65 'make':44 'manag':79 'memori':32,57,78 'memory-manag':77 'number':28 'oldest':37 'perform':7,82 'python':8 'regular':67 'remov':35 'size':27 'structur':10,51,71 'updat':68 'usag':33 'version':11","created_at":"2026-04-12T13:54:12.384158+00:00","updated_at":"2026-04-16T02:11:06.538761+00:00","problems":[{"fix":"Install the package using pip: `pip install circular-dict`, and ensure the import statement is `from circular_dict import CircularDict`.","cause":"The 'circular-dict' package is not installed in the Python environment, or the import statement uses an incorrect module name.","error":"ModuleNotFoundError: No module named 'circular_dict'"},{"fix":"Increase the 'maxsize_bytes' parameter when initializing CircularDict or ensure that individual items being added do not exceed the set limit. Consider using `sys.getsizeof()` to estimate object sizes and add a buffer.","cause":"An attempt was made to add an item to a CircularDict whose memory footprint alone, or the total memory usage of the dictionary with the new item, exceeds the configured 'maxsize_bytes' limit.","error":"MemoryError"},{"fix":"Avoid modifying the CircularDict (e.g., adding new items) during iteration. If iteration is necessary, iterate over a copy of its keys (`list(my_dict.keys())`) or values to prevent concurrent modification.","cause":"This error occurs when you are iterating over a CircularDict while simultaneously modifying it, such as by adding new items that trigger the automatic removal of older entries due to size or memory limits.","error":"RuntimeError: dictionary changed size during iteration"},{"fix":"Access dictionary elements using square bracket notation: `my_dict['some_key']`. While CircularDict is a dict-like object, it does not support dot notation for key access.","cause":"You are attempting to access a key in the CircularDict using dot notation (e.g., `my_dict.some_key`) instead of the standard Python dictionary square bracket notation.","error":"AttributeError: 'CircularDict' object has no attribute 'some_key'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.9","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/Eric-Canas/CircularDict","docs":null,"changelog":null,"pypi":"https://pypi.org/project/circular-dict/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}