YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

PyPy Advent Calendar 2011 6日目 Frequently Asked Questions

はじめに

こんにちは、Python界の情弱です。前日の id:Ehren からバトンを受け取りました。Python界の情弱なので、PyPyは情報は追っかけてましたが、ぜーんぜん使ったことありませんでした。とりあえず何かきっかけをってことでPyPy Advent Calendarに参加してみてとりあえずドキュメントを読もうかなと。
で、何はともあれ「PyPyでなんなんすか?」ってことでFAQを翻訳することにしました。この翻訳は日本語訳本家にマージ予定。

一般的な話

PyPyとは何か

PyPyは次の両方を指します。

PyPyは作りやすさ、柔軟性、維持が容易さ、言語実装における速度のトレードオフに対する新しい解を見つけようとしています。
細かいことは「目標とアーキテクチャ」のドキュメントを参照してください。

PyPyはCPythonの代わりになるの?

ほとんどできてます!

どんなプロジェクトでも十中八九つまずくところは拡張モジュールのサポートです。PyPyは絶えず成長している多くの拡張モジュールをサポートしていますが、これまではたいてい標準ライブラリ内のものだけをサポートしてきました。

言語の機能(組み込み型と組み込み関数を含む)は全くもって完全でテストも十分に行われていますので、もしあなたのプロジェクトが多くの拡張モジュールを使っていなければ、PyPyで上手く動作させるのにいい機会です。

既知のCPythonとの違いを「CPythonとの違い」に挙げました。

CPython拡張モジュールはPyPyで動くの?

CPython拡張モジュールの実験的サポートは行なっていますので、ちょっとコードを変えるだけで動きます。この機能はPyPy 1.4から一部サポートしていますが、まだβ版です。PyPyのCPython拡張モジュールは、参照カウントをエミュレートしなければいけないのでしばしばCPythonよりもずっと遅いです。CPython拡張をpure python版に置き換えるとずっと速くなることもよくあります。
ctypesベースの拡張はすべてサポートしています。
PyPyでどの3rd party拡張が動くか(あるいは動かないか)については互換性Wikiを参考にしてください。

PyPyはどのプラットフォームで動くか?

PyPyは通常大規模にはLinuxMac OS Xでテストされて、Windowsでもたいていは動作します。(しかし前者2つよりはテストは小規模です)PyPyはブートストラップするために対象のプラットフォームでCPythonが動作している必要があり、その理由でクロスコンパイルはまだ実際には動作していません。しばらくはCPython 2.5-2.7がトランスレーション処理に必要となります。PyPyのJITx86またはx86_64のCPUを必要とします。

PyPyはPythonのどのバージョン(2.x)を実装していますか?

PyPyは今のところPython 2.7と完全互換を目指しています。これはPython 2.7の標準ライブラリも含むという意味です。そして2.7の機能(たとえばセット内包)もサポートします。

PyPyにはGILがあるんですか?なぜですか?

はい、PyPyにはGILがあります。GILを取り除くのはとても厳しいです。最初の課題はガベージコレクションがリエントリー性ではないということです。

PyPyの拡張モジュールはどうやって書けばいいですか?

