What PyInstaller Does and How It Does It — PyInstaller 6.6.0 documentation (2024)

This section covers the basic ideas of PyInstaller.These ideas apply to all platforms.Options and special cases are covered below, under Using PyInstaller.

PyInstaller reads a Python script written by you.It analyzes your code to discover every other module and libraryyour script needs in order to execute.Then it collects copies of all those files – includingthe active Python interpreter! – and puts them withyour script in a single folder,or optionally in a single executable file.

For the great majority of programs, this can be done with one short command,

pyinstaller myscript.py

or with a few added options, for example a windowed applicationas a single-file executable,

pyinstaller --onefile --windowed myscript.py

You distribute the bundle as a folder or file to other people,and they can executeyour program.To your users, the app is self-contained.They do not need to install any particular version of Python or any modules.They do not need to have Python installed at all.

Note

The output of PyInstaller is specific to the active operating systemand the active version of Python.This means that to prepare a distribution for:

you run PyInstaller on that OS, under that version of Python.The Python interpreter that executes PyInstaller is part ofthe bundle, and it is specific to the OS and the word size.

Analysis: Finding the Files Your Program Needs

What other modules and libraries does your script need in order to run?(These are sometimes called its “dependencies”.)

To find out, PyInstaller finds all the import statementsin your script.It finds the imported modules and looks in them for importstatements, and so on recursively, until it has a complete list ofmodules your script may use.

PyInstaller understands the “egg” distribution format often usedfor Python packages.If your script imports a module from an “egg”, PyInstaller addsthe egg and its dependencies to the set of needed files.

PyInstaller also knows about many major Python packages,including the GUI packagesQt (imported via PyQt or PySide), WxPython, TkInter, matplotlib,and other major packages.For a complete list, see Supported Packages.

Some Python scripts import modules in ways that PyInstaller cannot detect:for example, by using the __import__() function with variable data,using importlib.import_module(),or manipulating the sys.path value at run time.If your script requires files that PyInstaller does not know about,you must help it:

  • You can give additional files on the pyinstaller command line.

  • You can give additional import paths on the command line.

  • You can edit the myscript.spec filethat PyInstaller writes the first time you run it for your script.In the spec file you can tell PyInstaller about code modulesthat are unique to your script.

  • You can write “hook” files that inform PyInstaller of hidden imports.If you create a “hook” for a package that other users might also use,you can contribute your hook file to PyInstaller.

If your program depends on access to certain data files,you can tell PyInstaller to include them in the bundle as well.You do this by modifying the spec file, an advanced topic that iscovered under Using Spec Files.

In order to locate included files at run time,your program needs to be able to learn its path at run timein a way that works regardless ofwhether or not it is running from a bundle.This is covered under Run-time Information.

PyInstaller does not include libraries that should exist inany installation of this OS.For example in GNU/Linux, it does not bundle any filefrom /lib or /usr/lib, assumingthese will be found in every system.

Bundling to One Folder

When you apply PyInstaller to myscript.py the defaultresult is a single folder named myscript.This folder contains all your script’s dependencies,and an executable file also named myscript(myscript.exe in Windows).

You compress the folderto myscript.zip and transmit it to your users.They install the program simply by unzipping it.A user runs your app byopening the folder and launching the myscript executable inside it.

It is easy to debug problems that occur when building the appwhen you use one-folder mode.You can see exactly what files PyInstaller collected into the folder.

Another advantage of a one-folder bundleis that when you change your code, as longas it imports exactly the same set of dependencies, you could send outonly the updated myscript executable.That is typically much smallerthan the entire folder.(If you change the script so that it imports moreor different dependencies, or if the dependenciesare upgraded, you must redistribute the whole bundle.)

How the One-Folder Program Works

A bundled program always starts execution in the PyInstaller bootloader.This is the heart of the myscript executable in the folder.

The PyInstaller bootloader is a binaryexecutable program for the active platform(Windows, GNU/Linux, macOS, etc.).When the user launches your program, it is the bootloader that runs.The bootloader creates a temporary Python environmentsuch that the Python interpreter will find all imported modules andlibraries in the myscript folder.

The bootloader starts a copy of the Python interpreterto execute your script.Everything follows normally from there, providedthat all the necessary support files were included.

(This is an overview.For more detail, see The Bootstrap Process in Detail below.)

Bundling to One File

PyInstaller can bundle your script and all its dependencies into a singleexecutable named myscript (myscript.exe in Windows).

