TYPE_CHECKING a built-in constantThis PEP proposes adding a new built-in variable,TYPE_CHECKING, toimprove the experience of writing Python code with type annotations. It isevaluated asTrue when the code is being analyzed by a static type checker,and asFalse during normal runtime execution. Unliketyping.TYPE_CHECKING, which this variable replaces, it does not requirean import statement.
Type annotations were defined for Python byPEP 484, and have enjoyedwidespread adoption. A challenge with fully-annotated code is that manymore imports are required in order to bring the relevant name into scope,potentially causing import cycles without careful design. This has beenrecognized byPEP 563 and laterPEP 649, which introduce two differentmechanisms for deferred evaluation of type annotations. As PEP 563 notes,“type hints are … not computationally free”. Thetyping.TYPE_CHECKINGconstant was thusintroduced, initially to aid in breaking cyclic imports.
In situations where startup time is critical, such as command-line interfaces,applications, or core libraries, programmers may place all import statementsnot required for runtime execution within a ‘TYPE_CHECKING block’, or evendefer certain imports to within functions. Thetyping module itself thoughcan take as much as 10ms to import, longer than Python takes to initialize.The time taken to import thetyping module clearly cannot be ignored.
To avoid importingTYPE_CHECKING fromtyping, developers currentlydefine a module-level variable such asTYPE_CHECKING=False or use codelikeifFalse: #TYPE_CHECKING. Providing a standard method will allowmany tools to implement the same behavior consistently. It will also allowthird-party tools in the ecosystem to standardize on a single behaviorwith guaranteed semantics, as for example some static type checkers currentlydo not permit local constants, only recognizingtyping.TYPE_CHECKING.
TYPE_CHECKING is a built-in constant and its value isFalse.UnlikeTrue,False,None, and__debug__,TYPE_CHECKING isnot a real constant; assigning to it will not raise aSyntaxError.
Static type checkers must treatTYPE_CHECKING asTrue, similar totyping.TYPE_CHECKING.
If this PEP is accepted, the newTYPE_CHECKING constant will bethe preferred approach and importingtyping.TYPE_CHECKING will bedeprecated.To minimize the runtime impact of typing, this deprecation will generateDeprecationWarning no sooner than Python 3.13’s end of life, scheduledfor October 2029.
Instead, type checkers may warn about such deprecated usage when the targetversion of the checked program is signalled to be Python 3.14 or newer.
SinceTYPE_CHECKING doesn’t prohibit assignment, existing code usingTYPE_CHECKING will continue to work.
# This code will continue to workTYPE_CHECKING=FalsefromtypingimportTYPE_CHECKING
User can remove the assignment toTYPE_CHECKING after they stop usingPython 3.13 or older versions.
ifTYPE_CHECKING: for skipping type-checking code at runtime.fromtypingimportTYPE_CHECKING to support Python versions before3.14.TYPE_CHECKING=False orifFalse: #TYPE_CHECKINGwill continue to work, but are not recommended.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 enoughto justify the complexity.
importtypingFuture optimizations may eliminate the need to avoid importing thetypingmodule for startup time.
Even with such optimizations, there will still be use cases where minimizingimports is beneficial, such as running Python on embedded systems orin browsers.
Therefore, defining a constant for skipping type-checking-only code outsidethetyping module remains valuable.
This document is placed in the public domain or under theCC0-1.0-Universal license, whichever is more permissive.
Source:https://github.com/python/peps/blob/main/peps/pep-0781.rst
Last modified:2025-05-06 20:54:28 GMT