What's New in Python 2.3
************************

著者:
   A.M. Kuchling

この文書は Python 2.3 の新機能について解説します。Python 2.3 は 2003
年 7 月 29 日にリリースされました。

Python 2.3 の主要なテーマは、2.2 で追加されたいくつかの機能を磨くこと
、言語中核に小さいながらも有用な種々の拡張をすること、そして標準ライブ
ラリの拡充です。ひとつ前のバージョンで導入された新しいオブジェクトモデ
ルは、18 ヶ月に渡るバグフィックスと新スタイルクラスの性能改善をもたら
した最適化の努力の恩恵を受けました。 "sum()", "enumerate()" のような、
新たなビルトイン関数が少し追加されました。 "in" 演算子がサブストリング
の検索に使えるようになりました (例えば ""ab" in "abc"" は "True" を返
します)。

たくさんのライブラリ新機能…、Boolean、 set、 heap、 日付/時刻データ型
、ZIP 形式アーカイブからのモジュールインポート、待ち望まれていた
Python カタログのためのメタデータサポート、更新されたバージョンの IDLE
、ロギングメッセージのためのモジュール、テキストの折り返し、CSV ファイ
ルの解析、コマンドラインオプションの処理、BerkeleyDB データベースの使
用…、新機能、強化機能のリストは長大になります。

このドキュメントは個々の新機能の完全な詳細を提供するのではなくて、簡易
な概要を提供することを目的にしています。完全な詳細が知りたければ、
Python ライブラリリファレンス、Python リファレンスマニュアルのような
Python 2.4 のドキュメントを参照してください。設計と実装の根拠を理解し
たい場合は、新機能に関する PEP を参照してください。


PEP 218: 標準の集合データ型
===========================

(---訳注: イキナリですが、あなたが今これを「Python の歴史を知る」もし
くは「初登場時の熱量高い紹介」を読みたくて読んでいるのでない限りは、も
しくは本当に今 2.3 を使う必要があれば別ですが、このモジュールは 2.4 で
既にビルトインで置き換えられ、2.6 では非推奨となり、3.0 では削除されて
います。ので、集合型について知りたければここよりも 2.4 のビルトインの
方から読んだ方が良いです。---) --- 新しいモジュール "sets" には、集合
データ型の実装が含まれています。 "Set" クラスは *mutable* の集合のため
のクラスで、メンバの追加と削除が出来ます。 "ImmutableSet" は変更できな
い集合のためのクラスなので、辞書のキーとして利用出来ます。集合型は辞書
の上に構築されているので、集合内の要素はハッシュ可能でなければなりませ
ん。

単純な使用例です:

   >>> import sets
   >>> S = sets.Set([1,2,3])
   >>> S
   Set([1, 2, 3])
   >>> 1 in S
   True
   >>> 0 in S
   False
   >>> S.add(5)
   >>> S.remove(3)
   >>> S
   Set([1, 2, 5])
   >>>

和集合 (union) と共通集合 (intersection) は "union()" と
"intersection()" メソッドで計算出来ます; 別の記法として、ビット演算子
"&" と "|" も使えます。変更可能な集合ではこれらのインプレイス版
"union_update()" と "intersection_update()" も使えます:

   >>> S1 = sets.Set([1,2,3])
   >>> S2 = sets.Set([4,5,6])
   >>> S1.union(S2)
   Set([1, 2, 3, 4, 5, 6])
   >>> S1 | S2                  # Alternative notation
   Set([1, 2, 3, 4, 5, 6])
   >>> S1.intersection(S2)
   Set([])
   >>> S1 & S2                  # Alternative notation
   Set([])
   >>> S1.union_update(S2)
   >>> S1
   Set([1, 2, 3, 4, 5, 6])
   >>>

It's also possible to take the symmetric difference of two sets.  This
is the set of all elements in the union that aren't in the
intersection.  Another way of putting it is that the symmetric
difference contains all elements that are in exactly one set.  Again,
there's an alternative notation ("^"), and an in-place version with
the ungainly name "symmetric_difference_update()".

   >>> S1 = sets.Set([1,2,3,4])
   >>> S2 = sets.Set([3,4,5,6])
   >>> S1.symmetric_difference(S2)
   Set([1, 2, 5, 6])
   >>> S1 ^ S2
   Set([1, 2, 5, 6])
   >>>

"issubset()" と "issuperset()" メソッドも使えます。これはある集合が部
分集合、上位集合であるかとうかをチェックします:

   >>> S1 = sets.Set([1,2,3])
   >>> S2 = sets.Set([2,3])
   >>> S2.issubset(S1)
   True
   >>> S1.issubset(S2)
   False
   >>> S1.issuperset(S2)
   True
   >>>

参考:

  **PEP 218** - 集合オブジェクト型をビルトインに追加する
     PEP 著 Greg V. Wilson. 実装: Greg V. Wilson, Alex Martelli, GvR.
     (---訳注: PEPそのものは 2.4 のビルトイン型 set, frozenset の追加
     と同じものですが、2.3 ではモジュールとして追加され、2.4 でビルト
     イン版が追加され、2.6 でモジュール版が非推奨となった、という流れ
     です。---)


PEP 255: 単純なジェネレータ
===========================

Python 2.2 では、ジェネレータが "from __future__ import generators" デ
ィレクティブで有効に出来るオプションの機能として追加されました。2.3 で
はジェネレータは特別に有効化する必要なく、もういつでもそこにあります。
このセクションの残りの部分は "What's New in Python 2.2" のジェネレータ
の記述からの丸々コピーですので、2.2 のときに読んだなら読み飛ばしてもら
って結構です。

Python や C の標準的な関数コールについては、よくご存じに違いありません
。関数を呼ぶと、ローカル変数を作るプライベートな名前空間ができますね。
その関数が "return" 文まで来ると、ローカル変数が破壊されてから、返り値
が呼び出し元に返ります。次に同じ関数をもう一度呼ぶと、新しいプライベー
ト名前空間に新規のローカル変数が作られるのです。しかし、関数を出るとき
にローカル変数を捨てなければどうなるでしょうか。その出ていったところか
ら関数を続行できたとしたら、どうでしょう。これこそジェネレータが提供す
る機能です; すなわち、ジェネレータは続行できる関数と考えることができま
す。

ジェネレータ関数の最も単純な例です:

   def generate_ints(N):
       for i in range(N):
           yield i

新しいキーワード "yield" がジェネレータのために導入されました。
"yield" ステートメントを含むどんな関数もジェネレータ関数です; Python
バイトコードコンパイラはこれを検知し、関数が特別に扱われるように翻訳し
ます。 (---訳注: Python 2.5 の PEP 342 も参照して下さい。この 2.2 で導
入時点の "yield" はステートメントではなく式に変更されています。---)

ジェネレータ関数を呼び出すと、単一の値の代わりにイテレータプロトコルに
対応したオブジェクトを返します。上の例で "yield" を実行したとき、ジェ
ネレータは "return" 文のようにして "i" の値を生成します。 "yield" と
"return" 文の大きな違いは、 "yield" に到達した段階でジェネレータの実行
状態が一時停止になって、ローカル変数が保存される点です。次回そのジェネ
レータの ".next()" メソッドを呼ぶと、 "yield" の直後から関数が実行を再
開します。(複雑な理由により、 "yield" は "try"..."finally" の "try" ブ
ロック内に含めることは許されていません; **PEP 255** に "yield" と例外
の相互作用についての詳細説明がありますので参照して下さい。) --- (---訳
注: Python 2.5 の PEP 342 で "try"..."finally" 内に置けないという制約
はなくなりました。また、 "try"..."finally" の "try" 、とここであえて特
定しているのは、同じく 2.5 の PEP 341 によって try/except/finally の一
体化されるまでは、 "finally" の "try" と "except" の "try" が別物だっ
たからです。---)

上記 "generate_ints()" ジェネレータはこんな具合に使います:

   >>> gen = generate_ints(3)
   >>> gen
   <generator object at 0x8117f90>
   >>> gen.next()
   0
   >>> gen.next()
   1
   >>> gen.next()
   2
   >>> gen.next()
   Traceback (most recent call last):
     File "stdin", line 1, in ?
     File "stdin", line 2, in generate_ints
   StopIteration

同じく "for i in generate_ints(5)" や "a,b,c = generate_ints(3)" とい
った書き方もできます。

ジェネレータ関数内で "return" 文は、引数を付けずに、処理の終わりを知ら
せるためにだけ使うことができます; "return" を実行したあとは、もうその
ジェネレータが値を返すことはできません。ジェネレータ関数の中では、
"return 5" などと値を付けた "return" は構文エラーです。ジェネレータの
出力が終わったことを示すには、ほかにも、手動で "StopIteration"  を投げ
てもいいですし、関数の最後まで実行するだけでも同じことになります。(---
訳注: Python 2.7 まではジェネレータ内での戻り値のある "return 5" は構
文エラーになりますが、少なくとも Python 3.4 で構文エラーとはなりません
。単に無視されます。リファレンスに言及されていない振舞いなので、何かの
事故かもしれません。いずれにせよジェネレータ内では Python 3 でも
"return" で値は戻せません。---)

自分でクラスを書いて、ジェネレータで言うところのローカル変数をインスタ
ンス変数として全部保管しておけば、同じ効果を得ることは可能です。たとえ
ば整数のリストを返すのは、 "self.count" を 0 にして、 "next()" メソッ
ドが "self.count" をインクリメントして返すようにすればできます。しかし
ながら、ある程度複雑なジェネレータになってくると、同じことをするクラス
を書くのは格段にややこしいことになります。
"Lib/test/test_generators.py" にはもっと面白い例がたくさん含まれていま
す。一番単純な一つは、ジェネレータを再帰的に使ってツリーを順繰りに横断
する実装をするこれです (---訳注: ジェネレータは現在の最新 3.5 までの間
に 2 度大きな機能強化が行われているのですが、一つが 2.5 での PEP 342
でこれは yield 「に」値を戻せるようにするものです。もう一つが 3.3 での
PEP 380 で、これはサブジェネレータへの委譲 "yield from <subgen>" の追
加でした。ですのでこの 3.3 からの "yield from" を使うと下記例はもっと
スッキリ書けます。---):

   # A recursive generator that generates Tree leaves in in-order.
   def inorder(t):
       if t:
           for x in inorder(t.left):
               yield x
           yield t.label
           for x in inorder(t.right):
               yield x

ほかにも:file:*Lib/test/test_generators.py* には、N-Queens 問題 (N×N
コマのチェス盤に、互いに攻撃できないような配置で N 個のクイーンを置く)
やナイト・ツアー (N×N 盤の全コマをナイトが一度ずつ通るような経路を探す
) の解を出す例が入っています。

