FreeCAD

Форк
0
/
PyTools.c 
662 строки · 26.5 Кб
1
// clang-format off
2
/*
3
PPEMBED, VERSION 2.0
4
AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
5

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.
10
*/
11

12
#include <FCConfig.h>
13
#include "PyTools.h"
14

15
#include <stdarg.h>
16
#include <string.h>
17
#include <assert.h>
18
#include <compile.h>
19
#include <frameobject.h>
20
#if PY_VERSION_HEX < 0x030b0000
21
#include <eval.h>
22
#endif
23

24
//NOLINTBEGIN
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
 *****************************************************************************/
30

31
int
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 */
35
{
36
    PyObject *pmeth = NULL, *pargs = NULL, *presult = NULL;
37
    va_list argslist;                              /* "pobject.method(args)" */
38
    va_start(argslist, argfmt);
39

40
    Py_Initialize();                               /* init if first time */
41
    pmeth = PyObject_GetAttrString(pobject, method);
42
    if (pmeth == NULL) {                           /* get callable object */
43
        va_end(argslist);
44
        return -1;                                 /* bound method? has self */
45
    }
46

47
    pargs = Py_VaBuildValue(argfmt, argslist);     /* args: c->python */
48
    va_end(argslist);
49

50
    if (pargs == NULL) {
51
        Py_DECREF(pmeth);
52
        return -1;
53
    }
54
    if (PP_DEBUG)                                    /* debug it too? */
55
        presult = PP_Debug_Function(pmeth, pargs);
56
    else
57
#if PY_VERSION_HEX < 0x03090000
58
        presult = PyEval_CallObject(pmeth, pargs);   /* run interpreter */
59
#else
60
        presult = PyObject_CallObject(pmeth, pargs);   /* run interpreter */
61
#endif
62

63
    Py_DECREF(pmeth);
64
    Py_DECREF(pargs);
65

66
	return PP_Convert_Result(presult, resfmt, cresult);    /* to C format */
67
}
68

69

70
int
71
PP_Get_Member(PyObject *pobject, const char *attrname,
72
                  const char *resfmt,  void *cresult)         /* convert to c/c++ */
73
{
74
    PyObject *pmemb = NULL;                                    /* "pobject.attrname" */
75
    Py_Initialize();
76
    pmemb = PyObject_GetAttrString(pobject, attrname);  /* incref'd */
77
    return PP_Convert_Result(pmemb, resfmt, cresult);   /* to C form, decrefs */
78
}
79

80

81
int
82
PP_Set_Member(PyObject *pobject, const char *attrname,
83
                  const char *argfmt,  ... /* arg,... */ )    /* convert to python */
84
{
85
    int result = 0;
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 */
91
    va_end(argslist);
92
    if (pval == NULL)
93
        return -1;
94
    result = PyObject_SetAttrString(pobject, attrname, pval);     /* setattr */
95
    Py_DECREF(pval);
96
    return result;
97
}
98

99

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
 *****************************************************************************/
109

110
int
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 */
114
{
115
    /* call a function or class in a module */
116
    PyObject *func = NULL, *args = NULL, *presult = NULL;
117
    va_list argslist;
118
    va_start(argslist, argfmt);                   /* "modname.funcname(args)" */
119

120
    func = PP_Load_Attribute(modname, funcname);  /* may reload; incref'd */
121
    if (func == NULL) {                           /* func or class or C type */
122
        va_end(argslist);
123
        return -1;
124
    }
125
    args = Py_VaBuildValue(argfmt, argslist);     /* convert args to python */
126
    va_end(argslist);
127
    if (args == NULL) {                           /* args incref'd */
128
        Py_DECREF(func);
129
        return -1;
130
    }
131
    if (PP_DEBUG && strcmp(modname, "pdb") != 0)    /* debug this call? */
132
        presult = PP_Debug_Function(func, args);    /* run in pdb; incref'd */
133
    else
134
#if PY_VERSION_HEX < 0x03090000
135
        presult = PyEval_CallObject(func, args);    /* run function; incref'd */
136
#else
137
        presult = PyObject_CallObject(func, args);    /* run function; incref'd */
138
#endif
139

140
    Py_DECREF(func);
141
    Py_DECREF(args);                                    /* result may be None */
142
    return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
143
}
144

145

146
PyObject *
147
PP_Debug_Function(PyObject *func, PyObject *args)
148
{
149
    int oops = 0, res = 0;
150
    PyObject *presult = NULL;
151

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);
157
    if (oops)
158
        return NULL;                        /* "args = (funcobj,) + (arg,..)" */
159

