Skip to content

Commit 58d2b30

Browse files
authored
gh-102936: typing: document performance pitfalls of protocols decorated with @runtime_checkable (#102937)
1 parent 4695709 commit 58d2b30

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

Doc/library/typing.rst

+18-2
Original file line numberDiff line numberDiff line change
@@ -1584,16 +1584,32 @@ These are not used in annotations. They are building blocks for creating generic
15841584

15851585
assert isinstance(open('/some/file'), Closable)
15861586

1587+
@runtime_checkable
1588+
class Named(Protocol):
1589+
name: str
1590+
1591+
import threading
1592+
assert isinstance(threading.Thread(name='Bob'), Named)
1593+
15871594
.. note::
15881595

1589-
:func:`runtime_checkable` will check only the presence of the required
1590-
methods, not their type signatures. For example, :class:`ssl.SSLObject`
1596+
:func:`!runtime_checkable` will check only the presence of the required
1597+
methods or attributes, not their type signatures or types.
1598+
For example, :class:`ssl.SSLObject`
15911599
is a class, therefore it passes an :func:`issubclass`
15921600
check against :data:`Callable`. However, the
15931601
``ssl.SSLObject.__init__`` method exists only to raise a
15941602
:exc:`TypeError` with a more informative message, therefore making
15951603
it impossible to call (instantiate) :class:`ssl.SSLObject`.
15961604

1605+
.. note::
1606+
1607+
An :func:`isinstance` check against a runtime-checkable protocol can be
1608+
surprisingly slow compared to an ``isinstance()`` check against
1609+
a non-protocol class. Consider using alternative idioms such as
1610+
:func:`hasattr` calls for structural checks in performance-sensitive
1611+
code.
1612+
15971613
.. versionadded:: 3.8
15981614

15991615
Other special directives

0 commit comments

Comments
 (0)