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

Steven D'Aprano steve at pearwood.info
Thu Aug 14 20:52:45 CEST 2014


On Thu, Aug 14, 2014 at 07:25:04PM +0100, Cory Benfield wrote:
> On 14 August 2014 19:15, Steven D'Aprano <steve at pearwood.info> wrote:
> > I really dislike that syntax. I dislike adding cruft like "@type" and
> > ":param" into docstrings, which should be written for human readers, not
> > linters.
> 
> That ship has long-since sailed. Sphinx uses exactly this :param: and
> :return: syntax for its docstring parsing. It is by now a common
> convention (at least, I see it all over the place in open source
> code), and should not be considered a surprise.

I've seen it too, but not in docstrings written in vanilla ReST. That's 
a disappointment to hear that Sphinx uses it, because I think it is 
hideously ugly :-(


> > So, I think this proposal might actually lead to *more* duck typing
> > rather than less, since you can always turn off the type checking.
> 
> I found this conclusion impossible to understand: have I missed
> something Steven? To my eyes, the fact that when run by a user who
> knows nothing about the static type checker much duck typing will fail
> will clearly not lead to more duck typing. It will lead either to a)
> less duck typing because of all the bug reports (your code breaks
> whenever I try to run it!), or b) everyone turning the static type
> checker off.

Let me explain my reasoning.

Back in the Old Days, before Python 2.2, there was no isinstance(). We 
were strongly discouraged from doing type checks, instead we were 
encouraged to rely on duck-typing and that functions would fail loudly 
if passed the wrong argument. With the introduction of isinstance, 
Python code has slowly, gradually, begun using more and more run-time 
explicit type checks with isinstance. Some people do this more than 
others. Let's consider Fred, who is a Java programmer at heart and so 
writes code like this:

def foo(x):
    if not instance(x, float): 
        raise TypeError("Why doesn't python check this for me?")
    return (x+1)/2

I want to pass a Decimal to foo(), but can't, because of the explicit 
type check. I am sad.

But with this proposal, Fred may write his function like this:

def foo(x:float)->float:
    return (x+1)/2

and rely on mypy to check the types at compile time. Fred is happy: he 
has static type checks, Python does it automatically for him (once he 
has set up his build system to call mypy), and he is now convinced that 
foo() is type-safe and an isinstance check at run-time would be a waste 
of cycles.

I want to pass a Decimal to foo(). All I have to do is *not* install 
mypy, or disable it, and lo and behold, like magic, the type checking 
doesn't happen, and foo() operates by duck-typing just like in the glory 
days of Python 1.5. Both Fred and I are now happy, and with the explicit 
isinstance check removed, the only type checking that occurs when I run 
Fred's library are the run-time duck-typing checks.

-- 
Steven


More information about the Python-ideas mailing list