2to3 - Python 2 から 3 への自動コード変換
*****************************************

2to3 は、 Python 2.x のソースコードを読み込み、一連の *変換プログラム
(fixer)* を適用して正しい Python 3.x のコードに変換する Python プログ
ラムです。標準ライブラリはほとんど全てのコードを取り扱うのに十分な
fixer を含んでいます。ただし 2to3 を構成している "lib2to3" は柔軟かつ
一般的なライブラリなので、 2to3 のために独自の fixer を書くこともでき
ます。


2to3 の使用
===========

2to3 は大抵の場合、 Python インタープリターと共に、スクリプトとしてイ
ンストールされます。場所は、 Python のルートディレクトリにある、
"Tools/scripts" ディレクトリです。

2to3 に与える基本の引数は、変換対象のファイル、もしくは、ディレクトリ
のリストです。ディレクトリの場合は、 Python ソースコードを再帰的に探索
します。

Python 2.x のサンプルコード、 "example.py" を示します:

   def greet(name):
       print "Hello, {0}!".format(name)
   print "What's your name?"
   name = raw_input()
   greet(name)

これは、コマンドラインから 2to3 を呼び出すことで、Python 3.x コードに
変換されます:

   $ 2to3 example.py

オリジナルのソースファイルに対する差分が表示されます。 2to3 は必要とな
る変更をソースファイルに書き込むこともできます ("-n" も与えたのでない
限りオリジナルのバックアップも作成されます)。変更の書き戻しは "-w" フ
ラグによって有効化されます:

   $ 2to3 -w example.py

変換後、 "example.py" は以下のようになります:

   def greet(name):
       print("Hello, {0}!".format(name))
   print("What's your name?")
   name = input()
   greet(name)

変換処理を通じて、コメントと、インデントは保存されます。

デフォルトでは、 2to3 は一連の 事前定義された変換プログラム を実行しま
す。 "-l" フラグは、利用可能な変換プログラムの一覧を表示します。 "-f"
フラグにより、実行する変換プログラムを明示的に与えることもできます。同
様に、 "-x" は変換プログラムを明示的に無効化します。下記の例では、
"imports" と "has_key" 変換プログラムだけを実行します:

   $ 2to3 -f imports -f has_key example.py

このコマンドは "apply" 以外のすべての変換プログラムを実行します:

   $ 2to3 -x apply example.py

いくつかの変換プログラムは *明示的*、つまり、デフォルトでは実行されず
、コマンドラインで実行するものとして列記する必要があります。デフォルト
の変換プログラムに "idioms" 変換プログラムを追加して実行するには、下記
のようにします:

   $ 2to3 -f all -f idioms example.py

ここで、 "all" を指定することで、全てのデフォルトの変換プログラムを有
効化できることに注意して下さい。

2to3 がソースコードに修正すべき点を見つけても、自動的には修正できない
場合もあります。この場合、 2to3 はファイルの変更点の下に警告を表示しま
す。 3.x に準拠したコードにするために、あなたはこの警告に対処しなくて
はなりません。

2to3 は doctest の修正もできます。このモードを有効化するには "-d" フラ
グを指定して下さい。 doctest *だけ* が修正されることに注意して下さい。
これは、モジュールが有効な Python コードであることを要求しないというこ
とでもあります。例えば、 reST ドキュメント中の doctest に似たサンプル
コードなども、このオプションで修正することができます。

"-v" は、変換処理のより詳しい情報の出力を有効化します。

いくつかの print 文は関数呼び出しとしても文としても解析できるので、
2to3 は print 関数を含むファイルを常に読めるとは限りません。 2to3 は
"from __future__ import print_function" コンパイラディレクティブが存在
することを検出すると、内部の文法を変更して "print()" を関数として解釈
するようになります。 "-p" フラグによって手動でこの変更を有効化すること
もできます。 print 文を変換済みのコードに対して変換プログラムを適用す
るには "-p" を使用してください。同様に、"exec()" を関数として解釈させ
るには "-e" を使用してください。

