Python

2008年07月10日

setuptoolsでモジュールのバージョンを指定する方法

はてなブックマークに登録

ほとんどのPythonistaがお世話になっているeasy_install (setuptools) ですが、よく、

$ easy_install "SQLAlchemy == 0.4.6"

のようにバージョン指定してモジュールをインストールすることがあります。

バージョン指定には不等号も使うことができるのですが、例えば0.4系の新バージョンが出てupgradeする場合に、

$ easy_install -U "SQLAlchemy < 0.5"

として最新版を自動的に探してupgradeしようとすると、0.5beta1がインストールされてしまいました。確かに 0.5betaは0.5よりも前のバージョンだろうけど…あぅあぅ…ということで、setuptoolsがバージョンをどう扱うか 調べてみました。

バージョン番号について

リリース番号
1.2.3 みたいな部分
タグ
1.2.3foobar のうち foobar の部分
プレリリースタグ
タグが辞書順で"final"よりも前だと、プレリリースタグになる。 ただし、rc、pre、preview は文字cと同じ扱い。 プレリリースタグがつくと、タグなしの同じリリース番号が示すバージョンよりも 過去のバージョンになる。 1.2.3pre3 < 1.2.3
ポストリリースタグ
タグが辞書順で"final"よりも後ろだと、ポストリリースタグになる。'-'も使える。 ポストリリースタグがつくと、より新しいバージョンを示す。 1.2.3 < 1.2.3r2 , 1.2.3rc1 < 1.2.3rc1-20080707

バージョン条件の指定の仕方

easy_install や、 setupスクリプトの依存関係記述において、バージョンに関する 複数の条件を、カンマで区切って指定できる。

$ easy_install "SQLAlchemy >= 0.4, < 0.5a"


いままで自分でsetupスクリプト(setup.py)を書くときに、○○以上というバージョン指定しか してなかったのですが、そのパッケージをeasy_installでインストールする人が依存パッケージの 自動インストールで想定したより新しい、しかもα版のパッケージをインストールしてしまったり していたので、これからは○○以上△△未満という形で書いていこうと思います。


@methane
klab_gijutsu2 at 18:38|この記事のURLComments(0)TrackBack(0)
2008年07月01日

Pythonで@deprecatedというデコレータを用意する

はてなブックマークに登録

@deprecatedというデコレータがあれば、

## そろそろ削除したい関数があるとき
@deprecated
def unsupportedfunc():
  nanika

## foo から bar に関数名を変えるとき
def bar():
  nanika
foo = deprecated(bar)
とできて便利です。

このdecoratorの実装例が、Cookbookに載っていました <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/391367> Cookbookのコメント欄にもありますが、stacklevelを設定することで、deprecatedな関数を呼んだのがどこかを調べることができます。
        warnings.warn("Call to deprecated function %s." % func.__name__,
-                      category=DeprecationWarning)
+                      category=DeprecationWarning,
+                      stacklevel=2)

Python 2.5にdeprecated decoratorを入れるかどうかがPython-Devで話題になっていたのですが、今のところ__builtin__にも標準ライブラリにも入ってないようです。(あまり深く追っていません)


@methane
klab_gijutsu2 at 14:15|この記事のURLComments(0)TrackBack(0)
2008年06月19日

Linux上のPythonのzipfileを使って、permissionを気にしないでzipファイルを作成する

はてなブックマークに登録

Pythonの標準ライブラリには、zipファイルを扱うためのzipfileモジュールがあります。以下のようにして、簡単にzipファイルを作成することが出来ます。
In [1]: from zipfile import ZipFile

In [2]: z = ZipFile('foo.zip', 'w')

In [3]: z.writestr('foo.txt', 'foo\nbar\nbaz')

In [4]: z.close()
しかし、これをunzipすると、permissionが全部0になってしまいます。
In [5]: !unzip foo.zip
Archive:  foo.zip
 extracting: foo.txt                