「[http://doc.pypy.org/en/latest/extending.html:title=PyPyの拡張モジュールを書く」を参照して下さい。

PyPyはどれくらい速いですか?

これはコードに依ります。pure Pythonのアルゴリズムコードならとても速いです。典型的なPythonプログラムであれば、CPython 2.6の3倍速いです。我々のベンチマークサイトJITドキュメントも興味があればどうぞ。

PyPyのトランスレーションツールチェーンをPython以外の言語にも使えますか?

はい、PyPyインタープリターを翻訳するツールスイートはかなり汎用的で、Pythonだけでなく、どんな言語のインタープリタの最適化版を作るのにも使えます。もちろん、これらのインタープリタはPyPyがPythonにもたらしたものと同じ機能を使うことができます。具体的には様々な言語の翻訳機能、スタックレス、ガベージコレクション、任意長整数型などの様々実装などです。
現在、JavaScriptインタープリタの暫定版を作っています。(Leonardo Santagadaが夏のPyPyプロジェクトでやっていました)Prologインタープリタの暫定版(Carl Friedrich Bolzの学士論文)やSmallTalkインタープリタの暫定版(スプリント中に作られました)もあります。PyPyのbitbucketページにはSchemeとIoの実装もあります。どちらもいまはまだ完成していません。

開発

PyPyの開発にはどのようにして関われますか?スプリントに参加できますか?

もちろんスプリントに参加できますよ!私たちはいつでも新人を歓迎していますし、できるだけプロジェクトに参加しやすくなるようなお手伝いもしています。チュートリアルや経験があるPyPy開発者とのペアプロも実施します。スプリントに初めて参加する場合にはPythonの経験とPyPyのドキュメントを読んできて下さい。
スプリントに参加するのはPyPy開発をする上で最も良い方法です。もし行き詰ってしまったりアドバイスが必要なら、私達に連絡して下さい。IRCは最も迅速にフィードバックを得られる方法です。(少なくとも似宙はそうです。ほとんどのPyPy開発者はヨーロッパにいます)そしてメーリングリストは長い議論に向いています。

OSError: ...reloc後のセグメントprotを復元できません...ボスケテ

Linux上ではSELinuxが有効になっていると、“OSError: externmod.so: cannot restore segment prot after reloc: Permission denied.”に続くエラーが出てくると思います。これはconfigure中のCコンパイラの乱用によるもので、次のコマンドをroot権限で実行すれば無効に出来ます:

# setenforce 0

これでSELinuxの保護を無効にして、PyPyがきちんとconfigureされます。必要なときは再度有効にすることを忘れずに!

PyPyトランスレーションツールチェーン

PyPyは普通のPythonプログラムをCにコンパイルできますか?

いいえ、PyPyはPythonのコンパイラではありません。
Pythonでは、静的解析をすることでプログラムが扱う型を証明することはほぼ不可能です。Pythonをよく知っていれば当たり前ですが、もし懐疑的なら[BRETT]を参考にしてください。
もし速いPythonプログラムが欲しいなら、代わりに我々のJITを使って下さい!

[BRETT] Brett Cannon, Localized Type Inference of Atomic Types in Python, http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.3231

RPythonとはなんですか?

RPythonとはPythonの制限されたサブセットです。これはPyPyツールチェーンの中で動的言語インタープリタを実装するのに使われます。制限のお陰でRPythonプログラムの型推論が出来ます。(またそれによって究極的には他の言語へトランスレートできます)
"RPythonになる"という特性は関数やモジュール1つではなく常にプログラム全てに適用されます。(トランスレーションツールチェーンはプログラム全体の解析を行います)トランスレーションツールチェーンは全ての呼び出しを再帰的に追って、何がどのプログラムに所属していて、何がそうでないかを見つけ出します。
RPythonプログラムは任意の方法での混合型の使用を制限します。RPythonは1つの変数に対して2つの異なる型を束縛することを許可しません。この観点から(そしてほかの観点からも)Javaに似た感じがします。RPythonで許可されていない他の特徴としては、__init__, __del__ 以外のスペシャルメソッド(__xxx__)の利用です。リフレクションも使えません。(__dict__など)
RPythonからはほとんどの標準ライブラリも使えません。例外はネイティブサポートがあるos, math, timeの一部の関数です。
RPythonの制限についてもっと知りたい方はRPythonの説明を読んで下さい。

RPythonはZopeのRestricted Pythonと関係ありますか?

いいえ、ZopeのRestricted PythonはCPythonのサンドボックス実行環境を提供しようとしているものです。PyPyのRPythonは動的言語インタープリタを実装するための言語です。しかしながらPyPyはロバストなサンドボックスのPythonインタープリタも提供しています。

Docstringにある"NOT_RPYTHON"とはなんですか?

"NOT_RPYTHON"と関数のdocstringに書けば、その関数はRPythonプログラムのトランスレート中に見つけられ、トランスレート処理が止まってエラーとして報告します。それ故、関数を"NOT_RPYTHON"とマークすることでそれらを絶対に解析されないように出来ます。

Python構文木を単純にLispに変換することはできないですか?

必要無いですしナンセンスですし、PyPyのやり方ではありません。このPythonをトランスレートするのはなんらかの型推論なしにはとても難しいです。

a + b

これを次のCommonLispよりも意味があるものにするのは難しいです。

(py:add a b)

そして型推論を可能にするのがRPythonがしていることです。
#'py:addを汎用関数にして、CLOS実装が実用的な速度で動くか確かめてもいいでしょう。(しかし私が思うに矯正ルールはとてつもなく速くしてくれると思います)―mwh

私のプログラムをRPythonに書き換えなければいけないのですか?

いいえ。そして試すことすらすべきではありません。PyPyは常に独自のインタープリタでコードを走らせます。インタープリタはPython 2.7に完全準拠しています。RPythonはPyPy自身とそれ用の拡張モジュールが一部書かれている言語にすぎません。RPythonでコードを書き直す必要がないだけでなく、試してみても速度の改善には繋がらないと思います。

RPythonのツールチェーンにはどんなバックエンドがありますか?

現在のところ、C、CLIJVMのバックエンドがあります。これらすべてPyPyインタープリタ全体をトランスレート可能です。バックエンドについてもっと知りたい方はtranslation documentを見てください。

どのようにPyPyをコンパイルするのですか?

getting startedのガイドを読んで下さい。

どのようにオレオレインタープリタをコンパイルするのですか?

Andrew Brownのチュートリアルを読むことから始めて下さい。

PyPy向けのRPythonモジュールは独立してトランスレートできますか?

いいえ、インタープリタ全体を再ビルドする必要があります。理由は次の2つです:

  • テスト駆動開発をする義務があります。トランスレートする前にさえ、あなたのモジュールをpure Pythonで徹底的にテストしなければなりません。一度トランスレートしたら、直すのはいくつかの型の問題だけになるでしょう。そうでなければそのまま動作します。
  • 次にが最も大事です:まずRPythonでモジュールを書くのに真っ当な理由がありますか?近頃では代替の方法を見るべきで、たとえばCのコードを呼ぶ必要があるならpure Pythonでctypesを使ってみるなどです。他の方法としては(2011年夏の段階では)Cythonバインディングのようなものも開発されています。

このような理由から、RPythonモジュールをインタープリタ全体のトランスレートとは独立してトランスレートできることはさほど重要ではありません。(かなり頑張ればできないことはないですが、それは大仕事です。いまは見込みがないと思ったほうがいいです)

なぜPyPyはトランスレーションの間Mandelbrotのフラクタルを描くんですか?

楽しいからです。

おわりに

翻訳エントリではありましたが、これでPyPyの雰囲気がつかめたらなと思います。僕はなんかRPythonが楽しそうだなと思いました。明日は id:jbking です!よろしくお願いします!