In the following MCVE two different scripts get executed. Both don't do anything special, the first one has an empty function, the second script does literally nothing. But depending on the script PyEval_EvalCode increfs the passed global/local dictionary or not. The documentation doesn't say anything. But depending on the script I have a dangling dictionary after it got executed. When do I have to decref them afterwards or when not? Or what am I missing here? The following C snippet outputs the refcount of the passed dictionaries.
I tried this on Windows with the standard Python-2.7 interpreter.
#pragma comment(lib, "C:\\Python27\\libs\\python27.lib")
#include "C:\\Python27\\include\\Python.h"
static int execute(const char* script)
{
PyObject* globals = PyDict_New();
PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
PyObject* code = Py_CompileString(script, "test", Py_file_input);
if (!code)
{
PyErr_Print();
return 0;
}
PyObject* result = PyEval_EvalCode((PyCodeObject*)code, globals, nullptr);
Py_DECREF(code);
if (!result)
{
PyErr_Print();
return 0;
}
Py_DECREF(result);
printf("Refcount of globals: %zd\n", globals->ob_refcnt);
Py_DECREF(globals); // missing decref spotted by user2357112
return 0;
}
int main()
{
const char* script = nullptr;
Py_Initialize();
// First script contains a function
script =
"def main():\n" \
" pass\n" \
"main()\n";
execute(script);
// second script does nothing
script = "12345";
execute(script);
Py_Finalize();
return 0;
}