Whats new in Python 3.5?

Python 3.5 was released in the 2nd week of September, 2015 and brought a bunch of useful changes with it. In this article, I'll be discussing some of the enhancements to the language that I found extremely useful in the latest release.

Apart from some of the smaller improvements like CPython optimizations, deprecations and resolution to porting issues, following are some of the major enhancements that directly or indirectly affects the Python developer community,

async and await

Now we have the ability to use async for and async with inside a co-routine function declared with async def. Inside a coroutine function, the new await expression can be used to suspend coroutine execution until the result is available. Any object can be awaited, as long as it implements the __await__() method.

async def read_data(db):
    data = await db.fetch('SELECT ...')

await suspends the execution of read_data coroutine until db.fetch completes and returns the result data.


Python 3.5 provides a new infix operator @ for matrix multiplication. Matrix multiplication is a notably common operation in many fields of mathematics, science, engineering, and the addition of @ allows writing cleaner code.

>>> import numpy

>>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.])

>>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
       [ 0., 1., 0.],
       [ 0., 0., 1.]])

>>> x @ m
array([ 1., 1., 1.])


PEP 448 extends the allowed uses of the * iterable unpacking operator and ** dictionary unpacking operator. It is now possible to use an arbitrary number of unpackings designed to work in the following way,

>>> def fn(a, b, c, d):
...     print(a, b, c, d)

>>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4

>>> [*range(4), 4]
[0, 1, 2, 3, 4]

>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

Type hints

Type hints was perhaps the most talked topic in this year's PyCon '15, after Guide introduced it to the world. And predictably, it increased the anticipation amongst the developer community for all the right reasons.

def greeting(name: str) -> str:
    return 'Hello ' + name


In the latest release, there is a new addition to the directory iteration function, os.scandir(), in the standard library. Additionally, os.walk() is now implemented using scandir, which makes it 3 to 5 times faster on POSIX systems and 7 to 20 times faster on Windows systems. This is largely achieved by greatly reducing the number of calls to os.stat() required to walk a directory tree.

Additionally, scandir returns an iterator, as opposed to returning a list of file names, which improves memory efficiency when iterating over very large directories.

for entry in os.scandir(path):
    if not entry.name.startswith('.') and entry.is_file():

Ofcourse, the entire list of ehancements and improvements is pretty long. Refer the official changelog for the complete list.