Skip to content
Tech News
← Back to articles

Python's pre-declared constants are kinda weird

read original more articles
Why This Matters

This article highlights the peculiar behaviors of Python's pre-declared constants, which are fundamental to the language's design but behave inconsistently. Understanding these quirks is important for developers to write correct and efficient code, especially when dealing with language internals or debugging. Recognizing these differences can also influence how new features or language updates are approached in the future.

Key Takeaways

python's pre-declared constants are kinda weird 2026-08-01

python has 6 pre-declared "constants": True , False , None , __debug__ , Ellipsis (or equivalently ... ), and NotImplemented . but they all behave slightly differently, for some reason.

True , False , and None

True , False , and None are keywords. they aren't identifiers, they're just straight up their own lexical tokens. which is really weird; nothing else is like this in python. usually stuff is resolved during regular name resolution, not in the lexer itself.

an interesting side effect of this is that expressions like x.True raise a SyntaxError . i'm curious as to what the rationale was for this decision (if there was one).

there's some more interesting stuff with these constants, but i'll get to it later, since it ties in with the other constants.

__debug__

__debug__ is a boolean constant: it's normally True , but when running with -O , it's False . the idea is similar to how assert is disabled in non-debug builds: you can wrap code in if __debug__ if the check would be too expensive in an "optimized" build, or something.

__debug__ is really interesting though, because although it's a normal identifier (unlike True , False , and None ), it's the only identifier in the language which can't be assigned to:

>>> __debug__ = 67 File " ", line 1 SyntaxError: cannot assign to __debug__

... continue reading