Messages when using python on z/OS

This post gives some of the error messages I received, and the actions I took to resolve the problems.

FSUM3008 Specify a file with the correct suffix (.c, .i, .s, .o, .x, .p, .I, or .a), or a corresponding data set name, instead of -o ….

I got this during a Python C extension build. You need

export _C89_CCMODE=1
export _C99_CCMODE=1
export _Ccc_CCMODE=1
export _CC_CCMODE=1
export _CXX_CCMODE=1
export _C89_CCMODE=1
export _CC_EXTRA_ARGS=1
export _CXX_EXTRA_ARGS=1
export _C89_EXTRA_ARGS=1

Before doing any builds.

Python builds

DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives.

Easy fix which no one tells you about (it took me 3 days to find this). Add

import setuptools

to the top of the file.

COLIN:/u/pymqi: >python3 -m build
No module named build.main; ‘build’ is a package and cannot be directly executed

You have a build directory in your project

https://pypi.org/search/?q=build

then install it

python3 setup.py bdist_wheel … error: invalid command ‘bdist_wheel’

I needed “import setuptools” at the top of the setup.py file. I also needed wheel to be installed.

CEE3501S The module libpython3.10.so was not found.

I was trying to do

import ctypes
from ctypes.util import find_library
testlib = ctypes.CDLL(“… “)

This file was in /u/tmp/python/usr/lpp/IBM/cyp/v3r10/pyz/lib/

You need

export LIBPATH=/u/tmp/python/usr/lpp/IBM/cyp/v3r10/pyz/lib/:$LIBPATH

python3 ….

CEE3587S A call was made to a function in the AMODE 31 DLL //ADD2 from an AMODE 64 caller.

I was trying to call a C program from Python – but i was built with 31 bit mode – not 64 bit mode.

You need to compile it with LP64, and bind in 64 bit mode, and use //BIND.SYSLIB DD DISP=SHR,DSN=CEE.SCEEBND2

ImportError: CEE3512S An HFS load of module /u/tmp/py/mq.so failed. The system return code was 0000000130; the reason code was 0BDF0

I had a bind error. When I fixed it – it worked.

The IBM documentation says

A package shared library may get tagged incorrectly when using the xlc utility. Verify that the shared library is untagged by running the following line:

ls -alT

If the file is tagged, with the output being similar to the following line:

t ISO8859-1 T=on

you can remove the tag with the following command:

chtag -r <filename.so>

ERROR: Could not install packages due to an EnvironmentError: Erno 111 EDC5111I Permission denied.: ‘/u/.local’
Check the permissions.

I was trying to install a package using

python3 -m pip install /tmp/… .whl /tmp/… whl –no-cache-dir

It defaults to storing things in /u/.local. I needed

export PYTHONUSERBASE=.

Before running the command.

ImportError: CEE3512S An HFS load of module …. failed. The system return code was 0000000111; the reason code was EF076015 .

You need to use chmod +x …. to the module

SystemError: unmatched paren in format

I had a C program and was using

rv = Py_BuildValue("(blll",
...
);

but was missing a backet in "(blll)"

CEE3204S The system detected a protection exception (System Completion Code=0C4).
From compile unit TOROLABA:./Python/getargs.c at entry point vgetargskeywords at statement 1687

I had code

