@@ -302,11 +302,13 @@ class Signature(inspect.Signature):
302302 Primarily used in the implementation of `ibis.common.grounds.Annotable`.
303303 """
304304
305- __slots__ = ('_cached_params ' )
305+ __slots__ = ('_patterns' , '_dataclass ' )
306306
307307 def __init__ (self , * args , ** kwargs ):
308308 super ().__init__ (* args , ** kwargs )
309- self ._cached_params = dict (self .parameters ) # avoids access via MappingProxyType which is slow compared to dict
309+ # prebuild dict of patterns to avoid slow retrieval via property&MappingProxyType
310+ self ._patterns = {k : param .annotation .pattern for k , param in self .parameters .items () if hasattr (param .annotation , 'pattern' )}
311+ self ._dataclass = self .to_dataclass ()
310312
311313 @classmethod
312314 def merge (cls , * signatures , ** annotations ):
@@ -514,27 +516,27 @@ def validate(self, func, args, kwargs):
514516
515517 return this
516518
517- def validate_nobind_using_dataclass (self , cls , * args , ** kwargs ):
519+ def validate_fast (self , func , args , kwargs ):
520+ """Faster validation using internal dataclass to bind args/kwargs to names instead of Signature.bind."""
518521 try :
519- instance = cls . __dataclass__ (* args , ** kwargs )
522+ instance = self . _dataclass (* args , ** kwargs )
520523 except TypeError as err :
521524 raise SignatureValidationError (
522525 "{call} {cause}\n \n Expected signature: {sig}" ,
523526 sig = self ,
524- func = cls ,
527+ func = func ,
525528 args = args ,
526529 kwargs = kwargs ,
527530 ) from err
528531
529- return self .validate_nobind (cls , instance .__dict__ )
532+ return self .validate_nobind (func , instance .__dict__ )
530533
531534 def validate_nobind (self , func , kwargs ):
532535 """Validate the arguments against the signature without binding."""
533536 this , errors = {}, []
534- for name , param in self ._cached_params .items ():
537+ for name , pattern in self ._patterns .items ():
535538 value = kwargs [name ]
536539
537- pattern = param .annotation .pattern
538540 result = pattern .match (value , this )
539541 if result is NoMatch :
540542 errors .append ((name , value , pattern ))
@@ -581,12 +583,12 @@ def validate_return(self, func, value):
581583 )
582584
583585 return result
584-
585- def to_dataclass (self , cls_name : str ) -> type :
586+
587+ def to_dataclass (self , cls_name : str = 'SignatureDataclass' ) -> type :
586588 """Create a dataclass from this signature.
587589
588590 Later, instantiating a dataclass from arg+kwargs and accessing the resulting __dict__
589- is much faster (~100x ) than using Signature.bind
591+ is much faster (~10-20x ) than using Signature.bind
590592 """
591593 fields = []
592594 for k , v in self .parameters .items ():
0 commit comments