160
    res = PP_Run_Function(                  /* "pdb.runcall(funcobj, arg,..)" */
161
                 "pdb",  "runcall",         /* recursive run_function */
162
                 "O",    &presult,
163
                 "O",     args);            /* args already is a tuple */
164
    return (res != 0) ? NULL : presult;     /* errors in run_function? */
165
}                                           /* presult not yet decref'd */
166

167

168
int
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 */
172
{
173
    /* call a known callable object */
174
    PyObject *args = NULL, *presult = NULL;
175
    va_list argslist;
176
    va_start(argslist, argfmt);                     /* "return object(args)" */
177

178
    Py_Initialize();
179
    args = Py_VaBuildValue(argfmt, argslist);       /* convert args to python */
180
    va_end(argslist);
181
    if (args == NULL)                               /* args incref'd */
182
        return -1;
183
    if (PP_DEBUG)                                   /* debug this call? */
184
        presult = PP_Debug_Function(object, args);  /* run in pdb; incref'd */
185
    else
186
#if PY_VERSION_HEX < 0x03090000
187
        presult = PyEval_CallObject(object, args);  /* run function; incref'd */
188
#else
189
        presult = PyObject_CallObject(object, args);  /* run function; incref'd */
190
#endif
191

192
    Py_DECREF(args);                                    /* result may be None */
193
    return PP_Convert_Result(presult, resfmt, cresult); /* convert result to C*/
194
}
195

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
 *****************************************************************************/
212

213
#define MAX 2024
214
/*
215
FC_OS_LINUX: This is dangerous. How about PY_EXCEPT_MAX?
216
*/
217

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 */
222

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 */
226

227

228
void PP_Fetch_Error_Text()
229
{
230

231
    char *tempstr = NULL;
232
    PyObject *errobj = NULL, *errdata = NULL, *errtraceback = NULL, *pystring = NULL, *pydict = NULL;
233

234
    /* get latest python exception information */
235
    /* this also clears the current exception  */
236

237
    PyErr_Fetch(&errobj, &errdata, &errtraceback);       /* all 3 incref'd */
238

239

240
    /* convert type and data to strings */
241
    /* calls str() on both to stringify */
242

243
    pystring = NULL;
244
    if (errobj != NULL &&
245
       (pystring = PyObject_Str(errobj)) != NULL &&      /* str(errobj) */
246
       (PyUnicode_Check(pystring)) )                      /* str() increfs */
247
    {
248
        strncpy(PP_last_error_type, PyUnicode_AsUTF8(pystring), MAX); /*Py->C*/
249
        PP_last_error_type[MAX-1] = '\0';
250
    }
251
    else
252
    {
253
        PP_last_error_type[0] = '\0';
254
    }
255

256
    Py_XDECREF(pystring);
257

258
    pystring = NULL;
259
    pydict = NULL;
260
    if (errdata != NULL &&
261
        (PyDict_Check(errdata)) )                      /* str() increfs */
262
    {
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");
266

267
        if (value!=NULL) {
268
            strncpy(PP_last_error_info, PyUnicode_AsUTF8(value), MAX);
269
            PP_last_error_info[MAX-1] = '\0';
270
        }
271

272
        pydict = errdata;
273
        Py_INCREF(pydict);
274
    }
275
    else if (errdata != NULL &&
276
       (pystring = PyObject_Str(errdata)) != NULL &&     /* str(): increfs */
277
       (PyUnicode_Check(pystring)) )
278
    {
279
        strncpy(PP_last_error_info, PyUnicode_AsUTF8(pystring), MAX); /*Py->C*/
280
        PP_last_error_info[MAX-1] = '\0';
281
    }
282
    else
283
        strcpy(PP_last_error_info, "<unknown exception data>");
284

285
    Py_XDECREF(pystring);
286

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); */
290

291
    pystring = NULL;
292
    if (errtraceback != NULL &&
293
       (PP_Run_Function("io", "StringIO", "O", &pystring, "()") == 0) &&
294

295
       (PyTraceBack_Print(errtraceback, pystring) == 0) &&
296
       (PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) )
297
    {
298
        strncpy(PP_last_error_trace, tempstr, MAX);
299
        PP_last_error_trace[MAX-1] = '\0';
300
        free(tempstr);  /* it's a strdup */
301
    }
