22
33from collections .abc import Callable , Hashable
44from functools import wraps
5- from typing import Any , Generic , ParamSpec , TypeVar , TYPE_CHECKING
6-
7- if TYPE_CHECKING :
8- type NodeKey = Any | None
9- type NodeValue = Any | None
10- else :
11- NodeKey = TypeVar ("NodeKey" , bound = Hashable )
12- NodeValue = TypeVar ("NodeValue" )
5+ from typing import Any , Generic , ParamSpec , TypeVar
136
147T = TypeVar ("T" , bound = Hashable )
158U = TypeVar ("U" )
1811
1912
2013class DoubleLinkedListNode :
21- """Node built for LRU Cache"""
14+ """Node for LRU Cache"""
2215
23- def __init__ (self , key : NodeKey , val : NodeValue ) -> None :
16+ def __init__ (self , key : Any | None , val : Any | None ) -> None :
2417 self .key = key
2518 self .val = val
2619 self .next : DoubleLinkedListNode | None = None
@@ -52,7 +45,7 @@ def add(self, node: DoubleLinkedListNode) -> None:
5245 prev = self .rear .prev
5346 if not prev :
5447 raise ValueError ("Invalid list state" )
55-
48+
5649 prev .next = node
5750 node .prev = prev
5851 self .rear .prev = node
@@ -62,7 +55,7 @@ def remove(self, node: DoubleLinkedListNode) -> DoubleLinkedListNode | None:
6255 """Remove node from list"""
6356 if not node .prev or not node .next :
6457 return None
65-
58+
6659 node .prev .next = node .next
6760 node .next .prev = node .prev
6861 node .prev = node .next = None
@@ -96,7 +89,7 @@ def get(self, key: T) -> U | None:
9689 node = self .cache [key ]
9790 if self .list .remove (node ):
9891 self .list .add (node )
99- return node .val
92+ return node .val # type: ignore[return-value]
10093 self .misses += 1
10194 return None
10295
@@ -112,7 +105,7 @@ def put(self, key: T, value: U) -> None:
112105 if self .size >= self .capacity :
113106 first = self .list .head .next
114107 if first and first .key and self .list .remove (first ):
115- del self .cache [first .key ]
108+ del self .cache [first .key ] # type: ignore[index]
116109 self .size -= 1
117110
118111 new_node = DoubleLinkedListNode (key , value )
@@ -123,26 +116,25 @@ def put(self, key: T, value: U) -> None:
123116 @classmethod
124117 def decorator (cls , size : int = 128 ) -> Callable [[Callable [P , R ]], Callable [P , R ]]:
125118 """LRU Cache decorator"""
126-
127119 def decorator_func (func : Callable [P , R ]) -> Callable [P , R ]:
128- cache = cls [Any , R ](size ) # type: ignore[type-var]
129-
120+ # Create non-generic cache instance
121+ cache = cls (size ) # type: ignore[assignment]
122+
130123 @wraps (func )
131124 def wrapper (* args : P .args , ** kwargs : P .kwargs ) -> R :
132125 key = (args , tuple (sorted (kwargs .items ())))
133126 if (result := cache .get (key )) is None :
134127 result = func (* args , ** kwargs )
135128 cache .put (key , result )
136129 return result
137-
130+
138131 # Add cache_info attribute
139132 wrapper .cache_info = lambda : cache # type: ignore[attr-defined]
140133 return wrapper
141-
134+
142135 return decorator_func
143136
144137
145138if __name__ == "__main__" :
146139 import doctest
147-
148140 doctest .testmod ()
0 commit comments