144
144
from .utils import (
145
145
Settable ,
146
146
get_defining_class ,
147
+ get_types ,
147
148
strip_doc_annotations ,
148
149
suggest_similar ,
149
150
)
@@ -5544,10 +5545,10 @@ def _validate_callable_param_count(cls, func: Callable[..., Any], count: int) ->
5544
5545
def _validate_prepostloop_callable (cls , func : Callable [[], None ]) -> None :
5545
5546
"""Check parameter and return types for preloop and postloop hooks."""
5546
5547
cls ._validate_callable_param_count (func , 0 )
5547
- # make sure there is no return notation
5548
- signature = inspect . signature (func )
5549
- if signature . return_annotation is not None :
5550
- raise TypeError (f"{ func .__name__ } must declare return a return type of 'None'" )
5548
+ # make sure there is no return annotation or the return is specified as None
5549
+ _ , ret_ann = get_types (func )
5550
+ if ret_ann is not None :
5551
+ raise TypeError (f"{ func .__name__ } must have a return type of 'None', got: { ret_ann } " )
5551
5552
5552
5553
def register_preloop_hook (self , func : Callable [[], None ]) -> None :
5553
5554
"""Register a function to be called at the beginning of the command loop."""
@@ -5563,11 +5564,13 @@ def register_postloop_hook(self, func: Callable[[], None]) -> None:
5563
5564
def _validate_postparsing_callable (cls , func : Callable [[plugin .PostparsingData ], plugin .PostparsingData ]) -> None :
5564
5565
"""Check parameter and return types for postparsing hooks."""
5565
5566
cls ._validate_callable_param_count (cast (Callable [..., Any ], func ), 1 )
5566
- signature = inspect .signature (func )
5567
- _ , param = next (iter (signature .parameters .items ()))
5568
- if param .annotation != plugin .PostparsingData :
5567
+ type_hints , ret_ann = get_types (func )
5568
+ if not type_hints :
5569
+ raise TypeError (f"{ func .__name__ } parameter is missing a type hint, expected: 'cmd2.plugin.PostparsingData'" )
5570
+ par_ann = next (iter (type_hints .values ()))
5571
+ if par_ann != plugin .PostparsingData :
5569
5572
raise TypeError (f"{ func .__name__ } must have one parameter declared with type 'cmd2.plugin.PostparsingData'" )
5570
- if signature . return_annotation != plugin .PostparsingData :
5573
+ if ret_ann != plugin .PostparsingData :
5571
5574
raise TypeError (f"{ func .__name__ } must declare return a return type of 'cmd2.plugin.PostparsingData'" )
5572
5575
5573
5576
def register_postparsing_hook (self , func : Callable [[plugin .PostparsingData ], plugin .PostparsingData ]) -> None :
@@ -5582,21 +5585,21 @@ def _validate_prepostcmd_hook(
5582
5585
cls , func : Callable [[CommandDataType ], CommandDataType ], data_type : type [CommandDataType ]
5583
5586
) -> None :
5584
5587
"""Check parameter and return types for pre and post command hooks."""
5585
- signature = inspect .signature (func )
5586
5588
# validate that the callable has the right number of parameters
5587
5589
cls ._validate_callable_param_count (cast (Callable [..., Any ], func ), 1 )
5590
+
5591
+ type_hints , ret_ann = get_types (func )
5592
+ if not type_hints :
5593
+ raise TypeError (f"{ func .__name__ } parameter is missing a type hint, expected: { data_type } " )
5594
+ param_name , par_ann = next (iter (type_hints .items ()))
5588
5595
# validate the parameter has the right annotation
5589
- paramname = next (iter (signature .parameters .keys ()))
5590
- param = signature .parameters [paramname ]
5591
- if param .annotation != data_type :
5592
- raise TypeError (f'argument 1 of { func .__name__ } has incompatible type { param .annotation } , expected { data_type } ' )
5596
+ if par_ann != data_type :
5597
+ raise TypeError (f'argument 1 of { func .__name__ } has incompatible type { par_ann } , expected { data_type } ' )
5593
5598
# validate the return value has the right annotation
5594
- if signature . return_annotation == signature . empty :
5599
+ if ret_ann is None :
5595
5600
raise TypeError (f'{ func .__name__ } does not have a declared return type, expected { data_type } ' )
5596
- if signature .return_annotation != data_type :
5597
- raise TypeError (
5598
- f'{ func .__name__ } has incompatible return type { signature .return_annotation } , expected { data_type } '
5599
- )
5601
+ if ret_ann != data_type :
5602
+ raise TypeError (f'{ func .__name__ } has incompatible return type { ret_ann } , expected { data_type } ' )
5600
5603
5601
5604
def register_precmd_hook (self , func : Callable [[plugin .PrecommandData ], plugin .PrecommandData ]) -> None :
5602
5605
"""Register a hook to be called before the command function."""
@@ -5614,12 +5617,16 @@ def _validate_cmdfinalization_callable(
5614
5617
) -> None :
5615
5618
"""Check parameter and return types for command finalization hooks."""
5616
5619
cls ._validate_callable_param_count (func , 1 )
5617
- signature = inspect .signature (func )
5618
- _ , param = next (iter (signature .parameters .items ()))
5619
- if param .annotation != plugin .CommandFinalizationData :
5620
- raise TypeError (f"{ func .__name__ } must have one parameter declared with type { plugin .CommandFinalizationData } " )
5621
- if signature .return_annotation != plugin .CommandFinalizationData :
5622
- raise TypeError ("{func.__name__} must declare return a return type of {plugin.CommandFinalizationData}" )
5620
+ type_hints , ret_ann = get_types (func )
5621
+ if not type_hints :
5622
+ raise TypeError (f"{ func .__name__ } parameter is missing a type hint, expected: { plugin .CommandFinalizationData } " )
5623
+ _ , par_ann = next (iter (type_hints .items ()))
5624
+ if par_ann != plugin .CommandFinalizationData :
5625
+ raise TypeError (
5626
+ f"{ func .__name__ } must have one parameter declared with type { plugin .CommandFinalizationData } , got: { par_ann } "
5627
+ )
5628
+ if ret_ann != plugin .CommandFinalizationData :
5629
+ raise TypeError (f"{ func .__name__ } must declare return a return type of { plugin .CommandFinalizationData } " )
5623
5630
5624
5631
def register_cmdfinalization_hook (
5625
5632
self , func : Callable [[plugin .CommandFinalizationData ], plugin .CommandFinalizationData ]
0 commit comments