Expected behavior and actual behavior.
I expected to compile a script using rasterio
into an executable using pyinstaller
. The script runs fine from within my python environment. However I am not able to freeze it into an executable using PyInstaller
.
Steps to reproduce the problem.
I have a script called workflow_3.py
which contains the following:
import rasterio
That's it. I tried to compile then run this using pyinstaller as follows:
(wps_env36) D:\11202750-002_RA2CE\Basis>pyinstaller workflow_3.py
(wps_env36) D:\11202750-002_RA2CE\Basis>dist\workflow_3\workflow_3.exe
The compilation seems to run to completion, however when I run the executable I get the following error:
(wps_env36) D:\11202750-002_RA2CE\Basis>dist\workflow_3\workflow_3.exe
Traceback (most recent call last):
File "workflow_3.py", line 1, in <module>
import rasterio
File "c:\programdata\anaconda2\envs\wps_env36\lib\site-packages\PyInstaller\loader\pyimod03_i
mporters.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\rasterio\__init__.py", line 23, in <module>
File "rasterio\_base.pyx", line 1, in init rasterio._base
ModuleNotFoundError: No module named 'rasterio._shim'
[17536] Failed to execute script workflow_3
Attempt to fix the problem
I modified the spec file by explicitly adding 'rasterio._shim'
to the list contained by the hidden-imports
variable. Then I ran pyinstaller workflow_3.spec
. This caused other ModuleNotFoundError
for modules such as control
.py, crs.py
and vrt.py
.
Adding these to hidden-imports
successfully eliminates the ModuleNotFoundError
for that particular package but it still looks for other packages, all of which are contained in C:\ProgramData\Anaconda2\envs\wps_env36\Lib\site-packages\rasterio
. There are about 40 modules in this directory. It seems excessive to add every single filename in this directory to the hidden-imports
variable. In fact I don't even know if it would work.
Therefore, I also tried adding that whole directory into my pathex
variable so that it can extend the PYTHONPATH
with it. However this causes another problem:
File "c:\programdata\anaconda2\envs\wps_env36\lib\traceback.py", line 5, in <module>
File "c:\programdata\anaconda2\envs\wps_env36\lib\linecache.py", line 11, in <module>
File "c:\programdata\anaconda2\envs\wps_env36\lib\tokenize.py", line 27, in <module>
ImportError: cannot import name 'open'
pre-safe-import-module hook failed, needs fixing.
Operating system
Windows 7
Rasterio version and provenance
The rasterio version is 1.0.8, from conda-forge The python version is 3.6.6
I have two versions of pyinstaller
pyinstaller 3.4 py36h7602738_0 conda-forge
PyInstaller 3.5.dev0+b13e6b30b <pip>
The second one is the development version, which I had to get because of this problem
Question
How do I use PyInstaller
to freeze an application which uses rasterio
?
The current solution that I came up with is to force feed
hidden-imports
variable all modules contained withinC:\ProgramData\Anaconda2\envs\wps_env36\Lib\sitepackages\rasterio
using theglob
package. In my spec file I added some python code to do this:Unfortunately this does not explain why
pyinstaller
was not able to see those modules in the first place. However it does momentarily solve this problem, and the code compiles fine.