[Python-Dev] Please reject or postpone PEP 526

Steven D'Aprano steve at pearwood.info
Sun Sep 4 08:43:59 EDT 2016


On Sun, Sep 04, 2016 at 12:30:18PM +0100, Mark Shannon wrote:

> It would be a real shame if PEP 526 mandates against checkers doing as 
> good as job as possible. Forcing all uses of a variable to have the same 
> type is a major and, IMO crippling, limitation.

This is approaching FUD.

Guido has already stated that the section of the PEP which implied that 
*any* change of type of a variable would be a warning (not an error) is 
too strong:

https://mail.python.org/pipermail/python-dev/2016-September/146064.html

and indeed the relevant section of the PEP has already been changed:

    Duplicate type annotations will be ignored. However, static type 
    checkers may issue a warning for annotations of the same variable 
    by a different type:

    a: int
    a: str  # Static type checker may or may not warn about this.


This PEP does not mandate any behaviour for type-checkers. It describes 
the syntax for type annotations in Python code. What type-checkers do 
with that information is up to them.



> E.g.
> def foo(x:Optional[int])->int:
>     if x is None:
>        return -1
>     return x + 1
> 
> If the type of the *variable* 'x' is Optional[int] then 'return x + 1' 
> doesn't type check.

That makes no sense. Why wouldn't it type check?

It may be that some simple-minded type-checkers are incapable of 
checking that code because it is too complex. If so, that's a limitation 
of that specific checker, not of type-checkers in general. MyPy already 
can type-check that code. See below.


> If the type of the *parameter* 'x' is Optional[int] 
> then a checker can readily verify the above code.

This makes even less sense, since the parameter "x" is, of course, 
precisely the same as the variable "x".

Here's MyPy in action, successfully checking code that you state can't 
be checked:

[steve at ando ~]$ cat test.py
from typing import Optional

def foo(x:Optional[int])->int:
    if x is None:
        return -1
    return x + 1

def bar(x:Optional[int])->int:
    y = x  # the type of y must be inferred
    if y is None:
        return y + 1
    return len(y)

[steve at ando ~]$ mypy --strict-optional test.py
test.py: note: In function "bar":
test.py:11: error: Unsupported operand types for + (None and "int")
test.py:12: error: Argument 1 to "len" has incompatible type "int"; expected "Sized"


foo passes the type check; bar fails.


> I want a checker to check my code and, with minimal annotations, give me 
> confidence that my code is correct.

Don't we all.



-- 
Steve


More information about the Python-Dev mailing list