Actualizar Python en z/OS (IBM Open Enterprise SDK for Python)
IBM publica cada pocos meses nuevas versiones del IBM Open Enterprise SDK for Python. Son PTF acumulativas, así que basta con instalar la última: ahora mismo, la 3.14.7.1, del 29 de octubre de 2026.
Vamos a actualizarlo igual que hicimos con Node.js: cada versión en su propio zFS y un enlace current que apunta a la que usamos. Así, si algo falla, volver atrás es cambiar el enlace.
Los cambios de cada versión están en la lista de fixes de IBM.
Qué versión tenemos y dónde está
Desde OMVS (TSO OMVS), comprobamos la versión de Python que tenemos. En este caso, Python 3.14.0.1.
También vemos el directorio: /usr/lpp/IBM/cyp/v3r14/pyz/bin/python3
Y el zFS que usa: PYTHON.V3R14M0.ZFS
python3 -V
which python3
df -kP /usr/lpp/IBM/cyp/v3r14/
Podemos comprobar la lista de paquetes instalados.
pip3 listLos paquetes ibm_db y zoautil_py no los tendremos en la nueva instalación. Más adelante veremos cómo instalarlos en la versión nueva.

Descargar la versión nueva
IBM lo distribuye de dos formas: como producto SMP/E, que se pide por Shopz, o como fichero PAX, que se descarga gratis. Igual que con Node.js, usaremos el PAX. Se descarga desde la página del producto, con el botón «Download now» (pide iniciar sesión con un IBMid), y ocupa unos 250 MB.
Antes de descargarlo, repasamos los requisitos. Aquí van resumidos; el detalle está en la guía de instalación de IBM.
- z/OS 2.5, 3.1 o 3.2 con z/OS UNIX System Services, en una máquina z13 o posterior (hasta z17).
- Unos 660 MB para la instalación y otros 660 MB libres en /tmp. Si /tmp no tiene espacio, podemos usar otro directorio con la variable TMPDIR.
- Que exista /usr/bin/env. Lo veremos en el apartado de variables de entorno.
También hay algunos requisitos opcionales:
- zIIP: Python puede ejecutarse en procesadores zIIP. En z/OS 2.5 hace falta la APAR OA63406.
- Un compilador de C/C++, si vamos a instalar con pip paquetes que incluyen código nativo.
- ICSF, solo si la máquina es un z14.
Comprobamos el espacio libre en /tmp. En este caso tenemos unos 1.000 MB, así que no hace falta usar TMPDIR:
df -kP /tmp
Página del producto: IBM Open Enterprise SDK for Python


Podemos elegir entre Python 3.13 y 3.14. Elegiré la 3.14.
Se descargará con el nombre HAMB3E0.nonsmpe.pax.Z.

