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 ?

Asked By: mananony

||

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.

Answered By: mananony

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

Answered By: cnstntn.kndrtv

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.

Answered By: McKUNJOUS
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.