Skip to content
Search

PyInstaller

lastmod 2024-09-23created 2020-06-2522 edits

PyInstaller freezes (packages) Python applications into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX.

Options

-F, --onefile
Create a one-file bundled executable.
--clean
Clean PyInstaller cache and remove temporary files before building.

Windows And Mac Os X Specific Options

-w, --windowed, --noconsole
Windows and Mac OS X: do not provide a console window for standard i/o.
On Mac OS this also triggers building a Mac OS .app bundle.
On Windows this option is automatically set if the first script is a .pyw file.
This option is ignored on *NIX systems.
-i ICON , --icon ICON
ICON is FILE.ico or FILE.exe,ID or FILE.icns or Image or NONE
  • FILE.ico: apply the icon to a Windows executable.
  • FILE.exe,ID: extract the icon with ID from an exe.
  • FILE.icns: apply the icon to the .app bundle on Mac OS.
  • Image: If an image file is entered that isn’t in the platform format (ico on Windows, icns on Mac), PyInstaller tries to use Pillow to translate the icon into the correct format (if Pillow is installed).
  • NONE to not apply any icon, thereby making the OS show some default (default: apply PyInstaller’s icon).
This option can be used multiple times.

Hide console window

To keep the console window from appearing, add -w or --windowed to the command as below.

pyinstaller -w qtextbrowser_advanced.py

Single executable

To generate just a single executable file, add -F or –onefile to the command as below.

pyinstaller -F qtextbrowser_advanced.py

Setting the icon

pyinstaller --icon=./test.ico --onefile 파이썬 파일명.py

Using Spec Files

There are four cases where it is useful to modify the spec file.

  • When you want to bundle data files with the app.
  • When you want to include runtime libraries ( .dll or files) that PyInstaller does not know about from other sources..so
  • When you want to add Python runtime options to the executable.
  • When you want to create a multiprogram bundle with merged common modules.

Specifying the data folder

pyinstaller -F --add-data "./res/data;data" yourtarget.py

multiprocessing in windows

To support multiprocessing on other platforms, you must use the freeze_support function. The docs say that running it only affects freeze support on Windows... you can probably think of it as fixing the processes that shut down when running a program built as an exe file.

if __name__ == "__main__":
    multiprocessing.freeze_support()

Applying UPX

Package Data

Generate Pyinstaller binaries

Typically, you generate a single executable file with pyinstaller using the following command.

$pyinstaller --onefile --clean <file_name.py>

Adding data files to a pyinstaller executable

Suppose your application has a help file that needs to be packaged along with the executable. The application must read the file at runtime and display it to the user.

How do you do that? The file exists as part of the application during packaging, but it is not packaged with the binary. So you may get an error like the following at runtime.

FileNotFoundError: [Errno 2] No such file or directory:C:\\Users\\Username\\AppData\\Local\\Temp\\_MEI41602\\help.md
[11200] Failed to execute script

This is because the pyinstaller executable looks for data files in a temporary directory _MEIXXXX, where XXXX is a random number. You need to make sure all supporting data files are copied there.

Pyinstaller extracts the data into a temporary folder and stores this directory path in the MEIPASS variable. This attribute is set in the sys environment by the bootloader.

The MEIPASS variable is available only when the program is running in bundle mode. It also helps you check whether the program is running from the bundle or from source code.

Windows

$pyinstaller --onefile --clean --add-data "help.md;." <file_name.py>

Here we pass the file path to the add data flag with the path inside the bundle separated by a semi colon.

Linux/Mac

$pyinstaller --onefile --clean --add-data "help.md:." <file_name.py>

Here we pass the file path to the add data flag with the path inside the bundle separated by a colon.

Spec file

The data files can be added via spec files as well.

a = Analysis(...
     datas=[ ('help.md', '.') ],
     ...
     )

datas is a tuple whose first string indicates that the existing file is help.md. That file is looked up relative to the location of the spec file and copied to the top level of the bundled app. In this case the help file is in the current directory.

Now that the help data file has been added to the pyinstaller binary, how do you read it and display it to the user?

First, you need to make sure the help file can be read both from source code and in bundle mode. As mentioned earlier, you can check whether the program is running from source code or from pyinstaller.

def read_help_file():
    # Check if MEIPASS attribute is available in sys else return current file path
    bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
    path_to_help = os.path.abspath(os.path.join(bundle_dir,'help.md'))
    with open(path_to_help, "r+") as help_file:
        print(help_file.read())

Troubleshotting

_tkinter.TclError: invalid command name "PyImagingPhoto"

When using tkinter together with PIL, the following error is printed:

Traceback (most recent call last):
  File "PIL/ImageTk.py", line 181, in paste
_tkinter.TclError: invalid command name "PyImagingPhoto"

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "magic-collection-tracker/test.py", line 22, in <module>
  File "magic-collection-tracker/test.py", line 11, in main
  File "PIL/ImageTk.py", line 120, in __init__
  File "PIL/ImageTk.py", line 185, in paste
ModuleNotFoundError: No module named 'PIL._tkinter_finder'

Solve it with hiddenimports.

hiddenimports=['PIL', 'PIL._imagingtk', 'PIL._tkinter_finder']

UPX is not available

Install UPX (executable compression) first.

See also

Favorite site

author Zer0 sitemap