diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 3125ae97808a..bfff81e26760 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1658,6 +1658,20 @@ Introspection helpers .. versionadded:: 3.8 +.. function:: is_typeddict(tp) + + Check if an annotation is a TypedDict class. + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + + .. versionadded:: 3.10 + .. class:: ForwardRef A class used for internal typing representation of string forward references. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 05140fc61b9b..42aa430c5e10 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -16,6 +16,7 @@ from typing import cast, runtime_checkable from typing import get_type_hints from typing import get_origin, get_args +from typing import is_typeddict from typing import no_type_check, no_type_check_decorator from typing import Type from typing import NewType @@ -3900,6 +3901,12 @@ class Cat(Animal): 'voice': str, } + def test_is_typeddict(self): + assert is_typeddict(Point2D) is True + assert is_typeddict(Union[str, int]) is False + # classes, not instances + assert is_typeddict(Point2D()) is False + class IOTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 2aedbeb852a7..8c61bd8e084a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -103,6 +103,7 @@ 'get_args', 'get_origin', 'get_type_hints', + 'is_typeddict', 'NewType', 'no_type_check', 'no_type_check_decorator', @@ -1479,6 +1480,20 @@ def get_args(tp): return () +def is_typeddict(tp): + """Check if an annotation is a TypedDict class + + For example:: + class Film(TypedDict): + title: str + year: int + + is_typeddict(Film) # => True + is_typeddict(Union[list, str]) # => False + """ + return isinstance(tp, _TypedDictMeta) + + def no_type_check(arg): """Decorator to indicate that annotations are not type hints. diff --git a/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst b/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst new file mode 100644 index 000000000000..fbbc6724ba51 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-15-07-55-35.bpo-41792.qMpSlU.rst @@ -0,0 +1,6 @@ +Add is_typeddict function to typing.py to check if a type is a TypedDict +class + +Previously there was no way to check that without using private API. See the +`relevant issue in python/typing +`