diff --git a/stdlib/@tests/test_cases/builtins/check_isinstance.py b/stdlib/@tests/test_cases/builtins/check_isinstance.py new file mode 100644 index 000000000000..67def3187d89 --- /dev/null +++ b/stdlib/@tests/test_cases/builtins/check_isinstance.py @@ -0,0 +1,9 @@ +from typing import Any, cast +from typing_extensions import TypeIs, assert_type + +o = cast(Any, "") +assert_type(isinstance(o, int), TypeIs[int]) +assert_type(isinstance(o, object), TypeIs[object]) +assert_type(isinstance(o, str), TypeIs[str]) +assert_type(isinstance(o, (bytes, memoryview)), TypeIs[bytes | memoryview[int]]) +assert_type(isinstance(o, (set, type[dict])), TypeIs[set[Any] | type[dict[Any, Any]]]) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 9c8394ced492..2db9868662d1 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1882,7 +1882,27 @@ def iter(object: Callable[[], _T], sentinel: object, /) -> Iterator[_T]: ... _ClassInfo: TypeAlias = type | types.UnionType | tuple[_ClassInfo, ...] +@overload +def isinstance(obj: object, class_or_tuple: type[_T] | tuple[type[_T]], /) -> TypeIs[_T]: ... +@overload +def isinstance(obj: object, class_or_tuple: tuple[type[_T], type[_T1]], /) -> TypeIs[_T | _T1]: ... +@overload +def isinstance(obj: object, class_or_tuple: tuple[type[_T], type[_T1], type[_T2]], /) -> TypeIs[_T | _T1 | _T2]: ... +@overload +def isinstance( + obj: object, class_or_tuple: tuple[type[_T], type[_T1], type[_T2], type[_T3]], / +) -> TypeIs[_T | _T1 | _T2 | _T3]: ... +@overload +def isinstance( + obj: object, class_or_tuple: tuple[type[_T], type[_T1], type[_T2], type[_T3], type[_T4]], / +) -> TypeIs[_T | _T1 | _T2 | _T3 | _T4]: ... +@overload +def isinstance( + obj: object, class_or_tuple: tuple[type[_T], type[_T1], type[_T2], type[_T3], type[_T4], type[_T5]], / +) -> TypeIs[_T | _T1 | _T2 | _T3 | _T4 | _T5]: ... +@overload def isinstance(obj: object, class_or_tuple: _ClassInfo, /) -> bool: ... + def issubclass(cls: type, class_or_tuple: _ClassInfo, /) -> bool: ... def len(obj: Sized, /) -> int: ...