3. 2to3
ツールの使い方¶
3.1. 2to3
の概要¶
2to3
はPythonと共にインストールされる 標準的なツール で、
その名の通りPython2向けのソースコードを、Python3対応のソースコードに
変換してくれます。後に説明する future
モジュールも類似の機能を持つています(future モジュール 参照)。
2to3
はpython2対応コードをpython3対応コードに
変換する際に必要な変更のほとんどに対応していますが、若干の手直しを
必要とする場合があります。
しかしながら、Python2向けソースコードを
Python3対応にする為の最初の一歩としては必須のツールです。
future
モジュールの futureize コマンドや Modernize コマンドも内部ではlib2to3の機能を使っています。
3.2. 2to3
の基本的な使い方¶
2to3
が変更された文法のどれに対応しているかは、
2to3 -l
を実行することで確認できます。 この文章作成時に実行したところ、52の変換項目(変換サブプログラムに対応している)が挙げられました。 [1]
|
|
|
|
|
これらの変換項目は "-f
"オプションや"-x
"オプションを追加することで、明示的に変換項目に有効化/無効化を指定できます。
これらの変換項目のいくつか( buffer, idioms, set_lieteral, ws_comma )はオプショナルな変換項目となっており、通常は無効化されています。
これらの変換項目による結果は、厳密に等価なプログラムを与える訳では無いことから、オプショナルな変換項目となっているようです。
-f
を使って変換項目を指定すると、明示的に指定した変換項目だけが有効化されます。既定の変換項目に変換項目を追加するには、
2to3 -f all -f <変換項目名> .
とします。
3.2.1. 変換項目(変換プログラム)¶
上にあげた変換項目(apply,...) の内容は、例えば https://docs.python.org/ja/3/library/2to3.html#fixersに説明されています。
これらの変換プログラムのうち、
imports/imports2
は python2
から python3
への移行時にモジュール名が変更されたモジュール(例えばTkinter -> tkinter)に対応してくれます。
importsでは、Tkinter, FileDialo, Tix, ttk などのTk関係のモジュール、dbmに関連したモジュール, xmlrpcサーバ関係のモジュール、
httplibやHTTPServerに関連したモジュールなどに対応しています。
また、imports2ではwhichdbm, anydbmの使用がdbmモジュールを使うように変更されます。
importsとimports2に分離されているのは、"単に技術的な制約のため" だそうです。
urllib
については imports
とは別に変換プログラム ``urllib``(fix_urllib.py)が用意されています。
idioms
変換プログラムは、"Python コードをより Python らしい書き方" にするいくつかの変形を行います。
objectの型type(obj)
とTypeオブジェクトT
との
比較を、可能なところでは、isInstance(obj,T)
に置き換える、
while 1:
をwhile True:
に置き換える、
可能な場所ではsorted(EXPR)
を使う、等の変換を行います。
3.2.2. Tabとスペース¶
http://python3porting.com/differences.html#index-14 には次の記載があります。
In Python 2 a tab will be equal to eight spaces as indentation, so you can indent one line with a tab, and the next line with eight spaces. This is confusing if you are using an editor that expands tabs to another number than eight spaces.
In Python 3 a tab is only equal to another tab. This means that each indentation level has to be consistent in its use of tabs and spaces. If you have a file where an indented block sometimes uses spaces and sometimes tabs, you will get the error TabError: inconsistent use of tabs and spaces in indentation.
つまり、python2では 一つのブロック中で tabとspaceを混在しても、tabとspaceの関係( 1 tab = 8 spaces)を使ってブロック内 の各行の始まりが一致していれば問題はありませんでした。 一方python3 では、同じブロックの中では、tabとスペースの数と位置が一致している必要があります。
このため、同じブロック内でtabとスペースの数が異なる行があるスクリプトでは、python2では動作するけれど、python3では動作しないことになります。
TABと空白の混在はエディタなどの環境の違いによって、見かけ上の構造と Pythonインタプリタからみた構造が異なる場合があります。 これはpython2においても同様ですので、python2/python3にかかわらずTABと空白の混在は避けておくのが得策です。
ちなみに私自身はemacsのPython-modeを使いpythonプログラムを開発します。
此の環境では、キーボードからのTAB入力は複数の空白に置き換えてくれます。
デフォルトは4個の空白ですが、これを変更することも可能です(Preference
でPython Indent Offset
を変更する)。
3.2.3. 変更部分の確認¶
2to3
を出力を指定するオプションをつけずに実行することで、
2to3
が加える変更をdiff形式の出力で確認できます。
2to3 *.py
あるいは
2to3 .
で現在にディレクトリにあるpythonコードで必要な変換内容を確認します。
必要に応じて、-f``あるいは
-x``オプションをつけて変更項目の有効化/無効化を試行して見ます。
3.2.4. 新しいディレクトリにPytho3対応ソースコードを作成する。¶
2to3
には様々なオプションが用意されていますが、次のシェルコマンド
mkdir ../PY3
2to3 -W -n -o ../PY3 .
を知っていれば、最低限の用は足りるでしょう。このコマンドは、 python2のソースコードのディレクトリに現在居るとして、
Python3用の作業ディレクトリ../PY3を作成し、(mkdir ../PY3)
そのディレクトリに現在のディレクトリにある全てのPythonソースコードを
2to3
で必要な場合には、Python3向けに変換し、(2to3
)変換の必要の無いファイルを含めて(-W -n)
新しいディレクトリ(../PY3)に書き出します。(-o ../PY3)
-n
オプションは、オリジナルのPython2向けコードをbackupとして作成しないことを指定しています。-n
オプションは-o
オプション を使う際には必須となっています。
2to3
コマンドの詳細は、
2to3 --help
で確認できます。
3.3. mercurialなどを使って管理している場合¶
ソースコードを mercurial などの管理ツールを使って 管理している場合には、ブランチなどの機能を使って、python3版の 開発を進めることが考えられます。
mkdir PY3
cd PY3
hg clone <repository> .
によって、現在のバージョンのコピーを作業ディレクトリ(PY3)に作成します。ここで、
2to3 -w -n .
を実行すると、Python3への変更が必要なファイルだけが2to3
によって変更されます。
変更前のファイルをバックアップとして残して置きたい場合には、
2to3 -w
とします。もっとも、hgで管理しているのであれば、hg diffで見ることができるので、あまり必要な無いように思われます。
3.3.1. setup ツールとの連携¶
setuptoolsを使ったinstall scriptでは、use_2to3
オプション
を設定することで、”setup.py intall"実行時に自動的に2to3
を適用してからインストールすることができます。
後で見るように、2to3
で自動変換したプログラムがpython3では意図した動作とならない場合があることから、その有用性はあまり無いのかもしれません。 setuptools のドキュメントでも
Setuptools provides a facility to invoke 2to3 on the code as a part of the build process, by setting the keyword parameter use_2to3 to True, but the Setuptools project strongly recommends instead developing a unified codebase using six, future, or another compatibility library.
—setuptools 45.2.0 documentation
となっています。一般的には、この記述にも触れられている six
あるいは future
などのモジュールを使うことが推奨されています。必要な変更の数が少ない場合には、有効な方法ですので、ダメもとで一度試して見るだけの価値は有りそうです。