diff --git a/peps/pep-0849.rst b/peps/pep-0849.rst index 3a0c5931e79..783175c4cbf 100644 --- a/peps/pep-0849.rst +++ b/peps/pep-0849.rst @@ -62,7 +62,7 @@ as ``Literal[1, 2, 3]``. Many users intuitively want to instead spell this as ``1 | 2 | 3``, writing out the bare literals and using the union operator to join them, which also is what other languages such as TypeScript use. This is currently not possible in Python because the expression ``1 | 2 | 3`` evaluates -simply to ``3`` because ``|`` is interpreted as the binary-or operation rather than +simply to ``3`` because ``|`` is interpreted as the bitwise-or operation rather than the union of types. Further, constant folding eliminates this expression from appearing anywhere in the generated bytecode, and it thus is impossible to retrieve the actual type annotation at runtime. @@ -118,7 +118,7 @@ usual annotation dict ``{"a": int, "b": list[str]}``. But when called as { "a": AnnotationAST(ast.Name("int"), {"int": int}), - "b": AnnotationAST(ast.Subscript(ast.Name("list"), ast.Name("str")), {"list": list, "str": str), + "b": AnnotationAST(ast.Subscript(ast.Name("list"), ast.Name("str")), {"list": list, "str": str}), } However, most users will never see these objects directly. Rather, we propose @@ -134,7 +134,7 @@ allow complete runtime introspection. We also propose to add some additional utility functionality related to annotate functions and these AST objects. In particular, a new -``create_annoate_function`` in the :py:mod:`annotationlib` module to easily +``create_annotate_function`` in the :py:mod:`annotationlib` module to easily synthesize an annotate function. The core of this functionality is already implemented in the :py:mod:`dataclasses` module, and we foresee that many users will need this in order to create annotate functions that support @@ -150,11 +150,11 @@ the class from above: .. code-block:: python - MyClass: + class MyClass: a: int b: list[str] -Under this proposal its annotate function may behave similar to this Python code: +Under this proposal its annotate function may behave similarly to this Python code: .. code-block:: python @@ -185,13 +185,13 @@ using a function like this: .. code-block:: python - def eval_type_annotation_AST(ast, namespace): - match ast: + def eval_type_annotation_AST(node, namespace): + match node: case ast.Name: - return namespace[ast.id] + return namespace[node.id] case ast.Attribute: - value = eval_type_annotation_AST(ast.value, namespace) - return getattr(value, ast.attr) + value = eval_type_annotation_AST(node.value, namespace) + return getattr(value, node.attr) ... @@ -236,7 +236,7 @@ of users, who also benefit from the newly possible type annotations, we consider this a worthwhile trade-off. The specification of the proposed format is also open enough that many optimizations are possible should they be deemed necessary in the future. For many users, this proposal will even be a slight performance -increase since their code never evaluates any annotate functions. +improvement since their code never evaluates any annotate functions. .. _outside-annos: @@ -289,13 +289,15 @@ The ``AST`` Format A new value called ``AST`` is added to the ``annotationlib.Format`` enum with value 5. Annotate functions do not have to support this format. If an annotate function is called with this format, it must return a -``AnnotationAST`` object. These are instances of a proposed new class that +dict with str keys and ``AnnotationAST`` objects as values (or a single ``AnnotationAST`` object +for evaluate functions, like ``evaluate_value`` on ``TypeAliasType``). +These are instances of a proposed new class that hold the annotation's AST as an ``ast.expr`` object and a namespace that is used to evaluate them. Compiler-generated annotate functions will always support this format. -They will store the necessary AST data stored as string constants and then -construct a new ``AnnotationAST`` objects each time they are called. The +They will store the necessary AST data as string constants and then +construct new ``AnnotationAST`` objects each time they are called. The contained AST objects will be identical to the objects created by parsing the annotation source code directly. @@ -363,7 +365,7 @@ about existing user annotations being reinterpreted to different objects when the library is updated. But this also is not an issue. The typing spec already is covered by backwards compatibility concerns, which means that any currently valid type annotations will not be changed to mean something different. -Potential future changes can only define new semantics to syntax constructs that +Potential future changes can only define new semantics for syntactic constructs that currently are not valid type annotations and thus do not occur in user code. @@ -424,15 +426,15 @@ relevant typing objects themselves. This can be achieved in several ways, for example via a new optional argument to signal typing-specific semantics or a new format. These approaches were rejected because they force the type-specific semantics to be defined in the interpreter itself. This not only limits the -semantics to e.g. not require namespace lookups and also locks the usage of +semantics to e.g. not require namespace lookups but also locks the usage of typing features to the Python version that is being used, rather than allowing the currently possible backporting via ``typing_extensions``. Storing Annotation Source Code ============================== -Instead of storing binary data that defines the annotations' ASTs an alternative -is to simply store the annotations source code directly. This also was presented +Instead of storing binary data that defines the annotations' ASTs, we could +simply store the annotations source code directly. This also was presented as a possibility all the way back in :pep:`649`. The two approaches are largely equivalent since one can create the AST from the source code and vice versa. While the unparsed AST is not necessarily the exact string that occurred in