[Python-Dev] Please reject or postpone PEP 526
Mark Shannon
mark at hotpy.org
Fri Sep 2 09:47:00 EDT 2016
Hi everyone,
I think we should reject, or at least postpone PEP 526.
PEP 526 represents a major change to the language, however there are, I
believe, a number of technical flaws with the PEP.
It is probable that with significant revisions it can be a worthwhile
addition to the language, but that cannot happen in time for 3.6 beta 1
(in 11 days).
PEP 526 claims to be an extension of PEP 484, but I don't think that is
entirely correct.
PEP 484 was primarily about defining the semantics of pre-existing
syntax. PEP 526 is about adding new syntax.
Historically the bar for adding new syntax has been set very high. I
don't think that PEP 526, in its current form, reaches that bar.
Below is a list of the issues I have with the PEP as it stands.
In many cases it makes it more effort than type comments
========================================================
Type hints should be as easy to use as possible, and that means pushing
as much work as possible onto the checker, and not burdening the programmer.
Attaching type hints to variables, rather than expressions, reduces the
potential for inference. This makes it harder for programmer, but easier
for the checker, which is the wrong way around.
For example,, given a function:
def spam(x: Optional[List[int]])->None: ...
With type comments, this is intuitively correct and should type check:
def eggs(cond:bool):
if cond:
x = None
else:
x = [] # type: List[int]
spam(x) # Here we can infer the type of x
With PEP 526 we loose the ability to infer types.
def eggs(cond:bool):
if cond:
x = None # Not legal due to type declaration below
else:
x: List[int] = []
spam(x)
So we need to use a more complex type
def eggs(cond:bool):
x: Optional[List[int]]
if cond:
x = None # Now legal
else:
x: = []
spam(x)
I don't think this improves readability.
Whether this is an acceptable change is debatable, but it does need some
debate.
It limits the use of variables
==============================
In Python a name (variable) is just a binding that refers to an object.
A name only exists in a meaningful sense once an object has been
assigned to it. Any attempt to use that name, without an object bound to
it, will result in a NameError.
PEP 526 makes variables more than just bindings, as any rebinding must
conform to the given type. This looses us some of the dynamism for which
we all love Python.
Quoting from the PEP:
```
a: int
a: str # Static type checker will warn about this.
```
In other words, it is illegal for a checker to split up the variable,
even though it is straightforward to do so.
However, without the type declarations,
```
a = 1
a = "Hi"
```
is just fine. Useless, but fine.
We should be free to add extra variables, whenever we choose, for
clarity. For example,
total = foo() - bar()
should not be treated differently from:
revenue = foo()
tax = bar()
total = revenue - tax
If types are inferred, there is no problem.
However, if they must be declared, then the use of meaningfully named
variables is discouraged.
[A note about type-inference:
Type inference is not a universal panacea, but it can make life a lot
easier for programmers in statically type languages.
Languages like C# use local type inference extensively and it means that
many variables often do not need their type declared. We should take
care not to limit the ability of checkers to infer values and types and
make programmers' lives easier.
Within a function, type inference is near perfect, failing only
occasionally for some generic types.
One place where type inference definitely breaks down is across calls,
which is why PEP 484 is necessary.
]
It is premature
===============
There are still plenty of issues to iron out w.r.t. PEP 484 types. I
don't think we should be adding more syntax, until we have a *precise*
idea of what is required.
PEP 484 states:
"If type hinting proves useful in general, a syntax for typing variables
may be provided in a future Python version."
Has it proved useful in general? I don't think it has. Maybe it will in
future, but it hasn't yet.
It seems confused about class attributes and instance attributes
================================================================
The PEP also includes a section of how to define class attributes and
instance attributes. It seems that everything needs to be defined in the
class scope, even it is not an attribute of the class, but of its
instances. This seems confusing, both to human reader and machine analyser.
Example from PEP 526:
class Starship:
captain: str = 'Picard'
damage: int
stats: ClassVar[Dict[str, int]] = {}
def __init__(self, damage: int, captain: str = None):
self.damage = damage
if captain:
self.captain = captain # Else keep the default
With type hints as they currently exist, the same code is shorter and
doesn't contaminate the class namespace with the 'damage' attribute.
class Starship:
captain = 'Picard'
stats = {} # type: Dict[str, int]
def __init__(self, damage: int, captain: str = None):
self.damage = damage # Can infer type as int
if captain:
self.captain = captain # Can infer type as str
This isn't an argument against adding type syntax for attributes in
general, just that the form suggested in PEP 526 doesn't seem to follow
Python semantics.
One could imagine applying minimal PEP 526 style hints, with standard
Python semantics and relying on type inference, as follows:
class Starship:
captain = 'Picard'
stats: Dict[str, int] = {}
def __init__(self, damage: int, captain: str = None):
self.damage = damage
if captain:
self.captain = captain
The PEP overstates the existing use of static typing in Python
==============================================================
Finally, in the rejected proposal section, under "Should we introduce
variable annotations at all?" it states that "Variable annotations have
already been around for almost two years in the form of type comments,
sanctioned by PEP 484."
I don't think that this is entirely true.
PEP 484 was about the syntax for types, declaring parameter and return
types, and declaring custom types to be generic.
PEP 484 does include a description of type comments, but they are always
annotations on assignment statements and were primarily intended for use
in stub files.
Please don't turn Python into some sort of inferior Java.
There is potential in this PEP, but in its current form I think it
should be rejected.
Cheers,
Mark.
More information about the Python-Dev
mailing list