"-o" または "--output-dir" で処理結果の出力先ディレクトリを変更出来ま
す。入力ファイルを上書きしないならバックアップは意味をなさないので、オ
プション "-n" フラグが要ります。

バージョン 3.2.3 で追加: "-o" オプションが追加されました。

"-W" または "--write-unchanged-files" により、たとえファイルに変更が必
要なくても常にファイルを出力するように 2to3 に指示することが出来ます。
これは、 "-o" とともに使って、Python ソースツリー全体を変換して別のデ
ィレクトリに書き出す際に最も有用です。

バージョン 3.2.3 で追加: "-W" フラグが追加されました。

オプション "--add-suffix" で、全ての出力ファイル名に与えた文字列を追加
します。これを指定するのであれば別名で書き出されるためバックアップは必
要ないので、オプション "-n" フラグが要ります。例えば:

   $ 2to3 -n -W --add-suffix=3 example.py

とすれば変換後ファイルは "example.py3" として書き出されます。

バージョン 3.2.3 で追加: "--add-suffix" オプションが追加されました。

ひとつのディレクトリツリーからプロジェクト全体を変換したければこのよう
に使います:

   $ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode


変換プログラム
==============

コード変形の各ステップは変換プログラムに隠蔽されます。 "2to3 -l" コマ
ンドは変換プログラムのリストを表示します。 上記 の通り、それぞれの変換
プログラムを個別に有効化したり無効化したりすることができます。ここでは
それらをさらに詳細に説明します。

apply

   "apply()" の使用を削除します。例えば "apply(function, *args,
   **kwargs)" は "function(*args, **kwargs)" に変換されます。

asserts

   廃止になった "unittest" メソッド名を新しい名前に置換します。

   +----------------------------------+--------------------------------------------+
   | 対象                             | 変換先                                     |
   |==================================|============================================|
   | "failUnlessEqual(a, b)"          | "assertEqual(a, b)"                        |
   +----------------------------------+--------------------------------------------+
   | "assertEquals(a, b)"             | "assertEqual(a, b)"                        |
   +----------------------------------+--------------------------------------------+
   | "failIfEqual(a, b)"              | "assertNotEqual(a, b)"                     |
   +----------------------------------+--------------------------------------------+
   | "assertNotEquals(a, b)"          | "assertNotEqual(a, b)"                     |
   +----------------------------------+--------------------------------------------+
   | "failUnless(a)"                  | "assertTrue(a)"                            |
   +----------------------------------+--------------------------------------------+
   | "assert_(a)"                     | "assertTrue(a)"                            |
   +----------------------------------+--------------------------------------------+
   | "failIf(a)"                      | "assertFalse(a)"                           |
   +----------------------------------+--------------------------------------------+
   | "failUnlessRaises(exc, cal)"     | "assertRaises(exc, cal)"                   |
   +----------------------------------+--------------------------------------------+
   | "failUnlessAlmostEqual(a, b)"    | "assertAlmostEqual(a, b)"                  |
   +----------------------------------+--------------------------------------------+
   | "assertAlmostEquals(a, b)"       | "assertAlmostEqual(a, b)"                  |
   +----------------------------------+--------------------------------------------+
   | "failIfAlmostEqual(a, b)"        | "assertNotAlmostEqual(a, b)"               |
   +----------------------------------+--------------------------------------------+
   | "assertNotAlmostEquals(a, b)"    | "assertNotAlmostEqual(a, b)"               |
   +----------------------------------+--------------------------------------------+

basestring

   "basestring" を "str" に変換します。

buffer

   "buffer" を "memoryview" に変換します。 "memoryview" API は
   "buffer" と似ているものの厳密に同じではないので、この変換プログラム
   はオプションです。

