[Python-ideas] Conventions for function annotations

Masklinn masklinn at masklinn.net
Wed Dec 5 21:34:43 CET 2012


On 2012-12-05, at 20:22 , Guido van Rossum wrote:
> 
>> 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.

My problem there was more about having e.g. Int | Float return a set,
but isinstance not working with a set. But indeed it could return a
TypeSet which would implement __instancecheck__.

> - Tuples. Sometimes you want to say e.g. "a tuple of integers, don't
> mind the length"; other times you want to say e.g. "a tuple of fixed
> length containing an int and two strs". Perhaps the former should be
> expressed using ImmutableSequence[Int] and the second as Tuple[Int,
> Str, Str].



> - Unions. We need a way to say "either X or Y". Given that we're
> defining our own objects we may actually be able to get away with
> writing e.g. "Int | Str" or "Str | List[Str]", and isinstance() would
> still work. It would also be useful to have a shorthand for "either T
> or None", written as Optional[T] or Optional(T).

Well if `|` is the "union operator", as Ben notes `T | None` works well,
is clear and is sufficient. Though that's if and only if "Optional[T]"
is equivalent to "T or None" which Bruce seems to disagree with. There's
some history with this pattern:
http://journal.stuffwithstuff.com/2010/08/23/void-null-maybe-and-nothing/
(bottom section, from "Or Some Other Solution")

> - Whether to design notations to express other constraints. E.g.
> "integer in range(10, 100)", or "one of the strings 'r', 'w' or 'a'",
> etc. You can go crazy on this.

Yes this is going in Oleg territory, a sound core is probably a
good starting idea. Although basic enumerations ("one of the strings
'r', 'w' or 'a'") could be rather neat.

> - Composability (Nick's pet peeve, in that he is against it). I
> propose that we reserve plain tuples for this. If an annotation has
> the form "x: (P, Q)" then that ought to mean that x must conform to
> both P and Q. Even though Nick doesn't like this, I don't think we
> should do everything with decorators. Surly, the decorators approach
> is good for certain use cases, and should take precedence if it is
> used. But e.g. IDEs that use annotations for suggestions and
> refactoring should not require everything to be decorated -- that
> would just make the code too busy.
> 
> - Runtime enforcement. What should we use type annotations for? IDEs,
> static checkers (linters) and refactoring tools only need the
> annotations when they are parsing the code.

For IDEs, that's pretty much all the time though, either they're parsing
the code or they're trying to perform static analysis on it, which uses
the annotations.

> While it is tempting to
> invent some kind of runtime checking that automatically checks the
> actual types against the annotations whenever a function is called, I
> think this is rarely useful, and often prohibitively slow.

Could be useful for debug or testing runs though, in the same way
event-based profilers are prohibitively slow and can't be enabled all
the time but are still useful. Plus it might be possible to
enable/disable this mechanism with little to no source modification via
sys.setprofile (I'm not sure what hooks it provides exactly and the
documentation is rather sparse, so I'm not sure if the function object
itself is available to the setprofile callback, looking at
Lib/profiler.py it might only get the code object).


More information about the Python-ideas mailing list