Here is an example, which in fact works, and so it does not actually illustrate my problem, but just to set a basis for discussion:
mkdir C:/test/testpyinstcd C:/test/testpyinst
Here I have main.py
:
#!/usr/bin/env python3import sys, osfrom lib import relative_path2def relative_path(relative_path): # https://stackoverflow.com/q/58487122 try: base_path = sys._MEIPASS print("_MEIPASS OK {}".format(base_path)) except Exception: base_path = os.path.abspath(".") print("_MEIPASS exception {}".format(base_path)) return os.path.join(base_path, relative_path)def main(): print("Hello from main") print("relative_path {}".format(relative_path("."))) print("relative_path2 {}".format(relative_path2(".")))if __name__ == '__main__': main()
... and lib.py
:
import sys, osdef relative_path2(relative_path): # https://stackoverflow.com/q/58487122 try: base_path = sys._MEIPASS print("_MEIPASS OK {}".format(base_path)) except Exception: base_path = os.path.abspath(".") print("_MEIPASS exception {}".format(base_path)) return os.path.join(base_path, relative_path)
I use this - pyinstaller
installed via python3 -m pip install pyinstaller
:
$ uname -sMINGW64_NT-10.0-19045$ python3 --versionPython 3.11.8$ pyinstaller --version6.5.0
When I run this code directly from python, _MEIPASS
is as expected not accessible:
$ python3 main.pyHello from main_MEIPASS exception C:/test/testpyinstrelative_path C:/test/testpyinst/._MEIPASS exception C:/test/testpyinstrelative_path2 C:/test/testpyinst/.
Then I create an .exe
with PyInstaller:
pyinstaller --onefile main.py
... and when I run the .exe, as expected, _MEIPASS
works:
$ ./dist/main.exeHello from main_MEIPASS OK D:\msys64\tmp\_MEI199762relative_path D:\msys64\tmp\_MEI199762/._MEIPASS OK D:\msys64\tmp\_MEI199762relative_path2 D:\msys64\tmp\_MEI199762/.
So, here is my problem - in my actual (pyqt5) project, sys._MEIPASS
does not work - in the sense that I always get an exception in relative_path()
when trying to read sys._MEIPASS
while running from the final .exe
created by PyInstaller !?
I found this AttributeError: 'module' object has no attribute '_MEIPASS' (redux) · Issue #1785 · pyinstaller/pyinstaller:
sys._MEIPASS
is set by the exe produced by pyinstaller before it runs any python code. I can think of a few reasons why it would not be set:
- The code reload(sys) is executed
- You are using a version of PyInstaller prior to 3.0
- PyInstaller was improperly installed and is using the old 2.1 bootloader files
I have tried running python3 -m trace --trace myprogram.py | grep reload
, and apparently reload(sys) is never called in my program ...
So, I am still at a loss: what can I possibly do in my project, to get sys._MEIPASS
working as expected?