Я пытаюсь выяснить, как загрузить динамический/скрытый импорт с помощью PyInstaller, до сих пор я получил эту простую структуру:
Прежде всего, я получил пакет фреймов, добавленный в мой PYTHONPATH, живущий в d:\Sources\personal\python\framework
Этот пакет используется многими моими проектами python, в частности, он используется с нижепростым проектом, который я хочу упаковать
Main project
├───data <- Pure static data
├───plugins <- Dynamic modules which uses framework modules
├───resources <- Static data+embedded (generated by pyqt), used by plugins
│ ├───css
│ ├───images
| resources.py
| resources.qrc
main.py <- Uses framework modules to load plugins dynamically
Мой файл спецификации выглядит так:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['d:\\sources\\personal\\python\\pyqt\\pyshaders'],
binaries=None,
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
##### include mydir in distribution #######
def extra_datas(mydir):
def rec_glob(p, files):
import os
import glob
for d in glob.glob(p):
if os.path.isfile(d):
files.append(d)
rec_glob("%s/*" % d, files)
files = []
rec_glob("%s/*" % mydir, files)
extra_datas = []
for f in files:
extra_datas.append((f, f, 'DATA'))
return extra_datas
###########################################
a.datas += extra_datas('data')
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='main')
Проблема возникает, когда я пытаюсь добавить скрытый импорт в список Analysis (..., hiddenimports = [],...) hiddenimports, я до сих пор пробовал это:
-
hiddenimports=['d:\\sources\\personal\\python\\pyqt\\plugins']
-
hiddenimports=['d:\\sources\\personal\\python\\pyqt\\plugins\\*']
-
hiddenimports=['plugins']
Также попытался листинг в виде отдельных файлов с абсолютными путями:
hiddenimports=[
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\api.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\config.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_actions.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_dialogs.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_docks.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_post_init.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_toolbar.py'
]
И также попытался загрузить их в виде пакетов модулей (__init__.py
живет в папке плагинов)
hiddenimports=[
'plugins.api',
'plugins.config',
'plugins.plugins_actions',
'plugins.plugins_dialogs',
'plugins.plugins_docks',
'plugins.plugins_post_init',
'plugins.plugins_toolbar'
]
Также попробовал collect_submodules
hiddenimports=collect_submodules('plugins')
Ни одна из этих попыток не работала, и плагин для папки не добавляется должным образом на dist (когда я говорю "правильно", я думаю, что pyinstaller будет анализировать импорт, используемый этими скрытыми плагинами, анализируя рекурсивно их зависимости и копируя *.pyc файлы)... Итак, я хотел бы знать, как я могу добавить правильно "скрытые" модули, которые динамически загружаются в спецификацию pyinstaller.