What's new in Python 3.2

  • For Python Users Group, Singapore

  • Senthil Kumaran

Schedule

  • 3.2 beta 1: December 4, 2010. (Feature Freeze)

  • 3.2 final: February 19, 2011 (Release Date)

  • 3.2 Release Manager: Georg Brandl

  • Binaries/Installers: Windows (Martin v. Loewis) and Mac (Ronald Oussoren)

At the moment

$python -q
>>> import sys;sys.version
'3.2rc3+ (py3k:88430M, Feb 17 2011, 14:53:19) \n[GCC 4.4.5]'

Python Language Moratorium

  • Python 3.1 was released on June 27, 2009

  • Disallows changes to syntax, semantics, and built-ins

  • Language Moratorium to allow non-CPython implmentations to catchup.

  • Help ease the adoption of Python 3.x and provide a more stable base.

  • Here are list of issues which would be handled after moratorium. http://goo.gl/CCqDn

Defining a Stable ABI

  • Python Extension modules were required to be rebuilt for each feature release

  • Now, Extension modules can limit themselves to a limited APIs Py_LIMITED_API

  • During the compilation of applications, the preprocessor macro Py_LIMITED_API must be defined.

  • There are list of GLOBALS, Functions available which fall under stable ABI. A definition file is made available.

  • There is a converter module, which C source can use to convert itself to ABI compatible way.

  • http://www.python.org/dev/peps/pep-0384/

import argparse

  • There is an argparse command line parsing module included in stdlib.

  • That makes it 3. getopt,optparse and argparse. It was quite a discussion.

  • argparse will be the future and optparse will slowly be deprecated.

  • Support for positional args, sub-commands, 'required options', pattern for specifying and validating options.

  • argparse has the ability to define subparsers, each with their own argument patterns and help displays:

argparse

::

import argparse

