What changed, and why it matters
This commit only adds Python type hints to a cache utility file. It does not change any actual program behavior, logic, or security controls. There is no security issue here.
No action needed. This is a non-security refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff modifies electrum/lrucache.py to add typing annotations (TypeVar, Dict, generic MutableMapping[_KT, _VT], and return/parameter types). No runtime logic is altered; the code’s behavior remains identical. Type hints are not enforced at runtime in Python, so this is a static-analysis/documentation improvement only.
Changed components
electrum/lrucache.pyInspect captured patch +24 / −21
diff --git a/electrum/lrucache.py b/electrum/lrucache.py
index f6c0956..9f81984 100644
--- a/electrum/lrucache.py
+++ b/electrum/lrucache.py
@@ -26,6 +26,7 @@
import collections
import collections.abc
+from typing import TypeVar, Dict
class _DefaultSize:
@@ -42,19 +43,21 @@ class _DefaultSize:
return 1
-class Cache(collections.abc.MutableMapping):
+_KT = TypeVar("_KT")
+_VT = TypeVar("_VT")
+class Cache(collections.abc.MutableMapping[_KT, _VT]):
"""Mutable mapping to serve as a simple cache or cache base class."""
__marker = object()
__size = _DefaultSize()
- def __init__(self, maxsize, getsizeof=None):
+ def __init__(self, maxsize: int, getsizeof=None):
if getsizeof:
self.getsizeof = getsizeof
if self.getsizeof is not Cache.getsizeof:
self.__size = dict()
- self.__data = dict()
+ self.__data = dict() # type: Dict[_KT, _VT]
self.__currsize = 0
self.__maxsize = maxsize
@@ -66,13 +69,13 @@ class Cache(collections.abc.MutableMapping):
self.__currsize,
)
- def __getitem__(self, key):
+ def __getitem__(self, key: _KT) -> _VT:
try:
return self.__data[key]
except KeyError:
return self.__missing__(key)
- def __setitem__(self, key, value):
+ def __setitem__(self, key: _KT, value: _VT) -> None:
maxsize = self.__maxsize
size = self.getsizeof(value)
if size > maxsize:
@@ -88,15 +91,15 @@ class Cache(collections.abc.MutableMapping):
self.__size[key] = size
self.__currsize += diffsize
- def __delitem__(self, key):
+ def __delitem__(self, key: _KT) -> None:
size = self.__size.pop(key)
del self.__data[key]
self.__currsize -= size
- def __contains__(self, key):
+ def __contains__(self, key: _KT) -> bool:
return key in self.__data
- def __missing__(self, key):
+ def __missing__(self, key: _KT):
raise KeyError(key)
def __iter__(self):
@@ -105,13 +108,13 @@ class Cache(collections.abc.MutableMapping):
def __len__(self):
return len(self.__data)
- def get(self, key, default=None):
+ def get(self, key: _KT, default: _VT = None) -> _VT | None:
if key in self:
return self[key]
else:
return default
- def pop(self, key, default=__marker):
+ def pop(self, key: _KT, default=__marker) -> _VT:
if key in self:
value = self[key]
del self[key]
@@ -121,7 +124,7 @@ class Cache(collections.abc.MutableMapping):
value = default
return value
- def setdefault(self, key, default=None):
+ def setdefault(self, key: _KT, default: _VT = None) -> _VT | None:
if key in self:
value = self[key]
else:
@@ -129,43 +132,43 @@ class Cache(collections.abc.MutableMapping):
return value
@property
- def maxsize(self):
+ def maxsize(self) -> int:
"""The maximum size of the cache."""
return self.__maxsize
@property
- def currsize(self):
+ def currsize(self) -> int:
"""The current size of the cache."""
return self.__currsize
@staticmethod
- def getsizeof(value):
+ def getsizeof(value) -> int:
"""Return the size of a cache element's value."""
return 1
-class LRUCache(Cache):
+class LRUCache(Cache[_KT, _VT]):
"""Least Recently Used (LRU) cache implementation."""
- def __init__(self, maxsize, getsizeof=None):
+ def __init__(self, maxsize: int, getsizeof=None):
Cache.__init__(self, maxsize, getsizeof)
self.__order = collections.OrderedDict()
- def __getitem__(self, key, cache_getitem=Cache.__getitem__):
+ def __getitem__(self, key: _KT, cache_getitem=Cache.__getitem__) -> _VT | None:
value = cache_getitem(self, key)
if key in self: # __missing__ may not store item
self.__update(key)
return value
- def __setitem__(self, key, value, cache_setitem=Cache.__setitem__):
+ def __setitem__(self, key: _KT, value, cache_setitem=Cache.__setitem__) -> None:
cache_setitem(self, key, value)
self.__update(key)
- def __delitem__(self, key, cache_delitem=Cache.__delitem__):
+ def __delitem__(self, key: _KT, cache_delitem=Cache.__delitem__) -> None:
cache_delitem(self, key)
del self.__order[key]
- def popitem(self):
+ def popitem(self) -> tuple[_KT, _VT]:
"""Remove and return the `(key, value)` pair least recently used."""
try:
key = next(iter(self.__order))
@@ -174,7 +177,7 @@ class LRUCache(Cache):
else:
return (key, self.pop(key))
- def __update(self, key):
+ def __update(self, key: _KT) -> None:
try:
self.__order.move_to_end(key)
except KeyError:
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.