Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exe-file created by pyinstaller, not find self-defined modules while running

I create two python files, and the directory/file relations is as follows:

mytest---
     |---mycommon.py
     |---myMainDir---
                     |----myMain.py

In mycommon.py:

def myFunc(a):
    ...

And in myMain.py:

import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath('__file__')), '..'))
import mycommon.py
mycommon.myFunc("abc")

Then I created exe using pyinstaller:

pyinstall.py -F mytest\myMainDir\myMain.py

MyMain.exe is created, but when run, is tells that can not find mycommon module.

like image 709
DarkMagic Avatar asked Aug 19 '15 10:08

DarkMagic


People also ask

Why is the .exe file created by PyInstaller not working?

The most common reason a PyInstaller package fails is that PyInstaller failed to bundle a required file. Such missing files fall into a few categories: Hidden or missing imports: Sometimes PyInstaller can't detect the import of a package or library, typically because it is imported dynamically.

How do I add modules to PyInstaller?

Once you know what modules are needed, you add the needed modules to the bundle using the --hidden-import command option, or by editing the spec file, or with a hook file (see Understanding PyInstaller Hooks below).

Does PyInstaller include all dependencies?

PyInstaller can bundle your script and all its dependencies into a single executable named myscript ( myscript.exe in Windows). The advantage is that your users get something they understand, a single executable to launch.

Does PyInstaller include libraries?

spec extension. The . Spec file has the same name as the python script file. PyInstaller creates a distribution directory, DIST containing the main executable and the dynamic libraries bundled in an executable file.


2 Answers

PyInstaller's official manual describes this issue:

Some Python scripts import modules in ways that PyInstaller cannot detect: for example, by using the __import__() function with variable data, or manipulating the sys.path value at run time. If your script requires files that PyInstaller does not know about, you must help it.

It also suggests what should be done in such a case:

If Analysis recognizes that a module is needed, but cannot find that module, it is often because the script is manipulating sys.path. The easiest thing to do in this case is to use the --paths= option to list all the other places that the script might be searching for imports:

pyi-makespec --paths=/path/to/thisdir --paths=/path/to/otherdir myscript.py

These paths will be added to the current sys.path during analysis.

Therefore, please specify the --paths argument while building the application. The manual states that specifying the -p argument is equivalent:

-p dir_list, --paths=dir_list

Set the search path(s) for imported modules (like using PYTHONPATH). Use this option to help PyInstaller to search in the right places when your code modifies sys.path for imports. Give one or more paths separated by ; (under Windows) or : (all other platforms), or give the option more than once to give multiple paths to search.

like image 123
Yoel Avatar answered Sep 19 '22 17:09

Yoel


Also I had to fight a bit to get pyinstaller correctly import python scripts in a subfolder where the path to the subfolder was set relatively via sys.path.insert.

The answer by Yoel was correct for me but I needed careful setting of paths in Windows. Here is what I did:

My main py is:

D:\_Development\pCompareDBSync\pCompareDBSync\pCompareDBSync.py

My imported py is:

D:\_Development\pCompareDBSync\pCompareDBSync\py\pCompareNVR.py

(I have many of such imported py's in folder .\py\ but here i just use a single one as example)

So my main PY, I have the following include:

sys.path.insert(0, 'py')

try:
    from pCompareNVR import fgetNV_sN_dict
    from pCompareNVR import findNVRJobInDBSync
    from pCompareNVR import getNVRRecords
    from pCompareNVR import saveNVRRecords
    from pCompareNVR import compareNVRs
except Exception as e:
    print('Can not import files:' + str(e))
    input("Press Enter to exit!")
    sys.exit(0)
pyinstaller --onefile pCompareDBSync.py 

-> pCompareDBSync.exe that did NOT include py/pCompareNVR.py

I had to include the absolute pad to the main PY and the imported PY's:

pyinstaller --onefile --paths=D:\_Development\pCompareDBSync\pCompareDBSync\ --paths=D:\_Development\pCompareDBSync\pCompareDBSync\py pCompareDBSync.py

-> pCompareDBSync.exe that did now include py/pCompareNVR.py -> OK

And that solved this issue for me!

like image 44
Al-Noor Ladhani Avatar answered Sep 19 '22 17:09

Al-Noor Ladhani