4
AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
6
Copyright 1996-2000, by Mark Lutz, and O'Reilly and Associates.
7
Permission to use, copy, modify, and distribute this software
8
for any purpose and without fee is hereby granted. This software
9
is provided on an as is basis, without warranties of any kind.
19
#include <frameobject.h>
20
#if PY_VERSION_HEX < 0x030b0000
25
/*****************************************************************************
26
* RUN EMBEDDED OBJECT METHODS, ACCESS OBJECT ATTRIBUTES
27
* handles attribute fetch, debugging, input/output conversions;
28
* there is no module to reload here: assumes a known object;
29
*****************************************************************************/
32
PP_Run_Method(PyObject *pobject, const char *method,
33
const char *resfmt, void *cresult, /* convert to c/c++ */
34
const char *argfmt, ... /* arg,... */ ) /* convert to python */
36
PyObject *pmeth = NULL, *pargs = NULL, *presult = NULL;
37
va_list argslist; /* "pobject.method(args)" */
38
va_start(argslist, argfmt);
40
Py_Initialize(); /* init if first time */
41
pmeth = PyObject_GetAttrString(pobject, method);
42
if (pmeth == NULL) { /* get callable object */
44
return -1; /* bound method? has self */
47
pargs = Py_VaBuildValue(argfmt, argslist); /* args: c->python */
54
if (PP_DEBUG) /* debug it too? */
55
presult = PP_Debug_Function(pmeth, pargs);
57
#if PY_VERSION_HEX < 0x03090000
58
presult = PyEval_CallObject(pmeth, pargs); /* run interpreter */
60
presult = PyObject_CallObject(pmeth, pargs); /* run interpreter */
66
return PP_Convert_Result(presult, resfmt, cresult); /* to C format */
71
PP_Get_Member(PyObject *pobject, const char *attrname,
72
const char *resfmt, void *cresult) /* convert to c/c++ */
74
PyObject *pmemb = NULL; /* "pobject.attrname" */
76
pmemb = PyObject_GetAttrString(pobject, attrname); /* incref'd */
77
return PP_Convert_Result(pmemb, resfmt, cresult); /* to C form, decrefs */
82
PP_Set_Member(PyObject *pobject, const char *attrname,
83
const char *argfmt, ... /* arg,... */ ) /* convert to python */
86
PyObject *pval = NULL;
87
va_list argslist; /* "pobject.attrname = v" */
88
va_start(argslist, argfmt);
89
Py_Initialize(); /* init if first time */
90
pval = Py_VaBuildValue(argfmt, argslist); /* input: C->Python */
94
result = PyObject_SetAttrString(pobject, attrname, pval); /* setattr */
100
/*****************************************************************************
101
* RUN EMBEDDED MODULE FUNCTIONS
102
* handles module (re)import, debugging, input/output conversions;
103
* note: also useful for calling classes (and C type constructors) at the
104
* top-level of a module to make Python instances: use class-name (or type
105
* constructor function name) and 'O' result convert-code to get raw object;
106
* use argfmt="()" for no args, cresult='NULL' for no result (procedure);
107
* New tools: support for calling known Python objects directly;
108
*****************************************************************************/
111
PP_Run_Function(const char *modname, const char *funcname, /* load from module */
112
const char *resfmt, void *cresult, /* convert to c/c++ */
113
const char *argfmt, ... /* arg, arg... */ ) /* convert to python */
115
/* call a function or class in a module */
116
PyObject *func = NULL, *args = NULL, *presult = NULL;
118
va_start(argslist, argfmt); /* "modname.funcname(args)" */
120
func = PP_Load_Attribute(modname, funcname); /* may reload; incref'd */
121
if (func == NULL) { /* func or class or C type */
125
args = Py_VaBuildValue(argfmt, argslist); /* convert args to python */
127
if (args == NULL) { /* args incref'd */
131
if (PP_DEBUG && strcmp(modname, "pdb") != 0) /* debug this call? */
132
presult = PP_Debug_Function(func, args); /* run in pdb; incref'd */
134
#if PY_VERSION_HEX < 0x03090000
135
presult = PyEval_CallObject(func, args); /* run function; incref'd */
137
presult = PyObject_CallObject(func, args); /* run function; incref'd */
141
Py_DECREF(args); /* result may be None */
142
return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
147
PP_Debug_Function(PyObject *func, PyObject *args)
149
int oops = 0, res = 0;
150
PyObject *presult = NULL;
152
/* expand tuple at front */
153
// it seems that some versions of python want just 2 arguments; in that
154
// case, remove trailing 1
155
oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args)));
156
oops |= PyTuple_SetItem(args, 0, func);
158
return NULL; /* "args = (funcobj,) + (arg,..)" */
160
res = PP_Run_Function( /* "pdb.runcall(funcobj, arg,..)" */
161
"pdb", "runcall", /* recursive run_function */
163
"O", args); /* args already is a tuple */
164
return (res != 0) ? NULL : presult; /* errors in run_function? */
165
} /* presult not yet decref'd */
169
PP_Run_Known_Callable(PyObject *object, /* func|class|method */
170
const char *resfmt, void *cresult, /* skip module fetch */
171
const char *argfmt, ... /* arg,.. */) /* convert args, result */
173
/* call a known callable object */
174
PyObject *args = NULL, *presult = NULL;
176
va_start(argslist, argfmt); /* "return object(args)" */
179
args = Py_VaBuildValue(argfmt, argslist); /* convert args to python */
181
if (args == NULL) /* args incref'd */
183
if (PP_DEBUG) /* debug this call? */
184
presult = PP_Debug_Function(object, args); /* run in pdb; incref'd */
186
#if PY_VERSION_HEX < 0x03090000
187
presult = PyEval_CallObject(object, args); /* run function; incref'd */
189
presult = PyObject_CallObject(object, args); /* run function; incref'd */
192
Py_DECREF(args); /* result may be None */
193
return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
196
/*****************************************************************************
197
* PYTHON EXCEPTION INFORMATION ACCESS
198
* fetch Python-related error info (type, value);
199
* after an API call returns an exception indicator, call
200
* PP_Fetch_Error_Text, then get text from the 3 char[]'s;
201
* note: calling PyErr_Fetch() clears/erases the current
202
* exception in the Python system, as does PyErr_Print(),
203
* so you should call one of these, one time, per exception:
204
* caveats: not thread-specific since saves data in globals,
205
* and only exports traceback object (the exception type and
206
* data are converted to text strings and discarded); the
207
* PyErr_Print() built-in also does a bit more on syntax errors,
208
* and sends its text to sys.stderr: in principle, we could
209
* assign stderr to a StringIO object and call PyErr_Print, but
210
* the code here makes the 3 exception components more distinct;
211
*****************************************************************************/
215
FC_OS_LINUX: This is dangerous. How about PY_EXCEPT_MAX?
218
/* exception text is here after PP_Fetch_Error_Text call */
219
char PP_last_error_type[MAX]; /* exception name text */
220
char PP_last_error_info[MAX]; /* exception data text */
221
char PP_last_error_trace[MAX]; /* exception traceback text */
223
PyObject *PP_last_traceback = NULL; /* saved exception traceback object */
224
PyObject *PP_PyDict_Object = NULL; /* saved exception dictionary object */
225
PyObject *PP_last_exception_type = NULL; /* saved exception python type */
228
void PP_Fetch_Error_Text()
231
char *tempstr = NULL;
232
PyObject *errobj = NULL, *errdata = NULL, *errtraceback = NULL, *pystring = NULL, *pydict = NULL;
234
/* get latest python exception information */
235
/* this also clears the current exception */
237
PyErr_Fetch(&errobj, &errdata, &errtraceback); /* all 3 incref'd */
240
/* convert type and data to strings */
241
/* calls str() on both to stringify */
244
if (errobj != NULL &&
245
(pystring = PyObject_Str(errobj)) != NULL && /* str(errobj) */
246
(PyUnicode_Check(pystring)) ) /* str() increfs */
248
strncpy(PP_last_error_type, PyUnicode_AsUTF8(pystring), MAX); /*Py->C*/
249
PP_last_error_type[MAX-1] = '\0';
253
PP_last_error_type[0] = '\0';
256
Py_XDECREF(pystring);
260
if (errdata != NULL &&
261
(PyDict_Check(errdata)) ) /* str() increfs */
263
// PyDict_GetItemString returns a borrowed reference
264
// so we must make sure not to decrement the reference
265
PyObject* value = PyDict_GetItemString(errdata,"swhat");
268
strncpy(PP_last_error_info, PyUnicode_AsUTF8(value), MAX);
269
PP_last_error_info[MAX-1] = '\0';
275
else if (errdata != NULL &&
276
(pystring = PyObject_Str(errdata)) != NULL && /* str(): increfs */
277
(PyUnicode_Check(pystring)) )
279
strncpy(PP_last_error_info, PyUnicode_AsUTF8(pystring), MAX); /*Py->C*/
280
PP_last_error_info[MAX-1] = '\0';
283
strcpy(PP_last_error_info, "<unknown exception data>");
285
Py_XDECREF(pystring);
287
/* convert traceback to string */
288
/* print text to a StringIO.StringIO() internal file object, then */
289
/* fetch by calling object's .getvalue() method (see lib manual); */
292
if (errtraceback != NULL &&
293
(PP_Run_Function("io", "StringIO", "O", &pystring, "()") == 0) &&
295
(PyTraceBack_Print(errtraceback, pystring) == 0) &&
296
(PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) )
298
strncpy(PP_last_error_trace, tempstr, MAX);
299
PP_last_error_trace[MAX-1] = '\0';
300
free(tempstr); /* it's a strdup */
303
PyFrameObject* frame = PyEval_GetFrame();
306
int line = PyFrame_GetLineNumber(frame);
307
#if PY_VERSION_HEX < 0x030b0000
308
const char *file = PyUnicode_AsUTF8(frame->f_code->co_filename);
310
PyCodeObject* code = PyFrame_GetCode(frame);
311
const char *file = PyUnicode_AsUTF8(code->co_filename);
315
const char *_f = strstr(file, "\\src\\");
317
const char *_f = strstr(file, "/src/");
319
snprintf(PP_last_error_trace,sizeof(PP_last_error_trace),"%s(%d)",(_f?_f+5:file),line);
321
Py_XDECREF(pystring);
323
Py_XDECREF(PP_last_exception_type);
325
PP_last_exception_type = errobj;
328
PP_last_exception_type = 0;
330
Py_XDECREF(errdata); /* this function owns all 3 objects */
331
Py_XDECREF(PP_last_traceback); /* they've been NULL'd out in Python */
332
Py_XDECREF(PP_PyDict_Object);
333
PP_last_traceback = errtraceback; /* save/export raw traceback object */
334
PP_PyDict_Object = pydict;
338
/*****************************************************************************
339
* GET/SET MODULE-LEVEL (GLOBAL) PYTHON VARIABLES BY NAME
340
* handles module (re)loading, input/output conversions;
341
* useful for passing data to/from codestrings (no args or return
342
* val)--load module, set inputs, run codestring, get outputs;
343
* subtle thing: Python "s" output conversion code sets a C char* to
344
* the text in the middle of a Python string object, which may be
345
* returned to the heap if decref'd--this api copies the text to a new
346
* char array (with strdup) that the caller must free() when possible,
347
* rather than assuming the caller can and will copy the result out;
348
* could postpone the decref till next api call, but that's too subtle;
349
*****************************************************************************/
353
PP_Convert_Result(PyObject *presult, const char *resFormat, void *resTarget)
355
if (presult == NULL) /* error when run: fail */
358
if (resTarget == NULL) { /* passed target=NULL: ignore result */
359
Py_DECREF(presult); /* procedures and stmts return None */
362
if (! PyArg_Parse(presult, resFormat, resTarget)) { /* convert Python->C */
363
Py_DECREF(presult); /* need not be tuple */
364
return -1; /* error in convert */
366
if (strcmp(resFormat, "O") != 0) { /* free object unless exported */
367
if (strcmp(resFormat, "s") == 0) { /* copy string: caller owns it */
368
char **target = (char**) resTarget;
369
#if defined (__GNUC__)
370
*target = strdup(*target);
372
*target = _strdup(*target);
377
return 0; /* returns 0=success, -1=failure */
378
/* if 0: C result in *resTarget */
379
} /* caller must decref if fmt="O" */
380
/* caller must free() if fmt="s" */
383
PP_Get_Global(const char *modname, const char *varname, const char *resfmt, void *cresult)
385
PyObject *var = NULL; /* "x = modname.varname" */
386
var = PP_Load_Attribute(modname, varname); /* var is incref'd */
387
return PP_Convert_Result(var, resfmt, cresult); /* convert var to C form */
392
PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ... /* cval(s) */)
395
PyObject *module = NULL, *val = NULL; /* "modname.varname = val" */
397
va_start(cvals, valfmt); /* C args after valfmt */
399
module = PP_Load_Module(modname); /* get/load module */
400
if (module == NULL) {
404
val = Py_VaBuildValue(valfmt, cvals); /* convert input to Python */
408
result = PyObject_SetAttrString(module, varname, val);
409
Py_DECREF(val); /* set global module var */
410
return result; /* decref val: var owns it */
411
} /* 0=success, varname set */
414
/*****************************************************************************
416
* make/import/reload a python module by name
417
* Note that Make_Dummy_Module could be implemented to keep a table
418
* of generated dictionaries to be used as namespaces, rather than
419
* using low level tools to create and mark real modules; this
420
* approach would require extra logic to manage and use the table;
421
* see basic example of using dictionaries for string namespaces;
422
*****************************************************************************/
425
int PP_RELOAD = 0; /* reload modules dynamically? */
426
int PP_DEBUG = 0; /* debug embedded code with pdb? */
429
const char *PP_Init(const char *modname) {
430
Py_Initialize(); /* init python if needed */
433
/* we assume here that the caller frees allocated memory */
439
PP_Make_Dummy_Module(const char *modname) /* namespace for strings, if no file */
440
{ /* instead of sharing __main__ for all */
441
PyObject *module = NULL, *dict = NULL; /* note: __main__ is created in py_init */
443
module = PyImport_AddModule(modname); /* fetch or make, no load */
444
if (module == NULL) /* module not incref'd */
446
/* module.__dict__ */
447
dict = PyModule_GetDict(module); /* ['__dummy__'] = None */
448
PyDict_SetItemString(dict, "__dummy__", Py_None);
449
PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
454
PyObject * /* returns module object named modname */
455
PP_Load_Module(const char *modname) /* modname can be "package.module" form */
456
{ /* reload just resets C extension mods */
459
* - module "__main__" has no file, and not prebuilt: fetch or make
460
* - dummy modules have no files: don't try to reload them
461
* - reload=on and already loaded (on sys.modules): "reload()" before use
462
* - not loaded yet, or loaded but reload=off: "import" to fetch or load
465
PyObject *module = NULL, *sysmods = NULL;
466
modname = PP_Init(modname); /* default to __main__ */
468
if (strcmp(modname, "__main__") == 0) /* main: no file */
469
return PyImport_AddModule(modname); /* not increfd */
471
sysmods = PyImport_GetModuleDict(); /* get sys.modules dict */
472
module = PyDict_GetItemString(sysmods, modname); /* mod in sys.modules? */
474
if (module != NULL && /* dummy: no file */
475
PyModule_Check(module) &&
476
PyDict_GetItemString(PyModule_GetDict(module), "__dummy__")) {
477
return module; /* not increfd */
479
if (PP_RELOAD && module != NULL && PyModule_Check(module)) {
480
module = PyImport_ReloadModule(module); /* reload file,run code */
481
Py_XDECREF(module); /* still on sys.modules */
482
return module; /* not increfd */
484
module = PyImport_ImportModule(modname); /* fetch or load module */
485
Py_XDECREF(module); /* still on sys.modules */
486
return module; /* not increfd */
491
PP_Load_Attribute(const char *modname, const char *attrname)
493
PyObject *module = NULL; /* fetch "module.attr" */
494
modname = PP_Init(modname); /* use before PyEval_CallObject */
495
module = PP_Load_Module(modname); /* not incref'd, may reload */
498
return PyObject_GetAttrString(module, attrname); /* func, class, var,.. */
499
} /* caller must xdecref */
504
PP_Run_Command_Line(const char *prompt)
506
int res = 0; /* interact with python, in "__main__" */
507
Py_Initialize(); /* in the program's "stdio" window */
509
#if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX)
510
printf("[%s <Use Ctrl-D (i.e. EOF) to exit.>]\n", prompt);
511
#elif defined (FC_OS_WIN32)
512
printf("[%s <Use Ctrl-Z plus Return to exit.>]\n", prompt);
514
res = PyRun_InteractiveLoop(stdin, "<stdin>");
518
/*****************************************************************************
519
* RUN EMBEDDED CODE-STRINGS
520
* handles debugging, module (re)loading, namespaces, output conversions;
521
* pbd.runeval returns a value: "eval(expr + '\n', globals, locals)";
522
* pdb.run is just a statement: "exec cmd + '\n' in globals, locals"
523
* New tools: precompiling strings to bytecode, running bytecode;
524
*****************************************************************************/
529
PP_Run_Codestr(PPStringModes mode, const char *code, /* expr or stmt string */
530
const char *modname, /* loads module if needed */
531
const char *resfmt, void *cresult) /* converts expr result to C */
533
/* run a string of Python code */
534
int parse_mode = 0; /* "eval(code, d, d)", or */
535
PyObject *module = NULL, *dict = NULL, *presult = NULL; /* "exec code in d, d" */
537
module = PP_Load_Module(modname); /* get module, init python */
538
if (module == NULL) /* not incref'd */
540
dict = PyModule_GetDict(module); /* get dict namespace */
541
if (dict == NULL) /* not incref'd */
544
parse_mode = (mode == PP_EXPRESSION ? Py_eval_input : Py_file_input);
546
presult = PP_Debug_Codestr(mode, code, dict); /* run in pdb */
548
presult = PyRun_String(code, parse_mode, dict, dict); /* eval direct */
550
if (mode == PP_STATEMENT) {
551
int result = (presult == NULL? -1 : 0); /* stmt: 'None' */
552
Py_XDECREF(presult); /* ignore result */
555
return PP_Convert_Result(presult, resfmt, cresult); /* expr val to C */
560
PP_Compile_Codestr(PPStringModes mode, /* precompile string to bytecode */
561
const char *codestr) /* pass result to PP_Run_Bytecode */
567
start = Py_file_input; break;
569
start = Py_eval_input; break;
571
start = Py_single_input; /* prints expr results */
573
return Py_CompileString(codestr, "<PP_Compile_Codestr>", start);
578
PP_Run_Bytecode(PyObject *codeobj, /* run compiled bytecode object */
579
const char *modname, /* in named module's namespace */
580
const char *resfmt, void *restarget)
582
PyObject *presult = NULL, *module = NULL, *dict = NULL;
584
if (! PyCode_Check(codeobj)) /* make sure it's bytecode */
586
module = PP_Load_Module(modname); /* get module, init python */
587
if (module == NULL) /* not incref'd */
589
dict = PyModule_GetDict(module); /* get dict namespace */
590
if (dict == NULL) /* not incref'd */
593
presult = PP_Debug_Bytecode(codeobj, dict); /* run in pdb */
595
presult = PyEval_EvalCode((PyObject*)codeobj, dict, dict);
596
return PP_Convert_Result(presult, resfmt, restarget); /* expr val to C */
600
/**************************************************************************
602
* 1) pdb.run and pdb.runeval both accept either a string or a
603
* compiled code object, just because they call the built in exec and
604
* eval(), which allow either form; further, eval() works on code
605
* objects compiled as either expressions or statements, but returns
606
* None as the result of statements, so we don't need to distinguish
607
* between expressions and statements here again for bytecode (we
608
* did when compiling); the equivalents in Python code:
610
* >>> s = compile('x = 1', '', 'exec')
611
* >>> e = compile('a + 1', '', 'eval')
616
* on the other hand, we can't blindly use pdb.runeval when dealing
617
* with uncompiled strings, because eval() fails on statement strings;
619
* 2) in 1.5, if you debug a string or bytecode object in a module's
620
* namespace where you've already debugged once, you may see a bogus
621
* return value on entry which is left over from a prior debug; this
622
* is because pdb leaves a '__return__' attribute in the module's
623
* dictionary, which may be a pdb bug, but we work around it here by
624
* manually deleting __return__ if present before starting pdb again;
625
* only happens for strings--function namespaces aren't persistent;
626
**************************************************************************/
629
static void fixPdbRetval(PyObject *moddict)
630
{ if (PyDict_DelItemString(moddict, "__return__")) PyErr_Clear(); }
634
PP_Debug_Codestr(PPStringModes mode, const char *codestring, PyObject *moddict)
637
PyObject *presult = NULL;
638
const char *pdbname = (mode == PP_EXPRESSION ? "runeval" : "run");
639
fixPdbRetval(moddict);
640
/* pass code to a pbd.py function */
641
res = PP_Run_Function( /* "pdb.run(stmt, gdict, ldict)" */
642
"pdb", pdbname, /* "pdb.runeval(expr, gdict, ldict)" */
644
"(sOO)", codestring, moddict, moddict);
645
return (res != 0) ? NULL : presult; /* return null or increfd object */
650
PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict)
653
PyObject *presult = NULL;
654
fixPdbRetval(moddict);
655
res = PP_Run_Function( /* "pdb.runeval(codeobj, gdict, ldict)" */
656
"pdb", "runeval", /* accepts string|code, code=stmt|expr */
658
"(OOO)", codeobject, moddict, moddict);
659
return (res != 0) ? NULL : presult; /* null if error in run_function */