# What's New in Python 2.0

著者:

  A.M. Kuchling and Moshe Zadka

## はじめに

新 Python リリース、バージョン 2.0 は、2000 年 10 月 16 日にリリースされました。この記事では 2.0 のエキサイティングな新機能をカバーし、いくつかの有用な変更点をハイライトし、少しの、コードの書き換えを要する互換性のない変更点について指摘します。

Python の開発は、リリースとリリースの間で止まることはなく、バグフィックスと改善はとめどなく、日夜提出されます。多くのマイナーフィックス、少しの最適化、ドキュメンテーション文字列の追加、より良いエラーメッセージが 2.0 に仲間入りしました。これら全てを列挙するのは不可能ですが、それは確かに大事でしょう、全てのリストを見たければ、公に入手可能な CVS ログを調べてください。この前進は、今やバグ修正に日々を費やすことで報酬を受け取って PythonLabs のために働く 5 人の開発者、それと SourceForge に移行した結果改善されたコミュニケーションのおかげです。

## Python 1.6 はいかがですか?

Python 1.6 は「推定的義務」の Python リリースと考えることが出来ます。2000 年 5 月にコア開発チームが CNRI を離れたあと、CNRI は Python にかかる作業全てが CNRI で実施されることを含む 1.6 リリースが作成されることをリクエストしました。それゆえ Python 1.6 は、最も重要な新機能としての Unicode サポートを含む、2000 年 5 月の CVS ツリーの状態と同等です。開発はもちろん 5 月以降も継続されましたので、1.6 ツリーは Python 2.0 との前方互換を保障するために少しの修正を受け取りました。1.6 はですから、Python の進化の一部であり、側枝ではありません。

では、あなたは Python 1.6 に興味を示すべきでしょうか? おそらく答えはノーです。1.6final と 2.0beta1 のリリースは同じ日に行われ (2000 年 9 月 5 日)、Python 2.0 のファイナライズはその一ヶ月かそこらで行われるよう計画されました。もしあなたが保守すべきアプリケーションを持っているならば、1.6 への移行には少しばかりコードの破壊を伴うようです。つまりその修正を行い、一ヶ月の間に 2.0 への移行による別の破壊ラウンドがやってきます。直接 2.0 に移行したほうが良いでしょう。このドキュメントに記載する、ほとんどの面白い機能は 2.0 のみのものであり、なぜならほとんどの作業は、5 月から 9 月の間に行われたからなのです。

## 新しい開発プロセス

Python 2.0 における最も重要な変化はコードに対するものではまったくなくて、Python がどのように開発されるのかについてでしょう: 2000 年 5 月に Python 開発者たちは、ソースコード格納、バグ報告の追跡、パッチ提出の待ち行列管理のための SourceForge によって利用出来るようになったツールの使用を始めました。Python 2.0 ではバグ報告やパッチの提出には、Python プロジェクトページで利用可能なバグトラッキングとパッチ管理ツールを使ってください。 https://sourceforge.net/projects/python/ にあります(訳注: 2015 年現在の状況は What's New in Python 2.6 参照)。

SourceForge で現在ホストされているサービスの中で最も重要なのは Python CVS ツリーで、Python のソースコードを含む、バージョンコントロールされたレポジトリです。以前までは、CVS ツリーへの書き込み許可を持つ人々が 7 人ほどいて、全てのパッチはその中の一人が精査とチェックをする必要がありました。明らかにこれはスケーラブルではありませんでした。CVS ツリーを SourceForge に移動することで、より多くの人々に書き込み許可を与えることが可能になりました; 2000 年 9 月時点で、27 人の人々が変更をチェックイン出来るようになっていました。これは 4 倍の増加です。これは大規模な変更、これまでであれば小さなコア開発グループによるフィルタを経由しなければならないために試みられなかったような、大規模な変更を可能にしています。例えばある日 Peter Schneider-Kamp は K&R C 互換を落としてしまうことを思い立ち、Python の C ソースを ANSI C に変換しました。python-dev メーリングリストでの承認を得たのち、彼は立て続けにチェックインを開始しておよそ一週間ほどで終わらせ、ほかの開発者たちも手助けに参加し、そして作業は完了しました。書き込み許可が 5 人だけだったならば、おそらくそのタスクはこう見做されたでしょう:「素晴らしい。けれども時間と労力に見合わない」。そして決して実現することはなかったことでしょう。

SourceForge のサービスを使うことへのシフトは、開発の目覚しいスピードアップをもたらしました。パッチはいまや、提出され、コメントされ、提出者以外の別人によって改定されて戻ってきて、などなどが、パッチがチェックインの価値があると判断されるまで行われています。バグは唯一つの中央保管庫で追跡され、修正には特定の誰かを割り当てることが出来、そして私たちはオープンバグを進捗の指標として考えることが出来ます。これは代償なしでは達成しませんでした; 開発者には今や以前よりもたくさんの処理すべき電子メールがあり、より多くメーリングリストに追従しなければならず、そして新しい環境のための特別なツールを要しました。例えば、SourceForge はデフォルトでパッチ提出とバグ報告を電子メールで通知しますが、これは全く助けにならないもので、Ka-Ping Yee はもっと有用なメッセージを送信するための HTML スクリーンスクレイパを書きました。

簡単にコードを追加出来るようになったことは、当初少し苦痛を大きくしました。例えばコードが不十分なままだったり、開発グループからのはっきりとした承諾のないままチェックインされたりするといったことです。浮上してきた承認プロセスは、Apache グループが使っているようなものにいくらか似たものです。開発者たちは +1, +0, -0, -1 というふうにパッチに投票できます; +1 と -1 は承諾、却下を表し、+0 と -0 は、開発者は変更にほとんど興味がないけれどもやや肯定、否定の傾向であることを意味します。Apache モデルからの最も大きな違いは、投票行為は本質的に助言であって、優しい終身独裁者 Guido van Rossum 侯に大衆の民意を伝えるものであることです。彼は投票結果をそれでも無視出来ますし、コミュニティが異論を唱えようが変更を承認したり却下したり出来ます。

実際のパッチの作成は新機能の追加での最後のステップであり、通常、良いデザインを工面する前のタスクと容易に比較出来ます。一方で新機能についての議論はしばしばメーリングリストでの長大なスレッドを巻き起こし、議論に追いつくのが大変になり、そして誰も python-dev の投稿全てを読めません。それゆえに、Python 拡張提案 (Python Enhancement Proposals: PEPs)を書く、相対的に形式ばったプロセスが、始動しました。インターネットの RFC をモデルにしたものです。PEPs は新機能提案を記述した草案文書であり、コミュニティの合意として提案が承認されるか却下されるまで継続的に改定されます。 PEP 1 の導入部、"PEP の目的とガイドライン" から引用します:

> PEP は Python Enhancement Proposal を意味します。PEP は、Python コミュニティに対して情報を提供する、あるいは Python の新機能について記述する設計文書です。PEP は、機能についての技術的な仕様とその機能の論拠(理論)を簡潔に伝えるべきです。

> 私たちは PEP が新機能提案にかかる、コミュニティによる問題提起の集積と Python になされる設計決断の文書化のための最上位の機構となることを意図しています。PEP の著者にはコミュニティ内の合意形成を行うこと、反対意見を文書化することの責務があります。

