
Python 3.5 type hinting in PyCharm 5 - ceronman
http://blog.jetbrains.com/pycharm/2015/11/python-3-5-type-hinting-in-pycharm-5/
======
ghshephard
Pretty impressive that the syntax:

    
    
       def greeting(name: str) -> str:
    

Turns out to be _backwards_ compatible in Python3 before 3.5 (though not
Python2, yet another reason, if you actually needed one, to start new stuff in
Python3)

~~~
jsmeaton
How is it backwards compatible? Was there syntax added to the language in
preparation?

~~~
ghshephard
I have no idea how they managed to find something that didn't throw a syntax
error, yet looked reasonable. Perhaps someone who followed the process will
chime in.

------
themartorana
Recently stumbled upon IntelliJ using the Go plugin package after a Rubyist
friend of mine spoke very highly of RubyMine. I have to say I was incredibly
impressed. I looked at it a couple years ago when I was mostly Python and it
was ok, but it's really stepped up its game - both feature-wise and visually.

The IntelliJ IDE set is really far better than I understood. IMHO.

~~~
mateuszf
The things you could do in Go vs in (Python | Ruby) are actually are results
of difference between static vs dynamic typing. Yeah, static typing requires
more key presses and some thinking, but in the case of tools (navigation,
refactoring) it makes a huge difference. Ruby support would be years ahead of
what it is now if the tools could understand the types in all cases.

------
cdnsteve
I can see this being very useful in teams. Hell, its even useful for a single
developer as a form of future documentation. I generally write code today and
think, when I read this in 6 months and have no memory, how can I help my
future self? For new code bases I'll be adding this.

~~~
pauleveritt
I'm the author of the article. When I gave a preview of this at the PyRVA
meetup, I gave this exact illustration, even using "my future self".
So...jinx. :)

~~~
cdnsteve
haha maybe we're twins!

------
thomasahle
I wonder why, given they call it 'type hints', they didn't go for Haskell-like
type comments:

    
    
        #greeting :: (str, int) -> str
        def greeting(name, age):
    

In fact, I wonder why more languages don't adopt this syntax, since it greatly
simplifies functions with very large types.

~~~
p4wnc6
I love Haskell, but I'm not sure this would actually be better for Python. To
be Haskell-like, the comment would actually be different than what you wrote:

#greeting :: str -> int -> str

and this is specifically related to the functional nature of Haskell.
`greeting "hello"` now instantly becomes a _function_ with type :: int -> str.
So the Haskell syntax is about currying, it's about how the function you wrote
is really just a cascade of functions.

Doing something silly like making the "arguments" reside in an artificial
tuple would definitely be bad practice in most Haskell cases, and so
syntactically looks a bit weird and out of place, like it's shoehorned on just
because Python function arguments are not like Haskell arguments.

Since Python is not based on this model of a function, I think it's a lot
better to keep the syntax in the actual def statement. Adding the return type
annotation at the end is nice.

Most probably, this stuff was added to the signature because there were
already natural tools like the inspect library that would provide the
immediate hooks for making use of it. But even if the implementation didn't
need it to be part of the signature like that, I still think it's better for
Python's paradigm.

~~~
thomasahle
I don't think this is a case of shoehorning anything. It is true that in
Haskell you use currying more often, while in Python you usually supply a
tuple with all the arguments at once.

However there are also cases in Python where you get currying, like
decorators. And for complicated types like:

    
    
        # greeting :: (str -> (str, str), int -> List[str]) -> Dict[str, int -> int]
    

being able to separate the signature from the declaration certainly makes
reading it easier.

~~~
p4wnc6
But in Python, to do currying, you either use decorators, functools.partial,
or forced early binding (like nested function factories), etc. Just because
currying is a thing you can do in the language (in a much different way than
in Haskell where it is fundamental to every function) doesn't seem like a good
reason to me to adopt Haskell-like type signatures.

Just for example, in Python it's extremely common to use default arguments,
and in fact a lot of stuff in the typing module exists to make it easier to do
something like make an Optional type that can either be `None` or a `str` or
something. So whatever type signature you're going to mimic from Haskell, you
won't be able to give optional types or default arguments without making it
totally un-Haskell. And of course no one is going to go off and change Python
to work based on Haskell-like type classes (nor should they).

------
zurn
There's quite some dissonance between the artificial "generics" vs normal
types. Why the concrete str type for strings, but not for lists? I realize
there are implementation level arguments for it, but the resulting compromise
does not seem good.

And specifying the concrete str type goes diametrically against the "don't
check against a concrete type, embrace duck typing" mantra that Python
programmers are taught early.

~~~
arnsholt
Probably because Python doesn't distinguish characters and strings. When you
index into a string, you get a string back (that happens to be length one, of
course), which means that a string is a list of strings. Thus, exploding
string into a list type isn't really possible as the type of `str` is
something like `List[str]`, which doesn't make a whole lot of sense.

------
2bitencryption
something that's always had me a bit confused:

the type hinting in Python is just that -- _hinting,_ right?

