How PyInstaller Bundles Python Scripts to Executables
PyInstaller converts Python scripts into standalone executable applications by analyzing source code to detect all necessary dependencies, gathering those files alongside a dedicated Python runtime, and wrapping them with an executable launcher called a bootloader. This enables users to run Python programs on machines that do not have Python installed, preserving all libraries, binary extensions, and data assets within a self-contained distribution.
1. Dependency Analysis
The bundling process begins with static code analysis. PyInstaller
reads the primary Python script and parses its Abstract Syntax Tree
(AST) to identify every import statement. It then
recursively inspects the imported modules to discover secondary
dependencies, including standard library modules, third-party packages,
and compiled C-extensions (.pyd on Windows or
.so on Linux and macOS). PyInstaller also uses built-in
"hooks" to identify hidden imports or dynamic dependencies that cannot
be detected through static analysis alone.
2. Gathering the Runtime Components
Python scripts require an interpreter to execute; they cannot be translated directly into native machine code. To resolve this, PyInstaller collects:
- The target operating system's specific Python dynamic library (such
as
python3x.dllon Windows orlibpythonon Linux/macOS). - All identified third-party libraries and local modules.
- Any bundled data files, configuration files, or binaries explicitly specified by the developer.
3. The Bootloader
PyInstaller provides a precompiled native binary executable known as
the bootloader. This small C program serves as the entry point of the
final application. When a user runs the compiled application, the
bootloader initializes first. It sets up the execution environment,
creates an isolated Python runtime instance using the bundled shared
library, and points Python's module search path (sys.path)
to the bundled dependencies. Finally, it tells the embedded interpreter
to execute the primary Python script.
4. Packaging Modes: One-Folder vs. One-File
PyInstaller packages the application into one of two formats:
- One-Folder Mode (
--onedir): This is the default mode. PyInstaller places the executable bootloader, the Python shared libraries, and all dependencies into a single directory. The executable launches directly from this directory, which offers faster startup times because no files need extraction. - One-File Mode (
--onefile): PyInstaller packages the bootloader, all code, libraries, and resources into a single executable using a compressed archive. When executed, the bootloader extracts these contents into a temporary directory (typically named_MEIxxxxxxin the system's temporary directory). The bootloader then runs the application from this temporary path and automatically deletes the files once the program terminates.
5. Runtime Execution
Regardless of the packaging mode, the resulting binary is an encapsulated environment. Because it includes both the interpreter and all necessary modules, the application executes independently of any system-wide Python installation on the target machine.