The advantage is that your users get something they understand,a single executable to launch.A disadvantage is that any related filessuch as a README must be distributed separately.Also, the single executable is a little slower to start up thanthe one-folder bundle.

Before you attempt to bundle to one file, make sure your appworks correctly when bundled to one folder.It is is much easier to diagnose problems in one-folder mode.

How the One-File Program Works

The bootloader is the heart of the one-file bundle also.When started it creates a temporary folderin the appropriate temp-folder location for this OS.The folder is named _MEIxxxxxx, where xxxxxx is a random number.

The one executable file contains an embedded archive of all the Pythonmodules used by your script, as well ascompressed copies of any non-Python support files (e.g. .so files).The bootloader uncompresses the support files and writes copiesinto the the temporary folder.This can take a little time.That is why a one-file app is a little slower to startthan a one-folder app.

Note

PyInstaller currently does not preserve file attributes.see #3926.

After creating the temporary folder, the bootloaderproceeds exactly as for the one-folder bundle,in the context of the temporary folder.When the bundled code terminates,the bootloader deletes the temporary folder.

(In GNU/Linux and related systems, it is possibleto mount the /tmp folder with a “no-execution” option.That option is not compatible with a PyInstallerone-file bundle. It needs to execute code out of /tmp.If you know the target environment,--runtime-tmpdir might be a workaround. Alternatively,you can set the environment variable that controls the temporarydirectory before launching the program. See Defining the Extraction Location).

Because the program makes a temporary folder with a unique name,you can run multiple copies of the app;they won’t interfere with each other.However, running multiple copies is expensive in disk space becausenothing is shared.

The _MEIxxxxxx folder is not removed if the program crashesor is killed (kill -9 on Unix, killed by the Task Manager on Windows,“Force Quit” on macOS).Thus if your app crashes frequently, your users will lose disk space tomultiple _MEIxxxxxx temporary folders.

It is possible to control the location of the _MEIxxxxxx folder byusing the --runtime-tmpdir command line option. The specified path isstored in the executable, and the bootloader will create the_MEIxxxxxx folder inside of the specified folder. Please seeDefining the Extraction Location for details.

Note

Do not give administrator privileges to a one-file executable on Windows(“Run this program as an administrator”).There is an unlikely but not impossible way in which a malicious attacker couldcorrupt one of the shared libraries in the temp folderwhile the bootloader is preparing it.When distributing a privileged program in general, ensure that filepermissions prevent shared libraries or executables from being tampered with.Otherwise, an unelevated process which has write access to these files mayescalate privileges by modifying them.

Note

Applications that use os.setuid() may encounter permissions errors.The temporary folder where the bundled app runs may not being readableafter setuid is called. If your script needs tocall setuid, it may be better to use one-folder modeso as to have more control over the permissions on its files.

Using a Console Window

By default the bootloader creates a command-line console(a terminal window in GNU/Linux and macOS, a command window in Windows).It gives this window to the Python interpreter for its standard input and output.Your script’s use of print and input() are directed here.Error messages from Python and default logging outputalso appear in the console window.

An option for Windows and macOS is to tell PyInstaller to not provide a console window.The bootloader starts Python with no target for standard output or input.Do this when your script has a graphical interface for user input and can properlyreport its own diagnostics.

As noted in the CPython tutorial Appendix,for Windows a file extension of .pyw suppresses the console windowthat normally appears.Likewise, a console window will not be provided when usinga myscript.pyw script with PyInstaller.

Hiding the Source Code

The bundled app does not include any source code.However, PyInstaller bundles compiled Python scripts (.pyc files).These could in principle be decompiled to reveal the logic ofyour code.

If you want to hide your source code more thoroughly, one possible optionis to compile some of your modules with Cython.Using Cython you can convert Python modules into C and compilethe C to machine language.PyInstaller can follow import statements that refer toCython C object modules and bundle them.

What PyInstaller Does and How It Does It — PyInstaller 6.6.0 documentation (2024)
Top Articles
Latest Posts
Article information

Author: Fr. Dewey Fisher

Last Updated:

Views: 5617

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Fr. Dewey Fisher

Birthday: 1993-03-26

Address: 917 Hyun Views, Rogahnmouth, KY 91013-8827

Phone: +5938540192553

Job: Administration Developer

Hobby: Embroidery, Horseback riding, Juggling, Urban exploration, Skiing, Cycling, Handball

Introduction: My name is Fr. Dewey Fisher, I am a powerful, open, faithful, combative, spotless, faithful, fair person who loves writing and wants to share my knowledge and understanding with you.