c29d626cbdf84fd73628110d94fa6065750c2594
[deliverable/binutils-gdb.git] / gdb / python / py-frame.c
1 /* Python interface to stack frames
2
3 Copyright (C) 2008-2013 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "charset.h"
22 #include "block.h"
23 #include "frame.h"
24 #include "exceptions.h"
25 #include "symtab.h"
26 #include "stack.h"
27 #include "value.h"
28 #include "python-internal.h"
29 #include "symfile.h"
30 #include "objfiles.h"
31
32 typedef struct {
33 PyObject_HEAD
34 struct frame_id frame_id;
35 struct gdbarch *gdbarch;
36
37 /* Marks that the FRAME_ID member actually holds the ID of the frame next
38 to this, and not this frames' ID itself. This is a hack to permit Python
39 frame objects which represent invalid frames (i.e., the last frame_info
40 in a corrupt stack). The problem arises from the fact that this code
41 relies on FRAME_ID to uniquely identify a frame, which is not always true
42 for the last "frame" in a corrupt stack (it can have a null ID, or the same
43 ID as the previous frame). Whenever get_prev_frame returns NULL, we
44 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
45 int frame_id_is_next;
46 } frame_object;
47
48 /* Require a valid frame. This must be called inside a TRY_CATCH, or
49 another context in which a gdb exception is allowed. */
50 #define FRAPY_REQUIRE_VALID(frame_obj, frame) \
51 do { \
52 frame = frame_object_to_frame_info (frame_obj); \
53 if (frame == NULL) \
54 error (_("Frame is invalid.")); \
55 } while (0)
56
57 /* Returns the frame_info object corresponding to the given Python Frame
58 object. If the frame doesn't exist anymore (the frame id doesn't
59 correspond to any frame in the inferior), returns NULL. */
60
61 struct frame_info *
62 frame_object_to_frame_info (PyObject *obj)
63 {
64 frame_object *frame_obj = (frame_object *) obj;
65 struct frame_info *frame;
66
67 frame = frame_find_by_id (frame_obj->frame_id);
68 if (frame == NULL)
69 return NULL;
70
71 if (frame_obj->frame_id_is_next)
72 frame = get_prev_frame (frame);
73
74 return frame;
75 }
76
77 /* Called by the Python interpreter to obtain string representation
78 of the object. */
79
80 static PyObject *
81 frapy_str (PyObject *self)
82 {
83 char *s;
84 PyObject *result;
85 struct ui_file *strfile;
86
87 strfile = mem_fileopen ();
88 fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
89 s = ui_file_xstrdup (strfile, NULL);
90 result = PyString_FromString (s);
91 xfree (s);
92
93 return result;
94 }
95
96 /* Implementation of gdb.Frame.is_valid (self) -> Boolean.
97 Returns True if the frame corresponding to the frame_id of this
98 object still exists in the inferior. */
99
100 static PyObject *
101 frapy_is_valid (PyObject *self, PyObject *args)
102 {
103 struct frame_info *frame = NULL;
104 volatile struct gdb_exception except;
105
106 TRY_CATCH (except, RETURN_MASK_ALL)
107 {
108 frame = frame_object_to_frame_info (self);
109 }
110 GDB_PY_HANDLE_EXCEPTION (except);
111
112 if (frame == NULL)
113 Py_RETURN_FALSE;
114
115 Py_RETURN_TRUE;
116 }
117
118 /* Implementation of gdb.Frame.name (self) -> String.
119 Returns the name of the function corresponding to this frame. */
120
121 static PyObject *
122 frapy_name (PyObject *self, PyObject *args)
123 {
124 struct frame_info *frame;
125 char *name = NULL;
126 enum language lang;
127 PyObject *result;
128 volatile struct gdb_exception except;
129
130 TRY_CATCH (except, RETURN_MASK_ALL)
131 {
132 FRAPY_REQUIRE_VALID (self, frame);
133
134 find_frame_funname (frame, &name, &lang, NULL);
135 }
136
137 if (except.reason < 0)
138 xfree (name);
139
140 GDB_PY_HANDLE_EXCEPTION (except);
141
142 if (name)
143 {
144 result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
145 xfree (name);
146 }
147 else
148 {
149 result = Py_None;
150 Py_INCREF (Py_None);
151 }
152
153 return result;
154 }
155
156 /* Implementation of gdb.Frame.type (self) -> Integer.
157 Returns the frame type, namely one of the gdb.*_FRAME constants. */
158
159 static PyObject *
160 frapy_type (PyObject *self, PyObject *args)
161 {
162 struct frame_info *frame;
163 enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */
164 volatile struct gdb_exception except;
165
166 TRY_CATCH (except, RETURN_MASK_ALL)
167 {
168 FRAPY_REQUIRE_VALID (self, frame);
169
170 type = get_frame_type (frame);
171 }
172 GDB_PY_HANDLE_EXCEPTION (except);
173
174 return PyInt_FromLong (type);
175 }
176
177 /* Implementation of gdb.Frame.architecture (self) -> gdb.Architecture.
178 Returns the frame's architecture as a gdb.Architecture object. */
179
180 static PyObject *
181 frapy_arch (PyObject *self, PyObject *args)
182 {
183 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
184 frame_object *obj = (frame_object *) self;
185 volatile struct gdb_exception except;
186
187 TRY_CATCH (except, RETURN_MASK_ALL)
188 {
189 FRAPY_REQUIRE_VALID (self, frame);
190 }
191 GDB_PY_HANDLE_EXCEPTION (except);
192
193 return gdbarch_to_arch_object (obj->gdbarch);
194 }
195
196 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
197 Returns one of the gdb.FRAME_UNWIND_* constants. */
198
199 static PyObject *
200 frapy_unwind_stop_reason (PyObject *self, PyObject *args)
201 {
202 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
203 volatile struct gdb_exception except;
204 enum unwind_stop_reason stop_reason;
205
206 TRY_CATCH (except, RETURN_MASK_ALL)
207 {
208 FRAPY_REQUIRE_VALID (self, frame);
209 }
210 GDB_PY_HANDLE_EXCEPTION (except);
211
212 stop_reason = get_frame_unwind_stop_reason (frame);
213
214 return PyInt_FromLong (stop_reason);
215 }
216
217 /* Implementation of gdb.Frame.pc (self) -> Long.
218 Returns the frame's resume address. */
219
220 static PyObject *
221 frapy_pc (PyObject *self, PyObject *args)
222 {
223 CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
224 struct frame_info *frame;
225 volatile struct gdb_exception except;
226
227 TRY_CATCH (except, RETURN_MASK_ALL)
228 {
229 FRAPY_REQUIRE_VALID (self, frame);
230
231 pc = get_frame_pc (frame);
232 }
233 GDB_PY_HANDLE_EXCEPTION (except);
234
235 return gdb_py_long_from_ulongest (pc);
236 }
237
238 /* Implementation of gdb.Frame.block (self) -> gdb.Block.
239 Returns the frame's code block. */
240
241 static PyObject *
242 frapy_block (PyObject *self, PyObject *args)
243 {
244 struct frame_info *frame;
245 struct block *block = NULL, *fn_block;
246 volatile struct gdb_exception except;
247
248 TRY_CATCH (except, RETURN_MASK_ALL)
249 {
250 FRAPY_REQUIRE_VALID (self, frame);
251 block = get_frame_block (frame, NULL);
252 }
253 GDB_PY_HANDLE_EXCEPTION (except);
254
255 for (fn_block = block;
256 fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
257 fn_block = BLOCK_SUPERBLOCK (fn_block))
258 ;
259
260 if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
261 {
262 PyErr_SetString (PyExc_RuntimeError,
263 _("Cannot locate object file for block."));
264 return NULL;
265 }
266
267 if (block)
268 {
269 struct symtab *symt;
270
271 symt = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
272 return block_to_block_object (block, symt->objfile);
273 }
274
275 Py_RETURN_NONE;
276 }
277
278
279 /* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
280 Returns the symbol for the function corresponding to this frame. */
281
282 static PyObject *
283 frapy_function (PyObject *self, PyObject *args)
284 {
285 struct symbol *sym = NULL;
286 struct frame_info *frame;
287 volatile struct gdb_exception except;
288
289 TRY_CATCH (except, RETURN_MASK_ALL)
290 {
291 FRAPY_REQUIRE_VALID (self, frame);
292
293 sym = find_pc_function (get_frame_address_in_block (frame));
294 }
295 GDB_PY_HANDLE_EXCEPTION (except);
296
297 if (sym)
298 return symbol_to_symbol_object (sym);
299
300 Py_RETURN_NONE;
301 }
302
303 /* Convert a frame_info struct to a Python Frame object.
304 Sets a Python exception and returns NULL on error. */
305
306 PyObject *
307 frame_info_to_frame_object (struct frame_info *frame)
308 {
309 frame_object *frame_obj;
310 volatile struct gdb_exception except;
311
312 frame_obj = PyObject_New (frame_object, &frame_object_type);
313 if (frame_obj == NULL)
314 return NULL;
315
316 TRY_CATCH (except, RETURN_MASK_ALL)
317 {
318
319 /* Try to get the previous frame, to determine if this is the last frame
320 in a corrupt stack. If so, we need to store the frame_id of the next
321 frame and not of this one (which is possibly invalid). */
322 if (get_prev_frame (frame) == NULL
323 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
324 && get_next_frame (frame) != NULL)
325 {
326 frame_obj->frame_id = get_frame_id (get_next_frame (frame));
327 frame_obj->frame_id_is_next = 1;
328 }
329 else
330 {
331 frame_obj->frame_id = get_frame_id (frame);
332 frame_obj->frame_id_is_next = 0;
333 }
334 frame_obj->gdbarch = get_frame_arch (frame);
335 }
336 GDB_PY_HANDLE_EXCEPTION (except);
337
338 return (PyObject *) frame_obj;
339 }
340
341 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
342 Returns the frame immediately older (outer) to this frame, or None if
343 there isn't one. */
344
345 static PyObject *
346 frapy_older (PyObject *self, PyObject *args)
347 {
348 struct frame_info *frame, *prev = NULL;
349 volatile struct gdb_exception except;
350 PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
351
352 TRY_CATCH (except, RETURN_MASK_ALL)
353 {
354 FRAPY_REQUIRE_VALID (self, frame);
355
356 prev = get_prev_frame (frame);
357 }
358 GDB_PY_HANDLE_EXCEPTION (except);
359
360 if (prev)
361 prev_obj = (PyObject *) frame_info_to_frame_object (prev);
362 else
363 {
364 Py_INCREF (Py_None);
365 prev_obj = Py_None;
366 }
367
368 return prev_obj;
369 }
370
371 /* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
372 Returns the frame immediately newer (inner) to this frame, or None if
373 there isn't one. */
374
375 static PyObject *
376 frapy_newer (PyObject *self, PyObject *args)
377 {
378 struct frame_info *frame, *next = NULL;
379 volatile struct gdb_exception except;
380 PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
381
382 TRY_CATCH (except, RETURN_MASK_ALL)
383 {
384 FRAPY_REQUIRE_VALID (self, frame);
385
386 next = get_next_frame (frame);
387 }
388 GDB_PY_HANDLE_EXCEPTION (except);
389
390 if (next)
391 next_obj = (PyObject *) frame_info_to_frame_object (next);
392 else
393 {
394 Py_INCREF (Py_None);
395 next_obj = Py_None;
396 }
397
398 return next_obj;
399 }
400
401 /* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
402 Returns the frame's symtab and line. */
403
404 static PyObject *
405 frapy_find_sal (PyObject *self, PyObject *args)
406 {
407 struct frame_info *frame;
408 struct symtab_and_line sal;
409 volatile struct gdb_exception except;
410 PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */
411
412 TRY_CATCH (except, RETURN_MASK_ALL)
413 {
414 FRAPY_REQUIRE_VALID (self, frame);
415
416 find_frame_sal (frame, &sal);
417 sal_obj = symtab_and_line_to_sal_object (sal);
418 }
419 GDB_PY_HANDLE_EXCEPTION (except);
420
421 return sal_obj;
422 }
423
424 /* Implementation of gdb.Frame.read_var_value (self, variable,
425 [block]) -> gdb.Value. If the optional block argument is provided
426 start the search from that block, otherwise search from the frame's
427 current block (determined by examining the resume address of the
428 frame). The variable argument must be a string or an instance of a
429 gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
430 NULL on error, with a python exception set. */
431 static PyObject *
432 frapy_read_var (PyObject *self, PyObject *args)
433 {
434 struct frame_info *frame;
435 PyObject *sym_obj, *block_obj = NULL;
436 struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
437 struct value *val = NULL;
438 volatile struct gdb_exception except;
439
440 if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
441 return NULL;
442
443 if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
444 var = symbol_object_to_symbol (sym_obj);
445 else if (gdbpy_is_string (sym_obj))
446 {
447 char *var_name;
448 const struct block *block = NULL;
449 struct cleanup *cleanup;
450 volatile struct gdb_exception except;
451
452 var_name = python_string_to_target_string (sym_obj);
453 if (!var_name)
454 return NULL;
455 cleanup = make_cleanup (xfree, var_name);
456
457 if (block_obj)
458 {
459 block = block_object_to_block (block_obj);
460 if (!block)
461 {
462 PyErr_SetString (PyExc_RuntimeError,
463 _("Second argument must be block."));
464 return NULL;
465 }
466 }
467
468 TRY_CATCH (except, RETURN_MASK_ALL)
469 {
470 FRAPY_REQUIRE_VALID (self, frame);
471
472 if (!block)
473 block = get_frame_block (frame, NULL);
474 var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
475 }
476 GDB_PY_HANDLE_EXCEPTION (except);
477
478 if (!var)
479 {
480 PyErr_Format (PyExc_ValueError,
481 _("Variable '%s' not found."), var_name);
482 do_cleanups (cleanup);
483
484 return NULL;
485 }
486
487 do_cleanups (cleanup);
488 }
489 else
490 {
491 PyErr_SetString (PyExc_TypeError,
492 _("Argument must be a symbol or string."));
493 return NULL;
494 }
495
496 TRY_CATCH (except, RETURN_MASK_ALL)
497 {
498 FRAPY_REQUIRE_VALID (self, frame);
499
500 val = read_var_value (var, frame);
501 }
502 GDB_PY_HANDLE_EXCEPTION (except);
503
504 return value_to_value_object (val);
505 }
506
507 /* Select this frame. */
508
509 static PyObject *
510 frapy_select (PyObject *self, PyObject *args)
511 {
512 struct frame_info *fi;
513 volatile struct gdb_exception except;
514
515 TRY_CATCH (except, RETURN_MASK_ALL)
516 {
517 FRAPY_REQUIRE_VALID (self, fi);
518
519 select_frame (fi);
520 }
521 GDB_PY_HANDLE_EXCEPTION (except);
522
523 Py_RETURN_NONE;
524 }
525
526 /* Implementation of gdb.newest_frame () -> gdb.Frame.
527 Returns the newest frame object. */
528
529 PyObject *
530 gdbpy_newest_frame (PyObject *self, PyObject *args)
531 {
532 struct frame_info *frame = NULL;
533 volatile struct gdb_exception except;
534
535 TRY_CATCH (except, RETURN_MASK_ALL)
536 {
537 frame = get_current_frame ();
538 }
539 GDB_PY_HANDLE_EXCEPTION (except);
540
541 return frame_info_to_frame_object (frame);
542 }
543
544 /* Implementation of gdb.selected_frame () -> gdb.Frame.
545 Returns the selected frame object. */
546
547 PyObject *
548 gdbpy_selected_frame (PyObject *self, PyObject *args)
549 {
550 struct frame_info *frame = NULL;
551 volatile struct gdb_exception except;
552
553 TRY_CATCH (except, RETURN_MASK_ALL)
554 {
555 frame = get_selected_frame ("No frame is currently selected.");
556 }
557 GDB_PY_HANDLE_EXCEPTION (except);
558
559 return frame_info_to_frame_object (frame);
560 }
561
562 /* Implementation of gdb.stop_reason_string (Integer) -> String.
563 Return a string explaining the unwind stop reason. */
564
565 PyObject *
566 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
567 {
568 int reason;
569 const char *str;
570
571 if (!PyArg_ParseTuple (args, "i", &reason))
572 return NULL;
573
574 if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
575 {
576 PyErr_SetString (PyExc_ValueError,
577 _("Invalid frame stop reason."));
578 return NULL;
579 }
580
581 str = frame_stop_reason_string (reason);
582 return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
583 }
584
585 /* Implements the equality comparison for Frame objects.
586 All other comparison operators will throw a TypeError Python exception,
587 as they aren't valid for frames. */
588
589 static PyObject *
590 frapy_richcompare (PyObject *self, PyObject *other, int op)
591 {
592 int result;
593
594 if (!PyObject_TypeCheck (other, &frame_object_type)
595 || (op != Py_EQ && op != Py_NE))
596 {
597 Py_INCREF (Py_NotImplemented);
598 return Py_NotImplemented;
599 }
600
601 if (frame_id_eq (((frame_object *) self)->frame_id,
602 ((frame_object *) other)->frame_id))
603 result = Py_EQ;
604 else
605 result = Py_NE;
606
607 if (op == result)
608 Py_RETURN_TRUE;
609 Py_RETURN_FALSE;
610 }
611
612 /* Sets up the Frame API in the gdb module. */
613
614 int
615 gdbpy_initialize_frames (void)
616 {
617 frame_object_type.tp_new = PyType_GenericNew;
618 if (PyType_Ready (&frame_object_type) < 0)
619 return -1;
620
621 /* Note: These would probably be best exposed as class attributes of
622 Frame, but I don't know how to do it except by messing with the
623 type's dictionary. That seems too messy. */
624 if (PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME) < 0
625 || PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME) < 0
626 || PyModule_AddIntConstant (gdb_module, "INLINE_FRAME", INLINE_FRAME) < 0
627 || PyModule_AddIntConstant (gdb_module, "TAILCALL_FRAME",
628 TAILCALL_FRAME) < 0
629 || PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME",
630 SIGTRAMP_FRAME) < 0
631 || PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME) < 0
632 || PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME",
633 SENTINEL_FRAME) < 0)
634 return -1;
635
636 #define SET(name, description) \
637 if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
638 return -1;
639 #define FIRST_ERROR(name) \
640 if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
641 return -1;
642 #include "unwind_stop_reasons.def"
643 #undef SET
644 #undef FIRST_ERROR
645
646 return gdb_pymodule_addobject (gdb_module, "Frame",
647 (PyObject *) &frame_object_type);
648 }
649
650 \f
651
652 static PyMethodDef frame_object_methods[] = {
653 { "is_valid", frapy_is_valid, METH_NOARGS,
654 "is_valid () -> Boolean.\n\
655 Return true if this frame is valid, false if not." },
656 { "name", frapy_name, METH_NOARGS,
657 "name () -> String.\n\
658 Return the function name of the frame, or None if it can't be determined." },
659 { "type", frapy_type, METH_NOARGS,
660 "type () -> Integer.\n\
661 Return the type of the frame." },
662 { "architecture", frapy_arch, METH_NOARGS,
663 "architecture () -> gdb.Architecture.\n\
664 Return the architecture of the frame." },
665 { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
666 "unwind_stop_reason () -> Integer.\n\
667 Return the reason why it's not possible to find frames older than this." },
668 { "pc", frapy_pc, METH_NOARGS,
669 "pc () -> Long.\n\
670 Return the frame's resume address." },
671 { "block", frapy_block, METH_NOARGS,
672 "block () -> gdb.Block.\n\
673 Return the frame's code block." },
674 { "function", frapy_function, METH_NOARGS,
675 "function () -> gdb.Symbol.\n\
676 Returns the symbol for the function corresponding to this frame." },
677 { "older", frapy_older, METH_NOARGS,
678 "older () -> gdb.Frame.\n\
679 Return the frame that called this frame." },
680 { "newer", frapy_newer, METH_NOARGS,
681 "newer () -> gdb.Frame.\n\
682 Return the frame called by this frame." },
683 { "find_sal", frapy_find_sal, METH_NOARGS,
684 "find_sal () -> gdb.Symtab_and_line.\n\
685 Return the frame's symtab and line." },
686 { "read_var", frapy_read_var, METH_VARARGS,
687 "read_var (variable) -> gdb.Value.\n\
688 Return the value of the variable in this frame." },
689 { "select", frapy_select, METH_NOARGS,
690 "Select this frame as the user's current frame." },
691 {NULL} /* Sentinel */
692 };
693
694 PyTypeObject frame_object_type = {
695 PyVarObject_HEAD_INIT (NULL, 0)
696 "gdb.Frame", /* tp_name */
697 sizeof (frame_object), /* tp_basicsize */
698 0, /* tp_itemsize */
699 0, /* tp_dealloc */
700 0, /* tp_print */
701 0, /* tp_getattr */
702 0, /* tp_setattr */
703 0, /* tp_compare */
704 0, /* tp_repr */
705 0, /* tp_as_number */
706 0, /* tp_as_sequence */
707 0, /* tp_as_mapping */
708 0, /* tp_hash */
709 0, /* tp_call */
710 frapy_str, /* tp_str */
711 0, /* tp_getattro */
712 0, /* tp_setattro */
713 0, /* tp_as_buffer */
714 Py_TPFLAGS_DEFAULT, /* tp_flags */
715 "GDB frame object", /* tp_doc */
716 0, /* tp_traverse */
717 0, /* tp_clear */
718 frapy_richcompare, /* tp_richcompare */
719 0, /* tp_weaklistoffset */
720 0, /* tp_iter */
721 0, /* tp_iternext */
722 frame_object_methods, /* tp_methods */
723 0, /* tp_members */
724 0, /* tp_getset */
725 0, /* tp_base */
726 0, /* tp_dict */
727 0, /* tp_descr_get */
728 0, /* tp_descr_set */
729 0, /* tp_dictoffset */
730 0, /* tp_init */
731 0, /* tp_alloc */
732 };
This page took 0.122818 seconds and 4 git commands to generate.