Python's pre-declared constants are kinda weird
Python’s handling of built-in constants like `True`, `False`, `None`, `Ellipsis`, and `__debug__` exposes some surprising edge cases, such as conditional code being stripped at compile time or historical quirks like reassigning booleans in early versions. Commenters use these examples to probe broader design trade-offs in Python: its accumulated “baggage,” odd corners of the type and async systems, and notoriously messy packaging, versus its strengths as an accessible, batteries-included language with a powerful ecosystem for scripting, data work, and glue code. The exchange also contrasts Python with languages like PHP, JavaScript, Ruby, and Haskell, highlighting recurring tensions between theoretical language elegance, backward compatibility, and pragmatic usability at scale.
Special constants and conditional compilation
- Discussion centers on Python’s “pre-declared constants”:
True,False,None(keywords) vsEllipsis,NotImplemented,__debug__(identifiers with special treatment). __debug__is highlighted as especially odd:if __debug__:blocks are compiled out entirely underPYTHONOPTIMIZE/-O, making it a form of conditional compilation together withassert.- This is why assigning to
__debug__is forbidden: the compiler assumes it is constant when eliminating code. - Several commenters admit they’d never heard of
__debug__, or of its interaction withassert, and note the potential for real security bugs whenassertis (mis)used for critical checks. - Upcoming
TYPE_CHECKINGin 3.15 is mentioned as another pre-declared constant behaving likeEllipsis/NotImplemented.
Historical quirks of booleans and design “baggage”
- Early Python had no
True/False; users defined them as1/0. Python 2 allowed reassigning them; Python 3 turned them into keywords. boolis still a subclass ofint, which continues to surprise people and has caused bugs.- Broader point: retrofitting
bool/null into a language is hard; C and Python are cited as examples. - Some discuss broader language-design regrets: lack of built-in multidimensional arrays, bit arrays, and standardized small vector types.
Python vs other languages and evolution
- One camp argues Python is old, slow, brittle, with weak typing and chaotic packaging; they claim communities like PHP’s have evolved more aggressively and learned better lessons (e.g., enforced types, unified tooling).
- Others list substantial Python improvements: type hints, async/await, performance work, f-strings, pattern matching, dict merge operators, dataclasses, GIL removal work,
pathlib, etc. - A critical view holds that these features often copy ideas without key semantics (non-enforced types, non-exhaustive pattern matching, async “function coloring”), calling them “anti-features”.
- Comparisons with JavaScript, PHP, Ruby, Racket/Scheme/Haskell are frequent; opinions vary on which is “weirder,” more consistent, or more beginner-friendly.
Beginner-friendliness and usage niches
- Some say Python is too full of edge cases to be a good first language; others argue its REPL, batteries-included stdlib, readability, and Windows support make it an excellent teaching and “glue” language.
- Significant indentation, truthiness, and duck typing are called “weird” by some, “consistent and learnable” by others.
Ecosystem, packaging, and imports
- Many complaints about dependency management, virtualenvs, and fragmented tooling; uv is praised as a big improvement but not yet standard.
- Import semantics (
__name__ == "__main__", packages vs filesystem,__init__.py, relative imports) are seen as unintuitive by some, but defended as consistent with Python’s module model.