py_compile en Python: compila un archivo

Publicado el: 27/08/2026
Tempo de leitura: 6 minutos
Person sorting documents in folders outdoors, hands visible, neutral tone.

El módulo py_compile compila un archivo fuente Python individual en bytecode .pyc. Es la herramienta directa para editores, builds incrementales, instaladores, generadores y validadores que necesitan controlar un archivo en lugar de procesar un árbol completo.

La API permite elegir el destino, definir el filename lógico mostrado en tracebacks, seleccionar optimización y configurar cómo se invalida el cache. Para directorios completos, compileall suele ser más cómodo; para flujos archivo por archivo, py_compile ofrece precisión.

Compila un archivo fuente

La función principal es py_compile.compile().

import py_compile

ruta_pyc = py_compile.compile(
    "modulo.py",
    doraise=True,
)
print(ruta_pyc)

Cuando termina correctamente, devuelve la ruta del bytecode generado.

Usa doraise en automatización

Con doraise=True, los fallos generan PyCompileError.

try:
    py_compile.compile("modulo.py", doraise=True)
except py_compile.PyCompileError as error:
    print(error)

Este comportamiento es claro para CI, editores, generadores y package builders porque el caller puede detener el proceso y registrar un error estructurado.

Comportamiento sin doraise

Con doraise=False, el módulo puede imprimir la información en stderr en lugar de lanzar directamente.

No ignores el retorno. Un archivo .pyc antiguo puede permanecer después de un fallo y no demuestra que la fuente actual sea válida.

Detalles de PyCompileError

La excepción conserva información sobre el error original y una representación formateada.

Un diagnóstico debería mantener filename, línea, columna y tipo. Puedes recuperar un fragmento con linecache en Python.

Destino predeterminado

Sin cfile, Python calcula el path normal bajo __pycache__.

__pycache__/modulo.cpython-314.pyc

La tag permite que varias versiones y optimizaciones coexistan.

Elige cfile

El parámetro cfile selecciona un destino específico.

py_compile.compile(
    "src/modulo.py",
    cfile="build/modulo.pyc",
    doraise=True,
)

Crea el directorio padre y confirma que pertenece al workspace del build.

Protege los destinos

El módulo verifica determinados casos de sustitución insegura, incluidos enlaces simbólicos y archivos no regulares en situaciones relevantes.

Aun así, valida siempre el destino, resuélvelo contra una raíz aprobada y no aceptes rutas arbitrarias.

Escritura atómica

Python moderno escribe datos temporales y reemplaza el destino, reduciendo la posibilidad de un cache parcial.

Las garantías dependen del filesystem. Prueba volúmenes de red, mounts de containers y almacenamiento especial.

El parámetro dfile

dfile define el filename lógico guardado en el code object y mostrado en tracebacks.

py_compile.compile(
    "/build/work/modulo.py",
    dfile="/opt/app/modulo.py",
    doraise=True,
)

Así evitas que las rutas del runner aparezcan en producción.

dfile no copia el fuente

El parámetro solo cambia la referencia lógica. No mueve el archivo ni garantiza que exista en destino.

Alinea el valor con el layout final y conserva fuente correspondiente cuando sea necesario depurar.

Selecciona optimización

optimize elige el nivel.

py_compile.compile(
    "modulo.py",
    optimize=1,
    doraise=True,
)

El default sigue la configuración del intérprete actual.

Asserts y docstrings

El nivel 1 elimina asserts y el nivel 2 también puede eliminar docstrings.

Las reglas obligatorias de entrada, autorización y negocio deben usar comprobaciones explícitas que permanezcan activas.

Modos de invalidación

invalidation_mode controla cómo el sistema de importación decide si el bytecode todavía coincide con el fuente.

py_compile.compile(
    "modulo.py",
    doraise=True,
    invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH,
)

TIMESTAMP

TIMESTAMP registra metadatos como modificación y tamaño.

Es eficiente y común, aunque los artefactos reproducibles pueden preferir hash.

CHECKED_HASH

CHECKED_HASH guarda un hash del fuente y solicita verificación durante la importación.

Ofrece una relación más fuerte entre contenido y cache, con lectura adicional según la política.

UNCHECKED_HASH

UNCHECKED_HASH guarda el hash y permite que un entorno gestionado trate el artefacto como validado previamente.

Úsalo en sistemas de build confiables que controlan instalación y actualización.

SOURCE_DATE_EPOCH

Los builds reproducibles pueden definir SOURCE_DATE_EPOCH, influyendo en defaults de invalidación.

Cuando la política forme parte del contrato, establece el modo explícitamente.

Compilar no ejecuta

El compilador analiza y genera bytecode sin ejecutar imports, decorators, llamadas de módulo o inicialización de clases.

Un archivo puede compilar y fallar al importar por dependencia ausente o error de runtime.

Validación incremental

Un editor puede compilar únicamente el documento guardado.

def validar(ruta):
    try:
        py_compile.compile(ruta, doraise=True)
    except py_compile.PyCompileError as error:
        return False, str(error)
    return True, None

Detecta sintaxis rápidamente, pero no reemplaza language server, linter o type checker.

