/***************************************************************************** * MODULE INTERFACE * make/import/reload a python module by name * Note that Make_Dummy_Module could be implemented to keep a table * of generated dictionaries to be used as namespaces, rather than * using low level tools to create and mark real modules; this * approach would require extra logic to manage and use the table; * see basic example of using dictionaries for string namespaces; *****************************************************************************/ #include "ppembed.h" int PP_RELOAD = 0; /* reload modules dynamically? */ int PP_DEBUG = 0; /* debug embedded code with pdb? */ char *PP_Init(char *modname) { Py_Initialize(); /* init python if needed */ return modname == NULL? "__main__" : modname; /* default to '__main__' */ } int PP_Make_Dummy_Module(char *modname) /* namespace for strings, if no file */ { /* instead of sharing __main__ for all */ PyObject *module, *dict; /* note: __main__ is created in py_init */ Py_Initialize(); module = PyImport_AddModule(modname); /* fetch or make, no load */ if (module == NULL) /* module not incref'd */ return -1; else { /* module.__dict__ */ dict = PyModule_GetDict(module); /* ['__dummy__'] = None */ PyDict_SetItemString(dict, "__dummy__", Py_None); PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()); return 0; } } PyObject * /* returns module object named modname */ PP_Load_Module(char *modname) /* modname can be "package.module" form */ { /* reload just resets C extension mods */ /* * 4 cases: * - module "__main__" has no file, and not prebuilt: fetch or make * - dummy modules have no files: don't try to reload them * - reload=on and already loaded (on sys.modules): "reload()" before use * - not loaded yet, or loaded but reload=off: "import" to fetch or load */ PyObject *module, *sysmods; modname = PP_Init(modname); /* default to __main__ */ if (strcmp(modname, "__main__") == 0) /* main: no file */ return PyImport_AddModule(modname); /* not increfd */ sysmods = PyImport_GetModuleDict(); /* get sys.modules dict */ module = PyDict_GetItemString(sysmods, modname); /* mod in sys.modules? */ if (module != NULL && /* dummy: no file */ PyModule_Check(module) && PyDict_GetItemString(PyModule_GetDict(module), "__dummy__")) { return module; /* not increfd */ } else if (PP_RELOAD && module != NULL && PyModule_Check(module)) { module = PyImport_ReloadModule(module); /* reload file,run code */ Py_XDECREF(module); /* still on sys.modules */ return module; /* not increfd */ } else { module = PyImport_ImportModule(modname); /* fetch or load module */ Py_XDECREF(module); /* still on sys.modules */ return module; /* not increfd */ } } PyObject * PP_Load_Attribute(char *modname, char *attrname) { PyObject *module; /* fetch "module.attr" */ modname = PP_Init(modname); /* use before PyEval_CallObject */ module = PP_Load_Module(modname); /* not incref'd, may reload */ if (module == NULL) return NULL; return PyObject_GetAttrString(module, attrname); /* func, class, var,.. */ } /* caller must xdecref */ /* extra ops */ int PP_Run_Command_Line(char *prompt) { int res; /* interact with python, in "__main__" */ Py_Initialize(); /* in the program's "stdio" window */ if (prompt != NULL) printf("[%s ]\n", prompt); res = PyRun_InteractiveLoop(stdin, ""); return res; }