@@ -397,19 +397,16 @@ class multidispatch(multimethod, dict[tuple[type, ...], Callable[..., RETURN]]):
397
397
Allows dispatching on keyword arguments based on the first function signature.
398
398
"""
399
399
400
- signature : Optional [ inspect .Signature ]
400
+ signatures : dict [ tuple , inspect .Signature ]
401
401
402
402
def __new__ (cls , func : Callable [..., RETURN ]) -> "multidispatch[RETURN]" :
403
403
return functools .update_wrapper (dict .__new__ (cls ), func ) # type: ignore
404
404
405
405
def __init__ (self , func : Callable [..., RETURN ]) -> None :
406
406
self .pending = set ()
407
407
self .generics = []
408
- try :
409
- self .signature = inspect .signature (func )
410
- except ValueError :
411
- self .signature = None
412
- msg = "base implementation will eventually ignore annotations as `singledispatch does`"
408
+ self .signatures = {}
409
+ msg = "base implementation will eventually ignore annotations as `singledispatch` does"
413
410
with contextlib .suppress (NameError , AttributeError , TypeError ):
414
411
hints = signature .from_hints (func )
415
412
if hints and all (map (issubclass , hints , hints )):
@@ -419,9 +416,20 @@ def __init__(self, func: Callable[..., RETURN]) -> None:
419
416
def __get__ (self , instance , owner ) -> Callable [..., RETURN ]:
420
417
return self if instance is None else types .MethodType (self , instance ) # type: ignore
421
418
419
+ def __setitem__ (self , types : tuple , func : Callable ):
420
+ super ().__setitem__ (types , func )
421
+ with contextlib .suppress (ValueError ):
422
+ signature = inspect .signature (func )
423
+ self .signatures .setdefault (tuple (signature .parameters ), signature )
424
+
422
425
def __call__ (self , * args : Any , ** kwargs : Any ) -> RETURN :
423
426
"""Resolve and dispatch to best method."""
424
- params = self .signature .bind (* args , ** kwargs ).args if (kwargs and self .signature ) else args
427
+ params = args
428
+ if kwargs :
429
+ for signature in self .signatures .values (): # pragma: no branch
430
+ with contextlib .suppress (TypeError ):
431
+ params = signature .bind (* args , ** kwargs ).args
432
+ break
425
433
func = self .dispatch (* params )
426
434
return func (* args , ** kwargs )
427
435
0 commit comments