Skip to content

Commit 0ceee2d

Browse files
committed
Write a bunch more about functions
1 parent bddf241 commit 0ceee2d

1 file changed

Lines changed: 72 additions & 11 deletions

File tree

pep.rst

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,18 @@ Here ``BaseTypedDict`` is defined as::
340340
class BaseTypedDict(typing.TypedDict):
341341
pass
342342

343-
But any typeddict would be allowed there. (Or, maybe we should allow ``dict``?)
343+
But any typeddict would be allowed there. (TODO: Or maybe we should
344+
allow ``dict``?)
344345

345346
This is basically a combination of
346347
"PEP 692 – Using TypedDict for more precise ``**kwargs`` typing"
347348
and the behavior of ``Unpack`` for ``*args``
348349
from "PEP 646 – Variadic Generics".
349350

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`` erving as the bound?)
354+
350355
This is potentially moderately useful on its own but is being done to
351356
support processing ``**kwargs`` with type level computation.
352357

@@ -718,7 +723,7 @@ as the ``Init`` field of the ``Member``.
718723
Annotated
719724
'''''''''
720725

721-
This could maybe be dropped?
726+
TODO: This could maybe be dropped if it doesn't seem implementable?
722727

723728
Libraries like FastAPI use annotations heavily, and we would like to
724729
be able to use annotations to drive type-level computation decision
@@ -758,28 +763,34 @@ values too?
758763
.. _generic-callable:
759764

760765
Generic Callable
761-
''''''''''''''''
766+
""""""""""""""""
762767

763768
* ``GenericCallable[Vs, lambda <vs>: Ty]``: A generic callable. ``Vs`` are a tuple
764769
type of unbound type variables and ``Ty`` should be a ``Callable``,
765770
``staticmethod``, or ``classmethod`` that has access to the
766771
variables in ``Vs`` via the bound variables in ``<vs>``.
767772

768-
(LAMBDA PART NOT IMPLEMENTED YET)
773+
For now, we restrict the use of ``GenericCallable`` to
774+
the type argument of ``Member`` (that is, to disallow its use for
775+
locals, parameter types, return types, nested inside other types,
776+
etc).
769777

770-
This is kind of unsatisfying but we at least need some way to return
771-
existing generic methods and put them back into a new protocol and we
772-
need to be able to delay evaluation of conditionals/iteration at
773-
runtime.
778+
(This is a little unsatisfying. Rationale discussed :ref:`below
779+
<generic-callable-rationale>`.)
774780

775-
The unbound type variable tuple is so that bounds and defaults and
776-
``TypeVarTuple``-ness can be specified, though maybe we want to come
777-
up with a new approach.
781+
782+
(LAMBDA PART NOT IMPLEMENTED YET)
778783

779784
TODO: Decide if we have any mechanisms to inspect/destruct
780785
``GenericCallable``. Maybe can fetch the variable information and
781786
maybe can apply it to concrete types?
782787

788+
Overloaded function types
789+
"""""""""""""""""""""""""
790+
791+
* ``Overloaded[*Callables]`` - An overloaded function type, with the
792+
underlying types in order.
793+
783794
String manipulation
784795
'''''''''''''''''''
785796

@@ -1172,6 +1183,56 @@ I am proposing a fully new extended callable syntax because:
11721183
is a non starter)
11731184

11741185

1186+
.. _generic-callable-rationale:
1187+
1188+
Generic Callable
1189+
----------------
1190+
1191+
Consider a method with the following signature::
1192+
1193+
def process[T](self, x: T) -> T if IsSub[T, list] else list[T]:
1194+
...
1195+
1196+
The type of the method is generic, and the generic is bound at the
1197+
**method**, not the class. We need a way to represent such a generic
1198+
function both as a programmer might write it for a ``NewProtocol``.
1199+
1200+
One option that is somewhat appealing but doesn't work would be to use
1201+
unbound type variables and let them be generalized::
1202+
1203+
type Foo = NewProtocol[
1204+
Member[
1205+
Literal["process"],
1206+
Callable[[T], set[T] if IsSub[T, int] else T]
1207+
]
1208+
]
1209+
1210+
The problem is that this is basically incompatible with runtime
1211+
evaluation support, since evaluating the alias ``Foo`` will need to
1212+
evalaute the ``IsSub``, and so we will lose one side of the
1213+
conditional at least. Similar problems will happen when evaluating
1214+
``Members`` on a class with generic functions. By wrapping the body
1215+
in a lambda, we can delay evaluation in both of these cases. (The
1216+
``Members`` case of delaying evaluation works quite nicely for
1217+
functions with explicit generic annotations. For old-style generics,
1218+
we'll probably have to try to evaluate it and then raise an error when
1219+
we encounter a variable.)
1220+
1221+
1222+
The reason we suggest restricting the use of ``GenericCallable`` to
1223+
the type argument of ``Member`` is because full impredicative
1224+
polymorphism (where you can have generic type binding nested inside
1225+
types and you can instantiate type variables with other generic types)
1226+
is an big can of worms when combined with type inference (TODO: CITE).
1227+
While it would be nice to support, we don't want to
1228+
open that can of worms now.
1229+
1230+
1231+
The unbound type variable tuple is so that bounds and defaults and
1232+
``TypeVarTuple``-ness can be specified, though maybe we want to come
1233+
up with a new approach.
1234+
1235+
11751236
Backwards Compatibility
11761237
=======================
11771238

0 commit comments

Comments
 (0)