dict

   辞書をイテレートするメソッドを修正します。 "dict.iteritems()" は
   "dict.items()" に、 "dict.iterkeys()" は "dict.keys()" に、
   "dict.itervalues()" は "dict.values()" に変換されます。同様に
   "dict.viewitems()", "dict.viewkeys()" "dict.viewvalues()" はそれぞ
   れ "dict.items()", "dict.keys()", "dict.values()" に変換されます。
   また、 "list" の呼び出しの中で "dict.items()", "dict.keys()",
   "dict.values()" を使用している場合はそれをラップします。

except

   "except X, T" を "except X as T" に変換します。

exec

   "exec" 文を "exec()" 関数に変換します。

execfile

   "execfile()" の使用を削除します。 "execfile()" への引数は "open()",
   "compile()", "exec()" の呼び出しでラップされます。

exitfunc

   "sys.exitfunc" への代入を "atexit" モジュールの使用に変更します。

filter

   "list" 呼び出しの中で "filter()" を使用している部分をラップします。

funcattrs

   名前が変更された関数の属性を修正します。例えば
   "my_function.func_closure" は "my_function.__closure__" に変換され
   ます。

future

   "from __future__ import new_feature" 文を削除します。

getcwdu

   "os.getcwdu()" を "os.getcwd()" に置き換えます。

has_key

   "dict.has_key(key)" を "key in dict" に変更します。

idioms

   このオプションの変換プログラムは、 Python コードをより Python らし
   い書き方にするいくつかの変形を行います。 "type(x) is SomeClass" や
   "type(x) == SomeClass" のような型の比較は "isinstance(x,
   SomeClass)" に変換されます。 "while 1" は "while True" になります。
   また、適切な場所では "sorted()" が使われるようにします。例えば、こ
   のブロックは

      L = list(some_iterable)
      L.sort()

   次のように変更されます

      L = sorted(some_iterable)

import

   暗黙の相対インポート (sibling imports) を検出して、明示的な相対イン
   ポート (relative imports) に変換します。

imports

   標準ライブラリ中のモジュール名の変更を扱います。

imports2

   標準ライブラリ中の別のモジュール名の変更を扱います。単に技術的な制
   約のために "imports" とは別になっています。

input

   "input(prompt)" を "eval(input(prompt))" に変換します。

intern

   "intern()" を "sys.intern()" に変換します。

isinstance

   "isinstance()" の第 2 引数の重複を修正します。例えば "isinstance(x,
   (int, int))" は "isinstance(x, int)" に "isinstance(x, (int, float,
   int))" は "isinstance(x, (int, float))" に変換されます。

itertools_imports

   "itertools.ifilter()", "itertools.izip()", "itertools.imap()" のイ
   ンポートを削除します。また "itertools.ifilterfalse()" のインポート
   を "itertools.filterfalse()" に変換します。

itertools

   "itertools.ifilter()", "itertools.izip()", "itertools.imap()" を使
   っている箇所を同等の組み込み関数で置き換えます。
   "itertools.ifilterfalse()" は "itertools.filterfalse()" に変換され
   ます。

long

   "long" を "int" に変更します。

map

   "list" 呼び出しの中の "map()" をラップします。また、 "map(None, x)"
   を "list(x)" に変換します。 "from future_builtins import map" を使
   うと、この変換プログラムを無効にできます。

metaclass

   古いメタクラス構文 (クラス定義中の "__metaclass__ = Meta") を、新し
   い構文 ("class X(metaclass=Meta)") に変換します。

methodattrs

   古いメソッドの属性名を修正します。例えば "meth.im_func" は
   "meth.__func__" に変換されます。

ne

   古い不等号の構文 "<>" を "!=" に変換します。

next

   イテレータの "next()" メソッドの使用を "next()" 関数に変換します。
   また "next()" メソッドを "__next__()" に変更します。

nonzero

   Renames definitions of methods called "__nonzero__()" to
   "__bool__()".

numliterals

   8 進数リテラルを新しい構文に変換します。