ジェネレータの発想はほかのプログラミング言語、特に Icon
(https://www.cs.arizona.edu/icon/) から着想しています。Icon ではジェネ
レータが言語の中枢になっています。Icon では、あらゆる式と関数がジェネ
レータのように振舞います。
https://www.cs.arizona.edu/icon/docs/ipd266.htm の "Icon プログラミン
グ言語の概要" の一つの例が、これがどのようなものであるのかを教えてくれ
ます:

   sentence := "Store it in the neighboring harbor"
   if (i := find("or", sentence)) > 5 then write(i)

Icon では "find()" 関数は部分文字列 "or" が見つかる位置 3, 23, 33 を返
します。 "if" 文内では "i" には最初 3 が代入されますが、これは 3 より
小さいので比較は失敗し、Icon は次の値 23 を取り出します。 23 は 5 より
大きいので比較は成功し、コードは 23 をスクリーンに表示します。

Python では Icon がそうするほどにはジェネレータを中心的概念に置きませ
ん。ジェネレータは Python 言語中核の新たな一面ではありますが、それらを
学ぶのも使うのも誰しも行うべきだというものでもなく、そしてこれで解決で
きない何か問題があれば、忘れてしまっても良いものです。Icon と比較した
特筆すべき Python インターフェイスの機能はジェネレータの状態が具象オブ
ジェクト (イテレータ) で表現されることであり、それは他の関数に渡せます
し、データ構造に記憶しておくことも出来ます。(---訳注: ジェネレータにつ
いてかなり控えめなのは、この時点で著者は将来の拡張を既に見据えていたか
ら? かもしれませんね。PEP 342 と PEP 380 により今やジェネレータはこの
頃より遥かに高機能になっており、今ではきっと「こんなものなくても困らな
い」なんて Python 使いはいないでしょう。---)

参考:

  **PEP 255** - 単純なジェネレータ
     Neil Schemenauer, Tim Peters, Magnus Lie Hetland により著されまし
     た。実装のほとんどは Neil Schemenauer と Tim Peters により行われ
     、 Python Labs クルーにより他の修正が行われました。


PEP 263: ソースコードのエンコーディング
=======================================

Python ソースファイルで、異なる文字セットエンコーディングを宣言出来る
ようになりました。エンコーディングはソースコードの 1 行目か 2 行目に特
殊形式のコメントを含めることで宣言出来ます。 UTF-8 ファイルであればこ
のように宣言出来ます:

   #!/usr/bin/env python
   # -*- coding: UTF-8 -*-

このエンコーディング宣言がなければ、デフォルトの 7 ビット ASCII エンコ
ーディングが使われます(訳注: Python 3 からはデフォルトは utf-8 (PEP
3120))。8 ビット文字を含んでいるのにエンコーディング宣言がないモジュー
ルの実行やインポートを行うと、 Python 2.3 では "DeprecationWarning" を
引き起こします; 2.4 ではこれは構文エラーになる予定です(訳注: 実際には
2.4 ではこれは実現せず、2.5 から)。

エンコーディング宣言は Unicode 文字列リテラルにのみ影響します。それら
は指定したエンコーディングで Unicode 文字列に変換されます。Python 識別
子は今でも ASCII 文字列に制限されていることに注意してください。ですか
ら普通の英数字範囲外の文字を変数名に使うことは出来ません。

参考:

  **PEP 263** - Python ソースコードのエンコーディングを定義する
     Marc-André Lemburg、 Martin von Löwis 著; Suzuki Hisao、 Martin
     von Löwis 実装.


PEP 273: Zip アーカイブからモジュールをインポートする
=====================================================

The new "zipimport" module adds support for importing modules from a
ZIP-format archive.  You don't need to import the module explicitly;
it will be automatically imported if a ZIP archive's filename is added
to "sys.path". For example:

   amk@nyman:~/src/python$ unzip -l /tmp/example.zip
   Archive:  /tmp/example.zip
     Length     Date   Time    Name
    --------    ----   ----    ----
        8467  11-26-02 22:30   jwzthreading.py
    --------                   -------
        8467                   1 file
   amk@nyman:~/src/python$ ./python
   Python 2.3 (#1, Aug 1 2003, 19:54:32)
   >>> import sys
   >>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
   >>> import jwzthreading
   >>> jwzthreading.__file__
   '/tmp/example.zip/jwzthreading.py'
   >>>

"sys.path" には今や ZIP 書庫のファイル名も入れることが出来ます。ZIP ア
ーカイブ内にはどんなファイルを置いてもかまいませんが、import できるの
は "*.py", "*.pyc", "*.pyo" だけです。書庫に "*.py" だけが含まれる場合
には、Python は書庫を修正して対応する "*.pyc" を作るなどということはし
ないので、 "*.pyc" ファイルを含まない ZIP 書庫からのインポートはやや遅
いかもしれません。

書庫内のパスをサブディレクトリ以下のみインポートするように指定出来ます
; 例えば、パス "/tmp/example.zip/lib/" はその書庫内の "lib/" サブディ
レクトリだけからインポートします。

参考:

  **PEP 273** - Zip アーカイブからモジュールをインポートする
     このモジュールの実装も行った、James C. Ahlstrom による PEP です。
     Python 2.3 は  **PEP 273** の仕様に従っていますが、 Just van
     Rossum の書いた、 **PEP 302** に記述されている import フックによ
     る実装を使っています。その新しい import フックについては  PEP
     302: 新たなインポートフック  をみてください。


PEP 277: Windows NT での Unicode ファイル名サポート
===================================================

Windows NT, 2000, XP では、ファイルシステムはファイル名として Unicode
文字列を使います。伝統的に Python はファイル名をバイト文字列として表現
してきましたが、それはアクセス出来ないファイル名を表してしまう場合があ
って、不十分でした。

Python はいまや (ファイルシステムの制約の範囲内での) 任意の Unicode 文
字列をファイル名が期待される全ての関数で許容します。 "os.listdir()" に
Unicode 文字列が渡されれば、Python は今では Unicode 文字列のリストを返
します。新しい関数 "os.getcwdu()" は Unicode 文字列でカレントディレク
トリを返します(訳注: ちなみに Python 3 での Unicode 周りの大改造に伴い
この関数はなくなり、代わりに「あえてバイト列のほうを返す」
"os.getcwdb" が追加されています("os.getcwdu" がもはや Unicode を返すの
で)。)。

ファイル名のバイト文字列はいまでも動きます。Windows 版 Python は透過的
にそれらを Unicode に "mbcs" エンコーディングを使って変換します。

ほかのシステムでもファイル名の Unicode は許容されますが、システムに渡
す前にバイト文字列に変換され、 "UnicodeError" 例外を引き起こすかもしれ
ません。アプリケーションは任意の Unicode 文字列がファイル名に許される
かどうかを、ブーリアン値 "os.path.supports_unicode_filenames" をチェッ
クすることでテスト出来ます。

MacOS では、 "os.listdir()" は Unicode ファイル名を返すようになってい
るでしょう。

参考:

  **PEP 277** - Windows NT での Unicode ファイル名サポート
     Neil Hodgson 著; 実装 Neil Hodgson, Martin von Löwis, Mark
     Hammond。


PEP 278: Universal Newline サポート
===================================

The three major operating systems used today are Microsoft Windows,
Apple's Macintosh OS, and the various Unix derivatives.  A minor
irritation of cross-platform work  is that these three platforms all
use different characters to mark the ends of lines in text files.
Unix uses the linefeed (ASCII character 10), MacOS uses the carriage
return (ASCII character 13), and Windows uses a two-character sequence
of a carriage return plus a newline.

Python のファイルオブジェクトが、動作しているプラットフォームに従わな
い行終端変換をサポートするようになりました。ファイルのオープンにモード
"'U'" や "'rU'" を使うと、 *universal newlines* モードを使った読み込み
としてファイルを開きます。これで "read()", "readline()" などのファイル
メソッドが、 3 つどの行終端でも "'\n'" に翻訳して返すようになります。

universal newline サポートはモジュールのインポートと "execfile()" 関数
でのファイル実行にも使われます。これで 3 つ全てのオペレーティングシス
テム間で行終端変換の必要なく Python モジュールを共有出来ます。

This feature can be disabled when compiling Python by specifying the "
--without-universal-newlines" switch when running Python's
**configure** script.

参考:

  **PEP 278** : Universal Newline サポート
     Jack Jansen 著、実装


PEP 279: enumerate()
====================

新たな組み込み関数 "enumerate()" はある種のループ処理を少し簡潔にする
ものです。 *thing* がイテレータかシーケンスだとして、
"enumerate(thing)" は "(0, thing[0])", "(1, thing[1])", "(2,
thing[2])", … を生成するイテレータを返します。

リストの全てを変更するためのよくあるイディオムはこのようなものでしょう
:

   for i in range(len(L)):
       item = L[i]
       # ... compute some result based on item ...
       L[i] = result

これは "enumerate()" を使ってこのように書き換えることが出来ます:

   for i, item in enumerate(L):
       # ... compute some result based on item ...
       L[i] = result

参考:

  **PEP 279** - 組み込み関数 enumerate()
     Raymond D. Hettinger 著、実装.


PEP 282: ロギングパッケージ
===========================

ログ記録のための標準パッケージ "logging" が Python 2.3 に追加されてい
ます。それはログ出力生成の強力で柔軟なメカニズムを提供し、フィルタと加
工を色々な方法で行えます。標準フォーマットで書く設定ファイルで、プログ
ラムのロギングの振る舞いを制御出来ます。ログレコードを標準エラー出力や
ファイルやソケット、システムログへの送信、あるいは e-mail 送信するよう
なハンドラが Python に含まれています。もちろん、あなた自身のハンドラク
ラスを書くことも出来ます。

"Logger" が最も重要なクラスです。ほとんどのアプリケーションコードは一
つかそれ以上の "Logger" オブジェクトを扱い、それぞれ一つはそのアプリケ
ーションの特定のサブシステムで使われるでしょう。それぞれの "Logger" は
名前で識別され、名前は "." をコンポーネントのセパレータとして使う階層
で体系化されます。例えば "server", "server.auth", "server.network" と
いった名前の "Logger" インスタンスを持つといった具合です。この例の後ろ
2 つは階層で "server" の下にあります。 "server" への冗長性を見つけた場
合や "server" メッセージを直接異なるハンドラに向けた場合、変更は
"server.auth" と "server.network" へのログ記録にも適用されるということ
です。全てのほかのロガーの親となる、ルート "Logger" もあります。

単純な用法のために、 "logging" パッケージはいくつかの便利関数を含んで
いて、これは常にルートログを使います:

   import logging

   logging.debug('Debugging information')
   logging.info('Informational message')
   logging.warning('Warning:config file %s not found', 'server.conf')
   logging.error('Error occurred')
   logging.critical('Critical error -- shutting down')

上記のコードは以下のような出力になります:

   WARNING:root:Warning:config file server.conf not found
   ERROR:root:Error occurred
   CRITICAL:root:Critical error -- shutting down

デフォルトの設定では、情報メッセージとデバッグメッセージは揉み消され、
また、出力は標準エラー出力に送られます。情報メッセージとデバッグメッセ
ージ表示の有効化は、ルートロガーの "setLevel()" メソッドを呼び出して行
えます。

上の例での "warning()" 呼び出しの文字列フォーマットの操作に注目してく
ださい。全てのログメッセージ関数は、引数 "(msg, arg1, arg2, ...)" を取
り、 "msg % (arg1, arg2, ...)" の結果の文字列をログ出力します。

最も最新のトレースバックを記録する "exception()" 関数もあります。他の
全ての関数も、 *exc_info* 引数を真にすればトレースバックを記録します。
:

   def f():
       try:    1/0
       except: logging.exception('Problem recorded')

   f()

上記のコードは以下のような出力になります:

   ERROR:root:Problem recorded
   Traceback (most recent call last):
     File "t.py", line 6, in f
       1/0
   ZeroDivisionError: integer division or modulo by zero

多少なりとも高度なプログラムでは、ルートロガー以上のロガーを使うでしょ
う。 "getLogger(name)" 関数は特定のロガーを取得するのに使います。その
時点で存在していなければ、作成されます。 "getLogger(None)" はルートロ
ガーを返します。:

   log = logging.getLogger('server')
    ...
   log.info('Listening on port %i', port)
    ...
   log.critical('Disk full')
    ...

ログレコードは普通階層を上に向かって伝播するので、 "server.auth" への
ログは "server" と "root" にも見られますが、 "Logger" はこれを
"propagate" 属性に "False" を設定することで避けれます。

"logging" パッケージにはさらに、カスタマイズ可能なクラス群があります。
"Logger" インスタンスにログメッセージを伝える際、それは "LogRecord" イ
ンスタンスを作って、任意の数の異なる "Handler" インスタンスへ送ります
。ロガーとハンドラにはフィルタのリストを取り付けることも出来、それぞれ
のフィルタは無視する "LogRecord" を決めたり、渡す前にレコードを修正し
たり出来ます。それらが最後に出力される際、 "LogRecord" インスタンスは
"Formatter" クラスによりテキストに変換されます。これら全てのクラスはあ
なた自身の特別に書いたクラスに置き換え可能です。

これら全ての機能で "logging" パッケージは最も複雑なアプリケーションで
さえ、十分な柔軟性を提供しているはずです。ここではそれら機能の不完全な
概要しか示しませんでしたので、全ての詳細はパッケージのドキュメントを参
照してください。 **PEP 282** を読むことも助けになるでしょう。(---訳注:
今ではクックブックもあるのでそちらもどうぞ。---)

参考:

  **PEP 282** - ログシステム
     PEP 著: Vinay Sajip と Trent Mick; 実装: Vinay Sajip.


PEP 285: Boolean 型
===================

真偽値型 (Boolean) が Python 2.3 に追加されました。関連して 2 つの定数
"True" と "False" が "__builtin__" モジュールに追加されています。(定数
"True" と "False" は Python 2.2.1 にはビルトインに追加されてはいたので
すが、 2.2.1 版のものは単純に整数の 1 と 0 をセットしただけのもので、
独立した真偽値型ではありませんでした。)

この新しい型の型オブジェクトの名前は "bool" です; これのコンストラクタ
は任意の Python 値を取り、 "True" または "False" に変換します:

   >>> bool(1)
   True
   >>> bool(0)
   False
   >>> bool([])
   False
   >>> bool( (1,) )
   True

標準ライブラリモジュールとビルトイン関数のほとんどが、そうすべきときに
は Boolean を返すように変更されました:

   >>> obj = []
   >>> hasattr(obj, 'append')
   True
   >>> isinstance(obj, list)
   True
   >>> isinstance(obj, tuple)
   False

Python の Boolean はコードを明快にすることを主たる目標として追加されま
した。例えばあなたがコードを読んでいて "return 1" に出くわした場合、あ
なたは考えるはずです。この "1" は、真偽としての真値なのであろうか、そ
れともインデクスだろうか、はたまた何かほかの数量に掛ける係数だろうか、
と。 "return True" であればその意味するところはかなり明らかです。

Python の Boolean は、厳格な型チェックを目的として追加された *のではあ
りません* 。Pascal のようなとても厳格な言語では、Boolean の数学演算も
阻むでしょうし、 "if" ステートメントの式が必ず Boolean の結果に評価さ
れなければならないことを要求するでしょう。 Python はこの厳しさを今持ち
ませんし、 **PEP 285** が名言するように、未来永劫持つことはありません
。このことは、 "if" ステートメントにこれからも任意の式を書けることを意
味しますし、リストやらタプルやら何かほかのデタラメなオブジェクトに評価
されるものでも良いことを意味します。Boolean 型は "int" クラスのサブク
ラスであって、Boolean の算術演算はこれからも動作します:

   >>> True + 1
   2
   >>> False + 1
   1
   >>> False * 75
   0
   >>> True * 75
   75

"True" と "False" はぶっちゃけて言えば…: これらは整数値 1 と 0 の別名
だけれども唯一異なるのは "str()" と "repr()" が "'1'" と "'0'" ではな
く "'True'" と "'False'" を返すことだけである。

参考:

  **PEP 285** - 真偽値型の追加
     Guido van Rossum 著、実装


PEP 293: コーデックエラーを処理するコールバック
===============================================

Unicode 文字列をバイト文字列にエンコードする際には、エンコード出来ない
文字に出会うことがあります。いまのところ Python は、そのエラー処理とし
て "strict" ("UnicodeError" を発生させる)、  "ignore" (その文字をスキ
ップする)、 "replace" (出力文字列ではクエッションマークに置換する)、の
いずれか一つを指定出来て、 "strict" がデフォルトの振る舞いになっていま
す。その種のエラーのために、ほかの代わりとなる処理が望ましいかもしれま
せん。例えば XML や HTML の実体参照に置き換えるなどの。

Python は今や、異なる処理戦略を追加する柔軟なフレームワークを手にしま
した。新しいエラーハンドラを "codecs.register_error()" で追加出来、コ
ーデックは "codecs.lookup_error()" を使ってそのエラーハンドラにアクセ
ス出来ます。等価な C API も C で書かれたコーデックのために追加されてい
ます。エラーハンドラは、変換すべき文字列、そのエラーが検出されたその文
字列内での位置、ターゲットエンコーディングのような必要な状態情報を受け
取ります。ハンドラは例外を投げるか、置換文字列を返せます。

このフレームワークを使って 2 つのエラーハンドラが実装されました:
"backslashreplace" はエンコード出来ない文字をバックスラッシュで引用し
、 "xmlcharrefreplace" は XML 文字参照を発行します。

参考:

  **PEP 293** - コーデックエラーを処理するコールバック
     Walter Dörwald 著、実装


PEP 301: パッケージインデクスと、 Distutils のためのメタデータ
==============================================================

長い間要望されてきた Python カタログのサポートが 2.3 で初登場です。

カタログの心臓部は Distutils の新コマンド **register** です。 "python
setup.py register" を実行すると、名前、バージョン、メンテナ、説明、ラ
イセンスのようなパッケージ記述のメタデータを収集して、中央カタログサー
バに送信します。結果のカタログは https://pypi.org で利用可能です。

カタログ作成をもう少し便利にするために、Distutils の "setup()" 関数に
新たにオプショナルな *classifiers* キーワード引数が追加されています。
Trove スタイルの文字列のリストは、ソフトウェアの分類を助けるために与え
ることが出来ます。

以下は "setup.py" に分類指定子 (classifier) を記述する例です。
Distutils の古いバージョンと互換になるように書いています。:

   from distutils import core
   kw = {'name': "Quixote",
         'version': "0.5.1",
         'description': "A highly Pythonic Web application framework",
         # ...
         }

   if (hasattr(core, 'setup_keywords') and
       'classifiers' in core.setup_keywords):
       kw['classifiers'] = \
           ['Topic :: Internet :: WWW/HTTP :: Dynamic Content',
            'Environment :: No Input/Output (Daemon)',
            'Intended Audience :: Developers'],

   core.setup(**kw)

classifier の完全なリストは "python setup.py register --list-
classifiers" と実行することで得ることが出来ます。

参考:

  **PEP 301** - Package Index and Metadata for Distutils
     Richard Jones 著、実装


PEP 302: 新たなインポートフック
===============================

カスタムなインポートフックを書くことは、Python 1.3 で "ihooks" モジュ
ールが導入されたその日からずっと可能でした。それでも本当のところそれで
幸せになった人は誰一人いません。それで新しいインポートフックを書くのが
難しくてとっ散らかっていたからです。 "imputil" と "iu" モジュール のよ
うな代わりとなる色々な提案がありましたが、そのいずれも多くの賛同を得る
ことが出来たものはありませんし、そのいずれもが簡単に C コードから使う
ことが出来ませんでした。

**PEP 302** はその先駆者、特に Gordon McMillan の "iu" モジュールから
アイディアを借りています。3 つの新たなアイテムが "sys" モジュールに追
加されています:

* "sys.path_hooks" は呼び出し可能オブジェクトのリストです。ほとんど
  の 場合クラスになるでしょう。それぞれの呼び出し可能オブジェクトは、
  パス を含む文字列を受け取って、このパスからインポートを処理するイン
  ポータ ーオブジェクトを返すか、このパスを処理出来なければ
  "ImportError" を 送出します。

* "sys.path_importer_cache" はそれぞれのパスごとのインポーターオブジ
  ェ クトをキャッシュしますので、 "sys.path_hooks" は個々のパスを一回
  だけ 横断すれば良いことになります。

* "sys.meta_path" は "sys.path" がチェックされる前に横断させるインポ
  ー ターオブジェクトのリストです(訳注: ここだけ読むとわかりにくいです
  が ライブラリリファレンスを読めばわかります)。このリストは初期状態で
  空 ですが、ユーザコードがオブジェクトをそれに追加出来ます。追加のビ
  ルト インと凍結モジュールを、このリストにオブジェクトを追加すること
  によっ てインポートさせることが出来ます。

インポーターオブジェクトは一つのメソッド "find_module(fullname,
path=None)" を持たなければなりません。 *fullname* はモジュールかパッケ
ージの名前です。例えば "string" や "distutils.core" です。
"find_module()" メソッドは一つのメソッド "load_module(fullname)" を持
つローダーオブジェクトを返さなければなりません。
"load_module(fullname)" では対応するモジュールオブジェクトを生成して返
します。

