@@ -116,7 +116,7 @@ def __init__(
116116 self .stub_desc = stub_desc or str (getattr (stub_object , "type" , stub_object ))
117117
118118 if runtime_desc is None :
119- runtime_sig = safe_inspect_signature (runtime_object )
119+ runtime_sig = safe_inspect_signature (runtime_object , object_path )
120120 if runtime_sig is None :
121121 self .runtime_desc = _truncate (repr (runtime_object ), 100 )
122122 else :
@@ -1036,7 +1036,7 @@ def verify_funcitem(
10361036 for message in _verify_static_class_methods (stub , runtime , static_runtime , object_path ):
10371037 yield Error (object_path , "is inconsistent, " + message , stub , runtime )
10381038
1039- signature = safe_inspect_signature (runtime )
1039+ signature = safe_inspect_signature (runtime , object_path )
10401040 runtime_is_coroutine = inspect .iscoroutinefunction (runtime )
10411041
10421042 if signature :
@@ -1164,7 +1164,7 @@ def verify_overloadedfuncdef(
11641164 # TODO: Should call _verify_final_method here,
11651165 # but overloaded final methods in stubs cause a stubtest crash: see #14950
11661166
1167- signature = safe_inspect_signature (runtime )
1167+ signature = safe_inspect_signature (runtime , object_path )
11681168 if not signature :
11691169 return
11701170
@@ -1526,37 +1526,48 @@ def is_read_only_property(runtime: object) -> bool:
15261526 return isinstance (runtime , property ) and runtime .fset is None
15271527
15281528
1529- def safe_inspect_signature (runtime : Any ) -> inspect .Signature | None :
1529+ def safe_inspect_signature (
1530+ runtime : Any , object_path : list [str ] | None = None
1531+ ) -> inspect .Signature | None :
15301532 if (
15311533 hasattr (runtime , "__name__" )
15321534 and runtime .__name__ == "__init__"
15331535 and hasattr (runtime , "__text_signature__" )
15341536 and runtime .__text_signature__ == "($self, /, *args, **kwargs)"
15351537 and hasattr (runtime , "__objclass__" )
1536- and runtime .__objclass__ is not object
15371538 and hasattr (runtime .__objclass__ , "__text_signature__" )
15381539 and runtime .__objclass__ .__text_signature__ is not None
15391540 ):
15401541 # This is an __init__ method with the generic C-class signature.
15411542 # In this case, the underlying class usually has a better signature,
15421543 # which we can convert into an __init__ signature by adding in the
15431544 # self parameter.
1545+ runtime_objclass = None
1546+ if runtime .__objclass__ is object :
1547+ if object_path :
1548+ module_name = "." .join (object_path [:- 2 ])
1549+ module = silent_import_module (module_name )
1550+ if module :
1551+ runtime_objclass = getattr (module , object_path [- 2 ], None )
1552+ if not (
1553+ hasattr (runtime_objclass , "__text_signature__" )
1554+ and runtime_objclass .__text_signature__ is not None
1555+ ):
1556+ runtime_objclass = None
1557+ else :
1558+ runtime_objclass = runtime .__objclass__
15441559
1545- # TODO: Handle classes who get __init__ from object, but would have
1546- # a better signature on the actual objclass if we had access to it
1547- # here. This would probably require a second parameter on
1548- # safe_inspect_signature to pass in the original class that this
1549- # runtime method object was collected from?
1550- try :
1551- s = inspect .signature (runtime .__objclass__ )
1552- return s .replace (
1553- parameters = [
1554- inspect .Parameter ("self" , inspect .Parameter .POSITIONAL_OR_KEYWORD ),
1555- * s .parameters .values (),
1556- ]
1557- )
1558- except Exception :
1559- pass
1560+ if runtime_objclass is not None :
1561+ try :
1562+ s = inspect .signature (runtime_objclass )
1563+ return s .replace (
1564+ parameters = [
1565+ inspect .Parameter ("self" , inspect .Parameter .POSITIONAL_OR_KEYWORD ),
1566+ * s .parameters .values (),
1567+ ]
1568+ )
1569+ except Exception :
1570+ pass
15601571
15611572 try :
15621573 try :
0 commit comments