Skip to content
-
Subscribe to our newsletter & never miss our best posts. Subscribe Now!
PHDPedia PHDPedia PHDPedia
PHDPedia PHDPedia PHDPedia
  • Home
  • Sitemap
  • Home
  • Sitemap
Close

Search

  • https://www.facebook.com/
  • https://twitter.com/
  • https://t.me/
  • https://www.instagram.com/
  • https://youtube.com/
Subscribe
Data Science & Statistics for Researchers

PEP 849: More Expressive Type Expressions

By Lina Irawan
October 24, 2026 6 Min Read
Comments Off on PEP 849: More Expressive Type Expressions

The Python steering committee and the broader developer community are currently reviewing a significant evolution in the language’s type hinting system through PEP 849, a proposal that seeks to remove long-standing restrictions on the expressions used within type annotations. Authored by Imogen Hergeth and sponsored by Jelle Zijlstra, PEP 849 addresses a fundamental limitation in how the Python interpreter handles type metadata at runtime. While Python currently allows any valid expression to be used as an annotation, the practical utility of these annotations is often constrained by the interpreter’s standard evaluation rules. PEP 849 proposes a shift toward an Abstract Syntax Tree (AST) based format for annotations, which would allow developers to use complex logic, ternary operators, and even bitwise operators in ways that were previously impossible without losing runtime introspectability.

The Evolution of Python’s Annotation Landscape

Since the introduction of type hints in PEP 484, Python has struggled to balance the needs of static analysis with the realities of runtime execution. Initially, annotations were evaluated as standard Python expressions at the time of definition. This led to "forward reference" issues, where a class could not refer to itself in a type hint because the class object did not yet exist. To solve this, PEP 563 introduced "Postponed Evaluation of Annotations," which turned all annotations into strings. However, this created a new set of problems for runtime libraries like Pydantic and FastAPI, which needed to evaluate those strings back into actual objects—a process that is often fragile and context-dependent.

PEP 849 represents the next stage of this journey, following the groundwork laid by PEP 649 (Deferred Evaluation of Annotations Using Descriptors) and the introduction of the annotationlib module. The core issue PEP 849 identifies is that many intuitive type expressions are currently "swallowed" or misinterpreted by the Python interpreter. For example, in languages like TypeScript, a union of literal values is written as 1 | 2 | 3. In current Python, writing x: 1 | 2 | 3 results in the interpreter performing a bitwise OR operation, evaluating the entire expression to the integer 3 before any type checker or runtime library can see the individual components. By moving to an AST-based reporting format, PEP 849 ensures that the original structure of the expression is preserved and accessible.

Chronology of the Proposal

The development of PEP 849 has followed a rigorous path through the Python Discourse community and official standards track.

  • November 5, 2025: Imogen Hergeth introduced the initial concept in a Discourse thread titled "Simpler and more expressive type annotations." The discussion focused on the frustration of using Literal[1, 2, 3] when simpler syntax felt more "Pythonic."
  • September 2, 2026: The first formal draft of the PEP was published, detailing the technical requirements for changing how the __annotate__ function operates.
  • September 20, 2026: PEP 849 was officially created and assigned its number, targeting Python version 3.16.
  • September 22, 2026: A dedicated discussion thread was opened on the Python Discourse, where core developers began debating the performance trade-offs and the impact on the typing module’s API.

The proposal is currently in the "Draft" status, undergoing active revision as the community evaluates the reference implementation hosted in a CPython fork.

Technical Mechanics: The AST Format

At the heart of PEP 849 is the introduction of a new format for the __annotate__ method. Currently, when a class or function is defined, Python generates an annotate function that can return annotations in various formats, such as VALUE (the evaluated objects) or STRING (the literal text). PEP 849 adds Format.AST (assigned the value 5 in the annotationlib.Format enum).

When a runtime consumer calls MyClass.__annotate__(Format.AST), the function will no longer return a simple dictionary of evaluated values. Instead, it returns a dictionary of AnnotationAST objects. Each object contains two critical pieces of data:

  1. The AST Node: An ast.expr object representing the parsed structure of the annotation.
  2. The Namespace: A dictionary containing the local and global variables necessary to evaluate that AST in the correct context.

This dual-payload approach solves the "context loss" problem that plagued previous string-based solutions. Because the namespace is captured at the time of definition, the typing.get_type_annotations function—a new addition proposed by this PEP—can faithfully reconstruct the intended type objects even if they involve complex logic like ternary expressions (TypeA if Condition else TypeB) or comprehensions.

Performance Metrics and Impact Analysis

One of the most scrutinized aspects of any PEP is its impact on the Python interpreter’s performance. The authors of PEP 849 conducted extensive testing using a reference implementation to determine how these changes would affect different classes of users.

Import Time and Memory

For the vast majority of Python users—those who do not use type annotations or only use them for static analysis (linting)—the impact of PEP 849 is negligible. In fact, the reference implementation showed a moderate decrease in import times (a few percentage points) because the new annotate functions are more efficient at storing metadata than the current string-heavy or descriptor-heavy approaches. Memory footprint also saw a slight reduction of approximately 2-3% in annotated modules.

Runtime Evaluation

The primary performance cost is localized to users who actively evaluate type annotations at runtime, such as developers using dataclasses, Pydantic, or ORM frameworks like SQLAlchemy. The study found that in the "worst-case scenario"—where every annotation is requested in the VALUE format and all names are defined—the evaluation time could increase by up to sevenfold.

