PyTools.c

Go to the documentation of this file.
00001 /*
00002 PPEMBED, VERSION 2.0
00003 AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
00004 
00005 Copyright 1996-2000, by Mark Lutz, and O'Reilly and Associates.
00006 Permission to use, copy, modify, and distribute this software 
00007 for any purpose and without fee is hereby granted.  This software
00008 is provided on an as is basis, without warranties of any kind.
00009 */
00010 
00011 #include <FCConfig.h>
00012 #include "PyTools.h"
00013 
00014 #include <stdarg.h>
00015 #include <string.h>
00016 #include <assert.h>
00017 #include <compile.h>
00018 #include <eval.h>
00019 
00020 
00021 #if PY_VERSION_HEX <= 0x02050000
00022 #error "Use Python2.5.x or higher"
00023 #endif
00024 
00025 
00026 /*****************************************************************************
00027  * RUN EMBEDDED OBJECT METHODS, ACCESS OBJECT ATTRIBUTES 
00028  * handles attribute fetch, debugging, input/output conversions; 
00029  * there is no module to reload here: assumes a known object;
00030  *****************************************************************************/
00031 
00032 int
00033 PP_Run_Method(PyObject *pobject,  const char *method,
00034                   const char *resfmt,   void *cresult,        /* convert to c/c++ */
00035                   const char *argfmt,   ... /* arg,... */ )   /* convert to python */
00036 {
00037     PyObject *pmeth, *pargs, *presult;
00038     va_list argslist;                              /* "pobject.method(args)" */
00039     va_start(argslist, argfmt);
00040 
00041     Py_Initialize();                               /* init if first time */
00042     pmeth = PyObject_GetAttrString(pobject, method);  
00043     if (pmeth == NULL)                             /* get callable object */
00044         return -1;                                 /* bound method? has self */
00045         /* handle zero args different */
00046 //      if(resfmt == 0 || strcmp(resfmt,"") == 0)
00047 //              pargs = Py_BuildValue("()");
00048 //      else
00049                 pargs = Py_VaBuildValue(argfmt, argslist);     /* args: c->python */
00050 
00051     if (pargs == NULL) {
00052         Py_DECREF(pmeth);
00053         return -1;
00054     }
00055     if (PP_DEBUG)                                    /* debug it too? */ 
00056         presult = PP_Debug_Function(pmeth, pargs); 
00057     else 
00058         presult = PyEval_CallObject(pmeth, pargs);   /* run interpreter */
00059 
00060     Py_DECREF(pmeth);
00061     Py_DECREF(pargs);
00062 //      if(cresult != 0 && resfmt != 0)
00063                 return PP_Convert_Result(presult, resfmt, cresult);    /* to C format */
00064 //      else 
00065 //              return 0;
00066 }
00067  
00068 
00069 int
00070 PP_Get_Member(PyObject *pobject, const char *attrname,
00071                   const char *resfmt,  void *cresult)         /* convert to c/c++ */
00072 {
00073     PyObject *pmemb;                                    /* "pobject.attrname" */
00074     Py_Initialize();                        
00075     pmemb = PyObject_GetAttrString(pobject, attrname);  /* incref'd */
00076     return PP_Convert_Result(pmemb, resfmt, cresult);   /* to C form, decrefs */
00077 }
00078  
00079 
00080 int
00081 PP_Set_Member(PyObject *pobject, const char *attrname,
00082                   const char *argfmt,  ... /* arg,... */ )    /* convert to python */
00083 {
00084     int result;
00085     PyObject *pval;
00086     va_list argslist;                             /* "pobject.attrname = v" */
00087     va_start(argslist, argfmt);
00088     Py_Initialize();                              /* init if first time */
00089     pval = Py_VaBuildValue(argfmt, argslist);     /* input: C->Python */
00090     if (pval == NULL) 
00091         return -1;
00092     result = PyObject_SetAttrString(pobject, attrname, pval);     /* setattr */
00093     Py_DECREF(pval); 
00094     return result;
00095 }
00096 
00097 
00098 /*****************************************************************************
00099  * RUN EMBEDDED MODULE FUNCTIONS 
00100  * handles module (re)import, debugging, input/output conversions;  
00101  * note: also useful for calling classes (and C type constructors) at the 
00102  * top-level of a module to make Python instances: use class-name (or type
00103  * constructor function name) and 'O' result convert-code to get raw object;
00104  * use argfmt="()" for no args, cresult='NULL' for no result (procedure);
00105  * New tools: support for calling known Python objects directly;
00106  *****************************************************************************/
00107 
00108 int
00109 PP_Run_Function(const char *modname, const char *funcname,          /* load from module */
00110                 const char *resfmt,  void *cresult,           /* convert to c/c++ */
00111                 const char *argfmt,  ... /* arg, arg... */ )  /* convert to python */
00112 {
00113     /* call a function or class in a module */
00114     PyObject *func, *args, *presult;
00115     va_list argslist;
00116     va_start(argslist, argfmt);                   /* "modname.funcname(args)" */
00117 
00118     func = PP_Load_Attribute(modname, funcname);  /* may reload; incref'd */
00119     if (func == NULL)                             /* func or class or C type */
00120         return -1;
00121     args = Py_VaBuildValue(argfmt, argslist);     /* convert args to python */
00122     if (args == NULL) {                           /* args incref'd */
00123         Py_DECREF(func);
00124         return -1;
00125     }
00126     if (PP_DEBUG && strcmp(modname, "pdb") != 0)    /* debug this call? */
00127         presult = PP_Debug_Function(func, args);    /* run in pdb; incref'd */
00128     else
00129         presult = PyEval_CallObject(func, args);    /* run function; incref'd */
00130 
00131     Py_DECREF(func);
00132     Py_DECREF(args);                                    /* result may be None */
00133     return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
00134 }
00135 
00136 
00137 PyObject *
00138 PP_Debug_Function(PyObject *func, PyObject *args)
00139 {
00140     int oops, res;
00141     PyObject *presult;
00142 
00143     /* expand tuple at front */
00144     // it seems that some versions of python want just 2 arguments; in that
00145     // case, remove trailing 1
00146 #if (PY_MAJOR_VERSION==2)&&(PY_MINOR_VERSION>=2)
00147     oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args))); 
00148 #else
00149     oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args)),1); 
00150 #endif    
00151     oops |= PyTuple_SetItem(args, 0, func);   
00152     if (oops) 
00153         return NULL;                        /* "args = (funcobj,) + (arg,..)" */
00154 
00155     res = PP_Run_Function(                  /* "pdb.runcall(funcobj, arg,..)" */
00156                  "pdb",  "runcall",         /* recursive run_function */
00157                  "O",    &presult,
00158                  "O",     args);            /* args already is a tuple */
00159     return (res != 0) ? NULL : presult;     /* errors in run_function? */
00160 }                                           /* presult not yet decref'd */
00161 
00162 
00163 int
00164 PP_Run_Known_Callable(PyObject *object,               /* func|class|method */
00165                       const char *resfmt, void *cresult,    /* skip module fetch */
00166                       const char *argfmt, ... /* arg,.. */) /* convert args, result */
00167 {
00168     /* call a known callable object */
00169     PyObject *args, *presult;
00170     va_list argslist;
00171     va_start(argslist, argfmt);                     /* "return object(args)" */
00172 
00173     Py_Initialize(); 
00174     args = Py_VaBuildValue(argfmt, argslist);       /* convert args to python */
00175     if (args == NULL)                               /* args incref'd */
00176         return -1;
00177     if (PP_DEBUG)                                   /* debug this call? */
00178         presult = PP_Debug_Function(object, args);  /* run in pdb; incref'd */
00179     else
00180         presult = PyEval_CallObject(object, args);  /* run function; incref'd */
00181 
00182     Py_DECREF(args);                                    /* result may be None */
00183     return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
00184 }
00185 
00186 /*****************************************************************************
00187  * PYTHON EXCEPTION INFORMATION ACCESS
00188  * fetch Python-related error info (type, value);
00189  * after an API call returns an exception indicator, call 
00190  * PP_Fetch_Error_Text, then get text from the 3 char[]'s;
00191  * note: calling PyErr_Fetch() clears/erases the current 
00192  * exception in the Python system, as does PyErr_Print(), 
00193  * so you should call one of these, one time, per exception:
00194  * caveats: not thread-specific since saves data in globals,
00195  * and only exports traceback object (the exception type and 
00196  * data are converted to text strings and disgarded);  the 
00197  * PyErr_Print() built-in also does a bit more on syntax errors,
00198  * and sends its text to sys.stderr: in principle, we could
00199  * assign stderr to a StringIO object and call PyErr_Print, but
00200  * the code here makes the 3 exception components more distinct;
00201  *****************************************************************************/
00202 
00203 #define MAX 2024
00204 /*
00205 FC_OS_LINUX: This is dangerous. How about PY_EXCEPT_MAX?
00206 */
00207 
00208 /* exception text is here after PP_Fetch_Error_Text call */
00209 char PP_last_error_type[MAX];           /* exception name text */
00210 char PP_last_error_info[MAX];           /* exception data text */
00211 char PP_last_error_trace[MAX];          /* exception traceback text */
00212 PyObject *PP_last_traceback = NULL;     /* saved exception traceback object */
00213 
00214 
00215 void PP_Fetch_Error_Text()
00216 {
00217     // called without exception happened!
00218     //assert(PyErr_Occurred());
00219 
00220     char *tempstr;
00221     PyObject *errobj, *errdata, *errtraceback, *pystring;
00222 
00223     /* get latest python exception information */
00224     /* this also clears the current exception  */
00225 
00226     PyErr_Fetch(&errobj, &errdata, &errtraceback);       /* all 3 incref'd */
00227 
00228 
00229     /* convert type and data to strings */
00230     /* calls str() on both to stringify */
00231 
00232     pystring = NULL;
00233     if (errobj != NULL &&
00234        (pystring = PyObject_Str(errobj)) != NULL &&      /* str(errobj) */
00235        (PyString_Check(pystring)) )                      /* str() increfs */
00236     {
00237         strncpy(PP_last_error_type, PyString_AsString(pystring), MAX); /*Py->C*/
00238         PP_last_error_type[MAX-1] = '\0';
00239     }
00240     else 
00241         strcpy(PP_last_error_type, "<unknown exception type>");
00242     Py_XDECREF(pystring);
00243 
00244 
00245     pystring = NULL;
00246     if (errdata != NULL &&
00247        (pystring = PyObject_Str(errdata)) != NULL &&     /* str(): increfs */
00248        (PyString_Check(pystring)) )
00249     {
00250         strncpy(PP_last_error_info, PyString_AsString(pystring), MAX); /*Py->C*/
00251         PP_last_error_info[MAX-1] = '\0';
00252     }
00253     else 
00254         strcpy(PP_last_error_info, "<unknown exception data>");
00255     Py_XDECREF(pystring);
00256 
00257 
00258     /* convert traceback to string */ 
00259     /* print text to a StringIO.StringIO() internal file object, then */
00260     /* fetch by calling object's .getvalue() method (see lib manual); */
00261 
00262     pystring = NULL;
00263     if (errtraceback != NULL &&
00264        (PP_Run_Function("StringIO", "StringIO", "O", &pystring, "()") == 0) &&
00265        (PyTraceBack_Print(errtraceback, pystring) == 0) &&
00266        (PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) )
00267     {
00268         strncpy(PP_last_error_trace, tempstr, MAX); 
00269         PP_last_error_trace[MAX-1] = '\0';
00270         free(tempstr);  /* it's a strdup */
00271     }
00272     else 
00273         strcpy(PP_last_error_trace, "<unknown exception traceback>"); 
00274     Py_XDECREF(pystring);
00275 
00276 
00277     Py_XDECREF(errobj);
00278     Py_XDECREF(errdata);               /* this function owns all 3 objects */
00279     Py_XDECREF(PP_last_traceback);     /* they've been NULL'd out in Python */ 
00280     PP_last_traceback = errtraceback;  /* save/export raw traceback object */
00281 }
00282 
00283 
00284 /*****************************************************************************
00285  * GET/SET MODULE-LEVEL (GLOBAL) PYTHON VARIABLES BY NAME
00286  * handles module (re)loading, input/output conversions;
00287  * useful for passing data to/from codestrings (no args or return 
00288  * val)--load module, set inputs, run codestring, get outputs;
00289  * subtle thing: Python "s" output conversion code sets a C char* to 
00290  * the text in the middle of a Python string object, which may be
00291  * returned to the heap if decref'd--this api copies the text to a new
00292  * char array (with strdup) that the caller must free() when possible,
00293  * rather than assuming the caller can and will copy the result out;
00294  * could postpone the decref till next api call, but that's too subtle;
00295  *****************************************************************************/
00296 
00297 
00298 int
00299 PP_Convert_Result(PyObject *presult, const char *resFormat, void *resTarget)
00300 {
00301     if (presult == NULL)                /* error when run: fail */
00302         return -1;
00303     else
00304     if (resTarget == NULL) {            /* passed target=NULL: ignore result */
00305         Py_DECREF(presult);             /* procedures and stmts return None  */
00306         return 0;
00307     }
00308     else
00309     if (! PyArg_Parse(presult, resFormat, resTarget)) {  /* convert Python->C */
00310         Py_DECREF(presult);                              /* need not be tuple */
00311         return -1;                                       /* error in convert  */
00312     }
00313     else {
00314         if (strcmp(resFormat, "O") != 0) {     /* free object unless exported */
00315             if (strcmp(resFormat, "s") == 0) { /* copy string: caller owns it */
00316                 char **target = (char**) resTarget;
00317 #if defined (__GNUC__)
00318                 *target = strdup(*target);
00319 #else
00320                 *target = _strdup(*target);
00321 #endif
00322             }
00323             Py_DECREF(presult);
00324         }
00325         return 0;                     /* returns 0=success, -1=failure */
00326     }                                 /* if 0: C result in *resTarget  */
00327 }                                     /* caller must decref if fmt="O" */
00328                                       /* caller must free() if fmt="s" */
00329 
00330 int
00331 PP_Get_Global(const char *modname, const char *varname, const char *resfmt, void *cresult)
00332 {
00333     PyObject *var;                                   /* "x = modname.varname" */
00334     var = PP_Load_Attribute(modname, varname);       /* var is incref'd */
00335     return PP_Convert_Result(var, resfmt, cresult);  /* convert var to C form */
00336 }
00337 
00338 
00339 int
00340 PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ... /* cval(s) */) 
00341 {
00342     int result;
00343     PyObject *module, *val;                     /* "modname.varname = val" */
00344     va_list cvals;
00345     va_start(cvals, valfmt);                    /* C args after valfmt */
00346 
00347     module = PP_Load_Module(modname);           /* get/load module */
00348     if (module == NULL) 
00349         return -1;
00350     val = Py_VaBuildValue(valfmt, cvals);       /* convert input to Python */
00351     va_end(cvals);
00352     if (val == NULL) 
00353         return -1;
00354     result = PyObject_SetAttrString(module, varname, val); 
00355     Py_DECREF(val);                             /* set global module var */
00356     return result;                              /* decref val: var owns it */
00357 }                                               /* 0=success, varname set */
00358 
00359 
00360 /*****************************************************************************
00361  * MODULE INTERFACE 
00362  * make/import/reload a python module by name
00363  * Note that Make_Dummy_Module could be implemented to keep a table
00364  * of generated dictionaries to be used as namespaces, rather than 
00365  * using low level tools to create and mark real modules; this 
00366  * approach would require extra logic to manage and use the table;
00367  * see basic example of using dictionaries for string namespaces;
00368  *****************************************************************************/
00369 
00370 
00371 int PP_RELOAD = 0;    /* reload modules dynamically? */
00372 int PP_DEBUG  = 0;    /* debug embedded code with pdb? */
00373 
00374 
00375 const char *PP_Init(const char *modname) {
00376     Py_Initialize();                               /* init python if needed */
00377 //#ifdef FC_OS_LINUX /* cannot convert `const char *' to `char *' in assignment */
00378     if (modname!=NULL) return modname;
00379     { /* we assume here that the caller frees allocated memory */
00380       char* __main__=(char *)malloc(sizeof("__main__"));
00381       return __main__="__main__";
00382     }
00383 //#else    
00384 //    return modname == NULL ? "__main__" : modname;  /* default to '__main__' */
00385 //#endif    
00386 }
00387 
00388 
00389 int
00390 PP_Make_Dummy_Module(const char *modname)   /* namespace for strings, if no file */
00391 {                                     /* instead of sharing __main__ for all */
00392     PyObject *module, *dict;          /* note: __main__ is created in py_init */
00393     Py_Initialize();
00394     module = PyImport_AddModule(modname);    /* fetch or make, no load */
00395     if (module == NULL)                      /* module not incref'd */
00396         return -1;                  
00397     else {                                            /* module.__dict__ */
00398         dict = PyModule_GetDict(module);              /* ['__dummy__'] = None */
00399         PyDict_SetItemString(dict, "__dummy__", Py_None); 
00400         PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
00401         return 0;
00402     }
00403 }
00404 
00405 
00406 PyObject *                          /* returns module object named modname  */
00407 PP_Load_Module(const char *modname)       /* modname can be "package.module" form */
00408 {                                   /* reload just resets C extension mods  */
00409     /* 
00410      * 4 cases:
00411      * - module "__main__" has no file, and not prebuilt: fetch or make
00412      * - dummy modules have no files: don't try to reload them
00413      * - reload=on and already loaded (on sys.modules): "reload()" before use
00414      * - not loaded yet, or loaded but reload=off: "import" to fetch or load 
00415      */
00416 
00417     PyObject *module, *sysmods;                  
00418     modname = PP_Init(modname);                       /* default to __main__ */
00419 
00420     if (strcmp(modname, "__main__") == 0)             /* main: no file */
00421         return PyImport_AddModule(modname);           /* not increfd */
00422 
00423     sysmods = PyImport_GetModuleDict();               /* get sys.modules dict */
00424     module  = PyDict_GetItemString(sysmods, modname); /* mod in sys.modules? */
00425     
00426     if (module != NULL &&                             /* dummy: no file */
00427         PyModule_Check(module) && 
00428         PyDict_GetItemString(PyModule_GetDict(module), "__dummy__")) {
00429         return module;                                /* not increfd */
00430     }
00431     else
00432     if (PP_RELOAD && module != NULL && PyModule_Check(module)) {
00433         module = PyImport_ReloadModule(module);       /* reload file,run code */
00434         Py_XDECREF(module);                           /* still on sys.modules */
00435         return module;                                /* not increfd */
00436     }
00437     else {  
00438         module = PyImport_ImportModule(modname);      /* fetch or load module */
00439         Py_XDECREF(module);                           /* still on sys.modules */
00440         return module;                                /* not increfd */
00441     }
00442 }
00443 
00444 
00445 PyObject *
00446 PP_Load_Attribute(const char *modname, const char *attrname)
00447 {
00448     PyObject *module;                         /* fetch "module.attr" */
00449     modname = PP_Init(modname);               /* use before PyEval_CallObject */
00450     module  = PP_Load_Module(modname);        /* not incref'd, may reload */
00451     if (module == NULL)
00452         return NULL;
00453     return PyObject_GetAttrString(module, attrname);  /* func, class, var,.. */
00454 }                                                     /* caller must xdecref */
00455 
00456 
00457 /* extra ops */
00458 int
00459 PP_Run_Command_Line(const char *prompt)
00460 {
00461     int res;               /* interact with python, in "__main__" */
00462     Py_Initialize();       /* in the program's "stdio" window     */
00463     if (prompt != NULL)
00464 #if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX)
00465         printf("[%s <Use Ctrl-D (i.e. EOF) to exit.>]\n", prompt);
00466 #elif defined (FC_OS_WIN32)
00467         printf("[%s <Use Ctrl-Z plus Return to exit.>]\n", prompt);
00468 #endif
00469     res = PyRun_InteractiveLoop(stdin, "<stdin>");
00470     return res;
00471 }
00472 
00473 /*****************************************************************************
00474  * RUN EMBEDDED CODE-STRINGS 
00475  * handles debugging, module (re)loading, namespaces, output conversions;
00476  * pbd.runeval returns a value: "eval(expr + '\n', globals, locals)";
00477  * pdb.run is just a statement: "exec cmd + '\n' in globals, locals"
00478  * New tools: precompiling strings to bytecode, running bytecode; 
00479  *****************************************************************************/
00480 
00481 
00482 
00483 int
00484 PP_Run_Codestr(PPStringModes mode, const char *code,  /* expr or stmt string */
00485                const char *modname,                   /* loads module if needed */
00486                const char *resfmt, void *cresult)     /* converts expr result to C */
00487 {
00488     /* run a string of Python code */
00489     int parse_mode;                             /* "eval(code, d, d)", or */
00490     PyObject *module, *dict, *presult;          /* "exec code in d, d" */
00491 
00492     module = PP_Load_Module(modname);           /* get module, init python */
00493     if (module == NULL)                         /* not incref'd */
00494         return -1;
00495     dict = PyModule_GetDict(module);            /* get dict namespace */
00496     if (dict == NULL)                           /* not incref'd */
00497         return -1;
00498 
00499     parse_mode = (mode == PP_EXPRESSION ? Py_eval_input : Py_file_input);
00500     if (PP_DEBUG) 
00501         presult = PP_Debug_Codestr(mode, code, dict);         /* run in pdb */
00502     else 
00503         presult = PyRun_String(code, parse_mode, dict, dict); /* eval direct */
00504                                                               /* increfs res */
00505     if (mode == PP_STATEMENT) {
00506         int result = (presult == NULL? -1 : 0);          /* stmt: 'None' */
00507         Py_XDECREF(presult);                             /* ignore result */
00508         return result;
00509     }
00510     return PP_Convert_Result(presult, resfmt, cresult);  /* expr val to C */
00511 }
00512 
00513 
00514 PyObject *
00515 PP_Compile_Codestr(PPStringModes mode,    /* precompile string to bytecode */
00516                    const char *codestr)         /* pass result to PP_Run_Bytecode */
00517 {
00518     int start;
00519     Py_Initialize();
00520     switch (mode) {
00521     case PP_STATEMENT:
00522         start = Py_file_input; break;
00523     case PP_EXPRESSION:
00524         start = Py_eval_input; break;
00525     default:
00526         start = Py_single_input;  /* prints expr results */
00527     }
00528     return Py_CompileString(codestr, "<PP_Compile_Codestr>", start);
00529 }
00530 
00531 
00532 int
00533 PP_Run_Bytecode(PyObject *codeobj,           /* run compiled bytecode object */
00534                 const char     *modname,           /* in named module's namespace */
00535                 const char     *resfmt, void *restarget)
00536 {
00537     PyObject *presult, *module, *dict;
00538 
00539     if (! PyCode_Check(codeobj))             /* make sure it's bytecode */
00540         return -1;
00541     module = PP_Load_Module(modname);        /* get module, init python */
00542     if (module == NULL)                      /* not incref'd */
00543         return -1;
00544     dict = PyModule_GetDict(module);         /* get dict namespace */
00545     if (dict == NULL)                        /* not incref'd */
00546         return -1;
00547     if (PP_DEBUG)
00548         presult = PP_Debug_Bytecode(codeobj, dict);        /* run in pdb */
00549     else
00550         presult = PyEval_EvalCode((PyCodeObject *)codeobj, dict, dict);
00551     return PP_Convert_Result(presult, resfmt, restarget);  /* expr val to C */
00552 }
00553 
00554 
00555 /**************************************************************************
00556  * subtle things:
00557  * 1) pdb.run and pdb.runeval both accept either a string or a
00558  * compiled code object, just because they call the built in exec and 
00559  * eval(), which allow either form;  further, eval() works on code
00560  * objects compiled as either expressions or statements, but returns
00561  * None as the result of statements, so we don't need to distinguish 
00562  * between expressions and statements here again for bytecode (we 
00563  * did when compiling); the equivalents in Python code:
00564  *     >>> a = 1
00565  *     >>> s = compile('x = 1', '', 'exec')
00566  *     >>> e = compile('a + 1', '', 'eval')
00567  *     >>> print eval(e)
00568  *     2
00569  *     >>> print eval(s)
00570  *     None
00571  * on the other hand, we can't blindly use pdb.runeval when dealing  
00572  * with uncompiled strings, because eval() fails on statement strings;
00573  *
00574  * 2) in 1.5, if you debug a string or bytecode object in a module's
00575  * namespace where you've already debugged once, you may see a bogus
00576  * return value on entry which is left over from a prior debug; this
00577  * is because pdb leaves a '__return__' attribute in the module's
00578  * dictionary, which may be a pdb bug, but we work around it here by
00579  * manually deleting __return__ if present before starting pdb again;
00580  * only happens for strings--function namespaces aren't persistent;
00581  **************************************************************************/
00582 
00583 
00584 static void fixPdbRetval(PyObject *moddict) 
00585     { if (PyDict_DelItemString(moddict, "__return__")) PyErr_Clear(); }
00586 
00587 
00588 PyObject *
00589 PP_Debug_Codestr(PPStringModes mode, const char *codestring, PyObject *moddict)
00590 {
00591     int res;
00592     PyObject *presult;
00593     const char *pdbname = (mode == PP_EXPRESSION ? "runeval" : "run");
00594     fixPdbRetval(moddict);
00595                                       /* pass code to a pbd.py function    */
00596     res = PP_Run_Function(            /* "pdb.run(stmt, gdict, ldict)"     */
00597              "pdb",    pdbname,       /* "pdb.runeval(expr, gdict, ldict)" */
00598              "O",      &presult,
00599              "(sOO)",  codestring, moddict, moddict); 
00600     return (res != 0) ? NULL : presult;     /* return null or increfd object */
00601 }
00602 
00603 
00604 PyObject *
00605 PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict)
00606 {
00607     int res;
00608     PyObject *presult;
00609     fixPdbRetval(moddict);
00610     res = PP_Run_Function(            /* "pdb.runeval(codeobj, gdict, ldict)" */
00611              "pdb",    "runeval",     /* accepts string|code, code=stmt|expr  */
00612              "O",      &presult,
00613              "(OOO)",  codeobject, moddict, moddict); 
00614     return (res != 0) ? NULL : presult;     /* null if error in run_function */
00615 }
00616 
00617 
00618 
00619 

Generated on Wed Nov 23 19:00:32 2011 for FreeCAD by  doxygen 1.6.1