[Python-ideas] Optional static typing -- the crossroads

Guido van Rossum guido at python.org
Sun Aug 17 07:03:48 CEST 2014


I'd like to summarize the main issues that have come up. As an experiment,
I'm not changing the subject, but I am still not quoting anything in
particular. Only two issues (or issue clusters) really seem contentious:

(1) Should the function annotation syntax (eventually) be reserved for type
annotations in a standard syntax? Or can multiple different uses of
annotations coexist? And if they can, how should a specific use be
indicated? (Also, some questions about compile-time vs. run-time use.)

(2) For type annotations, should we adopt (roughly) the mypy syntax or the
alternative proposed by Dave Halter? This uses built-in container notations
as a shorthand, e.g. {str: int} instead of Dict[str, int]. This also
touches on the issue of abstract vs. concrete types (e.g. iterable vs.
list).

Regarding (1), I continue to believe that we should eventually reserve
annotations for types, to avoid confusing both humans and tools, but I
think there's nothing we have to do in 3.5 -- 3.5 must preserve backward
compatibility, and we're not proposing to give annotations any new
semantics anyway -- the actual changes to CPython are limited to a new
stdlib module (typing) and some documentation.

Perhaps a thornier issue is how mypy should handle decorators that
manipulate the signature or annotations of the function they wrap. But I
think the only reasonable answer here can be that mypy must understand what
decorators do if it wants to have any chance at type-checking decorated
functions. I don't actually know how sophisticated mypy's understanding of
decorators is, currently, but I don't think there's anything fundamentally
more difficult than all the other things it must understand.

Moving on to (2), the proposal is elegant enough by itself, and indeed has
the advantage of being clear and concise: [T] instead of List[T], {T: U}
instead of Dict[T, U], and so on. However, there are a few concerns.

My first concern is that these expressions are only unambiguous in the
context of function annotations. I want to promote the use of type aliases,
and I think in general a type alias should behave similarly to an ABC. In
particular, I think that any object used to represent a type in an
annotation should itself be a type object (though you may not be able to
instantiate it), and e.g. [int] doesn't satisfy that requirement. Without
this, it would be difficult to implement isinstance() and issubclass() for
type aliases -- and while we could special-case lists, sets and dicts,
using a tuple *already* has a meaning!

The second concern is that the proposal seems to steer users in the
direction of using concrete types. A lot of Python's power stems from
concepts like iterable and mapping and their variants (e.g. iterable,
container, sequence, mutable sequence). There are justified concerns that
users will unnecessarily constrain the argument types more than necessary
(e.g. specifying a sequence where any iterable would do), and this proposal
lacks the subtlety to express the difference.

A third (minor) concern reflects issue (1): until we have agreement that
annotations should only be used as type annotations, a type checker cannot
assume that the presence of annotations means that types should be checked.
Using e.g. Iterable[int] is pretty unambiguous (especially when Iterable is
imported from typing.py), whereas just [int] is somewhat ambiguous. I call
this only a minor issue because it still occurs for simple types like int
or str, so if we can live with it for those we could presumably live with
[int] and {str: float}.

All in all I prefer the mypy syntax, despite being somewhat more verbose
and requiring an import, with one caveat: I agree that it would be nicer if
the mypy abstract collection types were the same objects as the ABCs
exported by collections.abc. I'm not quite sure whether we should also
change the concrete collection types from List, Dict, Set, Tuple to list,
dict, set, tuple; the concrete types are so ubiquitous that I worry that
there may be working code out there that somehow relies on the type objects
themselves not being subscriptable.

A mostly unrelated issue: there are two different uses of tuples, and we
need a notation for both. One is a tuple of fixed length with
heterogeneous, specific types for the elements; for example Tuple[int,
float]. But I think we also need a way to indicate that a function expects
(or returns) a variable-length tuple with a homogeneous element type.
Perhaps we should call this type frozenlist, analogous to frozenset (and it
seems there's a proposal for frozendict making the rounds as well).

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


More information about the Python-ideas mailing list