PEP の編集に関するプロセス、様式、体裁についての詳細が PEP 1 の残りの部分に書かれています。PEPs は SourceForge 上の Python CVS ツリーで営まれますが Python 2.0 配布物の一部ではなく、 https://peps.python.org/ で HTML 形式で利用可能です。2000 年 9 月時点で PEP 201 の "Lockstep Iteration" から PEP 225 の "Elementwise/Objectwise Operators" までの 25 の PEP があります。

## Unicode 文字列型

Python 2.0 での最大の新機能は新しい基礎データ型、Unicode 文字列です。Unicode は文字を表現するのに ASCII で使用される 8 ビット数の代わりに 16 ビットを使います。これによって 65,536 の個別の文字がサポート出来ます。(---訳注: Unicode の扱いはまず Python 2.2 で UCS4 が使えるように拡張され(つまり 32 ビットに拡張)、Python 3 では Unicode が唯一の文字列型に変更されています。後者の変更点は非常に大きいですが、クックブックの「Python 2 から Python 3 への移植」に比較的よくまとめられています。---)

最終的な Unicode サポートに関するインターフェイスは、python-dev メーリングリストにおける数え切れない、時として嵐のような議論を経て、Fredrik Lundh によって実装された Unicode 文字列型に基づいて、ほとんどが Marc-André Lemburg によって実装されました。インターフェイスについての詳細な説明は PEP 100 「Python Unicode の統合」に記述されました。今ここでは、Unicode インターフェイスについて、一番重要な点を単純にカバーするだけにしましょう。

Python ソースコード内では Unicode 文字列は `u"string"` のように書きます。任意の Unicode 文字は新しく追加されたエスケープシーケンスで書きます。 `\uHHHH` のように書き、 HHHH は 0000 から FFFF までの 4 桁の 16 進表記数です。以前からあるエスケープシーケンス `\xHH` も使えますし、8 進表記も、 `\777` で表現される U+01FF までの文字に使えます。

Unicode 文字列は普通の文字列と全く似ていて、 immutable なシーケンス型です。添え字でアクセス出来、スライス出来ますが、インプレイスに変更することは出来ません。Unicode 文字列は `encode( [encoding] )` メソッドを持っていて、これは望みのエンコーディングでエンコードした 8 ビット文字列を返します。エンコーディングは文字列で名前付けられていて、例えば `'ascii'`, `'utf-8'`, `'iso-8859-1'` のようなものです。コーデック API は、新しいエンコーディングを実装し、Python プログラム全体を通して利用可能となるよう登録するために定義されています。エンコーディングが指定されない場合はデフォルトのエンコーディングは普通 7 ビット ASCII ですが、Python インストレーションにおいて、 `site.py` のカスタマイズ版内で `sys.setdefaultencoding(encoding)` を呼び出すことで変更出来ます。

8 ビット文字列と Unicode 文字列を結合すると常に、デフォルトの ASCII エンコーディングを使って Unicode に型変換されます。 `'a' + u'bc'` の結果は `u'abc'` になります。

新たなビルトイン関数が追加され、既存のビルトイン関数も Unicode サポートのために修正されました:

- `unichr(ch)` は Unicode におけるコードが整数 ch になるような文字 1 文字からなる Unicode 文字列を返します。

- u が 1 文字の通常文字あるいは Unicode 文字として、 `ord(u)` はコードを整数で返します。

- `unicode(string [, encoding] [, errors] )` は、8 ビット文字列から Unicode 文字列を作ります。 `encoding` は使用するエンコーディング名の文字列です。 `errors` パラメータは、現在エンコーディングにおいて不正な文字の扱いを指示します; これに値として `'strict'` を渡すと全てのエンコーディングエラーに対し、例外を引き起こします。 `'ignore'` を渡すとエラーは黙って無視されます。 `'replace'` を渡すと、全ての問題ケースで、公式な置き換え文字である U+FFFD に置き換えます。

- `exec` 文や`eval()`, `getattr()`, `setattr()` のような色々なビルトインも、普通の文字列同様に Unicode 文字列を受け付けるようになりました。(この修正をするプロセスをいくつかのビルトインで忘れている可能性もあります。文字列を受け取るものが Unicode を全く受け取らないビルトインを見つけたら、バグとして報告してください。)

新規モジュール `unicodedata` は、Unicode 文字の特性へのインターフェイスを提供します。例えば `unicodedata.category(u'A')` は 2 文字の文字列 'Lu' を返しますが、これは、 'L' が letter を、 'u' が uppercase を表します。 `unicodedata.bidirectional(u'\u0660')` は 'AN' を返し、これは U+0660 が Arabic Number であることを表します。

`codecs` モジュールには、既存のエンコーディングをルックアップする関数、新しいエンコーディングを登録する関数が含まれます。新しいエンコーディングを実装したいと思うのでない限りは、一番使うことになるのは `codecs.lookup(encoding)` でしょう。これは 4 要素のタプルを返します: `(encode_func, decode_func, stream_reader, stream_writer)` 。

- encode_func は、Unicode 文字列を受け取って 2 要素タプル `(string, length)` を返す関数です。 string は、与えられたエンコーディングで Unicode 文字列を変換した部分 (おそらく全体) を含む 8 ビット文字列で、 length は何文字の Unicode 文字列が変換されたかを伝えます。

- decode_func は encode_func の対となる関数で、8 ビット文字列を受け取って、2 要素のタプル `(ustring, length)` を返します。 ustring が結果の Unicode 文字列で、整数 length が、8 ビット文字列何文字が消費されたかを表します。

- stream_reader is a class that supports decoding input from a stream. stream_reader(file_obj) returns an object that supports the `read()`, `readline()`, and `readlines()` methods. These methods will all translate from the given encoding and return Unicode strings.

- stream_writer, similarly, is a class that supports encoding output to a stream. stream_writer(file_obj) returns an object that supports the `write()` and `writelines()` methods. These methods expect Unicode strings, translating them to the given encoding on output.

例えば以下のコードは Unicode 文字列を UTF-8 でエンコーディングしてファイルに書きます:

    import codecs

    unistr = u'\u0660\u2000ab ...'

    (UTF8_encode, UTF8_decode,
     UTF8_streamreader, UTF8_streamwriter) = codecs.lookup('UTF-8')

    output = UTF8_streamwriter( open( '/tmp/output', 'wb') )
    output.write( unistr )
    output.close()

そして以下コードではファイルから UTF-8 で読めます:

    input = UTF8_streamreader( open( '/tmp/output', 'rb') )
    print repr(input.read())
    input.close()

`re` モジュールでは Unicode 対応した正規表現が利用可能で、これは新しい根底となる SRE なる実装から成り、Secret Labs AB の Fredrik Lundh によって書かれました。

