BPStudy#54 そろそろPython3

66
今年はPython3.3! そろそろ乗り換えモードじゃない? BPStudy #54 小田切 "aodag" 篤

Transcript of BPStudy#54 そろそろPython3

Page 1: BPStudy#54 そろそろPython3

今年はPython3.3!そろそろ乗り換えモードじゃない?

BPStudy #54小田切 "aodag" 篤

Page 2: BPStudy#54 そろそろPython3

お前誰よ?

小田切篤@aodag とある代々木の会社のエンジニア

http://facebook.com/aodaghttp://aodag.posterous.com

Page 3: BPStudy#54 そろそろPython3

アジェンダ

なぜPython3?Python アドベントカレンダー2011 (Python3)Python3対応奮闘記Python3対応に役立つツールPython3対応の勘所

Page 4: BPStudy#54 そろそろPython3

Python3って?

Pythonのバージョン3後方互換性のない変更を含む

Python2.6 Python3.1Python2.7 Python3.2と並行してリリースされてきた

今年の3月にPython3.3a1のリリースが予定されている

Page 5: BPStudy#54 そろそろPython3

なぜPython3

Python2系は2.7で終わりもうPythonへの機能追加はPython3でしか行われない

Python3は単なるメジャーバージョンアップ

Python3でうれしい?いつかはPython3になってしまう。Python3対応は必然。

Page 6: BPStudy#54 そろそろPython3

Python3対応に手を出すわけ

去年の夏にフォームライブラリを調べた(PyConJP 2011で発表)したが、Python3に対応したものがまったくないことが気になっていた

Page 7: BPStudy#54 そろそろPython3

Python3対応に手を出すワケ

今ならPython3対応することで、オープンソースコミュニティに貢献しやすい。(大半が機械的な作業なので、実はローカライズについで手が出しやすい)

Page 8: BPStudy#54 そろそろPython3

Python3対応奮闘記

ある日、ある雪山の開発合宿、あるIRCで

aodag: Python3やってるひとー。フォームライブラリ何使ってる?other: Python3対応してるフォームライブラリないよmcdonc_: deformとcolander対応する予定だけど、優先度高くないよ。

※ mcdonc_はpyramidの主要開発者です

Page 9: BPStudy#54 そろそろPython3

aodag: deformとかなんで2.4とかまだサポートしてるのん? mcdonc_: ちゃんとした理由はないよ。3対応するなら2.6以降だけのサポートでいいね。 aodag: pyramidと同じようにワンソースアプローチだといいね。 mcdonc: それでうまくやってけそうだからね。

Page 10: BPStudy#54 そろそろPython3

mcdonc_: Start Hacking ;)

Page 11: BPStudy#54 そろそろPython3

(え、俺がやるの....?)

Page 12: BPStudy#54 そろそろPython3

ということで

pylonsprojectとrepoze、Paste の以下のライブラリについてpy3対応

● peppercorn リリース済● colander リリース済 ● deform リリース済● repoze.who 作業中

やろうかなと思うもの● pyramid_who● pyramid_rpc● PasteScript

Page 13: BPStudy#54 そろそろPython3

現在Python3対応しているライブラリ

http://pypi.python.org/pypi?:action=browse&c=533&show=all

SQLAlchemylxmlPyQtbottlepyramidSphinxnumpy/scipyipython...

Page 14: BPStudy#54 そろそろPython3

Python3対応のアプローチ(1)ワンソースアプローチ

2to3変換やバージョンごとのモジュール切り替え

を行いません

Page 15: BPStudy#54 そろそろPython3

Python3対応のアプローチ(1)ワンソースアプローチ

Pylons、repozeはこの方法

2系は2.6以降のサポートにします2.5以前は文法の差異を吸収できませんtoxにより、対応バージョンのテストを一度に実行できるようにします

3系は3.0,3.1は無視してもかまいません。

Page 16: BPStudy#54 そろそろPython3

今現在Python3に手を出すような人は

3.2に移行してます。

Page 17: BPStudy#54 そろそろPython3

Python3対応のアプローチ(2)2to3を使う方法

2to3を使ってソースを変換する

SQLAlchemyはこの方法

setupで、use_2to3=Trueにすれば、インストール時に2to3でコード変換してくれます

Page 18: BPStudy#54 そろそろPython3

2to3

変換後にちゃんと動くかは、やはりテストが必要。開発中に2to3すると、ソースを直接書き換えられてしまう。toxで2to3変換後のソースをテストするにはコツが必要。

Page 19: BPStudy#54 そろそろPython3

Fuckin' 2to3 !

2to3は使いたくない!

使いたくないワケ

テストコードも2to3するの?変換したテストコードで変換後のテスト...怖い><

