47

I try to compile a Python project under Windows 7 using PyInstaller. The project works fine, there are no issues, however when I try to compile it the result doesn't work. Though I get no warnings during compilation there are many in the warnmain.txt file in the build directory: warnmain.txt

I don't really understand those warnings, for example "no module named numpy.pi" since numpy.pi is no module but a number. I never tried to import numpy.pi. I did import numpy and matplotlib explicitly. In addition I'm using PyQt4. I thought the error might be related to those libraries.

However I was able to compile a simple script which uses numpy succesfully:

import sys
from PyQt4 import QtGui, QtCore
import numpy as np

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.pb = QtGui.QPushButton(str(np.pi), self)

app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())

Successfully here means that the created executable file actually showed the desired output. However there is also a warnmain.txt file created which contains exactly the same 'warnings' as the one before. So I guess the fact that compiling my actual project does not give any success is not (or at least not only) related to those warnings. But what else could be the error then? The only output during compilation are 'INFO's and none of the is a negative statement.

I did not specify an additional hook directory but the hooks where down using the default directory as far as I could read from the compile output, e.g. hook-matplotlib was executed. I could not see any hook for numpy neither could I for my small example script but this one worked. I used the following imports in my files (not all in the same but in different ones):

import numpy as np
import matplotlib.pyplot as ppl
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from PyQt4 import QtGui, QtCore
import json
import sys
import numpy # added this one later
import matplotlib # added this one later

