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 文字は新しく追加されたエスケープシーケンスで書きま
す。 "\u*HHHH*" のように書き、 *HHHH* は 0000 から FFFF までの 4 桁の
16 進表記数です。以前からあるエスケープシーケンス "\x*HH*" も使えます
し、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.