ws_comma_fixer が重い

Page 20: BPStudy#54 そろそろPython3

Python3対応の準備 ツールをそろえる

Python実行系の各種バージョンをそろえる

対応させたいバージョンはすべてそろえましょう

Page 21: BPStudy#54 そろそろPython3

Python3対応の準備 ツールをそろえる

toxvirtualenvnosepytestdistributecoverage

Page 22: BPStudy#54 そろそろPython3

tox - 対象バージョン全テスト

[tox]envlist = py26,py27,py32,pypy

[testenv]deps = nosecommands = nosetests []

Page 23: BPStudy#54 そろそろPython3

SIX - 汎用互換ライブラリ

pylonsproject内では個々のパッケージでcompat.pyを作ってますが、汎用的なものをまとめたライブラリにsixがあります。

Page 24: BPStudy#54 そろそろPython3

すでに誰かやってないか聞く

もしかしたら、もう誰かやってるかもしれないML, IRC, Twitter などで聞く

Page 25: BPStudy#54 そろそろPython3

多分いないので、聞いてしまったことにより、自分がやることになります。

Page 26: BPStudy#54 そろそろPython3

対応バージョン範囲を確認する。python2.5以前を切り捨てるかどうかがポイント切り捨てられないなら2to3を使うか、ダーティハックです。

Page 27: BPStudy#54 そろそろPython3

Start Hacking ;)

Page 28: BPStudy#54 そろそろPython3

手順(?) ソースを取り寄せる

pylonsprojectはgithubにリポジトリがあるのでとても楽でした。githubマジ神

ブランチを切ります

git checkout -b py3k

プロジェクトのやり方にあわせましょう。

Page 29: BPStudy#54 そろそろPython3

テスト環境作成

ひとまず無難なところで2.6か2.7で作業環境を作ります。

mkvirtualenv -p python2.7 testenv

テストツールインストールpip install tox nose coverage

依存ライブラリなどインストールpip install -e .

Page 30: BPStudy#54 そろそろPython3

手順(?) 既存のテストを確認する

そもそも2系で動くテストなければ

はじまりません。

なければテストを充実させるところからです。

Page 31: BPStudy#54 そろそろPython3

既存のテストを確認するカバレージの確認

コマンドラインオプション

nosetests --with-coverage --cover-package=テスト対象

Page 32: BPStudy#54 そろそろPython3

既存のテストを確認する noseの設定

setup.cfg でコマンドラインオプション固定

[nosetests]with-coverage = 1cover-package = テスト対象

Page 33: BPStudy#54 そろそろPython3

toxを設定する

;; tox.ini

[tox]envlist = py26,py27,py32,pypy

[testenv]deps = nose coveragecommands = nosetests []

Page 34: BPStudy#54 そろそろPython3

toxを動かす

コマンド自体は簡単です

$ tox

1回目は対象バージョンすべてのvirtualenvを実行するので時間がかかります。

Page 35: BPStudy#54 そろそろPython3

多分python3で動かないことを確認できるでしょう。 

Page 36: BPStudy#54 そろそろPython3

依存ライブラリを確認する

py3k対応していないライブラリをどうするか?

●依存からはずして代替ライブラリに変更●依存からはずして、同等機能をついか●そのライブラリをpy3k対応する

○本当に対応する○コードをとりこむ

●諦める

Page 37: BPStudy#54 そろそろPython3

互換モジュールを追加する

●独自にcompatモジュールを作る●sixを使う

Page 38: BPStudy#54 そろそろPython3

compatモジュール

バージョンフラグpy3 = sys.version_info > (3,0)

Page 39: BPStudy#54 そろそろPython3

compatモジュール

名前の変わった標準ライブラリ

StringIOurllib周りcookieやconfigparser, httplib

Page 40: BPStudy#54 そろそろPython3

compatモジュール

str, bytes の差異を吸収するユーティリティ

binary_typestext_types

text_bytes_

などをpython2用とpython3用にそれぞれていぎ

Page 41: BPStudy#54 そろそろPython3

文法の非互換に立ち向かう

2大文法エラー

●例外ブロック●ユニコードリテラル

Page 42: BPStudy#54 そろそろPython3

例外ブロック

old except Exception, e:

new 2.6から使えるexcept Exception as e:

Page 43: BPStudy#54 そろそろPython3

ユニコードリテラル

ユニコード文字列リテラルu"日本語"

compatユーティリティでラップする

text_("日本語")

Page 44: BPStudy#54 そろそろPython3

importエラーをなおす

よくあるimportエラー

●相対import●名前が変わった標準ライブラリ

Page 45: BPStudy#54 そろそろPython3