operator

   "operator" モジュール内のさまざまな関数呼び出しを、他の、しかし機能
   的には同等の関数呼び出しに変換します。必要に応じて、"import
   collections.abc" などの適切な "import" ステートメントが追加されます
   。以下のマッピングが行われます。

   +------------------------------------+-----------------------------------------------+
   | 対象                               | 変換先                                        |
   |====================================|===============================================|
   | "operator.isCallable(obj)"         | "callable(obj)"                               |
   +------------------------------------+-----------------------------------------------+
   | "operator.sequenceIncludes(obj)"   | "operator.contains(obj)"                      |
   +------------------------------------+-----------------------------------------------+
   | "operator.isSequenceType(obj)"     | "isinstance(obj, collections.abc.Sequence)"   |
   +------------------------------------+-----------------------------------------------+
   | "operator.isMappingType(obj)"      | "isinstance(obj, collections.abc.Mapping)"    |
   +------------------------------------+-----------------------------------------------+
   | "operator.isNumberType(obj)"       | "isinstance(obj, numbers.Number)"             |
   +------------------------------------+-----------------------------------------------+
   | "operator.repeat(obj, n)"          | "operator.mul(obj, n)"                        |
   +------------------------------------+-----------------------------------------------+
   | "operator.irepeat(obj, n)"         | "operator.imul(obj, n)"                       |
   +------------------------------------+-----------------------------------------------+

paren

   リスト内包表記で必要になる括弧を追加します。例えば "[x for x in 1,
   2]" は "[x for x in (1, 2)]" になります。

print

   "print" 文を "print()" 関数に変換します。

raise

   "raise E, V" を "raise E(V)" に、"raise E, V, T" を "raise
   E(V).with_traceback(T)" に変換します。例外の代わりにタプルを使用す
   ることは 3.0 で削除されたので、"E" がタプルならこの変換は不正確にな
   ります。

raw_input

   "raw_input()" を "input()" に変換します。

reduce

   "reduce()" が "functools.reduce()" に移動されたことを扱います。

reload

   "reload()" を "importlib.reload()" に変換します。

renames

   "sys.maxint" を "sys.maxsize" に変更します。

repr

   バッククォートを使った repr を "repr()" 関数に置き換えます。

set_literal

   "set" コンストラクタの使用を set リテラルに置換します。この変換プロ
   グラムはオプションです。

standarderror

   "StandardError" を "Exception" に変更します。

sys_exc

   廃止された "sys.exc_value", "sys.exc_type", "sys.exc_traceback" の
   代わりに "sys.exc_info()" を使うように変更します。

throw

   ジェネレータの "throw()" メソッドの API 変更を修正します。

tuple_params

   関数定義における暗黙的なタプルパラメータの展開を取り除きます。この
   変換プログラムによって一時変数が追加されます。

types

   "types" モジュールのいくつかのメンバオブジェクトが削除されたことに
   よって壊れたコードを修正します。

unicode

   "unicode" を "str" に変更します。

urllib

   "urllib" と "urllib2" が "urllib" パッケージに変更されたことを扱い
   ます。

ws_comma

   コンマ区切りの要素から余計な空白を取り除きます。この変換プログラム
   はオプションです。

xrange

   "xrange()" を "range()" に変更して、既存の "range()" 呼び出しを
   "list" でラップします。

xreadlines

   "for x in file.xreadlines()" を "for x in file" に変更します。

zip

   "list" 呼び出しの中で使われている "zip()" をラップします。これは
   "from future_builtins import zip" が見つかった場合は無効にされます
   。


"lib2to3" - 2to3's library
==========================

**ソースコード:** Lib/lib2to3/

======================================================================

バージョン 3.10 で非推奨: Python 3.9 から構文解析器が PEG パーサに変更
になり (**PEP 617** を参照のこと)、Python 3.10 には lib2to3 の使用する
LL(1) パーサでは解析できない文法が導入される可能性があります。Python
の将来のバージョンでは "lib2to3" モジュールが標準ライブラリから削除さ
れる可能性があります。その場合、代替として LibCST や parso のようなサ
ードパーティ・ライブラリの使用を検討してください。

注釈:

  "lib2to3" API は安定しておらず、将来、劇的に変更されるかも知れないと
  考えるべきです。
