I'm trying to compile a python application using Pyinstaller with the following spec file:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['src\\cdi_live.py'],
pathex=['src', 'venv/Lib/site-packages'],
binaries=[],
datas=[
('example_data/*.tif', 'example_data'),
('LICENSE.txt', '.'),
('README.md', '.')
],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='cdi_live',
debug="all",
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='cdi_live',
)
When I run Pyinstaller on this, it works exactly as expected. No red flags while compiling, and the output goes into my dist
directory. When I run the executable, a terminal opens up, I get my verbose debugging messages, and then my GUI opens on top of that. Everything in the application functions perfectly, and I breathe a sigh of relief.
Then, because I don't want to open a console every time I run my application, I change one line in the spec file:
exe = EXE(
...
console=False,
...
)
I run Pyinstaller again. At first, it seems to have worked again. But when I run the executable, I get a message saying that it failed to execute the script due to an unhandled AttributeError
when I imported scipy.ndimage
(full traceback given below).
Why would that single line cause the compiled executable to fail, and how do I fix it?
I don't know how much of this will be useful, but I'll include everything I think might have bearing on the question.
I've gone back and forth with the console
option and it always works with console=True
and always fails with console=False
.
I've used the same spec file to compile this app in the past, and it worked fine. Since the previous version, I've added some matplotlib.backends.backend_tkagg.FigureCanvasTkAgg
widgets.
The traceback that shows up in the error pop-up is long and burrows deep into the dependencies:
Traceback (most recent call last):
File "cdi_live.py", line 20, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "phasing.py", line 7, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "scipy\ndimage\__init__.py", line 152, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "scipy\ndimage\_filters.py", line 37, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "scipy\_lib\_util.py", line 18, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "scipy\_lib\_array_api.py", line 21, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "scipy\_lib\array_api_compat\numpy\__init__.py", line 1, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "numpy\f2py\__init__.py", line 19, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "numpy\f2py\f2py2e.py", line 23, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "numpy\f2py\crackfortran.py", line 159, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "numpy\f2py\auxfuncs.py", line 19, in <module>
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 378, in exec_module
File "numpy\f2py\cfuncs.py", line 19, in <module>
AttributeError: 'NoneType' object has no attribute 'write'
The last call to my own code (File "phasing.py", line 7, in <module>
) is an attempt to import scipy.ndimage
. Before that point, python has already imported tkinter, numpy, and several packages from matplotlib.
Running the EXE with a debugger active doesn't provide much help. The output is identical to the console output. After I close out the error message, I get a few additional lines:
00000047 33.55646133 [31580] [PYI-31580:DEBUG] LOADER: ERROR.
00000048 33.55653381 [31580] [PYI-31580:DEBUG] LOADER: cleaning up Python interpreter...
00000049 33.63221741 [31580] [PYI-31580:DEBUG] LOADER: unloading Python shared library...
00000050 33.63228989 [31580] [PYI-31580:DEBUG] LOADER: end of process reached!
that's a bug in numpy 2.0
that was fixed 2 months ago, https://github.com/numpy/numpy/issues/26862
either upgrade to the latest numpy 2.1
or downgrade to 1.26
, or just dump stderr manually by putting this as the first line in your program.
import sys
class dummyOut:
def write(self, data):
pass
sys.stderr = dummyOut()