Python コンパイラに全ての文字列リテラルを Unicode 文字列として解釈させるための `-U` コマンドラインオプションが追加されました。これはあなたの Python コードのテストと将来の保障を意図しています。というのも、将来の Python バージョンでは 8 ビット文字列のサポートがなくなって、Unicode 文字列だけとなる予定だからです。 (---訳注: ここで言っている将来バージョンとは、結果的には Python 3 になりました。What's New での明記はないのですが `-U` オプションは Python 2.7 時点では存在していません。ですが同じことは 2.6 以降では `from __future__ import unicode_literals` で出来ます。 ---)

## リストの内包表記

リストというのは Python の主要なデータ型で、多くのプログラムがリストをいつかは操るものです。リストの操作での 2 つのよくある操作は、それらについてループし、あるいは特定の基準に合致したものを取り出すか個々の要素にある関数を適用するかする、といったものです。例えば文字列のリストが与えられた場合、特定の部分文字列を含む全ての文字列を引き抜いたり、あるいは各行から末尾の空白を取り除いたりしたいでしょう。

既にあった `map()` 関数、 `filter()` 関数がこの目的のためには使えますが、それらにはその引数の一つに関数が必要です。何か既存のビルトイン関数で直接渡せるものがあればよいのですが、これがない場合その必要とされる仕事をする小さな関数を作る必要があって、また、Python のスコープ規則によって、その小さな関数が何かほかの情報を必要とする場合に醜いものになります。前パラグラフでの最初の例を考えましょう。指定の部分文字列を含む文字列リストから全てを探す例です。このように書けるでしょう:

    # Given the list L, make a list of all strings
    # containing the substring S.
    sublist = filter( lambda s, substring=S:
                         string.find(s, substring) != -1,
                      L)

Python のスコープ規則のために、 `lambda` 式で作っている匿名関数にデフォルト引数を使い、これに検索対象の部分文字列を渡しています。リスト内包表記はこれを明快にします:

    sublist = [ s for s in L if string.find(s, S) != -1 ]

リスト内包表記は以下の形式を持ちます:

    [ expression for expr in sequence1
                 for expr2 in sequence2 ...
                 for exprN in sequenceN
                 if condition ]

`for`...`in` 節はイテレートするシーケンスを含みます。シーケンス群は同じ長さである必要はありません。それらは並列でイテレートされる のではなく 左から右の順で周ります。続くパラグラフでもっとわかりやすく説明します。生成されるリストの要素は一連の expression の値となります。最後の `if` 節はオプショナルです。これがあれば expression は condition が真の場合にのみ評価・追加されます。

セマンティクスについてとてもわかりやすく説明しておきましょう。リスト内包は以下の Python コードと等価です:

    for expr1 in sequence1:
        for expr2 in sequence2:
        ...
            for exprN in sequenceN:
                 if (condition):
                      # Append the value of
                      # the expression to the
                      # resulting list.

つまり、複数の `for`...`in` 節があって `if` がないときの最終出力は、長さが各シーケンス長の積に等しくなるということです。長さ 3 のリスト二つなら、出力リストの長さは 9 要素です:

    seq1 = 'abc'
    seq2 = (1,2,3)
    >>> [ (x,y) for x in seq1 for y in seq2]
    [('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1),
    ('c', 2), ('c', 3)]

Python の文法に曖昧さを紛れ込ませないように、expression でタプルを作るなら括弧で囲わなくてはなりません。下にあるリスト内包表記で、最初のは構文エラーですが、二番目は有効です:

    # Syntax error
    [ x,y for x in seq1 for y in seq2]
    # Correct
    [ (x,y) for x in seq1 for y in seq2]

リスト内包表記のアイディアは、もともとは関数型プログラミング言語 Haskell (https://www.haskell.org) に由来しています。Greg Ewing が Python にこれを追加することを最も実際的に主張し、彼が最初のリスト内包のパッチを書きました。それは傍目には終わりのない議論が python-dev メーリングリストにて続き、Skip Montanaro によって最新に保たれました。

## 累算代入 (Augmented Assignment)

累算代入はもう一つの長らく待ち望まれた機能であり、Python 2.0 に追加されました。累算代入演算子には `+=`, `-=`, `*=` などがあります。例えばステートメント `a += 2` は変数 `a` に 2 を加算し、これはちょっとだけ長い記述 `a = a + 2` と同じです。

The full list of supported assignment operators is `+=`, `-=`, `*=`, `/=`, `%=`, `**=`, `&=`, `|=`, `^=`, `>>=`, and `<<=`. Python classes can override the augmented assignment operators by defining methods named `__iadd__()`, `__isub__()`, etc. For example, the following `Number` class stores a number and supports using += to create a new instance with an incremented value.

    class Number:
        def __init__(self, value):
            self.value = value
        def __iadd__(self, increment):
            return Number( self.value + increment)

    n = Number(5)
    n += 3
    print n.value

The `__iadd__()` special method is called with the value of the increment, and should return a new instance with an appropriately modified value; this return value is bound as the new value of the variable on the left-hand side.

累算代入演算子は最初に C 言語で導入されて、 awk, C++, Java, Perl, PHP といった C から派生した言語のほとんどでサポートされています。累算代入のパッチは Thomas Wouters により実装されました。

## 文字列メソッド

Until now string-manipulation functionality was in the `string` module, which was usually a front-end for the `strop` module written in C. The addition of Unicode posed a difficulty for the `strop` module, because the functions would all need to be rewritten in order to accept either 8-bit or Unicode strings. For functions such as `string.replace()`, which takes 3 string arguments, that means eight possible permutations, and correspondingly complicated code.

代わりに、Python 2.0 は問題を文字列型に押し込み、文字列操作機能が 8 ビット文字列と Unicode 文字列の両方のメソッドを通じて利用可能としました。

    >>> 'andrew'.capitalize()
    'Andrew'
    >>> 'hostname'.replace('os', 'linux')
    'hlinuxtname'
    >>> 'moshe'.find('sh')
    2

変わらない一つのこと、華やかなエイプリルフールのジョークではありませんが、それは Python 文字列が immutable だということです。ですので文字列メソッドは新しい文字列を返し、それが操作する文字列を変更しません。

古い `string` モジュールはまだ後方互換性のために残されますが、それはほとんど新たな文字列メソッドへのフロントエンドとして振舞います。

Two methods which have no parallel in pre-2.0 versions, although they did exist in JPython for quite some time, are `startswith()` and `endswith()`. `s.startswith(t)` is equivalent to `s[:len(t)] == t`, while `s.endswith(t)` is equivalent to `s[-len(t):] == t`.

One other method which deserves special mention is `join()`. The `join()` method of a string receives one parameter, a sequence of strings, and is equivalent to the `string.join()` function from the old `string` module, with the arguments reversed. In other words, `s.join(seq)` is equivalent to the old `string.join(seq, s)`.

## 循環参照のガベージコレクション

Python の C 実装は、ガーベージコレクションの実装に参照カウントを使っています。全ての Python オブジェクトは自身を参照している数を維持していて、参照が作成されたり破壊されたりするカウントを調整しています。参照カウントがゼロになればそのオブジェクトにはもはや到達可能ではありません。あなたはそれにアクセスするためのオブジェクトへの参照を持つ必要がありますが、カウントがゼロならば参照はもはや存在しないということです。

参照カウントはある種望ましい特徴を持っています。それは理解しやすく、実装しやすく、結果としての実装の移植性は高く、かなり高速であり、そして、独自のメモリ処理方式を実装しているようなほかのライブラリと共にでも良く振舞います。参照カウントの主要な問題点は、それが時々、オブジェクトにはもう到達不能であることに気付かないので、結果としてメモリリークを引き起こすことです。これは参照の循環がある場合に発生します。

最も単純な循環について考えてみます。クラスインスタンスが自身への参照を持つ場合です:

    instance = SomeClass()
    instance.myself = instance

上の例の 2 行のコードが実行された後では、 `instance` の参照カウントは 2 です。参照の一つ目は `'instance'` と名付けられた変数からのもので、もう一つの参照は、インスタンスの `myself` 属性から来るものです。

このあとに続くコードが `del instance` だとしたら、何が起こるでしょうか? `instance` の参照カウントは 1 減るので参照カウントは 1 になります。 `myself` 属性内の参照はいまだ存在します。けれどもインスタンスはもう Python コードからは到達不能ですから、本来削除出来るはずです。お互いを参照しあうならばいくつものオブジェクトが循環に参加しえるので、結果それら全てのオブジェクトはリークしてしまいます。

Python 2.0 はこの問題を、循環検出アルゴリズムを周期的に実行することによりフィックスします。そのアルゴリズムは、到達不能な循環を探して関係するオブジェクトを削除します。新しく追加された `gc` モジュールは、ガーベージコレクションを実行する関数、デバッグのための統計情報を取得する関数、コレクタのパラメータを調整する関数を提供します。

循環検出アルゴリズムの実行はいくらかの時間がかかるので、結果として多少の追加的なオーバヘッドがかかるでしょう。2.0 を使って循環のコレクションの経験を積んだのちに、 Python 2.1 では注意深い調整によりオーバヘッドを最小に出来ることが望まれています。今のところパフォーマンスの損失がいかほどなのかは明らかではありません。これはこれのベンチマークがトリッキーであり、プログラムがどれだけの頻度でオブジェクトを構築・破棄するのかに大きく依存するからです。循環の検出は Python コンパイル時に無効に出来ます。もしもあなたが小さな速度のペナルティでさえも許容出来ないであるとか、あるいは循環のコレクションがバギーであることを疑うのであれば、 configure スクリプト実行時に `--without-cycle-gc` スイッチを与えることでそうすることが出来ます。 (---訳注: Python 2.3 でこの循環参照の GC は必須となり、 `--without-cycle-gc` 、 `--with-cycle-gc` での有無効化は撤廃されました。---)

何人かの人々がこの問題に体当たりで取り組み、解決に対する貢献をしました。循環検出アプローチの初期の実装は、Toby Kelsey により書かれました。現在のアルゴリズムは CNRI を訪れている間に Eric Tiedemann によって提案されて、Guido van Rossum と Neil Schemenauer が別々の 2 つの実装を書いて、あとで Neil によって統合されたものです。そこに至るまでにもほかの数多くの人々によって提案がなされました。python-dev メーリングリストの 2000 年 3 月のアーカイブに、これに関するほとんどの議論が含まれています。特にタイトルが "Reference cycle collection for Python" と "Finalization again" のスレッドです。

## その他の言語コアの変更

Python 文法とビルトイン関数について、色々マイナーな変更がなされました。影響が広範囲に及ぶものは一つもありませんが、手軽で便利なものです。

### 言語のマイナー変更

A new syntax makes it more convenient to call a given function with a tuple of arguments and/or a dictionary of keyword arguments. In Python 1.5 and earlier, you'd use the `apply()` built-in function: `apply(f, args, kw)` calls the function `f()` with the argument tuple args and the keyword arguments in the dictionary kw. `apply()` is the same in 2.0, but thanks to a patch from Greg Ewing, `f(*args, **kw)` is a shorter and clearer way to achieve the same effect. This syntax is symmetrical with the syntax for defining functions:

    def f(*args, **kw):
        # args is a tuple of positional args,
        # kw is a dictionary of keyword args
        ...

The `print` statement can now have its output directed to a file-like object by following the `print` with `>> file`, similar to the redirection operator in Unix shells. Previously you'd either have to use the `write()` method of the file-like object, which lacks the convenience and simplicity of `print`, or you could assign a new value to `sys.stdout` and then restore the old value. For sending output to standard error, it's much easier to write this:

    print >> sys.stderr, "Warning: action field not supplied"

`import module as name` または `from module import name as othername` という構文を使って、インポートするモジュールの名前をリネーム出来るようになりました。パッチは Thomas Wouters が投稿しました。

`%` 演算子を使う際に新しい書式化スタイルが利用可能です; '%r' はその引数の `repr()` を挿入します。これは対称性の検討からも考えられました。今の場合は既存の '%s' が引数の `str()` を挿入することに呼応するものです。例えば `'%r %s' % ('abc', 'abc')` は文字列 `'abc' abc` を返します。

Previously there was no way to implement a class that overrode Python's built-in `in` operator and implemented a custom version. `obj in seq` returns true if obj is present in the sequence seq; Python computes this by simply trying every index of the sequence until either obj is found or an `IndexError` is encountered. Moshe Zadka contributed a patch which adds a `__contains__()` magic method for providing a custom implementation for `in`. Additionally, new built-in objects written in C can define what `in` means for them via a new slot in the sequence protocol.

以前のバージョンの Python では、オブジェクトの削除に再帰するアルゴリズムを使っていました。データ構造が深くネストしている場合、インタプリタが C のスタックを使い果たしてクラッシュしていました。Christian Tismer はこの問題をフィックスする削除ロジックに書き直しました。これに関係する注目すべきものとしては、再帰するオブジェクトの比較が無限再帰してクラッシュしていたのを、Jeremy Hylton が書き直してクラッシュしないようにして、有用な結果を生成するようにしたことです。例えば以下コード:

    a = []
    b = []
    a.append(a)
    b.append(b)

The comparison `a==b` returns true, because the two recursive data structures are isomorphic. See the thread "trashcan and PR#7" in the April 2000 archives of the python-dev mailing list for the discussion leading up to this implementation, and some useful relevant links. Note that comparisons can now also raise exceptions. In earlier versions of Python, a comparison operation such as `cmp(a,b)` would always produce an answer, even if a user-defined `__cmp__()` method encountered an error, since the resulting exception would simply be silently swallowed.

Work has been done on porting Python to 64-bit Windows on the Itanium processor, mostly by Trent Mick of ActiveState. (Confusingly, `sys.platform` is still `'win32'` on Win64 because it seems that for ease of porting, MS Visual C++ treats code as 32 bit on Itanium.) PythonWin also supports Windows CE; see the Python CE page at https://pythonce.sourceforge.net/ for more information.

Another new platform is Darwin/MacOS X; initial support for it is in Python 2.0. Dynamic loading works, if you specify "configure --with-dyld --with-suffix=.x". Consult the README in the Python source distribution for more instructions.

変数に値が割り当てられる前にローカル変数を参照するコードにおいて、 `NameError` 例外はよく混乱するものであり、この欠点を軽減する試みがなされました。例えば下に挙げるコードは `print` 文で 1.5.2 と 2.0 の両方で例外が発生しますが、1.5.2 は `NameError` 例外が、2.0 では新規の例外 `UnboundLocalError` が投げられます。 `UnboundLocalError` は `NameError` のサブクラスですので `NameError` が投げられることを想定する既存のコードはそのまま動作するはずです。:

    def f():
        print "i=",i
        i = i + 1
    f()

2 つの新規例外 `TabError` と `IndentationError` が導入されました。これらはともに `SyntaxError` のサブクラスで、Python コードに不適切なインデントが見つかると送出されます。

### ビルトイン関数の変更

新しいビルトイン関数 `zip(seq1, seq2, ...)` が追加されました。 `zip()` はタプルのリストを返します。それぞれは、引数のシーケンスのそれぞれの i 番目要素たちを含むタプルです。 `zip()` と `map(None, seq1, seq2)` の違いは、 `map()` はシーケンスが同じ長さを持たない場合に `None` が埋められるのに対し、 `zip()` は返すリストの長さを、引数のシーケンスの最も短い長さに切り詰めます。

The `int()` and `long()` functions now accept an optional "base" parameter when the first argument is a string. `int('123', 10)` returns 123, while `int('123', 16)` returns 291. `int(123, 16)` raises a `TypeError` exception with the message "can't convert non-string with explicit base".

`sys` モジュールに、これまでより詳細なバージョン情報を持つ変数が追加されました。 `sys.version_info` はタプル `(major, minor, micro, level, serial)` です。例えば仮に 2.0.1beta1 というバージョンだったとすれば、 `sys.version_info` は `(2, 0, 1, 'beta', 1)` となるでしょう。 level は `"alpha"` や `"beta"` といった文字列で、最終リリースでは `"final"` です。(---訳注: Python 2.7 で名前付きタプルになっています。また、その属性名では level ではなく releaselevel です。---)

Dictionaries have an odd new method, `setdefault(key, default)`, which behaves similarly to the existing `get()` method. However, if the key is missing, `setdefault()` both returns the value of default as `get()` would do, and also inserts it into the dictionary as the value for key. Thus, the following lines of code:

    if dict.has_key( key ): return dict[key]
    else:
        dict[key] = []
        return dict[key]

は、単一の `return dict.setdefault(key, [])` ステートメントだけで書けます。

再帰の暴走を C のスタックが埋め尽くされてコアダンプしたり GPF (訳注: General Protection Fault) する前に捕捉するために、インタプリタは最大の再帰の深さをセットします。以前まではこの制限は Python コンパイル時点で決めてしまっていましたが、2.0 では最大の再帰の深さは `sys.getrecursionlimit()` と `sys.setrecursionlimit()` を使って読み取れ、修正出来ます。このデフォルトは 1000 です。また、当該プラットフォームでのおよその最大値は、新たに追加されたスクリプト `Misc/find_recursionlimit.py` を実行することで知ることが出来ます。

## Python 2.0 への移植

新しい Python リリースは以前のリリースとの互換性を保つために苦心していますし、その記録はかなり良くなされてきました。ですがいくつかの変更に関しては、大抵は大きな誤りであると判明した初期デザインを修正するという理由で、後方互換性を破壊することを必ずしも回避せずに有用性が検討されています。このセクションでは Python 2.0 において、古い Python コードを破壊するかもしれない変更点について列挙します。

The change which will probably break the most code is tightening up the arguments accepted by some methods. Some methods would take multiple arguments and treat them as a tuple, particularly various list methods such as `append()` and `insert()`. In earlier versions of Python, if `L` is a list, `L.append( 1,2 )` appends the tuple `(1,2)` to the list. In Python 2.0 this causes a `TypeError` exception to be raised, with the message: 'append requires exactly 1 argument; 2 given'. The fix is to simply add an extra set of parentheses to pass both values as a tuple: `L.append( (1,2) )`.

The earlier versions of these methods were more forgiving because they used an old function in Python's C interface to parse their arguments; 2.0 modernizes them to use `PyArg_ParseTuple()`, the current argument parsing function, which provides more helpful error messages and treats multi-argument calls as errors. If you absolutely must use 2.0 but can't fix your code, you can edit `Objects/listobject.c` and define the preprocessor symbol `NO_STRICT_LIST_APPEND` to preserve the old behaviour; this isn't recommended.

`socket` モジュールのいくつかの関数についてはまだこの方法が許されています。例えば、 `socket.connect( ('hostname', 25) )` が正しい形式なのですが、 `socket.connect('hostname', 25)` も動作します。`socket.connect_ex` と `socket.bind` も同じようにおおらかです。2.0alpha1 がそれら関数を厳しくしたのですが、ドキュメントが実際には複数引数を取る形式で誤って書かれたために、多くの人々がその厳しくなったチェックに違反してしまうコードを書いてしまいました。GvR はその変更を、市民たちの反応を受けて元に戻し、 `socket` モジュールについてはドキュメントは修正されて、複数引数形式は非推奨としてマークするに留められました。将来バージョンの Python においてこれはもう一度厳しく なります 。 (---訳注: What's New からは読み取れませんが少なくとも 2.7 では単一引数でしか渡せません。つまり明示的にタプルにして渡す必要があります。---)

文字列リテラル内の `\x` エスケープは、正確に 2 桁の 16 進表記文字になりました。以前は 'x' に続く 16 進表記文字全てを消費して最後の 8 ビットを使っていたため、 `\x123456` は `\x56` と同じでした。

例外 `AttributeError` と `NameError` がよりフレンドリなエラーメッセージを持つようになっています。それらのテキストは `'Spam' instance has no attribute 'eggs'` や `name 'eggs' is not defined` のようなものになります。以前まではエラーメッセージは存在しない属性名 `eggs` だけでしたので、この事実に便乗して書かれたコードは 2.0 では壊れます。

Some work has been done to make integers and long integers a bit more interchangeable. In 1.5.2, large-file support was added for Solaris, to allow reading files larger than 2 GiB; this made the `tell()` method of file objects return a long integer instead of a regular integer. Some code would subtract two file offsets and attempt to use the result to multiply a sequence or slice a string, but this raised a `TypeError`. In 2.0, long integers can be used to multiply or slice a sequence, and it'll behave as you'd intuitively expect it to; `3L * 'abc'` produces 'abcabcabc', and `(0,1,2,3)[2L:4L]` produces (2,3). Long integers can also be used in various contexts where previously only integers were accepted, such as in the `seek()` method of file objects, and in the formats supported by the `%` operator (`%d`, `%i`, `%x`, etc.). For example, `"%d" % 2L**64` will produce the string `18446744073709551616`.

一番微妙な長整数についての変更は、長整数を `str()` してももはや末尾の 'L' 文字が付かないことです。 `repr()` では今でも付くのにも関わらずです。 'L' は長整数を普通の整数と全く同じように印字したい多くの人々を悩ませてきました。それを各々自分なりの手段で取り除く必要があったからです。これはもう 2.0 では問題でなくなりましたが、 'L' が付くことをあてにして `str(longval)[:-1]` とするコードが今度は数値の最後の桁を失ってしまいます。

Taking the `repr()` of a float now uses a different formatting precision than `str()`. `repr()` uses `%.17g` format string for C's `sprintf()`, while `str()` uses `%.12g` as before. The effect is that `repr()` may occasionally show more decimal places than `str()`, for certain numbers. For example, the number 8.1 can't be represented exactly in binary, so `repr(8.1)` is `'8.0999999999999996'`, while str(8.1) is `'8.1'`.

The `-X` command-line option, which turned all standard exceptions into strings instead of classes, has been removed; the standard exceptions will now always be classes. The `exceptions` module containing the standard exceptions was translated from Python to a built-in C module, written by Barry Warsaw and Fredrik Lundh.

## 拡張と埋め込みについての変更

いくつかの変更点については覆いが被されていて、C 拡張モジュールや大きなアプリケーションでの Python インタプリタの埋め込みを書く人々からしか見えないものです。Python C API を扱う必要がないのであれば、このセクションは読み飛ばして差し支えありません。

Python C API のバージョン番号がインクリメントされたので、1.5.2 でコンパイルされた C 拡張は 2.0 で動作させるために再コンパイルしなければなりません。Windows では Python 1.5.x でビルドされたサードパーティ拡張を Python 2.0 でインポートすることは、Windows の DLL の仕組みのために、出来ません。その場合 Python は例外を投げ、インポートは失敗します。(---訳注: この文章、おかしなことを言っているので一応…。おそらく「Windows の一般市民は C コンパイラを持っていない」ことが著者の頭にあって、手が滑っているのだと思います。DLL の動作の仕組みが問題となるのは事実ですが、本質的には Windows 云々はあまり関係ないです。API が変わるか ABI が変わるならプラットフォームに関係なくリコンパイルは常に必要です。 ---)

Users of Jim Fulton's ExtensionClass module will be pleased to find out that hooks have been added so that ExtensionClasses are now supported by `isinstance()` and `issubclass()`. This means you no longer have to remember to write code such as `if type(obj) == myExtensionClass`, but can use the more natural `if isinstance(obj, myExtensionClass)`.

`Python/importdl.c` ファイルが多くの異なるプラットフォームの動的ロードをサポートするのに大量の #ifdef だらけになっていたのを、Greg Stein が掃除して再編成しました。 `importdl.c` は今ではとても小さくなり、プラットフォーム依存のコードは `Python/dynload_*.c` ファイル群の束にそれぞれ移動しました。もう一つの掃除。include/ ディレクトリ内で色々な移植性のためのハックを施すためのたくさんの `my*.h` ファイルたちが、単一の `Include/pyport.h` にマージされました。

Vladimir Marangozov の手による、待ち望まれた malloc の再編成が完了しました。これは Python インタプリタが C 標準の `malloc()` の代わりにカスタムアロケータを使うことを容易にするものです。ドキュメントについては `Include/pymem.h` と `Include/objimpl.h` のコメントを読んで下さい。インターフェイスが決着するまでの間の長い長い議論については python.org の 'patches' と 'python-dev' リストのウェブアーカイブをみてください。(---訳注: この件についての続きの話が What's New in Python 2.3 に Pymalloc として少しわかりやすく記述されています。---)

MacOS の GUSI 開発環境の最近のバージョンは POSIX スレッドをサポートしています。ですので Python の POSIX スレッディングのサポートは今では Macintosh で動作します。ユーザ空間での GNU `pth` ライブラリを使ったスレッディングサポートも寄稿されました。

Windows でのスレッディングサポートも拡張されました。Windows は、競合があるケースでのみカーネルオブジェクトを使うスレッドロックをサポートしています。競合がない普通のケースではそれらはより単純な関数を使い、これは段違いに高速です。NT での Python 1.5.2 版でスレッド化すると、非スレッド版の 2 倍遅くなりますが、2.0 に変えるとその差はたった 10% です。これらの改善は Yakov Markovitch の貢献によるものです。

Python 2.0 のソースが ANSI C プロトタイプだけを使うようになったので、Python のコンパイルには ANSI C コンパイラが必須になりました。K&R C しかサポートしないコンパイラではもうコンパイル出来ません。

Previously the Python virtual machine used 16-bit numbers in its bytecode, limiting the size of source files. In particular, this affected the maximum size of literal lists and dictionaries in Python source; occasionally people who are generating Python code would run into this limit. A patch by Charles G. Waldman raises the limit from `2**16` to `2**32`.

Three new convenience functions intended for adding constants to a module's dictionary at module initialization time were added: `PyModule_AddObject()`, `PyModule_AddIntConstant()`, and `PyModule_AddStringConstant()`. Each of these functions takes a module object, a null-terminated C string containing the name to be added, and a third argument for the value to be assigned to the name. This third argument is, respectively, a Python object, a C long, or a C string.

Unix スタイルのシグナルハンドラへのラッパーAPIが追加されました。 `PyOS_getsig()` でシグナルハンドラを取得し、 `PyOS_setsig()` で新しいハンドラをセットします。

## Distutils: モジュールの簡単インストール

Python 2.0 以前は、モジュールのインストールは退屈な作業でした -- Python がどこにインストールされているかや拡張モジュールのコンパイルに必要なオプションを自動的に知る方法はありませんでした。ソフトウェアの作者は Makefile と設定ファイル群の編集という大変な労力を要する儀式を通過しなければならないのに、それは実際には Unix だけのためであって Windows と MacOS のサポートを置き去りにするものでした。Python ユーザは全く異なったインストール命令に直面していました。それは拡張パッケージごとに異なり、Python インストールをある種つまらない作業としていました。

The SIG for distribution utilities, shepherded by Greg Ward, has created the Distutils, a system to make package installation much easier. They form the `distutils` package, a new part of Python's standard library. In the best case, installing a Python module from source will require the same steps: first you simply mean unpack the tarball or zip archive, and the run "`python setup.py install`". The platform will be automatically detected, the compiler will be recognized, C extension modules will be compiled, and the distribution installed into the proper directory. Optional command-line arguments provide more control over the installation process, the distutils package offers many places to override defaults -- separating the build from the install, building or installing in non-default directories, and more.

Distutils を使うには `setup.py` スクリプトを書く必要があります。単純なケースでは、ソフトウェアが .py ファイルだけを含む場合、最小限の `setup.py` は数行足らずで書けます:

    from distutils.core import setup
    setup (name = "foo", version = "1.0",
           py_modules = ["module1", "module2"])

`setup.py` ファイルは、ソフトウェアが少しのパッケージで構成される場合はこれより大きく複雑になることはありません:

    from distutils.core import setup
    setup (name = "foo", version = "1.0",
           packages = ["package", "package.subpackage"])

C 拡張が最も複雑なケースになりえます。以下は PyXML パッケージからもってきた例です:

    from distutils.core import setup, Extension

    expat_extension = Extension('xml.parsers.pyexpat',
         define_macros = [('XML_NS', None)],
         include_dirs = [ 'extensions/expat/xmltok',
                          'extensions/expat/xmlparse' ],
         sources = [ 'extensions/pyexpat.c',
                     'extensions/expat/xmltok/xmltok.c',
                     'extensions/expat/xmltok/xmlrole.c', ]
           )
    setup (name = "PyXML", version = "0.5.4",
           ext_modules =[ expat_extension ] )

Distutils ではソース配布物、バイナリ配布物の作成の面倒もみてくれます。 "sdist" コマンドは "`python setup.py sdist`" を実行することで起動し、これは `foo-1.0.tar.gz` のようなソース配布物を作ります。新しいコマンドを作るのは難しくありません。コマンド "bdist_rpm" と "bdist_wininst" が既に寄稿されていて、各々 RPM 配布物の作成、Windows インストーラの作成を行います。Debian パッケージや Solaris の `.pkg` のようなほかの配布フォーマットを作成するコマンドについての開発ステージは様々です。

これら全ては、 Python ドキュメントの基本的なセットとして追加されたマニュアル Python モジュールの配布 にドキュメントされています。

## XML モジュール

Python 1.5.2 included a simple XML parser in the form of the `xmllib` module, contributed by Sjoerd Mullender. Since 1.5.2's release, two different interfaces for processing XML have become common: SAX2 (version 2 of the Simple API for XML) provides an event-driven interface with some similarities to `xmllib`, and the DOM (Document Object Model) provides a tree-based interface, transforming an XML document into a tree of nodes that can be traversed and modified. Python 2.0 includes a SAX2 interface and a stripped-down DOM interface as part of the `xml` package. Here we will give a brief overview of these new interfaces; consult the Python documentation or the source code for complete details. The Python XML SIG is also working on improved documentation.

### SAX2 サポート

SAX defines an event-driven interface for parsing XML. To use SAX, you must write a SAX handler class. Handler classes inherit from various classes provided by SAX, and override various methods that will then be called by the XML parser. For example, the `startElement()` and `endElement()` methods are called for every starting and end tag encountered by the parser, the `characters()` method is called for every chunk of character data, and so forth.

イベントドリブンのアプローチはドキュメント全体をいっときにメモリに持たなくて良い点で有利であり、ドキュメントが本当に巨大であるものを処理する際にはこれは重要です。ですが SAX ハンドラクラスを記述することは、ドキュメント構造を変更しようとする場合にはある種入り組んだものとなって、とても複雑になりえます。

以下の小さな実例プログラムでは、全ての開始・終了タグでメッセージを印字するハンドラを定義して、ファイル `hamlet.xml` をそのハンドラを使ってパースしています:

    from xml import sax

    class SimpleHandler(sax.ContentHandler):
        def startElement(self, name, attrs):
            print 'Start of element:', name, attrs.keys()

        def endElement(self, name):
            print 'End of element:', name

    # Create a parser object
    parser = sax.make_parser()

    # Tell it what handler to use
    handler = SimpleHandler()
    parser.setContentHandler( handler )

    # Parse a file!
    parser.parse( 'hamlet.xml' )

For more information, consult the Python documentation, or the XML HOWTO at https://pyxml.sourceforge.net/topics/howto/xml-howto.html.

### DOM サポート

The Document Object Model is a tree-based representation for an XML document. A top-level `Document` instance is the root of the tree, and has a single child which is the top-level `Element` instance. This `Element` has children nodes representing character data and any sub-elements, which may have further children of their own, and so forth. Using the DOM you can traverse the resulting tree any way you like, access element and attribute values, insert and delete nodes, and convert the tree back into XML.

DOM は XML ドキュメントを修正するのに有用です。というのも DOM ツリーは作成出来、新規ノードを追加したりサブツリーを再編成したりすることで修正出来、出力として新たな XML ドキュメントを生成出来るからです。DOM ツリーを手動で構築して XML に変換することも出来ます。これにより単純に `<tag1>`...`</tag1>` をファイルに書くよりも柔軟性の高い方法で XML 出力を生成出来ます。

The DOM implementation included with Python lives in the `xml.dom.minidom` module. It's a lightweight implementation of the Level 1 DOM with support for XML namespaces. The `parse()` and `parseString()` convenience functions are provided for generating a DOM tree:

    from xml.dom import minidom
    doc = minidom.parse('hamlet.xml')

`doc` is a `Document` instance. `Document`, like all the other DOM classes such as `Element` and `Text`, is a subclass of the `Node` base class. All the nodes in a DOM tree therefore support certain common methods, such as `toxml()` which returns a string containing the XML representation of the node and its children. Each class also has special methods of its own; for example, `Element` and `Document` instances have a method to find all child elements with a given tag name. Continuing from the previous 2-line example:

    perslist = doc.getElementsByTagName( 'PERSONA' )
    print perslist[0].toxml()
    print perslist[1].toxml()

Hamlet XML ファイルに対して上の例は以下のような出力をします:

    <PERSONA>CLAUDIUS, king of Denmark. </PERSONA>
    <PERSONA>HAMLET, son to the late, and nephew to the present king.</PERSONA>

ドキュメントのルートエレメントは `doc.documentElement` として取得出来、その子は簡単に、ノードを削除したり追加したりすることで修正出来ます:

    root = doc.documentElement

    # Remove the first child
    root.removeChild( root.childNodes[0] )

    # Move the new first child to the end
    root.appendChild( root.childNodes[0] )

    # Insert the new first child (originally,
    # the third child) before the 20th child.
    root.insertBefore( root.childNodes[0], root.childNodes[20] )

Again, I will refer you to the Python documentation for a complete listing of the different `Node` classes and their various methods.

### PyXML との関係

The XML Special Interest Group has been working on XML-related Python code for a while. Its code distribution, called PyXML, is available from the SIG's web pages at https://www.python.org/community/sigs/current/xml-sig. The PyXML distribution also used the package name `xml`. If you've written programs that used PyXML, you're probably wondering about its compatibility with the 2.0 `xml` package.

結論として、Python 2.0 の `xml` パッケージは PyXML と互換性がありません。ですが、直近バージョンの PyXML をインストールすることで互換性を持たせることができます。 多くのアプリケーションは Python 2.0 に含まれる XML サポートで十分ですが、より複雑なアプリケーションは完全なPyXML パッケージをインストールする必要があります。 インストールされた PyXML バージョン 0.6.0 以上は、Python に同梱されている `xml` パッケージを置き換え、標準パッケージの厳密なスーパーセットとなり、多くの追加機能が追加されます。 PyXML の追加機能には次のようなものがあります。

- 4DOM, a full DOM implementation from FourThought, Inc.

- The xmlproc validating parser, written by Lars Marius Garshol.

- The `sgmlop` parser accelerator module, written by Fredrik Lundh.

## 更新されたモジュール

Lots of improvements and bugfixes were made to Python's extensive standard library; some of the affected modules include `readline`, `ConfigParser`, `cgi`, `calendar`, `posix`, `readline`, `xmllib`, `aifc`, `chunk` `wave`, `random`, `shelve`, and `nntplib`. Consult the CVS logs for the exact patch-by-patch details.

Brian Gallew contributed OpenSSL support for the `socket` module. OpenSSL is an implementation of the Secure Socket Layer, which encrypts the data being sent over a socket. When compiling Python, you can edit `Modules/Setup` to include SSL support, which adds an additional function to the `socket` module: `socket.ssl(socket, keyfile, certfile)`, which takes a socket object and returns an SSL socket. The `httplib` and `urllib` modules were also changed to support `https://` URLs, though no one has implemented FTP or SMTP over SSL.

The `httplib` module has been rewritten by Greg Stein to support HTTP/1.1.

Backward compatibility with the 1.5 version of `httplib` is provided, though using HTTP/1.1 features such as pipelining will require rewriting code to use a different set of interfaces.

The `Tkinter` module now supports Tcl/Tk version 8.1, 8.2, or 8.3, and support for the older 7.x versions has been dropped. The Tkinter module now supports displaying Unicode strings in Tk widgets. Also, Fredrik Lundh contributed an optimization which makes operations like `create_line` and `create_polygon` much faster, especially when using lots of coordinates.

`curses` モジュールが、Oliver Andrich による拡張版をもとに大規模に拡張され、ncurses と SYSV curses からの多くの追加機能、例えば色付きの表示、別の文字集合サポート、パッド、マウスサポートなどをサポートするようになりました。このことは、モジュールが BSD curses だけしか持っていない OS とは互換性が無いことを意味しますが、現在メンテナンスされている OS でそういう類のものは無さそうです。

2.0 の Unicode サポートについて前述したように、 `re` モジュールで提供される正規表現の根底となる実装が変更されました。SRE は新しい正規表現エンジンで、Fredrik Lundh によって書かれ、部分的に Hewlett Packard 社により寄贈されました。これは 8 ビット文字列と Unicode 文字列両方に合致するようサポートされています。

## 新しいモジュール

数多くのモジュールが新しく追加されました。ここではそれらを短い説明とともに列挙するだけにします。特定のモジュールの詳細は 2.0 のドキュメントを調べてください。

- `atexit`: Python インタプリタが終了する前に呼び出す関数を登録します。これまで `sys.exitfunc` に直接セットしてきたコードは `atexit` モジュールを代わりに用いるように修正してください。 `atexit` をインポートし、 `atexit.register()` で終了時に呼び出す関数を登録します。(Contributed by Skip Montanaro.)

- `codecs`, `encodings`, `unicodedata`: Added as part of the new Unicode support.

- `filecmp`: Supersedes the old `cmp`, `cmpcache` and `dircmp` modules, which have now become deprecated. (Contributed by Gordon MacMillan and Moshe Zadka.)

- `gettext`: このモジュールは Python プログラムに、GNU gettext メッセージカタログライブラリへのインターフェイスを提供することで国際化 (I18N=internationalization) と地域化 (L10N=localization) サポートをもたらします。 (Integrated by Barry Warsaw, from separate contributions by Martin von Löwis, Peter Funk, and James Henstridge.)

- `linuxaudiodev`: Support for the `/dev/audio` device on Linux, a twin to the existing `sunaudiodev` module. (Contributed by Peter Bosch, with fixes by Jeremy Hylton.)

- `mmap`: Windows、Unix 両方でのメモリマップドファイルへのインターフェイスです。ファイル内容をメモリに直接マッピング出来、それは mutable な文字列であるかのように振る舞い、これにより読み書き出来ます。それらは例えば `re` モジュールのような普通は文字列を期待するような関数にさえも渡せます。(Contributed by Sam Rushing, with some extensions by A.M. Kuchling.)

- `pyexpat`: An interface to the Expat XML parser. (Contributed by Paul Prescod.)

- `robotparser`: Parse a `robots.txt` file, which is used for writing web spiders that politely avoid certain areas of a web site. The parser accepts the contents of a `robots.txt` file, builds a set of rules from it, and can then answer questions about the fetchability of a given URL. (Contributed by Skip Montanaro.)

- `tabnanny`: Python ソースコードが曖昧なインデントになっていないかをチェックするモジュール/スクリプトです。 (Contributed by Tim Peters.)

- `UserString`: A base class useful for deriving objects that behave like strings.

- `webbrowser`: 指定した URL で、プラットフォームに依存しない方法でウェブブラウザを起動するモジュールです。個々のプラットフォームにおいて様々なブラウザが特定の順序で試されます。ユーザはどのブラウザを起動するかを環境変数 BROWSER をセットすることで変更出来ます。(元々は Eric S. Raymond による `urllib` への、同じ機能追加をするパッチに触発されましたが、最終的なモジュールは Fred Drake が元々 `Tools/idle/BrowserControl.py` として実装したものに由来し、Fred が標準ライブラリに適合させました。)

- `_winreg`: An interface to the Windows registry. `_winreg` is an adaptation of functions that have been part of PythonWin since 1995, but has now been added to the core distribution, and enhanced to support Unicode. `_winreg` was written by Bill Tutt and Mark Hammond.

- `zipfile`: ZIP 形式アーカイブの読み書きのためのモジュールです。DOS/Windows での PKZIP や Unix での zip により生成されるアーカイブで、 gzip 形式とは混同しないで下さい (こちらは `gzip` モジュールによってサポートされています)。(Contributed by James C. Ahlstrom.)

- `imputil`: A module that provides a simpler way for writing customized import hooks, in comparison to the existing `ihooks` module. (Implemented by Greg Stein, with much discussion on python-dev along the way.)

## IDLE の改善

IDLE は公式の Python のクロスプラットフォームな IDE で、 Tkinter を使って書かれています。Python 2.0 では IDLE 0.6 を含めました。これは多くの新機能追加と改善がなされています。以下はその一部です:

- UI の、特にシンタックスハイライトと自動インデントの領域において、改善と最適化がなされました。

- クラスブラウザで、例えばモジュール内のトップレベル関数のような、より多くの情報をみることが出来るようになりました。

- タブ幅をユーザ制御出来るようになりました。既存の Python ファイルを操作する際には、IDLE は自動的にインデントの慣習を検知してそれに合わせます。

- 色々なプラットフォームでブラウザの呼び出しがサポートされています。これを使って、ブラウザで Python ドキュメントを開きます。

- IDLE がコマンドラインを持つようになりました。これは普通の Python インタプリタに大きく似せてあります。

- 色々な場所でコンテキストヘルプが出るようになっています。

- IDLE は今ではパッケージとしてインストール出来ます。

- エディタウィンドウ内では、下部に行/桁を表示するようになっています。

- 新たな 3 つのキーストロークコマンド: モジュールのチェック (`Alt`-`F5`)、モジュールのインポート (`F5`)、スクリプト実行 (`Ctrl`-`F5`).

## 削除されたモジュール、非推奨となったモジュール

A few modules have been dropped because they're obsolete, or because there are now better ways to do the same thing. The `stdwin` module is gone; it was for a platform-independent windowing toolkit that's no longer developed.

A number of modules have been moved to the `lib-old` subdirectory: `cmp`, `cmpcache`, `dircmp`, `dump`, `find`, `grep`, `packmail`, `poly`, `util`, `whatsound`, `zmod`. If you have code which relies on a module that's been moved to `lib-old`, you can simply add that directory to `sys.path` to get them back, but you're encouraged to update any code that uses these modules.

## 謝辞

著者は提案の申し出や修正、様々なこの記事の草稿の助けをしてくれた以下の人々に感謝します: David Bolen, Mark Hammond, Gregg Hauser, Jeremy Hylton, Fredrik Lundh, Detlef Lannert, Aahz Maruch, Skip Montanaro, Vladimir Marangozov, Tobias Polzin, Guido van Rossum, Neil Schemenauer, and Russ Schmidt.