In [6]: !ls -l
total 8
---------- 1 naoki naoki  11 Jun 19 18:21 foo.txt
-rw-r--r-- 1 naoki naoki 123 Jun 19 18:21 foo.zip
いくつかのフラグを操作すれば任意のパーミッションを設定できるはずなのですが、特に設定したいパーミッションが無い場合は、zipファイルが Windows上で作成されたと偽装することで、unzip時にデフォルトのパーミッションが設定されるようにすることが出来ます。
In [7]: z = ZipFile('bar.zip', 'w')

In [8]: z.writestr('bar.txt', 'foo\nbar\nbaz')

In [9]: for zi in z.filelist:                    
   ...:     zi.create_system = 0   # Linuxだとデフォルトで3が設定されている。
   ...:    

In [10]: z.close()

In [11]: !unzip bar.zip
Archive:  bar.zip
 extracting: bar.txt                

In [12]: !ls -l bar.txt
-rw-r--r-- 1 naoki naoki 11 Jun 19 18:23 bar.txt

@methane
klab_gijutsu2 at 18:35|この記事のURLComments(0)TrackBack(0)
2008年04月01日

WindowsでPython Scriptの起動用exeを用意する

はてなブックマークに登録

MercurialやTaskCoachといったPython製ツールをWindows上で使うとき、py2exeでビルドして配布されているパッケージを利用するとインストールはとても簡単なのですが、アプリ毎にpython25.dllといったdllやPythonモジュール群が大量にインストールされるのが欠点です。

普段からPythonを利用している人にとっては、distutilsを利用したインストール(easy_installやsetup.py install)の方がメモリ効率の面でも起動速度等の面でも有利な筈です。僕はできるだけこちらの方法を使っていて、起動速度・最小化解除のレスポンス共に向上することが体感できます。(プラシーボ効果かもしれませんが)

ただし、Mercurialをeasy_installしたところ、hg.exeが生成されず、Pythonをインストールしたディレクトリの下のScriptsディレクトリに"#!"(shebang)を利用した起動スクリプトであるhgが生成されただけでした。また、TaskCoachも、taskcoach.pyとtaskcoach.pywがあるだけでした。もちろんこのままでも利用はできます。でも、例えばNetBeansでMercurialを利用しようとするとhg.exeの場所を指定しないといけなかったりするので、やはり起動用の実行ファイルがあったほうが便利です。

そこで、easy_install.exeのような起動用実行ファイルを作るにはどうしたら良いのだろうと、distutilsを拡張するモジュールであるsetuptoolsを調べてみました。これを使えば、非常に簡単にPythonスクリプトをexeから起動できるようになります。

起動用実行ファイルは、コマンドプロンプトを開かないWindowアプリ用とコマンドプロンプトを開くコマンドライン用の2種類があり、以下のような動作をします。

  1. 起動対象スクリプトのパスを、GetModuleFileName()の結果から求めます。
    パスから拡張子(.exe)を取り除いた後、Windowアプリ用なら"-script.pyw"を、コマンドライン用なら"-script.py"をつけたものが、起動対象のスクリプトになります。
  2. 起動対象スクリプトを開き、先頭に"#!"があるかどうかを調べます。"#!"があれば、続きを起動するPythonインタプリタとして扱い、"#!"が無ければ"python.exe"をPythonインタプリタとします。
  3. 引数を渡してsapwn()します。

setuptoolsをインストールしてあれば、この起動用実行ファイルが、Lib/site-packages/setuptools/の中にgui.exeとcli.exeの名前で入っています。名前から判るように、gui.exeがWindowアプリ用、cli.exeがコマンドラインアプリ用です。例えば、次のようにすれば、hg.exeとtaskcoach.exeを用意することができます。

C:\python\Scripts>copy hg hg-script.py
C:\python\Scripts>copy ..\Lib\site-packages\setuptools\cli.exe hg.exe
C:\python\Scripts>copy taskcoach.pyw taskcoach-script.pyw
C:\python\Scripts>vim taskcoach-script.pyw (先頭に #!C:\python\pythonw.exe を追加)
C:\python\Scripts>copy ..\Lib\site-packages\setuptools\gui.exe taskcoach.exe

同じ方法で、自作のスクリプトでもお手軽にexe化できます。これでWindowsユーザーのPythonライフが少し楽しくなればと思います。


@methane
klab_gijutsu2 at 17:12|この記事のURLComments(3)TrackBack(0)
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント