When embedding a Python interpreter in another application, such as a game, a tricky parts is to get it to start up and find the right modules. You typically want Python to:
- Find your version of the standard library
- Find your application modules
- Not be confused by any other Python system that may be installed on the machine.
The application has absolute knowledge of the location of the python modules. It has been installed in a known location and it knows where its resources are.
Unfortunately, Python often appears to be designed for the specific needs of python.exe, the “canonical embedding application”. When one calls Py_Initialize(), a number of magic steps are invoked whereby the Python runtime tries to guess the initial setting for sys.path. This may involve finding the program location, looking at the PYTHONPATH environment variable, and so on. When Py_Initialize() returns, it may be too late to modify sys.path because in the mean time, module imports could have occured, such as that of copy_reg.
I have found that circumventing this involves patching pythoncore itself. What we do in EVE before calling Py_Initialize() is to call a custom API, Py_SetPath() with an application-crafted semicolon-separated path string. This will turn off any path-guessing in pythoncore and gives us absolute control.
Before we started doing this, for example, we could not encourage developers to have Python installed on their workstations, for example. We would invariably run into conflicts where the embedded python picked up modules from the installed python and mysterious things would happen. Now there is no need, and the embedded Python and the installed Python can coexsist without conflict.
I’ve recently contributed this patch to python.org.