[Python-ideas] ideas for type hints for variable: beyond comments
Steven D'Aprano
steve at pearwood.info
Tue Sep 1 15:03:54 CEST 2015
On Tue, Sep 01, 2015 at 09:19:29PM +1000, Chris Angelico wrote:
> On Tue, Sep 1, 2015 at 8:24 PM, Ian <ian.team.python at gmail.com> wrote:
> >
> > mypy currently inspects the comment on the line of first assignment for the
> > variables to be type hinted.
> >
> > It is logical that at some time python language will add support to allow
> > these type hints to move from comments to the code as has happened for 'def'
> > signatures.
>
> Potential problem: Function annotations are supported all the way back
> to Python 3.0, but any new syntax would be 3.6+ only. That's going to
> severely limit its value for quite some time. That doesn't mean new
> syntax can't be added (otherwise none ever would), but the bar is that
> much higher - you'll need an extremely compelling justification.
PEP 484 says:
"No first-class syntax support for explicitly marking variables as being
of a specific type is added by this PEP. To help with type inference in
complex cases, a comment of the following format may be used: ..."
https://www.python.org/dev/peps/pep-0484/
I recall that in the discussions prior to the PEP, I got the strong
impression that Guido was open to the concept of annotating variables in
principle, but didn't think it was very important (for the most part,
the type checker should be able to infer the variable type), and he
didn't want to delay the PEP for the sake of agreement on a variable
declaration syntax when a simple comment will do the job.
So in principle, if we agree that type declarations for variables should
look like (let's say) `str s = some_function(arg)` then the syntax may
be added in the future, but it's a low priority.
> > The other question is 'what about globals and nonlocals?'. Currently
> > globals and nonlocals need a 'global' or 'nonlocal' statement to allow
> > assignment, but what if these values are not assigned in scope?
>
> Not sure what you're talking about here. If they're not assigned in
> this scope, then presumably they have the same value they had from
> some other scope.
But they will be assigned in the scope, otherwise there's no need to
declare them global.
def spam(*args):
global eggs
eggs = len(args)
process(something, eggs)
That's a case where the type-checker should be able to infer that eggs
will be an int. But what if the type inference engine cannot work that
out? The developer may choose to add a hint.
eggs = len(args) # type:int
will work according to PEP 484 (although, I guess that's a quality of
implementation issue for the actual type checker). Or we could steal
syntax from some other language and make it "official" that type
checkers have to look at this:
eggs:int # (Pascal, Swift, Ada, F#, Scala)
int eggs # (Java, C, Perl6)
eggs int # (Go)
eggs as int # (RealBasic)
Hence, for example:
global eggs:int
cheese:int, ham:str = 23, "foo"
A big question would be, what runtime effect (if any) would this have?
If the default Python compiler ignored the type hint at both
compile-time and run-time, it would be hard to justify making it syntax.
But perhaps the current namespace could get a magic variable
__annotations__ = {name: hint}
similar to the __annotations__ attribute of functions. Again, the
default compiler would simply record the annotation and ignore it, the
same as for functions, leaving any actual type-checking to third-party
tools.
[...]
> > Use of the 'local' keyword in the global namespace could indicate a value
> > not accessible in other namespaces.
That won't work without a *major* change to Python's design. Currently,
module namespaces are regular dicts, and there is no way to prevent
others from looking up names in that dict/namespace. If you (Ian) want
to change that, you should raise it as a completely separate PEP.
--
Steve
More information about the Python-ideas
mailing list