PyInstaller, archivo de especificaciones, ImportError: ningún módulo llamado 'blah'

Resuelto Cmag asked hace 13 años • 3 respuestas

Estoy intentando crear un script en Python a través de PyInstaller . He utilizado los siguientes comandos para configurar, generar un archivo de especificaciones y compilar:

wget pyinstaller.zip, extracted it, python Configure.py, etc, then:

python pyinstaller/Makespec.py --onefile myscript.py
python pyinstaller/Build.py myscript.spec 

Aquí está el archivo de especificaciones que generó:

# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
             pathex=['/home/user/projects/icinga_python/releases/v2.1'])
pyz = PYZ(a.pure)
exe = EXE( pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'myscript'),
          debug=False,
          strip=False,
          upx=True,
          console=1 )

Esto creó un archivo ejecutable en dist/el directorio. Al intentar ejecutar este archivo, aparece lo siguiente:

Traceback (most recent call last):
  File "<string>", line 12, in <module>
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
    raise ImportError, "No module named %s" % fqname
ImportError: No module named mysql

Si moví este ejecutable al directorio del código Python real, dio resultados diferentes:

Traceback (most recent call last):
  File "<string>", line 12, in <module>
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 436, in importHook
    mod = _self_doimport(nm, ctx, fqname)
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 521, in doimport
    exec co in mod.__dict__
  File "CLUSTER/mysql/icingasql.py", line 13, in <module>
    import urllib2
  File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
    raise ImportError, "No module named %s" % fqname
ImportError: No module named urllib2

En los documentos ... de pyinstaller veo que esa --onefilees la opción que necesito/quiero, pero por alguna razón no se está compilando todo.

En realidad, el script no incluye nada sofisticado, solo pequeños módulos rápidos que escribí para declaraciones SQL y análisis de ciertos sitios web.

Cmag avatar Sep 16 '11 02:09 Cmag
Aceptado

Este error puede ocurrir cuando tienes importaciones dinámicas en tu código. En ese caso, pyinstaller no incluye esos paquetes en el archivo exe. En ese caso puedes:

  1. Agregue la importación no utilizada de esos paquetes en su código
  2. Dile a pyinstaller que lo incluya

Una opción de archivo no cambia nada al ejecutar su código. Si crea --onefile exe, todos los archivos creados por pyinstaller se empaquetan en un archivo exe y se descomprimen en la temperatura local cada vez que ejecuta exe.

gkocjan avatar Aug 27 '2014 08:08 gkocjan

El problema es que pyinstaller no verá importaciones de segundo nivel . Entonces, si importa el módulo A , pyinstaller ve esto. Pero no se verá ningún módulo adicional que se importe en A.

No es necesario cambiar nada en sus scripts de Python. Puede agregar directamente las importaciones que faltan al archivo de especificaciones . Simplemente agregue lo siguiente en a = Analysis(...):

hiddenimports=["mysql"],

Este debería ser el resultado:

a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
         pathex=['/home/user/projects/icinga_python/releases/v2.1'], hiddenimports=["mysql"],)

Después de eso, ejecute pyinstaller con el archivo de especificaciones como argumento.

user1251007 avatar Jan 26 '2017 08:01 user1251007

Solo agregaré mis 2 centavos porque encontré el mismo problema hoy, 6 años después: D

Para ventanas:

1) cmd => rightclick => with admin rights
2) Enter in cmd: "pip install pyinstaller"
3) navigate in cmd to the folder of "yourMain.py"
4) Enter in cmd: "pyinstaller --onefile --windowed yourMain.py"

5) If you import other scripts / data in "yourMain.py": 
Manually enter the folder "dist" (gets created - where "yourMain.exe" should be by now), 
and copy your scripts or folder structure there

(e.g. /assets/sounds; /assets/graphics; /scripts; anotherscript.py )

Luego pude ejecutar el exe haciendo doble clic.

Resultó ser bastante fácil. Lo que funcionó para mí fue "--onefile" y agregar mis otros archivos a la carpeta "dist".

El "--windowed" es solo para que la ventana de comando de Python no aparezca cuando inicias el exe.

Cribber avatar Nov 16 '2017 19:11 Cribber