Why upgrade to Python 3.7?

2 minute read

Python 3.7 adds performance to common operations, and adds user-visible changes in the following categories. Feature freeze is end of January 2018, and release anticipated June 2018. What do you think about the ordering shown here, and did I miss a feature? Let me know in comments below.

Data Classes

The boilerplate copy-paste required for Python classes can seem inelegant. Python 3.7 data class eliminates the boilerplate code in initializing classes. The @dataclass decorator enables this template.

class Rover:
    '''Class for robotic rover.'''
    name: str
    uid: int
    battery_charge: float=0.
    temperature: float

    def check_battery_voltage(self) -> float:
        return self.aioread(port35) / 256 * 4.1


The new breakpoint() function abstracts away pdb.set_trace(), and allows other debuggers to be used.



z = x/y

breakpoint() just looks pretty and is immediately clear as to its purpose. Bravo!


It’s very common to have more than one version of Python installed. Likewise, multiple versions of the same library may be installed, overriding other versions. For example, system Numpy may be overridden with a pip installed Numpy.

From Python 3.7, we get the absolute path and filename from which the ImportError was generated.

  • Python ≤ 3.6
    from numpy import blah

    ImportError: cannot import name ‘blah’

  • Python ≥ 3.7
    from numpy import blah

    ImportError: cannot import name ‘blah’ from ‘numpy’ (c:\Python37\Lib\site-packages\numpy__init__.py)


The popular and efficient argparse module can now handle intermixed positional and optional arguments, just like the shell.

from argparse import ArgumentParser
p = ArgumentParser()
p = p.parse_intermixed_args()   # instead of p.parse_args()

python myprogram.py my.xml 26 --plottype inv 2 3

Namespace(indices=[26,2,3], plottype=’inv’, xmlfm=’my.xml’)

whereas if you have used p.parse_args() you would have gotten

error: unrecognized arguments: 2 3

Note: optparse was deprecated in 2011 and is no longer maintained. It’s past time to upgrade to argparse.

Robust “import as”

This is termed circular import, which technically it is. It eliminated further annoyance with imports that were partially cleared up in Python 3.5, namely Python ≥ 3.7 can now do

import a.b as c

instead of Python ≤ 3.6 needing

from a import b as c

which is less clear and inelegant. The discussion makes the details clear for those who are really interested in Python import behavior.


dis.dis() can now reach more deeply inside Python code, adding a depth parameter useful for recursive functions, and elements including:

  • list comprehension: x2 = [x**2 for x in X] (greedy eval)
  • generator expressions: x2 = (x**2 for x in X) (lazy eval)


Case-insensitive regex sped up by as much as 20x.

Windows subprocess

Python 3.7 adds constants that allow controlling subprocess priority in Windows. This allows keeping the main Python program at one execution priority , while launching subprocesses at another priority.

The ability to start subprocesses without opening a new console window is enabled by subprocess.CREATE_NO_WINDOW.

The confusingly named but important universal_newlines boolean parameter is now named text. When text=True, stdin/stderr/stdout will emit/receive text stream instead of bytes stream.



Leave a Comment