@@ -16,9 +16,15 @@ Post-History: `05-Nov-2025 <https://discuss.python.org/t/idea-simpler-and-more-e
1616Abstract
1717********
1818
19- Currently, only a small subset of Python expressions can be used in type
20- annotations, which greatly limits the expressiveness of the Python type system
21- and its ease of use. This PEP proposes to expand annotate functions such that
19+ Currently, the Python interpreter allows any expression to be used as an
20+ annotation. But their most popular usage, type anntotations, are restricted to
21+ only a small subset of possible expressions. This is because type annotations
22+ need to be introspectable at runtime and many valid expressions produce
23+ values where that is not possible. This greatly limits which expressions can
24+ be assigned a meaning within the typing spec and limits the expressiveness and
25+ ease of use of type annotations.
26+
27+ This PEP proposes to expand annotate functions such that
2228any Python expression can be used in type annotations. It does this by creating
2329a new annotation format which instructs annotate functions to return the
2430annotation's AST and namespaces. Runtime consumers of type annotations can then
@@ -56,9 +62,9 @@ as ``Literal[1, 2, 3]``. Many users intuitively want to instead spell this as
5662them, which also is what other languages such as TypeScript use. This is
5763currently not possible in Python because the expression ``1 | 2 | 3 `` evaluates
5864simply to ``3 `` because ``| `` is interpreted as the binary-or operation rather than
59- the union of types. Further, constant folding completely eliminates this
65+ the union of types. Further, constant folding eliminates this
6066expression from appearing anywhere in the generated bytecode, and it thus is
61- completely impossible to retrieve the actual type annotation at runtime.
67+ impossible to retrieve the actual type annotation at runtime.
6268
6369The above example only prevents us from using slightly shorter spelling for
6470already existing types. There also are many type annotations that either
@@ -192,7 +198,7 @@ Performance Impact
192198==================
193199
194200While every new feature has to be weighed against its impact on performance and
195- complexity, typing related features deserve additional scrutiy because type
201+ complexity, typing related features deserve additional scrutiny because type
196202annotations are an entirely optional part of the Python language. We thus need
197203to consider three separate groups of users and its impact on them: users who
198204do not use type annotations at all , users who annotate their code for type
@@ -210,7 +216,19 @@ Using our reference implementation, we have found no significant difference in
210216import times of modules that do not use type annotations. For modules that do
211217use annotations, import was moderately faster and the memory footprint slightly
212218smaller using the proposed annotate functions, both by a few percent. But
213- unfortunately, evaluation time increases by a lot, about seven times as long .
219+ unfortunately, evaluation time can increase significantly. In the worst case,
220+ when annotations are requested in the value format and every used named is
221+ defined, the increase is about sevenfold. However, when some names are not
222+ defined and the string or forwardref formats have to be used the current
223+ approach also is significantly slower and results in comparable times to the
224+ proposed annotate functions.
225+
226+ A common situation where type annotations are evaluated is when tools like
227+ :py:mod:`dataclasses` or similar ORM packages analyze class or function
228+ definitions to synthesize additional behaviour. For these tools, the time to
229+ e.g. create a dataclass will be impacted by this proposal. But as mentioned
230+ above, there already are many situations where inspecting annotations takes
231+ a similar amount of time.
214232
215233In total, since the negative performance impacts only affect the smallest group
216234of users, who also benefit from the newly possible type annotations, we consider
@@ -230,22 +248,21 @@ example in ``cast(<some complex expression>, value)``. Since the interpreter
230248cannot differentiate these cases from other function calls, it is impossible
231249for it to infer that it should use a mechanism like we suggest.
232250
233- We think that directly supporting these use cases is not needed. This would
234- require new syntax, which we do not think is merited for this functionality.
235- Instead, this problem can be avoided using an intermediate type alias.
236- That is , one would write:
251+ This problem can be avoided using an intermediate type alias:
237252
238253.. code- block:: python
239254
240255 type _TargetType = < some complex expression>
241256 cast(_TargetType, value)
242257
243258This lets you use any new type expression within `` < some complex expression> ``
244- since type aliases also are implemented using annotate functions. While this
245- workaround is somewhat annoying, the fact that it is needed relatively
246- infrequently makes us believe that it is the better solution at this moment.
247- We recommend that this usage of intermediate type aliases is observed in the
248- future and new syntax to avoid it considered should it be necessary.
259+ since type aliases also are implemented using annotate functions.
260+
261+ While this solution only presents a workaround to this problem, a more
262+ comprehensive fix would require adding a new keyword to the Python language,
263+ which we do not think is necessary. This decision can be reconsidered in the
264+ future if using intermediate type aliases like this does present a significant
265+ problem in real- world code.
249266
250267
251268** ***********
0 commit comments