Python’s Simplicity Is a Lie. Here’s the Ugly Truth About Its Constants

We fell in love with Python because it wasn’t PHP. In the 2010s, it felt like a breath of fresh air—clean syntax, readable code, no semicolons. We left Perl and PHP behind because they were chaotic, brittle, and dangerous to write at scale. But if you look closely at the very fabric of Python, you’ll realize the chaos never left. It just put on a nice sweater.

We fell in love with Python because it wasn’t PHP. A decade later, it’s just PHP with whitespace.

Consider the most basic elements of the language: the pre-declared constants. You use them every day. True. False. None. __debug__. You probably treat them as fixed, immutable primitives. They are supposed to be the bedrock of your logic. But they aren’t. They are a messy amalgamation of lexical tokens, hardwired values, and compile-time conditionals. They are active language machinery disguised as simple values.

Take __debug__. This isn’t just a boolean that evaluates to True. If you run Python with PYTHONOPTIMIZE=1, any block of code guarded with if __debug__: is entirely omitted from the bytecode. The compiler literally deletes it. This isn’t a constant; it’s a compiler directive masquerading as a variable. It is one of the only examples of real “conditional compilation” in Python, and it’s hidden right in plain sight.

You think True is a fact. In Python, it’s a suggestion that the compiler occasionally agrees with.

Or look at ... (Ellipsis). It behaves like True and None, but it’s actually a lexical token that resolves to a hardwired value during parsing. The language tries to present a uniform, simple front, but underneath the hood, it’s a patchwork of pragmatic decisions. They fixed the ability to assign to True and False in Python 3, but the scars of bad design are baked into the interpreter.

This is the dark side of the “batteries included” philosophy. When a language tries to be everything to everyone, it inevitably accumulates cruft. The loose typing, the potluck standard library, the package manager drama—it all adds up. As one developer perfectly put it: Python now feels like a weird PHP itself that is slow, brittle, and dangerous to write code at scale in.

A language that tries to be everything to everyone eventually becomes a museum of compromises.

If you’re writing Python today, you need to understand these quirks. Not because it’s a fun trivia fact, but because relying on these “constants” for optimization or logic will introduce subtle, impossible-to-debug bugs into your code. Python’s pre-declared constants aren’t simple. They are a warning sign. The simplicity we loved is gone, replaced by an interpreter full of hidden complexity. We didn’t escape the chaos of the 2000s. We just repackaged it.

FAQ

Q: Why does it matter if True or __debug__ is a lexical token instead of a simple constant?

A: Because it breaks the mental model of the language. If a constant can alter bytecode (like __debug__ does under optimization), it's no longer a passive value—it's a compiler directive. Relying on it without knowing how the interpreter handles it leads to subtle, hard-to-trace bugs in production.

Q: Isn't this just a necessary evil of language evolution?

A: No, it's a symptom of pragmatic, short-term decision-making overriding clean design. Other languages handle constants and compiler directives explicitly. Python hides them in plain sight, creating a leaky abstraction that confuses developers who expect uniform behavior.

Q: Is Python actually becoming as bad as PHP or Perl?

A: While 'bad' is subjective, the comparison is accurate in terms of internal consistency. Python has accumulated decades of cruft, a chaotic standard library, and packaging woes. It traded the syntax chaos of Perl for the internal architectural chaos of PHP.

📎 Source: View Source