Skip to content

Commit ecf8555

Browse files
committed
handle when __objclass__ is object
1 parent bfab0f8 commit ecf8555

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

mypy/stubtest.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)