[Python-Dev] Type hints -- a mediocre programmer's reaction

Steven D'Aprano steve at pearwood.info
Tue Apr 21 14:47:23 CEST 2015


On Tue, Apr 21, 2015 at 11:56:15AM +0100, Rob Cliffe wrote:

>         (Adding a type hint that restricted the argument to say a 
> sequence of numbers turns out to be a mistake.

Let's find out how big a mistake it is with an test run.

py> def sorter(alist: List[int]) -> List[int]:
...     return sorted(alist)
...
py> data = (chr(i) + 'ay' for i in range(97, 107))
py> type(data)
<class 'generator'>
py> sorter(data)
['aay', 'bay', 'cay', 'day', 'eay', 'fay', 'gay', 'hay', 'iay', 'jay']


When we say that type checking is optional, we mean it.

[Disclaimer: I had to fake the List object, since I don't have the 
typing module, but everything else is exactly as you see it.]

Annotations will be available for type checking. If you don't want to 
type check, don't type check. If you want to go against the type hints, 
you can go against the type hints, and get exactly the same runtime 
errors as you have now:

py> sorter(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in sorter
TypeError: 'NoneType' object is not iterable

There is no compile time checking unless you choose to run a type 
checker or linter -- and even if the type checker flags errors, you can 
ignore it and run the program regardless. Just like today with linters 
like PyFlakes, PyLint and similar.

For those who choose not to run a type checker, the annotations will be 
nothing more than introspectable documentation.


> And what is a number?
>          Is Fraction?  What about complex numbers, which can't be 
> sorted?  What if the function were written before the Decimal class?)

I know that you are intending these as rhetorical questions, but Python 
has had a proper numeric tower since version 2.5 or 2.6. So:

py> from numbers import Number
py> from decimal import Decimal
py> isinstance(Decimal("1.25"), Number)
True
py> isinstance(2+3j, Number)
True


>     Errors are often not caught until run time that would be caught at 
> compile time in other languages (though static code checkers help).

Yes they do help, which is exactly the point.


>         (Not much of a disadvantage because of Python's superb error 
> diagnostics.)

That's certainly very optimistic of you.

If I had to pick just one out of compile time type checking versus run 
time unit tests, I'd pick run time tests. But it is naive to deny the 
benefits of compile time checks in catching errors that you otherwise 
might not have found even with extensive unit tests (and lets face it, 
we never have enough unit tests).

Ironically, type hinting will *reduce* the need for intrusive, 
anti-duck-testing explicit calls to isinstance() at runtime:

def func(x:float):
    if isinstance(x, float): ...
    else: raise TypeError


Why bother making that expensive isinstance call every single time the 
function is called, if the type checker can prove that x is always a 
float?


> Python code typically says what it is doing, with the minimum of 
> syntactic guff.  (Well, apart from colons after if/while/try etc. :-) )
>     Which makes it easy to read.
> Now it seems as if this proposal wants to start turning Python in the 
> C++ direction, encouraging adding ugly boilerplate code.  (This may only 
> be tangentially relevant, but I want to scream when I see some 
> combination of public/private/protected/static/extern etc., most of 
> which I don't understand.)

Perhaps if you understood it you would be less inclined to scream.


> Chris A makes the valid point (if I understand correctly) that
>     Authors of libraries should make it as easy as possible to
>           (i) know what object types can be passed to functions
>           (ii) diagnose when the wrong type of object is passed
>     Authors of apps are not under such obligation, they can basically 
> do what they want.
> 
> Well,
>     (i) can be done with good documentation (docstrings etc.).
>     (ii) can be done with appropriate runtime checks and good error 
> messages.

How ironic. After singing the praises of duck-typing, now you are 
recommending runtime type checks.

As far as good error messages go, they don't help you one bit when the 
application suddenly falls over in a totally unexpected place due to a 
bug in your code.

I can't go into too many details due to commercial confidentiality, but 
we experienced something similar recently. A situation nobody foresaw, 
that wasn't guarded against, and wasn't tested for, came up after 
deployment. There was a traceback, of course, but a failure in the field 
200km away with a stressed customer and hundreds of angry users is not 
as useful as a compile-time failure during development.


> You see where I'm going with this - adding type hints to Python feels a 
> bit like painting feet on the snake.

Pythons are one of the few snakes which have vestigal legs:

http://en.wikipedia.org/wiki/Pelvic_spur


-- 
Steve


More information about the Python-Dev mailing list