Skip to content

Commit 324ad7b

Browse files
authored
Write a backward compatibility section (#105)
1 parent e5ded19 commit 324ad7b

1 file changed

Lines changed: 52 additions & 13 deletions

File tree

pep.rst

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ and to perform validation/filtering of the data in the endpoint::
173173
secret_name: str | None = None
174174

175175

176-
The ``HeroPublic`` type is used as the return types of the read
176+
The ``HeroPublic`` type is used as the return type of the read
177177
endpoint (and is validated while being output, including having extra
178178
fields stripped), while ``HeroCreate`` and ``HeroUpdate`` serve as
179179
input types (automatically converted from JSON and validated based on
@@ -342,7 +342,7 @@ support processing ``**kwargs`` with type level computation.
342342
Extended Callables, take 2
343343
--------------------------
344344

345-
We introduce a new extended callable proposal for expressing arbitrary
345+
We introduce a new extended callable proposal for expressing arbitrarily
346346
complex callable types. The goal here is not really to produce a new
347347
syntax to write in annotations (it seems less pleasant to write than
348348
callback protocols are), but to provide a way of constructing the types
@@ -573,7 +573,7 @@ Basic operators
573573

574574
* ``GetArg[T, Base, Idx: Literal[int]]``: returns the type argument
575575
number ``Idx`` to ``T`` when interpreted as ``Base``, or ``Never``
576-
if it cannot be. (That is, if we have ``class A(B[C]): ...``, then
576+
if it cannot be. (That is, if we have ``class A(B[C]): ...``, then
577577
``GetArg[A, B, 0] == C`` while ``GetArg[A, A, 0] == Never``).
578578

579579
Negative indexes work in the usual way.
@@ -600,7 +600,7 @@ Basic operators
600600

601601

602602
* ``GetSpecialAttr[T: type, Attr: Literal[str]]``: Extracts the value
603-
of special attribute named ``Attr`` from the class ``T``. Valid
603+
of the special attribute named ``Attr`` from the class ``T``. Valid
604604
attributes are ``__name__``, ``__module__``, and ``__qualname__``.
605605
Returns the value as a ``Literal[str]``.
606606

@@ -676,7 +676,7 @@ Object creation
676676
allows specifying bases too. The idea is that a type would satisfy
677677
this protocol if it extends all of the given bases and has the
678678
specified members. (TODO: Is this something we actually
679-
want? It would would be a potentially powerful feature for dealing
679+
want? It would be a potentially powerful feature for dealing
680680
with things like Pydantic models, but protocol-with-bases would be
681681
something of a new concept.)
682682

@@ -847,7 +847,7 @@ base classes and type decorators that do ``dataclass`` like things.
847847

848848
One snag here: it introduces type-evaluation-order dependence; if the
849849
``UpdateClass`` return type for some ``__init_subclass__`` inspects
850-
some unrelated class's ``Members`` , and that class also has an
850+
some unrelated class's ``Members``, and that class also has an
851851
``__init_subclass__``, then the results might depend on what order
852852
they are evaluated. Ideally this kind of case would be rejected,
853853
which I think ought to be possible?
@@ -916,9 +916,9 @@ those cases, we add a new hook to ``typing``:
916916

917917

918918
There has been some discussion of adding a ``Format.AST`` mode for
919-
fetching annotations. That would combine extremely well with this
920-
proposal, as it would make it easy to still fetch fully unevaluated
921-
annotations.
919+
fetching annotations (see this `PEP draft <#ast_format_>`_). That
920+
would combine extremely well with this proposal, as it would make it
921+
easy to still fetch fully unevaluated annotations.
922922

923923
Examples / Tutorial
924924
===================
@@ -1213,7 +1213,45 @@ up with a new approach.
12131213
Backwards Compatibility
12141214
=======================
12151215

1216-
[Describe potential impact and severity on pre-existing code.]
1216+
In the most strict sense, this PEP only proposes new features, and so
1217+
shouldn't have backward compatibility issues.
1218+
1219+
More loosely speaking, though, the use of ``if`` and ``for`` in type
1220+
annotations can cause trouble for tools that want to extract type
1221+
annotations.
1222+
1223+
Tools that want to fully evaluate the annotations will need to either
1224+
implement an evaluator or use a library for it (the PEP authors are
1225+
planning to produce such a library).
1226+
1227+
Tools that want to extract the annotations unevaluated and process
1228+
them in some way are possibly in more trouble. Currently, this is
1229+
doable if ``from __future__ import annotations`` is specified, because
1230+
the string annotation could be parsed with ``ast.parse`` and then handled
1231+
in arbitrary ways.
1232+
1233+
Absent that, as things currently stand, things get trickier, since
1234+
there is currently no way to get useful info out of the
1235+
``__annotate__`` functions without running the annotation, and its
1236+
tricks for building a string do not work for loops and
1237+
conditionals.
1238+
1239+
This could be mitigated by doing one of:
1240+
1. The `"Just store the
1241+
strings" <https://peps.python.org/pep-0649/#just-store-the-strings>`_
1242+
option from :pep:`649`, which would allow always extracting
1243+
unevaluated strings.
1244+
2. Adding a ``Format.AST`` mode for
1245+
fetching annotations (see this `PEP draft <#ast_format_>`_)
1246+
1247+
If neither of those options are taken, then tools that want to process
1248+
unevaluated type manipulation expressions will probably need to
1249+
reparse the source code and extract annotations from there.
1250+
1251+
Note that all of these snags only come up *if* the new syntax is being
1252+
used, so this is arguably less of a backward compatibility hazard than
1253+
it is that supporting the new feature may be somewhat annoying for
1254+
certain tools.
12171255

12181256

12191257
Security Implications
@@ -1402,7 +1440,7 @@ In TypeScript, conditional types are formed like::
14021440

14031441
SomeType extends OtherType ? TrueType : FalseType
14041442

1405-
What's more, the right hand side of the check allows binding type
1443+
What's more, the right-hand side of the check allows binding type
14061444
variables based on pattern matching, using the ``infer`` keyword, like
14071445
this example that extracts the element type of an array::
14081446

@@ -1515,7 +1553,7 @@ changes.)
15151553
Another advantage is not needing any notion of a special
15161554
``<type-bool>`` class of types.
15171555

1518-
The disadvantage is that is that the syntax seems a *lot*
1556+
The disadvantage is that the syntax seems a *lot*
15191557
worse. Supporting filtering while mapping would make it even more bad
15201558
(maybe an extra argument for a filter?).
15211559

@@ -1544,7 +1582,7 @@ but it's still a lot of surface area, and programmers would need to
15441582
keep in mind the boundaries of it.
15451583

15461584
Additionally there would need to be a clear specification of how types
1547-
are represented in the "mini-plugin" functions, as well defining
1585+
are represented in the "mini-plugin" functions, as well as defining
15481586
functions/methods for performing various manipulations. Those
15491587
functions would have a pretty big overlap with what this PEP currently
15501588
proposes.
@@ -1619,6 +1657,7 @@ Footnotes
16191657
.. _#prisma-example: https://github.com/prisma/prisma-examples/tree/latest/orm/express
16201658
.. _#qb-test: https://github.com/vercel/python-typemap/blob/main/tests/test_qblike_2.py
16211659
.. _#starlark: https://starlark-lang.org/
1660+
.. _#ast_format: https://imogenbits-peps.readthedocs.io/en/ast_format/pep-9999/
16221661

16231662
.. [#ref-impl] https://github.com/msullivan/mypy/tree/typemap
16241663
.. [#runtime] https://github.com/vercel/python-typemap/

0 commit comments

Comments
 (0)