302
    else {
303
        PyFrameObject* frame = PyEval_GetFrame();
304
        if(!frame)
305
            return;
306
        int line = PyFrame_GetLineNumber(frame);
307
#if PY_VERSION_HEX < 0x030b0000
308
        const char *file = PyUnicode_AsUTF8(frame->f_code->co_filename);
309
#else
310
        PyCodeObject* code = PyFrame_GetCode(frame);
311
        const char *file = PyUnicode_AsUTF8(code->co_filename);
312
        Py_DECREF(code);
313
#endif
314
#ifdef FC_OS_WIN32
315
        const char *_f = strstr(file, "\\src\\");
316
#else
317
        const char *_f = strstr(file, "/src/");
318
#endif
319
        snprintf(PP_last_error_trace,sizeof(PP_last_error_trace),"%s(%d)",(_f?_f+5:file),line);
320
    }
321
    Py_XDECREF(pystring);
322

323
    Py_XDECREF(PP_last_exception_type);
324
    if(errobj) {
325
        PP_last_exception_type = errobj;
326
        Py_INCREF(errobj);
327
    }else
328
        PP_last_exception_type = 0;
329
    Py_XDECREF(errobj);
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;
335
}
336

337

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
 *****************************************************************************/
350

351

352
int
353
PP_Convert_Result(PyObject *presult, const char *resFormat, void *resTarget)
354
{
355
    if (presult == NULL)                /* error when run: fail */
356
        return -1;
357
    else
358
    if (resTarget == NULL) {            /* passed target=NULL: ignore result */
359
        Py_DECREF(presult);             /* procedures and stmts return None  */
360
        return 0;
361
    }
362
    if (! PyArg_Parse(presult, resFormat, resTarget)) {  /* convert Python->C */
363
        Py_DECREF(presult);                              /* need not be tuple */
364
        return -1;                                       /* error in convert  */
365
    }
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);
371
#else
372
            *target = _strdup(*target);
373
#endif
374
        }
375
        Py_DECREF(presult);
376
    }
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" */
381

382
int
383
PP_Get_Global(const char *modname, const char *varname, const char *resfmt, void *cresult)
384
{
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 */
388
}
389

390

391
int
392
PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ... /* cval(s) */)
393
{
394
    int result = 0;
395
    PyObject *module = NULL, *val = NULL;                     /* "modname.varname = val" */
396
    va_list cvals;
397
    va_start(cvals, valfmt);                    /* C args after valfmt */
398

399
    module = PP_Load_Module(modname);           /* get/load module */
400
    if (module == NULL) {
401
        va_end(cvals);
402
        return -1;
403
    }
404
    val = Py_VaBuildValue(valfmt, cvals);       /* convert input to Python */
405
    va_end(cvals);
406
    if (val == NULL)
407
        return -1;
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 */
412

413

414
/*****************************************************************************
415
 * MODULE INTERFACE
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
 *****************************************************************************/
423

424

425
int PP_RELOAD = 0;    /* reload modules dynamically? */
426
int PP_DEBUG  = 0;    /* debug embedded code with pdb? */
427

428

429
const char *PP_Init(const char *modname) {
430
    Py_Initialize();                               /* init python if needed */
431
    if (modname)
432
        return modname;
433
    /* we assume here that the caller frees allocated memory */
434
    return "__main__";
435
}
436

437

438
int
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 */
442
    Py_Initialize();
443
    module = PyImport_AddModule(modname);    /* fetch or make, no load */
444
    if (module == NULL)                      /* module not incref'd */
445
        return -1;
446
    /* module.__dict__ */
447
    dict = PyModule_GetDict(module);         /* ['__dummy__'] = None */
448
    PyDict_SetItemString(dict, "__dummy__", Py_None);
449
    PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
450
    return 0;
451
}
452

453

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  */
457
    /*
458
     * 4 cases:
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
463
     */
464

465
    PyObject *module = NULL, *sysmods = NULL;
466
    modname = PP_Init(modname);                       /* default to __main__ */
467

468
    if (strcmp(modname, "__main__") == 0)             /* main: no file */
469
        return PyImport_AddModule(modname);           /* not increfd */
470

471
    sysmods = PyImport_GetModuleDict();               /* get sys.modules dict */
472
    module  = PyDict_GetItemString(sysmods, modname); /* mod in sys.modules? */
473

474
    if (module != NULL &&                             /* dummy: no file */
475
        PyModule_Check(module) &&
476
        PyDict_GetItemString(PyModule_GetDict(module), "__dummy__")) {
477
        return module;                                /* not increfd */
478
    }
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 */
483
    }
484
    module = PyImport_ImportModule(modname);          /* fetch or load module */
485
    Py_XDECREF(module);                               /* still on sys.modules */
486
    return module;                                    /* not increfd */
487
}
488

489

