We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Our Breakpoint class should reset all stop caches
Essentially what I wrote here https://github.com/pwndbg/pwndbg/pull/1799#discussion_r1267211887 - instead of clearing only registers cache, we should clear all caches that were registered to be cleared by the 'stop' event in our Breakpoint class:

https://github.com/pwndbg/pwndbg/blob/cb053dda41c0aadb9e186c596c306ec86773867e/pwndbg/gdblib/bpoint.py#L6-L26

This can be done with this code:
```py
pwndbg.lib.cache._ALL_CACHE_UNTIL_EVENTS['stop'].clear()
```

but we should probably make a function for this instead of using the `_...` variable? :)

Our Breakpoint class should reset all stop caches
Essentially what I wrote here https://github.com/pwndbg/pwndbg/pull/1799#discussion_r1267211887 - instead of clearing only registers cache, we should clear all caches that were registered to be cleared by the 'stop' event in our Breakpoint class:

https://github.com/pwndbg/pwndbg/blob/cb053dda41c0aadb9e186c596c306ec86773867e/pwndbg/gdblib/bpoint.py#L6-L26

This can be done with this code:
```py
pwndbg.lib.cache._ALL_CACHE_UNTIL_EVENTS['stop'].clear()
```

but we should probably make a function for this instead of using the `_...` variable? :)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwndbg/gdblib/bpoint.py`
Content:
```
1 import gdb
2 
3 import pwndbg.lib.cache
4 
5 
6 class Breakpoint(gdb.Breakpoint):
7     """
8     Breakpoint class, similar to gdb.Breakpoint, but clears the caches
9     associated with the stop event before determining whether it should stop the
10     inferior or not.
11 
12     Unlike gdb.Breakpoint, users of this class should override `should_stop()`,
13     instead of `stop()`, as the latter is used to do cache invalidation.
14     """
15 
16     def stop(self):
17         # Clear the cache for the stop event.
18         pwndbg.gdblib.regs.__getattr__.cache.clear()
19         return self.should_stop()
20 
21     def should_stop(self):
22         """
23         This function is called whenever this breakpoint is hit in the code and
24         its return value determines whether the inferior will be stopped.
25         """
26         return True
27
```

Path: `pwndbg/lib/cache.py`
Content:
```
1 """
2 Caches return values until some event in the inferior happens,
3 e.g. execution stops because of a SIGINT or breakpoint, or a
4 new library/objfile are loaded, etc.
5 """
6 
7 from collections import UserDict
8 from functools import wraps
9 from typing import Any
10 from typing import Callable
11 from typing import Dict
12 from typing import List
13 from typing import Tuple
14 from typing import Union
15 
16 # Set to enable print logging of cache hits/misses/clears
17 NO_DEBUG, DEBUG_GET, DEBUG_CLEAR, DEBUG_SET = 0, 1, 2, 4
18 # combine the flags with | operator
19 debug = NO_DEBUG
20 # debug_name can be used to filter cache results by a given name
21 debug_name = "regs"
22 
23 
24 class DebugCacheDict(UserDict):
25     def __init__(self, func, *args, **kwargs) -> None:
26         super().__init__(*args, **kwargs)
27         self.hits = 0
28         self.misses = 0
29         self.func = func
30         self.name = f'{func.__module__.split(".")[-1]}.{func.__name__}'
31 
32     def __getitem__(self, key):
33         if debug & DEBUG_GET and (not debug_name or debug_name in self.name):
34             print(f"GET {self.name}: {key}")
35         try:
36             value = self.data[key]
37             self.hits += 1
38             return value
39         except KeyError:
40             self.misses += 1
41             raise
42 
43     def __setitem__(self, key, value) -> None:
44         if debug & DEBUG_SET and (not debug_name or debug_name in self.name):
45             print(f"SET {self.name}: {key}={value}")
46         self.data[key] = value
47 
48     def clear(self) -> None:
49         if debug & DEBUG_CLEAR and (not debug_name or debug_name in self.name):
50             print(f"CLEAR {self.name} (hits: {self.hits}, misses: {self.misses})")
51         self.data.clear()
52         self.hits = 0
53         self.misses = 0
54 
55 
56 Cache = Union[Dict[Tuple[Any], Any], DebugCacheDict]
57 
58 
59 class _CacheUntilEvent:
60     def __init__(self) -> None:
61         self.caches: List[Cache] = []
62 
63     def connect_event_hooks(self, event_hooks) -> None:
64         """
65         A given cache until event may require multiple debugger events
66         to be handled properly. E.g. our `stop` cache needs to be handled
67         by `stop`, `mem_changed` and `reg_changed` events.
68         """
69         for event_hook in event_hooks:
70             event_hook(self.clear)
71 
72     def clear(self) -> None:
73         for cache in self.caches:
74             cache.clear()
75 
76     def add_cache(self, cache) -> None:
77         self.caches.append(cache)
78 
79 
80 _ALL_CACHE_UNTIL_EVENTS = {
81     "stop": _CacheUntilEvent(),
82     "exit": _CacheUntilEvent(),
83     "objfile": _CacheUntilEvent(),
84     "start": _CacheUntilEvent(),
85     "cont": _CacheUntilEvent(),
86     "thread": _CacheUntilEvent(),
87     "prompt": _CacheUntilEvent(),
88     "forever": _CacheUntilEvent(),
89 }
90 _ALL_CACHE_EVENT_NAMES = tuple(_ALL_CACHE_UNTIL_EVENTS.keys())
91 
92 
93 def connect_clear_caching_events(event_dicts) -> None:
94     """
95     Connect given debugger event hooks to correspoonding _CacheUntilEvent instances
96     """
97     for event_name, event_hooks in event_dicts.items():
98         _ALL_CACHE_UNTIL_EVENTS[event_name].connect_event_hooks(event_hooks)
99 
100 
101 # A singleton used to mark a cache miss
102 _NOT_FOUND_IN_CACHE = object()
103 _KWARGS_SEPARATOR = object()
104 
105 # Global value whether the results from cache are returned or not
106 IS_CACHING = True
107 
108 
109 def cache_until(*event_names) -> Callable:
110     if any(event_name not in _ALL_CACHE_EVENT_NAMES for event_name in event_names):
111         raise ValueError(
112             f"Unknown event name[s] passed to the `cache_until` decorator: {event_names}.\n"
113             f"Expected: {_ALL_CACHE_EVENT_NAMES}"
114         )
115 
116     def inner(func):
117         if hasattr(func, "cache"):
118             raise ValueError(
119                 f"Cannot cache the {func.__name__} function twice! "
120                 "Pass multiple event names to the `cache_until` decorator."
121             )
122 
123         cache: Cache = {} if not debug else DebugCacheDict(func)
124 
125         @wraps(func)
126         def decorator(*a, **kw):
127             if IS_CACHING:
128                 key: Tuple[Any] = (a, _KWARGS_SEPARATOR, *kw.items())
129 
130                 # Check if the value is in the cache; if we have a cache miss,
131                 # we return a special singleton object `_NOT_FOUND_IN_CACHE`. This way
132                 # we can also cache a result of 'None' from a function
133                 value = cache.get(key, _NOT_FOUND_IN_CACHE)
134                 if value is not _NOT_FOUND_IN_CACHE:
135                     return value
136 
137                 value = func(*a, **kw)
138 
139                 # Sanity check: its not perfect and won't cover all cases like ([],)
140                 # but it should be good enough
141                 if isinstance(value, list):
142                     print(f"Should not cache mutable types! {func.__name__}")
143 
144                 cache[key] = value
145 
146                 return value
147 
148             return func(*a, **kw)
149 
150         # Set the cache on the function so it can be cleared on demand
151         # this may be useful for tests
152         decorator.cache = cache
153 
154         # Register the cache for the given event so it can be cleared
155         for event_name in event_names:
156             _ALL_CACHE_UNTIL_EVENTS[event_name].add_cache(cache)
157 
158         return decorator
159 
160     return inner
161 
162 
163 def clear_caches() -> None:
164     for cache in _ALL_CACHE_UNTIL_EVENTS.values():
165         cache.clear()
166
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwndbg/gdblib/bpoint.py b/pwndbg/gdblib/bpoint.py
--- a/pwndbg/gdblib/bpoint.py
+++ b/pwndbg/gdblib/bpoint.py
@@ -15,7 +15,7 @@
 
     def stop(self):
         # Clear the cache for the stop event.
