Overview

Python 3.1, released on June 27, 2009, is the first improvement release of the 3.x branch. While Python 3.0 had broken compatibility to clean up the language, Python 3.1 focuses on performance and stability.

It is a relatively modest release in terms of new features, but it brings highly anticipated additions like OrderedDict and the int.bit_length() method. The I/O module also receives significant performance improvements.

Major Features

OrderedDict

The collections module gains an OrderedDict, a dictionary that preserves the insertion order of keys. It is a valuable tool for processing configuration files, JSON serialization with a predictable order, or creating simple LRU-style caches.

python
from collections import OrderedDict

# Configuration with guaranteed ordering
config = OrderedDict()
config["host"] = "localhost"
config["port"] = 5432
config["database"] = "my_db"
config["user"] = "admin"

# Order is always preserved
for key, value in config.items():
    print(f"{key} = {value}")
# host = localhost
# port = 5432
# database = my_db
# user = admin

# Preserving order during a JSON round-trip
import json

json_data = '{"name": "Martin", "age": 35, "city": "Lyon"}'
result = json.loads(json_data, object_pairs_hook=OrderedDict)
print(list(result.keys()))  # ['name', 'age', 'city']

# Moving an element to the end of the dictionary
config.move_to_end("host")
print(list(config.keys()))  # ['port', 'database', 'user', 'host']

int.bit_length()

The int.bit_length() method returns the number of bits needed to represent an integer in binary, excluding the sign and leading zeros. This is useful for determining minimum storage sizes or for bit-manipulation algorithms.

python
# Number of bits needed to represent an integer
print((0).bit_length())    # 0
print((1).bit_length())    # 1
print((7).bit_length())    # 3  (binary: 111)
print((255).bit_length())  # 8  (binary: 11111111)
print((256).bit_length())  # 9  (binary: 100000000)

# Practical application: determine the minimal storage type
def minimal_storage_type(value):
    """Determine the smallest integer type to store a value."""
    bits = value.bit_length()
    if bits <= 8:
        return "uint8"
    elif bits <= 16:
        return "uint16"
    elif bits <= 32:
        return "uint32"
    else:
        return "uint64"

values = [42, 300, 70000, 5000000000]
for v in values:
    print(f"{v:>12} -> {v.bit_length():>2} bits -> {minimal_storage_type(v)}")
# 42 ->  6 bits -> uint8
# 300 ->  9 bits -> uint16
# 70000 -> 17 bits -> uint32
# 5000000000 -> 33 bits -> uint64

Improved io module

The io module, introduced in Python 3.0, receives significant performance improvements in Python 3.1. File read and write operations are noticeably faster, which was a frequent complaint about Python 3.0.

python
# Writing and reading in text mode (str)
with open("example.txt", "w", encoding="utf-8") as f:
    f.write("First line\n")
    f.write("Accented characters: \u00e9\u00e8\u00ea\n")

with open("example.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(type(content))  # <class 'str'>

# Writing and reading in binary mode (bytes)
data = bytes(range(256))
with open("data.bin", "wb") as f:
    f.write(data)

with open("data.bin", "rb") as f:
    binary_content = f.read()
    print(type(binary_content))  # <class 'bytes'>
    print(len(binary_content))   # 256

# The io module also allows working in-memory
import io

buffer = io.StringIO()
buffer.write("temporary data\n")
buffer.write("in memory\n")
print(buffer.getvalue())
# temporary data
# in memory

Minor Improvements

  • Floating-point numbers are now displayed with the shortest representation that allows exact reconstruction (e.g., 1.1 instead of 1.1000000000000001).
  • The unittest module gains the assertAlmostEqual method and other useful assertions.
  • The json module accepts the object_pairs_hook parameter to control the dictionary type used during decoding.
  • Module imports are slightly faster.
  • .pyc files can be executed directly if the corresponding .py file does not exist.

Deprecations and Removals

Python 3.1 does not remove major features, as the bulk of the cleanup was done in Python 3.0. A few notable points:

  • The compiler module is permanently removed.
  • Several obsolete methods in the unittest module are marked as deprecated (such as assertEquals in favor of assertEqual).
  • contextlib.nested is deprecated in favor of the multiple with statement syntax.

Sources