-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
PEP 781: Make TYPE_CHECKING a built-in constant
#4318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
4fd34d2
PEP 781: Adding __type_checking__ constant
methane f94601c
Apply suggestions from code review
methane a173c94
apply suggestions
methane 1651246
update based on latest template
methane a942926
update based on the feedback from the discussion
methane 0598730
Apply suggestions from code review
methane aa9dcfe
Apply suggestions from code review
methane 179c1b6
Apply suggestions from code review
methane ddc3075
fix an incorrect role
AA-Turner e915074
The pep role doesn't support suppressed cross-references
AA-Turner 0cb92cb
Add TYPE_CHECKING, not __type_checking__.
methane f043cd6
Apply suggestions from code review
methane 5fb51f2
Wrap to 80 columns
AA-Turner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| PEP: 781 | ||
| Title: Make ``TYPE_CHECKING`` a built-in constant | ||
| Author: Inada Naoki <songofacandy@gmail.com> | ||
| Discussions-To: https://discuss.python.org/t/85728 | ||
| Status: Draft | ||
| Type: Standards Track | ||
| Topic: Typing | ||
| Created: 24-Mar-2025 | ||
| Python-Version: 3.14 | ||
| Post-History: `11-Jan-2025 <https://discuss.python.org/t/76766>`__, | ||
| `24-Mar-2025 <https://discuss.python.org/t/85728>`__, | ||
|
|
||
|
|
||
| Abstract | ||
| ======== | ||
|
|
||
| This PEP proposes adding a new built-in variable, :data:`!TYPE_CHECKING`, to | ||
| improve the experience of writing Python code with type annotations. It is | ||
| evaluated as ``True`` when the code is being analyzed by a static type checker, | ||
| and as ``False`` during normal runtime execution. Unlike | ||
| :data:`typing.TYPE_CHECKING`, which this variable replaces, it does not require | ||
| an import statement. | ||
|
|
||
|
|
||
| Motivation | ||
| ========== | ||
|
|
||
| Type annotations were defined for Python by :pep:`484`, and have enjoyed | ||
| widespread adoption. A challenge with fully-annotated code is that many | ||
| more imports are required in order to bring the relevant name into scope, | ||
| potentially causing import cycles without careful design. This has been | ||
| recognized by :pep:`563` and later :pep:`649`, which introduce two different | ||
| mechanisms for deferred evaluation of type annotations. As PEP 563 notes, | ||
| "type hints are ... not computationally free". The :data:`typing.TYPE_CHECKING` | ||
| constant was thus introduced__, initially to aid in breaking cyclic imports. | ||
|
|
||
| __ https://github.com/python/typing/issues/230 | ||
|
|
||
| In situations where startup time is critical, such as command-line interfaces, | ||
| applications, or core libraries, programmers may place all import statements | ||
| not required for runtime execution within a 'TYPE_CHECKING block', or even | ||
| defer certain imports to within functions. The ``typing`` module itself though | ||
| can take as much as 10ms to import, longer than Python takes to initialize. | ||
| The time taken to import the ``typing`` module clearly cannot be ignored. | ||
|
|
||
| To avoid importing ``TYPE_CHECKING`` from ``typing``, developers currently | ||
| define a module-level variable such as ``TYPE_CHECKING = False`` or use code | ||
| like ``if False: # TYPE_CHECKING``. Providing a standard method will allow | ||
| many tools to implement the same behavior consistently. It will also allow | ||
| third-party tools in the ecosystem to standardize on a single behavior | ||
| with guaranteed semantics, as for example some static type checkers currently | ||
| do not permit local constants, only recognizing ``typing.TYPE_CHECKING``. | ||
|
|
||
|
|
||
| Specification | ||
| ============= | ||
|
|
||
| ``TYPE_CHECKING`` is a built-in constant and its value is ``False``. | ||
| Unlike ``True``, ``False``, ``None``, and ``__debug__``, ``TYPE_CHECKING`` is | ||
| not a real constant; assigning to it will not raise a ``SyntaxError``. | ||
|
|
||
| Static type checkers must treat ``TYPE_CHECKING`` as ``True``, similar to | ||
| :data:`typing.TYPE_CHECKING`. | ||
|
|
||
| If this PEP is accepted, the new ``TYPE_CHECKING`` constant will be | ||
| the preferred approach, instead of the existing ``typing.TYPE_CHECKING``. | ||
| However, ``typing.TYPE_CHECKING`` will not be deprecated in the foreseeable | ||
| future. | ||
|
|
||
|
|
||
| Backwards Compatibility | ||
| ======================= | ||
|
|
||
| Since ``TYPE_CHECKING`` doesn't prohibit assignment, existing code using | ||
| ``TYPE_CHECKING`` will continue to work. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # This code will continue to work | ||
| TYPE_CHECKING = False | ||
| from typing import TYPE_CHECKING | ||
|
|
||
|
|
||
| User can remove the assignment to ``TYPE_CHECKING`` after they stop using | ||
| Python 3.13 or older versions. | ||
|
|
||
|
|
||
| How to Teach This | ||
| ================= | ||
|
|
||
| * Use ``if TYPE_CHECKING:`` for skipping type-checking code at runtime. | ||
| * Use ``from typing import TYPE_CHECKING`` to support Python versions before | ||
| 3.14. | ||
| * Workarounds like ``TYPE_CHECKING = False`` or ``if False: # TYPE_CHECKING`` | ||
| will continue to work, but are not recommended. | ||
|
|
||
|
|
||
| Reference Implementation | ||
| ======================== | ||
|
|
||
| * `python/cpython#131793 <https://github.com/python/cpython/pull/131793>`__ | ||
|
|
||
|
|
||
| Rejected Ideas | ||
| ============== | ||
|
|
||
| Eliminate type-checking-only code | ||
| --------------------------------- | ||
|
|
||
| It is considered to add real constant named ``__type_checking__`` | ||
| to eliminate type-checking-only code at compile time. | ||
|
|
||
| However, adding real constant to language increase complexity of the language. | ||
| Benefit from eliminating type-checking-only code is estimated to be not enough | ||
| to justify the complexity. | ||
|
|
||
|
|
||
| Copyright | ||
| ========= | ||
|
|
||
| This document is placed in the public domain or under the | ||
| CC0-1.0-Universal license, whichever is more permissive. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.