What's new in Python 3.3

Ezio Melotti

Something about me

The best Python ever

I am incredibly proud of you all for producing such a great release. As the marketeers would say, "Python 3.3 is the best Python ever!"
The feature list is amazing.

Guido van Rossum

Outline

New PEPs implemented

This slide intentionally left blank

New PEPs implemented

New PEPs implemented

PEP 393: Flexible String Representation

Before the PEP (Python 2.x, 3.0, 3.1, 3.2):

Two Python builds: narrow and wide

PEP 393: Flexible String Representation

After the PEP (Python 3.3, 3.4, ...):

No more distinctions between narrow and wide

PEP 393: Flexible String Representation

PEP written by Martin von Löwis;
implemented by Torsten Becker and Martin von Löwis

PEP 397: Python Launcher for Windows

PEP 397: Python Launcher for Windows

Examples:

PEP 397: Python Launcher for Windows

PEP written by Mark Hammond and Martin v. Löwis;
implemented by Vinay Sajip.

PEP 405: Virtual Environments

PEP written by Carl Meyer;
implemented by Carl Meyer and Vinay Sajip.

PEP 405: Virtual Environments

Usage example:

3.3$ python -m venv venvtest
3.3$ cd venvtest/
3.3/venvtest$ tree
.
├── bin
│   ├── activate
│   ├── pydoc
│   ├── python -> /path/to/3.3/python
│   └── python3 -> python
├── include
├── lib
│   └── python3.3
│       └── site-packages
└── pyvenv.cfg
5 directories, 5 files

PEP 405: Virtual Environments

3.3/venvtest$ cat pyvenv.cfg
home = /path/to/3.3
include-system-site-packages = false
version = 3.3.0
3.3/venvtest$ python -c 'import sys; print(sys.executable)'
/usr/bin/python
3.3/venvtest$ source bin/activate
(venvtest) 3.3/venvtest$
(venvtest) 3.3/venvtest$ python -c 'import sys; print(sys.executable)'
/path/to/3.3/venvtest/bin/python
(venvtest) 3.3/venvtest$ deactivate
3.3/venvtest$

PEP 420: Implicit Namespace Packages

PEP written by Eric V. Smith;
implementation by Eric V. Smith.

PEP 380: Syntax for Delegating to a Subgenerator

PEP written by Greg Ewing;
implementation by Greg Ewing et al.

PEP 409: Suppressing exception context

PEP written by Ethan Furman;
implementation by Ethan Furman and Nick Coghlan

PEP 409: Suppressing exception context

Without context suppression:

>>> try:
...     5/0
... except ZeroDivisionError:
...     raise RuntimeError("You can't divide by zero!")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: You can't divide by zero!

PEP 409: Suppressing exception context

With context suppression:

>>> try:
...     5/0
... except ZeroDivisionError:
...     raise RuntimeError("You can't divide by zero!") from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: You can't divide by zero!

PEP 3151: Reworking the OS and IO exception hierarchy

PEP 3151: Reworking the OS and IO exception hierarchy

Before PEP 3151:

from errno import ENOENT, EACCES, EPERM

try:
    with open("document.txt") as f:
        content = f.read()
except IOError as err:
    if err.errno == ENOENT:
        print("document.txt file is missing")
    elif err.errno in (EACCES, EPERM):
        print("You are not allowed to read document.txt")
    else:
        raise

PEP 3151: Reworking the OS and IO exception hierarchy

After PEP 3151:

try:
    with open("document.txt") as f:
        content = f.read()
except FileNotFoundError:
    print("document.txt file is missing")
except PermissionError:
    print("You are not allowed to read document.txt")

PEP written by Antoine Pitrou;
implementation by Antoine Pitrou

PEP 3155: Qualified name for classes and functions

PEP written by Antoine Pitrou;
implementation by Antoine Pitrou

PEP 3155: Qualified name for classes and functions

>>> class Foo:
...     def meth(self): pass
...     class Bar:
...         def meth(self):
...             def func(): pass
...             return func
...
>>> Foo.__name__, Foo.__qualname__
('Foo', 'Foo')
>>> Foo.meth.__name__, Foo.meth.__qualname__
('meth', 'Foo.meth')
>>> Foo.Bar.__name__, Foo.Bar.__qualname__
('Bar', 'Foo.Bar')
>>> Foo.Bar.meth.__name__, Foo.Bar.meth.__qualname__
('meth', 'Foo.Bar.meth')
>>> Foo.Bar().meth().__name__, Foo.Bar().meth().__qualname__
('func', 'Foo.Bar.meth.<locals>.func')

