compileall


Compileall Module

Purpose:

The compileall module helps you automatically compile Python source files into bytecode files (.pyc) for faster execution.

Command-Line Usage

Compileall as a Script:

You can run compileall as a script to compile Python source files.

Usage:

python -m compileall [options] <files and directories>

Options:

  • -l: Only compile files directly in specified directories, not in subdirectories.

  • -f: Force recompilation, even if source file timestamps are up-to-date.

  • -q: Suppress printing the list of compiled files.

  • -d : Prepend given directory to file paths in compiled bytecode files.

  • -s <strip_prefix>: Remove specified prefix from file paths in bytecode files.

  • -p <prepend_prefix>: Add specified prefix to file paths in bytecode files.

  • -x : Skip files that match the given regular expression.

  • -i : Read list of files and directories to compile from the given file or stdin.

  • -b: Write bytecode files to their legacy locations and names (e.g., foo.pyc instead of pycache/foo.cpython-310.pyc).

  • -r : Control maximum recursion level for subdirectories.

  • -j : Use N worker processes to compile files (0 means use all available CPUs).

  • --invalidation-mode [timestamp|checked-hash|unchecked-hash]: Control how bytecode files are invalidated at runtime.

  • -o : Compile with the given optimization level (can be used multiple times to compile for multiple levels).

  • -e: Ignore symlinks pointing outside the given directory.

  • --hardlink-dupes: Use hard links to consolidate duplicate bytecode files with the same content.

Potential Applications

  • Faster Execution: Precompiled bytecode files make code execution faster.

  • Convenience: Automatically compiles source files, saving you the hassle of doing it manually.

  • Deployment: Precompile code for deployment in environments where direct compilation is not possible or inconvenient.

Code Implementation Example

# Compile all Python source files in the current directory
import compileall

compileall.compile_dir(".")

Topic: Compiling Python Files Recursively

Explanation:

Imagine you have a directory with many Python .py files. You want to turn these files into .pyc files, which contain the compiled bytecode of your programs. The compileall module helps you do this recursively, meaning it goes through all the subdirectories as well.

Example:

import compileall

# Compile all `.py` files in the 'my_dir' directory
compileall.compile_dir('my_dir')

Topic: Options for Customization

Explanation:

You can customize the compilation process with several options:

  • maxlevels: How deep to go into subdirectories (defaults to the maximum recursion limit).

  • ddir: Prepend a path to compiled files (useful for debugging).

  • force: Recompile files even if they're up-to-date.

  • rx: Use a regex to skip files that match a pattern (e.g., exclude test files).

  • quiet: Control how much output is printed (0 for all, 1 for errors only, 2 for none).

  • legacy: Use the old bytecode file naming scheme.

  • optimize: Specify the optimization level for the compiler (higher numbers = better optimization).

  • workers: How many parallel processes to use for compilation (0 for auto-detect).

  • invalidation_mode: Control how bytecode files are invalidated when source files change.

  • stripdir: Remove a directory prefix from the source file paths.

  • prependdir: Add a directory prefix to the source file paths.

  • limit_sl_dest: Limit the length of symbolic link destinations (useful for avoiding errors on some systems).

  • hardlink_dupes: Use hard links to consolidate duplicate bytecode files with different optimization levels.

Example:

# Compile all `.py` files in 'my_dir', skipping files that end with 'test.py'
compileall.compile_dir('my_dir', rx=re.compile("test\\.py$"))

# Compile all `.py` files in 'my_dir', using 4 parallel processes
compileall.compile_dir('my_dir', workers=4)

# Compile all `.py` files in 'my_dir', using the highest optimization level
compileall.compile_dir('my_dir', optimize=3)

Real-World Applications:

  • Distributing Pre-Compiled Code: Compiling Python files before distributing them can improve performance by avoiding the compilation step on end-user machines.

  • Debugging with Source File Paths: Specifying ddir can help pinpoint the original source file in debugging situations.

  • Managing Multiple Python Versions: legacy mode can be useful when working with different Python versions that have different bytecode formats.

  • Optimizing Performance: Using higher optimize levels can improve the speed of your code (but may also increase compilation time).

  • Parallelizing Compilation: workers can speed up compilation on multi-core machines.


Compile_file Function

The compile_file function in Python's compileall module compiles a Python source file into its corresponding bytecode file.

