PEP 749: Rename SOURCE to STRING, go back on __annotations__ setting (#4000)
This commit is contained in:
parent
aced24fc35
commit
55cf374db5
|
@ -30,9 +30,11 @@ specification:
|
|||
that can be run in a "fake globals" environment. Instead, we add a fourth format,
|
||||
``VALUE_WITH_FAKE_GLOBALS``, to allow third-party implementors of annotate functions to
|
||||
indicate what formats they support.
|
||||
* Setting the ``__annotations__`` attribute directly will not affect the ``__annotate__`` attribute.
|
||||
* Deleting the ``__annotations__`` attribute directly will also clear ``__annotate__``.
|
||||
* We add functionality to allow evaluating type alias values and type parameter bounds and defaults
|
||||
(which were added by :pep:`695` and :pep:`696`) using PEP 649-like semantics.
|
||||
* The ``SOURCE`` format is renamed to ``STRING`` to improve clarity and reduce the risk of
|
||||
user confusion.
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
@ -229,13 +231,13 @@ The module will contain the following functionality:
|
|||
dictionary. This is intended to be used for evaluating deferred attributes introduced by
|
||||
:pep:`695` and :pep:`696`; see below for details. *func* may be ``None``
|
||||
for convenience; if ``None`` is passed, the function also returns ``None``.
|
||||
* ``annotations_to_source(annotations: dict[str, object]) -> dict[str, str]``: a function that
|
||||
* ``annotations_to_string(annotations: dict[str, object]) -> dict[str, str]``: a function that
|
||||
converts each value in an annotations dictionary to a string representation.
|
||||
This is useful for
|
||||
implementing the ``SOURCE`` format in cases where the original source is not available,
|
||||
such as in the functional syntax for :py:class:`typing.TypedDict`.
|
||||
* ``value_to_source(value: object) -> str``: a function that converts a single value to a
|
||||
string representation. This is used by ``annotations_to_source``.
|
||||
* ``value_to_string(value: object) -> str``: a function that converts a single value to a
|
||||
string representation. This is used by ``annotations_to_string``.
|
||||
It uses ``repr()`` for most values, but for types it returns the fully qualified name.
|
||||
It is also useful as a helper for the ``repr()`` of a number of objects in the
|
||||
:py:mod:`typing` and :py:mod:`collections.abc` modules.
|
||||
|
@ -629,29 +631,23 @@ Third-party code that implements ``__annotate__`` functions should raise
|
|||
and the function is not prepared to be run in a "fake globals" environment.
|
||||
This should be mentioned in the data model documentation for ``__annotate__``.
|
||||
|
||||
Effect of setting ``__annotations__``
|
||||
=====================================
|
||||
Effect of deleting ``__annotations__``
|
||||
======================================
|
||||
|
||||
:pep:`649` specifies:
|
||||
|
||||
Setting ``o.__annotations__`` to a legal value
|
||||
automatically sets ``o.__annotate__`` to ``None``.
|
||||
|
||||
We would prefer to keep ``__annotate__`` unchanged when ``__annotations__``
|
||||
is written to. Conceptually, ``__annotate__`` provides the ground truth
|
||||
and ``__annotations__`` is merely a cache, and we shouldn't throw away the
|
||||
ground truth if the cache is modified.
|
||||
|
||||
The motivation for :pep:`649`'s behavior is to keep the two attributes in sync.
|
||||
However, this is impossible in general; if the ``__annotations__`` dictionary
|
||||
is modified in place, this will not be reflected in the ``__annotate__`` attribute.
|
||||
The overall mental model for this area will be simpler if setting ``__annotations__``
|
||||
has no effect on ``__annotate__``.
|
||||
However, the PEP does not say what happens if the ``__annotations__`` attribute
|
||||
is deleted (using ``del``). It seems most consistent that deleting the attribute
|
||||
will also delete ``__annotate__``.
|
||||
|
||||
Specification
|
||||
-------------
|
||||
|
||||
The value of ``__annotate__`` is not changed when ``__annotations__`` is set.
|
||||
Deleting the ``__annotations__`` attribute on functions, modules, and classes
|
||||
results in setting ``__annotate__`` to None.
|
||||
|
||||
Deferred evaluation of PEP 695 and 696 objects
|
||||
==============================================
|
||||
|
@ -730,6 +726,34 @@ can use the ``ForwardRef.evaluate`` method.
|
|||
If use cases come up in the future, we could add additional functionality,
|
||||
such as a new method that re-evaluates the annotation from scratch.
|
||||
|
||||
Renaming ``SOURCE`` to ``STRING``
|
||||
=================================
|
||||
|
||||
The ``SOURCE`` format is meant for tools that need to show a human-readable
|
||||
format that is close to the original source code. However, we cannot retrieve
|
||||
the original source in ``__annotate__`` functions, and in some cases, we have
|
||||
``__annotate__`` functions in Python code that do not have access to the original
|
||||
code. For example, this applies to :py:func:`dataclasses.make_dataclass`
|
||||
and the call-based syntax for :py:class:`typing.TypedDict`.
|
||||
|
||||
This makes the name ``SOURCE`` a bit of a misnomer. The goal of the format
|
||||
should indeed be to recreate the source, but the name is likely to mislead
|
||||
users in practice. A more neutral name would emphasize that the format returns
|
||||
an annotation dictionary with only strings. We suggest ``STRING``.
|
||||
|
||||
Specification
|
||||
-------------
|
||||
|
||||
The ``SOURCE`` format is renamed to ``STRING``. To reiterate the changes in this
|
||||
PEP, the four supported formats are now:
|
||||
|
||||
- ``VALUE``: the default format, which evaluates the annotations and returns the
|
||||
resulting values.
|
||||
- ``VALUE_WITH_FAKE_GLOBALS``: for internal use; should be handled like ``VALUE``
|
||||
by annotate functions that support execution with fake globals.
|
||||
- ``FORWARDREF``: replaces undefined names with ``ForwardRef`` objects.
|
||||
- ``STRING``: returns strings, attempts to recreate code close to the original source.
|
||||
|
||||
Miscellaneous implementation details
|
||||
====================================
|
||||
|
||||
|
|
Loading…
Reference in New Issue