It's for IDEs like PyCharm to use to generate better docs and to be more
intelligent about suggestions when writing code. But what it does NOT do is
inform the interpreter/compiler about type information, correct?

I.e., Python3 code with perfectly implemented type hints would only make it
easier on the developer, and not the interpreter/compiler, yeah?

~~~
rplnt
Oh, I was somehow hoping this would allow you to have multiple function
signatures. i.e. two functions foo, both accepting one variable named bar, but
one would implement str and one int, for example.

~~~
zsiciarz
You can have that since 3.4, thanks to PEP 443
([https://www.python.org/dev/peps/pep-0443/](https://www.python.org/dev/peps/pep-0443/)).
Here's a (slightly contrived) example:
[https://gist.github.com/zsiciarz/e15199d9be1b0e07faf6](https://gist.github.com/zsiciarz/e15199d9be1b0e07faf6)

------
Animats
"Type hinting" without checking is kind of lame. If you're going to have
declarations such as

    
    
        def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
    

people are going to get them wrong some of the time. Dumping the checking
problem on some IDE, with a very vague specification of what an error is, is
not progress. If functions have type specifications, you should not be able to
call them with the wrong type, ever. This is the job of the compiler and the
run time system, not the IDE.

Somebody should stop Python's little tin god before he creates another giant
step backwards like the Python 2 to 3 mess.

~~~
StavrosK
So just run the compiler and runtime type checker, what's the problem?

~~~
pjmlp
Usually optional tooling tends to be ignored.

For example, C would have been a much safer language if lint was part of the
compiler, instead of being optional.

~~~
StavrosK
Sure, but how is that "another 2 to 3 mess"? If anything, the backwards-
incompatible changes made the language more robust.

~~~
pjmlp
I was replying to the issue that this being two separate tools:

"This is the job of the compiler and the run time system, not the IDE."

Making this optional will mean the majority won't bother to run the checker.

How many do bother to run lint, jslint, core.typed or dialyzer?

~~~
anentropic
that doesn't make sense? Who would go to the effort of adding type hints and
then not run the checker?

~~~
pjmlp
Just spend some months working in enterprise environments....

------
douche
I have fond memories of using Python 8-10 years ago, but looking at it today,
I'm not sure I see compelling reasons not to just use C# instead.

I can have real static typing if I want it. I can also have dynamic typing if
I want that. I can use lambda functions. I have LINQ. I can use ScriptCS or
some of the new Roslyn stuff if I want to use it as a scripting language. Unix
support is not as great, but they are coming along with that. There's no GIL.

Is there some killer feature for Python that I'm overlooking?

~~~
vpkaihla
Compared to C#, it doesn't require you to run Windows in production.

~~~
adenadel
C# doesn't require you to run Windows in production, even before .NET was
open-sourced. Mono works well for a lot of use cases.

~~~
Sammi
Mono performance was at least an order of magnitude worse than MS .Net. At
least before the open sourcing of .Net.

------
mark_l_watson
I like this. I use Ruby as a scripting language more often than Python and I
would be happy to see similar additions to Ruby to improve code readability
and IDE support (although RubyMine) does an awesome job of warning of possible
code problems just using code inspection).

I sometimes wish that one programming language would work for all of my
requirements but I keep needing: scripting languages for quickly getting stuff
done; practical languages like Clojure and Java, and type strict languages
like Haskell (that I would like to use more, but development takes longer).

Looking ahead a few years, the ideal for me would be a loose scripting
language that had awesome static analysis tools. So, for example, I would get
the safety of Haskell when hacking in Ruby.

------
pixelmonkey
It's cool that PyCharm added support for this -- the point of the typing
module and the type hinting PEP is for IDEs to adopt it for linting purposes.

For those of you using vim, emacs, and the standard UNIX editing toolchain,
the mypy linter provides command-line support. This blog post from April 2015
describes the first version of mypy that includes support for the official
typing library.

[http://mypy-lang.blogspot.co.uk/2015/04/mypy-02-released.htm...](http://mypy-
lang.blogspot.co.uk/2015/04/mypy-02-released.html)

------
graffitici
So how do we get some of these benefits if we don't use PyCharm, but use Vim?
Are there standalone tools, or VIM plugins?

~~~
bitdivision
If you can deal with a different file navigation setup (and outside a terminal
obviously), VIM emulation in PyCharm is very good.

Having recently switched, PyCharm really does make larger projects a lot
easier to refactor / manage.

Edit: Also, to actually answer your question, this is a relatively new feature
so I don't think any of the VIM plugins support it yet. Jedi has had type
hinting from doc strings for some time now. I'd imagine they'll update that to
use this soon.

------
eccstartup
Can this be fixed?

[http://stackoverflow.com/questions/25588642/pycharm-false-
sy...](http://stackoverflow.com/questions/25588642/pycharm-false-syntax-error-
using-turtle)

------
Klasiaster
Has someone tried GNOME Builder? I found it quite good for C, but the Python
mode of PyCharm is still superior regarding search and introspection, yet it
is not Free Software…

------
ZLeviathan
Finally! without the additional type information, it's almost impossible to do
any meaningful refactoring...

