What value in Python corresponds to `Py_GetPythonHome`? `sys.prefix`?

Viewed 79

Py_GetPythonHome is a C API.

How do I get the same value within Python?

Is that sys.base_prefix? sys.exec_prefix? Sth else? I found sys._home but this is None.

3 Answers

How do I get the same value within Python?

Well I don't see any option to consume the Py_GetPythonHome directly using the sys module. My assumption is that Py_GetPythonHome might be exposed only as C-API.

To get the same value in python you can consume the C-API via ctypes module.

>>> from ctypes import pythonapi, c_wchar_p
>>>
>>> home = pythonapi.Py_GetPythonHome
>>> home.argtypes = ()
>>> home.restype = c_wchar_p
>>> home()

From everything I can tell looking at the source, Py_GetPythonHome holds the value of the environment variable PYTHONHOME, if it is set, or the value assigned to it using Py_SetPythonHome. If neither os.environ["PYTHONHOME"] has been set, Py_SetPythonHome called, or the system function Py_Initialize has been called, then as of v3.10 its default value is NULL.

The Py_GetPythonHome function is defined in Python/pathconfig.c, which is also where Py_SetPythonHome is defined. The _PyPathConfig struct (of which _Py_path_config is an instance) contains wchar_t *home, which has this comment:

Set by Py_SetPythonHome() or PYTHONHOME environment variable

So, it looks like the only way you can access Py_GetPythonHome is either directly through the C API (as Abdul demonstrates in another answer) or via os.environ["PYTHONHOME"], if that environment variable has been set.

sys._home seems to only be set in virtualenvs - I'm not sure what relation it has to Py_GetPythonHome. I haven't yet looked directly into how sys.base_prefix and similar attributes are set.

From looking a bit more to the CPython code, it seems that Py_SetPythonHome is deprecated from Python 3.11 on. So maybe it is anyway not a good idea to make much use of it.

Further, you find this (here):

    if (_Py_path_config.home != NULL) {
        _Py_path_config.stdlib_dir = _PyMem_RawWcsdup(_Py_path_config.home);
    }

And that can be accessed via sys._stdlib_dir in Python >=3.11 (here).

Related