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.

19
demandé sur BPL 2016-11-10 00:07:32

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.

1
répondu Eugene Lisitsky 2017-05-23 11:45:44