Latest in branch 2.2
2.2.3
Released 30 May 2003
(23 years ago)
SoftwarePython
Version2.2
Status
End of life
Initial release2.2
29 Mar 2002
(24 years ago)
Latest release2.2.3
30 May 2003
(23 years ago)
End of life30 May 2003
(Ended 23 years ago)
Source codehttps://github.com/python/cpython/tree/v2.2.3
Documentationhttps://docs.python.org/release/2.2.3/
Downloadhttps://www.python.org/downloads/release/python-223/
Python 2.2 ReleasesView full list

What Is New in Python 2.2

Python 2.2 was one of the most fundamental Python releases -- it unified the old-style and new-style object system, introduced descriptors, properties, and slots, and brought generators into the language. These changes laid the groundwork for everything Python's object model is today.

Category Change PEP / Reference
Object Model New-style classes: inherit from object PEP 252, PEP 253
Object Model Descriptors, property(), classmethod(), staticmethod() PEP 252
Object Model __slots__ for memory-efficient classes PEP 252
New Syntax Generators with yield keyword PEP 255
Builtins iter() and next() protocol formalised PEP 234
Standard Library itertools predecessor: __iter__ protocol everywhere --
Performance MRO (Method Resolution Order) changed to C3 linearization --
Standard Library Improved os.path, doctest, difflib --

The Most Important Python 2.2 Changes

New-Style Classes and the Unified Object Model

Before Python 2.2, there were two class flavors: "old-style" (classic) classes defined with class Foo: and the built-in types like int, list, dict. They were separate hierarchies with different behaviors. Python 2.2 unified them -- new-style classes inherit from object (explicitly or via a built-in type) and have consistent semantics for __init__, __new__, descriptors, and MRO.

# Old-style class (Python 2 only, deprecated)
class OldFoo:
    pass

# New-style class (Python 2.2+, only kind in Python 3)
class NewFoo(object):
    pass

# In Python 3, all classes are new-style automatically
class Foo:  # implicitly inherits from object
    pass

Descriptors and property() (PEP 252)

Descriptors are objects that define __get__, __set__, or __delete__ -- they control what happens when you access an attribute on a class or instance. The property() built-in uses descriptors to create managed attributes with getter, setter, and deleter methods.

class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Below absolute zero")
        self._celsius = value

    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

Generators (PEP 255)

Functions containing yield become generator functions. Calling one returns a generator object that produces values lazily. This was the building block for Python's async and iteration story in later versions.

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

gen = fibonacci()
first_10 = [next(gen) for _ in range(10)]
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

FAQ

Why did the old-style / new-style class distinction matter so much?
Old-style classes did not support descriptors, MRO was broken for diamond inheritance, type(instance) returned <type 'instance'> regardless of the actual class, and you could not subclass built-in types. New-style classes fixed all of this. In Python 3, all classes are new-style and the distinction no longer exists.

What is C3 MRO and why was it important?
The old MRO used depth-first left-to-right lookup, which broke for diamond inheritance. C3 linearization (used by Dylan and CLOS) computes a consistent, monotonic order that respects local precedence and inheritance graph constraints. In practice this means super() works correctly in complex class hierarchies.

What is the difference between classmethod and staticmethod?
@classmethod receives the class (cls) as its first argument -- useful for alternative constructors. @staticmethod receives no implicit first argument -- it is just a regular function namespaced inside the class. Use classmethod when the method needs to access or create instances of the class; use staticmethod for utility functions logically grouped with the class.

When should __slots__ be used?
When you have many instances (thousands or millions) of a class and memory is tight. __slots__ prevents the per-instance __dict__, reducing memory to a fixed set of typed slots. The downside: you lose flexibility to add arbitrary attributes, and subclassing becomes more complex.

Are generators lazy by default in Python 2.2?
Yes. A generator function only executes code up to the next yield when next() is called. The state is frozen between calls. The full sequence is never materialized in memory. This is why generators are the right choice for large data pipelines.

Releases In Branch 2.2

VersionRelease date
2.2.330 May 2003
(23 years ago)
2.2.3c122 May 2003
(23 years ago)
2.2.214 Oct 2002
(23 years ago)
2.2.2b107 Oct 2002
(23 years ago)
2.2.109 Apr 2002
(24 years ago)
2.229 Mar 2002
(24 years ago)
2.2.1c226 Mar 2002
(24 years ago)
2.2.1c118 Mar 2002
(24 years ago)
2.2a308 Sep 2001
(24 years ago)