Python の新しいインポートのロジックは、なので、擬似コードで示すとだい
たいこんな感じです (少し単純化しています; 完全な詳細は **PEP 302** 参
照):

   for mp in sys.meta_path:
       loader = mp(fullname)
       if loader is not None:
           <module> = loader.load_module(fullname)

   for path in sys.path:
       for hook in sys.path_hooks:
           try:
               importer = hook(path)
           except ImportError:
               # ImportError, so try the other path hooks
               pass
           else:
               loader = importer.find_module(fullname)
               <module> = loader.load_module(fullname)

   # Not found!
   raise ImportError

参考:

  **PEP 302** - 新たなインポートフック
     Just van Rossum、Paul Moore 著、実装 Just van Rossum。


PEP 305: カンマ区切り形式ファイル
=================================

カンマ区切りファイルは、データベースやスプレッドシートからのエキスポー
トのために頻繁に使われるフォーマットです。Python 2.3 はカンマ区切りフ
ァイルのパーサを追加しました。

カンマ区切りフォーマットは、ぱっと見で、簡単そうに見えます:

   Costs,150,200,3.95

行を読んで "line.split(',')": これほどに簡単なものはあるだろうか、って
? ですが、文字列データ内にカンマを含んだりすると、コトは複雑になります
:

   "Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"

デカくて醜い正規表現でこれをパース出来るでしょうが、新登場の "csv" を
使えば遥かに単純になります:

   import csv

   input = open('datafile', 'rb')
   reader = csv.reader(input)
   for line in reader:
       print line

"reader()" 関数はたくさんのオプションを取ります。フィールドセパレータ
はカンマだけに制限されておらず任意の文字に変更出来、引用も変更できます
。

カンマ区切りファイルの異なった方言を定義して登録出来ます。今のところ 2
つの方言があって、両者とも Microsoft Excel で使われるものです。独立し
ている "csv.writer" はタプルやリストの連続から、デリミタを含む文字列は
引用符で囲みつつカンマ区切りファイルを生成します。

参考:

  **PEP 305** - CSV File API
     PEP 著と実装: Kevin Altis, Dave Cole, Andrew McNamara, Skip
     Montanaro, Cliff Wells.


PEP 307: Pickle の機能拡張
==========================

"pickle", "cPickle" モジュールで、2.3 の開発サイクル中にいくつか留意す
べきことがありました。2.2 では新スタイルクラスを特に困難なく pickle 化
出来たものの、あまりコンパクトには pickle 化は出来ませんでした。 **PEP
307** が些細な例を引用しています。新スタイルクラスは旧スタイルクラスに
較べて 3 倍の長さになっていました。

解決方法として、新しい pickle プロトコルが発明されました。
"pickle.dumps()" 関数はずっと長い間、テキストとするのかバイナリとする
のかについてはサポートしていました。2.3 ではこのフラグは Boolean から
整数に再定義されました: 0 は旧式のテキストモード pickle フォーマット、
1 が同じく旧式のバイナリフォーマット、そして 2 が今回の 2.3 から特有の
フォーマットです。新しく追加された定数 "pickle.HIGHEST_PROTOCOL" を指
定すると、最も望ましいものが選択されます。

