PyInstaller bundles a Python application and all its dependencies into a single package.
—
PyInstaller's spec file classes provide programmatic control over the build process. These classes define the dependency analysis, archive creation, and executable generation phases, allowing for complex customization beyond what's possible with command-line options.
The Analysis class performs dependency analysis of Python scripts, collecting all required modules, binaries, and data files.
class Analysis:
"""
Performs analysis of Python scripts and their dependencies.
The Analysis class discovers all modules, binaries, and data files
required by the application through import analysis and hook execution.
"""
def __init__(self, scripts, pathex=[], binaries=[], datas=[],
hiddenimports=[], hookspath=[], hooksconfig={},
runtime_hooks=[], excludes=[], win_no_prefer_redirects=False,
win_private_assemblies=False, cipher=None, noarchive=False,
module_collection_mode={}, optimize=-1):
"""
Initialize Analysis instance.
Args:
scripts (list): List of main script file paths to analyze
pathex (list): Additional paths to search before sys.path
binaries (list): Additional binaries as (src, dest) tuples
datas (list): Additional data files as (src, dest) tuples
hiddenimports (list): Hidden module names to force include
hookspath (list): Additional directories to search for hooks
hooksconfig (dict): Configuration dictionary for hooks
runtime_hooks (list): Runtime hook script paths
excludes (list): Module names to exclude from analysis
win_no_prefer_redirects (bool): Windows redirect handling
win_private_assemblies (bool): Windows assembly handling
cipher (deprecated): Previously used for encryption
noarchive (bool): Keep files as individual files instead of archive
module_collection_mode (dict): Per-module collection mode settings
optimize (int): Python bytecode optimization level (-1, 0, 1, 2)
"""
# Key attributes available after analysis:
scripts: list # Scripts with runtime hooks prepended
pure: list # Pure Python modules TOC
binaries: list # Extension modules and shared libraries TOC
datas: list # Data files TOC
zipfiles: list # Deprecated (always empty)
zipped_data: list # Deprecated (always empty)# Basic analysis
a = Analysis(
['main.py'],
pathex=['/extra/path'],
binaries=[('mylib.so', '.')],
datas=[('config/', 'config/')],
hiddenimports=['scipy.special'],
excludes=['matplotlib'],
optimize=0
)
# Analysis with hooks configuration
a = Analysis(
['app.py'],
hooksconfig={
'gi': {
'icons': ['Adwaita'],
'themes': ['Adwaita'],
'languages': ['en_US', 'de_DE']
}
}
)Creates a zlib-compressed archive containing compiled Python modules.
class PYZ:
"""
Creates a zlib-based PYZ archive containing byte-compiled Python modules.
The PYZ archive contains all pure Python modules collected during analysis,
compressed for efficient storage and fast loading at runtime.
"""
def __init__(self, *tocs, name=None):
"""
Initialize PYZ archive.
Args:
*tocs: One or more Table of Contents lists (typically Analysis.pure)
name (str, optional): Custom filename for .pyz archive
"""
# Attributes:
name: str # Archive filename
dependencies: list # Bootstrap dependencies# Standard PYZ creation
pyz = PYZ(a.pure, a.zipped_data)
# Custom PYZ name
pyz = PYZ(a.pure, name='myapp.pyz')Creates a CArchive package containing all collected files and dependencies.
class PKG:
"""
Creates CArchive package containing all collected files.
The PKG contains binaries, data files, and the PYZ archive,
providing the complete application bundle for the executable.
"""
def __init__(self, toc, name=None, cdict=None, exclude_binaries=0,
strip_binaries=False, upx_binaries=False, upx_exclude=[]):
"""
Initialize PKG archive.
Args:
toc: Table of contents from Analysis or COLLECT
name (str, optional): Package name
cdict (dict, optional): Code dictionary for optimization
exclude_binaries (int): Exclude binary files (0=include, 1=exclude)
strip_binaries (bool): Strip debug symbols from binaries
upx_binaries (bool): Compress binaries with UPX
upx_exclude (list): Patterns for UPX exclusion
"""Creates the final executable from PKG and bootloader.
class EXE:
"""
Creates final executable from PKG and bootloader.
The EXE class combines the application package with the appropriate
bootloader to create a standalone executable file.
"""
def __init__(self, *args, name='', console=True, debug=False,
bootloader_ignore_signals=False, strip=False, upx=True,
upx_exclude=[], runtime_tmpdir=None, contents_directory=None,
uac_admin=False, uac_uiaccess=False, win_no_prefer_redirects=False,
win_private_assemblies=False, embed_manifest=True, resources=[],
icon=None, version=None, disable_windowed_traceback=False,
argv_emulation=False, target_arch=None, codesign_identity=None,
entitlements_file=None, strictArchitecture=True):
"""
Initialize EXE instance.
Args:
*args: PKG instance and other dependencies
name (str): Executable name
console (bool): Console application (True) vs windowed (False)
debug (bool): Include debug information
bootloader_ignore_signals (bool): Bootloader signal handling
strip (bool): Strip debug symbols from executable
upx (bool): Compress executable with UPX
upx_exclude (list): UPX exclusion patterns
runtime_tmpdir (str): Runtime temporary directory path
contents_directory (str): Contents directory name for onedir
uac_admin (bool): Windows UAC admin execution level
uac_uiaccess (bool): Windows UAC UI access permissions
win_no_prefer_redirects (bool): Windows DLL redirect preferences
win_private_assemblies (bool): Windows private assembly handling
embed_manifest (bool): Embed Windows manifest in executable
resources (list): Additional Windows resources
icon (str): Application icon file path (.ico, .icns)
version (str): Version resource file path (Windows)
disable_windowed_traceback (bool): Disable traceback in windowed mode
argv_emulation (bool): macOS argv emulation for drag-and-drop
target_arch (str): Target architecture (x86_64, arm64, universal2)
codesign_identity (str): macOS code signing identity
entitlements_file (str): macOS entitlements file path
strictArchitecture (bool): macOS strict architecture enforcement
"""# One-file executable
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='MyApp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True
)
# Windows executable with icon and version
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='MyApp',
console=False,
icon='app.ico',
version='version_info.txt',
uac_admin=True
)
# macOS application
exe = EXE(
pyz,
a.scripts,
exclude_binaries=True,
name='MyApp',
debug=False,
console=False,
icon='app.icns',
codesign_identity='Developer ID Application: My Name',
entitlements_file='entitlements.plist'
)Collects files into a directory structure for onedir distribution.
class COLLECT:
"""
Collects files into directory structure for onedir distribution.
COLLECT creates a directory containing the executable and all
its dependencies, providing a complete application folder.
"""
def __init__(self, *args, name='', strip_binaries=False,
upx_binaries=False, upx_exclude=[]):
"""
Initialize COLLECT instance.
Args:
*args: Target instances (EXE, PYZ) or TOC lists to collect
name (str): Output directory name
strip_binaries (bool): Strip debug symbols from binaries
upx_binaries (bool): Compress binaries with UPX
upx_exclude (list): UPX exclusion patterns
"""# Create onedir distribution
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip_binaries=False,
upx_binaries=False,
name='MyApp'
)Merges multiple Analysis instances for multi-program bundles.
class MERGE:
"""
Merges multiple Analysis instances for multi-program bundles.
MERGE allows creating a single distribution containing multiple
executables that share common dependencies.
"""
def __init__(self, *args):
"""
Initialize MERGE instance.
Args:
*args: Dependencies as (analysis, script_name, executable_name) tuples
"""# Create separate analyses for each program
a1 = Analysis(['prog1.py'], ...)
a2 = Analysis(['prog2.py'], ...)
# Merge analyses
merge = MERGE(
(a1, 'prog1', 'Program1'),
(a2, 'prog2', 'Program2')
)
# Create executables from merged analysis
exe1 = EXE(PYZ(merge.pure), merge.scripts[0], ...)
exe2 = EXE(PYZ(merge.pure), merge.scripts[1], ...)# myapp.spec - Complete spec file example
from PyInstaller.building.build_main import Analysis
from PyInstaller.building.api import PYZ, EXE, COLLECT
# Analysis phase
a = Analysis(
['src/main.py'],
pathex=['src'],
binaries=[],
datas=[
('config/', 'config/'),
('assets/', 'assets/'),
],
hiddenimports=[
'pkg_resources.py2_warn',
'sklearn.utils._cython_blas'
],
hookspath=['hooks'],
hooksconfig={},
runtime_hooks=['runtime_hooks/matplotlib_hook.py'],
excludes=['matplotlib', 'tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
optimize=0
)
# PYZ archive creation
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
# Executable creation
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='MyApplication',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='assets/icon.ico'
)
# Optional: Create onedir distribution
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip_binaries=False,
upx_binaries=False,
name='MyApplication'
)After creating a .spec file:
# Build from spec file
pyinstaller myapp.spec
# Clean build
pyinstaller --clean myapp.spec
# Debug build
pyinstaller --log-level DEBUG myapp.specInstall with Tessl CLI
npx tessl i tessl/pypi-pyinstaller