#include <boost/algorithm/string/classification.hpp>
namespace alg = boost::algorithm;
+
MussaPython::MussaPython()
+{
+}
+
+void MussaPython::add_module(const std::string &name, python_module_init initfunc)
+{
+ python_modules.push_back( module_item(name, initfunc) );
+}
+
+void MussaPython::AppendInittab(const module_item &item)
+{
+ PyImport_AppendInittab(const_cast<char *>(item.first.c_str()), item.second);
+}
+
+void MussaPython::init_interpreter()
{
try {
- // add our mussa module to our environment
- PyImport_AppendInittab("mussa", &initmussa);
- PyImport_AppendInittab("mussaqui", &initmussaqui);
+ // add any compiled in modules to our environment
+ for_each(python_modules.begin(), python_modules.end(), AppendInittab);
// go ahead and finish initalizing python
Py_Initialize();
// get reference to the global namespace
py::object main_module(
(py::handle<>(py::borrowed(PyImport_AddModule("__main__"))))
);
+ // setting the main_namespace must come before any calls to run or eval
main_namespace = main_module.attr("__dict__");
- // FIXME: this really should be a configuration file?
- run("import __main__\n"
- "import mussa\n"
- "import mussaqui");
+ run("import __main__\n");
+ // import modules that were added to us into the interpreter
+ for(module_list::const_iterator item = python_modules.begin();
+ item != python_modules.end();
+ ++item)
+ {
+ std::string code("import " + item->first);
+ run(code);
+ }
} catch (py::error_already_set e) {
PyErr_Print();
}
}
+py::object MussaPython::get_namespace()
+{
+ if (main_namespace.ptr() == Py_None) {
+ init_interpreter();
+ }
+ return main_namespace;
+}
+
void MussaPython::run(std::string code)
{
try {
- PyObject *global_ptr = main_namespace.ptr();
+ PyObject *global_ptr = get_namespace().ptr();
py::object result( py::handle<>(
(PyRun_String(code.c_str(), Py_file_input, global_ptr, global_ptr)
)));
py::object MussaPython::eval(std::string code)
{
try {
- PyObject *global_ptr = main_namespace.ptr();
+ PyObject *global_ptr = get_namespace().ptr();
py::object result( py::handle<>(
(PyRun_String(code.c_str(), Py_eval_input, global_ptr, global_ptr)
)));
string_vector split_name;
alg::split(split_name, name, alg::is_any_of("."));
- py::object lookup = main_namespace["__main__"];
+ py::object lookup = get_namespace()["__main__"];
for (string_vector::const_iterator name_i = split_name.begin();
name_i != split_name.end();
}
//! return a reference to a single mussa python interpreter
-MussaPython& get_py()
+MussaPython *get_py()
{
static MussaPython *py;
if (!py) {
py = new MussaPython;
}
- return *py;
+ return py;
}
\ No newline at end of file