490
PyObject *
491
PP_Load_Attribute(const char *modname, const char *attrname)
492
{
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 */
496
    if (module == NULL)
497
        return NULL;
498
    return PyObject_GetAttrString(module, attrname);  /* func, class, var,.. */
499
}                                                     /* caller must xdecref */
500

501

502
/* extra ops */
503
int
504
PP_Run_Command_Line(const char *prompt)
505
{
506
    int res = 0;               /* interact with python, in "__main__" */
507
    Py_Initialize();       /* in the program's "stdio" window     */
508
    if (prompt != NULL)
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);
513
#endif
514
    res = PyRun_InteractiveLoop(stdin, "<stdin>");
515
    return res;
516
}
517

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
 *****************************************************************************/
525

526

527

528
int
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 */
532
{
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" */
536

537
    module = PP_Load_Module(modname);           /* get module, init python */
538
    if (module == NULL)                         /* not incref'd */
539
        return -1;
540
    dict = PyModule_GetDict(module);            /* get dict namespace */
541
    if (dict == NULL)                           /* not incref'd */
542
        return -1;
543

544
    parse_mode = (mode == PP_EXPRESSION ? Py_eval_input : Py_file_input);
545
    if (PP_DEBUG)
546
        presult = PP_Debug_Codestr(mode, code, dict);         /* run in pdb */
547
    else
548
        presult = PyRun_String(code, parse_mode, dict, dict); /* eval direct */
549
                                                              /* increfs res */
550
    if (mode == PP_STATEMENT) {
551
        int result = (presult == NULL? -1 : 0);          /* stmt: 'None' */
552
        Py_XDECREF(presult);                             /* ignore result */
553
        return result;
554
    }
555
    return PP_Convert_Result(presult, resfmt, cresult);  /* expr val to C */
556
}
557

558

559
PyObject *
560
PP_Compile_Codestr(PPStringModes mode,    /* precompile string to bytecode */
561
                   const char *codestr)         /* pass result to PP_Run_Bytecode */
562
{
563
    int start = 0;
564
    Py_Initialize();
565
    switch (mode) {
566
    case PP_STATEMENT:
567
        start = Py_file_input; break;
568
    case PP_EXPRESSION:
569
        start = Py_eval_input; break;
570
    default:
571
        start = Py_single_input;  /* prints expr results */
572
    }
573
    return Py_CompileString(codestr, "<PP_Compile_Codestr>", start);
574
}
575

576

577
int
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)
581
{
582
    PyObject *presult = NULL, *module = NULL, *dict = NULL;
583

584
    if (! PyCode_Check(codeobj))             /* make sure it's bytecode */
585
        return -1;
586
    module = PP_Load_Module(modname);        /* get module, init python */
587
    if (module == NULL)                      /* not incref'd */
588
        return -1;
589
    dict = PyModule_GetDict(module);         /* get dict namespace */
590
    if (dict == NULL)                        /* not incref'd */
591
        return -1;
592
    if (PP_DEBUG)
593
        presult = PP_Debug_Bytecode(codeobj, dict);        /* run in pdb */
594
    else
595
        presult = PyEval_EvalCode((PyObject*)codeobj, dict, dict);
596
    return PP_Convert_Result(presult, resfmt, restarget);  /* expr val to C */
597
}
598

599

600
/**************************************************************************
601
 * subtle things:
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:
609
 *     >>> a = 1
610
 *     >>> s = compile('x = 1', '', 'exec')
611
 *     >>> e = compile('a + 1', '', 'eval')
612
 *     >>> print eval(e)
613
 *     2
614
 *     >>> print eval(s)
615
 *     None
616
 * on the other hand, we can't blindly use pdb.runeval when dealing
617
 * with uncompiled strings, because eval() fails on statement strings;
618
 *
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
 **************************************************************************/
627

628

629
static void fixPdbRetval(PyObject *moddict)
630
    { if (PyDict_DelItemString(moddict, "__return__")) PyErr_Clear(); }
631

632

633
PyObject *
634
PP_Debug_Codestr(PPStringModes mode, const char *codestring, PyObject *moddict)
635
{
636
    int res = 0;
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)" */
643
             "O",      &presult,
644
             "(sOO)",  codestring, moddict, moddict);
645
    return (res != 0) ? NULL : presult;     /* return null or increfd object */
646
}
647

648

649
PyObject *
650
PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict)
651
{
652
    int res = 0;
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  */
657
             "O",      &presult,
658
             "(OOO)",  codeobject, moddict, moddict);
659
    return (res != 0) ? NULL : presult;     /* null if error in run_function */
660
}
661
// NOLINTEND
662
// clang-format on
663

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.