これは何?
このドキュメントは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}]
この変更が一番きつい。