# Draft PEP: More Expressive Type Expressions

**URL:** <https://discuss.python.org/t/draft-pep-more-expressive-type-expressions/108856>\
**Category:** Typing\
**Created:** [September 2, 2026, 7:58am UTC](https://discuss.python.org/t/draft-pep-more-expressive-type-expressions/108856 "2026-09-02T07:58:34Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![DavidCEllis](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/davidcellis/32/9789_2.png) [@DavidCEllis](https://discuss.python.org/u/DavidCEllis)\
**Post date:** [September 2, 2026, 9:48am UTC](https://discuss.python.org/t/draft-pep-more-expressive-type-expressions/108856/3 "2026-09-02T09:48:13Z")

</div>

> [@ImogenBits](#):
>
> [As was recently mentioned](https://discuss.python.org/t/idea-simpler-and-more-expressive-type-annotations/104730/82), associating a unique namespace to every annotation rather than returning a single namespace from the annotate function makes merging annotations from different modules more straightforward.

I think you misunderstood me slightly here, I didn’t mean a _unique_ namespace per annotation. Just a reference to the appropriate context for the annotation function the annotation originated from. This ‘context’ object itself would need to have references to all of the relevant namespaces (globals, locals etc) in order to be able to evaluate forward references correctly.

Essentially having an format that’s something more like this:

```python
def __annotate__ (format, /):
    match format:
        case Format.DEFERRED:
            context = _capture_annotation_context()
            annotations = {
                "a": DeferredAnnotation(<data object>, context),
                "b": DeferredAnnotation(<data object>, context),
            }
            return annotations
        ...

```

* * *

This is roughly what [reannotate](https://github.com/DavidCEllis/Reannotate) tries to do on current Python except it is limited in that it can only currently retrieve annotations that `Format.STRING` would support. So `error_level: 1 | 2 | 3` is still `DeferredAnnotation('3')`.

```python
from annotationlib import Format
from reannotate import get_deferred_annotations

class Example:
    a: list[undefined]
    b: int

annos = get_deferred_annotations(Example)

# Annotations from the same CPython generated __annotate__ share context
assert annos['a'].evaluation_context is annos['b'].evaluation_context

print("Annotation:", annos['a'])
print("Internal Object:", annos['a']._obj)
print("Context Object:", annos['a'].evaluation_context)

print("As ForwardRef:", annos['a'].evaluate(format=Format.FORWARDREF))

# Now we define 'undefined' and the annotation will evaluate, the same as `ForwardRef`.
undefined = str

print("As VALUE:", annos['a'].evaluate())

```

```python
Annotation: DeferredAnnotation('list[undefined]')
Internal Object: Subscript(value=Name(id='list', ctx=Load()), slice=Name(id='undefined', ctx=Load()), ctx=Load())
Context Object: <reannotate.EvaluationContext object at 0x1056a87c0>
As ForwardRef: list[ForwardRef('undefined', is_class=True, owner=<class ' __main__.Example'>)]
As VALUE: list[str]

```

Working like this would also make it possible to essentially backport the _format_ to current Python as is, and then improve the correctness of the string support when the underlying generated ` __annotate__ ` functions are supported.

* * *

> [@ImogenBits](#):
>
> I then also measured the total execution time of the annotate functions in these modules. These are my relative results for each of the best variants:
> 
> | | Current | AST | Strings |
> | --- | --- | --- | --- |
> | Memory | 100% | 99.4% | 99.2% |
> | Time | 1x | 7x | 24x |

Out of curiosity, what’s the memory usage/performance like if you do both? If the ` __annotate__ ` functions look more like.

```python
def __annotate__ (format, /):
    match format:
        case Format.VALUE | Format.VALUE_WITH_FAKE_GLOBALS:
            return {
                "a": int,
                "b": some_module.MyClass,
            }
        case Format.AST/DEFERRED:
            return { ... }
        case _:
            raise NotImplementedError(format)

```

---

_[View the full topic](https://discuss.python.org/t/draft-pep-more-expressive-type-expressions/108856)._
