PEP 526 - var annotations and the spirit of python
steve+comp.lang.python at pearwood.info
Wed Jul 4 22:01:01 EDT 2018
On Wed, 04 Jul 2018 19:57:12 +0100, Bart wrote:
> On 04/07/2018 16:31, Steven D'Aprano wrote:
>> On Wed, 04 Jul 2018 13:48:26 +0100, Bart wrote:
>> Of course the type (whether inferred or annotated) applies for the
>> entire scope of that variable.
> In that case I don't understand what you're complaining about. You say
> that hinting is not needed here:
> x = 3
> because you know x will be int at this point. But what you don't know if
> whether x will keep its int type.
*I* don't know, but that's why I'm running a type-checker.
*The checker* knows, because it does static analysis of the code looking
for mismatches between types (say, trying to add None to an int, or
multiply a string by a dict, or assigning a list to something that ought
to be a float).
>> With type-inference, the type-checker is smart enough to recognise what
>> type a variable is supposed to be (at least sometimes):
>> x = 3; # of course it's an int, what else could it be? x = f(x);
>> and likewise complain if f(x) returns something other than an int.
> Are you still talking about Python here? Python is famous for being
> highly dynamic. So that that second assignment could set x to ANYTHING.
Of course it could. And if that's your intention, as author of the code,
you can simply *not run the type checker*, and the code will run just as
you've written it.
But we know (as so many people keep reminding us) that just because
Python is extremely dynamic, that doesn't necessarily mean that we use it
in extremely dynamic ways. Most of the time, say, 95% of the time, if x
is an int *here*, it is intended to *stay* an int all the way through the
lifetime of that variable.
In those cases, if a later assignment to x sets it to "anything", that
means you have a bug in your code. It might not be an obvious bug, or one
that you spot up front. Testing can only prove the presence of bugs, not
So you'll probably get a bunch of TypeErrors, one at a time, and over a
period of many days or months or years, gradually your users will find
each TypeError in your code, and report the bug, and you'll fix it.
If that works for you, great!
Or... you can run the type-checker, it will perform static analysis of
your code, using whatever type information it can infer or you have
annotated, and spot some (if not all) of those type errors ahead of time,
so you can fix them immediately.
If that doesn't work for you, that's cool too. That's why these are
optional type hints not mandatory type declarations.
> I though the point of the type hint was to say that x has a particular
> type and it always keeps that same type. That way it is possible to make
> some assumptions about it.
> Otherwise, what's the point?
There wouldn't be one.
> I understand that type hinting doesn't enforce anything, such as
> checking that anything assigned to x is actually an int. Although that
> wouldn't be hard to do: just implement every x = y as x = int(y) or
> better, x = intcheck(y).
No, that would needlessly slow down the runtime. First off, it would be
x = int(2)
is just a waste of a function call. Secondly, it would be *wrong*:
x = f(x)
is supposed to return an int, but is buggy and return a string, which by
some ill chance happens to be "12345" which int() will happily convert.
And thirdly, failures will still be *runtime failures*, just as they
already are. So even when you catch the error, you aren't catching them
ahead of time.
Python already does runtime type checking. Every time you get a TypeError
or AttributeError, that's a form of runtime type checking. The point of
static type checking is to do some of the work ahead of time, and detect
type errors before you run the code.
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson
More information about the Python-list