-        pwndbg.gdblib.regs.__getattr__.cache.clear()
+        pwndbg.lib.cache.clear_cache("stop")
         return self.should_stop()
 
     def should_stop(self):
diff --git a/pwndbg/lib/cache.py b/pwndbg/lib/cache.py
--- a/pwndbg/lib/cache.py
+++ b/pwndbg/lib/cache.py
@@ -163,3 +163,7 @@
 def clear_caches() -> None:
     for cache in _ALL_CACHE_UNTIL_EVENTS.values():
         cache.clear()
+
+
+def clear_cache(cache_name) -> None:
+    _ALL_CACHE_UNTIL_EVENTS[cache_name].clear()

{"golden_diff": "diff --git a/pwndbg/gdblib/bpoint.py b/pwndbg/gdblib/bpoint.py\n--- a/pwndbg/gdblib/bpoint.py\n+++ b/pwndbg/gdblib/bpoint.py\n@@ -15,7 +15,7 @@\n \n     def stop(self):\n         # Clear the cache for the stop event.\n-        pwndbg.gdblib.regs.__getattr__.cache.clear()\n+        pwndbg.lib.cache.clear_cache(\"stop\")\n         return self.should_stop()\n \n     def should_stop(self):\ndiff --git a/pwndbg/lib/cache.py b/pwndbg/lib/cache.py\n--- a/pwndbg/lib/cache.py\n+++ b/pwndbg/lib/cache.py\n@@ -163,3 +163,7 @@\n def clear_caches() -> None:\n     for cache in _ALL_CACHE_UNTIL_EVENTS.values():\n         cache.clear()\n+\n+\n+def clear_cache(cache_name) -> None:\n+    _ALL_CACHE_UNTIL_EVENTS[cache_name].clear()\n", "issue": "Our Breakpoint class should reset all stop caches\nEssentially what I wrote here https://github.com/pwndbg/pwndbg/pull/1799#discussion_r1267211887 - instead of clearing only registers cache, we should clear all caches that were registered to be cleared by the 'stop' event in our Breakpoint class:\r\n\r\nhttps://github.com/pwndbg/pwndbg/blob/cb053dda41c0aadb9e186c596c306ec86773867e/pwndbg/gdblib/bpoint.py#L6-L26\r\n\r\nThis can be done with this code:\r\n```py\r\npwndbg.lib.cache._ALL_CACHE_UNTIL_EVENTS['stop'].clear()\r\n```\r\n\r\nbut we should probably make a function for this instead of using the `_...` variable? :)\r\n\nOur Breakpoint class should reset all stop caches\nEssentially what I wrote here https://github.com/pwndbg/pwndbg/pull/1799#discussion_r1267211887 - instead of clearing only registers cache, we should clear all caches that were registered to be cleared by the 'stop' event in our Breakpoint class:\r\n\r\nhttps://github.com/pwndbg/pwndbg/blob/cb053dda41c0aadb9e186c596c306ec86773867e/pwndbg/gdblib/bpoint.py#L6-L26\r\n\r\nThis can be done with this code:\r\n```py\r\npwndbg.lib.cache._ALL_CACHE_UNTIL_EVENTS['stop'].clear()\r\n```\r\n\r\nbut we should probably make a function for this instead of using the `_...` variable? :)\r\n\n", "before_files": [{"content": "import gdb\n\nimport pwndbg.lib.cache\n\n\nclass Breakpoint(gdb.Breakpoint):\n    \"\"\"\n    Breakpoint class, similar to gdb.Breakpoint, but clears the caches\n    associated with the stop event before determining whether it should stop the\n    inferior or not.\n\n    Unlike gdb.Breakpoint, users of this class should override `should_stop()`,\n    instead of `stop()`, as the latter is used to do cache invalidation.\n    \"\"\"\n\n    def stop(self):\n        # Clear the cache for the stop event.\n        pwndbg.gdblib.regs.__getattr__.cache.clear()\n        return self.should_stop()\n\n    def should_stop(self):\n        \"\"\"\n        This function is called whenever this breakpoint is hit in the code and\n        its return value determines whether the inferior will be stopped.\n        \"\"\"\n        return True\n", "path": "pwndbg/gdblib/bpoint.py"}, {"content": "\"\"\"\nCaches return values until some event in the inferior happens,\ne.g. execution stops because of a SIGINT or breakpoint, or a\nnew library/objfile are loaded, etc.\n\"\"\"\n\nfrom collections import UserDict\nfrom functools import wraps\nfrom typing import Any\nfrom typing import Callable\nfrom typing import Dict\nfrom typing import List\nfrom typing import Tuple\nfrom typing import Union\n\n# Set to enable print logging of cache hits/misses/clears\nNO_DEBUG, DEBUG_GET, DEBUG_CLEAR, DEBUG_SET = 0, 1, 2, 4\n# combine the flags with | operator\ndebug = NO_DEBUG\n# debug_name can be used to filter cache results by a given name\ndebug_name = \"regs\"\n\n\nclass DebugCacheDict(UserDict):\n    def __init__(self, func, *args, **kwargs) -> None:\n        super().__init__(*args, **kwargs)\n        self.hits = 0\n        self.misses = 0\n        self.func = func\n        self.name = f'{func.__module__.split(\".\")[-1]}.{func.__name__}'\n\n    def __getitem__(self, key):\n        if debug & DEBUG_GET and (not debug_name or debug_name in self.name):\n            print(f\"GET {self.name}: {key}\")\n        try:\n            value = self.data[key]\n            self.hits += 1\n            return value\n        except KeyError:\n            self.misses += 1\n            raise\n\n    def __setitem__(self, key, value) -> None:\n        if debug & DEBUG_SET and (not debug_name or debug_name in self.name):\n            print(f\"SET {self.name}: {key}={value}\")\n        self.data[key] = value\n\n    def clear(self) -> None:\n        if debug & DEBUG_CLEAR and (not debug_name or debug_name in self.name):\n            print(f\"CLEAR {self.name} (hits: {self.hits}, misses: {self.misses})\")\n        self.data.clear()\n        self.hits = 0\n        self.misses = 0\n\n\nCache = Union[Dict[Tuple[Any], Any], DebugCacheDict]\n\n\nclass _CacheUntilEvent:\n    def __init__(self) -> None:\n        self.caches: List[Cache] = []\n\n    def connect_event_hooks(self, event_hooks) -> None:\n        \"\"\"\n        A given cache until event may require multiple debugger events\n        to be handled properly. E.g. our `stop` cache needs to be handled\n        by `stop`, `mem_changed` and `reg_changed` events.\n        \"\"\"\n        for event_hook in event_hooks:\n            event_hook(self.clear)\n\n    def clear(self) -> None:\n        for cache in self.caches:\n            cache.clear()\n\n    def add_cache(self, cache) -> None:\n        self.caches.append(cache)\n\n\n_ALL_CACHE_UNTIL_EVENTS = {\n    \"stop\": _CacheUntilEvent(),\n    \"exit\": _CacheUntilEvent(),\n    \"objfile\": _CacheUntilEvent(),\n    \"start\": _CacheUntilEvent(),\n    \"cont\": _CacheUntilEvent(),\n    \"thread\": _CacheUntilEvent(),\n    \"prompt\": _CacheUntilEvent(),\n    \"forever\": _CacheUntilEvent(),\n}\n_ALL_CACHE_EVENT_NAMES = tuple(_ALL_CACHE_UNTIL_EVENTS.keys())\n\n\ndef connect_clear_caching_events(event_dicts) -> None:\n    \"\"\"\n    Connect given debugger event hooks to correspoonding _CacheUntilEvent instances\n    \"\"\"\n    for event_name, event_hooks in event_dicts.items():\n        _ALL_CACHE_UNTIL_EVENTS[event_name].connect_event_hooks(event_hooks)\n\n\n# A singleton used to mark a cache miss\n_NOT_FOUND_IN_CACHE = object()\n_KWARGS_SEPARATOR = object()\n\n# Global value whether the results from cache are returned or not\nIS_CACHING = True\n\n\ndef cache_until(*event_names) -> Callable:\n    if any(event_name not in _ALL_CACHE_EVENT_NAMES for event_name in event_names):\n        raise ValueError(\n            f\"Unknown event name[s] passed to the `cache_until` decorator: {event_names}.\\n\"\n            f\"Expected: {_ALL_CACHE_EVENT_NAMES}\"\n        )\n\n    def inner(func):\n        if hasattr(func, \"cache\"):\n            raise ValueError(\n                f\"Cannot cache the {func.__name__} function twice! \"\n                \"Pass multiple event names to the `cache_until` decorator.\"\n            )\n\n        cache: Cache = {} if not debug else DebugCacheDict(func)\n\n        @wraps(func)\n        def decorator(*a, **kw):\n            if IS_CACHING:\n                key: Tuple[Any] = (a, _KWARGS_SEPARATOR, *kw.items())\n\n                # Check if the value is in the cache; if we have a cache miss,\n                # we return a special singleton object `_NOT_FOUND_IN_CACHE`. This way\n                # we can also cache a result of 'None' from a function\n                value = cache.get(key, _NOT_FOUND_IN_CACHE)\n                if value is not _NOT_FOUND_IN_CACHE:\n                    return value\n\n                value = func(*a, **kw)\n\n                # Sanity check: its not perfect and won't cover all cases like ([],)\n                # but it should be good enough\n                if isinstance(value, list):\n                    print(f\"Should not cache mutable types! {func.__name__}\")\n\n                cache[key] = value\n\n                return value\n\n            return func(*a, **kw)\n\n        # Set the cache on the function so it can be cleared on demand\n        # this may be useful for tests\n        decorator.cache = cache\n\n        # Register the cache for the given event so it can be cleared\n        for event_name in event_names:\n            _ALL_CACHE_UNTIL_EVENTS[event_name].add_cache(cache)\n\n        return decorator\n\n    return inner\n\n\ndef clear_caches() -> None:\n    for cache in _ALL_CACHE_UNTIL_EVENTS.values():\n        cache.clear()\n", "path": "pwndbg/lib/cache.py"}], "after_files": [{"content": "import gdb\n\nimport pwndbg.lib.cache\n\n\nclass Breakpoint(gdb.Breakpoint):\n    \"\"\"\n    Breakpoint class, similar to gdb.Breakpoint, but clears the caches\n    associated with the stop event before determining whether it should stop the\n    inferior or not.\n\n    Unlike gdb.Breakpoint, users of this class should override `should_stop()`,\n    instead of `stop()`, as the latter is used to do cache invalidation.\n    \"\"\"\n\n    def stop(self):\n        # Clear the cache for the stop event.\n        pwndbg.lib.cache.clear_cache(\"stop\")\n        return self.should_stop()\n\n    def should_stop(self):\n        \"\"\"\n        This function is called whenever this breakpoint is hit in the code and\n        its return value determines whether the inferior will be stopped.\n        \"\"\"\n        return True\n", "path": "pwndbg/gdblib/bpoint.py"}, {"content": "\"\"\"\nCaches return values until some event in the inferior happens,\ne.g. execution stops because of a SIGINT or breakpoint, or a\nnew library/objfile are loaded, etc.\n\"\"\"\n\nfrom collections import UserDict\nfrom functools import wraps\nfrom typing import Any\nfrom typing import Callable\nfrom typing import Dict\nfrom typing import List\nfrom typing import Tuple\nfrom typing import Union\n\n# Set to enable print logging of cache hits/misses/clears\nNO_DEBUG, DEBUG_GET, DEBUG_CLEAR, DEBUG_SET = 0, 1, 2, 4\n# combine the flags with | operator\ndebug = NO_DEBUG\n# debug_name can be used to filter cache results by a given name\ndebug_name = \"regs\"\n\n\nclass DebugCacheDict(UserDict):\n    def __init__(self, func, *args, **kwargs) -> None:\n        super().__init__(*args, **kwargs)\n        self.hits = 0\n        self.misses = 0\n        self.func = func\n        self.name = f'{func.__module__.split(\".\")[-1]}.{func.__name__}'\n\n    def __getitem__(self, key):\n        if debug & DEBUG_GET and (not debug_name or debug_name in self.name):\n            print(f\"GET {self.name}: {key}\")\n        try:\n            value = self.data[key]\n            self.hits += 1\n            return value\n        except KeyError:\n            self.misses += 1\n            raise\n\n    def __setitem__(self, key, value) -> None:\n        if debug & DEBUG_SET and (not debug_name or debug_name in self.name):\n            print(f\"SET {self.name}: {key}={value}\")\n        self.data[key] = value\n\n    def clear(self) -> None:\n        if debug & DEBUG_CLEAR and (not debug_name or debug_name in self.name):\n            print(f\"CLEAR {self.name} (hits: {self.hits}, misses: {self.misses})\")\n        self.data.clear()\n        self.hits = 0\n        self.misses = 0\n\n\nCache = Union[Dict[Tuple[Any], Any], DebugCacheDict]\n\n\nclass _CacheUntilEvent:\n    def __init__(self) -> None:\n        self.caches: List[Cache] = []\n\n    def connect_event_hooks(self, event_hooks) -> None:\n        \"\"\"\n        A given cache until event may require multiple debugger events\n        to be handled properly. E.g. our `stop` cache needs to be handled\n        by `stop`, `mem_changed` and `reg_changed` events.\n        \"\"\"\n        for event_hook in event_hooks:\n            event_hook(self.clear)\n\n    def clear(self) -> None:\n        for cache in self.caches:\n            cache.clear()\n\n    def add_cache(self, cache) -> None:\n        self.caches.append(cache)\n\n\n_ALL_CACHE_UNTIL_EVENTS = {\n    \"stop\": _CacheUntilEvent(),\n    \"exit\": _CacheUntilEvent(),\n    \"objfile\": _CacheUntilEvent(),\n    \"start\": _CacheUntilEvent(),\n    \"cont\": _CacheUntilEvent(),\n    \"thread\": _CacheUntilEvent(),\n    \"prompt\": _CacheUntilEvent(),\n    \"forever\": _CacheUntilEvent(),\n}\n_ALL_CACHE_EVENT_NAMES = tuple(_ALL_CACHE_UNTIL_EVENTS.keys())\n\n\ndef connect_clear_caching_events(event_dicts) -> None:\n    \"\"\"\n    Connect given debugger event hooks to correspoonding _CacheUntilEvent instances\n    \"\"\"\n    for event_name, event_hooks in event_dicts.items():\n        _ALL_CACHE_UNTIL_EVENTS[event_name].connect_event_hooks(event_hooks)\n\n\n# A singleton used to mark a cache miss\n_NOT_FOUND_IN_CACHE = object()\n_KWARGS_SEPARATOR = object()\n\n# Global value whether the results from cache are returned or not\nIS_CACHING = True\n\n\ndef cache_until(*event_names) -> Callable:\n    if any(event_name not in _ALL_CACHE_EVENT_NAMES for event_name in event_names):\n        raise ValueError(\n            f\"Unknown event name[s] passed to the `cache_until` decorator: {event_names}.\\n\"\n            f\"Expected: {_ALL_CACHE_EVENT_NAMES}\"\n        )\n\n    def inner(func):\n        if hasattr(func, \"cache\"):\n            raise ValueError(\n                f\"Cannot cache the {func.__name__} function twice! \"\n                \"Pass multiple event names to the `cache_until` decorator.\"\n            )\n\n        cache: Cache = {} if not debug else DebugCacheDict(func)\n\n        @wraps(func)\n        def decorator(*a, **kw):\n            if IS_CACHING:\n                key: Tuple[Any] = (a, _KWARGS_SEPARATOR, *kw.items())\n\n                # Check if the value is in the cache; if we have a cache miss,\n                # we return a special singleton object `_NOT_FOUND_IN_CACHE`. This way\n                # we can also cache a result of 'None' from a function\n                value = cache.get(key, _NOT_FOUND_IN_CACHE)\n                if value is not _NOT_FOUND_IN_CACHE:\n                    return value\n\n                value = func(*a, **kw)\n\n                # Sanity check: its not perfect and won't cover all cases like ([],)\n                # but it should be good enough\n                if isinstance(value, list):\n                    print(f\"Should not cache mutable types! {func.__name__}\")\n\n                cache[key] = value\n\n                return value\n\n            return func(*a, **kw)\n\n        # Set the cache on the function so it can be cleared on demand\n        # this may be useful for tests\n        decorator.cache = cache\n\n        # Register the cache for the given event so it can be cleared\n        for event_name in event_names:\n            _ALL_CACHE_UNTIL_EVENTS[event_name].add_cache(cache)\n\n        return decorator\n\n    return inner\n\n\ndef clear_caches() -> None:\n    for cache in _ALL_CACHE_UNTIL_EVENTS.values():\n        cache.clear()\n\n\ndef clear_cache(cache_name) -> None:\n    _ALL_CACHE_UNTIL_EVENTS[cache_name].clear()\n", "path": "pwndbg/lib/cache.py"}]}