Skip to content

Commit 14e06c2

Browse files
authored
stubtest: be safer with inspect.signature (#10884)
1 parent 6fd2dc2 commit 14e06c2

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

mypy/stubtest.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -653,23 +653,16 @@ def verify_funcitem(
653653
yield Error(object_path, "is not present at runtime", stub, runtime)
654654
return
655655

656-
if (
657-
not isinstance(runtime, (types.FunctionType, types.BuiltinFunctionType))
658-
and not isinstance(runtime, (types.MethodType, types.BuiltinMethodType))
659-
and not inspect.ismethoddescriptor(runtime)
660-
):
656+
if not is_probably_a_function(runtime):
661657
yield Error(object_path, "is not a function", stub, runtime)
662658
if not callable(runtime):
663659
return
664660

665661
for message in _verify_static_class_methods(stub, runtime, object_path):
666662
yield Error(object_path, "is inconsistent, " + message, stub, runtime)
667663

668-
try:
669-
signature = inspect.signature(runtime)
670-
except (ValueError, RuntimeError):
671-
# inspect.signature throws sometimes
672-
# catch RuntimeError because of https://bugs.python.org/issue39504
664+
signature = safe_inspect_signature(runtime)
665+
if not signature:
673666
return
674667

675668
stub_sig = Signature.from_funcitem(stub)
@@ -737,21 +730,16 @@ def verify_overloadedfuncdef(
737730
# We get here in cases of overloads from property.setter
738731
return
739732

740-
if (
741-
not isinstance(runtime, (types.FunctionType, types.BuiltinFunctionType))
742-
and not isinstance(runtime, (types.MethodType, types.BuiltinMethodType))
743-
and not inspect.ismethoddescriptor(runtime)
744-
):
733+
if not is_probably_a_function(runtime):
745734
yield Error(object_path, "is not a function", stub, runtime)
746735
if not callable(runtime):
747736
return
748737

749738
for message in _verify_static_class_methods(stub, runtime, object_path):
750739
yield Error(object_path, "is inconsistent, " + message, stub, runtime)
751740

752-
try:
753-
signature = inspect.signature(runtime)
754-
except ValueError:
741+
signature = safe_inspect_signature(runtime)
742+
if not signature:
755743
return
756744

757745
stub_sig = Signature.from_overloadedfuncdef(stub)
@@ -888,6 +876,24 @@ def is_dunder(name: str, exclude_special: bool = False) -> bool:
888876
return name.startswith("__") and name.endswith("__")
889877

890878

879+
def is_probably_a_function(runtime: Any) -> bool:
880+
return (
881+
isinstance(runtime, (types.FunctionType, types.BuiltinFunctionType))
882+
or isinstance(runtime, (types.MethodType, types.BuiltinMethodType))
883+
or (inspect.ismethoddescriptor(runtime) and callable(runtime))
884+
)
885+
886+
887+
def safe_inspect_signature(runtime: Any) -> Optional[inspect.Signature]:
888+
try:
889+
return inspect.signature(runtime)
890+
except (ValueError, RuntimeError, TypeError):
891+
# inspect.signature throws sometimes
892+
# catch RuntimeError because of https://bugs.python.org/issue39504
893+
# catch TypeError because of https://github.com/python/typeshed/pull/5762
894+
return None
895+
896+
891897
def is_subtype_helper(left: mypy.types.Type, right: mypy.types.Type) -> bool:
892898
"""Checks whether ``left`` is a subtype of ``right``."""
893899
left = mypy.types.get_proper_type(left)
@@ -930,8 +936,8 @@ def anytype() -> mypy.types.AnyType:
930936
type_info = builtins.names["function"].node
931937
assert isinstance(type_info, nodes.TypeInfo)
932938
fallback = mypy.types.Instance(type_info, [anytype()])
933-
try:
934-
signature = inspect.signature(runtime)
939+
signature = safe_inspect_signature(runtime)
940+
if signature:
935941
arg_types = []
936942
arg_kinds = []
937943
arg_names = []
@@ -953,7 +959,7 @@ def anytype() -> mypy.types.AnyType:
953959
arg_kinds.append(nodes.ARG_STAR2)
954960
else:
955961
raise AssertionError
956-
except ValueError:
962+
else:
957963
arg_types = [anytype(), anytype()]
958964
arg_kinds = [nodes.ARG_STAR, nodes.ARG_STAR2]
959965
arg_names = [None, None]

0 commit comments

Comments
 (0)