4

Importing Python modules from files is relatively easy with the Python C API with PyImport_Import() however I would need to use functions stored in strings. Is there a way to import python modules from strings (to clarify: there is no file; the code is in a string) or will I have to save the strings as temp files?

3 Answers 3

4

No need to use temp files. Use this code:

const char *MyModuleName = "blah";
const char *MyModuleCode = "print 'Hello world!'";
PyObject *pyModule = PyModule_New(MyModuleName);
// Set properties on the new module object
PyModule_AddStringConstant(pyModule, "__file__", "");
PyObject *localDict = PyModule_GetDict(pyModule);   // Returns a borrowed reference: no need to Py_DECREF() it once we are done
PyObject *builtins = PyEval_GetBuiltins();  // Returns a borrowed reference: no need to Py_DECREF() it once we are done
PyDict_SetItemString(localDict, "__builtins__", builtins);

// Define code in the newly created module
PyObject *pyValue = PyRun_String(MyModuleCode, Py_file_input, localDict, localDict);
if (pyValue == NULL) {
    // Handle error
}
else
    Py_DECREF(pyValue);

This is code taken from a real commercial application (I've slightly modified it by removing error handling and other non-needed details). Just set the wanted module name in MyModuleName and the Python code in MyModuleCode and you are done!

Sign up to request clarification or add additional context in comments.

Comments

1

If my understanding is correct, you could use PyImport_ImportModule which takes a const char* name to specify the module to be imported.

Since my understanding was incorrect:

It would generally be better to dump the contents to a .py file and then execute them with PyRun_File but, if you have strings and want to work with those I guess you could use Py_CompileString to compile it to a code object and then feed it to PyEval_EvalCode for evaluation.

6 Comments

There is no file; the module contents are stored in a string.
Hm, you can't dump the contents to a file and then import it? I'm pretty sure there's functions to exec valid python code, could you add some examples?
My application contains a text editing area where the user can type python code and execute it. To execute the code the program puts in function and calls it.
Dumping it in a temporary file and then letting python parse, compile and eval it should be way easier. If you need to do manually, the functions I added should help you out.
Is it possible to replace a function with a nother function with the same name and parameters so the code can be edited?
|
0

I've had success following the strategy laid out by Dimitirs.

            Py_Initialize();
            PyObject *module = Py_CompileString(
                // language: Python
                R"EOT(
fake_policy = {
      "maxConnections": 4,
      "policyDir": "/tmp",
      "enableVhostPolicy": True,
      "enableVhostNamePatterns": False,
})EOT",
                "test_module", Py_file_input);
            REQUIRE(module != nullptr);

            PyObject *pModuleObj = PyImport_ExecCodeModule("test_module", module);
            REQUIRE(pModuleObj != nullptr);
            // better to check with an if, use PyErr_Print() or such to read the error

            PyObject *pAttrObj = PyObject_GetAttrString(pModuleObj, "fake_policy");
            REQUIRE(pAttrObj != nullptr);

            auto *entity = reinterpret_cast<qd_entity_t *>(pAttrObj);
            REQUIRE(qd_entity_has(entity, "enableVhostNamePatterns"));  // sanity check for the test input

            // call Py_DecRef s

I used https://awasu.com/weblog/embedding-python/calling-python-code-from-your-program/ as another reference, when writing this.

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.