From 5aacaa4abf61eb09fa9f24669dff5b4f90aa426a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 07:03:08 -0700 Subject: [PATCH 1/2] gh-149574: Document that is_typeddict, is_protocol, is_dataclass, isclass return False for generic aliases --- Doc/library/dataclasses.rst | 3 ++- Doc/library/inspect.rst | 3 +++ Doc/library/stdtypes.rst | 3 ++- Doc/library/typing.rst | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 0bce3e5b762b8b..15a1fce4958fe2 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -498,7 +498,8 @@ Module contents .. function:: is_dataclass(obj) Return ``True`` if its parameter is a dataclass (including subclasses of a - dataclass) or an instance of one, otherwise return ``False``. + dataclass, but not including :ref:`generic specializations `) + or an instance of one, otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for ``not diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 8713765b8aebfb..80ef9472aa06ac 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -416,6 +416,9 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Return ``True`` if the object is a class, whether built-in or created in Python code. + This function returns ``False`` for :ref:`generic specializations ` of classes, + such as ``list[int]``. + .. function:: ismethod(object) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 3d943566be34ff..e3bd1a46891adc 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5858,7 +5858,8 @@ type and the :class:`bytes` data type: ``GenericAlias`` objects are instances of the class :class:`types.GenericAlias`, which can also be used to create ``GenericAlias`` -objects directly. +objects directly. Specializations of user-defined :ref:`generic classes ` +may not be instances of :class:`types.GenericAlias`, but they provide similar functionality. .. describe:: T[X, Y, ...] diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index dca51b8014da5a..ec9a928ca837d0 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3642,6 +3642,15 @@ Introspection helpers is_protocol(P) # => True is_protocol(int) # => False + This function only returns true for ``Protocol`` classes, not for + :ref:`generic specializations ` of them:: + + class GenericP[T](Protocol): + def a(self) -> T: ... + b: int + + assert not is_protocol(GenericP[int]) + .. versionadded:: 3.13 .. function:: is_typeddict(tp) @@ -3663,6 +3672,15 @@ Introspection helpers # not a typed dict itself assert not is_typeddict(TypedDict) + This function only returns true for ``TypedDict`` classes, not for + :ref:`generic specializations ` of them:: + + class GenericFilm[T](TypedDict): + title: str + year: T + + assert not is_typeddict(GenericFilm[int]) + .. versionadded:: 3.10 .. class:: ForwardRef From 0ab60004f700191fdd5b1f79541db3c3e5fdcfa0 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 07:31:54 -0700 Subject: [PATCH 2/2] revise --- Doc/library/dataclasses.rst | 2 +- Doc/library/inspect.rst | 2 +- Doc/library/typing.rst | 16 +++++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 15a1fce4958fe2..a09c28ad979158 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -498,7 +498,7 @@ Module contents .. function:: is_dataclass(obj) Return ``True`` if its parameter is a dataclass (including subclasses of a - dataclass, but not including :ref:`generic specializations `) + dataclass, but not including :ref:`generic aliases `) or an instance of one, otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 80ef9472aa06ac..48ae9147587c64 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -416,7 +416,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Return ``True`` if the object is a class, whether built-in or created in Python code. - This function returns ``False`` for :ref:`generic specializations ` of classes, + This function returns ``False`` for :ref:`generic aliases ` of classes, such as ``list[int]``. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index ec9a928ca837d0..71b395c80166cc 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3633,17 +3633,21 @@ Introspection helpers Determine if a type is a :class:`Protocol`. - For example:: + For example: + + .. testcode:: class P(Protocol): def a(self) -> str: ... b: int - is_protocol(P) # => True - is_protocol(int) # => False + assert is_protocol(P) + assert not is_protocol(int) This function only returns true for ``Protocol`` classes, not for - :ref:`generic specializations ` of them:: + :ref:`generic aliases ` of them: + + .. testcode:: class GenericP[T](Protocol): def a(self) -> T: ... @@ -3673,7 +3677,9 @@ Introspection helpers assert not is_typeddict(TypedDict) This function only returns true for ``TypedDict`` classes, not for - :ref:`generic specializations ` of them:: + :ref:`generic aliases ` of them: + + .. testcode:: class GenericFilm[T](TypedDict): title: str