EuroPython 2018: What's new in Python 3.7

Stephane Wirtel is a contributor to CPython and a member of the EuroPython team.

PEP 553: breakpoint()

As opposed to JavaScript, we don't have a debugger keyword. And we have a lot of debuggers: pdb, ipdb, pudb, pdbpp, … Up until now, you had to explicitly import the right debugger, like import pdb; pdb.set_trace().

Now you can now use PYTHONBREAKPOING=IPython.embed or PYTHONBREAKPOING=pudb.set_trace to choose your debugger. Bonus feature: you can also use PYTHONBREAKPOING=0 to disable debugging entirely.

PEP 557: Data classes

We already have namedtuple, but we can't assign values to a dotted attribute of a namedtuple. If we want that, we can use simple classes with just an __init__ initialiser, a __str__ representation, __eq__ for equality, and __lt__ for comparison.

Instead, we can now use the much shorter data classes:

from dataclasses import dataclass

@dataclass
class Person:
   firstname: str
   lastname: str
   post_code: int = 11111

We get default values, comparison, properties, methods, and inheritance. The dataclass decorator also has some options:

  • init=True: create __init__ method.
  • repr=True: create __repr__ method.
  • eq=True: create __eq__ method.
  • order=False: create __gt__, __lt__, __ge__, and __le__.
  • unsafe_hash=False: If False (default), generate a __hash__ method based on eq and frozen.
  • frozen=False: If True, generates exceptions when fields are tried to be changed.

PEP 562: Module __getattr__ and __dir__

The __getattr__ method of a module can be used to issue deprecation warnings. The __dir__ method can be used to override the list of accessible properties.

PEP 563: Postponed Evaluation of Annotations

With delayed evaluation of type annotations, we can now use self referential method signatures on classes. This was badly missing. Use from __future__ import annotations.

PEP 564: Time functions with nanosecond resolution

The time.time() function returns the current time as a floating-point numer. This is limited to 64 bits and is in IEEE 754 format, which limits it to losing nanoseconds after 104 days. Now we have time.clock_gettime_ns, time.time_ns, time.monotonic_ns etc.

PEP 565: Show DeprecationWarning in main()

DeprecationWarnings are once more shown by default, but only when the code triggering them is running directly in the main module. As a result, developers of single file scripts and those using Python interactively should once again start seeing deprecation warnings for the APIs they use, but deprecation warnings triggered by imported application, library and framework modules will continue to be hidden by default.

That also means that DeprecationWarning and PendingDeprecatinWarning can now be more meaninfully used.

PEP 567: Context Variables

Keep track of values of variables per asynchronous task. Access contextvars and Context and ContextVar.

foo = contextvars.ContextVar('foo', default=None)

PEP 540: Python documentation translations

We have documentation in English, French, Japanese, and Korean.

Not in PEPs

  • async and await are now keywords.
  • asyncio.run() replaces the combination of get_event_loop, run_until_compete, and close
  • asyncio.create_task is new
  • loop.start_tls(): upgrade to TLS
  • asyncio.current_task returns the current task
  • asyncio.all_tasks does exactly that
  • asyncio.get_event_loop is 15 times faster (C implementation)
  • python -X importtime profiles import times
  • PYTHONUTF8=1 or -X utf8 will enable UTF8 mode (disabled by default unless locale enables)
  • -X dev enables development mode of asyncio, adds runtime checks, installs debug hooks into memory allocators, etc.
  • importlib.resources allows to load a binary artifact that is shipped within a package (similar to pkg_resources but with better performance and less overhead)
  • Lots of bug fixes
  • Better performance