How to reinitialise an embedded Python interpreter?

前端 未结 3 1085
一向
一向 2021-02-04 13:06

I\'m working on embedding Python in our test suite application. The purpose is to use Python to run several tests scripts to collect data and make a report of tests. Multiple te

相关标签:
3条回答
  • 2021-02-04 13:29

    I'd write another shell script executing the sequence of test scripts with new instances of python each time. Or write it in python like

    # run your tests in the process first
    # now run the user scripts, each in new process to have virgin env
    for script in userScript:
        subprocess.call(['python',script])
    
    0 讨论(0)
  • 2021-02-04 13:43

    Here is another way I found to achieve what I want, start with a clean slate in the interpreter.

    I can control the global and local namespaces I use to execute the code:

    // get the dictionary from the main module
    // Get pointer to main module of python script
    object main_module = import("__main__");
    // Get dictionary of main module (contains all variables and stuff)
    object main_namespace = main_module.attr("__dict__");
    
    // define the dictionaries to use in the interpreter
    dict global_namespace;
    dict local_namespace;
    
    // add the builtins
    global_namespace["__builtins__"] = main_namespace["__builtins__"];
    

    I can then use use the namespaces for execution of code contained in pyCode:

    exec( pyCode, global_namespace, lobaca_namespace );
    

    I can clean the namespaces when I want to run a new instance of my test, by cleaning the dictionaries:

    // empty the interpreters namespaces
    global_namespace.clear();
    local_namespace.clear();        
    
    // Copy builtins to new global namespace
    global_namespace["__builtins__"] = main_namespace["__builtins__"];
    

    Depending at what level I want the execution, I can use global = local

    0 讨论(0)
  • 2021-02-04 13:45

    How about using code.IteractiveInterpreter?

    Something like this should do it:

    #include <boost/python.hpp>
    #include <string>
    #include <stdexcept>
    
    using namespace boost::python;
    
    std::string GetPythonError()
    {
        PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
        PyErr_Fetch(&ptype, &pvalue, &ptraceback);
        std::string message("");
        if(pvalue && PyString_Check(pvalue)) {
            message = PyString_AsString(pvalue);
        }
        return message;
    }
    
    // Must be called after Py_Initialize()
    void RunInterpreter(std::string codeToRun)
    {
        object pymodule = object(handle<>(borrowed(PyImport_AddModule("__main__"))));
        object pynamespace = pymodule.attr("__dict__");
    
        try {
            // Initialize the embedded interpreter
            object result = exec(   "import code\n"
                                    "__myInterpreter = code.InteractiveConsole() \n", 
                                    pynamespace);
            // Run the code
            str pyCode(codeToRun.c_str());
            pynamespace["__myCommand"] = pyCode;
            result = eval("__myInterpreter.push(__myCommand)", pynamespace);
        } catch(error_already_set) {
            throw std::runtime_error(GetPythonError().c_str());
        }
    }
    
    0 讨论(0)
提交回复
热议问题