[Python-ideas] Adding Type[C] support to PEP 484 and typing.py

Guido van Rossum guido at python.org
Thu May 12 17:59:57 EDT 2016

On Thu, May 12, 2016 at 2:51 PM, Pavol Lisy <pavol.lisy at gmail.com> wrote:

> 2016-05-12 20:49 GMT+02:00, Guido van Rossum <guido at python.org>:
> > There are some subtleties, e.g. in the above example we would actually
> like
> > to know that the return type varies with the argument type:
> >
> > joe = new_user(ProUser)  # Really, joe is a ProUser, not just a User
> >
> > This can be done using a type variable, e.g.
> >
> > U = TypeVar('U', bound=User)
> > def new_user(user_class: Type[U]) -> U: ...
> > joe = new_user(ProUser)
> It is very probably I dont understand. Is U here same type (=ProUser)
> for parameter and for return?

Their status is different though. The return type is inferred from the
argument type but (usually) not the other way around.

> Because in PEP484 is written:
> -> CT = TypeVar('CT', bound=Comparable)
> ->
> ->   def min(x: CT, y: CT) -> CT:
> ->       if x < y:
> ->           return x
> ->       else:
> ->          return y
> ->
> ->  min(1, 2) # ok, return type int
> ->  min('x', 'y') # ok, return type str
> ->
> ->(Note that this is not ideal -- for example ``min('x', 1)`` is invalid
> ->at runtime but a type checker would simply infer the return type
> ->``Comparable``.  Unfortunately, addressing this would require
> ->introducing a much more powerful and also much more complicated
> ->vconcept, F-bounded polymorphism.  We may revisit this in the future.)
> which I understand that CT could be different type for x (=str) and y
> (=int).

No, *in a given call* CT will be the same for all. The example with
Comparable is that for `min('x', 1)` there is a solution where CT *is*
actually the same for both arguments -- both 'x' and 1 are instances of
Comparable. In that example this is not ideal.

But in the new_user(UserPro) example there's only one occurrence of U in
the argument list, and that will be inferred as the return type.

An example more similar to the CT example with users would be something like

def pair_accounts(personal_user_class: Type[U], business_use_class:
Type[U]) -> List[U]: ...

Here the return type of pair_accounts(ProUser, ProUser) would be inferred
as List[ProUser], but the return type of pair_accounts(ProUser, TeamUser)
would be inferred as List[User], since User is the common base class of
ProUser and TeamUser.

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160512/d575d413/attachment.html>

More information about the Python-ideas mailing list