1 /* GDB parameters implemented in Python 2 3 Copyright (C) 2008-2017 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 21 #include "defs.h" 22 #include "value.h" 23 #include "python-internal.h" 24 #include "charset.h" 25 #include "gdbcmd.h" 26 #include "cli/cli-decode.h" 27 #include "completer.h" 28 #include "language.h" 29 #include "arch-utils.h" 30 #include "py-ref.h" 31 32 /* Parameter constants and their values. */ 33 struct parm_constant 34 { 35 const char *name; 36 int value; 37 }; 38 39 struct parm_constant parm_constants[] = 40 { 41 { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */ 42 { "PARAM_AUTO_BOOLEAN", var_auto_boolean }, 43 { "PARAM_UINTEGER", var_uinteger }, 44 { "PARAM_INTEGER", var_integer }, 45 { "PARAM_STRING", var_string }, 46 { "PARAM_STRING_NOESCAPE", var_string_noescape }, 47 { "PARAM_OPTIONAL_FILENAME", var_optional_filename }, 48 { "PARAM_FILENAME", var_filename }, 49 { "PARAM_ZINTEGER", var_zinteger }, 50 { "PARAM_ENUM", var_enum }, 51 { NULL, 0 } 52 }; 53 54 /* A union that can hold anything described by enum var_types. */ 55 union parmpy_variable 56 { 57 /* Hold an integer value, for boolean and integer types. */ 58 int intval; 59 60 /* Hold an auto_boolean. */ 61 enum auto_boolean autoboolval; 62 63 /* Hold an unsigned integer value, for uinteger. */ 64 unsigned int uintval; 65 66 /* Hold a string, for the various string types. */ 67 char *stringval; 68 69 /* Hold a string, for enums. */ 70 const char *cstringval; 71 }; 72 73 /* A GDB parameter. */ 74 struct parmpy_object 75 { 76 PyObject_HEAD 77 78 /* The type of the parameter. */ 79 enum var_types type; 80 81 /* The value of the parameter. */ 82 union parmpy_variable value; 83 84 /* For an enum command, the possible values. The vector is 85 allocated with xmalloc, as is each element. It is 86 NULL-terminated. */ 87 const char **enumeration; 88 }; 89 90 typedef struct parmpy_object parmpy_object; 91 92 extern PyTypeObject parmpy_object_type 93 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object"); 94 95 /* Some handy string constants. */ 96 static PyObject *set_doc_cst; 97 static PyObject *show_doc_cst; 98 99 100 101 /* Get an attribute. */ 102 static PyObject * 103 get_attr (PyObject *obj, PyObject *attr_name) 104 { 105 if (PyString_Check (attr_name) 106 #ifdef IS_PY3K 107 && ! PyUnicode_CompareWithASCIIString (attr_name, "value")) 108 #else 109 && ! strcmp (PyString_AsString (attr_name), "value")) 110 #endif 111 { 112 parmpy_object *self = (parmpy_object *) obj; 113 114 return gdbpy_parameter_value (self->type, &self->value); 115 } 116 117 return PyObject_GenericGetAttr (obj, attr_name); 118 } 119 120 /* Set a parameter value from a Python value. Return 0 on success. Returns 121 -1 on error, with a python exception set. */ 122 static int 123 set_parameter_value (parmpy_object *self, PyObject *value) 124 { 125 int cmp; 126 127 switch (self->type) 128 { 129 case var_string: 130 case var_string_noescape: 131 case var_optional_filename: 132 case var_filename: 133 if (! gdbpy_is_string (value) 134 && (self->type == var_filename 135 || value != Py_None)) 136 { 137 PyErr_SetString (PyExc_RuntimeError, 138 _("String required for filename.")); 139 140 return -1; 141 } 142 if (value == Py_None) 143 { 144 xfree (self->value.stringval); 145 if (self->type == var_optional_filename) 146 self->value.stringval = xstrdup (""); 147 else 148 self->value.stringval = NULL; 149 } 150 else 151 { 152 gdb::unique_xmalloc_ptr<char> 153 string (python_string_to_host_string (value)); 154 if (string == NULL) 155 return -1; 156 157 xfree (self->value.stringval); 158 self->value.stringval = string.release (); 159 } 160 break; 161 162 case var_enum: 163 { 164 int i; 165 166 if (! gdbpy_is_string (value)) 167 { 168 PyErr_SetString (PyExc_RuntimeError, 169 _("ENUM arguments must be a string.")); 170 return -1; 171 } 172 173 gdb::unique_xmalloc_ptr<char> 174 str (python_string_to_host_string (value)); 175 if (str == NULL) 176 return -1; 177 for (i = 0; self->enumeration[i]; ++i) 178 if (! strcmp (self->enumeration[i], str.get ())) 179 break; 180 if (! self->enumeration[i]) 181 { 182 PyErr_SetString (PyExc_RuntimeError, 183 _("The value must be member of an enumeration.")); 184 return -1; 185 } 186 self->value.cstringval = self->enumeration[i]; 187 break; 188 } 189 190 case var_boolean: 191 if (! PyBool_Check (value)) 192 { 193 PyErr_SetString (PyExc_RuntimeError, 194 _("A boolean argument is required.")); 195 return -1; 196 } 197 cmp = PyObject_IsTrue (value); 198 if (cmp < 0) 199 return -1; 200 self->value.intval = cmp; 201 break; 202 203 case var_auto_boolean: 204 if (! PyBool_Check (value) && value != Py_None) 205 { 206 PyErr_SetString (PyExc_RuntimeError, 207 _("A boolean or None is required")); 208 return -1; 209 } 210 211 if (value == Py_None) 212 self->value.autoboolval = AUTO_BOOLEAN_AUTO; 213 else 214 { 215 cmp = PyObject_IsTrue (value); 216 if (cmp < 0 ) 217 return -1; 218 if (cmp == 1) 219 self->value.autoboolval = AUTO_BOOLEAN_TRUE; 220 else 221 self->value.autoboolval = AUTO_BOOLEAN_FALSE; 222 } 223 break; 224 225 case var_integer: 226 case var_zinteger: 227 case var_uinteger: 228 { 229 long l; 230 int ok; 231 232 if (! PyInt_Check (value)) 233 { 234 PyErr_SetString (PyExc_RuntimeError, 235 _("The value must be integer.")); 236 return -1; 237 } 238 239 if (! gdb_py_int_as_long (value, &l)) 240 return -1; 241 242 if (self->type == var_uinteger) 243 { 244 ok = (l >= 0 && l <= UINT_MAX); 245 if (l == 0) 246 l = UINT_MAX; 247 } 248 else if (self->type == var_integer) 249 { 250 ok = (l >= INT_MIN && l <= INT_MAX); 251 if (l == 0) 252 l = INT_MAX; 253 } 254 else 255 ok = (l >= INT_MIN && l <= INT_MAX); 256 257 if (! ok) 258 { 259 PyErr_SetString (PyExc_RuntimeError, 260 _("Range exceeded.")); 261 return -1; 262 } 263 264 self->value.intval = (int) l; 265 break; 266 } 267 268 default: 269 PyErr_SetString (PyExc_RuntimeError, 270 _("Unhandled type in parameter value.")); 271 return -1; 272 } 273 274 return 0; 275 } 276 277 /* Set an attribute. Returns -1 on error, with a python exception set. */ 278 static int 279 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val) 280 { 281 if (PyString_Check (attr_name) 282 #ifdef IS_PY3K 283 && ! PyUnicode_CompareWithASCIIString (attr_name, "value")) 284 #else 285 && ! strcmp (PyString_AsString (attr_name), "value")) 286 #endif 287 { 288 if (!val) 289 { 290 PyErr_SetString (PyExc_RuntimeError, 291 _("Cannot delete a parameter's value.")); 292 return -1; 293 } 294 return set_parameter_value ((parmpy_object *) obj, val); 295 } 296 297 return PyObject_GenericSetAttr (obj, attr_name, val); 298 } 299 300 /* A helper function which returns a documentation string for an 301 object. */ 302 303 static gdb::unique_xmalloc_ptr<char> 304 get_doc_string (PyObject *object, PyObject *attr) 305 { 306 gdb::unique_xmalloc_ptr<char> result; 307 308 if (PyObject_HasAttr (object, attr)) 309 { 310 gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr)); 311 312 if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ())) 313 { 314 result = python_string_to_host_string (ds_obj.get ()); 315 if (result == NULL) 316 gdbpy_print_stack (); 317 } 318 } 319 if (! result) 320 result.reset (xstrdup (_("This command is not documented."))); 321 return result; 322 } 323 324 /* Helper function which will execute a METHOD in OBJ passing the 325 argument ARG. ARG can be NULL. METHOD should return a Python 326 string. If this function returns NULL, there has been an error and 327 the appropriate exception set. */ 328 static gdb::unique_xmalloc_ptr<char> 329 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) 330 { 331 gdb::unique_xmalloc_ptr<char> data; 332 gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL)); 333 334 if (result == NULL) 335 return NULL; 336 337 if (gdbpy_is_string (result.get ())) 338 { 339 data = python_string_to_host_string (result.get ()); 340 if (! data) 341 return NULL; 342 } 343 else 344 { 345 PyErr_SetString (PyExc_RuntimeError, 346 _("Parameter must return a string value.")); 347 return NULL; 348 } 349 350 return data; 351 } 352 353 /* A callback function that is registered against the respective 354 add_setshow_* set_doc prototype. This function will either call 355 the Python function "get_set_string" or extract the Python 356 attribute "set_doc" and return the contents as a string. If 357 neither exist, insert a string indicating the Parameter is not 358 documented. */ 359 static void 360 get_set_value (char *args, int from_tty, 361 struct cmd_list_element *c) 362 { 363 PyObject *obj = (PyObject *) get_cmd_context (c); 364 gdb::unique_xmalloc_ptr<char> set_doc_string; 365 366 gdbpy_enter enter_py (get_current_arch (), current_language); 367 gdbpy_ref<> set_doc_func (PyString_FromString ("get_set_string")); 368 369 if (set_doc_func == NULL) 370 { 371 gdbpy_print_stack (); 372 return; 373 } 374 375 if (PyObject_HasAttr (obj, set_doc_func.get ())) 376 { 377 set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL); 378 if (! set_doc_string) 379 { 380 gdbpy_print_stack (); 381 return; 382 } 383 } 384 else 385 { 386 /* We have to preserve the existing < GDB 7.3 API. If a 387 callback function does not exist, then attempt to read the 388 set_doc attribute. */ 389 set_doc_string = get_doc_string (obj, set_doc_cst); 390 } 391 392 fprintf_filtered (gdb_stdout, "%s\n", set_doc_string.get ()); 393 } 394 395 /* A callback function that is registered against the respective 396 add_setshow_* show_doc prototype. This function will either call 397 the Python function "get_show_string" or extract the Python 398 attribute "show_doc" and return the contents as a string. If 399 neither exist, insert a string indicating the Parameter is not 400 documented. */ 401 static void 402 get_show_value (struct ui_file *file, int from_tty, 403 struct cmd_list_element *c, 404 const char *value) 405 { 406 PyObject *obj = (PyObject *) get_cmd_context (c); 407 gdb::unique_xmalloc_ptr<char> show_doc_string; 408 409 gdbpy_enter enter_py (get_current_arch (), current_language); 410 gdbpy_ref<> show_doc_func (PyString_FromString ("get_show_string")); 411 412 if (show_doc_func == NULL) 413 { 414 gdbpy_print_stack (); 415 return; 416 } 417 418 if (PyObject_HasAttr (obj, show_doc_func.get ())) 419 { 420 gdbpy_ref<> val_obj (PyString_FromString (value)); 421 422 if (val_obj == NULL) 423 { 424 gdbpy_print_stack (); 425 return; 426 } 427 428 show_doc_string = call_doc_function (obj, show_doc_func.get (), 429 val_obj.get ()); 430 if (! show_doc_string) 431 { 432 gdbpy_print_stack (); 433 return; 434 } 435 436 fprintf_filtered (file, "%s\n", show_doc_string.get ()); 437 } 438 else 439 { 440 /* We have to preserve the existing < GDB 7.3 API. If a 441 callback function does not exist, then attempt to read the 442 show_doc attribute. */ 443 show_doc_string = get_doc_string (obj, show_doc_cst); 444 fprintf_filtered (file, "%s %s\n", show_doc_string.get (), value); 445 } 446 } 447 448 449 /* A helper function that dispatches to the appropriate add_setshow 450 function. */ 451 static void 452 add_setshow_generic (int parmclass, enum command_class cmdclass, 453 char *cmd_name, parmpy_object *self, 454 char *set_doc, char *show_doc, char *help_doc, 455 struct cmd_list_element **set_list, 456 struct cmd_list_element **show_list) 457 { 458 struct cmd_list_element *param = NULL; 459 const char *tmp_name = NULL; 460 461 switch (parmclass) 462 { 463 case var_boolean: 464 465 add_setshow_boolean_cmd (cmd_name, cmdclass, 466 &self->value.intval, set_doc, show_doc, 467 help_doc, get_set_value, get_show_value, 468 set_list, show_list); 469 470 break; 471 472 case var_auto_boolean: 473 add_setshow_auto_boolean_cmd (cmd_name, cmdclass, 474 &self->value.autoboolval, 475 set_doc, show_doc, help_doc, 476 get_set_value, get_show_value, 477 set_list, show_list); 478 break; 479 480 case var_uinteger: 481 add_setshow_uinteger_cmd (cmd_name, cmdclass, 482 &self->value.uintval, set_doc, show_doc, 483 help_doc, get_set_value, get_show_value, 484 set_list, show_list); 485 break; 486 487 case var_integer: 488 add_setshow_integer_cmd (cmd_name, cmdclass, 489 &self->value.intval, set_doc, show_doc, 490 help_doc, get_set_value, get_show_value, 491 set_list, show_list); break; 492 493 case var_string: 494 add_setshow_string_cmd (cmd_name, cmdclass, 495 &self->value.stringval, set_doc, show_doc, 496 help_doc, get_set_value, get_show_value, 497 set_list, show_list); break; 498 499 case var_string_noescape: 500 add_setshow_string_noescape_cmd (cmd_name, cmdclass, 501 &self->value.stringval, 502 set_doc, show_doc, help_doc, 503 get_set_value, get_show_value, 504 set_list, show_list); 505 506 break; 507 508 case var_optional_filename: 509 add_setshow_optional_filename_cmd (cmd_name, cmdclass, 510 &self->value.stringval, set_doc, 511 show_doc, help_doc, get_set_value, 512 get_show_value, set_list, 513 show_list); 514 break; 515 516 case var_filename: 517 add_setshow_filename_cmd (cmd_name, cmdclass, 518 &self->value.stringval, set_doc, show_doc, 519 help_doc, get_set_value, get_show_value, 520 set_list, show_list); break; 521 522 case var_zinteger: 523 add_setshow_zinteger_cmd (cmd_name, cmdclass, 524 &self->value.intval, set_doc, show_doc, 525 help_doc, get_set_value, get_show_value, 526 set_list, show_list); 527 break; 528 529 case var_enum: 530 add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration, 531 &self->value.cstringval, set_doc, show_doc, 532 help_doc, get_set_value, get_show_value, 533 set_list, show_list); 534 /* Initialize the value, just in case. */ 535 self->value.cstringval = self->enumeration[0]; 536 break; 537 } 538 539 /* Lookup created parameter, and register Python object against the 540 parameter context. Perform this task against both lists. */ 541 tmp_name = cmd_name; 542 param = lookup_cmd (&tmp_name, *show_list, "", 0, 1); 543 if (param) 544 set_cmd_context (param, self); 545 546 tmp_name = cmd_name; 547 param = lookup_cmd (&tmp_name, *set_list, "", 0, 1); 548 if (param) 549 set_cmd_context (param, self); 550 } 551 552 /* A helper which computes enum values. Returns 1 on success. Returns 0 on 553 error, with a python exception set. */ 554 static int 555 compute_enum_values (parmpy_object *self, PyObject *enum_values) 556 { 557 Py_ssize_t size, i; 558 struct cleanup *back_to; 559 560 if (! enum_values) 561 { 562 PyErr_SetString (PyExc_RuntimeError, 563 _("An enumeration is required for PARAM_ENUM.")); 564 return 0; 565 } 566 567 if (! PySequence_Check (enum_values)) 568 { 569 PyErr_SetString (PyExc_RuntimeError, 570 _("The enumeration is not a sequence.")); 571 return 0; 572 } 573 574 size = PySequence_Size (enum_values); 575 if (size < 0) 576 return 0; 577 if (size == 0) 578 { 579 PyErr_SetString (PyExc_RuntimeError, 580 _("The enumeration is empty.")); 581 return 0; 582 } 583 584 self->enumeration = XCNEWVEC (const char *, size + 1); 585 back_to = make_cleanup (free_current_contents, &self->enumeration); 586 587 for (i = 0; i < size; ++i) 588 { 589 gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); 590 591 if (item == NULL) 592 { 593 do_cleanups (back_to); 594 return 0; 595 } 596 if (! gdbpy_is_string (item.get ())) 597 { 598 do_cleanups (back_to); 599 PyErr_SetString (PyExc_RuntimeError, 600 _("The enumeration item not a string.")); 601 return 0; 602 } 603 self->enumeration[i] 604 = python_string_to_host_string (item.get ()).release (); 605 if (self->enumeration[i] == NULL) 606 { 607 do_cleanups (back_to); 608 return 0; 609 } 610 make_cleanup (xfree, (char *) self->enumeration[i]); 611 } 612 613 discard_cleanups (back_to); 614 return 1; 615 } 616 617 /* Object initializer; sets up gdb-side structures for command. 618 619 Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM]) 620 621 NAME is the name of the parameter. It may consist of multiple 622 words, in which case the final word is the name of the new command, 623 and earlier words must be prefix commands. 624 625 CMDCLASS is the kind of command. It should be one of the COMMAND_* 626 constants defined in the gdb module. 627 628 PARMCLASS is the type of the parameter. It should be one of the 629 PARAM_* constants defined in the gdb module. 630 631 If PARMCLASS is PARAM_ENUM, then the final argument should be a 632 collection of strings. These strings are the valid values for this 633 parameter. 634 635 The documentation for the parameter is taken from the doc string 636 for the python class. 637 638 Returns -1 on error, with a python exception set. */ 639 640 static int 641 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) 642 { 643 parmpy_object *obj = (parmpy_object *) self; 644 const char *name; 645 char *set_doc, *show_doc, *doc; 646 char *cmd_name; 647 int parmclass, cmdtype; 648 PyObject *enum_values = NULL; 649 struct cmd_list_element **set_list, **show_list; 650 651 if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass, 652 &enum_values)) 653 return -1; 654 655 if (cmdtype != no_class && cmdtype != class_run 656 && cmdtype != class_vars && cmdtype != class_stack 657 && cmdtype != class_files && cmdtype != class_support 658 && cmdtype != class_info && cmdtype != class_breakpoint 659 && cmdtype != class_trace && cmdtype != class_obscure 660 && cmdtype != class_maintenance) 661 { 662 PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument.")); 663 return -1; 664 } 665 666 if (parmclass != var_boolean /* ARI: var_boolean */ 667 && parmclass != var_auto_boolean 668 && parmclass != var_uinteger && parmclass != var_integer 669 && parmclass != var_string && parmclass != var_string_noescape 670 && parmclass != var_optional_filename && parmclass != var_filename 671 && parmclass != var_zinteger && parmclass != var_enum) 672 { 673 PyErr_SetString (PyExc_RuntimeError, 674 _("Invalid parameter class argument.")); 675 return -1; 676 } 677 678 if (enum_values && parmclass != var_enum) 679 { 680 PyErr_SetString (PyExc_RuntimeError, 681 _("Only PARAM_ENUM accepts a fourth argument.")); 682 return -1; 683 } 684 if (parmclass == var_enum) 685 { 686 if (! compute_enum_values (obj, enum_values)) 687 return -1; 688 } 689 else 690 obj->enumeration = NULL; 691 obj->type = (enum var_types) parmclass; 692 memset (&obj->value, 0, sizeof (obj->value)); 693 694 cmd_name = gdbpy_parse_command_name (name, &set_list, 695 &setlist); 696 697 if (! cmd_name) 698 return -1; 699 xfree (cmd_name); 700 cmd_name = gdbpy_parse_command_name (name, &show_list, 701 &showlist); 702 if (! cmd_name) 703 return -1; 704 705 set_doc = get_doc_string (self, set_doc_cst).release (); 706 show_doc = get_doc_string (self, show_doc_cst).release (); 707 doc = get_doc_string (self, gdbpy_doc_cst).release (); 708 709 Py_INCREF (self); 710 711 TRY 712 { 713 add_setshow_generic (parmclass, (enum command_class) cmdtype, 714 cmd_name, obj, 715 set_doc, show_doc, 716 doc, set_list, show_list); 717 } 718 CATCH (except, RETURN_MASK_ALL) 719 { 720 xfree (cmd_name); 721 xfree (set_doc); 722 xfree (show_doc); 723 xfree (doc); 724 Py_DECREF (self); 725 PyErr_Format (except.reason == RETURN_QUIT 726 ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, 727 "%s", except.message); 728 return -1; 729 } 730 END_CATCH 731 732 return 0; 733 } 734 735 736 737 /* Initialize the 'parameters' module. */ 738 int 739 gdbpy_initialize_parameters (void) 740 { 741 int i; 742 743 parmpy_object_type.tp_new = PyType_GenericNew; 744 if (PyType_Ready (&parmpy_object_type) < 0) 745 return -1; 746 747 set_doc_cst = PyString_FromString ("set_doc"); 748 if (! set_doc_cst) 749 return -1; 750 show_doc_cst = PyString_FromString ("show_doc"); 751 if (! show_doc_cst) 752 return -1; 753 754 for (i = 0; parm_constants[i].name; ++i) 755 { 756 if (PyModule_AddIntConstant (gdb_module, 757 parm_constants[i].name, 758 parm_constants[i].value) < 0) 759 return -1; 760 } 761 762 return gdb_pymodule_addobject (gdb_module, "Parameter", 763 (PyObject *) &parmpy_object_type); 764 } 765 766 767 768 PyTypeObject parmpy_object_type = 769 { 770 PyVarObject_HEAD_INIT (NULL, 0) 771 "gdb.Parameter", /*tp_name*/ 772 sizeof (parmpy_object), /*tp_basicsize*/ 773 0, /*tp_itemsize*/ 774 0, /*tp_dealloc*/ 775 0, /*tp_print*/ 776 0, /*tp_getattr*/ 777 0, /*tp_setattr*/ 778 0, /*tp_compare*/ 779 0, /*tp_repr*/ 780 0, /*tp_as_number*/ 781 0, /*tp_as_sequence*/ 782 0, /*tp_as_mapping*/ 783 0, /*tp_hash */ 784 0, /*tp_call*/ 785 0, /*tp_str*/ 786 get_attr, /*tp_getattro*/ 787 set_attr, /*tp_setattro*/ 788 0, /*tp_as_buffer*/ 789 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 790 "GDB parameter object", /* tp_doc */ 791 0, /* tp_traverse */ 792 0, /* tp_clear */ 793 0, /* tp_richcompare */ 794 0, /* tp_weaklistoffset */ 795 0, /* tp_iter */ 796 0, /* tp_iternext */ 797 0, /* tp_methods */ 798 0, /* tp_members */ 799 0, /* tp_getset */ 800 0, /* tp_base */ 801 0, /* tp_dict */ 802 0, /* tp_descr_get */ 803 0, /* tp_descr_set */ 804 0, /* tp_dictoffset */ 805 parmpy_init, /* tp_init */ 806 0, /* tp_alloc */ 807 }; 808