osmnx類をimportしたコードをpyinstallerでexe化しようとしたら発生したエラーとその対処法まとめ
はじめましてしほみです。
仕事でosmnxをつかったPythonコードを書いてpyinstallerでexeファイル化しようとしたのですが、思いのほかエラーが何件か続いたので記事にまとめてみました。
OSはmacOS、以下はパッケージのバージョンです。
// packages
networkx==2.4
notebook==6.0.3
numpy==1.19.0
osmnx==0.14.1
pandas==1.0.5
PyInstaller==3.6
urllib3==1.25.8
まずこれが動かしたいコードです。(簡略化してます)
import numpy as np
import matplotlib.pyplot as plt
import sys
import pandas as pd
import osmnx as ox
import networkx as nx
import itertools
print('hello world')
ただライブラリをインポートしてるだけですね。
pyinstallerでexe化してみましょう
(ここから長い戦いが始まるとは誰も予想してなかった・・)
pyinstaller test.py --onefile
pyi_rth__tkinter / tk / tcl エラー
エラー文
Traceback (most recent call last):
File "site-packages/PyInstaller/loader/rthooks/pyi_rth__tkinter.py", line 30, in <module>
FileNotFoundError: Tcl data directory "/var/folders/0k/__dir/T/_MEIaXD01I/tcl" not found.
[33999] Failed to execute script pyi_rth__tkinter
logout
早速エラーが出てきました。
tclがうまくインポートされてないのでマニュアル的にバイナリを読み込むよう.specファイルを修正しましょう
// test.spec
a = Analysis(
//ADD
binaries=[
('/System/Library/Frameworks/Tcl.framework/Tcl', 'tcl'),
('/System/Library/Frameworks/Tk.framework/Tk', 'tk')
],
)
もう一回変換します。(ここから先はずっと .specファイルでビルドしていきます)
pyinstaller test.spec
datadir エラー
// エラー文
File "site-packages/pyproj/__init__.py", line 51, in <module>
File "pyproj/_datadir.pyx", line 6, in init pyproj._datadir
ModuleNotFoundError: No module named 'pyproj.datadir'
[35099] Failed to execute script test
logout
from pyproj import _datadir, datadir
を追加します。
// test.py
import numpy as np
import matplotlib.pyplot as plt
import sys
import pandas as pd
import osmnx as ox
import networkx as nx
import itertools
//ADD
from pyproj import _datadir, datadir
libpng16.16.dylib エラー
この調子でどんどん直していきます
// エラー文
File "site-packages/fiona/__init__.py", line 84, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "site-packages/fiona/collection.py", line 9, in <module>
ImportError: dlopen(/var/folders/0k/__dir/T/__dir/fiona/ogrext.cpython-38-darwin.so, 2): Library not loaded: @loader_path/libpng16.16.dylib
Referenced from: /private/var/folders/0k/__dir/T/__dir/libgdal.20.dylib
Reason: Incompatible library version: libgdal.20.dylib requires version 52.0.0 or later, but libpng16.16.dylib provides version 38.0.0
[36001] Failed to execute script test
logout
どうやらライブラリのバージョンがリンクできてないっぽいですね
brew update && brew upgrade
しても解消できなかった場合は手動でやってあげます。
https://qiita.com/omuram/items/7be71191e3d1b41c8835
を参考にライブラリの場所を確認し、sudo install_name_tool -change "ライブラリの名前" "リンクしたいライブラリの場所" エラー文にでてきた.soファイル
でリンクしなおします
sudo install_name_tool -change "@loader_path/libpng16.16.dylib" "/opt/X11/lib/libpng16.16.dylib" /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/fiona/ogrext.cpython-38-darwin.so
バージョンダブり防止に下の行を a = Analysis()の後に追加します
// test.spec
//ADD
a.binaries = a.binaries - TOC([('libpng16.16.dylib',None,None)])
この方法があってるかどうかは微妙ですが
fiona._shim エラー
pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "site-packages/fiona/collection.py", line 9, in <module>
File "fiona/ogrext.pyx", line 1, in init fiona.ogrext
ModuleNotFoundError: No module named 'fiona._shim'
[36952] Failed to execute script test
logout
from fiona import _shim, schema
を追加して半ば無理矢理モジュールを入れます。
// test.py
import numpy as np
import matplotlib.pyplot as plt
import sys
import pandas as pd
//ADD
from fiona import _shim, schema
import osmnx as ox
import networkx as nx
import itertools
from pyproj import _datadir, datadir
datasets エラー
エラー文を保存してませんでしたが、geopandasのdatasetsは .specファイルでマニュアル的にビルドできないとのことなので site-packages/geopandas/__init__.py", line 13
のgeopandas.datasets
をインポートするところをコメントアウトします
# commentout
# import geopandas.datasets # noqa
_cnames エラー
エラー文
packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "site-packages/branca/__init__.py", line 7, in <module>
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "site-packages/branca/colormap.py", line 25, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/0k/__dir/T/__dir/branca/_cnames.json'
[37930] Failed to execute script test
logout
site-packages\branca\element.py
を以下に変更します。
\branca\element.py
# commment out
# ENV = Environment(loader=PackageLoader('folium', 'templates'))
import os, sys
from jinja2 import FileSystemLoader
if getattr(sys, 'frozen', False):
templatedir = sys._MEIPASS
else:
templatedir = os.path.dirname(os.path.abspath(__file__))
ENV = Environment(loader=FileSystemLoader(templatedir + '/templates'))
a = Analysis()
に以下を追加します。
//test.spec
a = Analysis(
datas=[
//追加
("/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/branca/*.json","branca"),
("/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/branca/templates","templates"),
],
)
ついに
hello world
logout
できました〜
長い道のりでした。 地理情報系のライブラリ/geopandas/osmnx/fionaを使おうとすると起きるようです。 バージョン問題には頭かかえますね、ではでは
引用
http://eeko-amaryllis.hatenablog.com/entry/2016/07/28/181303
https://stackoverflow.com/questions/56804095/pyinstaller-stopiteration-error-when-i-import-geopandas