pythonperlbraintree

Perl's Inline::Python Leads to Odd Error on AlmaLinux 8, but Not CentOS 7


I'm trying to use Inline::Python to access the Braintree API that isn't available in Perl directly. It's code that has been working for years on a CentOS 7 server, but as I'm trying to move this code to a new, AlmaLinux 8 server, the very same code I've used for six years won't run, immediately failing as I try to import the Braintree Python module.

For example:

#!/usr/bin/perl

use strict;
use warnings;
use v5.10;

use Inline 'Python' => <<'END_OF_PYTHON_CODE';

import braintree

END_OF_PYTHON_CODE

Results in this error:

[tbutler@cedar tcms]# perl -MInline=info,force ~/testInline2.pl
<-----------------------Information Section----------------------------------->

Information about the processing of your Inline Python code:

Your source code needs to be compiled. I'll use this build directory:
/home/tbutler/public_html/cgi-bin/tcms/_Inline/build/testInline2_pl_4db4

and I'll install the executable as:
/home/tbutler/public_html/cgi-bin/tcms/_Inline/lib/auto/testInline2_pl_4db4/testInline2_pl_4db4.pydat

Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named braintree
Error -- py_eval raised an exception at /usr/local/lib64/perl5/Inline/Python.pm line 177.

<-----------------------End of Information Section---------------------------->
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named braintree
Error -- py_eval raised an exception at /usr/local/lib64/perl5/Inline/Python.pm line 177.
BEGIN failed--compilation aborted at /home/tbutler/testInline2.pl line 9.

However that same import works just fine on the older CentOS 7 system. It also works fine if I do that import straight within Python on the new system.

I thought perhaps it has something to do with the version of Python on the system, so I tried running this code inline:

import sys
print("Python version")
print (sys.version)

On the system where Inline::Python works ok with the braintree module, here is what it reports back:

2.7.5 (default, Jun 28 2022, 15:30:04) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

On the system where it fails:

2.7.18 (default, Oct 18 2022, 11:09:45) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-15)]

So everything seems reasonably similar. Is there some kind of setting Inline needs in order to function properly?

(To answer the inevitable question: the reason I'm using Inline rather than using Python is that the rest of the code I'm using in written in Perl and am reasonably proficient at Perl programming, but not Python programming.)

Edit (December 12 at 8:34 PM): I realize when I try the Python code directly, I've been using Python3, but the Inline tool is using Python 2.7, as reported above. That worked just fine on the old CentOS system, but not so much on the AlmaLinux one. I think this might be resolved by using Python 3.x instead, but have not yet figured out how to tell Inline::Python to use Python 3.x (both python2 and python3 are installed). Here is the error when I try to run the same import of Braintree on Python 2 on the new system:

    [tbutler@cedar safari]# python2 ~/testInline.py
Traceback (most recent call last):
  File "/tbutler/testInline.py", line 2, in <module>
    import braintree
  File "/usr/lib/python2.7/site-packages/braintree/__init__.py", line 1, in <module>
    from braintree.ach_mandate import AchMandate
  File "/usr/lib/python2.7/site-packages/braintree/ach_mandate.py", line 2, in <module>
    from braintree.util.datetime_parser import parse_datetime
  File "/usr/lib/python2.7/site-packages/braintree/util/__init__.py", line 4, in <module>
    from braintree.util.http import Http
  File "/usr/lib/python2.7/site-packages/braintree/util/http.py", line 3, in <module>
    from base64 import encodebytes

ImportError: cannot import name encodebytes

So, I either need to figure out why Python 2.7 runs the code on the one system but not the other or get Inline::Python to prefer Python 3 somehow.


Solution

  • So, I still don't know why Python2 works on the one system with the module in question but not the other, but I was able to rebuild Inline::Python to work with Python3, which seems to have resolved the issue without solving that mystery.

    To switch Inline::Python to python3 was a bit of a wrestling match, because it really wanted to go with python2 instead. Here is what it took:

    yum install python36-devel
    export INLINE_PYTHON_EXECUTABLE=/usr/bin/python3
    cpanm --look Inline::Python
    perl Makefile.PL
    

    The makefile process was interactive. I had to select the python3.6 option, which was not the default, at several different prompts. Then proceed:

    make
    make install
    

    After that, Inline::Python loaded my code fine.