Valida código generado

Los generadores pueden compilar la salida para confirmar que un template produjo Python válido.

Una secuencia fiable es escribir atómicamente, compilar y publicar el paquete solo después del éxito.

Encoding de fuente

El compilador sigue las reglas de encoding Python. Declaraciones inválidas o bytes incompatibles generan errores.

Usa tokenize.open() para inspección y consulta tokenize en Python.

Paths privados y útiles

Las rutas absolutas pueden revelar usuarios, directorios de CI e infraestructura.

Usa dfile para crear paths estables de producción sin perder información de diagnóstico.

Uso por CLI

El módulo compila archivos desde la línea de comandos.

python -m py_compile modulo.py otro.py

Comprueba el exit status en CI y consulta la ayuda de la versión activa.

Varios archivos

La función Python procesa uno por vez. Para un árbol, usa compileall en Python.

Los sistemas incrementales pueden mantener una queue limitada y asociar cada resultado con la revisión del fuente.

Compilación paralela

Los archivos independientes pueden compilarse concurrentemente, pero dos workers no deben escribir el mismo destino.

Genera paths determinísticos, elimina duplicados y limita concurrencia según el storage.

Cambios durante la tarea

La fuente puede cambiar entre programación y publicación. Un editor debería comparar hash o versión del documento.

Si ya cambió, descarta el resultado antiguo y compila la versión nueva.

Directorios read-only

Si el destino predeterminado no puede crearse, compila durante el build o elige un área con permiso.

El servicio de producción no debería necesitar root para crear __pycache__.

Compatibilidad de versión

El bytecode está ligado a implementación y versión major/minor. Un magic number evita muchos usos incompatibles.

Compila con el mismo intérprete que ejecutará la aplicación.

El bytecode no protege el fuente

Las herramientas inspeccionan nombres, constantes e instrucciones.

Mantén secretos fuera del código y no uses .pyc como ofuscación fuerte.

Prueba la importación

Después de compilar, importa el módulo en el entorno final.

python -c "import modulo"

Esto detecta dependencias e inicialización que la compilación no ve.

Artefactos huérfanos

Al eliminar fuentes pueden quedar caches antiguos. Un build limpio evita que módulos borrados sobrevivan en el paquete.

No mezcles caches de commits, versiones u optimizaciones diferentes sin layout intencional.

Control de paths

Valida fuente, destino, directorios padre y symlinks. Mantén toda compilación dentro del workspace.

Un servicio público debería usar worker y directorio temporal aislados.

Límites de recursos

Fuentes enormes o profundamente anidadas consumen CPU y memoria. Limita tamaño, jobs concurrentes y tiempo total.

Procesa uploads fuera del proceso principal de requests.

Observabilidad

Registra filename lógico, duración, tamaño, versión de Python, optimización, invalidación y resultado.

Evita guardar todo el fuente; un fragmento de diagnóstico suele bastar.

Pruebas

Cubre código válido, SyntaxError, encoding inválido, destino custom, dfile, modos de invalidación, optimización, permisos, symlink y cambios durante la tarea.

Verifica el path generado y el filename del traceback.

Errores comunes

Los fallos frecuentes son omitir doraise=True, ignorar el retorno, escribir en un destino no validado, compilar con otra versión, depender de asserts, confundir dfile con copia y dejar caches antiguos.

Conclusión

py_compile ofrece control preciso sobre la compilación de un archivo. Usa doraise=True, elige cfile y dfile seguros, define optimización e invalidación según el build y prueba la importación final.

Usa compileall para árboles completos. Consulta la documentación oficial de py_compile y dis en Python para inspeccionar el bytecode.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Colorful stacked shipping containers at Hamburg port, showcasing global trade and logistics.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    modulefinder en Python: descubre imports

    Aprende modulefinder en Python para descubrir imports, dependencias transitivas, módulos ausentes, paths, plugins y límites del análisis estático.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compileall en Python: genera bytecode .pyc

    Aprende compileall en Python para generar .pyc, validar sintaxis, compilar en paralelo y controlar optimización, paths y builds reproducibles.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    Vivid close-up of code on a computer screen showcasing programming details.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    codeop en Python: compila entrada interactiva

    Aprende codeop en Python para detectar comandos completos, incompletos o inválidos, crear REPLs y conservar flags de __future__ de forma

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    A close-up shot showcasing the intricate scales of a snake, highlighting texture and color.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    linecache en Python: lee líneas del código

    Aprende linecache en Python para recuperar líneas de código, actualizar cache, soportar tracebacks y loaders, conservar indentación y proteger rutas.

    Ler mais

    Tempo de leitura: 8 minutos
    27/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    faulthandler en Python: diagnostica fallos

    Aprende faulthandler en Python para diagnosticar crashes, deadlocks, señales fatales, timeouts y bloqueos con dumps de todas las threads.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026
    A detailed image of a reticulated python showcasing its patterned scales and intricate skin texture.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    symtable en Python: analiza scopes

    Aprende symtable en Python para analizar scopes, locals, globals, parámetros, imports, nonlocals, closures y namespaces del compilador.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026