Skip to content

Commit 9efee72

Browse files
committed
Write a bunch about the keyword stuff
1 parent ff33a3c commit 9efee72

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

pep.rst

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,14 +343,36 @@ Here ``BaseTypedDict`` is defined as::
343343
But any typeddict would be allowed there. (TODO: Or maybe we should
344344
allow ``dict``?)
345345

346+
Then, if we had a call like::
347+
348+
x: int
349+
y: list[str]
350+
f(x=x, y=y)
351+
352+
the type inferred for ``K`` would be something like::
353+
354+
TypedDict({'x': int, y: list[str]})
355+
346356
This is basically a combination of
347357
"PEP 692 – Using TypedDict for more precise ``**kwargs`` typing"
348358
and the behavior of ``Unpack`` for ``*args``
349359
from "PEP 646 – Variadic Generics".
350360

351-
When inferring types here, the type checker should be **aggressive in
352-
inferring literal types when possible**. (TODO: Or maybe we need to
353-
make that configurable in the ``TypedDict`` serving as the bound?)
361+
When inferring types here, the type checker should **infer literal
362+
types when possible**. This means inferring literal types for
363+
arguments that **do not** appear in the bound, as well as
364+
for arguments that **do** appear in the bound as read-only (TODO: Or
365+
maybe we should make whether to do it for extra arguments
366+
configurable in the ``TypedDict`` serving as the bound somehow? If
367+
``readonly`` had been added as a parameter to ``TypedDict`` we would
368+
use that.)
369+
370+
For each non-required item in the bound that does **not** have a
371+
matching argument provided, then if the item is read-only, it will
372+
have its type inferred as ``Never``, to indicate that it was not
373+
provided. (This can only be done for read-only items, since non
374+
read-only items are invariant.)
375+
354376

355377
This is potentially moderately useful on its own but is being done to
356378
support processing ``**kwargs`` with type level computation.
@@ -708,16 +730,18 @@ Our strategy for this is to introduce a new type
708730

709731
When ``InitField`` or (more likely) a subtype of it is instantiated
710732
inside a class body, we infer a *more specific* type for it, based on
711-
``Literal`` types for all the arguments passed.
733+
``Literal`` types where possible. (Though actually, this is just an
734+
application of the rule that typevar unpacking in ``**kwargs`` should
735+
use ``Literal`` types.)
712736

713737
So if we write::
714738

715739
class A:
716-
foo: int = InitField(default=0)
740+
foo: int = InitField(default=0, kw_only=True)
717741

718742
then we would infer the type ``InitField[TypedDict('...', {'default':
719-
Literal[0]})]`` for the initializer, and that would be made available
720-
as the ``Init`` field of the ``Member``.
743+
Literal[0], 'kw_only': Literal[True]})]`` for the initializer, and
744+
that would be made available as the ``Init`` field of the ``Member``.
721745

722746

723747
Annotated
@@ -1259,8 +1283,14 @@ like mapped types are unmentioned in current documentation
12591283
Reference Implementation
12601284
========================
12611285

1262-
[Link to any existing implementation and details about its state, e.g. proof-of-concept.]
1286+
There is an in-progress proof-of-concept implementation in mypy [#ref-impl]_.
1287+
1288+
It can type check the ORM and NumPy-style broadcasting examples.
1289+
1290+
It is missing support for callables, ``UpdateClass``, annotation
1291+
processing, and various smaller things.
12631292

1293+
There is a demo of a runtime evaluator as well [#runtime]_.
12641294

12651295
Rejected Ideas
12661296
==============
@@ -1396,11 +1426,15 @@ Footnotes
13961426
.. _#fastapi: https://fastapi.tiangolo.com/
13971427
.. _#pydantic: https://docs.pydantic.dev/latest/
13981428
.. _#fastapi-tutorial: https://fastapi.tiangolo.com/tutorial/sql-databases/#heroupdate-the-data-model-to-update-a-hero
1399-
.. _#fastapi-test: https://github.com/geldata/typemap/blob/main/tests/test_fastapilike_2.py
1429+
.. _#fastapi-test: https://github.com/vercel/python-typemap/blob/main/tests/test_fastapilike_2.py
14001430
.. _#prisma: https://www.prisma.io/
14011431
.. _#prisma-example: https://github.com/prisma/prisma-examples/tree/latest/orm/express
1402-
.. _#qb-test: https://github.com/geldata/typemap/blob/main/tests/test_qblike_2.py
1432+
.. _#qb-test: https://github.com/vercel/python-typemap/blob/main/tests/test_qblike_2.py
1433+
14031434
.. [#broadcasting] http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
1435+
.. [#ref-impl] https://github.com/msullivan/mypy/tree/typemap
1436+
.. [#runtime] https://github.com/vercel/python-typemap/
1437+
14041438
14051439
14061440
Copyright

0 commit comments

Comments
 (0)