I am digging my way through the Python C-API and have problems understanding the scopes within a self created module. This code snipped explains my troubles:
std::string temp =
"\<PythonPath\>\\Lib;"
"\<PythonPath\>\\Lib\\site-packages;"
"\<PythonPath\>;";
std::wstring wsTmp(temp.begin(),temp.end());
Py_SetPath(wsTmp.c_str());
Py_Initialize();
PyObject* module = PyImport_AddModule("example");
PyModule_AddStringConstant(module, "__file__", "");
PyObject* pGlobal = PyDict_New();
PyObject* pLocal = PyModule_GetDict(module);
std::string script = "def blah(x):\n"
"\tprint(5 * x)\n"
"\treturn 77\n"
"def ShowLocals():\n"
"\tprint(locals())\n"
"def ShowGlobals():\n"
"\t print(globals())\n"
"def HelloWorld():\n"
"\t print(\"Hello World\")\n"
"\t ShowLocals()\n";
PyObject* pErfolg = PyRun_String(script.c_str(), Py_file_input, pGlobal, pLocal);
PyObject* helloWorld = PyObject_GetAttrString(module, "HelloWorld");
PyObject* pReturn = PyObject_CallObject(helloWorld, nullptr);
//Python ExceptionHandling:
PyObject* type, * value, * traceback;
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
PyObject* errorMessagePython = PyObject_Str(value);
std::string errorMessage = PyUnicode_AsUTF8(errorMessagePython);
Py_DECREF(errorMessagePython);
std::cout << errorMessage.c_str();
PyObject* getGlobals = PyObject_GetAttrString(module, "ShowGlobals");
pReturn = PyObject_CallObject(getGlobals, nullptr);
As you can see, I added multiple function definitions. From my understanding executes PyRun_String in the global module scope. I would assume that all the functions are known, in the order they are declared. Thus, it puzzles me quite a lot, that HelloWorld() cannot find ShowLocals().
If I execute
pErfolg = PyRun_String("locals()", Py_single_input, pGlobal, pLocal);
I can see that all of the definitions exist in the local scope of the module.
If I add global ShowLocals
before the function call, it works.
So my questions are:
Is there a way to make the functions known amongst all other functions in the module, without introducing them via global?
Why are the functions in the local directory and not in the global ?
Why can I make the function known via global? I also tried a print(globals()) in the HelloWorld function and none of the declared functions were listed.