2012-02-06 18 views
10

pytzを使用するアプリケーションの配布に問題があります。私はPy2Exeを使ってPythonソースから実行ファイルを作成しています。Py2ExeでコンパイルされたPythonアプリケーションでUnknownTimezoneError例外が発生しました

は私がいる問題の簡単な例では、私が持っている: pytz_test.py:

import pytz 

tz_au = pytz.timezone("Australia/Sydney") 
print tz_au 

とsetup.pyで:

from distutils.core import setup 
import py2exe 

setup(console=['pytz_test.py'], options={"py2exe" : { 'packages': ['pytz'], } }) 

を私は、setup.pyを実行します:

python setup.py py2exe 

実行ファイルをコンパイルします。作成したpytz_test.exeを実行している私が取得:

私は、タイムゾーン情報が実行可能にバンドル取得されていないので、それがあると仮定し、私はそれを実現するするかどうかはわかりません。

EDIT: 簡単な解決策はlibrary.zipに、Pythonのsite-packagesディレクトリ内pytzモジュールから、のzoneinfoディレクトリを追加することです。

from distutils.core import setup 
import glob 
import py2exe 

options = { 
    "py2exe" : { 
     "compressed": 1, 
     "optimize": 2, 
     'packages': ['pytz'], 
    } 
} 

setup(console=['pytz_test.py'], options=options) 

import pytz 
import os 
import zipfile 
zipfile_path = os.path.join("dist/" 'library.zip') 
z = zipfile.ZipFile(zipfile_path, 'a') 
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo') 
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__)) 
for absdir, directories, filenames in os.walk(zoneinfo_dir): 
    assert absdir.startswith(disk_basedir), (absdir, disk_basedir) 
    zip_dir = absdir[len(disk_basedir):] 
    for f in filenames: 
     z.write(os.path.join(absdir, f), os.path.join(zip_dir, f)) 

z.close() 
+0

また、setuptoolsの最新バージョンが必要です。特にpkg_resources 'import pkg_resources'は失敗してはなりません。 – sbaechler

+0

正確に 'pkg_resources'が使われていますか?または単にそれをインポートすることによって? – Triztian

答えて

3

:私はsetup.pyが今のように見える修正 http://code.google.com/p/googletransitdatafeed/source/browse/trunk/python/setup.py

は自動的にこれを行うために、私はからそのプロジェクト内の溶液グーグルトランジットデータは、使用フィード続きます単純な解決策は、pytzモジュールのzoneinfoディレクトリをpython site-packagesに追加することですディレクトリ、library.zipに移動します。

from distutils.core import setup 
import glob 
import py2exe 

options = { 
    "py2exe" : { 
     "compressed": 1, 
     "optimize": 2, 
     'packages': ['pytz'], 
    } 
} 

setup(console=['pytz_test.py'], options=options) 

import pytz 
import os 
import zipfile 
zipfile_path = os.path.join("dist/" 'library.zip') 
z = zipfile.ZipFile(zipfile_path, 'a') 
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo') 
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__)) 
for absdir, directories, filenames in os.walk(zoneinfo_dir): 
    assert absdir.startswith(disk_basedir), (absdir, disk_basedir) 
    zip_dir = absdir[len(disk_basedir):] 
    for f in filenames: 
     z.write(os.path.join(absdir, f), os.path.join(zip_dir, f)) 

z.close() 

(:私はsetup.pyが今のように見える修正

は自動的にこれを行うために、私はからプロジェクトグーグルトランジットデータは、使用フィードソリューションを追いました返信者:asker)

2

zoneinfoを手作業で(Jason Sの記述どおりに)圧縮すると、実際にビルドに役立ちました私のコンピュータのいずれかのパッケージ しかし、別のコンピュータにパッケージをビルドしたときにエラーが戻ってきました! 理由を見つけるのはしばらく時間がかかりました。

提案されたソリューションは、新しいpytzバージョン(少なくとも2014.7)では機能しません! なぜpytzがzoneinfoファイルの形式をpycからいくつかのバイナリ形式に変更したことが判明しました。私にとっては、Pythonの組み込みzipimportメカニズムがバイナリファイルの読み込みには働かないので、この変更により、pytzをzipにパックするオプションを "壊した"ように見えます。 実は、この問題はpytzで固定されなければならないが、今のところ、私は別の解決策が見つかりました:

  • ちょうどあなたのメーンのパスを追加し、あなたのプログラム内で直接あなたのdistディレクトリ
  • に全体pytzディレクトリをコピーします

実際にPythonの検索パスにexectutable、これは交換してくださいあなたのsetup.py内であることを意味しpytz-ビュン

import pytz, os, shutil 
srcDir = os.path.dirname(pytz.__file__) 
dstDir = os.path.join('dist', 'pytz') 
shutil.copytree(srcDir, dstDir, ignore = shutil.ignore_patterns('*.py')) 

と-option「パッケージ」からpytzを移動するには、「除外」:あなたのプログラムのメインエントリで

options = { 
    "py2exe" : { 
     "compressed": 1, 
     "optimize": 2, 
     "packages": [], 
     "excludes": ['pytz'] 
    } 
} 

(必ずそれがインポートpytz前に実行されていることを確認するために)、あなたは何かを追加する必要がありますlike:

import os, sys 
basePath = os.path.dirname(os.path.abspath(sys.argv[0])) 
sys.path.insert(0, basePath) 
+0

これは私のために働いています(pytz 2014.10)が、shutil.copytree()からすべての無視を取り除かなければなりませんでした。 – Geotob

+0

はい!出来た!しかし、最も奇妙なことは、py2exeを使った私のpytzが動作していたことです。それから、pytzとはまったく無関係な私のプログラムのいくつかを修正し、突然それは動作を停止し、正確にUnkownTimeZoneError – wordsforthewise

+0

の言葉を与えました!それも私の問題でした。そして、(少なくとも私にとっては)py2exeが何をしているのか、それがどのように収集するのかは必ずしも明らかではないので、py2exeの収集段階で何がうまくいかなかったのかを見つけるためにpytzにデバッグプリントをハックする必要があった。 :-) – Zappotek

関連する問題