Comment ajouter des modules Python dynamiques aux spécifications de PyInstaller?
j'essaie de comprendre comment charger les importations dynamiques/cachées avec PyInstaller, jusqu'à présent j'ai eu cette structure simple:
tout d'abord, j'ai un paquet framework ajouté dans mon PYTHONPATH vivant dans d:Sourcespersonalpythonframework
ce paquet est utilisé par beaucoup de mes projets python, en particulier, il est utilisé avec le projet simple ci-dessous que je veux empaqueter
Main project
├───data <- Pure static data
├───plugins <- Dynamic modules which uses framework's modules
├───resources <- Static data+embedded (generated by pyqt), used by plugins
│ ├───css
│ ├───images
| resources.py
| resources.qrc
main.py <- Uses framework's modules to load plugins dynamically
Mon fichier spec ressemble à ceci:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['d:sourcespersonalpythonpyqtpyshaders'],
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')
Le problème c'est quand j'essaie d'ajouter importations cachées à L'analyse(... , hiddenimports= [],...)'s hiddenimports liste, j'ai essayé jusqu'à présent ceci:
hiddenimports=['d:sourcespersonalpythonpyqtplugins']
hiddenimports=['d:sourcespersonalpythonpyqtplugins*']
hiddenimports=['plugins']
a également essayé de lister en tant que fichiers individuels avec des chemins absolus:
hiddenimports=[
'd:sourcespersonalpythonpyqtpyshaderspluginsapi.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsconfig.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsplugins_actions.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsplugins_dialogs.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsplugins_docks.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsplugins_post_init.py',
'd:sourcespersonalpythonpyqtpyshaderspluginsplugins_toolbar.py'
]
et aussi essayé de les charger comme des paquets de modules (__init__.py
vit dans le dossier plugins)
hiddenimports=[
'plugins.api',
'plugins.config',
'plugins.plugins_actions',
'plugins.plugins_dialogs',
'plugins.plugins_docks',
'plugins.plugins_post_init',
'plugins.plugins_toolbar'
]
a également essayé les collect_submodules
hiddenimports=collect_submodules('plugins')
aucune de ces tentatives ont fonctionné et le plugin de dossier n'est pas ajouté correctement au dist (quand je dis "correctement" je suppose que pyinstaller analysera les importations utilisées par ces plugins cachés en analysant récursivement leurs dépendances et en copiant l' *.pyc fichiers)... Donc, je voudrais savoir comment ajouter correctement des modules "cachés" qui sont chargés dynamiquement sur le pyinstaller.
1 réponses
j'ai eu le même problème d'empaqueter L'application PyQt avec Py2Exe (J'ai aussi eu du mal avec PyInstaller et cx_freeze, mais seul py2exe m'a aidé).
Voici le détail solution. Je les ai ajoutés explicitement comme:
data_files += [('source', glob('source/*.py'),)]
setup(
data_files=data_files,
.... # other options
windows=[
{
"script": "launcher.py",
"icon_resources": [(0, "resources/favicon.ico")]
}
)
alors je les Importe et j'appelle. Espérons que cette approche sera utile.