static char *kwlist[] = {“routcde”};
if (!PyArg_ParseTupleAndKeywords(args, keywds, “s#|i”, kwlist,

It needs to be static char *kwlist[] = {“routcde”,NULL};

From compile unit TOROLABA:./Python/getargs.c at entry point vgetargskeywords at statement … at compile unit offset ….

With code like

static char *kwlist[] = {“text”,”routecde”,NULL};
PyArg_ParseTupleAndKeywords(args, keywds, .., kwlist,…

IEW2606S 4B39 MODULE INCORPORATES VERSION 3 PROGRAM OBJECT FEATURES AND CANNOT BE SAVED IN LOAD MODULE FORMAT.

I was trying to save a DLL in a load library.

I had created the PDSE using

//PYTALL JOB 1,MSGCLASS=H
//S1 EXEC PGM=IEFBR14
//DD1 DD DISP=(MOD,DELETE),SPACE=(CYL,(1,10,10)),
// DSN=COLIN.PDSE2
//S1 EXEC PGM=IEFBR14
//DD2 DD DISP=(NEW,CATLG),SPACE=(CYL,(1,10,10)),
// DSNTYPE=(LIBRARY,1),
// DSN=COLIN.PDSE2,
// DCB=(RECFM=U,LRECL=0,BLKSIZE=6400)

I was building it in OMVS using

/bin/xlc $name.o -o //’COLIN.PDSE2($name)’

This tried to use data set COLIN.COLIN.PDSE which did not, exist, so it tried to create it, and created a PDS, not a PDSE.

The statement

/bin/xlc $name.o -o “//’COLIN.PDSE2($name)'”

With double quotes around the name worked.

Binder problems compiling a module

IEW2456E 9207 SYMBOL CEETHLOC UNRESOLVED. MEMBER COULD NOT BE INCLUDED FROM THE DESIGNATED CALL LIBRARY.
IEW2456E 9207 SYMBOL @@ROND UNRESOLVED. MEMBER COULD NOT BE INCLUDED FROM THE DESIGNATED CALL LIBRARY.
IEW2456E 9207 SYMBOL CEEROOTD UNRESOLVED. MEMBER COULD NOT BE INCLUDED FROM THE DESIGNATED CALL LIBRARY.

I was compiling a C program using XPLINK and got the above messages.
I used the following JCL

//COMPILE EXEC PROC=EDCXCB,
// LIBPRFX=&LIBPRFX,
// CPARM=’OPTFILE(DD:SYSOPTF),LSEARCH(/usr/include/)’,
// BPARM=’SIZE=(900K,124K),RENT,LIST,RMODE=ANY’
//* BPARM=’SIZE=(900K,124K),RENT,LIST,RMODE=ANY,AMODE=31,AC=1′
//COMPILE.SYSOPTF DD *

….

//BIND.SYSLMOD DD DISP=SHR,DSN=&LOADLIB.
//BIND.SYSLIB DD DISP=SHR,DSN=&LIBPRFX..SCEELKED

SCEELKED is for non XPLINK.

It needs to be

DSNAME=&LIBPRFX..SCEEBND2,DISP=SHR

EDC5061I An error occurred when attempting to define a file to the system. (errno2=0xC00B0403)

I got this trying to open a data set from from a Python program.

C00B0403: The filename argument passed to fopen() or freopen() specified dsname syntax. Allocation of a ddname for the dsname was attempted, but failed.

I used

printf(“AMRC\n”);
printHex(stdout,__amrc ,sizeof(__amrc_type));

The first word was 00000210.

Interpreting error reason codes from DYNALLOC gives

210: Meaning: Requested data set unavailable. The data set is allocated to another job and its usage attribute conflicts with this request. (dsname allocation)

I had the dataset open in a ISPF window.

EDC5129I No such file or directory. (errno2=0x05620062)

I was trying to use fopen(“DD:VB”…) where VB was not in the JCL.

When I specified a data set name “//’COLIN/VB'” it worked.

BPXM018I BPXBATCH FAILED BECAUSE SPAWN (BPX1SPN) OF /BIN/LOGIN FAILED WITH RETURN CODE 0000009D REASON CODE
0B1B0473

I got this running under PGM=BPXBATSL. When I changed it to PGM=BPXBATCH it worked.

BPXBATCH

BPXBATCH makes it easy for you to run shell scripts and executable files that reside in z/OS® UNIX files through the MVS™ job control language (JCL)…

In addition to using BPXBATCH, a user who wants to perform a local spawn without being concerned about environment setup (that is, without having to set specific environment variables, which could be overwritten if they are also set in the user’s profile) can use BPXBATSL. BPXBATSL provides users with an alternate entry point into BPXBATCH. It also forces a program to run by using a local spawn instead of fork/exec as BPXBATCH does. These actions allow the program to run faster.

can’t open file ‘//DD:STDIN’: [Errno 92] EDC5092I An I/O abend was trapped.

I was using AOPBATCH, and had PGM=AOPBATCH,PARM=’//usr/lpp/IBM/cyp/v3r8/pyz/bin/python3 //DD:STDIN’

where STDIN was DD *, trying to read from the inline data. Using //STDIN DD PATH=’/u/tmp/zos/z.py’ worked fine.

SyntaxError: Non-UTF-8 code starting with ‘\x83’ in file on line 1, but no encoding declared;

I got this using // PGM=AOPBATCH,PARM=’//usr/lpp/IBM/cyp/v3r8/pyz/bin/python3′ and letting the Python source default to //STDIN. I had to specified

// PGM=AOPBATCH,PARM=’//usr/lpp/IBM/cyp/v3r8/pyz/bin/python3 //DD:STDIN’ for it to work.

BPXM047I BPXBATCH FAILED BECAUSE SPAWN (BPX1SPN) OF
… FAILED WITH RETURN CODE 00000082 REASON CODE 0B1B0C27

Return code 82, 0000008 0x82 0x00000082 decimal 130 is Exec format error.

I got 0B1B0C27 because I had

//R EXEC PGM=BPXBATCH,REGION=0M,TIME=NOLIMIT,MEMLIMIT=NOLIMIT,
// PARM=’pgm /u/tmp/zos/y.py …’

Instead of

//R EXEC PGM=BPXBATCH,REGION=0M,TIME=NOLIMIT,MEMLIMIT=NOLIMIT,
// PARM=’pgm /usr/lpp/IBM/cyp/v3r8/pyz/bin/python3 /u/tmp/zos/y.py….’

I also got this trying to run a java program. I needed environment variable _BPX_SPAWN_SCRIPT=YES when using the BPXBATSL utility
to run the command (or a nested command).

FOPEN: EDC5129I No such file or directory. (errno2=0x05620062)

If you try to use fopen(“DD:xxxx”…) from a shell script (or BPXBATCH PARM=”pgm… ” you will get

FOPEN: EDC5129I No such file or directory. (errno2=0x05620062)

If you use fopen(“//’COLIN.VB’”…) and specify a fully qualified dataset name if will work.

fopen(“//VB”..) will put the RACF userid in front of the name. For example attempt to open “//’COLIN.VB.’”

CCN3276 Syntax error: possible missing ‘)’?

I had

48 | asm(
49 | " LA 2,%[p1] Adderss of the block \n"
50 | :
     a…………………………………………………………….
*=ERROR===========> a - CCN3276 Syntax error: possible missing ')'?
51 | : [p1] "m"(pMsg)
52 | : "r0","r1"
53 | );

This was caused by not having ASM in the compiler options.

SEVERE ERROR CCN1104: Internal error while compiling function ….. Unsupported Assembler Template. Compilation terminated.

I had

asm(
" LA 3,[%EPA] \n"
:
: [EPA] "m"(SWAEPA)
: "r1","r2"
);

with the %inside the []. It should be %[EPA]

PIP

I got

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1019)

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1019)

trying to install a product. See here.

zoneinfo/init.py … EDC5129I No such file or directory.

I was getting

u/tmp/zowet/colin/envz /lib/python3.12/site-packages/dateutil/zoneinfo/init.py:26: UserWarning: I/O error(129): EDC5129I No such file or directory. warnings.warn(“I/O error({0}): {1}”.format(e.errno, e.strerror))

I put some debug code in, and found it was trying to find dateutil-zoneinfo.tar.gz.

I tried installing various packages. Finally the following worked for me

pip uninstall python-dateutil
pip install python-dateutil
...
Successfully installed python-dateutil-2.9.0.post0

pip install tzdata
...
Successfully installed tzdata-2025.3

and it worked.

ModuleNotFoundError: No module named

My code was

import dumphex

... dumphex.dumphex()

and I got the message

ModuleNotFoundError: No module named ‘dumphex’

This was strange because the dumphex.py was in the same directory as the main python code.

Solution

It needs

from . import dumphex

Python on z/OS coding a C extension.

I was porting the pymqi code, which provides a Python interface to IBM MQ, to z/OS.

I’ve documented getting the code to build. I also had challenges trying to use it.

The code runs as ASCII!

When my C extension was built, it gets built with the ASCII option. This means any character constants are in ASCII not, EBCDIC.

My python program had

import sys
sys.path.append(‘./’)
import pymqi
queue_manager = ‘AB12’
qmgr = pymqi.connect(queue_manager)
qmgr.disconnect()

When my C code got to see the AB12 value, it was in ASCII. When the code tried to connect to the queue manager, it return with name error. This was because the value was in ASCII, and the C code expected EBCDIC.

You can take see if the program has been compiled with the ASCII flag using

#ifdef __CHARSET_LIB

… It is has been compiled with option ASCII
#else

If you use printf to display the queue manager name it will print AB12. If you display it in hex you will be 41423132 where A is x41, B is x42, 1 is x31 is 2 is x32.

In your C program you can convert this using the c function a2e with length option, for example

char EQMName[4];
memcpy(&EQMName[0],QMname,4);
__a2e_l(&EQMName[0],sizeof(EQMName));

// then use &EQMName

Converting from ASCII to EBCDIC in Python.

Within Python you have strings stored as Unicode, and byte data. If you have a byte array with x41423132 (the ASCII equivalent to AB12). You can get this in the EBCDIC format using

a=b’41423132′ # this is the byte array
m = a.decode(“ascii”) # this creates a character string
e = m.encode(‘cp500’) # this create the new byte array of the EBCDIC version .. or xC1C2F1F2

In Python you convert from a dictionary of fields into a “control block” using the pack function. You can use the “e” value above in this.
MQ control blocks have a 4 character eye catcher at the front eg “OD “. If you use the pack function and pass “OD ” you will pass the ASCII version. You will need to do the decode(‘ascii’) encode(‘CP500’) to create the EBCDIC version.

Similarly passing an object such as MQ queue name, will need to be converted to the EBCDIC version.

Converting from EBCDIC to ASCII

If you want to return character data from your C program to Python, you will need to the opposite.

For example m is a byte array retuned back from the load module.

#v is has the value b’C1C2F2F3′ (AB23)
m = v.decode(“cp500”)
a = m.encode(‘ascii’)

# a now has b’41423132′ which is the ascii equivilant

Python on z/OS – Helpful hints

This posts contains small snippets of useful information about using IBM Python on z/OS.

Setup an alias for python3

I set up an alias so I can type p3 or py instead of python3.

alias p3=”python3″
alias py=”python3″

Creating a .py file is harder than it looks

It was easy to create a .py file in Unix Services. It was hard to create a file which I could edit, would build and be compiled. For example I could execute a .py file. If I tried to compile it (as happens when you build it) I got

Compiling ‘/u/pymqi/mq2.py’…
*** Sorry: UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xa2 in position 0: invalid start byte

I found a couple of ways of solving this problem

Use

touch myfile.py
chtag -tc ISO8859-1 myfile.py
oedit myfile.py

To undo this use IBM-1047.

Copy an existing file for example

cp /u/tmp/python/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/pip/main.py my.py

Then edit my.py, remove all of the content and add in my content using cut and paste.

A different approach – useful when copying packages to z/OS was to FTP a .py file from Linux as BINARY then use

chtag -tc t ISO8859-1 mynew.py

So that z/OS recognises it as ASCII.

Displaying [] in your OMVS session

I could only get ISPF to display [] by using settings, and configuring terminal type to be 3278 (not 3278A as the documentation says).

The OMVS command has a CONVERT option that lets you specify a conversion
table for converting between code pages. The table you want to specify depends
on the code pages you are using in MVS and in the shell. For example, if you are
using code page IBM-037 in MVS and code page IBM-1047 in the shell, specify the
following when you enter the TSO OMVS command:
OMVS CONVERT((BPXFX111))

For example the program

a = {“a1″,2,”a3”}
b = [“a1″,2,”a3”]
print(a)
print(b)

With OMVS CONVERT((BPXFX111)) when you run it, you get

{‘a1’, 2, ‘a3’}
[‘a1’, 2, ‘a3’]

With OMVS you get

{‘a1’, 2, ‘a3’}
Ý’a1′, 2, ‘a3’¨

How to edit source and get the brackets right

The provided .py files format ok in ISPF when using US English 037. This is different to my normal code page of Bracket CP037 Modified.

With US English 037 in ISPF editor I get

a = {“a1″,2,”a3”}
b = [“a1″,2,”a3”]

With Bracket CP037 Modified – which works for normal C

a = {“a1″,2,”a3”}
b = Ý“a1″,2,”a3”¨

What is installed

python3 -m pip list

How to install Python software in an isolated environment

If your z/OS is connected to the internet, you can use python3 -m pip install ….
It is harder if your z/OS is isolated and does not have direct connectivity.

Download the software to your workstation

I used site https://pypi.org/, found the software I was interested in (eg wheel) and downloaded it to Linux.

Upload to z/OS

I FTPed the file to z/OS in binary, keeping the same name wheel-0.37.1-py2.py3-none-any.whl

Install the software

You can install this in a virtual environment, or on the system wide Python. The file system Python is on needs to be writeable.

To display the syntax of the install command

python3 -m pip install -help

When I tried to install it using my non privileged userid I got


-[31]ERROR: Could not install packages due to an OSError: [Errno 111] EDC5111I Permission denied.: ‘/u/.local’ Check the permissions.
-[0]

I had to install it using my IBMUSER id which had more authority ( and could change any file etc), or use the option –no-cache-dir .

The command was

python3 -m pip install /u/tmp/py/wheel-0.37.1-py2.py3-none-any.whl /u/tmp/py/wheel-0.37.1-py2.py3-none-any.whl
Looking in links: /u/tmp/py/wheel-0.37.1-py2.py3-none-any.whl
Processing /u/tmp/py/wheel-0.37.1-py2.py3-none-any.whl
Installing collected packages: wheel
Successfully installed wheel-0.37.1
-[33]WARNING: Running pip as the ‘root’ user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv-%5B0%5D

When installing other software I had to use options

  • -f : search for pre-req software in this directory
  • –no-cache-dir : because it tried to write to a read only cache
  • –user : to install it in the virtual environment, not the system wide python.

Uninstall the software

python3 -m pip uninstall wheel

What machine is this running on ?

My z/OS is z/OS 2.4 on zPDT on Linux.

import platform
sys.path.append('./')
import pymqi
print("machine",platform.machine())
print("platform",platform.platform())
print("arch ",platform.architecture())
print("process ",platform.processor())
print("compiler",platform.python_compiler())
print("system ",platform.system())

gives

machine 1090
platform OS-390-27.00-1090-64bit
arch (’64bit’, ”)
process
compiler Clang 4.0.1 (tags/RELEASE_401/final)
system OS/390

Using struct.pack on z/OS

I wanted to understand what pack did on z/OS. See “format characters” in the documentation. For example ‘c’ is character, ‘L’ is unsigned long. Using a statement like print(“i”,struct.pack(“i”,1)) to format a number I got


b b’\x01′
h b’\x00\x01′
H b’\x00\x01′
i b’\x00\x00\x00\x01′
I b’\x00\x00\x00\x01′
l b’\x00\x00\x00\x00\x00\x00\x00\x01′
L b’\x00\x00\x00\x00\x00\x00\x00\x01′
q b’\x00\x00\x00\x00\x00\x00\x00\x01′
Q b’\x00\x00\x00\x00\x00\x00\x00\x01′
n b’\x00\x00\x00\x00\x00\x00\x00\x01′
N b’\x00\x00\x00\x00\x00\x00\x00\x01′
P b’\x00\x00\x00\x00\x00\x00\x00\x01′

I also noticed a “funny”

z = b’AB23′
print(“4sll” , struct.pack(“4sll”,z,2,1))

gave me

4sll b’AB23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01′

The red text is from the long variable, the green text is the padding to make the long value on a long boundary (8).

Have a good REST and save a fortune in CPU with Python

Following on from Have a good REST and save a fortune in CPU. The post gives some guidance on reducing the costs of using Liberty based servers from a Python program.

Certificate set up

I used certificate authentication from Linux to z/OS. I used

  • A certificate defined on Linux using Openssl.
  • I sent the Linux CA certificate to z/OS and imported it to the TRUST keyring.
  • I created a certificate on z/OS and installed it into the KEY keyring.
  • I exported the z/OS CA, sent it to Linux, and created a file called tempca.pem.

Python set up

Define the names of the user certificate private key, and certificate

cf=”colinpaicesECp256r1.pem”
kf=”colinpaicesECp256r1.key.pem”
cpcert=(cf,kf)

Define the name of the certificate for validating the server’s certificate

v=’tempca.pem’

Set up a cookie jar to hold the cookies sent down from the server

jar = requests.cookies.RequestsCookieJar()

Define the URL and request

geturl =”https://10.1.1.2:9443/ibmmq/rest/v1/admin/qmgr/

Define the headers

import base64
useridPassword = base64.b64encode(b’colin:passworm’)
my_header = {
‘Content-Type’: ‘application/json’,
‘Authorization’: useridPassword,
‘ibm-mq-rest-csrf-token’ : ‘ ‘
}

An example flow of two requests, using two connections

For example using python

s = requests
response1 = s.get(geturl,headers=my_header,verify=v,cookies=jar,cert=cpcert)
response2 = s.get(geturl,headers=my_header,verify=v,cookies=jar,cert=cpcert)

creates two session, each has a TLS handshake, issue a request, get a response and end.

An example of two requests using one session

For example using python

s = requests.Session()
response1 = s.get(geturl,headers=my_header,verify=v,cookies=jar,cert=cpcert1)
response2 = s.get(geturl,headers=my_header,verify=v,cookies=jar,cert=cpcert2)

The initial request has one expensive TLS handshake, the second request reuses the session.

Reusing this session means there was only one expensive Client Hello,Server Hello exchange for the whole conversation.

Even though the second request specified a different set of certificates, the certificates from when the session was established, using cpcert1 were used. (No surprise here as the certificates are only used when the session is established).

For the authentication, in both cases the first requests received a cookie with the LtpaToken2 cookie in it.

When this was passed up on successive requests, the userid information from the first request was used.

What is the difference?

I ran a workload of a single thread doing 200 requests. The ratios are important, not the absolute values.

Shared sessionOne session per requests
TCP flows to server1 11
CPU cost1 5
Elapsed time16

Installing python on z/OS.

I wanted to use Python on z/OS to run a REST workload. It took a bit of time, but it worked with no major problems.

As well as installing Python, I had to install some packages so I could use the request package to issue REST requests.

This page has a good article about using python on z/OS. I used it to install additional packages.

This post has topics

There is a Python from Rocket software, and one from IBM. They may be the same; I used the IBM version.

There are instructions here. I logged on to my usual IBM web site, where my usual browser remembered my userid and password, then used https://www.ibm.com/products/open-enterprise-python-zos/pricing .

I used the web site https://www.ibm.com/docs/en/python-zos/3.9?topic=configuration-installing-configuring-pax-edition.

When I used the web site directly, I had to enter my userid and password.

The web site has a .pax file, and instructions.

The HAMB390.runnable.pax.Z file used 492418 * 512 byte blocks on z/OS.

I did not have enough space in my ZFS on z/OS, so I had to allocate a new ZFS

Allocate a ZFS

//DEFINE EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE –
CLUSTER –
(NAME(COLIN.ZFS1 ) –
VOLUMES(USER00) –
LINEAR –
MEGABYTES(254 25) –
SHAREOPTIONS(3 3))
/*

Format it

//FORMATFS EXEC PGM=IOEAGFMT,REGION=0M,COND=(0,NE,DEFINE),
// PARM=(‘-aggregate COLIN.ZFS1 -compat’)
//SYSPRINT DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*
//*

Mount it

//MOUNT EXEC PGM=IKJEFT1A,COND=((0,NE,DEFINE),(0,NE,FORMATFS))
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
MOUNT FILESYSTEM(‘COLIN.ZFS1’) TYPE(ZFS) +
MOUNTPOINT(‘/colin2’) MODE(RDWR) PARM(‘AGGRGROW’) AUTOMOVE
/*

If you want to use this ZFS after an IPL you will have to mount it. If you only want to use the ZFS as a temporary ZFS you can unmount and delete it.

I created another ZFS for the unpacked Python with size MEGABYTES(550 50).

I followed the install instructions https://www.ibm.com/docs/en/python-zos/3.9?topic=configuration-installing-configuring-pax-edition using the directory /colin3.

After I had unpacked it, there was a directory usr/lpp/IBM/cyp/v3r9 with members IBM and pyz.

The path for python is /colin3/usr/lpp/IBM/cyp/v3r9/pyz/bin

You may want to consider setting up a symbolic link from /usr/lpp/pyz to the new libraries. From an authorised userid issue

ln -s /colin3/usr/lpp/IBM/cyp/v3r9/pyz /usr/lpp/pyz

Set up a profile

I set up a pythonprof file with

export LIBPATH=/usr/lpp/pyz/lib:$LIBPATH
export _BPXK_AUTOCVT=’ON’
export _CEE_RUNOPTS=’FILETAG(AUTOCVT,AUTOTAG) POSIX(ON)’
# if you are using a bash shell, you should also set these:
export _TAG_REDIR_ERR=txt
export _TAG_REDIR_IN=txt
export _TAG_REDIR_OUT=txt
export PATH=/usr/lpp/pyz/bin:$PATH

When I wanted to run a python profile, I use . ./pythonprof to do the set up.

I then checked python worked using

/usr/lpp/pyz/bin/python3 –version

Which gave me

Python 3.9.2

Install the request package and co requisites

I used the information here to install additional packages so I could use a rest interface from python. I have copied the relevant section and expanded it.

If you want to use private keys with a password you need to use package requests_pkcs12. Use Pip download requests_pkcs12 instead of download requests below.

Our z/OS service isn’t connected to the internet, so we did it like this:

On a laptop with Python and pip installed:

a. mkdir requests
b. cd requests
c. pip download requests

This pulled the “requests” package and four dependencies: The files end in .whl

1. certifi
2. chardet
3. idna
4. urllib

Binary FTP all five to a USS directory (/u/myid/pipdl)

On z/OS, in USS in the directory we uploaded to, install all of the packages using:

. /u/adcd/pythonprof
pip3 install requests --find-links ./

Note lots of error messages as pip tries to access the internet version, but then success at the end.

You can now erase the .whl files.

I ran my python programs – and they worked!