However, the authors argue that this is a "worthwhile trade-off." The current system already suffers from significant slowdowns when it encounters undefined names or requires FORWARDREF resolution. In those instances, the performance of the proposed AST format is comparable to the existing system. Furthermore, since type evaluation typically happens only once (e.g., when a class is first defined or a dataclass is initialized), the sevenfold increase in a millisecond-scale operation is unlikely to impact overall application performance for most web or data science workloads.

Ecosystem Reactions and Deprecations

The proposal has sparked a range of reactions from the Python ecosystem. Library maintainers who rely on runtime introspection have generally expressed support for the added expressiveness. The ability to use ternary operators in type hints, for example, would allow for more dynamic API definitions that currently require verbose overloads or complex TypeVar hacks.

A significant consequence of PEP 849 is the proposed deprecation of typing.get_type_hints. This function has been the standard way to retrieve annotations for years, but its internal logic is incompatible with the new AST-based resolution. The PEP suggests that users migrate to annotationlib.get_annotations or the newly proposed typing.get_type_annotations. While the authors admit this will cause friction, they argue that leaving get_type_hints as-is would lead to "silent failures" where new type syntax is incorrectly parsed by the old function, leading to subtle bugs in user code.

Broader Implications for Python’s Future

If adopted, PEP 849 would bring Python’s typing system closer to the flexibility found in TypeScript, which is often cited as the gold standard for developer experience in typed dynamic languages. By decoupling the syntax of an annotation from the semantics of the Python execution engine, the language allows the typing module to evolve independently of the core interpreter.

For instance, the proposed "Conditional Types" (discussed in the draft of PEP 827) would be trivial to implement under PEP 849. A developer could write:
def process(data: list[int] if SETTING_ENABLED else list[str]): ...
Under the current system, the interpreter would evaluate SETTING_ENABLED immediately and discard the "else" branch, making it invisible to any tool trying to understand the full scope of the function. Under PEP 849, the tool would receive the AST for the entire conditional expression, allowing it to provide smarter suggestions or stricter validation based on both possibilities.

Security and Implementation Status

From a security perspective, the PEP introduces no new vulnerabilities. The ability to execute code via annotations already exists in Python, and the AST format does not expose any information that isn’t already accessible through the inspect module or by reading the source code.

The reference implementation in the CPython fork serves as a proof of concept, demonstrating that the __annotate__ function can be modified to store binary AST data in string constants. This compact format ensures that the bytecode remains small while providing the necessary "hooks" for the typing module to perform its work. As Python 3.16 approaches its development cycle, the focus will shift to refining these helper functions and ensuring that the transition for library maintainers is as smooth as possible.

In summary, PEP 849 is a foundational proposal. It does not implement new types itself, but it builds the infrastructure necessary for the next decade of Python typing evolution. By allowing the language to "see" the structure of its own annotations without the interference of standard runtime evaluation, it opens the door for a more expressive, intuitive, and powerful type system.

Tags:

Data ScienceexpressionsexpressiveMachine LearningR ProgrammingStatisticstype
Author

Lina Irawan

Follow Me
Other Articles
Previous

Mastering Python Descriptors to Build Robust Controlled Attributes for Scalable Software Development

Next

Mastering the Art of Instructional Design A Comprehensive Guide to Effective Daily Lesson Planning within the Backward Design Framework

Recent Posts

The Shadow Reviewer: Unpacking the Impact of Destructive Peer Review in AcademiaThe Over-40 PhD’s Job Search Conundrum: Navigating Ageism and Perceived Overqualification in Today’s MarketParticipatory Qualitative Data Analysis with Queer Young People: Insights from the QueerPar ProjectAI Agent Coordination: Establishing Verifiable Rules and Safeguards for Delegated Tasks
The Shadow Reviewer: Unpacking the Impact of Destructive Peer Review in AcademiaThe Over-40 PhD’s Job Search Conundrum: Navigating Ageism and Perceived Overqualification in Today’s MarketParticipatory Qualitative Data Analysis with Queer Young People: Insights from the QueerPar ProjectAI Agent Coordination: Establishing Verifiable Rules and Safeguards for Delegated Tasks
  • The Shadow Reviewer: Unpacking the Impact of Destructive Peer Review in Academia
  • The Over-40 PhD’s Job Search Conundrum: Navigating Ageism and Perceived Overqualification in Today’s Market
  • Participatory Qualitative Data Analysis with Queer Young People: Insights from the QueerPar Project
  • AI Agent Coordination: Establishing Verifiable Rules and Safeguards for Delegated Tasks
  • 5 Free AI Coding Agents You Should Try in 2026

Archives

  • October 2026
  • September 2026
  • August 2026
  • July 2026
  • May 2026
  • April 2026

Categories

  • Academic Productivity & Tools
  • Academic Publishing & Open Access
  • Data Science & Statistics for Researchers
  • Funding, Grants & Fellowships
  • Higher Education News
  • Humanities & Social Sciences Research
  • Pedagogy & Teaching in Higher Ed
  • PhD Life & Mental Health
  • Post-PhD Careers & Alt-Ac
  • Research Methods & Methodology
  • Science Communication (SciComm)
  • Thesis & Academic Writing
Copyright 2026 — PHDPedia. All rights reserved. Blogsy WordPress Theme