Since PyInstaller does not give any errors/warnings I could not figure out if the problem is related to the libraries or if there is something else to be considered.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • do you get an error when you try to launch your program from the command line? or it just wont start and nothing is printed (does qt redirect stdout to some other place like an output window that gets closed when you crash?)... to further my comment I suspect you have a crash (probably from something that uses json/xml resources or something (not import xxxx) ... and the error message is being printed to some QT window that ends up closing when you crash ... see if qt.App has a redirect=False option or something to keep the stdout – Joran Beasley Sep 08 '14 at 22:02
  • Interestingly, if I were to do something like `import numpy.sinh` I get `ImportError: No module named sinh` and it is only when I do `import numpy.numpy.sinh` that I get `ImportError: No module named numpy.sinh` . Have you checked [PyInstaller finding out what went wrong](http://pythonhosted.org/PyInstaller/#finding-out-what-went-wrong)? to grab errors / verbose imports / debug info? – ThatOneDude Sep 08 '14 at 22:05
  • 2
    @JoranBeasley: I just tried to launch the exe from the cmd without any result, but for compiling I used the flag `-w` (see http://pythonhosted.org/PyInstaller/#options-for-the-executable-output ) which prevents Windows from launching a console for any input/output. If I'd compile without `-w` I cannot get the graphical user interface. However the program works fine when invoking from the interpreter, so I don't think it's an error inside. @ssnobody: I'm aware of that link but it didn't bring any benefits for me. `import numpy.sinh` won't work since `sinh` is no module. – a_guest Sep 08 '14 at 22:23
  • @JoranBeasley: I have to correct myself, it seems to be possible to compile without `-w` and get the GUI. However if I do I get a console where I can see for a very short moment (far to short to actually read) that something's written there, but then the application terminates. The GUI does not appear. I try to get this stdout somehow to a file so I can actually read it. – a_guest Sep 08 '14 at 22:36
  • 2
    @JoranBeasley Thanks man, your suggestion was just the right way! There were actually some libraries missing (which I fixed by just importing them, see my edited question). In case you're not posting an answer I'll just summarize it in a short one. Thanks! – a_guest Sep 08 '14 at 23:16

13 Answers13

34

Had a similar problem with no module named FileDialog. Discovered that with version 3.2, I could use

pyinstaller --hidden-import FileDialog ...

instead of modifying my main script.

See Listing Hidden Imports documentation

Franklin Piat
  • 3,952
  • 3
  • 32
  • 45
HHest
  • 531
  • 1
  • 5
  • 11
  • Wow, this helped, tnx. Though I had to make my main script folder a python package by creating `__init__.py` in the same folder. Otherwise strange things would happen depending on from where the executable was run. Anything from failing relative import to not succeeding importing `serial`. – niCk cAMel Dec 03 '20 at 22:07
  • I've had to use this `--hidden-import` option more than once, to fix ModuleNotFound errors that appeared when trying to run the compiled exe. The missing modules were `_cffi_backend` and `nacl`, when using the `nacl` module. – LarsH Sep 16 '21 at 20:07
27

Pyinstaller won't see second level imports. So if you import module A, pyinstaller sees this. But any additional module that is imported in A will not be seen.

There is no need to change anything in your python scripts. You can directly add the missing imports to the spec file. Just change the following line:

hiddenimports=[],

to

hiddenimports=["Tkinter", "FileDialog"],
user1251007
  • 15,891
  • 14
  • 50
  • 76
21

If you are getting ModuleNotFoundError: No module named ... errors and you:

  • call PyInstaller from a directory other than your main script's directory
  • use relative imports in your script

then your executable can have trouble finding the relative imports.

This can be fixed by:

  • calling PyInstaller from the same directory as your main script

  • OR removing any __init__.py files (empty __init__.py files are not required in Python 3.3+)

  • OR using PyInstaller's paths flag to specify a path to search for imports. E.g. if you are calling PyInstaller from a parent folder to your main script, and your script lives in subfolder, then call PyInstaller as such:

    pyinstaller --paths=subfolder subfolder/script.py.

101
  • 8,514
  • 6
  • 43
  • 69
12

The problem were some runtime dependencies of matplotlib. So the compiling was fine while running the program threw some errors. Because the terminal closed itself immediately I didn't realize that. After redirecting stdout and stderr to a file I could see that I missed the libraries Tkinter and FileDialog. Adding two imports at the top of the main solved this problem.

a_guest
  • 34,165
  • 12
  • 64
  • 118
  • 1
    This is the redirect command I used: myprogram.exe 1> errors.txt 2>&1 --- I got the same result as you... I was missing Tkinter and FileDialog modules as well :) Thanks, much appreciated. – panofish Jul 13 '15 at 14:04
  • So is the problem that PyInstaller doesn't pick up second level imports? Or was this not a project with a setup.py? – Efren Mar 03 '16 at 03:25
  • Yes. If you import a module and this module imports other modules itself then PyInstaller apparently won't realize those second level imports. – a_guest Mar 04 '16 at 09:58
6

I was facing the same problem and the following solution worked for me:

  1. I first removed the virtual environment in which I was working.
  2. Reinstalled all the modules using pip (note: this time I did not create any virtual environment).
  3. Then I called the pyinstaller.
  4. The .exe file created thereafter executed smoothly, without any module import error.
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
HBK8396
  • 481
  • 1
  • 5
  • 9
  • Similar to you, I found pyinstaller could not find modules I installed with [Poetry](https://python-poetry.org/). I could, however, use modules installed in a "venv" virtual environment created with `python3 -m venv venv` – Sean McCarthy Feb 18 '21 at 20:25
  • This one worked for me Thanks a lot for this. – Ankit Chawla Apr 06 '21 at 13:46
2

If the matter is that you don't need Tkinter and friends because you are using PyQt4, then it might be best to avoid loading Tkinter etc altogether. Look into /etc/matplotlibrc and change the defaults to PyQt4, see the 'modified' lines below:

#### CONFIGURATION BEGINS HERE

# The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template.
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# 'module://my_backend'.

#modified 
#backend      : TkAgg
backend      : Qt4Agg


# If you are using the Qt4Agg backend, you can choose here
# to use the PyQt4 bindings or the newer PySide bindings to
# the underlying Qt4 toolkit.

#modified 
#backend.qt4 : PyQt4        # PyQt4 | PySide
backend.qt4 : PyQt4        # PyQt4 | PySide
ullix
  • 333
  • 1
  • 3
  • 14
1

I had the same problem with pyinstaller 3.0 and weblib. Importing it in the main didn't help.

Upgrading to 3.1 and deleting all build files helped.

pip install --upgrade pyinstaller
fivef
  • 2,397
  • 21
  • 21
0

May not be a good practice but installing pyinstaller in the original environment used in my project (instead of a separate venv) helped resolve ModuleNotFoundError

ATT
  • 1
  • 1
0

I had similar problem with PySimpleGUI. The problem was, pyinstaller was installed in different directory. SOLUTION (solved for me) : just install pyinstaller in the same directory in which the file is present (that to be converted to exe)

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

If these solutions don't work, simply deleting and reinstalling pyinstaller can fix this for you (as it did for me just now).

Putting this here for anyone else who might come across this post.

Ethicist
  • 791
  • 2
  • 7
  • 23
0

I had the same error. Mine said "ModuleNotFoundError: No module named 'numpy'". I fixed it by typing the following in the cmd:

pip install pyinstaller numpy

0

I had this problem because my binary was in a subfolder and I was using the top-level directory as my module root. That is, I had the following directory structure:

my-project/
└── a
    ├── b
    |   └── some_library.py
    └── c
        └── my_binary.py

I was always calling my_binary.py from the my-project directory as python -m a.c.my_binary and it imported some_library as from a.b import some_library. When I ran pyinstaller a/c/my_binary.py and then tried running my_binary, I got ModuleNotFound for some_library.

I had to run pyinstaller with the -paths flag, pointing it at the project root:

$ pyinstaller -paths=. a/c/my_binary.py
...
119 INFO: Extending PYTHONPATH with paths
['/home/me/gitroot/my-project/a/c', '/home/me/gitroot/my-project']
...

With the PYTHONPATH pointing at the project root, the module was included/resolved.

kris
  • 23,024
  • 10
  • 70
  • 79
0

My specific issue was that my Python installation was fragmented into a local directory (%APPDATA%/python) and the all-users' directory (C:/program files/python). I just deleted the local folder, reinstalled python + pyinstaller making sure they are in the all-users' directory, and it worked.

David Hsu
  • 1
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 30 '23 at 20:31