Skip to content

Commit 386d6f7

Browse files
committed
_find_impl_match
1 parent 3c2eefe commit 386d6f7

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

Lib/functools.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ def is_strict_base(typ):
843843
mro.append(subcls)
844844
return _c3_mro(cls, abcs=mro)
845845

846-
def _find_impl(cls_obj, registry):
846+
def _find_impl_match(cls_obj, registry):
847847
"""Returns the best matching implementation from *registry* for type *cls_obj*.
848848
849849
Where there is no registered implementation for a specific type, its method
@@ -856,6 +856,32 @@ def _find_impl(cls_obj, registry):
856856
cls = cls_obj if isinstance(cls_obj, type) else cls_obj.__class__
857857
mro = _compose_mro(cls, registry.keys())
858858
match = None
859+
860+
from typing import get_origin, get_args
861+
862+
if (not isinstance(cls_obj, type) and
863+
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)):
865+
# check containers that match cls first
866+
for t in [i for i in registry.keys() if get_origin(i) == cls]:
867+
if not all((isinstance(i, get_args(t)) for i in cls_obj)):
868+
continue
869+
870+
if match is None:
871+
match = t
872+
873+
else:
874+
match_args = get_args(get_args(match)[0])
875+
t_args = get_args(get_args(t)[0])
876+
if len(match_args) == len(t_args):
877+
raise RuntimeError("Ambiguous dispatch: {} or {}".format( match, t))
878+
879+
elif len(t_args)<len(match_args):
880+
match = t
881+
882+
if match:
883+
return match
884+
859885
for t in mro:
860886
if match is not None:
861887
# If *match* is an implicit ABC but there is another unrelated,
@@ -868,7 +894,13 @@ def _find_impl(cls_obj, registry):
868894
break
869895
if t in registry:
870896
match = t
871-
return registry.get(match)
897+
898+
return match
899+
900+
def _find_impl(cls_obj, registry):
901+
return (
902+
_find_impl_match(cls_obj, registry)
903+
)
872904

873905
def singledispatch(func):
874906
"""Single-dispatch generic function decorator.

0 commit comments

Comments
 (0)