Programación en la Práctica09/09/2026Redação de Tecnologia e Desenvolvimento10 min de lecturaActualizado el 15/09/2026

Python 3.15: APIs eliminadas que pueden romper extensiones y checklist de portabilidad antes del 1 de octubre

Consulta qué APIs de Python y C se eliminaron en 3.15, qué sustitutos usar y cómo probar extensiones y código antes del lanzamiento final previsto para el 1 de octubre.

Estação de desenvolvimento com símbolo do Python ao centro, erros em vermelho à esquerda e verificações de compatibilidade em verde à direita.

Python 3.15.0rc2 se publicó el 1 de septiembre de 2026 como el último candidato de lanzamiento previsto, y Python 3.15.0 final está programado para el 1 de octubre. A partir de la fase de release candidate, el proyecto indica que no habrá más cambios de ABI en la serie 3.15 y que los cambios de código deberían limitarse a correcciones claras de errores. Para quienes mantienen bibliotecas o extensiones nativas, esto convierte a RC2 en la mejor ventana para detectar incompatibilidades antes de la versión final.

El riesgo no se limita a si el código compila o no. Hay símbolos eliminados de la C API, APIs de Python que desaparecieron o se volvieron más estrictas y cambios de comportamiento capaces de romper pruebas sin provocar un error de importación. La guía siguiente separa esos tres grupos y, para cada elemento con impacto de portabilidad, indica la migración recomendada y una prueba mínima.

RC2 es la ventana de pruebas que importa

RC2 del 1 de septiembre es el último candidato de lanzamiento previsto. El calendario oficial mantiene Python 3.15.0 final para el 1 de octubre de 2026. La página de RC2 también afirma que no habrá cambios de ABI a partir de este punto en la serie 3.15, con el objetivo general de reducir al mínimo los cambios de código. Eso no convierte a RC2 en una versión recomendada para producción, pero hace que sus resultados de compatibilidad sean especialmente útiles.

El foco aquí es la portabilidad del código y de las extensiones, no el empaquetado de wheels. La prueba esencial es ejecutar la suite en 3.15 RC2 y, cuando haya C o C++, recompilar la extensión desde el código fuente contra los headers de 3.15.

APIs de Python eliminadas o endurecidas

