Python Enhancement Proposal 824 – None-coalescing operators
Python Enhancement Proposal 824 – None-coalescing operators represents a significant milestone in the evolution of the Python programming language, specifically targeting the reduction of boilerplate code associated with null-value handling. Authored by Marc Mueller and sponsored by Python’s creator and "Benevolent Dictator Emeritus" Guido van Rossum, the proposal aims to introduce two new operators—the None-coalescing operator (??) and the None-coalescing assignment operator (??=)—to the language’s core syntax. Currently in the draft stage and slated for potential inclusion in Python 3.16, this PEP seeks to formalize a feature that has been debated within the developer community for over a decade.
The fundamental objective of PEP 824 is to provide a concise, readable mechanism for handling None values, which are frequently used in Python to signify the absence of a value or a default state. While Python already possesses the or operator, which can be used for fallback values, it operates on the principle of "truthiness." This often leads to unintended consequences when valid values such as 0, empty strings "", or empty lists [] are treated as falsy and replaced by defaults. PEP 824 addresses this by focusing strictly on the identity of None, bringing Python in line with other modern languages like C#, JavaScript, and Swift.
Historical Context and the Legacy of PEP 505
The journey toward None-aware operators in Python began in earnest over ten years ago with the introduction of PEP 505. That proposal was significantly broader in scope, suggesting not only coalescing operators but also None-aware member access (?.) and indexing (?[]). While PEP 505 generated substantial interest, it was ultimately deferred due to concerns regarding "syntax soup"—the fear that adding too many symbolic operators would degrade Python’s signature readability.
PEP 824 represents a strategic pivot. By narrowing the focus to only the coalescing (??) and assignment (??=) operators, Mueller and van Rossum aim to provide the most high-impact features of the original proposal while minimizing the complexity of the changes. The None-aware access operators have been moved to a separate document, PEP 823, allowing the Python Steering Council to evaluate these features independently. This modular approach reflects a more cautious and iterative philosophy toward language design that has characterized Python’s development in the 2020s.
Technical Specifications of the New Operators
The core of the proposal lies in the mechanics of the ?? operator. When an expression a ?? b is evaluated, the interpreter first checks the value of a. If a is not None, that value is returned immediately, and b is never evaluated. If a is None, the interpreter evaluates b and returns the result. This "short-circuiting" behavior is critical for performance and for avoiding side effects that might occur if the right-hand expression were always executed.
The proposal includes a formal equivalent using the conditional expression syntax introduced in Python 2.5:
_t if ((_t := a) is not None) else b
The second operator, ??=, provides a shorthand for conditional assignment. It ensures that a variable is only assigned a new value if its current state is None. This is particularly useful for setting defaults at the beginning of a function or within a class constructor. The proposed logic for a ??= b is:
if a is None: a = b
From a technical standpoint, implementing these operators requires modifications to the Python Abstract Syntax Tree (AST) and the language grammar. A new Coalesce operator will be added to the boolop category within the AST, and the parser will be updated to recognize the ?? and ??= tokens. The precedence of the ?? operator is designed to be lower than or but higher than conditional expressions, ensuring that complex logical statements remain predictable for developers.
Comparative Analysis: Python in the Global Ecosystem
Python’s move toward None-coalescing operators is not an isolated event but rather a response to a broader trend in software engineering. As systems become more complex and data-driven, the explicit handling of "null" states has become a priority for language designers seeking to reduce "NullPointerExceptions" or their Python equivalent, the AttributeError on a NoneType object.
Several major languages have already successfully integrated these operators:
- JavaScript/ECMAScript: Introduced the
??operator in ES2020 to solve the exact problem Python currently faces—distinguishing betweennull/undefinedand falsy values like0or"". - C#: Has utilized
??since version 2.0 (2005) and??=since version 8.0 (2019), making it a cornerstone of the .NET ecosystem. - Swift and Kotlin: Both languages were built with "null safety" as a core tenet, using
??(Swift) and the "Elvis operator"?:(Kotlin) to manage optional types.
By adopting these operators, Python enhances its interoperability and lowers the barrier for developers moving between languages. It also provides a standard way to express a common pattern, reducing the "mental load" required to parse various idiosyncratic ways developers currently handle None checks.
Addressing the Verbosity of Current Python Patterns
One of the primary motivations cited in PEP 824 is the reduction of verbosity. Currently, a developer wishing to provide a default for a property must often repeat the variable name:
age = user.age if user.age is not None else "unknown"
This pattern is not only tedious to write but also prone to errors. If user.age is a function call with side effects, such as user.get_age_from_api(), the developer must remember to store the result in a temporary variable first to avoid calling the API twice. With PEP 824, this becomes:
age = user.age ?? "unknown"
Similarly, the proposal addresses a long-standing issue with mutable default arguments in functions. Because Python evaluates default arguments only once at the time of function definition, developers cannot use [] or as defaults directly. The standard workaround is to use None and assign the mutable object inside the function:
def add_user(users=None):
if users is None:
users = []
# ...
Under the new proposal, this is reduced to a single, clear line:
users ??= []
Community Reactions and Potential Objections
The introduction of new syntax into a mature language like Python is rarely without controversy. Discussion threads on the Python Discourse forum have highlighted several points of contention. Some purists argue that Python’s strength lies in its use of English-like keywords (such as and, or, and not) rather than symbolic operators. Suggestions were made to use a keyword like otherwise, but these were rejected by the authors as they lacked the industry-standard recognition of ??.
Another concern is the "proliferation of None." Critics argue that making it easier to work with None might encourage developers to use it as a "crutch" rather than designing better data structures or using early validation. However, the counter-argument, supported by the PEP’s authors, is that None is already ubiquitous in Python, and providing better tools to manage it is a pragmatic necessity rather than a stylistic choice.
The security implications of the proposal are considered negligible, as the operators do not introduce new execution paths that could be exploited. Instead, by making code more explicit and reducing the repetition of expressions, the operators may indirectly improve security by reducing the likelihood of logic errors.
Implementation Timeline and Future Impact
As of September 2026, PEP 824 remains in the "Draft" status, undergoing active revision based on feedback from the community and the Steering Council. A reference implementation has already been developed by the community, allowing developers to test the feature in a specialized branch of CPython. An online demo has also been launched to provide a sandbox environment for experimentation.
If accepted, the feature is expected to be a highlight of the Python 3.16 release. The impact on the ecosystem will likely be gradual but profound. Library maintainers will be able to clean up extensive "None-checking" boilerplate, leading to smaller, more maintainable codebases. For beginners, the operators will provide a clear distinction between logical "truth" and the existence of data, a common point of confusion in early programming education.
In conclusion, PEP 824 – None-coalescing operators represents a refined, focused effort to modernize Python’s syntax. By learning from the deferral of PEP 505 and observing the success of similar features in the wider programming world, Marc Mueller and Guido van Rossum have proposed a change that balances the desire for concise expression with the foundational principles of Pythonic readability. As the language approaches its fourth decade, such enhancements ensure that Python remains a competitive and efficient tool for developers across all domains of technology.