26.7. 2to3 - Python 2 から 3 への自動コード変換¶
2to3 は、 Python 2.x のソースコードを読み込み、一連の 変換プログラム を適用して Python 3.x のコードに変換するプログラムです。標準ライブラリはほとんど全てのコードを取り扱うのに十分な変換プログラムを含んでいます。ただし 2to3 を構成している lib2to3
は柔軟かつ一般的なライブラリなので、 2to3 のために自分で変換プログラムを書くこともできます。 lib2to3
は、 Python コードを自動編集する必要がある場合にも適用することができます。
26.7.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.
バージョン 3.2.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.
バージョン 3.2.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
として書き出されます。
バージョン 3.2.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
26.7.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)
-
buffer
¶ buffer
をmemoryview
に変換します。memoryview
API はbuffer
と似ているものの厳密に同じではないので、この変換プログラムはオプションです。
-
callable
¶ callable(x)
をisinstance(x, collections.Callable)
に変換し、必要ならcollections
のインポートを追加します。callable(x)
は Python 3.2 で復活したので、もしも Python 3.1 をサポートするつもりがないのであれば、この修正プログラムは無効に出来ます。
-
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
に変換します。
-
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
¶ 標準ライブラリ中のモジュール名の変更を扱います。
-
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()
に変換されます。
-
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 進数リテラルを新しい構文に変換します。
-
operator
¶ 関数の呼び出しは、
operator
モジュール内のさまざまな関数を、他の、しかし機能的には同等の関数の呼び出しに変換します。必要に応じて、適切なimport
ステートメントが追加されます。例import collections
など。以下のマッピングが行われます。対象
変換先
operator.isCallable(obj)
hasattr(obj, '__call__')
operator.sequenceIncludes(obj)
operator.contains(obj)
operator.isSequenceType(obj)
isinstance(obj, collections.Sequence)
operator.isMappingType(obj)
isinstance(obj, collections.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)]
になります。
-
raise
¶ raise E, V
をraise E(V)
に、raise E, V, T
をraise E(V).with_traceback(T)
に変換します。例外の代わりにタプルを使用することは 3.0 で削除されたので、E
がタプルならこの変換は不正確になります。
-
reduce
¶ reduce()
がfunctools.reduce()
に移動されたことを扱います。
-
reload
¶ reload()
をimp.reload()
に変換します。
-
renames
¶ sys.maxint
をsys.maxsize
に変更します。
-
sys_exc
¶ 廃止された
sys.exc_value
,sys.exc_type
,sys.exc_traceback
の代わりにsys.exc_info()
を使うように変更します。
-
throw
¶ ジェネレータの
throw()
メソッドの API 変更を修正します。
-
tuple_params
¶ 関数定義における暗黙的なタプルパラメータの展開を取り除きます。この変換プログラムによって一時変数が追加されます。
-
ws_comma
¶ コンマ区切りの要素から余計な空白を取り除きます。この変換プログラムはオプションです。
-
xreadlines
¶ for x in file.xreadlines()
をfor x in file
に変更します。
26.7.3. lib2to3
- 2to3’s library¶
ソースコード: Lib/lib2to3/
注釈
lib2to3
API は安定しておらず、将来、劇的に変更されるかも知れないと考えるべきです。