Crear un zFS para la versión
Como con Node.js, creamos un zFS para cada versión. Así cada versión queda separada de las demás y, si algo falla, podemos volver a la anterior. El job lo podemos generar con el zFS Generator. La instalación ocupa unos 660 MB y el pax unos 250 MB, así que con 1.300 cilindros (algo más de 1 GB) tenemos margen para los paquetes de pip.
//ZFSNEW JOB (ACCT),'CREATE ZFS',CLASS=A,MSGCLASS=X
//* 1. Mount point
//MKDIR EXEC PGM=BPXBATCH
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*
//STDPARM DD *
SH mkdir -p /u/python/python-v3.14.7.1
/*
//* 2. Define the aggregate (ZFS: EA, formatted at mount)
//DEFINE EXEC PGM=IDCAMS,COND=(0,NE)
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER (NAME(IBMUSER.PYTHON.V3R14M7.ZFS) -
ZFS -
CYLINDERS(1300 0) -
SHAREOPTIONS(3))
/*
//* 3. Mount it
//MOUNT EXEC PGM=IKJEFT01,COND=(0,NE)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
MOUNT FILESYSTEM('IBMUSER.PYTHON.V3R14M7.ZFS') +
MOUNTPOINT('/u/python/python-v3.14.7.1') +
TYPE(ZFS) MODE(RDWR)
/*Submitimos el job.

El job termina correctamente.

Comprobamos que el nuevo zFS está montado.

Subimos el pax por FTP, en modo binario, al directorio /u/python/python-v3.14.7.1.

Descomprimir
Vamos a OMVS y descomprimimos el fichero:
cd /u/python/python-v3.14.7.1
pax -r -ppAx -f HAMB3E0.nonsmpe.pax.Z
ls -l
En el pantallazo anterior, vemos que la carpeta descomprimida es “usr”; esto es debido a que conserva la ruta original “/usr/lpp/IBM/python/v3r14/pyz/”, además del directorio donde nosotros lo subimos.
<path to install dir>/usr/lpp/IBM/python/v3r14/pyz/IBM avisa de esto:
IBM Open Enterprise SDK for Python installation path update
The installation path for the IBM Open Enterprise SDK for Python has been updated. A symbolic link is provided at the previous path to maintain backward compatibility.
Note: The deprecated path and its symbolic link will be removed in future releases.
New path: The updated installation path for the IBM Open Enterprise SDK for Python is: <path_to_python_install>/usr/lpp/IBM/python/v3r14/pyz.
Old path (deprecated): The previous installation path is now deprecated and should no longer be used: <path_to_python_install>/usr/lpp/IBM/cyp/v3r14/pyz.
Symbolic link details: A symbolic link exists to redirect references from the deprecated directory to the updated location: <path_to_python_install>/usr/lpp/IBM/cyp/ → ../python/v3r14.

Según la documentación, si al extraer nos aparece este error, es debido a que el usuario que lo ha extraído no tiene permisos para dar el atributo APF a la librería compartida. Python seguirá funcionando igualmente pero usará el procesador general (CP) en vez de usar zIIP.
Pienso que es importante dar este atributo para que use los procesadores zIIP.
pax: FSUMF073 usr/lpp/IBM/python/v3r14/pyz/lib/python3.14/lib-dynload/libpyzutil.cpython-314.so: user not authorized to restore extended attribute "a"Un usuario que tenga autorización puede dar el atributo APF más adelante:
extattr +a <path_to_python_install>/lib/python3.14/lib-dynload/libpyzutil.cpython-314.soLo comprobamos con el comando:
extattr <path_to_python_install>/lib/python3.14/lib-dynload/libpyzutil.cpython-314.soPor ejemplo:
cd /u/python/python-v3.14.7.1/usr/lpp/IBM/python/v3r14/
extattr pyz/lib/python3.14/lib-dynload/libpyzutil.cpython-314.so
Comprobar la instalación
cd /u/python/python-v3.14.7.1/usr/lpp/IBM/python/v3r14/pyz
./install_test.shSi cumplimos todos los prerrequisitos, veremos el mensaje:
Successfully tested IBM Open Enterprise SDK for Python 3.14.7.1 Si hubiese algún error, aparecerá un mensaje indicando las PTFs que nos faltan.

También debemos comprobar que existe el miembro *.SCEERUN2(CRTEQCXE) en el sistema.
Si está en una ubicación no estándar, debemos añadir la variable de entorno _CC_PLIB_PREFIX.
Ejemplo:
_CC_PLIB_PREFIX=xxxxx
Donde xxxxx es el prefijo (HLQ) de las librerías de Language Environment. Por defecto es CEE.

Variables de entorno
Debemos comprobar que “/usr/bin/env” existe. Si no lo tenemos configurado, hay que seguir las instrucciones:
Customization and environment configuration (IBM Docs)
ls -l /usr/bin/env
A diferencia de Node.js, aquí no hay un setup.sh que nos prepare las variables: las definimos nosotros. Son las que indica la guía de IBM, pero apuntando al enlace /u/python/current, que crearemos en el siguiente paso.
PATH y LIBPATH indican dónde están los programas y las librerías de Python; las otras dos hacen que z/OS convierta automáticamente los ficheros entre EBCDIC y ASCII.
export PATH=/u/python/current/bin:$PATH
export LIBPATH=/u/python/current/lib:$LIBPATH
export _BPXK_AUTOCVT='ON'
export _CEE_RUNOPTS='FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)'Las añadimos al final del .profile de nuestro HOME, para que se carguen cada vez que entremos en OMVS. Si no existe, lo creamos.
Desde TSO ISHELL, ponemos el nombre del fichero y pulsamos ENTER para crearlo:
/u/ibmuser/.profile

Desde la opción 3.4 de ISPF, buscamos la ruta “/u/ibmuser” y editamos el fichero “.profile”.


En la stock image, _BPXK_AUTOCVT y _CEE_RUNOPTS ya las define /etc/profile, así que en nuestro .profile solo hacen falta PATH y LIBPATH. El /etc/profile también añade el Python del sistema al final del PATH:
PATH=$PATH:/usr/lpp/IBM/cyp/v3r14/pyz/binEl /etc/profile se lee antes que nuestro .profile. Como nosotros ponemos /u/python/current/bin delante, nuestro python3 tiene preferencia, y el resto de usuarios sigue usando el del sistema.

Cambiar a la versión nueva
Desde OMVS, creamos el enlace current apuntando a la versión nueva. Si ya existe, lo borramos antes:
cd /u/python
rm -f current # only if it already exists
ln -s python-v3.14.7.1/usr/lpp/IBM/python/v3r14/pyz current
ls -l current
Como las variables usan /u/python/current y no la ruta de cada versión, cambiar de versión es solo cambiar el enlace.
Cerramos la sesión de OMVS y abrimos otra para que se cargue el .profile. Comprobamos la versión de Python, la de pip y la de OpenSSL:
python3 -V
pip3 -V
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
Ya tenemos la 3.14.7.1, con OpenSSL 3.5.4, y pip se ejecuta desde /u/python/current, es decir, desde la versión nueva.
Los paquetes de pip
Los paquetes que instalamos con pip se guardan dentro de cada versión de Python, así que la nueva empieza sin ellos.
La instalación de la stock image no la tocamos: sigue en /usr/lpp/IBM/cyp/v3r14/pyz con todos sus paquetes, y lo que la use por su ruta sigue funcionando. Solo cambia el python3 que encontramos nosotros con el PATH.
La versión nueva ya trae algunos paquetes de IBM (cffi, cryptography, pycparser y six), pero no ibm_db ni zoautil_py, que sí tenía la de la stock image:
pip3 list
Instalamos solo los que vayamos a usar.
Por ejemplo, zoautil_py no está en PyPI, pero ZOAU trae un wheel para cada versión de Python. Instalamos el de la 3.14 y comprobamos que su Location ya está dentro de /u/python:
ls /usr/lpp/IBM/zoautil/*.whl
pip3 install /usr/lpp/IBM/zoautil/zoautil_py-1.4.1.0-cp314-cp314-zos.whl
pip3 show zoautil_py

El resto de paquetes se instalan con pip3 install y el nombre del paquete. pip los descarga de PyPI, así que z/OS necesita salida a internet. Los que llevan código en C, como ibm_db, necesitan además un compilador de C.
ibm_db es el driver de Python para Db2 (python-ibmdb). En la stock image, las variables que necesita para compilarse están en el fichero .profile_for_ibmdb del HOME: el compilador de C (CC=/bin/xlc), el prefijo de los data sets de Db2 (IBM_DB_HOME=DB2V13), el STEPLIB con las librerías de Db2 y el fichero de configuración de ODBC (DSNAOINI). Las cargamos en la sesión e instalamos la misma versión que tenía la stock image:
. /u/ibmuser/.profile_for_ibmdb
echo $IBM_DB_HOME
pip3 install ibm_db==3.2.8

pip3 show ibm_db
python3 -c "import ibm_db; print('ok')"
Para comprobar que funciona, la stock image trae un pequeño script de prueba, ibm_db_test.py. Se conecta al Db2 local y lista las tablas del catálogo (SYSIBM.SYSTABLES).
El script está en ASCII y sin etiqueta de codificación, así que para leerlo lo convertimos a EBCDIC:
iconv -f ISO8859-1 -t IBM-1047 /u/ibmuser/ibm_db_test.py
Lo ejecutamos:
python3 /u/ibmuser/ibm_db_test.py | head -20
Desde el Python nuevo ya podemos conectarnos al Db2 de z/OS y lanzar consultas SQL.
Volver atrás
Si algo no funciona con la versión nueva, volvemos a la anterior apuntando el enlace current a ella. En nuestro caso, la anterior es la de la stock image:
cd /u/python
rm -f current
ln -s /usr/lpp/IBM/cyp/v3r14/pyz current
python3 -VAl abrir una nueva sesión de OMVS, ya estamos otra vez con la versión anterior. Por eso no borramos ninguna versión hasta comprobar que la nueva funciona bien.
Con esto tenemos Python actualizado a la 3.14.7.1, cada versión en su propio zFS y la de la stock image intacta. Cuando IBM publique la siguiente PTF, repetimos los mismos pasos: un zFS nuevo, descomprimir y cambiar el enlace.
Referencias
- Guía de instalación PAX (3.14): https://www.ibm.com/docs/en/python-zos/3.14.0?topic=configuration-installing-configuring-pax-format
- Personalizar el entorno (/usr/bin/env): https://www.ibm.com/docs/en/python-zos/3.14.0?topic=configuration-customization-environment
- Fix list: https://www.ibm.com/support/pages/node/6232646
- Anuncio de la 3.14: https://community.ibm.com/community/user/blogs/jc-yao/2025/11/10/announcing-ibm-open-enterprise-sdk-for-python-314