unpickle は安全な操作についての考慮はしなくなりました。2.2 の "pickle"
は unpickle される安全でないクラス (特に "__safe_for_unpickling__" 属
性) を避けようとするフックを提供していましたが、このコードは一度も監査
されることがなく、2.3 で全て白紙にしました。Python のどのバージョンで
も、信頼出来ないデータを unpickle すべきではありません。

新スタイルクラスでの pickle のオーバーヘッドを減らすために、pickle を
カスタマイズする、3 つの特殊メソッドを使った新インターフェイスが追加さ
れました: "__getstate__()", "__setstate__()", "__getnewargs__()" 。こ
れらメソッドの完全なセマンティクスについては **PEP 307** を調べてくだ
さい。

pickle をもっとさらに圧縮する方法として、pickle されるクラスの身元特定
のために長い文字列を使う代わりに整数コードを使えるようになっています。
Python Software Foundation は標準コードのリストを保守しています; プラ
イベート使用のためのコード範囲もあります。現在のところ指定されているコ
ードはありません。

参考:

  **PEP 307** - pickle プロトコルの拡張
     著、実装: Guido van Rossum と Tim Peters


拡張スライス
============

Python 1.4 以来ずっと、スライシングの構文は省略可能な 3 つ目の引数
"step" またの名を "stride" 、をサポートしていたのです。例えばこれらは
全て合法な Python 構文です: "L[1:10:2]", "L[:-1:1]", "L[::-1]" 。これ
はこの 3 つ目の引数を大々的に使う Numerical Python 開発者によって要望
されたことで Python に追加されたものですが、Python ビルトインのリスト
、タプル、文字列といったシーケンス型がこの機能をサポートすることはなく
、これを試みると "TypeError" を起こしていました。Michael Hudson がこの
不徹底を修正するパッチを寄稿しました。

例えば、今やリストの偶数番目要素を簡単に取り出せます:

   >>> L = range(10)
   >>> L[::2]
   [0, 2, 4, 6, 8]

負の値では、同じリストの逆順コピーを作るように動作します:

   >>> L[::-1]
   [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

これはタプル、配列、文字列に対しても使えます:

   >>> s='abcd'
   >>> s[::2]
   'ac'
   >>> s[::-1]
   'dcba'

リストや配列のような *mutable* なシーケンスに対して、拡張スライスを代
入や削除に使えますが、拡張スライスと普通のスライスではいくつかの違いが
あります。普通のスライスで代入を行えば、シーケンスの長さを変更出来ます
(---訳注: 念のため。Python 3 の range は list を直接返す関数ではなくジ
ェネレータなので、以下例は "a = list(range(3))" などとしないと動作しま
せん。続く例でも同じです。---):

   >>> a = range(3)
   >>> a
   [0, 1, 2]
   >>> a[1:3] = [4, 5, 6]
   >>> a
   [0, 4, 5, 6]

拡張スライスにはこの柔軟性はありません。拡張スライスを代入に使う際は、
ステートメントの右辺のリストは、置換されるスライスとしての要素数と同数
でなければなりません:

   >>> a = range(4)
   >>> a
   [0, 1, 2, 3]
   >>> a[::2]
   [0, 2]
   >>> a[::2] = [0, -1]
   >>> a
   [0, 1, -1, 3]
   >>> a[::2] = [0,1,2]
   Traceback (most recent call last):
     File "<stdin>", line 1, in ?
   ValueError: attempt to assign sequence of size 3 to extended slice of size 2

削除はもっと素直です:

   >>> a = range(4)
   >>> a
   [0, 1, 2, 3]
   >>> a[::2]
   [0, 2]
   >>> del a[::2]
   >>> a
   [1, 3]

ビルトインのシーケンスの "__getitem__()" メソッドに slice オブジェクト
を渡すことも出来るようになりました:

   >>> range(10).__getitem__(slice(0, 5, 2))
   [0, 2, 4]

あるいは直接 slice オブジェクトを添え字に使えます:

   >>> range(10)[slice(0, 5, 2)]
   [0, 2, 4]

拡張スライスをサポートするシーケンスの実装を単純化するために、 slice
オブジェクトに "indices(length)()" メソッドが追加されています。これは
シーケンスの長さを受け取って、タプル "(start, stop, step)" を返すこと
で直接 "range()" に渡せるようにしています。 "indices()" は範囲外のイン
デクスを、標準のスライスと一貫した方法で処理します (そしてこの当たり障
りのない言い回しは、ややこしい詳細の荒波を隠しているのですよ…!) このメ
ソッドはこうやって使うのを意図したものです:

   class FakeSeq:
       ...
       def calc_item(self, i):
           ...
       def __getitem__(self, item):
           if isinstance(item, slice):
               indices = item.indices(len(self))
               return FakeSeq([self.calc_item(i) for i in range(*indices)])
           else:
               return self.calc_item(i)

ところでこの例からは、ビルトインの "slice" オブジェクトが今では slice
型という型オブジェクトで、もう関数ではないことがわかるでしょう。これは
、Python 2.2 で "int", "str" などに対して行われた同じ目的の修正と一貫
しています。


その他の言語の変更
==================

以下が、Python 2.3 言語コアに加えられた全ての変更点です。

* "yield" がこのドキュメントの PEP 255: 単純なジェネレータ で述べた
  通 り、キーワードになっています。

* 新たなビルトイン関数 "enumerate()" が追加されました。このドキュメ
  ン トの PEP 279: enumerate() で述べた通りです。

* 新たな定数 "True",  "False" がビルトイン "bool" 型の追加に伴い追加
  さ れました。このドキュメントの PEP 285: Boolean 型 で述べた通りです
  。

* "int()" 型コンストラクタは、文字列や浮動小数点数を整数に収める際、
  そ れがとても大き場合に  "OverflowError" を投げるのではなく長整数を
  返す ようになっています。これは "isinstance(int(expression), int)"
  が偽を 返すかもしれないという逆説的な結果をもたらし得ますが、これが
  実際に問 題を起こすとはあまり思えません。

* ビルトイン型が拡張スライス構文をサポートするようになりました。この
  ド キュメントの 拡張スライス で述べた通りです。

* 新規ビルトイン関数 "sum(iterable, start=0)" はイテラブル内の数値ア
  イ テムを足し込んで総和を返します。 "sum()" は数値しか受け付けません
  の で、文字列群を連結するのには使えません。 (Contributed by Alex
  Martelli.)

* "list.insert(pos, value)" で *value* を先頭に追加するのに *pos* に
  負 数が使われてきました。この振る舞いはスライスのインデクシングとの
  一貫 性のために変更されました。つまり *pos* が -1 の場合は最終要素の
  前へ の追加、などとなります。

* "list.index(value)" はリスト内から *value* を探してそのインデクス
  を 返しますが、オプショナルな *start* と *stop* 引数を取って、リスト
  の 部分列からの検索が可能になりました。

* 辞書の新たなメソッド "pop(key[, *default*])" は、 *key* に対応する
  値 を返して辞書からそのキー/値ペアを取り除きます。辞書内にそのキーが
  不 在であれば、 *default* が指定されていればそれを、そうでなければ
  "KeyError" を投げます。:

     >>> d = {1:2}
     >>> d
     {1: 2}
     >>> d.pop(4)
     Traceback (most recent call last):
       File "stdin", line 1, in ?
     KeyError: 4
     >>> d.pop(1)
     2
     >>> d.pop(1)
     Traceback (most recent call last):
       File "stdin", line 1, in ?
     KeyError: 'pop(): dictionary is empty'
     >>> d
     {}
     >>>

  また、新しいメソッド "dict.fromkeys(iterable, value)" は、与えられた
  イテレータ *iterable* からキーを取り出しつつ全ての値を *value* にセ
  ットすることで構築します。 *value* のデフォルトは "None" です。

  (Patches contributed by Raymond Hettinger.)

  また、 "dict()" コンストラクタは小さな辞書を簡単に構築出来るよう、キ
  ーワード引数を受け付けるようになりました:

     >>> dict(red=1, blue=2, green=3, black=4)
     {'blue': 2, 'black': 4, 'green': 3, 'red': 1}

  (Contributed by Just van Rossum.)

* "assert" ステートメントが "__debug__" フラグをチェックすることはも
  う ありません。このため、 "__debug__" に代入することによってアサーシ
  ョ ンを無効にすることは出来ません。Python を "-O" スイッチで起動によ
  り 全てのアサーションが実行されない点は、以前と変わりません。

* ほとんどの型オブジェクトが今では呼び出し可能であり、なので関数、ク
  ラ ス、モジュールのようなオブジェクトを新たに構築するのにそれを使え
  ます 。 ("new" モジュールはこれにより将来のバージョンの Python で撤
  廃され る可能性があります。 "types" モジュール内の型オブジェクトが使
  えるか らです。 ---訳注: 2.6 で実際に撤廃されています。---) 例えば新
  規モジ ュールオブジェクトは以下コードで構築出来ます:

     >>> import types
     >>> m = types.ModuleType('abc','docstring')
     >>> m
     <module 'abc' (built-in)>
     >>> m.__doc__
     'docstring'

* A new warning, "PendingDeprecationWarning" was added to indicate
  features which are in the process of being deprecated.  The warning
  will *not* be printed by default.  To check for use of features that
  will be deprecated in the future, supply
  "-Walways::PendingDeprecationWarning::" on the command line or use
  "warnings.filterwarnings()".

* 文字列ベースの例外、例えば "raise "Error occurred"" のようなもの、
  こ れは廃止のための過程を開始しています。文字列を例外として投げると
  "PendingDeprecationWarning" が発行されます。

* "None" を変数名に使うと "SyntaxWarning" 警告を出すようになっていま
  す 。将来バージョンの Python では "None" はキーワードになります。

* ファイルオブジェクト自身が自身のイテレータのように振舞うようになっ
  た ために、Python 2.1 で導入されたファイルオブジェクトの
  "xreadlines()" メソッドはもう必要ありません。 "xreadlines()" メソッ
  ドは元々はファイ ル内の全行をループするのに高速な手段として導入され
  ましたが、今では単 純に "for line in file_obj" と書くことが出来ます
  。ファイルオブジェク トにはさらに読み取り専用の "encoding" 属性を持
  つようになっていて、こ れはファイルで使われているエンコーディングを
  与えます。ファイルへの Unicode 文字列書き込みでは、与えられたエンコ
  ーディングを使って自動的 にバイト列に変換されます。(---訳注:
  "encoding" は読み取り専用なので 「与える」といっても直接セットするこ
  とは出来ません。ビルトインの "open()" と "file" にはエンコーディング
  を指定するインターフェイスが ありません。一般にはこれは何かほかの関
  数などで間接的にセットすること になりますが、2.6 以降であれば
  "open()" 、そうでないなら "codec" モ ジュールなどを介して制御するこ
  とになると思います。Python 3 以降を含 む 2.6 以降は "open()" が良い
  です。---)

* The method resolution order used by new-style classes has changed,
  though you'll only notice the difference if you have a really
  complicated inheritance hierarchy.  Classic classes are unaffected
  by this change.  Python 2.2 originally used a topological sort of a
  class's ancestors, but 2.3 now uses the C3 algorithm as described in
  the paper "A Monotonic Superclass Linearization for Dylan". To
  understand the motivation for this change,  read Michele Simionato's
  article "Python 2.3 Method Resolution Order", or read the thread on
  python-dev starting with the message at
  https://mail.python.org/pipermail/python-
  dev/2002-October/029035.html. Samuele Pedroni first pointed out the
  problem and also implemented the fix by coding the C3 algorithm.

* Python はマルチスレッドプログラムを、バイトコード N 個実行のたびに
  実 行スレッドを切り替えて実行します。このデフォルトの N が 10 から
  100 に増やされました。これはシングルスレッドアプリケーションにおいて
  この 切り替えのオーバヘッドを減らして高速化するためです。マルチスレ
  ッドア プリケーションでは応答時間が遅くなる被害を被るかもしれません
  が、この リミット値を元の小さな値に戻すのは簡単で、
  "sys.setcheckinterval(N)" を使います。設定されているリミット値は新規
  関数 "sys.getcheckinterval()" で取得できます。

* マイナーですが広範囲に渡る変更として、拡張型の名前の変更があります
  。 Python と一緒に含まれるモジュールで定義される拡張型の名前が、モジ
  ュ ール名と "'.'" が型名に前置されるようになりました。例えば Python
  2.2 ではソケットオブジェクトを作って "__class__" を出力すると、この
  よう な出力だったでしょう:

     >>> s = socket.socket()
     >>> s.__class__
     <type 'socket'>

  2.3 ではこうなります:

     >>> s.__class__
     <type '_socket.socket'>

* One of the noted incompatibilities between old- and new-style
  classes has been removed: you can now assign to the "__name__" and
  "__bases__" attributes of new-style classes.  There are some
  restrictions on what can be assigned to "__bases__" along the lines
  of those relating to assigning to an instance's "__class__"
  attribute.


文字列に関する変更
------------------

* "in" 演算子が文字列に対して違った振る舞いをするようになりました。
  以 前は *X* と *Y* が文字列の場合の "X in Y" は、 *X* は単一文字でな
  け ればなりませんでした。これが *X* はどんな長さでも良くなり、 "X in
  Y" は *X* が *Y* のサブストリングであれば "True" を返すように変更さ
  れま した。 *X* が空文字列の場合は結果は常に "True" になります。

     >>> 'ab' in 'abcd'
     True
     >>> 'ad' in 'abcd'
     False
     >>> '' in 'abcd'
     True

  これはサブストリングの開始位置を教えてくれるわけではないので、その情
  報が必要であれば "find()"  メソッドを使ってください。

* "strip()", "lstrip()", "rstrip()" に、剥ぎ取る文字を指定する省略可
  能 引数が追加されています。デフォルトは従来通り全ての空白文字を削除
  しま す。:

     >>> '   abc '.strip()
     'abc'
     >>> '><><abc<><><>'.strip('<>')
     'abc'
     >>> '><><abc<><><>\n'.strip('<>')
     'abc<><><>\n'
     >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')
     u'\u4001abc'
     >>>

  (Suggested by Simon Brunning and implemented by Walter Dörwald.)

* "startswith()", "endswith()" メソッドが *start* と *end* パラメー
  タ として負数を受け付けるようになりました。

* もう一つ追加の文字列メソッドは "zfill()" で、これは "string" モジ
  ュ ール内で元々関数だったものです。 "zfill()" は指定の幅まで数値文字
  列 の左側にゼロ埋めをします。なお、 "%" 演算子の方が今でも "zfill()"
  よ り柔軟で強力です。:

     >>> '45'.zfill(4)
     '0045'
     >>> '12345'.zfill(4)
     '12345'
     >>> 'goofy'.zfill(6)
     '0goofy'

  (Contributed by Walter Dörwald.)

* 新規の型オブジェクト "basestring" が追加されました。 8 ビット文字
  列 と Unicode 文字列はともにこの型から派生しているので、
  "isinstance(obj, basestring)" はどちらの文字列型でも "True" を返しま
  す。これは完全に抽象型なので "basestring" のインスタンスを構築するこ
  とは出来ません。 (---訳注: Python 3 では文字列 = Unicode、バイト列の
  扱いが大きく変わり、まずバイト列と Unicode は決して同じものとはみな
  されません (今ここで 8 ビット文字列と呼んでいるものは Python 3 では
  文字列ではありません、バイト列です) し、 "basestring" 型も撤廃されて
  います。Python 2.7 で Python 3 をサポートする必要があるような場合は
  、なるべく "basestring" に依存しないようにした方が良いです。---)

* 内部化した文字列はもう不死身ではないので、内部辞書からの参照が、参
  照 している唯一のものとなれば、普通にガーベージコレクト対象となりま
  す。 (Implemented by Oren Tirosh.)


最適化
------

* The creation of new-style class instances has been made much
  faster; they're now faster than classic classes!

* The "sort()" method of list objects has been extensively rewritten
  by Tim Peters, and the implementation is significantly faster.

* Multiplication of large long integers is now much faster thanks to
  an implementation of Karatsuba multiplication, an algorithm that
  scales better than the O(n*n) required for the grade-school
  multiplication algorithm.  (Original patch by Christopher A. Craig,
  and significantly reworked by Tim Peters.)

* The "SET_LINENO" opcode is now gone.  This may provide a small
  speed increase, depending on your compiler's idiosyncrasies. See
  section その他の変更と修正 for a longer explanation. (Removed by
  Michael Hudson.)

* "xrange()" objects now have their own iterator, making "for i in
  xrange(n)" slightly faster than "for i in range(n)".  (Patch by
  Raymond Hettinger.)

