Python 3: the deliberate break with backward compatibility

Python 3.0 fixes historical language inconsistencies: print becomes a function, Unicode strings by default, true division. A transition that will take years.

Open SourceWeb Open SourcePythonPython 3DevelopmentMigration

A deliberate decision

On 3 December 2008, the Python community releases Python 3.0, the first version of the language that is not backward compatible with previous versions. This is neither an accident nor a side effect: it is a deliberate design choice. After more than fifteen years of development, the language has accumulated inconsistencies, redundancies and design decisions that cannot be fixed without breaking existing code.

Guido van Rossum, Python’s creator and the project’s BDFL (Benevolent Dictator For Life), has guided the process through a series of PEPs (Python Enhancement Proposals) that document every change and its rationale. The guiding principle is clear: eliminate the “wrong ways” of doing things, even at the cost of a painful migration.

The key changes

Python 3’s changes touch fundamental aspects of the language:

print becomes a function. In Python 2, print is a statement: print "hello". In Python 3 it is a built-in function: print("hello"). The change is not cosmetic — a function can be replaced, passed as an argument, used in lambda expressions. It is also the change that breaks the greatest number of existing scripts.

Unicode strings by default. In Python 2 two string types coexist: str (bytes) and unicode (text). The confusion between the two is a constant source of errors, especially when handling internationalised data. Python 3 adopts Unicode as the default string type (str), with a separate and explicit bytes type for binary data.

True division. In Python 2, 5/2 returns 2 (integer division). In Python 3, 5/2 returns 2.5 (float division). Explicit integer division is obtained with the // operator. This eliminates a class of subtle errors in numerical computations.

Other changes include: views instead of lists for dict.keys(), dict.values() and dict.items(); the range() function replacing xrange(); the removal of implicit comparisons between different types; and a simplified exception hierarchy.

The cost of transition

Breaking backward compatibility has a concrete cost. The Python ecosystem is vast: thousands of libraries, frameworks and applications are written for Python 2. Migration requires updating code, testing it and verifying that all dependencies are compatible. The FSF and the community have released the 2to3 tool to automate the most common conversions, but complete migration remains a manual and incremental process.

Python 2 will continue to receive maintenance releases. The transition to Python 3 has only just begun and will require time — probably years — before the ecosystem converges on the new version. The community’s bet is that the cost of migration will be lower than the cost of indefinitely maintaining the inconsistencies of the past.

Link: python.org

Need support? Under attack? Service Status
Need support? Under attack? Service Status