LoginSignup
8
8

More than 5 years have passed since last update.

Python 2.7で稼働中のDjangoアプリケーションをPython 3.5へ移行する

Last updated at Posted at 2015-11-28

これは何?

このドキュメントは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

動作しないライブラリ

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文によるSyntaxErrorPython 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}]

この変更が一番きつい。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8