parser = argparse.ArgumentParser(

description = 'Manage servers', # main description for help epilog = 'Tested on Solaris and Linux') # displayed after help

parser.add_argument('action', # argument name

choices = ['deploy', 'start', 'stop'], # three allowed values help = 'action on each target') # help msg

parser.add_argument('targets',

metavar = 'HOSTNAME', # var name used in help msg nargs = '+', # require one or more targets help = 'url for target machines') # help msg explanation

parser.add_argument('-u', '--user', # -u or --user option

required = True, # make it a required argument help = 'login as user')

print(parser.parse_args('-h'.split()))

logging module - Configuration Dictionary.

  • The logging documentation has been augmented by a basic tutorial, an advanced tutorial, and a cookbook of logging recipes.

  • logging.config.dictConfig() - logging configuration with plain Python dictionaries.

with open('conf.json', 'r') as f:
        conf = json.load(f)
logging.config.dictConfig(conf)

from concurrent import futures

  • Code for creating and managing concurrency is being collected in a new top-level namespace, concurrent

  • first package is futures high level interface for managing threads and processes.

  • Inspired by java.utils.concurrent and Future Object.

  • status checks (running or done), timeouts, cancellations, adding callbacks, and access to results or exceptions

concurrent.futures module

The primary offering of the new module is a pair of executor classes
for launching and managing calls. The goal of the executors is to make
it easier to use existing tools for making parallel calls. They save
the effort needed to setup a pool of resources, launch the calls,
create a results queue, add time-out handling, and limit the total
number of threads, processes, or remote procedure calls.

Ideally, each application should share a single executor across
multiple components so that process and thread limits can be centrally
managed. This solves the design challenge that arises when each
component has its own competing strategy for resource management.

Both classes share a common interface with three methods: submit() for
scheduling a callable and returning a Future object; map() for
scheduling many asynchronous calls at a time, and shutdown() for
freeing resources. The class is a context manager and can be used in a
with statement to assure that resources are automatically released when
currently pending futures are done executing.

pyc directories

  • Multiple implementations can refer to their own .pyc files.

  • mymodule.cpython-32.pyc, mymodule.cpython-33.pyc, and mymodule.unladen10.pyc

  • pyc files are now collected in a __pycache__ directory stored under the package directory

  • Imported modules now have a __cached__ attribute which stores the name of the actual file that was imported

  • tag that is unique to each interpreter is accessible from the imp module

ABI version tagged .so

  • shared object files by giving them a common directory and distinct names for each version

  • common directory is “pyshared” and the file names are made distinct by identifying the Python implementation

  • /usr/share/pyshared/foo.cpython-32m.so

WSGI 1.1

  • Well Intentioned Upgrade for WSGI to support Python3.

  • Informational PEP clarifies how bytes/text issues are to be handled by the WGSI protocol

String formatting sub-language

  • Old string formatting had '#' type specifiers. It is included in the format sublanguage for compatiblity.

>>> format(20, '#o')
'0o24'
>>> format(12.34, '#5.0f') # You can have leading space.
'  12.'
>>> format(1,'#%')  # percent operation
'100.000000%'
>>> format(1,'#.0%') # trailing dot.
'100.%'
>>> format(1,'.0%')
'100%'

New string formatting methods

  • str.format_map

  • It can take dictionaries from defaultdict, shelve, ConfigParser, dbm.

>>> import shelve
>>> d = shelve.open('tmp.shl')
>>> 'The {project_name} status is {status} as of {date}'.format_map(d)
'The testing project status is green as of February 15, 2011'

Continued

>>> class PlaceholderDict(dict):
        def __missing__(self, key):
            return '<{}>'.format(key)
>>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())
'Hello <name>, welcome to <location>'

Some environment Variables

  • Warnings are now easier to control using the PYTHONWARNINGS environment variable as an alternative to using -W.

  • ResourceWarning, has been added. It is emitted when potential issues with resource consumption or cleanup are detected.

>>> f = open('foo','w')
>>> del f
__main__:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='foo' mode='w' encoding='UTF-8'>

New methods on range

>>> range(0, 100, 2).count(10)
1
>>> range(0, 100, 2).index(10)
5
>>> range(0, 100, 2)[5]
10
>>> range(0, 100, 2)[0:5]
range(0, 10, 2)
  • Part of an effort to make more objects fully implement the collections.Sequence abstract base class

Unicode handling improvements

  • Python’s import mechanism can now load modules installed in directories with non-ASCII characters in the path name.

stdlib - 1

  • email package, mailcap package, nntplib packages work properly with bytes/text model in Python 3.

  • Throughout stdlib there has been a careful attention to encodings and text versus bytes issues

  • Better support for SSL connections and security certificates in Internet Protocol related modules.

  • More classes now implement a context manager to support convenient and reliable resource clean-up using a with statement.

stdlib improvements -2

  • The xml.etree.ElementTree package and its xml.etree.cElementTree counterpart have been updated to version 1.3.

  • The datetime module has a new type timezone that implements the tzinfo interface by returning a fixed UTC offset and timezone name.

  • Many more ...

functools

  • The functools module includes a new decorator for caching function calls. functools.lru_cache() can save repeated queries to an external resource whenever the results are expected to be the same.

>>> import functools
>>> @functools.lru_cache(maxsize=300)
>>> def get_phone_number(name):
        c = conn.cursor()
        c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
        return c.fetchone()[0]
...
>>> get_phone_number(name)        # cached lookup

functools

  • We have cache stats

>>> get_phone_number.cache_info()
CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
  • OMG! Way to get unwrapped function.

>>> get_phone_number = get_phone_number.__wrapped__    # uncached function

functools

  • functools.total_ordering - rich comparison methods, a new decorator functools.total_ordering() will use a existing equality and inequality methods to fill in the remaining methods.

@total_ordering
class Student:
    def __eq__(self, other):
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
  • Magic happens.

itertools

>>> from itertools import accumulate
>>> list(accumulate([8, 2, 50]))
[8, 10, 60]

collections

collections

>>> tally = Counter(dogs=5, cat=3)
>>> tally -= Counter(dogs=2, cats=8)    # saturating subtraction
>>> tally
Counter({'dogs': 3})

>>> tally = Counter(dogs=5, cats=3)
>>> tally.subtract(dogs=2, cats=8)      # regular subtraction
>>> tally
Counter({'dogs': 3, 'cats': -5})

threading

  • The threading module has a new Barrier synchronization class for making multiple threads wait until all of them have reached a common barrier point.

from threading import Barrier, Thread

def get_votes(site):
    ballots = conduct_election(site)
    all_polls_closed.wait()        # do not count until all polls are closed
    totals = summarize(ballots)
    publish(site, totals)

all_polls_closed = Barrier(len(sites))
for site in sites:
    Thread(target=get_votes, args=(site,)).start()

ast module

  • The ast.literal_eval() function serves as a secure alternative to the builtin eval() function which is easily abused.

>>> from ast import literal_eval
>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}

>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
  ...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>

unicode - os module

  • The os module provides two new functions, fsencode() and fsdecode(), for encoding and decoding filenames based on file-system encoding.

unittest

  • improvements supporting test discovery for packages, easier experimentation at the interactive prompt

::

python -m unittest discover -s my_proj_dir -p _test.py

  • Interactivity!

>>> TestCase().assertEqual(pow(2, 3), 8)

urllib

  • The urlparse() function now supports IPv6 addresses as described in RFC 2732:

  • urlopen can take POST which can be an iterable.

  • http.client.HTTPSConnection, urllib.request.HTTPSHandler and urllib.request.urlopen() now take optional arguments to allow for server certificate checking against a set of Certificate Authorities, as recommended in public uses of HTTPS.

There is more

print('{0} {1}'.format('Thank',' you!'))

py32 singapore user group

By Senthil Kumaran

py32 singapore user group

Python User Group Singapore presentation. What's new in Python 3.2

  • 1,150