Overview

Python 3.2, released on February 20, 2011, is a feature-rich release. It introduces argparse to replace optparse, the concurrent.futures module to simplify parallel programming, and defines a stable ABI for C extensions.

This version also marks the arrival of functools.lru_cache, a caching decorator that would quickly become indispensable. With these additions, Python 3.2 establishes itself as a mature release of the 3.x branch.

Major Features

argparse

The argparse module replaces optparse for command-line argument processing. It supports subcommands, type validation, mutually exclusive arguments, and automatic help generation.

python
import argparse

def create_parser():
    """Create a CLI tool for file management."""
    parser = argparse.ArgumentParser(
        description="CSV data processing tool"
    )

    # Required positional argument
    parser.add_argument("file", help="Path to the CSV file")

    # Options with types and default values
    parser.add_argument(
        "-d", "--delimiter",
        default=",",
        help="Column delimiter (default: comma)"
    )
    parser.add_argument(
        "-n", "--num-lines",
        type=int,
        default=10,
        help="Number of lines to display"
    )

    # Subcommands
    subparsers = parser.add_subparsers(dest="command")

    # 'summarize' subcommand
    sp_summarize = subparsers.add_parser("summarize", help="Show a summary")
    sp_summarize.add_argument(
        "--columns",
        nargs="+",
        help="Columns to include in the summary"
    )

    # 'convert' subcommand
    sp_convert = subparsers.add_parser("convert", help="Convert the format")
    sp_convert.add_argument(
        "--format",
        choices=["json", "xml", "yaml"],
        required=True,
        help="Output format"
    )

    return parser

# Usage:
# python tool.py data.csv -n 5 summarize --columns name age
# python tool.py data.csv convert --format json

concurrent.futures

The concurrent.futures module provides a unified, high-level interface for executing tasks in parallel, whether using threads (ThreadPoolExecutor) or processes (ProcessPoolExecutor). Its future-based API greatly simplifies concurrent programming.

python
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import urllib.request
import time

# --- Example with ThreadPoolExecutor: parallel downloads ---

urls = [
    "https://www.python.org",
    "https://pypi.org",
    "https://docs.python.org",
    "https://peps.python.org",
]

def download(url):
    """Download a page and return its size."""
    start = time.time()
    with urllib.request.urlopen(url, timeout=10) as response:
        content = response.read()
    duration = time.time() - start
    return url, len(content), duration

# Download in parallel with 4 threads
with ThreadPoolExecutor(max_workers=4) as executor:
    results = executor.map(download, urls)

for url, size, duration in results:
    print(f"{url}: {size} bytes in {duration:.2f}s")

# --- Example with ProcessPoolExecutor: CPU-intensive work ---

def is_prime(n):
    """Check if a number is prime."""
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

numbers = [15485863, 15485867, 32452843, 32452867]

with ProcessPoolExecutor() as executor:
    futures = {executor.submit(is_prime, n): n for n in numbers}
    for future in futures:
        n = futures[future]
        print(f"{n} is prime: {future.result()}")

Stable ABI (PEP 384)

PEP 384 defines a stable subset of the Python C API. Extensions compiled against this stable ABI no longer need to be recompiled for each new minor version of Python. This is a considerable advantage for binary package authors: a single compilation can work across Python 3.2, 3.3, 3.4, and beyond.

To use the stable ABI, extension authors must define Py_LIMITED_API at compile time and restrict themselves to functions documented as stable. The resulting files use the .abi3.so extension (or .pyd on Windows) instead of the usual version-specific suffix.

functools.lru_cache

The functools.lru_cache decorator caches function results in memory using an LRU (Least Recently Used) strategy. It is particularly effective for expensive functions called repeatedly with the same arguments.

python
from functools import lru_cache
import time

# Example 1: recursive computation with cache (Fibonacci sequence)
@lru_cache(maxsize=128)
def fibonacci(n):
    """Compute the n-th Fibonacci number."""
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# Without caching, fibonacci(100) would take astronomical time
print(fibonacci(100))  # 354224848179261915075
print(fibonacci.cache_info())
# CacheInfo(hits=98, misses=101, maxsize=128, currsize=101)

# Example 2: caching conversion results
@lru_cache(maxsize=256)
def convert_temperature(celsius):
    """Convert Celsius to Fahrenheit with caching."""
    # Simulates an expensive computation or API call
    return celsius * 9.0 / 5.0 + 32

# Repeated calls are instant
temperature_readings = [20, 22, 20, 18, 22, 20, 25, 18]
for temp in temperature_readings:
    print(f"{temp} C = {convert_temperature(temp)} F")

print(convert_temperature.cache_info())
# hits=4 because 20, 22, and 18 are called multiple times

# Clear the cache if needed
convert_temperature.cache_clear()

Minor Improvements

  • .pyc files are now stored in a __pycache__ directory with a name that includes the Python version (PEP 3147).
  • The logging module gains dictionary-based configuration via logging.config.dictConfig().
  • The ssl module supports SSL contexts and certificate verification.
  • The html module is added with html.escape().
  • The str.format_map() string formatting method is added.

Deprecations and Removals

Notable changes in this category:

  • The optparse module is deprecated in favor of argparse.
  • Old insecure hash functions are deprecated in the hashlib module.
  • Hash randomization is introduced (disabled by default, enabled by default starting with Python 3.3).
  • platform.dist() is marked as obsolete.

Sources