オリジナルヘッダ PEP: 0263 Title: Defining Python Source Code Encodings Version: 43264 Last-Modified: 2006-03-23 21:13:19 +0100 (Thu, 23 Mar 2006) Author: Marc-Andre Lemburg , Martin v. Lowis Status: Final Type: Standards Track Python-Version: 2.3 Created: 06-Jun-2001 Last-Modified: 2006-05-18 Post-History: 翻訳 Title: Python ソースコードのエンコーディング定義 Version: 43264ja Last-Modified: 2006-10-02 Translator: Masaya jack Kato (jack at jk.to) 概要 このPEPは Python のソースファイルに文字エンコードを宣言する方法を提案します。 宣言されたエンコーディングはPythonがファイルを解釈するときに使用されます。 これにより、Unicode リテラルを含むソースコードの解釈がかなり改善されます。 また、Unicodeの使えるエディタで、例えばUTF-8を用いて直接ソースコードを 書くことができるようになります。 問題 Python 2.1 では、Unicode リテラルは "Unicode エスケープ"を用いた Latin-1エンコードで書く必要がありました。 しかし、多くのアジア諸国のように、Latin-1 のみで表現できない プログラミング環境は存在します。 この問題は、そのような環境に在住するPython ユーザにとっては不便なことです。 プログラマは好みのエンコードで8bit文字列を使うこともできますが、 "Unicodeエスケープ"のために文字列が区切られてしまうことがあります。 解決策の提案 各ソースファイルの先頭に、エンコーディングを宣言する特別なコメントを 置くことにより、Pythonソースコードのエンコーディングを見やすくし、 また、変更しやすくすることを提案します。 このエンコーディング宣言により、Pythonソースコードデータの扱いに注意を払いつつ、 Pythonのいくつかのコンセプトを変更する必要があります。 エンコードの定義 なにもエンコードに関するヒントがなければ、Python は ASCIIを 標準エンコードとして扱います。 ソースコードのエンコーディングを定義するためには、 **魔法のコメント** を一行目か二行目に書く必要があります。:: #!/usr/bin/python # -*- coding: <エンコード名> -*- より正確に言えば、1行目か2行目が、正規表現 "coding[:=]\s*([-\w.]+)" にマッチする必要があります。 この正規表現の最初のグループは、エンコード名として評価されます。 それがPython の知らないものだった場合、コンパイル中にエラーとなります。 エンコーティング宣言のある行にはどんなPython文も置くことはできません。 Windowsのように、ファイルの先頭にUnicode のBOM マークを置く プラットフォームでは、UTF-8のシグネチャである、'\xef\xbb\xbf'があれば、 (魔法のコメントが無い場合にも)utf-8エンコーディングと解釈します。 ソースファイルに、UTF-8 BOM シグネチャと魔法のコメントの両方がある場合、 コメントは utf-8 にする必要があります。 それ以外のエンコーディングはエラーとなります。 例示 Python のソースファイルの先頭で、エンコードの定義をするスタイルを 明確化するためにいくつかのサンプルを例示します。 1. インタプリタの指定と Emacs スタイルのファイルエンコーディングのコメント :: #!/usr/bin/python # -*- coding: latin-1 -*- import os, sys ... #!/usr/bin/python # -*- coding: iso-8859-15 -*- import os, sys ... #!/usr/bin/python # -*- coding: ascii -*- import os, sys ... 2. インタプリタの指定無しで、プレーンテキスト :: # This Python file uses the following encoding: utf-8 import os, sys ... 3. 違うエンコーディング指定の方法があるテキストエディタの例 :: #!/usr/local/bin/python # coding: latin-1 import os, sys ... 4. エンコーディング指定がない場合には、PythonパーサはASCII を仮定 :: #!/usr/local/bin/python # coding: latin-1 import os, sys ... 5. エンコーディング指定が働かない例 :: "coding:" エレメントが無い場合 :: #!/usr/local/bin/python # latin-1 import os, sys ... エンコーディング指定が1行目または2行目にない場合 :: #!/usr/local/bin/python # # -*- coding: latin-1 -*- import os, sys ... サポートされていないエンコーディング :: #!/usr/local/bin/python # -*- coding: utf-42 -*- import os, sys ... 概念 このPEP は魔法のコメントを使えるように実装するため以下の概念に基づいています :: 1. 完全な Python のソースファイルは単一のエンコーディングを使用すべきです。 異なるエンコードの混在は許可されていません。 またソースコードのコンパイル中にエラーとなる可能性もあります。 最初の2行で指定できるどのようなエンコーデングであっても、 マルチバイトのエンコーディングであるShift_JISと同様に、 ASCII互換のエンコードを含みます。 これには、UTF-16のような全ての文字が2バイト以上のエンコーディングは含みません これはエンコーディングを検知するトークナイザのアルゴリズムを シンプルに保つためです。 2. エスケープシーケンスの扱いは、raw文字列はエスケープシーケンスの 非常に小さなサブセットで展開されるのに対し、 (8bitとUnicode両方の)全てのソースコードエンコーディングにおいて、 標準文字列はエスケープシーケンス展開を受けるべきです 3. Pythonのトークナイザ、コンパイラは以下のようにアップデートする 必要があります。 1. ファイルを読みます 2. ファイルごとに確定されたエンコーディングからUnicode にデコードします 3. UTF-8 に変換します 4. UTF-8 のコンテンツをトークン化します 5. コンパイルします。そして、Unicode データからUnicode オブジェクトを作り、 UTF-8 から最初のエンコーディングによる 8bit 文字列データに再エンコードして、 Unicode 文字列から文字列オブジェクトを作成します。 Python の識別子はエンコーディングのASCII サブセットに制限されることと、 ステップ4以降の変換を必要としないことに注意してください。 実装 エンコーディングの宣言無しに非ASCII文字列が使われている既存のコードの後方互換性のため、 実装は2段階にわけて行われます 1. エンコーディング宣言が無い場合、内部的に "iso-8859-1"を宣言したと扱うことで、 非ASCII文字列を文字列やコメントに使えるようにします。 任意のバイト文字列の処理中、ステップ2~5の間を正しく行き来するため (This will cause arbitrary byte strings to correctly round-trip between step 2 and step 5 of the processing,) そして非ASCII文字を含むUnicode 文字列にPython 2.2 との互換性を提供ためです。 もし非ASCII文字が入力中にあれば不適切なエンコードのファイル一つにつき 一回の警告が発せられます 2. 警告を削除し、デフォルトエンコーディングを "ascii" とします。 Unicode を入力として受け付けるようにビルトインのcompile()API を拡張します。 8ビットの文字列は、上で述べたような標準的エンコーディング検知プロセスを受けます compile()に、コーディング宣言によるUnicode文字列が与えられた場合には、 SyntaxError を発生させます。 SUZUKI Hisao がパッチに取り組んでいます。詳しくは [2] を見てください。 第一段階の実装のみのパッチは [1] にあります。 現状 デフォルトエンコーディングを "ascii" に変えることを除き、上記 1, 2 の 実装は 2.3 で完了しています。 Python 2.5 で、デフォルトエンコーディングが "ascii" に変わりました。 スコープ このPEP は、現状エンコーディング未定義の(だいたいの)ソースコードから、 より頑丈で可搬的なエンコーディング定義へのアップグレードパス提供を 目的としてます リファレンス [1] Phase 1 implementation: http://python.org/sf/526840 [2] Phase 2 implementation: http://python.org/sf/534304 ヒストリ 1.10 以降: CVS history を見てください。 1.8: Added '.' to the coding RE. 1.7: 1段階目の実装へ警告を追加。 インタプリタのデフォルトエンコーディングを Latin-1に変更 compile() の微調整。 1.4 - 1.6: 細かい微調整 1.3: Martin v. Loewisのコメントより: UTF-8 BOM マークの検知、 Emacs スタイルの魔法のコメント、 実装の2段階アプローチ。 著作権 このドキュメントは、パブリックドメインです。 この翻訳もパブリックドメインです(訳者)。 正確な翻訳を心がけておりますが、誤訳やそれによる損害は保証しません(訳者)。