144144from .utils import (
145145 Settable ,
146146 get_defining_class ,
147+ get_types ,
147148 strip_doc_annotations ,
148149 suggest_similar ,
149150)
@@ -5544,10 +5545,10 @@ def _validate_callable_param_count(cls, func: Callable[..., Any], count: int) ->
55445545 def _validate_prepostloop_callable (cls , func : Callable [[], None ]) -> None :
55455546 """Check parameter and return types for preloop and postloop hooks."""
55465547 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 } " )
55515552
55525553 def register_preloop_hook (self , func : Callable [[], None ]) -> None :
55535554 """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:
55635564 def _validate_postparsing_callable (cls , func : Callable [[plugin .PostparsingData ], plugin .PostparsingData ]) -> None :
55645565 """Check parameter and return types for postparsing hooks."""
55655566 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 :
55695572 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 :
55715574 raise TypeError (f"{ func .__name__ } must declare return a return type of 'cmd2.plugin.PostparsingData'" )
55725575
55735576 def register_postparsing_hook (self , func : Callable [[plugin .PostparsingData ], plugin .PostparsingData ]) -> None :
@@ -5582,21 +5585,21 @@ def _validate_prepostcmd_hook(
55825585 cls , func : Callable [[CommandDataType ], CommandDataType ], data_type : type [CommandDataType ]
55835586 ) -> None :
55845587 """Check parameter and return types for pre and post command hooks."""
5585- signature = inspect .signature (func )
55865588 # validate that the callable has the right number of parameters
55875589 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 ()))
55885595 # 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 } ' )
55935598 # validate the return value has the right annotation
5594- if signature . return_annotation == signature . empty :
5599+ if ret_ann is None :
55955600 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 } ' )
56005603
56015604 def register_precmd_hook (self , func : Callable [[plugin .PrecommandData ], plugin .PrecommandData ]) -> None :
56025605 """Register a hook to be called before the command function."""
@@ -5614,12 +5617,16 @@ def _validate_cmdfinalization_callable(
56145617 ) -> None :
56155618 """Check parameter and return types for command finalization hooks."""
56165619 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 } " )
56235630
56245631 def register_cmdfinalization_hook (
56255632 self , func : Callable [[plugin .CommandFinalizationData ], plugin .CommandFinalizationData ]
0 commit comments