text: /*****************************************************************************
   * 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 <ctrl-d exits>]\n", prompt);
      res = PyRun_InteractiveLoop(stdin, "<stdin>");
      return res;
  }
  