3

I use Python 3.4 and Visual 2010. I'm embedding Python using the C API to give the user some script capabilities in processing his data. I call python functions defined by the user from my C++ code. I call specific function like Apply() for example that the user has to define in a Python file. Suppose the user has a file test.py where he has defined a function Apply() that process some data. All I have to do is to import his module and get a "pointer" to his python function from the C++.

PySys_SetPath(file_info.absolutePath().toUtf8().data()));
m_module = PyImport_ImportModule(module_name.toUtf8().data());
if (m_module)
{
    m_apply_function = PyObject_GetAttrString(m_module, "Apply");
    m_main_dict = PyModule_GetDict(m_module);
}

So far, so good. But if the user modifies his script, the new version of his function is never taken into account. I have to reboot my program to make it work... I read somewhere that I need to reload the module and get new pointers on functions but the PyImport_ReloadModule returns NULL with "Import error".

// .... code ....
// Reload the module
m_module = PyImport_ReloadModule(m_module);

Any ideas ? Best regards, Poukill

8
  • The module most probably isn't loading. Can you add a PyErr_Print to see if there's an exception and which exception is it ? Commented Feb 13, 2015 at 12:20
  • I can't use PyErrorPrint since I'm using the Python C API. But with some inspection, I have a "Import can't find module, or can't find name in module." Which is weird because I just loaded the module at this very same place (PySys_SetPath has been used for that). If I use PyImport_ImportModule instead, it's working, I get a valid pointer, but not updated. Commented Feb 13, 2015 at 16:25
  • PyErr_Print is a c api function, an alias to PyErr_PrintEx. There are a few caveats around reloading and name resolution. Is there a possibility to just restart the interpreter ? Commented Feb 13, 2015 at 17:22
  • 1
    have you tried importlib.reload(module)? Calling PyImport_ImportModule the second time is pointless; it probably just returns the cached value from sys.modules. Make sure PySys_SetPath argument contains all necessary paths (including pythonpath that is necessary for the user script). Commented Feb 14, 2015 at 12:36
  • @TasosVogiatzoglou : I know PyErr_Print is a C function, but it's printing directly into the python interpreter (sys.stderr) which I can not see. Like I said, I embed Python so I don't see the outputs of the interpreter for now, I have to capture the exception and the stacktrace using PyErr_Fetch(&ptype, &pvalue, &ptraceback), but it's not that easy. Restarting the interpreter may be a option, but clearly not the best as I would have to stop any running session. Commented Feb 16, 2015 at 8:30

1 Answer 1

1

The answer was found in the comments of my first post (thank you J.F Sebastian), the PySys_SetPath has to contain also the PYTHONPATH. In my case, that is the reason why the PyImport_ReloadModule was failing.

QString sys_path = file_info.absolutePath() + ";" + "C:\\Python34\\Lib";
PySys_SetPath(UTF8ToWide(sys_path.toUtf8().data()));
m_module = PyImport_ReloadModule(m_module); // Ok !
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.