compileall — Byte-compilar archivos fuente

Propósito:Convierte los archivos fuente a la versión compilada por bytes.

El módulo compileall encuentra los archivos fuente de Python y los compila en la representación de código de bytes, guardando los resultados en .pyc.

Compilar un directorio

compile_dir() se usa para escanear recursivamente un directorio y compilar en bytes los archivos que contiene.

compileall_compile_dir.py
import compileall
import glob


def show(title):
    print(title)
    for filename in glob.glob('examples/**',
                              recursive=True):
        print('  {}'.format(filename))
    print()


show('Before')

compileall.compile_dir('examples')

show('\nAfter')

Por defecto, todos los subdirectorios se escanean a una profundidad de 10. Los archivos de salida se escriben en un directorio __pycache__ y se nombran según la versión del intérprete de Python.

$ python3 compileall_compile_dir.py

Before
  examples/
  examples/README
  examples/a.py
  examples/subdir
  examples/subdir/b.py

Listing 'examples'...
Compiling 'examples/a.py'...
Listing 'examples/subdir'...
Compiling 'examples/subdir/b.py'...

After
  examples/
  examples/README
  examples/a.py
  examples/subdir
  examples/subdir/__pycache__
  examples/subdir/__pycache__/b.cpython-36.pyc
  examples/subdir/b.py
  examples/__pycache__
  examples/__pycache__/a.cpython-36.pyc

Ignorar archivos

Para filtrar directorios, usa el argumento rx para proporcionar una expresión regular que coincida con los nombres que se excluirán.

compileall_exclude_dirs.py
import compileall
import re

compileall.compile_dir(
    'examples',
    rx=re.compile(r'/subdir'),
)

Esta versión excluye archivos en el subdirectorio subdir.

$ python3 compileall_exclude_dirs.py

Listing 'examples'...
Compiling 'examples/a.py'...
Listing 'examples/subdir'...

El argumento maxlevels controla la profundidad de la recursividad. Por ejemplo, para evitar la recursión completamente pasa 0.

compileall_recursion_depth.py
import compileall
import re

compileall.compile_dir(
    'examples',
    maxlevels=0,
)

Solo se compilan los archivos dentro del directorio pasado a compile_dir().

$ python3 compileall_recursion_depth.py

Listing 'examples'...
Compiling 'examples/a.py'...

Compilar sys.path

Todos los archivos fuente de Python encontrados en sys.path pueden compilarse con una sola llamada a compile_path().

compileall_path.py
import compileall
import sys

sys.path[:] = ['examples', 'notthere']
print('sys.path =', sys.path)
compileall.compile_path()

Este ejemplo reemplaza el contenido predeterminado de sys.path para evitar errores de permisos mientras se ejecuta la secuencia de comandos, pero aún ilustra el comportamiento predeterminado. Ten en cuenta que el valor de maxlevels tiene como valor predeterminado 0.

$ python3 compileall_path.py

sys.path = ['examples', 'notthere']
Listing 'examples'...
Compiling 'examples/a.py'...
Listing 'notthere'...
Can't list 'notthere'

Compilar archivos individuales

Para compilar un solo archivo, en lugar de un directorio completo de archivos, usa compile_file().

compileall_compile_file.py
import compileall
import glob


def show(title):
    print(title)
    for filename in glob.glob('examples/**',
                              recursive=True):
        print('  {}'.format(filename))
    print()


show('Before')

compileall.compile_file('examples/a.py')

show('\nAfter')

El primer argumento debe ser el nombre del archivo, ya sea una ruta completa o una ruta relativa.

$ python3 compileall_compile_file.py

Before
  examples/
  examples/README
  examples/a.py
  examples/subdir
  examples/subdir/b.py

Compiling 'examples/a.py'...

After
  examples/
  examples/README
  examples/a.py
  examples/subdir
  examples/subdir/b.py
  examples/__pycache__
  examples/__pycache__/a.cpython-36.pyc

Desde la línea de comando

También es posible invocar compileall desde la línea de comandos, por lo que puede integrarse con un sistema de compilación a través de un Makefile. Por ejemplo:

$ python3 -m compileall -h

usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d
DESTDIR]
                     [-x REGEXP] [-i FILE] [-j WORKERS]
                     [FILE|DIR [FILE|DIR ...]]

Utilities to support installing Python libraries.

positional arguments:
  FILE|DIR              zero or more file and directory names to
compile; if
                        no arguments given, defaults to the
equivalent of -l
                        sys.path

optional arguments:
  -h, --help            show this help message and exit
  -l                    don't recurse into subdirectories
  -r RECURSION          control the maximum recursion level. if
`-l` and `-r`
                        options are specified, then `-r` takes
precedence.
  -f                    force rebuild even if timestamps are up
to date
  -q                    output only error messages; -qq will
suppress the
                        error messages as well.
  -b                    use legacy (pre-PEP3147) compiled file
locations
  -d DESTDIR            directory to prepend to file paths for
use in compile-
                        time tracebacks and in runtime
tracebacks in cases
                        where the source file is unavailable
  -x REGEXP             skip files matching the regular
expression; the regexp
                        is searched for in the full path of each
file
                        considered for compilation
  -i FILE               add all the files and directories listed
in FILE to
                        the list considered for compilation; if
"-", names are
                        read from stdin
  -j WORKERS, --workers WORKERS
                        Run compileall concurrently

Para recrear el ejemplo anterior, omitiendo el directorio subdir, ejecuta:

$ python3 -m compileall -x '/subdir' examples

Listing 'examples'...
Compiling 'examples/a.py'...
Listing 'examples/subdir'...