22
33from collections .abc import Callable , Hashable
44from functools import wraps
5- from typing import Any , Generic , ParamSpec , TypeVar , overload , TYPE_CHECKING
5+ from typing import Any , Generic , ParamSpec , TypeVar , TYPE_CHECKING
66
77if TYPE_CHECKING :
8- type NodeKey = T | None
9- type NodeValue = U | None
8+ type NodeKey = Any | None
9+ type NodeValue = Any | None
1010else :
1111 NodeKey = TypeVar ("NodeKey" , bound = Hashable )
1212 NodeValue = TypeVar ("NodeValue" )
@@ -34,8 +34,8 @@ class DoubleLinkedList(Generic[T, U]):
3434 """Double Linked List for LRU Cache"""
3535
3636 def __init__ (self ) -> None :
37- self .head : DoubleLinkedListNode [T , U ] = DoubleLinkedListNode (None , None )
38- self .rear : DoubleLinkedListNode [T , U ] = DoubleLinkedListNode (None , None )
37+ self .head : DoubleLinkedListNode [Any , Any ] = DoubleLinkedListNode (None , None )
38+ self .rear : DoubleLinkedListNode [Any , Any ] = DoubleLinkedListNode (None , None )
3939 self .head .next , self .rear .prev = self .rear , self .head
4040
4141 def __repr__ (self ) -> str :
@@ -51,19 +51,17 @@ def add(self, node: DoubleLinkedListNode[T, U]) -> None:
5151 prev = self .rear .prev
5252 if not prev :
5353 raise ValueError ("Invalid list state" )
54-
54+
5555 prev .next = node
5656 node .prev = prev
5757 self .rear .prev = node
5858 node .next = self .rear
5959
60- def remove (
61- self , node : DoubleLinkedListNode [T , U ]
62- ) -> DoubleLinkedListNode [T , U ] | None :
60+ def remove (self , node : DoubleLinkedListNode [T , U ]) -> DoubleLinkedListNode [T , U ] | None :
6361 """Remove node from list"""
6462 if not node .prev or not node .next :
6563 return None
66-
64+
6765 node .prev .next = node .next
6866 node .next .prev = node .prev
6967 node .prev = node .next = None
@@ -82,7 +80,10 @@ def __init__(self, capacity: int) -> None:
8280 self .cache : dict [T , DoubleLinkedListNode [T , U ]] = {}
8381
8482 def __repr__ (self ) -> str :
85- return f"Cache(hits={ self .hits } , misses={ self .misses } , cap={ self .capacity } , size={ self .size } )"
83+ return (
84+ f"Cache(hits={ self .hits } , misses={ self .misses } , "
85+ f"cap={ self .capacity } , size={ self .size } )"
86+ )
8687
8788 def __contains__ (self , key : T ) -> bool :
8889 return key in self .cache
@@ -121,9 +122,8 @@ def put(self, key: T, value: U) -> None:
121122 @classmethod
122123 def decorator (cls , size : int = 128 ) -> Callable [[Callable [P , R ]], Callable [P , R ]]:
123124 """LRU Cache decorator"""
124-
125125 def decorator_func (func : Callable [P , R ]) -> Callable [P , R ]:
126- cache = cls [Any , R ](size )
126+ cache = cls [Any , R ](size ) # type: ignore[type-var]
127127
128128 @wraps (func )
129129 def wrapper (* args : P .args , ** kwargs : P .kwargs ) -> R :
@@ -133,13 +133,13 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
133133 cache .put (key , result )
134134 return result
135135
136- wrapper .cache_info = lambda : cache # Direct attribute assignment
136+ # Add cache_info attribute
137+ wrapper .cache_info = lambda : cache # type: ignore[attr-defined]
137138 return wrapper
138-
139+
139140 return decorator_func
140141
141142
142143if __name__ == "__main__" :
143144 import doctest
144-
145145 doctest .testmod ()
0 commit comments