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

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


25.4.1. 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)

It can be converted to Python 3.x code via 2to3 on the command line:

   $ 2to3 example.py

A diff against the original source file is printed.  2to3 can also
write the needed modifications right back to the source file.  (A
backup of the original file is made unless "-n" is also given.)
Writing the changes back is enabled with the "-w" flag:

   $ 2to3 -w example.py

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

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

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

By default, 2to3 runs a set of predefined fixers.  The "-l" flag lists
all available fixers.  An explicit set of fixers to run can be given
with "-f".  Likewise the "-x" explicitly disables a fixer.  The
following example runs only the "imports" and "has_key" fixers:

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

This command runs every fixer except the "apply" fixer:

   $ 2to3 -x apply example.py

Some fixers are *explicit*, meaning they aren't run by default and
must be listed on the command line to be run.  Here, in addition to
the default fixers, the "idioms" fixer is run:

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

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

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

2to3 can also refactor doctests.  To enable this mode, use the "-d"
flag.  Note that *only* doctests will be refactored.  This also
doesn't require the module to be valid Python.  For example, doctest
like examples in a reST document could also be refactored with this
option.

The "-v" option enables output of more information on the translation
process.

Since some print statements can be parsed as function calls or
statements, 2to3 cannot always read files containing the print
function.  When 2to3 detects the presence of the "from __future__
import print_function" compiler directive, it modifies its internal
grammar to interpret "print()" as a function.  This change can also be
enabled manually with the "-p" flag.  Use "-p" to run fixers on code
that already has had its print statements converted.

The "-o" or "--output-dir" option allows specification of an alternate
directory for processed output files to be written to.  The "-n" flag
is required when using this as backup files do not make sense when not
overwriting the input files.

バージョン 2.7.3 で追加: The "-o" option was added.

The "-W" or "--write-unchanged-files" flag tells 2to3 to always write
output files even if no changes were required to the file.  This is
most useful with "-o" so that an entire Python source tree is copied
with translation from one directory to another. This option implies
the "-w" flag as it would not make sense otherwise.

バージョン 2.7.3 で追加: The "-W" flag was added.

The "--add-suffix" option specifies a string to append to all output
filenames.  The "-n" flag is required when specifying this as backups
are not necessary when writing to different filenames.  Example:

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

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

バージョン 2.7.3 で追加: The "--add-suffix" option was added.

To translate an entire project from one directory tree to another use:

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


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

コード変形の各ステップは変換プログラムに隠蔽されます。 "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))" に変換されます。

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

   "__nonzero__()" を "__bool__()" に変更します。

numliterals

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

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)" に変換します。例外の代わりにタプルを使用す
   ることは Python 3 で削除されたので、 "E" がタプルならこの変換は不正
   確になります。

raw_input

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

reduce

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

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" が見つかった場合は無効にされます
   。


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

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