@@ -71,8 +71,10 @@ def get_full_name(self) -> str:
71
71
72
72
def get_signature (self ) -> Optional [inspect .Signature ]:
73
73
"""Get the Spec's signature, if Spec represents a callable."""
74
+ source = self ._get_source ()
75
+
74
76
try :
75
- return inspect .signature (self . _source ) # type: ignore[arg-type]
77
+ return inspect .signature (source )
76
78
except TypeError :
77
79
return None
78
80
@@ -82,18 +84,12 @@ def get_class_type(self) -> Optional[Type[Any]]:
82
84
83
85
def get_is_async (self ) -> bool :
84
86
"""Get whether the Spec represents an async. callable."""
85
- source = self ._source
87
+ source = self ._get_source ()
86
88
87
89
# `iscoroutinefunction` does not work for `partial` on Python < 3.8
88
90
if isinstance (source , functools .partial ):
89
91
source = source .func
90
92
91
- # check if spec source is a class with a __call__ method
92
- elif inspect .isclass (source ):
93
- call_method = inspect .getattr_static (source , "__call__" , None )
94
- if inspect .isfunction (call_method ):
95
- source = call_method
96
-
97
93
return inspect .iscoroutinefunction (source )
98
94
99
95
def bind_args (self , * args : Any , ** kwargs : Any ) -> BoundArgs :
@@ -141,6 +137,19 @@ def get_child_spec(self, name: str) -> "Spec":
141
137
142
138
return Spec (source = child_source , name = child_name , module_name = self ._module_name )
143
139
140
+ def _get_source (self ) -> Any :
141
+ source = self ._source
142
+
143
+ # check if spec source is a class with a __call__ method
144
+ if inspect .isclass (source ):
145
+ call_method = inspect .getattr_static (source , "__call__" , None )
146
+ if inspect .isfunction (call_method ):
147
+ # consume the `self` argument of the method to ensure proper
148
+ # signature reporting by wrapping it in a partial
149
+ source = functools .partial (call_method , None )
150
+
151
+ return source
152
+
144
153
145
154
def _get_type_hints (obj : Any ) -> Dict [str , Any ]:
146
155
"""Get type hints for an object, if possible.
0 commit comments