ÁreaQué cambia en 3.15Sustituto o ajustePrueba mínima
astLos constructores de nodos AST ahora lanzan TypeError cuando faltan campos obligatorios o se pasan nombres que no corresponden a campos válidos.Instancia el nodo con todos los campos obligatorios y solo argumentos documentados.Ejecuta las pruebas que crean o transforman AST y fuerza las rutas de generación de código.
collections.abc.ByteStringByteString salió de collections.abc.__all__; el símbolo sigue obsoleto y está previsto que se elimine en 3.17.Para el protocolo de buffer en runtime, usa collections.abc.Buffer; para tipos, usa Buffer o una unión explícita como bytes | bytearray | memoryview.Prueba imports explícitos y cualquier import con asterisco que esperaba recibir ByteString.
ctypes.SetPointerType()La función no documentada fue eliminada.No hay sustituto 1:1 documentado; prefiere APIs públicas de punteros, como ctypes.POINTER(T), y elimina la dependencia de detalles internos.Importa el módulo que construye tipos ctypes y ejercita creación, lectura y escritura de los punteros usados por la biblioteca.
datetime.strptime()Un formato con %d sin una directiva de año ahora puede lanzar ValueError.Incluye el año tanto en la entrada como en la cadena de formato cuando se analice el día del mes.Añade un caso con el formato antiguo y confirma que la entrada real ahora incluye año.
glob.glob0()/glob.glob1()Las funciones internas no documentadas fueron eliminadas.Usa glob.glob() y pasa root_dir cuando necesites limitar la búsqueda a un directorio.Compara el conjunto de rutas devuelto antes y después de la migración en un árbol temporal.
http.server CGICGIHTTPRequestHandler y la opción --cgi de python -m http.server fueron eliminados.No existe un sustituto CGI 1:1 en la biblioteca estándar; elimina esa dependencia y ejecuta la aplicación con una solución de servidor adecuada.Haz un smoke test del comando de desarrollo o integración que antes iniciaba el modo CGI.
loaders de importlibLoader.load_module() y sus implementaciones correspondientes fueron eliminados del protocolo usado por el sistema de importación.Implementa exec_module(); cuando sea necesario, implementa también create_module() según el protocolo moderno.Instala el finder/loader personalizado en sys.meta_path o sys.path_hooks e importa/recarga un módulo real.
importlib.resources.files()Se eliminó el parámetro nombrado package.Pasa anchor, preferiblemente de forma posicional. Para una interfaz compatible con Pythons antiguos, la documentación sugiere importlib_resources >= 5.10.Lee un recurso de paquete usando exactamente la llamada utilizada en producción.
pathlib.PurePath.is_reserved()El método fue eliminado.Usa os.path.isreserved().Prueba nombres reservados y nombres comunes, especialmente en Windows.
platform.java_ver()La función fue eliminada; estaba orientada al soporte de Jython y tenía una API considerada confusa y poco probada.No hay sustituto directo en CPython; elimina la dependencia u obtén los datos del runtime Java desde la plataforma que realmente los proporciona.Busca llamadas y ejecuta la inicialización en cualquier entorno Java/Jython que el proyecto todavía soporte.
sre_compile, sre_constants, sre_parseLos módulos internos sre_* fueron eliminados.Migra a APIs públicas de re, como re.compile(), Pattern y funciones documentadas. No trates la estructura interna del parser como un contrato estable.Ejecuta pruebas de compilación e introspección de expresiones regulares que importaban sre_* directamente.
sysconfig.is_python_build(check_home=...)Se eliminó el parámetro check_home.Llama a sysconfig.is_python_build() sin ese argumento y ajusta la lógica del llamador si dependía del comportamiento anterior.Prueba la detección en un árbol de build y en una instalación normal.
threading.RLock()La implementación en C ya no acepta argumentos posicionales o nombrados arbitrarios que antes se ignoraban.Instancia RLock() sin argumentos.Busca RLock( en fábricas y wrappers y ejecuta la ruta que crea cada lock.
types.CodeType.co_lnotabEl atributo co_lnotab fue eliminado.Usa code.co_lines() para mapear rangos de bytecode a líneas; usa APIs documentadas de posición cuando necesites datos más ricos.Ejecuta profilers, tracers, coverage o herramientas de inspección que lean metadatos de objetos de código.
typing.ByteStringByteString salió de typing.__all__; sigue obsoleto y está previsto que se elimine en 3.17.Usa collections.abc.Buffer o tipos explícitos adecuados al contrato de la función.Prueba imports con asterisco y ejecuta el comprobador de tipos usado por el proyecto.
typing.NamedTupleLa sintaxis no documentada NamedTuple("Point", x=int, y=int) dejó de aceptarse.Usa la sintaxis basada en clase o la sintaxis funcional documentada.Importa todos los módulos que definen NamedTuple en runtime e instancia cada tipo.
typing.TypedDictTypedDict("TD") y TypedDict("TD", None) para cero campos ya no se aceptan.Usa class TD(TypedDict): pass o TypedDict("TD", {}).Importa los módulos de tipos en runtime y ejecuta el type checker para confirmar equivalencia.
typing.no_type_check_decoratorEl decorador fue eliminado.Cuando sea realmente necesario, aplica typing.no_type_check directamente a la función o clase cuyas anotaciones deban ignorarse.Busca el nombre eliminado y ejecuta tanto el import como la comprobación estática del módulo migrado.
wave getmark()/setmark()/getmarkers()Los métodos de compatibilidad con el antiguo módulo aifc fueron eliminados.No hay sustituto equivalente; elimina las llamadas que dependían de esos marcadores.Lee y escribe un WAV representativo y confirma que ninguna ruta llama a los métodos eliminados.
zipimport.zipimporter.load_module()El método fue eliminado.Usa exec_module() en el flujo moderno de importación.Crea un ZIP de prueba con un módulo y valida importación y recarga mediante el loader usado por el proyecto.

C API: símbolos que dejarán de compilar

En extensiones C/C++, la primera señal suele ser un error del compilador o del enlazador. Las eliminaciones siguientes están documentadas en “What’s New” de 3.15. En sustitutos que devuelven objetos, revisa también las reglas de ownership de referencias: por ejemplo, PyWeakref_GetRef() entrega una nueva referencia fuerte cuando el objetivo sigue vivo.

API eliminadaSustituto oficialPrueba mínima
PyUnicode_AsDecodedObject() / PyUnicode_AsDecodedUnicode()PyCodec_Decode().Compila desde cero y prueba al menos un codec textual y cualquier codec que pueda devolver bytes.
PyUnicode_AsEncodedObject() / PyUnicode_AsEncodedUnicode()PyCodec_Encode().Compila desde cero y valida el tipo devuelto para los codecs usados por la extensión.
PyImport_ImportModuleNoBlock()PyImport_ImportModule().Importa el módulo dependiente durante la inicialización normal de la extensión y confirma la propagación de errores.
PyWeakref_GetObject() / PyWeakref_GET_OBJECTPyWeakref_GetRef(). Para Pythons antiguos, la documentación apunta a pythoncapi-compat.Prueba un weakref vivo, uno muerto y la ruta de error, comprobando INCREF/DECREF de la nueva referencia.
PySys_ResetWarnOptions()Limpia sys.warnoptions y warnings.filters, según la orientación oficial.Configura filtros, invoca la rutina migrada y confirma el estado final y los warnings emitidos.
Py_GetExecPrefix()PyConfig_Get("base_exec_prefix"); usa "exec_prefix" cuando deba reflejarse un entorno virtual.Compara con sys.base_exec_prefix y sys.exec_prefix en una instalación normal y en un venv.
Py_GetPath()PyConfig_Get("module_search_paths").Compara la lista con sys.path después de inicializar el intérprete.
Py_GetPrefix()PyConfig_Get("base_prefix"); usa "prefix" para reflejar un venv.Compara con sys.base_prefix y sys.prefix dentro y fuera de un venv.
Py_GetProgramFullPath() / Py_GetProgramName()PyConfig_Get("executable").Valida la ruta en un ejecutable que embebe Python y en el intérprete estándar.
Py_GetPythonHome()PyConfig_Get("home") o la variable de entorno PYTHONHOME.Prueba con y sin PYTHONHOME y confirma el valor después de la inicialización.

PyConfig_Get() es una API de configuración en runtime: su documentación exige un thread state adjunto y dice que no puede llamarse antes de la inicialización de Python ni después de la finalización. Si un embedder usaba los antiguos Py_Get* antes de inicializar Python, la migración debe revisar la fase de configuración con las APIs modernas de inicialización, no limitarse a sustituir el nombre de la función.

Dos cambios de C API que también merecen búsqueda estática

  • Si un tipo define Py_TPFLAGS_MANAGED_DICT o Py_TPFLAGS_MANAGED_WEAKREF, también debe definir Py_TPFLAGS_HAVE_GC. Añade una prueba que cree, referencie, recolecte y destruya instancias del tipo.
  • PyDateTime_IMPORT ahora es thread-safe. El código que comprobaba PyDateTimeAPI directamente contra NULL debe llamar a PyDateTime_IMPORT. Ejercita el import y el uso de la DateTime C API en la ruta real de la extensión.

Cambios de comportamiento que pueden romper pruebas

ÁreaCambioCómo probarlo
sqlite3En sqlite3.connect(), todos los parámetros excepto database ahora son keyword-only; en create_function() y create_aggregate(), los tres primeros son positional-only; set_authorizer(), set_progress_handler() y set_trace_callback() también endurecieron la posición de su primer argumento.Ejecuta pruebas que creen conexiones y registren callbacks usando exactamente las firmas públicas expuestas por el proyecto.
resourceresource.RLIM_INFINITY ahora siempre es positivo; los enteros negativos que coincidían con su valor antiguo quedan obsoletos.Compara límites leídos y escritos en cada plataforma soportada y deja de guardar -1/-3 como sentinelas portables.
mmapmmap.mmap.resize() ahora está ausente en plataformas sin soporte para la llamada de sistema subyacente, en vez de existir y lanzar SystemError.Usa hasattr() en la plataforma objetivo y prueba el fallback de la aplicación cuando resize no esté disponible.
ElementTree.iterparse()Un iterador que abrió un archivo y no se cierra puede emitir ResourceWarning.Ejecuta pruebas tratando warnings como errores y cierra el iterador explícitamente con close() o contextlib.closing().
argparseCon una opción corta y una opción larga de un solo guion, como -f y -foo, dest ahora se infiere de -foo.Comprueba el Namespace final; si necesitas el comportamiento anterior, pasa dest de forma explícita.
base64urlsafe_b64decode() ya no exige padding en la entrada.Prueba entradas con y sin padding; si el producto lo exige, usa padded=True o b64decode(..., altchars=b'-_').
unittestassertWarns() y assertWarnsRegex() ya no descartan warnings que no coinciden, por lo que avisos antes ocultos pueden salir del bloque.Ejecuta la suite con filtros de warnings más estrictos y gestiona de forma explícita cada warning esperado.
Extensiones nativas y frame pointersCPython ahora se compila con frame pointers activados por defecto. Las bibliotecas nativas con builds personalizados deben mantener intacta la cadena de unwinding.En builds propios, usa flags equivalentes a los documentados por CPython y valida backtraces/crash handlers en una build 3.15.

Checklist de portabilidad antes del 1 de octubre

  1. Haz una búsqueda estática de los nombres eliminados. Incluye sre_, load_module, co_lnotab, package= en importlib.resources.files, Py_Get*, PyWeakref_GetObject y las funciones PyUnicode eliminadas.
  2. Ejecuta la suite en Python 3.15 RC2. Activa también DeprecationWarning en CI para detectar trabajo que todavía no rompe 3.15 pero ya anticipa cambios para 3.16–3.20.
  3. Recompila las extensiones C/C++ desde un árbol limpio. No reutilices objetos compilados con headers antiguos; el objetivo es que el compilador revele referencias eliminadas.
  4. Mantén un smoke test de importación. Importa todos los módulos públicos y los opcionales que cargan bibliotecas nativas, loaders personalizados, ctypes o recursos de paquetes.
  5. Prueba contratos, no solo excepciones. Verifica tipos devueltos por codecs, ownership de referencias C, valores de argparse.Namespace, callbacks sqlite3 y comportamiento de warnings.
  6. Prueba venv y embedding por separado al usar PyConfig. base_prefix/prefix y base_exec_prefix/exec_prefix no son equivalentes cuando hay un entorno virtual activo.
  7. Registra el baseline de RC2. Como la ABI no debería cambiar entre RC2 y 3.15 final, una suite verde y una compilación limpia ahora reducen de forma importante el riesgo de la migración del 1 de octubre, aunque aún puedan entrar correcciones de errores.

Separa roturas actuales de avisos futuros

Una eliminación efectiva debe corregirse para que el proyecto funcione en 3.15. Una nueva deprecación, en cambio, puede no romper hoy, pero conviene incorporarla al backlog con su versión prevista de eliminación. Mantener esas categorías separadas evita dos errores comunes: tratar cada warning como una emergencia o, en el extremo opuesto, ignorar los avisos hasta que la API desaparece.

Para bibliotecas con extensiones nativas, mantén dos comprobaciones independientes: compilación contra 3.15 y pruebas funcionales en runtime. Compilar demuestra que los símbolos y firmas usados todavía existen; las pruebas funcionales revelan diferencias de ownership de referencias, inicialización, callbacks y comportamiento de la biblioteca estándar.

Fuentes oficiales

Temas de este artículoC APIcompatibilidade Pythonextensões Cportabilidade PythonPython 3.15