@@ -843,6 +843,10 @@ def is_strict_base(typ):
843843 mro .append (subcls )
844844 return _c3_mro (cls , abcs = mro )
845845
846+ def _pep585_registry_matches (cls , registry ):
847+ from typing import get_origin
848+ return (i for i in registry .keys () if get_origin (i ) == cls )
849+
846850def _find_impl_match (cls_obj , registry ):
847851 """Returns the best matching implementation from *registry* for type *cls_obj*.
848852
@@ -861,9 +865,9 @@ def _find_impl_match(cls_obj, registry):
861865
862866 if (not isinstance (cls_obj , type ) and
863867 len (cls_obj ) > 0 and # dont try to match the types of empty containers
864- any (i for i in registry . keys () if get_origin ( i ) == cls )):
868+ any (_pep585_registry_matches ( cls , registry ) )):
865869 # check containers that match cls first
866- for t in [ i for i in registry . keys () if get_origin ( i ) == cls ] :
870+ for t in _pep585_registry_matches ( cls , registry ) :
867871 if not all ((isinstance (i , get_args (t )) for i in cls_obj )):
868872 continue
869873
@@ -898,10 +902,11 @@ def _find_impl_match(cls_obj, registry):
898902 return match
899903
900904def _find_impl (cls_obj , registry ):
901- return (
905+ return registry . get (
902906 _find_impl_match (cls_obj , registry )
903907 )
904908
909+
905910def singledispatch (func ):
906911 """Single-dispatch generic function decorator.
907912
@@ -920,6 +925,18 @@ def singledispatch(func):
920925 dispatch_cache = weakref .WeakKeyDictionary ()
921926 cache_token = None
922927
928+ def _fetch_dispatch_with_cache (cls ):
929+ try :
930+ impl = dispatch_cache [cls ]
931+ except KeyError :
932+ try :
933+ impl = registry [cls ]
934+ except KeyError :
935+ impl = _find_impl (cls , registry )
936+ dispatch_cache [cls ] = impl
937+ return impl
938+
939+
923940 def dispatch (cls_obj ):
924941 """generic_func.dispatch(cls) -> <function implementation>
925942
@@ -935,18 +952,13 @@ def dispatch(cls_obj):
935952 dispatch_cache .clear ()
936953 cache_token = current_token
937954
938-
939955 # if PEP-585 types are not registered for the given *cls*,
940956 # then we can use the cache. Otherwise, the cache cannot be used
941957 # because we need to confirm every item matches first
942- from typing import get_origin
943- if not any (i for i in registry .keys () if get_origin (i ) == cls ):
944- try :
945- impl = registry [cls ]
946- except KeyError :
947- impl = _find_impl (cls , registry )
948- dispatch_cache [cls ] = impl
949- return impl
958+ if not any (_pep585_registry_matches (cls , registry )):
959+ return _fetch_dispatch_with_cache (cls )
960+
961+ return _find_impl (cls_obj , registry )
950962
951963 def _is_valid_dispatch_type (cls ):
952964 if isinstance (cls , type ):
0 commit comments