[Python-ideas] Proposal: Use mypy syntax for function annotations

Steven D'Aprano steve at pearwood.info
Sat Aug 23 07:13:57 CEST 2014


On Fri, Aug 22, 2014 at 10:31:18PM -0400, Antoine Pitrou wrote:

> >>Python has one of the most powerful and user-friendly function call
> >>syntaxes around, why reinvent something clearly inferior and alien?
> >
> >I wouldn't say it is alien. abc[xyz] is clearly Python syntax.
> 
> But it is completely uncommon for anything else than subscripting and 
> indexing containers. 

And function call syntax is completely uncommon for anything else than 
calling functions (including types and methods). One way or the other, 
we're adding a new use, type declarations.


> Python isn't known for reusing operators for 
> completely unrelated things, e.g. it doesn't overload ">>" for I/O 
> (thank goodness).

I see you've forgotten Python 2's 

    print >>sys.stderr, x, y, z

:-)


> >How complex will the static type declarations
> >need to be for us to want to accept arbitrary keyword arguments, for
> >example? I think limiting the syntax possible is a good thing, it will
> >discourage people from trying to declare arbitrarily complex information
> >in the type notations.
> 
> I think this is an incredibly weak argument, and the proof is that it 
> hasn't been brought for anything else in the stdlib. 

We frequently reject syntax because it will be (allegedly) confusing or 
hard to read. E.g. try...except expressions, anonymous code blocks, 
multiline lambda. Especially multiline lambda. Even something which I 
think is a no-brainer, allowing the with statement to use parentheses 
around the context managers:

    with (this_manager() as m1,
          that_manager() as m2):
        ...

was criticised by Nick on the basis that if you can't fit the context 
managers all on one line, you ought to refactor your code. I'm sure if 
you check the rejected PEPs and Python-Ideas archives, you'll find 
many examples of my argument applied to the standard library.

I don't think it's unPythonic to argue that type hinting syntax should 
by default use an annotation style which is not arbitrarily complex. The 
annotations themselves will remain arbitrary Python expressions, so if 
you really need a complex type declaration, you can create a helper and 
call it with whatever signature you like.[1]


> Why the typing 
> module should be any different and use a deliberately repressive 
> parameter-passing syntax is beyond me - even though it's an advanced, 
> optional, feature and will be put in the hands of consenting adults.

I can't speak for the author of mypy, Jukka Lehtosalo, but for me, I 
think the answer is that type declarations make a *mini-language*, not 
full-blown Python. It is unclear to me just how powerful the type 
language will be, but surely we don't expect it to evaluate arbitrarily 
complex Python expressions at compile time? Do we?

I find it unlikely that we expect a static linter to make sense of this:

def bizarre(param:int if random.random() > 0.5 else str)->float:

except to say it returns a float and takes who-knows-what as argument. 
An extreme case, I grant, but I expect that there are going to be limits 
to what can be checked at compile time based on static analysis. I admit 
that I don't fully understand all the implications of static versus 
runtime type checking, but it doesn't seem unreasonable to expect static 
declarations to be considerably simpler than what can be expressed at 
runtime. Hence, a simpler mini-language is appropriate.


> Really, for it to be powerful enough, the type description system has to 
> use its own set of classes. It can't try to hack away existing builtins 
> and ABCs in the hope of expressing different things with them, or it 
> *will* hit a wall some day (and, IMO, sooner rather than later).

How powerful is "powerful enough"? Powerful enough for what?

You've probably heard of the famous "the compiler found my infinite 
loop", where the ML type checker was able to detect that code would 
never terminate. I find that remarkable, and even more astonishing that, 
according to some, solving the halting problem is "nothing special" for 
type systems.[2] But many languages make do with less powerful type systems, 
and tools such as IDEs and editors surely don't need something that 
powerful. So:

- how powerful do we expect the type system to be?

- and how much of that power needs to be expressed using 
  function annotations?

The second question is critical, because there are alternatives to 
function annotations: decorators, docstring annotations, and external 
stub files.




[1] Although if you do so, it is not clear to me how much the static 
checker will be able to use it.


[2] http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/


-- 
Steven


More information about the Python-ideas mailing list