PEP 412: Key-Sharing Dictionary

PEP written by Mark Shannon;
implementation by Mark Shannon

PEP 362: Function Signature Object

PEP written by Brett Cannon, Yury Selivanov, Larry Hastings, Jiwon Seo;
implementation by Yury Selivanov

PEP 362: Function Signature Object

>>> def foo(a, *, b, c=None): pass
...
>>> sig = inspect.signature(foo)
>>> str(sig)
'(a, *, b, c=None)'
>>> print(sig.parameters)
OrderedDict([('a', <Parameter at 0xb736a474 'a'>),
             ('b', <Parameter at 0xb73c9574 'b'>),
             ('c', <Parameter at 0xb73c95b4 'c'>)])
>>> for p in sig.parameters.values():
...     print(p.name, p.kind, p.default)
...
a POSITIONAL_OR_KEYWORD <class 'inspect._empty'>
b KEYWORD_ONLY <class 'inspect._empty'>
c KEYWORD_ONLY None

PEP 421: Adding sys.implementation

>>> sys.implementation
namespace(cache_tag='cpython-33', hexversion=50528496, name='cpython',
          version=sys.version_info(major=3, minor=3, micro=0,
                                   releaselevel='final', serial=0))

PEP 421: Adding sys.implementation

>>> ns = types.SimpleNamespace(foo=15, bar=42)
>>> ns
namespace(bar=42, foo=15)
>>> ns.foo, ns.bar
(15, 42)
>>> ns.foo = 9000
>>> ns
namespace(bar=42, foo=9000)

PEP written by Eric Snow;
implementation by Eric Snow

PEP 414: Explicit Unicode literals

PEP written by Armin Ronacher.

New modules

This slide intentionally left blank

New modules

faulthandler

faulthandler

Without faulthandler:

>>> import ctypes
>>> ctypes.string_at(0)
Segmentation fault (core dumped)

With faulthandler:

>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault

Current thread 0xb77c76c0:
  File "/path/to/3.3/Lib/ctypes/__init__.py", line 497 in string_at
  File "<stdin>", line 1 in <module>
Segmentation fault (core dumped)

ipaddress

ipaddress

address example:

>>> ipaddr = ip_address('127.0.0.1')
>>> ipaddr
IPv4Address('127.0.0.1')
>>> ipaddr.is_loopback
True
>>> print(str(ipaddr), int(ipaddr))
127.0.0.1 2130706433
>>> next_ipaddr = ipaddr + 1
>>> next_ipaddr
IPv4Address('127.0.0.2')
>>> ipaddr < next_ipaddr
True

ipaddress

network example:

>>> ipnet = ip_network('192.168.1.0/24')
>>> ipnet
IPv4Network('192.168.1.0/24')
>>> list(ipaddr.hosts())
[IPv4Address('192.168.1.1'), IPv4Address('192.168.1.2'), ...,
 IPv4Address('192.168.1.253'), IPv4Address('192.168.1.254')]
>>> list(ipnet.subnets())
[IPv4Network('192.168.1.0/25'), IPv4Network('192.168.1.128/25')]
>>> ipnet.supernet()
IPv4Network('192.168.0.0/23')
>>> ipnet[10]
IPv4Address('192.168.1.10')
>>> ipnet[10] in ipnet
True

lzma

Reading example:

>>> with lzma.open("file.xz") as f:
...     file_content = f.read()

Writing example:

>>> with lzma.open("file.xz", "w") as f:
...     f.write(b"data to be compressed")

unittest.mock

unittest.mock

Mock example:

>>> from unittest.mock import MagicMock
>>> thing = ProductionClass()
>>> thing.method = MagicMock(return_value=3)
>>> thing.method(3, 4, 5, key='value')
3
>>> thing.method.assert_called_with(3, 4, 5, key='value')
>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
 ...
KeyError: 'foo'

unittest.mock

patch example:

>>> def func():
...     sys.exit('farewell')
...
>>> @patch('sys.exit')
... def test(mock_exit):
...     func()
...     mock_exit.assert_called_once_with('farewell')
...
>>> test()
>>>

Language and module improvements

This slide intentionally left blank

Language and module improvements

Language and module improvements

Language and module improvements

Language and module improvements

Language and module improvements

Language and module improvements

The End

Questions?