[Python-ideas] Conventions for function annotations (original) (raw)

Guido van Rossum guido at python.org
Wed Dec 5 20:22:33 CET 2012


On Tue, Dec 4, 2012 at 10:12 AM, Masklinn <masklinn at masklinn.net> wrote:

On 2012-12-03, at 18:27 , Guido van Rossum wrote:

Obviously this would require inventing and standardizing notations for things like "list of X", "tuple with items X, Y, Z", "either X or Y", and so on, as well as a standard way of combining annotations intended for different tools. I've always felt that getitem and or/ror on type 1. looked rather good and 2. looked similar to informal type specs and type specs of other languages. Although that's the issue with annotations being Python syntax: it requires changing stuff fairly deep into Python to be able to experiment.

So, instead of using

def foo(a: int, b: str) -> float:

you use

from experimental_type_annotations import Int, Str, Float

def foo(a: Int, b: Str) -> Float:

And now we're ready for experimentation.

[Warning: none of this is particularly new; I've had these things in my brain for years, as the referenced Artima blog post made clear.]

The most bothersome part is that I "feel" "either X or Y" (aka X | Y) should be a set of type (and thus the same as {X, Y}[0]) but that doesn't work with isinstance or issubclass. Likewise, (a, b, c) in an annotation feels like it should mean the same as tuple[a, b, c] ("a tuple with 3 items of types resp. a, b and c") but that's at odds with the same type-checking functions.

Note that in Python 3 you can override isinstance, by defining instancecheck in the class: http://docs.python.org/3/reference/datamodel.html?highlight=instancecheck#class._instancecheck_

So it shouldn't be a problem to make isinstance(42, Int) work.

We can also make things like List[Int] and Dict[Str, Float] work, and even rig it so that

isinstance([1, 2, 3], List[Int]) == True

while

isinstance([1, 2, 'booh'], List[Int]) == False

Of course there are many bikeshedding topics like whether we should ever write List -- maybe we should write Iterable or Sequence instead, and maybe we have to be able to express mutability, and so on. The numeric tower (PEP 3141) is also good to keep in mind. I think that's all solvable once we start experimenting a bit.

Some important issues to bikeshed over:

The first could be fixable by relaxing slightly the constraints of isinstance and issubclass, but not so for the second.

[0] which works rather neatly for anonymous unions as | is the union of two sets, so the arithmetic would be type | type -> typeset, type | typeset -> typeset and typeset | typeset -> typeset, libraries could offer opaque types/typesets which would be composable without their users having to know whether they're type atoms or typesets

I like this for declaring union types. I don't like it for composing constraints that are intended for different tools.

-- --Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list