Python 3 has been mocked for a pretty long time for not having any big-ticket features. For the first four minor releases for Python 3 (3.1 to 3.4), this did not change. There are two features that are worth noting in Python 3.5. One being the type checker/hints. The other being the async/await key words coming to Python 3.5. Question is, how relevant?
This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and performance optimizations utilizing type information.
Python now has a type checker. This does not mean that python is going to magically become a statically typed language. In other words, the type checker is merely a tool for a better development experience. For example, if your IDE/Editor knows what type you're working with, it can provide better code completion. Some IDEs actually provide rudimentary type checking. However, this will standardize the way in which types are declared and that means this will raise the bar for all the python tools available at our disposal.
Other than better tooling, this also means that a type induced runtime errors can be thwarted before they happen, which is something that makes developing large code bases with Python a lot easier. You will hear no end of war stories about how a function that sometimes returned
None deep in the source brought about pyapocalypse. Having type problems deep within your source code, is by no means uncommon.
A friend of mine had to deal with this kind of problem once. The problem was with a function (buried deep in the source code as one of many decorators) that usually returned a
list but under a certain circumstances, it returned
None. This wasn't noted before because most of the time, the result would be checked in a simple
In other words
bool() return the same thing, which is
False. The problem was happening because another branch still thought that the returned value was a
list and so tried to
append to it. As you might expect, the traceback wasn't pretty.
I'm not saying that the person who originally wrote the code is a bad programmer. I'll leave that up to you. What I am saying is that python allows you to make such silly mistakes. This is especially problematic when you're working with really large code-bases.
However, while this is all good in terms of development tools, this does not mean a large boost in performance. PyPy's FAQ talks about this issue and addresses some of the key concerns.  In a nutshell, the performance will not increase simply because python's types are objects and do not correspond directly to how types are represented in binary. For example, python's
int type isn't necessarily a 64-bit number, but has the ability to grow to whatever size you need it to grow.
... annotations are at the wrong level (e.g. a PEP 484 “int” corresponds to Python 3’s int type, which does not necessarily fits inside one machine word; even worse, an “int” annotation allows arbitrary int subclasses).
PyPy FAQ (Would type annotations help PyPy’s performance?)
This proposal makes coroutines a native Python language feature, and clearly separates them from generators. This removes generator/coroutine ambiguity, and makes it possible to reliably define coroutines without reliance on a specific library. This also enables linters and IDEs to improve static code analysis and refactoring.
await are very good ideas. In fact, these two keywords have been an integral part of C# for quite some time now and make programing with tasks much easier. These two key words makes python feel a lot more abstract, whereas turning generators into coroutines (even through the use of a decorator) and then using them like generators feels rather clumsy. In simple terms,
async creates a coroutine for you. For example, the following is a coroutine:
import asyncio import datetime @asyncio.coroutine def display_date(loop): end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break yield from asyncio.sleep(1) loop = asyncio.get_event_loop() # Blocking call which returns when the display_date() coroutine is done loop.run_until_complete(display_date(loop)) loop.close()
The above will turn into the following under PEP-492:
import asyncio import datetime async def display_date(loop): end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(1) loop = asyncio.get_event_loop() # Blocking call which returns when the display_date() coroutine is done loop.run_until_complete(display_date(loop)) loop.close()
However, what is being introduced is syntactic sugar meaning that this does not change python on a fundamental level. For example, introducing these native constructs will not magically make python be able to compete with node (V8).
The new features being added are subtle but will go a long way into making Python 3 the abstract language that it needs to be as well as provide the tooling required to make it a potential choice for huge code-bases. However, this does not mean that Python has become a better choice over other languages such as golang for high performance applications. So, although these new features will definitely persuade people to move from Python 2 to Python 3 (at least for new projects), it does not necessarily mean that more and more people will leave Python seeking abstract yet high performance alternatives.
|||PEP-0484. This type checker is based on the mypy type checker created by one of the authors of PEP-0484, Jukka Lehtosalo.|
|||PEP-0492. This is a pretty radical change since it means Python will get new key words.|
|||PyCharm provides type checking through its skeletons. These are a lot like the stubs that PEP-0484 is proposing.|
|||PyPy's FAQ talks about this issue, and its lack of effect on performance under "Would type annotations help PyPy’s performance?". Look under the "PEP-484 Type Hints" sub section.|