Pyinstaller –onefile warning file already exists but should not
Question:
When running Pyinstaller --onefile
, and starting the resulting .exe
, multiple popups show up with the following warning:
WARNING: file already exists but should not: C:UsersmyuserAppDataLocalTemp_MEI90082Cipher_AES.cp37-win_amd64.pyd
This makes the .exe
hard to use even though clicking through the warnings still allows the .exe
to run properly.
How to get rid of these warnings ?
Answers:
Going to put this here in case it helps anyone, since I spent some time finding out how to do this.
in the .spec
of your pyinstaller project, add this after the line a = Analysis(...)
:
# Avoid warning
to_remove = ["_AES", "_ARC4", "_DES", "_DES3", "_SHA256", "_counter"]
for b in a.binaries:
found = any(
f'{crypto}.cp37-win_amd64.pyd' in b[1]
for crypto in to_remove
)
if found:
print(f"Removing {b[1]}")
a.binaries.remove(b)
Of course you may adapt the array to_remove
as well as the exact file name .cp37-win_amd64.pyd
to match the files that show up in your warnings.
This results in the files not being included in the .exe
and the warnings are gone.
I have almost the same issue.
Not a good idea – remove part of the list that you are iterating.
Try this:
from PyInstaller.building.datastruct import TOC
# ...
# a = Analysis(...)
x = 'cp36-win_amd64'
datas_upd = TOC()
for d in a.datas:
if x not in d[0] and x not in d[1]:
datas_upd.append(d)
a.datas = datas_upd
As good as it is to encounter the warning message, noting them and creating an iterable used to exclude them in the .spec file, it would be even better if we don’t have to pass through that stress procedure. Let’s try it.
Observation: The data structure of both the ‘datas’ and ‘binaries’ are the same within the .spec file. i.e [(module_or_file_name, absolute_path, type_DATA_or_BINARY), …]
The methods here are the same, the implementation is what’s different. We look for what has been added to a.datas and repeated/re-added into a.binaries
Method 1: [1-liner but slower]
# ...
# a = Analysis(...)
a.binaries = [b for b in a.binaries if not b in list(set(b for d in a.datas for b in a.binaries if b[1].endswith(d[0])))] # The unique binaries not repeated in a.datas.
Method 2: [faster]
# ...
# a = Analysis(...)
for b in a.binaries.copy(): # Traver the binaries.
for d in a.datas: # Traverse the datas.
if b[1].endswith(d[0]): # If duplicate found.
a.binaries.remove(b) # Remove the duplicate.
break
I used this implementation when I was creating a simplified combined power of Cython + PyInstaller + AES encryption GUI Bundling application.
Hope this helps someone in future.
When running Pyinstaller --onefile
, and starting the resulting .exe
, multiple popups show up with the following warning:
WARNING: file already exists but should not: C:UsersmyuserAppDataLocalTemp_MEI90082Cipher_AES.cp37-win_amd64.pyd
This makes the .exe
hard to use even though clicking through the warnings still allows the .exe
to run properly.
How to get rid of these warnings ?
Going to put this here in case it helps anyone, since I spent some time finding out how to do this.
in the .spec
of your pyinstaller project, add this after the line a = Analysis(...)
:
# Avoid warning
to_remove = ["_AES", "_ARC4", "_DES", "_DES3", "_SHA256", "_counter"]
for b in a.binaries:
found = any(
f'{crypto}.cp37-win_amd64.pyd' in b[1]
for crypto in to_remove
)
if found:
print(f"Removing {b[1]}")
a.binaries.remove(b)
Of course you may adapt the array to_remove
as well as the exact file name .cp37-win_amd64.pyd
to match the files that show up in your warnings.
This results in the files not being included in the .exe
and the warnings are gone.
I have almost the same issue.
Not a good idea – remove part of the list that you are iterating.
Try this:
from PyInstaller.building.datastruct import TOC
# ...
# a = Analysis(...)
x = 'cp36-win_amd64'
datas_upd = TOC()
for d in a.datas:
if x not in d[0] and x not in d[1]:
datas_upd.append(d)
a.datas = datas_upd
As good as it is to encounter the warning message, noting them and creating an iterable used to exclude them in the .spec file, it would be even better if we don’t have to pass through that stress procedure. Let’s try it.
Observation: The data structure of both the ‘datas’ and ‘binaries’ are the same within the .spec file. i.e [(module_or_file_name, absolute_path, type_DATA_or_BINARY), …]
The methods here are the same, the implementation is what’s different. We look for what has been added to a.datas and repeated/re-added into a.binaries
Method 1: [1-liner but slower]
# ...
# a = Analysis(...)
a.binaries = [b for b in a.binaries if not b in list(set(b for d in a.datas for b in a.binaries if b[1].endswith(d[0])))] # The unique binaries not repeated in a.datas.
Method 2: [faster]
# ...
# a = Analysis(...)
for b in a.binaries.copy(): # Traver the binaries.
for d in a.datas: # Traverse the datas.
if b[1].endswith(d[0]): # If duplicate found.
a.binaries.remove(b) # Remove the duplicate.
break
I used this implementation when I was creating a simplified combined power of Cython + PyInstaller + AES encryption GUI Bundling application.
Hope this helps someone in future.