I have an old Centos 7 system. It has one user [plus root] and has python2.7 and python3.6.8 installed. The latter has binary /bin/python3
Neither PYTHONHOME nor PYTHONPATH are defined. Python3 runs fine, for example, print(encodings.__file__)
gives usr/lib64/python3.6/encodings/__init__.py
but I need to upgrade it. There do not appear to be modern repositories for Centos 7 now, so I’ll build by scratch. No problem….
So I git clone Python.3.11.2
(also tried 3.11.0a4) and tar xvf
to create a directory and cd to that directory. The following fails
./configure
make
with an error
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
The error is hit when trying to run _bootstrap_python
. I’ve tried solving this a bunch of different ways. For example, trying a prefix gives this printout:
./_bootstrap_python ./Programs/_freeze_module.py abc ./Lib/abc.py Python/frozen_modules/abc.h
Python path configuration:
PYTHONHOME = (not set)
PYTHONPATH = (not set)
program name = './_bootstrap_python'
isolated = 0
environment = 0
user site = 0
safe_path = 0
import site = 1
is in build tree = 0
stdlib dir = '/usr/local/lib/python3.11'
sys._base_executable = '/bin/python3'
sys.base_prefix = '/usr/local'
sys.base_exec_prefix = '/usr/local'
sys.platlibdir = 'lib'
sys.executable = '/home/xuser/analysis/Python-3.11.2/_bootstrap_python'
sys.prefix = '/usr/local'
sys.exec_prefix = '/usr/local'
sys.path = [
'/usr/local/lib/python311.zip',
'/usr/local/lib/python3.11',
'/usr/local/lib/python3.11/lib-dynload',
]
I’ve tried running the configure inside a virtualenv. I’ve run it as xuser. I’ve run it as root…. It keeps stumbling on the same point. The download of 3.11 has perfectly fine encodings sitting inside the its Lib
directory, but I think they are not getting copied over to the destination where makefile expects them.
Doubtless a dumb mistake of mine, but damned if I can find it. I did see some old discussions on stackoverflow to change the contents of .ini
file (I dont have an .ini
file) and/or to edit PYTHONPATH to something else. [No matter what I set that path to, it still shows up as "not set" in the configuration listed by bootstrap, so I dont think that is the solution.] My guess is a definition needs to be passed to .configure. But what?
Looking at that print out, I see that sys._base_executable
is pointing at 3.6.8, which is suspicious (why does it care about old python?)
2
Answers
Ok, this is ugly. But it resulted in a working 3.11 environment on Centos 7 when I couldn't get anything else to work. I'll continue to sort out why .configure is screwing up, but here goes....
When building from a really old Python to 3.11, somehow the
sys.path
chosen by .configure is always wrong. Changing PYTHONHOME or PYTHONPATH doesn't help, I don't know why.But you can fix it by hand by editing
sysmodule.c
(!!) Look forCOPY_LIST("path"...)
and immediately before there you can add the search paths you need.Now just press "make" to get a fully functioning, modern python. You should leave PYTHONHOME and PYTHONPATH blank because the link to the modules was hardcoded at compile time.
My guess is that any future upgrade will be by the book and not require this hack, but I'm posting in case anybody in the same boat. And yes, I'm sure there is a flag for .configure or Make on Centos7too. If nothing else, this hack should clarify what is needed.
And now this works: so I can build 3.11.2 without any screwing around. [Thanks to a post by Lou King on Google Groups for advice on this].