名前が変わったものなどcompat内で解決import先をcompat経由に変更する

Page 46: BPStudy#54 そろそろPython3

相対import

2系では相対import優先。3系では絶対import優先

import amodule

どちらでも相対import優先

from . import amodule

Page 47: BPStudy#54 そろそろPython3

コード、テストを修正する

ここまでくればいつもどおり!いきなり80%のテストが失敗しますが、心折れずに進めましょう。

Page 48: BPStudy#54 そろそろPython3

Python3対応の勘所(1) iterator

組み込み関数がのきなみiteratorに対応zipもfilterもrangeもlistではなくiteratorを返す

それぞれのiterator版だった、izipやifilter, xrangeなどは消滅

Page 49: BPStudy#54 そろそろPython3

で す が 

Page 50: BPStudy#54 そろそろPython3

len(zip((1,2,3), ('a', 'b', 'c')))

3系だとNG!やりたければlistコンストラクタを明示的に呼び出す

len(list(zip((1,2,3), ('a', 'b', 'c'))))

Page 51: BPStudy#54 そろそろPython3

Python3対応の勘所(2) strとbytes

Python3の文字列はユニコードPython2のバイト配列に対応するものはbytesに変更

Python2でなんとなく使ってたバイト文字列とユニコード文字列の違いを意識する場面が増えた

Page 52: BPStudy#54 そろそろPython3

多くの関数、ライブラリがstr前提に

json.loads strしか受け取れないjson.load strを返すファイルライクオブジェクトじゃないとだめ

open関数が返すオブジェクトはstrを返すファイルライクオブジェクト

Page 53: BPStudy#54 そろそろPython3

StringIOとBytesIO

ioモジュールに統合

Page 54: BPStudy#54 そろそろPython3

bytesの注意点

bytesとstrは結合できない

NG b'a' + 'a'

2系では自動変換されてました

Page 55: BPStudy#54 そろそろPython3

bytesの注意点

%演算子を使ったフォーマットが使えない

NG b'%d' % 10

Page 56: BPStudy#54 そろそろPython3

bytesの注意点

コンストラクタ

3のbytesbytes(source, encoding, errors)

2のころのstrstr(object)

Page 57: BPStudy#54 そろそろPython3

bytesの注意点

2のころ

>>> str(b'a')'a'

3だと

>>> str(b'a')"b'a'"

Page 58: BPStudy#54 そろそろPython3

要するに

3系のbytesは2系のstrと

互換ではない

Page 59: BPStudy#54 そろそろPython3

Python3対応の勘所(3) strがちゃんとしたiteratorを実装している

__next__や__iter__が実装されiteratorとして正しいインターフェイスとなった。

し か し2系で使われていたバッドノウハウ__iter__ の有無でlistとstrを振り分けるは、もう使えません。ちゃんとisinstanceを使いましょう。

Page 60: BPStudy#54 そろそろPython3

Python3対応の勘所(4)basestringがなくなった

2系のstrとunicode共通のスーパークラスだったbasestringがなくなりました。

isisntance(s, basestring) はできません

バージョンチェックで str_typesを作って対応2系のstr_typesstr_types = (str,unicode)3系のstr_typesstr_types = (str,)

Page 61: BPStudy#54 そろそろPython3

Python3対応の勘所(5)相対importの罠

2系の場合と3系の場合で優先順位が違う

2系 相対importが優先3系 絶対importが優先

a/__init__.pya/a.py

3系で a/__init__.py で import aをやると自分をimportする!この場合は、from a import a か from . import a としましょう。

Page 62: BPStudy#54 そろそろPython3

相対importの罠にはまったライブラリ

iso8601

最終リリース(2007年)からissuesも放置状態...作者への連絡方法も分からず、py3k対応のスタンスも確認できない

MITライセンスだったので、ソース取り込みで対応

Page 63: BPStudy#54 そろそろPython3

例外文法

とくにキャッチする部分

2系のみexcept Exception, e:

2.6以降と3系except Exception as e:

Page 64: BPStudy#54 そろそろPython3

どのバージョンでも動く? 2.4や2.5でも3.2でも動く。except Exception: e = sys.exc_info()[1]

多分一番ポータブル!でも、なんかいや

Page 65: BPStudy#54 そろそろPython3

まとめ

鶏が先か卵が先か。せっかくなので提供する側になりたいです。

テストがすでにそろってる状態であれば、Python3対応は機械的に進められます。テスト大事。

当然Python3での変更を調べることになります。Python3を仕事で使う前にオープンソースプロジェクトに貢献しつつ、はまりどころを事前に知ることができます。しかも、世界レベルの開発者からのアドバイスまでもらえます。