[Python-checkins] peps: A new type hints draft. I've decided to publish more drafts.
Terry Reedy
tjreedy at udel.edu
Fri Mar 20 21:41:31 CET 2015
On 3/20/2015 12:47 PM, guido.van.rossum wrote:
> summary:
> A new type hints draft. I've decided to publish more drafts.
...
> +The proposal is strongly inspired by mypy [mypy]_. For example, the
> +type "sequence of integers" can be written as ``Sequence[int]``. The
> +square brackets mean that no new syntax needs to be added to the
> +language. The example here uses a custom class ``Sequence``, imported
> +from a pure-Python module ``typing.py``. The ``Sequence[int]``
> +notation works by implementing ``__getitem__()`` in the metaclass.
I really like this use of the fact that in Python, everything, including
a class, is an object that is an instance of some class, and that any
object, including a class, can be be created on an as-needed,
just-in-time basis.
> + from typing import List
from typing import List, cast # ??
> + def find_first_str(a: List[object]) -> str:
> + index = next(i for i, x in enumerate(a) if isinstance(x, str))
> + # We only get here if there's at least one string in a
> + return cast(str, a[index])
The superfluous introduction of indexes distracts from the point, while
I think catching of StopIteration is important. How about
def find_first_str(a: List[object]) -> str:
try:
return cast(str, next(x for x in a if isinstance(x, str)))
# any return must be str; so tell the type checker
except StopIteration:
raise ValueError('input list has no strings')
> +The type checker infers the type ``object`` for ``a[index]``, but we
/a[index]/the return value/
> +know that (if the code gets to that point) it must be a string. The
> +``cast(t, x)`` call tells the type checker that we are confident that
> +the type of ``x`` is ``t``. At runtime a cast always returns the
> +expression unchanged -- it does not check the type, and it does not
> +convert or coerce the value.
If someone redefines cast as
def cast(typ, val):
assert isinstance(val, typ)
return val
would the type checker continue to recognize it in uses such as the
above, or would it notice that cast != typing.case? Would the import
still be needed?
The new @overload looks nice.
> +Most people are familiar with the use of angular brackets
> +(e.g. ``List<int>``) in languages like C++, Java, C# and Swift to
> +express the parametrization of generic types.
Perhaps I am fortunate to not have such predisposing experience.
> +The problem with type hints is that annotations (per PEP 3107, and
> +similar to default values) are evaluated at the time a function is
> +defined, and thus any names used in an annotation must be already
> +defined when the function is being defined. A common scenario is a
> +class definition whose methods need to reference the class itself in
> +their annotations. (More general, it can also occur with mutually
/general/generally/
> +recursive classes.) This is natural for container types, for
> +example::
> +
> + class Node:
> + """Binary tree node."""
> +
> + def __init__(self, left: Node, right: None):
> + self.left = left
> + self.right = right
> +
> +As written this will not work, because of the peculiarity in Python
> +that class names become defined once the entire body of the class has
> +been executed.
I have sometimes wondered whether class definition could and should be
changed to be like module definition, which begins with an empty dict
and module object that are deleted upon error.
> +Is Type Hinting Pythonic?
> =========================
>
> +.. FIXME: Do we really need this section?
Maybe not.
> Type annotations provide important documentation for how a unit of code
> should be used. Programmers should therefore provide type hints on
> public APIs, namely argument and return types on functions and methods
This comes pretty close to saying that you *do* hope that type hints
become required, at least by convention.
TJR
More information about the Python-checkins
mailing list