これは何?
このドキュメントはPython 2.7で稼働しているDjangoアプリケーションをPython 3.5に移行するコストを調査した際のメモです。
2to3
xrangeの変更やkeys(), values(), items()の変更を2to3で変換する。
-xで適用しない変換を指定可能なので、以下の変換は除外した。
-
future-
from __future__ import unicode_literalsは残っていても支障がないのでdiffを少なくするために除外
-
-
print-
print関数を使うように徹底してきて、print文は存在しないはずなので除外
-
-
callable-
callableが利用できないのはPython 3.0/3.1だけであり、Python 3.5.xへの移行を想定しているため不要。
-
-wオプションで元のファイルを上書きして変換を実行。
$ 2to3 -x future -x print -x callable -w .
アップデートが必要だったライブラリ
python-memcached
だだしバイナリをMemcachedに入れた時の挙動は怪しいと思う。
tweepy
google-api-python-client
Django
1.8.xにアップデートが必要。
File "/home/csakatoku/.pyenv/versions/3.5.0/lib/python3.5/site-packages/django/utils/html_parser.py", line 12, in <module>
HTMLParseError = _html_parser.HTMLParseError
AttributeError: module 'html.parser' has no attribute 'HTMLParseError'
乗り換えが必要なライブラリ
dnspython
別のパッケージ名でリリースされているdnspython3に変更する必要がある。pipでインストールするときにdnspython3を指定すればOKで、コードの変更は不要。
MySQL-python
-
https://pypi.python.org/pypi/MySQL-python
-
MySQL-pythonではなくmysqlclientを使えば問題なし。
-
動作しないライブラリ
bitly-api
ImportErrorで動作しない。ただしmasterでは修正されている模様。
>>> import bitly_api
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/csakatoku/.pyenv/versions/3.5.0/lib/python3.5/site-packages/bitly_api/__init__.py", line 1, in <module>
from bitly_api import Connection, BitlyError, Error
ImportError: cannot import name 'Connection'
django_ses
try...except文の問題でインポートしようとした瞬間に落ちる。ただしmasterでは修正されている模様。
>>> import django_ses
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/csakatoku/.pyenv/versions/3.5.0/lib/python3.5/site-packages/django_ses/__init__.py", line 173
except SESConnection.ResponseError, err:
^
SyntaxError: invalid syntax
pynliner
print文によるSyntaxError。Python 3対応のPull Requestが出されている。
Collecting pynliner
Using cached pynliner-0.5.2.tar.gz
Collecting BeautifulSoup<4.0,>=3.2.1 (from pynliner)
Using cached BeautifulSoup-3.2.1.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 20, in <module>
File "/tmp/pip-build-7je9i10s/BeautifulSoup/setup.py", line 22
print "Unit tests have failed!"
^
SyntaxError: Missing parentheses in call to 'print'
修正が必要なコード
hashlib.sha1の引数にはbinaryを渡さないといけない
Bad
>>> import hashlib
>>> hashlib.sha1("SPAM").hexdigest()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Unicode-objects must be encoded before hashing
>>> hashlib.sha1("SPAM").hexdigest()
Good
>>> import hashlib
>>> hashlib.sha1("spam".encode("utf-8")).hexdigest()
'ded982e702e07bb7b6effafdc353db3fe172c83f'
Good
>>> import hashlib
>>> hashlib.sha1(b"spam").hexdigest()
'ded982e702e07bb7b6effafdc353db3fe172c83f'
urllib.basejoinがなくなった
どこに行った?
sortの引数が変わった
Bad
>>> data = [{"value": 1}, {"value": 3}, {"value": 2}]
>>> data.sort(lambda a, b: cmp(a["value"], b["value"]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must use keyword argument for key function
Good
>>> data = [{"value": 1}, {"value": 3}, {"value": 2}]
>>> data.sort(key=lambda x: x["value"])
>>> print(data)
[{'value': 1}, {'value': 2}, {'value': 3}]
この変更が一番きつい。