[Python-ideas] Trial balloon: adding variable type declarations in support of PEP 484

Gregory P. Smith greg at krypto.org
Mon Aug 1 19:39:50 EDT 2016


On Mon, Aug 1, 2016 at 2:32 PM Guido van Rossum <guido at python.org> wrote:

> PEP 484 doesn't change Python's syntax. Therefore it has no good
> syntax to offer for declaring the type of variables, and instead you
> have to write e.g.
>
> a = 0  # type: float
> b = []  # type: List[int]
> c = None  # type: Optional[str]
>
> I'd like to address this in the future, and I think the most elegant
> syntax would be to let you write these as follows:
>
> a: float = 0
> b: List[int] = []
> c: Optional[str] = None
>
> (I've considered a 'var' keyword in the past, but there just are too
> many variables named 'var' in my code. :-)
>
>
My first impression of this given the trivial int and str examples is...
Why are you declaring types for things that are plainly obvious?  I guess
that's a way of saying pick better examples. :)  Ones where the types
aren't implied by obvious literals on the RHS.

Your examples using complex types such as List[int] and Optional[str] are
already good ones as that can't be immediately inferred.

b: str = module.something(a)

is a better example as without knowledge of module.something we cannot
immediately infer the type and thus the type declaration might be
considered useful to prevent bugs rather than annoying read and keep up to
date.

I predict it will be more useful for people to declare abstract
interface-like types rather than concrete ones such as int or str anyways.
 (duck typing ftw)  But my predictions shouldn't be taken too seriously.  I
want to see what happens.


> There are some corner cases to consider. First, to declare a
> variable's type without giving it an initial value, we can write this:
>
> a: float
>

I don't like this at all.  We only allow pre-declaration without an
assignment using keywords today.  the 'local' suggestion others have
mentioned is worth consideration but I worry any time we add a keyword as
that breaks a lot of existing code.  Cython uses 'cdef' for this but we
obviously don't want that as it implies much more and isn't obvious outside
of the cython context.

You could potentially reuse the 'def' keyword for this.

def a: List[float].

This would be a surprising new syntax for many who are used to searching
code for r'^\s*def' to find function definitions.  Precedent: Cython
already overloads its own 'cdef' concept for both variable and
function/method use.

Potential alternative to the above def (ab)use:

def a -> List[float]
def a List[float]
def List[float] a  # copies the Cython ordering which seems to derive from
C syntax for obvious reasons

But the -> token really implies return value while the : token already
implies variable type annotation.  At first glance I'm not happy with these
but arguments could be made.

Second, when these occur in a class body, they can define either class
> variables or instance variables. Do we need to be able to specify
> which?
>
> Third, there's an annoying thing with tuples/commas here. On the one
> hand, in a function declaration, we may see (a: int = 0, b: str = '').
> On the other hand, in an assignment, we may see
>
> a, b = 0, ''
>
> Suppose we wanted to add types to the latter. Would we write this as
>
> a, b: int, str = 0, ''
>
> or as
>
> a: int, b: str = 0, ''
>
> ??? Personally I think neither is acceptable, and we should just write it
> as
>
> a: int = 0
> b: str = ''
>

Disallowing ": type" syntax in the presence of tuple assignment seems
simple and wise to me. Easy to parse. But I understand if people disagree
and want a defined way to do it.

but this is a slight step back from
>
> a, b = 0, ''   # type: (int, str)
>
> --
> --Guido van Rossum (python.org/~guido)
>

When thinking about how to spell this out in a PEP, it is worth taking into
account existing ways of declaring types on variables in Python. Cython
took the "Keyword Type Name" approach with "cdef double j" syntax.
http://cython.readthedocs.io/en/latest/src/quickstart/cythonize.html

Is it an error to write the following (poor style) code declaring a type
for the same variable multiple times:

c: int = module.count_things(x)
compute_thing(c)
if c > 3:
  c: str = module.get_thing(3)
  logging.info('end of thing 3: %s', c[-5:])
do_something(c)

where c takes on multiple types within a single scope? static single
assignment form would generate a c', c'', and union of c' and c'' types for
the final do_something call to reason about that code.  but it is entirely
doable in Python and does happen in unfortunately real world messy code as
variables are reused in bad ways.

My preference would be to make it an error for more than one type to be
declared for the same variable.
First type ever mentioned within the scope wins and all others are
SyntaxError worthy.
Assigning to a variable in a scope before an assignment that declares its
type should probably also be a SyntaxError.

-gps
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160801/600ddbd5/attachment.html>


More information about the Python-ideas mailing list