* A number of small rearrangements have been made in various
  hotspots to improve performance, such as inlining a function or
  removing some code.  (Implemented mostly by GvR, but lots of people
  have contributed single changes.)

The net result of the 2.3 optimizations is that Python 2.3 runs the
pystone benchmark around 25% faster than Python 2.2.


新たなモジュール、改良されたモジュール、非推奨のモジュール
==========================================================

いつものように、Python の標準ライブラリには数多くの拡張とバグ修正があ
りました。ここでは最も注目に値する変更について、モジュールの辞書順に列
挙します。変更の完全なリストについてはソースツリーの "Misc/NEWS" を調
べるか、あるいは全ての詳細について CVS ログに目を通してみてください。

* "array" モジュールが "'u'" フォーマット文字を使った Unicode 文字の
  配 列をサポートするようになっています。配列はまた、 "+=" 代入演算子
  を使 ってほかの配列内容を加算すること、 "*=" 演算子を使って配列を繰
  り返す ことが可能になっています。(Contributed by Jason Orendorff.)

* "bsddb" が PyBSDDB バージョン 4.1.6 によって置き換えられています。
  こ れは BerkeleyDB のトランザクションの機能へのより完全なインターフ
  ェイ スを提供します。

  古いバージョンのモジュールは "bsddb185" にリネームされて、自動的には
  ビルドされません。有効にするには "Modules/Setup" を編集する必要があ
  ります。新しい "bsddb" パッケージは古いモジュールと互換となるように
  意図されていますので、何か非互換を見つけたらファイルのバグを確認して
  ください。Python 2.3 へのアップグレードの際、前提となる BerkeleyDB
  ライブラリの新バージョンでインタプリタがコンパイルされるならば、ほぼ
  確実にあなたのデータベースは新バージョンに変換しなければならないでし
  ょう。ソース配布物の "Tools/scripts" ディレクトリの "db2pickle.py"
  と "pickle2db.py" スクリプトを使って、これをかなり簡単に行うことが出
  来ます。もし既に PyBSDDB パッケージを使っていて "bsddb3" としてイン
  ポートしているならば、 "bsddb" をインポートするように "import" 文を
  変更する必要があります。

* 新規の "bz2" モジュールは bz2 データ圧縮ライブラリへのインターフェ
  イ スです。bz2 圧縮データは普通 "zlib" 圧縮データよりも小さくなりま
  す。 (Contributed by Gustavo Niemeyer.)

* 標準の日付時刻型が "datetime" モジュールとして追加されています。詳
  細 はこのドキュメントの下の方に記述してありますのでそちらを参照して
  下さ い。

* Distutils の "Extension" クラスに新たにコンストラクタ引数
  *depends* が追加されました。これは拡張が依存する追加的なソースファイ
  ルを列挙し ます。Distutils はその依存ファイルのいずれかが更新される
  と再コンパイ ルを行います。例えば "sampmodule.c" がヘッダファイル
  "sample.h" をイ ンクルードしているとして、 "Extension" オブジェクト
  をこのように構築 します:

     ext = Extension("samp",
                     sources=["sampmodule.c"],
                     depends=["sample.h"])

  "sample.h" を修正するとモジュールは再コンパイルされます。
  (Contributed by Jeremy Hylton.)

* Distutils のほかのマイナーな変更: 環境変数 "CC", "CFLAGS", "CPP",
  "LDFLAGS", "CPPFLAGS" をチェックして Python のコンフィグレーションで
  の設定をオーバライドするようになっています (contributed by Robert
  Weber)。

* 以前までは "doctest" モジュールは公開メソッドの docstring とテスト
  ケ ースの関数を検索するだけでしたが、今ではプライベートなものも調べ
  ます 。 "DocTestSuite()" 関数は "doctest" テスト群から
  "unittest.TestSuite" オブジェクトを作ります。

* 新しい関数 "gc.get_referents(object)" は *object* により参照されて
  い る全てのオブジェクトのリストを返します。

* "getopt" モジュールに新規関数 "gnu_getopt()" が追加されました。こ
  れ は既存の "getopt()" 関数と同じ引数を取りますが、GNU スタイルの走
  査モ ードを使います。既存の "getopt()" 関数は非オプション引数が現れ
  るとす ぐにオプション処理をやめますが、GNU スタイルモードは処理を続
  行するの で、オプションと引数をミックス出来ます。例えば:

     >>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v')
     ([('-f', 'filename')], ['output', '-v'])
     >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v')
     ([('-f', 'filename'), ('-v', '')], ['output'])

  (Contributed by Peter Åstrand.)

* モジュール "grp", "pwd", "resource" では拡張されたタプルを返すよう
  に なりました:

     >>> import grp
     >>> g = grp.getgrnam('amk')
     >>> g.gr_name, g.gr_gid
     ('amk', 500)

* "gzip" モジュールが 2 GiB を超えるファイルを扱えるようになっていま
  す 。