Parameters:

  • fullname: The path to the source file to be compiled.

  • ddir: Optional directory to be prepended to the file path in compilation time tracebacks and bytecode files.

  • rx: Optional regular expression pattern; if the file path matches, compilation is skipped.

  • quiet: Verbosity level: 0 (default) shows filenames, 1 shows errors only, 2 suppresses all output.

  • legacy: If True, bytecode files are written to legacy locations and names; if False (default), uses PEP 3147 locations and names.

  • optimize: Optimization level for the compiler; can be a single level or a sequence, leading to multiple compilations.

  • invalidation_mode: Controls how generated bytecode files are invalidated at runtime.

  • stripdir: Optional directory to strip from the source file path when generating the bytecode file name.

  • prependdir: Optional directory to prepend to the source file path when generating the bytecode file name.

  • limit_sl_dest: Optional maximum size for the bytecode file destination directory.

  • hardlink_dupes: If True, hard links are used to consolidate duplicate bytecode files with different optimization levels.

Example:

import compileall

# Compile a single file
compileall.compile_file("/path/to/source.py")

# Compile a directory with specific optimization levels
compileall.compile_dir("/path/to/directory", optimize=(1, 3))

# Suppress compilation output
compileall.compile_dir("/path/to/directory", quiet=2)

Real-World Applications:

  • Compiling Python source code for faster execution as bytecode.

  • Creating custom bytecode files for modified or extended Python modules.

  • Generating pre-compiled bytecode for distribution with applications.

  • Maintaining bytecode files for compatibility with different versions of Python.


compileall Module

The compileall module in Python allows you to byte-compile all the Python files found in your system's search path.

compile_path Function

The compile_path function compiles all the .py files along the search paths specified in sys.path. It returns True if all files are compiled successfully and False otherwise.

Parameters:

  • skip_curdir: If True (default), the current directory is ignored.

  • maxlevels: Maximum depth to search subdirectories. Default is 0, which means no limits.

  • force: If True, forces recompilation of all files, even if they are up-to-date.

  • quiet: Controls the verbosity of output. Higher values suppress more output.

  • legacy: Use the old bytecode format. Default is False.

  • optimize: Optimization level for compiled bytecode. Default is -1, which uses the default level set in sys.flags.optimize.

  • invalidation_mode: Controls invalidation of up-to-date .pyc files. Default is None, which uses the default invalidated mode set in sys.flags.invalidation (currently "timestamp").

Usage:

To compile all .py files in your system's search path:

import compileall

compileall.compile_path()

Real-World Applications:

  • Speeding up Python code: Byte-compiled Python code (.pyc files) loads faster than source code because the Python interpreter doesn't need to parse and compile it every time.

  • Cross-platform compatibility: Byte-compiled code is specific to the platform on which it was compiled. This ensures that Python code runs correctly on different systems.

Example:

Suppose you have the following Python file hello.py:

print("Hello, world!")

To compile it into bytecode:

import compileall

compileall.compile_dir('.', force=True)

This will create a hello.pyc file in the current directory. When you run the Python interpreter with python3 hello.pyc, it will execute the compiled bytecode directly.


Simplifying Compileall Module:

Concept: Compileall is a Python module that helps you compile all the .py files in a directory and its subdirectories into .pyc files, which are bytecode files that run faster than source code.

Main Function: compile_dir

Simplified Explanation: compile_dir is the main function of the compileall module. It takes a directory as input and compiles all the .py files in it and its subdirectories.

Parameters:

  • dir: The directory containing the Python files you want to compile.

  • force: If True, all files will be recompiled, even if they already have .pyc files.

  • maxlevels: The maximum number of subdirectories to search. Default is 0, which means all subdirectories will be searched.

  • rx: A regular expression that matches files to exclude from compilation.

  • legacy: If True, only .pyc files will be generated, not .pyo files.

  • optimize: Controls the optimization level for generated .pyc files. 0 for no optimization, 1 for basic optimization, 2 for maximum optimization.

  • invalidation_mode: Specifies how to invalidate .pyc files during recompilation. Default is None, which means to trust file timestamps.

Usage:

import compileall

# Compile all Python files in the 'Lib' directory
compileall.compile_dir('Lib/', force=True)

# Compile all Python files in the 'Lib' directory, excluding files in '.svn' directories
import re
compileall.compile_dir('Lib/', rx=re.compile(r'[/\][.]svn'), force=True)

Real-World Applications:

  • Faster Startup: Precompiling Python files into .pyc files can speed up the startup time of your application.

  • Debugging: If you're debugging a Python program, it can be helpful to compile the source files into .pyc files to make the debugging process faster.

  • Distribution: When distributing Python code, it's often a good practice to include .pyc files instead of source code for better performance.

Tips:

  • Use the force parameter to recompile all files, even if they already have .pyc files.

  • Use the rx parameter to exclude specific files or directories from compilation.

  • Set the optimize parameter to 2 for maximum optimization, but note that this may increase compilation time.

  • Set the invalidation_mode parameter to a value other than None to control how .pyc files are invalidated during recompilation.