compileall - Compilazione in Byte-code di File Sorgente

Scopo: Converte i file sorgente nella versione compilata byte-code

Il modulo compileall cerca file sorgente Python e li compila nella rappresentazione byte-code, salvando il risultato in file con estensione .pyc.

Compilare Una Directory

compile_dir() viene usato per scorrere ricorsivamente una directory e compilare in byte-code i file sorgente Python in essa contenuti.

# compileall_compile_dir.py

import compileall
import glob


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


show('Prima')

compileall.compile_dir('esempi')

show('\nDopo')

Nella modalità predefinita, vengono esaminate tutte le sottodirectory fino ad una profondità di 10. I file in uscita sono scritti nella directory __pycache__ e nominati in base alla versione dell'interprete Python.

$ python3 compileall_compile_dir.py

Prima
  esempi/
  esempi/README
  esempi/subdir
  esempi/subdir/b.py
  esempi/subdir/__pycache__
  esempi/subdir/__pycache__/b.cpython-38.pyc
  esempi/__pycache__
  esempi/__pycache__/a.cpython-36.pyc
  esempi/__pycache__/a.cpython-38.pyc
  esempi/a.py

Listing 'esempi'...
Listing 'esempi/subdir'...

Dopo
  esempi/
  esempi/README
  esempi/subdir
  esempi/subdir/b.py
  esempi/subdir/__pycache__
  esempi/subdir/__pycache__/b.cpython-38.pyc
  esempi/__pycache__
  esempi/__pycache__/a.cpython-36.pyc
  esempi/__pycache__/a.cpython-38.pyc
  esempi/a.py

Ignorare i File

Per escludere delle directory, si usi l'argomento rx per fornire una espressione regolare per trovare corrispondenza con i nomi da escludere.

# compileall_exclude_dirs.py

import compileall
import re

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

Questa versione esclude i file nella sottodirectory subdir.

$ python3 compileall_exclude_dirs.py

Listing 'esempi'...
Listing 'esempi/subdir'...

L'argomento maxlevels controlla la profondità della ricorsione. Ad esempio, per evitare interamente la ricorsione si passi 0.

# compileall_recursion_depth.py

import compileall
import re

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

Solo i file contenuti nelle directory passate a compile_dir() sono compilati.

$ python3 compileall_recursion_depth.py

Listing 'esempi'...

Compilare sys.path

Tutti i file sorgente di Python che si trovano in sys.path possono essere compilati con una singola chiamata a compile_path().

# compileall_path.py

import compileall
import sys

sys.path[:] = ['esempi', 'nonqui']
print('sys.path =', sys.path)
compileall.compile_path()

Questo esempio sostituisce il contenuto predefinito di sys.path per evitare errori sui permessi quando si esegue lo script, ma è ancora valido per illustrare il comportamento predefinito. Si noti che il valore predefinito di maxlevels è 0.

$ python3 compileall_path.py

sys.path = ['esempi', 'nonqui']
Listing 'esempi'...
Listing 'nonqui'...
Can't list 'nonqui'

Compilare File Singoli

Per compilare un singolo file, invece tutti i file contenuti in una directory, si utilizzi compile_file().

# compileall_compile_file.py

import compileall
import glob


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


show('Prima')

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

show('\nDopo')

Il primo argomento dovrebbe essere il nome del file, rappresentato dal percorso completo oppure dal percorso relativo.

$ python3 compileall_compile_file.py

Prima
  esempi/
  esempi/README
  esempi/subdir
  esempi/subdir/b.py
  esempi/subdir/__pycache__
  esempi/subdir/__pycache__/b.cpython-38.pyc
  esempi/__pycache__
  esempi/__pycache__/a.cpython-36.pyc
  esempi/__pycache__/a.cpython-38.pyc
  esempi/a.py


Dopo
  esempi/
  esempi/README
  esempi/subdir
  esempi/subdir/b.py
  esempi/subdir/__pycache__
  esempi/subdir/__pycache__/b.cpython-38.pyc
  esempi/__pycache__
  esempi/__pycache__/a.cpython-36.pyc
  esempi/__pycache__/a.cpython-38.pyc
  esempi/a.py

Da Riga di Comando

E' anche possibile chiamare compileall da riga di comando, in modo che possa essere integrato con un sistema di compilazione tramite un Makefile. Ad esempio:

$ python3 -m compileall -h

usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d DESTDIR]
                     [-x REGEXP] [-i FILE] [-j WORKERS]
                     [--invalidation-mode {checked-hash,timestamp,unchecked-hash}]
                     [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
  --invalidation-mode {checked-hash,timestamp,unchecked-hash}
                        set .pyc invalidation mode; defaults to "checked-hash"
                        if the SOURCE_DATE_EPOCH environment variable is set,
                        and "timestamp" otherwise.

Per ricreare l'esempio precedente, ignorando la sottodirectory subdir, si esegue.

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

Listing 'esempi'...
Listing 'esempi/subdir'...

Vedere anche:

compileall
La documentazione della libreria standard per questo modulo.