1515from types import MappingProxyType
1616from typing import (
1717 Any , Awaitable , Callable , Coroutine , Dict , FrozenSet , Generator , Generic ,
18- Optional , Set , Tuple , TypeVar , Union , overload ,
18+ Optional , Set , Tuple , TypeVar , Union , overload , MutableMapping ,
1919)
20+ from weakref import WeakKeyDictionary
2021
2122from ._context_vars import EVENT_LOOP
2223from .compat import Concatenate , ParamSpec
@@ -379,6 +380,8 @@ class Threaded(ThreadedBase[P, T]):
379380 func_type : type
380381
381382 def __init__ (self , func : Callable [P , T ]) -> None :
383+ self .__cache : MutableMapping [Any , Any ] = WeakKeyDictionary ()
384+
382385 if isinstance (func , staticmethod ):
383386 self .func_type = staticmethod
384387 self .func = func .__func__
@@ -415,14 +418,22 @@ def __get__(
415418 instance : Any ,
416419 owner : Optional [type ] = None ,
417420 ) -> "Threaded[P, T] | BoundThreaded[Any, T]" :
421+ key = instance
422+ if key in self .__cache :
423+ return self .__cache [key ]
424+
418425 if self .func_type is staticmethod :
419- return self
426+ result = self
420427 elif self .func_type is classmethod :
421428 cls = owner if instance is None else type (instance )
422- return BoundThreaded (self .func , cls )
429+ result = BoundThreaded (self .func , cls )
423430 elif instance is not None :
424- return BoundThreaded (self .func , instance )
425- return self
431+ result = BoundThreaded (self .func , instance )
432+ else :
433+ result = self
434+
435+ self .__cache [key ] = result
436+ return result
426437
427438
428439class BoundThreaded (ThreadedBase [P , T ]):
@@ -570,6 +581,7 @@ def __init__(
570581
571582 self .func = actual_func
572583 self .max_size = max_size
584+ self .__cache : MutableMapping [Any , Any ] = WeakKeyDictionary ()
573585
574586 @overload
575587 def __get__ (
@@ -592,14 +604,22 @@ def __get__(
592604 instance : Any ,
593605 owner : Optional [type ] = None ,
594606 ) -> "ThreadedIterable[P, T] | BoundThreadedIterable[Any, T]" :
607+ key = instance
608+ if key in self .__cache :
609+ return self .__cache [key ]
610+
595611 if self .func_type is staticmethod :
596- return self
612+ result = self
597613 elif self .func_type is classmethod :
598614 cls = owner if instance is None else type (instance )
599- return BoundThreadedIterable (self .func , cls , self .max_size )
615+ result = BoundThreadedIterable (self .func , cls , self .max_size )
600616 elif instance is not None :
601- return BoundThreadedIterable (self .func , instance , self .max_size )
602- return self
617+ result = BoundThreadedIterable (self .func , instance , self .max_size )
618+ else :
619+ result = self
620+
621+ self .__cache [key ] = result
622+ return result
603623
604624
605625class BoundThreadedIterable (ThreadedIterableBase [P , T ]):
0 commit comments