* The new "heapq" module contains an implementation of a heap queue
  algorithm.  A heap is an array-like data structure that keeps items
  in a partially sorted order such that, for every index *k*, "heap[k]
  <= heap[2*k+1]" and "heap[k] <= heap[2*k+2]".  This makes it quick
  to remove the smallest item, and inserting a new item while
  maintaining the heap property is O(lg n).  (See
  https://xlinux.nist.gov/dads//HTML/priorityque.html for more
  information about the priority queue data structure.)

  "heapq" モジュールには、 "heappush()" 関数と "heappop()" 関数が含ま
  れており、これらはほかの *mutable* な Python シーケンス型の上にヒー
  ププライオリティを保ちつつアイテムの追加と削除を行います。Python リ
  ストを使う例としてはこのような具合です:

     >>> import heapq
     >>> heap = []
     >>> for item in [3, 7, 5, 11, 1]:
     ...    heapq.heappush(heap, item)
     ...
     >>> heap
     [1, 3, 5, 11, 7]
     >>> heapq.heappop(heap)
     1
     >>> heapq.heappop(heap)
     3
     >>> heap
     [5, 7, 11]

  (Contributed by Kevin O'Connor.)

* IDLE 統合開発環境は IDLEfork プロジェクト
  (http://idlefork.sourceforge.net) からのコードを用いるように更新され
  ました。最も特筆すべき特徴は開発コードがサブプロセスで実行されるよう
  になったことで、これにより手動で "reload()" 操作を行う必要はなくなっ
  ています。IDLE の中核コードは標準ライブラリの "idlelib" パッケージと
  して組み込まれました。

* "imaplib" モジュールが  IMAP over SSL をサポートするようになりまし
  た . (Contributed by Piers Lauder and Tino Lange.)

* "itertools" モジュールは ML 言語や Haskell 言語で提供されている様
  々 な関数に触発された、イテレータとともに用いる有用な数多くの関数を
  含ん でいます。例えば、 "itertools.ifilter(predicate, iterator)" は
  イテレ ータ内で関数 "predicate()" が "True" を返す要素全てを返し、
  "itertools.repeat(obj, N)" は "obj" の *N* 回繰り返しを返します。ほ
  かにもモジュールには数多くの関数を含んでいます。詳細はパッケージのド
  キュメントを参照してください。(Contributed by Raymond Hettinger.)

* "math" module の 2 つの新規関数 "degrees(rads)" と "radians(degs)"
  は、ラジアンと度の間の変換を行います。 "math" モジュールの
  "math.sin()" や "math.cos()" などは常にラジアンでの入力が必要です。
  "math.log()" 関数には底を指定するオプショナルの *base* 引数が追加さ
  れていて、 "e" と "10" でない底の対数を計算するのが簡単になりました
  。 (Contributed by Raymond Hettinger.)

* いくつもの新規 POSIX 関数 ("getpgid()", "killpg()", "lchown()",
  "loadavg()", "major()", "makedev()", "minor()", "mknod()") が "os"
  モジュールの下位の "posix" モジュールに追加されました。(Contributed
  by Gustavo Niemeyer, Geert Jansen, and Denis S. Otkidach.)

* "os" モジュール内の "*stat()" 系関数が、タイムスタンプの秒の端数を
  報 告するようになりました。そのようなタイムスタンプは "time.time()"
  が 返すのと同じで浮動小数点数で表現されます。

  テストを通じて、タイムスタンプが浮動小数点となっていくつかのアプリケ
  ーションが破壊されることがわかっています。互換性のために、
  "stat_result" タイムスタンプのタプルインターフェイスは整数で表現され
  ます。名前付きフィールド (これは Python 2.2 で最初に導入されました)
  を用いる場合にもタイムスタンプは今でも整数ですが、
  "os.stat_float_times()" を呼び出すことで浮動小数点数で返却するように
  出来ます:

     >>> os.stat("/tmp").st_mtime
     1034791200
     >>> os.stat_float_times(True)
     >>> os.stat("/tmp").st_mtime
     1034791200.6335014

  Python 2.4 では、浮動小数点数を返すのがデフォルトとなります。

  アプリケーション開発者は、この機能を有効にするのは、全ての自身のライ
  ブラリが浮動小数点数のタイムスタンプで正しく動作するか、タプル API
  を使用する場合のみにしてください。使うのであればこの機能は、都度都度
  有効にしようとせずにアプリケーションレベルで有効にすべきです。

* "optparse" モジュールに新たなコマンドライン引数パーサが追加されま
  し た。これはオプション値を特定の Python 型に変換することが出来、ま
  た、 自動的に使用例メッセージを生成します。詳細はこのドキュメントの
  続くセ クションを参照して下さい。

* 古く、また一度としてドキュメントされたこともない "linuxaudiodev"
  モ ジュールは非推奨となり、新しいバージョンが "ossaudiodev" として追
  加 されました。このモジュールがリネームされたのは OSS サウンドドライ
  バ は Linux に限って利用出来るものではなく、インターフェイスも整理さ
  れ 、色々な手で更新されたからです。(Contributed by Greg Ward and
  Nicholas FitzRoy-Dale.)

* 実行中のプラットフォームについての色々な特性を決定する数多くの関数
  を 含む、新規 "platform" モジュールが追加されました。アーキテクチャ
  、 CPU タイプ、Windows の OS バージョンや Linux ディストリビューショ
  ン のバージョンなどを取得できます。(Contributed by Marc-André
  Lemburg.)

* "pyexpat" モジュールのパーサオブジェクトが、オプショナルで文字デー
  タ をバッファ出来るようになりました。結果として文字データハンドラの
  呼び 出しが少なくなり、速くなります。バッファリングの有効化にはパー
  サオブ ジェクトの "buffer_text" 属性を "True" にセットします。

* "random" モジュールに "sample(population, k)" 関数が追加されました
  。 *population* は母集団の要素を含んだ、シーケンスか "xrange" オブジ
  ェ クトで、 "sample()" は母集団から *k* 要素を値の置換なしに選択しま
  す 。 *k* は "len(population)" までの任意の値を渡せます。例えば:

     >>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn']
     >>> random.sample(days, 3)      # Choose 3 elements
     ['St', 'Sn', 'Th']
     >>> random.sample(days, 7)      # Choose 7 elements
     ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn']
     >>> random.sample(days, 7)      # Choose 7 again
     ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
     >>> random.sample(days, 8)      # Can't choose eight
     Traceback (most recent call last):
       File "<stdin>", line 1, in ?
       File "random.py", line 414, in sample
           raise ValueError, "sample larger than population"
     ValueError: sample larger than population
     >>> random.sample(xrange(1,10000,2), 10)   # Choose ten odd nos. under 10000
     [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]

  "random" が C で実装された新しいアルゴリズムのメルセンヌ・ツイスタを
  使うようになりました。これは以前のアルゴリズムよりも高速で、より広く
  研究されています。

  (All changes contributed by Raymond Hettinger.)

* "readline" モジュールは多くの新規関数を追加しました:
  "get_history_item()", "get_current_history_length()", "redisplay()"
  。

* "rexec" モジュールと "Bastion" モジュールはもう利用出来ないように
  し てあります。インポートを試みれば "RuntimeError" を投げます。新ス
  タイ ルクラスは "rexec" により提供される制限実行環境を突破する新たな
  術を 持っており、誰もそれを修正することに興味もなく、その時間も持っ
  ていま せん。 "rexec" を使うアプリケーションを持っているならば、何か
  ほかの 手段で書き換えてください。

  (Python 2.2 または 2.1 に留まるにしてもそれは何一つあなたのアプリケ
  ーションを安全にはしません。それらバージョンの "rexec" モジュールに
  は既知のバグがあるからです。繰り返します。 "rexec" を使っているなら
  、即座に使用をやめてください。)

* "rotor" モジュールが非推奨となりました。暗号化に使うアルゴリズムが
  安 全ではないと思われているからです。暗号が必要なのであれば、独立し
  て入 手出来るいくつもの AES Python モジュールのなかの一つを使ってく
  ださい 。(---訳注: rotor モジュールは 2.4 で削除されました。---)

* "shutil" モジュールに "move(src, dest)" が追加されており、これはフ
  ァ イルまたはディレクトリを新しい場所へ再帰的に移動します。

* Support for more advanced POSIX signal handling was added to the
  "signal" but then removed again as it proved impossible to make it
  work reliably across platforms.

* "socket" モジュールがタイムアウトをサポートするようになりました。
  ソ ケットオブジェクトの "settimeout(t)" メソッドに *t* 秒を与えるこ
  とで 行えます。これに続くソケット操作が *t* 秒を超えて完了しない場合
  には 操作は中断し、 "socket.timeout" 例外を投げます。

  オリジナルのタイムアウト実装は Tim O'Malley によりなされました。
  Michael Gilfix がこれを Python "socket" モジュールに統合し、長い長い
  レビューに導きました。コードがチェックインされたのち、Guido van
  Rossum はそれを部分的に書き換えました。(これは協調的開発プロセスの好
  例です。)

* Windows での "socket" モジュールの Secure  Sockets Layer (SSL) サ
  ポ ートが始まりました。

* C マクロの "PYTHON_API_VERSION" の値が Python レベルで
  "sys.api_version" として公開されるようになりました。新関数
  "sys.exc_clear()" を呼び出すことで、現在の例外をクリア出来るようにな
  りました。

* 新モジュール "tarfile" で **tar** 形式のアーカイブファイルの読み書
  き が出来ます。 (Contributed by Lars Gustäbel.)

* 新規モジュール "textwrap" には、テキストのパラグラフを含んだ文字列
  を 折り返すための関数群を含まれています。 "wrap(text, width)" 関数は
  文 字列を入力に取り、指定した幅より長いものを含まない行に分割して文
  字列 のリストで返します。 "fill(text, width)" 関数は指定した幅を超え
  ない 分割行に再整形して単一文字列で返します。(ご想像どおり "fill()"
  は "wrap()" の上に構築されています。例えば:

     >>> import textwrap
     >>> paragraph = "Not a whit, we defy augury: ... more text ..."
     >>> textwrap.wrap(paragraph, 60)
     ["Not a whit, we defy augury: there's a special providence in",
      "the fall of a sparrow. If it be now, 'tis not to come; if it",
      ...]
     >>> print textwrap.fill(paragraph, 35)
     Not a whit, we defy augury: there's
     a special providence in the fall of
     a sparrow. If it be now, 'tis not
     to come; if it be not to come, it
     will be now; if it be not now, yet
     it will come: the readiness is all.
     >>>

  モジュールには実際のテキスト折り返しの戦略を実装する "TextWrapper"
  クラスが含まれています。 "TextWrapper" クラスと  "wrap()" 関数、
  "fill()" 関数のどちらも、整形を細かく制御するための数多くの追加的な
  キーワード引数をサポートしています。詳細はモジュールのドキュメントを
  調べてください。(Contributed by Greg Ward.)

* "thread" モジュールと "threading" モジュールの仲間として、プラット
  フ ォームがスレッドをサポートしない場合の何もしない実装の "thread"
  モジ ュールインターフェイスとして "dummy_thread" と
  "dummy_threading" が 追加されました。これはスレッド化を意図する (ス
  レッドが実際動くかには 依存 *しない*) モジュールがコードの先頭に以下
  のように書くことで単純 化することを狙ったものです:

     try:
         import threading as _threading
     except ImportError:
         import dummy_threading as _threading

  この例ではモジュール名として "_threading" を使っていて、これは実際の
  "threading" モジュールが必ずしも必要ではないことをはっきりさせていま
  す。 "_threading" モジュール内の関数とクラスはスレッドがサポートされ
  ているいないに関わらず呼び出すことが出来、これは "if" 文を避け、コー
  ドを少しばかり明快にします。このモジュールはスレッドなしのマルチスレ
  ッドコードを走らせるのに特別なことをしません。つまり他のスレッドが戻
  るのを待ったり何か他のことをするのを待つコードは、単に永遠にハングし
  ます。

* "time" モジュールの "strptime()" 関数は長いこと混乱の元でした。そ
  れ がプラットフォームの C 関数 "strptime()" を使い、異なったプラット
  フ ォームごとに時折おかしなバグを持っていたからです。Brett Cannon は
  pure Python で、全てのプラットフォームで全く同じに振舞うように書き直
  した実装を寄稿しました。

* 新規モジュール "timeit" は、Python コードの断片 (スニペット) を実
  行 するのにかかる時間を計測します。ファイル "timeit.py" は直接コマン
  ド ラインから実行出来ますし、モジュールの "Timer" クラスをインポート
  し て直接使うことも出来ます。以下に、空の Unicode 文字列を追加するこ
  と によって 8 ビット文字列を Unicode に変換するのと "unicode()" 関数
  を 使うのとでいずれが高速なのかを把握するための短い例をお見せします:

     import timeit

     timer1 = timeit.Timer('unicode("abc")')
     timer2 = timeit.Timer('"abc" + u""')

     # Run three trials
     print timer1.repeat(repeat=3, number=100000)
     print timer2.repeat(repeat=3, number=100000)

     # On my laptop this outputs:
     # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869]
     # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]

* "Tix" モジュールに色々バグ修正がなされ、Tix パッケージの現在バージ
  ョ ンに更新されました。

* "Tkinter" モジュールがスレッドを有効化した Tcl で動作するようにな
  り ました。Tcl のスレッドモデルは、ウィジットはそれが作られたスレッ
  ドか らのみアクセスされることを必要とします。ほかのスレッドからのア
  クセス は Tcl を混乱させます。ある特定の Tcl インターフェイスでは、
  "Tkinter" はウィジットがコマンドの纏め上げによって異なるスレッドから
  アクセスされる際に、正しいスレッドに向けて結果を待つことで自動的にこ
  れを避けるようになりました。それ以外のインターフェイスでは自動で処理
  は出来ませんが、 "Tkinter" はそのようなアクセス時に最低でもそれが問
  題とわかるよう例外を送出するようになっています。この変更についての詳
  細な説明は https://mail.python.org/pipermail/python-
  dev/2002-December/031107.html をみてください。(Implemented by Martin
  von Löwis.)

* "_tkinter" を介した Tcl メソッド呼び出しは今では文字列だけを返すの
  で はありません。代わりに Tcl は対応する Python の等価なオブジェクト
  に 変換されたオブジェクトを返します。Python に等価なものがなければ
  "_tkinter.Tcl_Obj" で包んで返します。この振る舞いは "tkapp" オブジェ
  クトの "wantobjects()" メソッドで制御出来ます。

  (ほとんどの Tkinter アプリケーションがそうするように) "Tkinter" モジ
  ュールを通して "_tkinter" を使う際、この機能は常に有効になります。こ
  れは互換性の問題を引き起こさないはずです。 Tkinter は可能な場合には
  文字列を Python 型に常に変換していたからです。

  何か非互換性を見つけたら古い振る舞いに戻せます。最初の "tkapp" オブ
  ジェクトを生成する前に "Tkinter" モジュールの "wantobjects" 変数に偽
  をセットしてください:

     import Tkinter
     Tkinter.wantobjects = 0

  ここで説明した変更によって何かアプリケーションの破壊があれば、バグと
  して報告してください。

* "UserDict" モジュールに新しく "DictMixin" クラスが追加されました。
  既 に最小限のマッピングインターフェイスを持っているクラスのために、
  全て の辞書メソッドを定義します。これは、 "shelve" モジュール内のク
  ラスの ような、辞書に置換可能である必要があるクラスの記述を大幅に単
  純化しま す。

  クラスがメソッド "__getitem__()", "__setitem__()", "__delitem__()",
  "keys()" を定義している場合にはいつでも、スーパークラスとして mix-in
  を追加すると完全な辞書インターフェイスになります。例えば:

     >>> import UserDict
     >>> class SeqDict(UserDict.DictMixin):
     ...     """Dictionary lookalike implemented with lists."""
     ...     def __init__(self):
     ...         self.keylist = []
     ...         self.valuelist = []
     ...     def __getitem__(self, key):
     ...         try:
     ...             i = self.keylist.index(key)
     ...         except ValueError:
     ...             raise KeyError
     ...         return self.valuelist[i]
     ...     def __setitem__(self, key, value):
     ...         try:
     ...             i = self.keylist.index(key)
     ...             self.valuelist[i] = value
     ...         except ValueError:
     ...             self.keylist.append(key)
     ...             self.valuelist.append(value)
     ...     def __delitem__(self, key):
     ...         try:
     ...             i = self.keylist.index(key)
     ...         except ValueError:
     ...             raise KeyError
     ...         self.keylist.pop(i)
     ...         self.valuelist.pop(i)
     ...     def keys(self):
     ...         return list(self.keylist)
     ...
     >>> s = SeqDict()
     >>> dir(s)      # See that other dictionary methods are implemented
     ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',
      '__init__', '__iter__', '__len__', '__module__', '__repr__',
      '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems',
      'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',
      'setdefault', 'update', 'valuelist', 'values']

  (Contributed by Raymond Hettinger.)

* "xml.dom.minidom" の DOM 実装で、指定したエンコーディングによる
  XML 出力が可能になりました。DOM ノードの "toxml()" メソッド、
  "toprettyxml()" メソッドにオプショナルなエンコーディング引数を与える
  ことで行えます。

* "xmlrpclib" モジュールが、 Python の "None" のような nil データを
  処 理するための XML-RPC 拡張をサポートするようになりました。 nil 値
  は XML-RPC 応答のアンマーシャルでいつでもサポートされます。 "None"
  を含 んだリクエストを生成するためには、 "Marshaller" のインスタンス
  を生成 する際に *allow_none* パラメータに真を与えなければなりません
  。

* 新規モジュール "DocXMLRPCServer" は、セルフ-ドキュメンティング
  XML- RPC サーバを書くのに使えます。実際のところをみるためにはデモモ
  ード ( つまりプログラムとして) 実行してみてください。ウェブブラウザ
  を RPC サーバに向ければ pydoc スタイルのドキュメントを生成します。
  xmlrpclib をサーバに向ければ実際のメソッドを呼び出せます。
  (Contributed by Brian Quinlan.)

* internationalized domain names (RFC 3454, 3490, 3491, 3492) のサポ
  ー トが追加されました。Unicode ドメイン名とその名前の ASCII 互換エン
  コ ーディング (ACE=ASCII-compatible encoding) の間の変換をするのに
  "idna" エンコーディングを使用出来ます:

     >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")
     'www.xn--alliancefranaise-npb.nu'

  "socket" モジュールも、C ライブラリに渡す前に Unicode ホスト名を ACE
  バージョンに透過的に変換するように拡張されています。 "httplib" や
  "ftplib" のようなホスト名を扱うモジュールも Unicode ホスト名をサポー
  トしています; "httplib" は HTTP "Host" ヘッダをドメイン名の ACE 版を
  使って送信します。 "urllib" は URL の "path" 部分が ASCII のみである
  限り、非 ASCII ホスト名を持つ Unicode URL をサポートします

  この変更の実装のために、 "stringprep" モジュール、 "mkstringprep" ツ
  ール、 "punycode" エンコーディングが追加されました。


日付時刻型
----------

タイムスタンプとして使うのに相応しい日付と時刻の型が "datetime" モジュ
ールとして追加されました。これら型は異なるカレンダであるとか多くの洒落
た機能をサポートはせずに、時刻表現の基礎だけに集中するものです。

The three primary types are: "date", representing a day, month, and
year; "time", consisting of hour, minute, and second; and "datetime",
which contains all the attributes of both "date" and "time". There's
also a "timedelta" class representing differences between two points
in time, and time zone logic is implemented by classes inheriting from
the abstract "tzinfo" class.

You can create instances of "date" and "time" by either supplying
keyword arguments to the appropriate constructor, e.g.
"datetime.date(year=1972, month=10, day=15)", or by using one of a
number of class methods.  For example, the "date.today()" class method
returns the current local date.

構築後の日付時刻クラスのインスタンスは全て *immutable* です。オブジェ
クトから書式化文字列を生成する数多くのメソッドがあります:

   >>> import datetime
   >>> now = datetime.datetime.now()
   >>> now.isoformat()
   '2002-12-30T21:27:03.994956'
   >>> now.ctime()  # Only available on date, datetime
   'Mon Dec 30 21:27:03 2002'
   >>> now.strftime('%Y %d %b')
   '2002 30 Dec'

The "replace()" method allows modifying one or more fields  of a
"date" or "datetime" instance, returning a new instance:

   >>> d = datetime.datetime.now()
   >>> d
   datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
   >>> d.replace(year=2001, hour = 12)
   datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
   >>>

Instances can be compared, hashed, and converted to strings (the
result is the same as that of "isoformat()").  "date" and "datetime"
instances can be subtracted from each other, and added to "timedelta"
instances.  The largest missing feature is that there's no standard
library support for parsing strings and getting back a "date" or
"datetime".

さらに詳しい情報については、モジュールのリファレンスドキュメントを参照
してください。 (Contributed by Tim Peters.)


optparse モジュール
-------------------

The "getopt" module provides simple parsing of command-line arguments.
The new "optparse" module (originally named Optik) provides more
elaborate command-line parsing that follows the Unix conventions,
automatically creates the output for "--help", and can perform
different actions for different options.

"OptionParser" インスタンスを作ることから始め、プログラムのオプション
がどんなであるかそれに対して教えてやります:

   import sys
   from optparse import OptionParser

   op = OptionParser()
   op.add_option('-i', '--input',
                 action='store', type='string', dest='input',
                 help='set input filename')
   op.add_option('-l', '--length',
                 action='store', type='int', dest='length',
                 help='set maximum length of output')

コマンドラインの解析は "parse_args()" メソッドを呼び出すことで行います

   options, args = op.parse_args(sys.argv[1:])
   print options
   print args

これは、全てのオプションの値を含んだオブジェクトと残った引数を含む文字
列リストを返します。

Invoking the script with the various arguments now works as you'd
expect it to. Note that the length argument is automatically converted
to an integer.

   $ ./python opt.py -i data arg1
   <Values at 0x400cad4c: {'input': 'data', 'length': None}>
   ['arg1']
   $ ./python opt.py --input=data --length=4
   <Values at 0x400cad2c: {'input': 'data', 'length': 4}>
   []
   $

The help message is automatically generated for you:

   $ ./python opt.py --help
   usage: opt.py [options]

   options:
     -h, --help            show this help message and exit
     -iINPUT, --input=INPUT
                           set input filename
     -lLENGTH, --length=LENGTH
                           set maximum length of output
   $

さらに詳しいことはモジュールのドキュメントを参照して下さい。

Optik は Getopt SIG の読者からの示唆を受けてGreg Ward により書かれまし
た。


Pymalloc: 特殊化されたオブジェクトアロケータ
============================================

Pymalloc は Vladimir Marangozov により書かれ Python 2.1 で追加された、
特殊化されたオブジェクトアロケータです。Pymalloc は典型的な Python プ
ログラムでのアロケーションのパターンにおいて、システムの "malloc()" よ
りも高速で省メモリであることを意図したものです。このアロケータは C の
"malloc()" 関数を大きなメモリプールを得るのに使い、それより小さなメモ
リ要求はこれらプールで実現しています。

In 2.1 and 2.2, pymalloc was an experimental feature and wasn't
enabled by default; you had to explicitly enable it when compiling
Python by providing the "--with-pymalloc" option to the **configure**
script.  In 2.3, pymalloc has had further enhancements and is now
enabled by default; you'll have to supply "--without-pymalloc" to
disable it.

この変更は Python で書いたコードからは見えませんが、 pymalloc は C 拡
張内のバグを露にするかもしれません。C 拡張の著者は pymalloc を有効にし
てテストすべきです。というのも、ある種の正しくないコードが実行時にコア
ダンプしうるからです。

問題を起こすとりわけ一般的な誤りが一つあります。Python の C API 内には
数多くのメモリアロケーション関数がありますが、これは以前は単に C ライ
ブラリの "malloc()" と "free()" への別名であり、何かの間違いでミスマッ
チな関数呼び出しをしても、誤りは気付かれないものでした。今回のこのオブ
ジェクトアロケータを有効化すると、これら関数は "malloc()" と "free()"
への別名ではまったくなくて、メモリ解放に誤った関数を呼び出すとコアダン
プし得ます。例えば "PyObject_Malloc()" を使って獲得したメモリは
"free()" ではなく "PyObject_Free()" を使って解放する必要があります。
Python に含まれるいくつかのモジュールがまさにこれに抵触し、修正の必要
がありました。間違いなく多くのサードパーティモジュールが同じ問題を抱え
ているでしょう。

この変更の一環として、メモリアロケーションのためのこんがらかった複数イ
ンターフェイスが統合されて 2 つの API ファミリになりました。一方のファ
ミリで獲得されたメモリは他方の関数で操作されることは許されません。一方
のファミリはメモリの塊を獲得するためのもので、もう一方は Python オブジ
ェクトの獲得に特殊化されたものです。

* 何某かの区別のないメモリの塊を獲得・解放するのには「生メモリ」ファ
  ミ リを使います: "PyMem_Malloc()", "PyMem_Realloc()",
  "PyMem_Free()".

* 「オブジェクトメモリ」ファミリは上述の pymalloc 機構へのインターフ
  ェ イスであり、多数の「小さな」獲得をするための特化がされています:
  "PyObject_Malloc()", "PyObject_Realloc()", "PyObject_Free()".

* Python オブジェクトの獲得と解放には「オブジェクト」ファミリ
  "PyObject_New()", "PyObject_NewVar()", "PyObject_Del()" を使います。

Thanks to lots of work by Tim Peters, pymalloc in 2.3 also provides
debugging features to catch memory overwrites and doubled frees in
both extension modules and in the interpreter itself.  To enable this
support, compile a debugging version of the Python interpreter by
running **configure** with "--with-pydebug".

拡張の著者のために、Python 2.3 のソースとともにヘッダファイル
"Misc/pymemcompat.h" が配布されています。これは Python 拡張に 2.3 イン
ターフェイスでのメモリ獲得を使えるようにするもので、1.5.2 以降の全ての
バージョンに対してコンパイル可能です。Python のソース配布物からファイ
ルをコピーして、あなたの拡張ソースにバンドル出来ます。

参考:

  https://hg.python.org/cpython/file/default/Objects/obmalloc.c
     pymalloc 実装に関する完全な詳細については Python ソースコード内の
     "Objects/obmalloc.c" ファイルの先頭のコメントを参照してください。
     上のファイルへのリンクは python.org の SVN ブラウザを指しています
     。


ビルドならびに C API の変更
===========================

Python のビルド過程と C API の変更は以下の通りです:

* The cycle detection implementation used by the garbage collection
  has proven to be stable, so it's now been made mandatory.  You can
  no longer compile Python without it, and the "--with-cycle-gc"
  switch to **configure** has been removed.

* Python can now optionally be built as a shared library
  ("libpython2.3.so") by supplying "--enable-shared" when running
  Python's **configure** script.  (Contributed by Ondrej Palkovsky.)

* マクロ "DL_EXPORT" と "DL_IMPORT" が非推奨となっています。Python
  コ アが一般的にマクロ "PyAPI_FUNC" と "PyAPI_DATA" を使うのに対し、
  Python 拡張モジュールの初期化関数が新規マクロ "PyMODINIT_FUNC" を使
  って宣言されなければならなくなりました。

* The interpreter can be compiled without any docstrings for the
  built-in functions and modules by supplying "--without-doc-strings"
  to the **configure** script. This makes the Python executable about
  10% smaller, but will also mean that you can't get help for Python's
  built-ins.  (Contributed by Gustavo Niemeyer.)

* "PyArg_NoArgs()" マクロが非推奨となったので、これを使っているコー
  ド は修正しなければなりません。Python 2.2 以降ではメソッド定義テーブ
  ル では引数を持たず、引数チェックを省けることを示すのに
  "METH_NOARGS" フラグが使えます。2.2 以前の Python バージョンとの互換
  性が重要な場合 には "PyArg_ParseTuple(args, "")" を代わりに使えます
  が、 "METH_NOARGS" を使うより遅いです。

* "PyArg_ParseTuple()" に符号なし整数の色々なサイズのためのフォーマ
  ッ ト文字が追加されました: "unsigned char" のための "B", "unsigned
  short int" のための "H", "unsigned int" のための "I", "unsigned long
  long" のための "K".

* 新規関数 "PyObject_DelItemString(mapping, char *key)" が
  "PyObject_DelItem(mapping, PyString_New(key))" の速記法として追加さ
  れました。

* ファイルオブジェクトの内部文字列バッファの管理が変更されて、必要な
  場 合には指数関数的に増やすようになりました。
  "Lib/test/test_bufio.py" 内のベンチマークテストの結果での速度向上は
  大幅なものです (ある一つの 計測では 57 秒から 1.7 秒になりました)。

* C 拡張型のクラスメソッドと静的メソッドを定義出来るようになりました
  。 メソッドの "PyMethodDef" 構造体に "METH_CLASS" フラグか
  "METH_STATIC" フラグをセットすることで行えます。

* Python は Expat XML パーサのソースコードのコピーを丸抱えするように
  な り、これにより Expat のシステムのバージョンやローカルにインストー
  ル されたものへの依存がなくなっています。

* If you dynamically allocate type objects in your extension, you
  should be aware of a change in the rules relating to the
  "__module__" and "__name__" attributes.  In summary, you will want
  to ensure the type's dictionary contains a "'__module__'" key;
  making the module name the part of the type name leading up to the
  final period will no longer have the desired effect.  For more
  detail, read the API reference documentation or the  source.


ポート特有の変更
----------------

Support for a port to IBM's OS/2 using the EMX runtime environment was
merged into the main Python source tree.  EMX is a POSIX emulation
layer over the OS/2 system APIs.  The Python port for EMX tries to
support all the POSIX-like capability exposed by the EMX runtime, and
mostly succeeds; "fork()" and "fcntl()" are restricted by the
limitations of the underlying emulation layer.  The standard OS/2
port, which uses IBM's Visual Age compiler, also gained support for
case-sensitive import semantics as part of the integration of the EMX
port into CVS.  (Contributed by Andrew MacIntyre.)

On MacOS, most toolbox modules have been weaklinked to improve
backward compatibility.  This means that modules will no longer fail
to load if a single routine is missing on the current OS version.
Instead calling the missing routine will raise an exception.
(Contributed by Jack Jansen.)

The RPM spec files, found in the "Misc/RPM/" directory in the Python
source distribution, were updated for 2.3.  (Contributed by Sean
Reifschneider.)

Other new platforms now supported by Python include AtheOS
(http://atheos.cx/), GNU/Hurd, and OpenVMS.


その他の変更と修正
==================

いつものように、たくさんのほかの改善とバグフィックスがソースツリー全体
に渡って散らばっています。CVS 変更ログを検索すると、Python 2.2 から
2.3 にかけて適用されたパッチは 523、バグ修正は 514 ありました。いずれ
も少なく見積もって、です。

ほかの、さらに特筆すべき変更のいくつかを挙げます:

* 環境変数 "PYTHONINSPECT" をセットしておくと、Python インタプリタが
  Python プログラム実行後に対話モードに入ります。これは Python を "-i"
  で起動するのと同じです。環境変数は Python インタプリタ実行前にセット
  するか、Python プログラムのその実行の一部としてセットすることが出来
  ます。

* The "regrtest.py" script now provides a way to allow "all
  resources except *foo*."  A resource name passed to the "-u" option
  can now be prefixed with a hyphen ("'-'") to mean "remove this
  resource."  For example, the option '"-uall,-bsddb"' could be used
  to enable the use of all resources except "bsddb".

* ドキュメントのビルドに使われるツールは今では Unix 同様に Cygwin で
  も 動作します。

* "SET_LINENO" 命令コード (opcode) は削除されました。彼方の昔に戻れ
  ば 、この命令コードはトレースバック内で行番号を生成し、トレース関数
  をサ ポートするのに必要でした (例えば "pdb" のために)。Python 1.5 よ
  り、 トレースバック内の行番号は "python -O" で働くための異なったメカ
  ニズ ムを用いて計算で求められてきました。2.3 のためには Michael
  Hudson が トレース関数を呼ぶのに決定する似た方法を実装しましたので、
  "SET_LINENO" の必要性は完全になくなりました。

  Python コードから何か異なる結果を見つけるのは、 "-O" なしで Python
  を実行する際のわずかなスピードアップを別とすれば、困難かもしれません
  。

  フレームオブジェクトの "f_lineno" フィールドにアクセスしている C 拡
  張は、代わりに "PyCode_Addr2Line(f->f_code, f->f_lasti)" を呼び出す
  べきです。これは以前の Python バージョンでも "python -O" のもとでコ
  ードが動作するのにも望ましい効果を持つでしょう。

  気の利いた新機能としては、トレース関数は、今ではフレームオブジェクト
  の "f_lineno" 属性を、次に実行される行に変更してセットします。 "pdb"
  デバッガにはこの新機能の恩恵を受けて "jump" コマンドが追加されていま
  す。 (Implemented by Richie Hindle.)


Python 2.3 への移植
===================

このセクションでは前述の変更により必要となるかもしれないコードの変更を
列挙します:

* "yield" は今では常にキーワードです。変数名として使っていたならば、
  別 の名前を選ぶ必要があります。

* 文字列 *X* と *Y* について、 "X in Y" は *X* が一文字以上の場合で
  も 動作するようになりました。

* "int()" 型コンストラクタは、文字列や浮動小数点数を整数に収める際、
  そ れがとても大き場合に  "OverflowError" を投げるのではなく長整数を
  返す ようになっています。

* 8 ビット文字を含んだ Unicode 文字列をソースコードに埋め込む場合、
  フ ァイルのエンコーディング (UTF-8, Latin-1, あるいはほか何か) を、
  ファ イルの先頭のコメントに宣言しなければなりません。 PEP 263: ソー
  スコー ドのエンコーディング を参照してください。

* "_tkinter" を介した Tcl メソッド呼び出しは今では文字列だけを返すの
  で はありません。代わりに Tcl は対応する Python の等価なオブジェクト
  に 変換されたオブジェクトを返します。Python に等価なものがなければ
  "_tkinter.Tcl_Obj" で包んで返します。

* "0xffffffff" のような大きな値の 8 進、16 進リテラルで
  "FutureWarning" が発行されます。2.3 ではこれは 32 ビットの値に格納さ
  れて結果は負の値になりますが、Python 2.4 ではこれは正の長整数になり
  ます。

  この警告の修正をする方法が少しだけあります。本当に正の値が欲しいので
  あれば "L" をリテラルの最後に付けて下さい。32 ビット分だけの下位ビッ
  トセットで 32 ビット整数を取り出したいのであれば、また、 "~(1 <<
  31)" のような式を使ってきたのであれば、おそらく全ビットをセットする
  ことから始めて上位ビットをクリアするのが最も簡明です。例えば最上位ビ
  ット (ビット 31) を単にクリアするには "0xffffffffL &~(1L<<31)" と書
  けます。(---訳注: 2 点。Python 3 サポートを検討するならば "L" は付け
  ないように。2.4 以降は警告もなしに長整数になりますし。もう一点はこの
  パラグラフ全体について。根本的に警告への対処の話をしてるようで後半は
  ほとんど本質でない話をしているので意味不明な文章になっています。本当
  に 2.3 を使わなければならないのでない限り、この文章を真面目に理解し
  ようとしなくとも良いと思います(本質的な措置は "L" を付けることしかな
  い、2.3 では)。---)

* "__debug__" に代入することでアサーションを無効にすることは出来なく
  な りました。

* Distutils の "setup()" 関数に *depends* のような色々な新しいキーワ
  ー ド引数が追加されています。Distutils の古いバージョンでは未知のキ
  ーワ ードを渡すと処理を中断してしまいます。新旧で動作させなければな
  らない のであれば、 "setup.py" 内で "get_distutil_options()" 関数の
  有無をチ ェックし、それらをサポートするバージョンの Distutils でのみ
  新しいキ ーワード引数を使うようにしてください:

     from distutils import core

     kw = {'sources': 'foo.c', ...}
     if hasattr(core, 'get_distutil_options'):
         kw['depends'] = ['foo.h']
     ext = Extension(**kw)

* "None" を変数名に使うと "SyntaxWarning" 警告を出すようになっていま
  す 。

* Python と一緒に含まれるモジュールで定義される拡張型の名前にモジュ
  ー ル名と "'.'" が型名の頭に付くようになっています。


謝辞
====

著者は提案の申し出や修正、様々なこの記事の草稿の助けをしてくれた以下の
人々に感謝します:  Jeff Bauer, Simon Brunning, Brett Cannon, Michael
Chermside, Andrew Dalke, Scott David Daniels, Fred L. Drake, Jr.,
David Fraser, Kelly Gerber, Raymond Hettinger, Michael Hudson, Chris
Lambert, Detlef Lannert, Martin von Löwis, Andrew MacIntyre, Lalo
Martins, Chad Netzer, Gustavo Niemeyer, Neal Norwitz, Hans Nowak,
Chris Reedy, Francesco Ricciardi, Vinay Sajip, Neil Schemenauer, Roman
Suzi, Jason Tishler, Just van Rossum.
