Что-то не так с тем, как я связываю rasterio в исполняемый файл

Ожидаемое поведение и фактическое поведение.

Я ожидал скомпилировать скрипт с использованием rasterio в исполняемый файл с использованием pyinstaller. Сценарий отлично работает в моей среде Python. Однако я не могу заморозить его в исполняемый файл, используя PyInstaller.

Действия по воспроизведению проблемы.

У меня есть скрипт под названием workflow_3.py, который содержит следующее:

import rasterio

Вот и все. Я попытался скомпилировать, а затем запустить это с помощью pyinstaller следующим образом:

(wps_env36) D:\11202750-002_RA2CE\Basis>pyinstaller workflow_3.py (wps_env36) D:\11202750-002_RA2CE\Basis>dist\workflow_3\workflow_3.exe

Компиляция, похоже, завершена, однако, когда я запускаю исполняемый файл, я получаю следующую ошибку:

(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

Попытка решить проблему

Я изменил файл спецификации, явно добавив 'rasterio._shim' в список, содержащийся в переменной hidden-imports. Затем я побежал pyinstaller workflow_3.spec . Это вызвало другие ModuleNotFoundError для таких модулей, как control.py, crs.py и vrt.py.

Добавление их в hidden-imports успешно удаляет ModuleNotFoundError для этого конкретного пакета, но по-прежнему ищет другие пакеты, все из которых содержатся в C:\ProgramData\Anaconda2\envs\wps_env36\Lib\site-packages\rasterio. В этом каталоге около 40 модулей. Кажется излишним добавлять каждое имя файла в этом каталоге к переменной hidden-imports. На самом деле я даже не знаю, будет ли это работать.

Поэтому я также попытался добавить весь этот каталог в свою переменную pathex, чтобы он мог расширить с его помощью PYTHONPATH. Однако это вызывает другую проблему:

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.

Операционная система

Windows 7

Версия Rasterio и происхождение

Версия rasterio — 1.0.8, от conda-forge Версия python — 3.6.6

У меня две версии pyinstaller

pyinstaller               3.4              py36h7602738_0    conda-forge
PyInstaller               3.5.dev0+b13e6b30b           <pip>

Вторая — версия для разработки, которую мне пришлось получить из-за этой проблемы.

Вопрос

Как использовать PyInstaller, чтобы заморозить приложение, использующее rasterio?


person user32882    schedule 05.11.2018    source источник
comment
Может ли кто-нибудь помочь? Какую еще информацию я могу предоставить, чтобы облегчить ответ на этот вопрос?   -  person user32882    schedule 05.11.2018
comment
Я думаю, вам просто нужно подождать, пока кто-нибудь не узнает ответ. Люди скажут вам, если пропустят какую-то информацию.   -  person YesThatIsMyName    schedule 06.11.2018
comment
Иногда люди не будут, если вы не спросите. Впрочем, проверить никогда не помешает...   -  person user32882    schedule 06.11.2018
comment
У меня очень похожая проблема, в настоящее время пробую ваше решение с небольшой удачей. Опубликую, если найду другое решение.   -  person morrismc    schedule 07.01.2020


Ответы (1)


Текущее решение, которое я придумал, состоит в том, чтобы принудительно передать переменную hidden-imports всем модулям, содержащимся в C:\ProgramData\Anaconda2\envs\wps_env36\Lib\sitepackages\rasterio, с помощью пакета glob. В моем файле спецификаций я добавил код Python для этого:

# -*- mode: python -*-

block_cipher = None
import glob, os
rasterio_imports_paths = glob.glob(r'C:\ProgramData\Anaconda2\envs\wps_env36\Lib\site-packages\rasterio\*.py')
rasterio_imports = ['rasterio._shim']

for item in rasterio_imports_paths:
    current_module_filename = os.path.split(item)[-1]
    current_module_filename = 'rasterio.'+current_module_filename.replace('.py', '')
    rasterio_imports.append(current_module_filename)

a = Analysis(['workflow_3.py'],
             pathex=['D:\\11202750-002_RA2CE\\Basis'],
             binaries=[],
             datas=[],
             hiddenimports=rasterio_imports,
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='workflow_3',
          debug=True,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='workflow_3')

К сожалению, это не объясняет, почему pyinstaller вообще не смог увидеть эти модули. Однако это на мгновение решает эту проблему, и код компилируется нормально.

person user32882    schedule 06.11.2018
comment
Вы установили pywin32 в дополнение к pyinstaller? Он доступен в виде пакета pypi pypi.org/project/pypiwin32 Согласно документам pyinstaller, это должно автоматически устанавливаться как зависимость, но в прошлом у меня были проблемы с этим, и ручная установка решила их - person lhk; 06.11.2018
comment
Что заставляет вас думать, что это связано с pywin32? - person user32882; 06.11.2018
comment
Просто предположение. И сообщение об ошибке, которое вы получили: ImportError: не удалось импортировать имя 'open' pre-safe-import-module hook, нуждается в исправлении. Очень похоже на мину - person lhk; 06.11.2018