1 2 /* Testing module for multi-phase initialization of extension modules (PEP 489) 3 */ 4 5 #include "Python.h" 6 7 /* Example objects */ 8 typedef struct { 9 PyObject_HEAD 10 PyObject *x_attr; /* Attributes dictionary */ 11 } ExampleObject; 12 13 /* Example methods */ 14 15 static int 16 Example_traverse(ExampleObject *self, visitproc visit, void *arg) 17 { 18 Py_VISIT(self->x_attr); 19 return 0; 20 } 21 22 static int 23 Example_finalize(ExampleObject *self) 24 { 25 Py_CLEAR(self->x_attr); 26 return 0; 27 } 28 29 static PyObject * 30 Example_demo(ExampleObject *self, PyObject *args) 31 { 32 PyObject *o = NULL; 33 if (!PyArg_ParseTuple(args, "|O:demo", &o)) 34 return NULL; 35 if (o != NULL && PyUnicode_Check(o)) { 36 Py_INCREF(o); 37 return o; 38 } 39 Py_INCREF(Py_None); 40 return Py_None; 41 } 42 43 44 static PyMethodDef Example_methods[] = { 45 {"demo", (PyCFunction)Example_demo, METH_VARARGS, 46 PyDoc_STR("demo() -> None")}, 47 {NULL, NULL} /* sentinel */ 48 }; 49 50 static PyObject * 51 Example_getattro(ExampleObject *self, PyObject *name) 52 { 53 if (self->x_attr != NULL) { 54 PyObject *v = PyDict_GetItem(self->x_attr, name); 55 if (v != NULL) { 56 Py_INCREF(v); 57 return v; 58 } 59 } 60 return PyObject_GenericGetAttr((PyObject *)self, name); 61 } 62 63 static int 64 Example_setattr(ExampleObject *self, const char *name, PyObject *v) 65 { 66 if (self->x_attr == NULL) { 67 self->x_attr = PyDict_New(); 68 if (self->x_attr == NULL) 69 return -1; 70 } 71 if (v == NULL) { 72 int rv = PyDict_DelItemString(self->x_attr, name); 73 if (rv < 0) 74 PyErr_SetString(PyExc_AttributeError, 75 "delete non-existing Example attribute"); 76 return rv; 77 } 78 else 79 return PyDict_SetItemString(self->x_attr, name, v); 80 } 81 82 static PyType_Slot Example_Type_slots[] = { 83 {Py_tp_doc, "The Example type"}, 84 {Py_tp_finalize, Example_finalize}, 85 {Py_tp_traverse, Example_traverse}, 86 {Py_tp_getattro, Example_getattro}, 87 {Py_tp_setattr, Example_setattr}, 88 {Py_tp_methods, Example_methods}, 89 {0, 0}, 90 }; 91 92 static PyType_Spec Example_Type_spec = { 93 "_testimportexec.Example", 94 sizeof(ExampleObject), 95 0, 96 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, 97 Example_Type_slots 98 }; 99 100 /* Function of two integers returning integer */ 101 102 PyDoc_STRVAR(testexport_foo_doc, 103 "foo(i,j)\n\ 104 \n\ 105 Return the sum of i and j."); 106 107 static PyObject * 108 testexport_foo(PyObject *self, PyObject *args) 109 { 110 long i, j; 111 long res; 112 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) 113 return NULL; 114 res = i + j; 115 return PyLong_FromLong(res); 116 } 117 118 /* Test that PyState registration fails */ 119 120 PyDoc_STRVAR(call_state_registration_func_doc, 121 "register_state(0): call PyState_FindModule()\n\ 122 register_state(1): call PyState_AddModule()\n\ 123 register_state(2): call PyState_RemoveModule()"); 124 125 static PyObject * 126 call_state_registration_func(PyObject *mod, PyObject *args) 127 { 128 int i, ret; 129 PyModuleDef *def = PyModule_GetDef(mod); 130 if (def == NULL) { 131 return NULL; 132 } 133 if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i)) 134 return NULL; 135 switch (i) { 136 case 0: 137 mod = PyState_FindModule(def); 138 if (mod == NULL) { 139 Py_RETURN_NONE; 140 } 141 return mod; 142 case 1: 143 ret = PyState_AddModule(mod, def); 144 if (ret != 0) { 145 return NULL; 146 } 147 break; 148 case 2: 149 ret = PyState_RemoveModule(def); 150 if (ret != 0) { 151 return NULL; 152 } 153 break; 154 } 155 Py_RETURN_NONE; 156 } 157 158 159 static PyType_Slot Str_Type_slots[] = { 160 {Py_tp_base, NULL}, /* filled out in module exec function */ 161 {0, 0}, 162 }; 163 164 static PyType_Spec Str_Type_spec = { 165 "_testimportexec.Str", 166 0, 167 0, 168 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 169 Str_Type_slots 170 }; 171 172 static PyMethodDef testexport_methods[] = { 173 {"foo", testexport_foo, METH_VARARGS, 174 testexport_foo_doc}, 175 {"call_state_registration_func", call_state_registration_func, 176 METH_VARARGS, call_state_registration_func_doc}, 177 {NULL, NULL} /* sentinel */ 178 }; 179 180 static int execfunc(PyObject *m) 181 { 182 PyObject *temp = NULL; 183 184 /* Due to cross platform compiler issues the slots must be filled 185 * here. It's required for portability to Windows without requiring 186 * C++. */ 187 Str_Type_slots[0].pfunc = &PyUnicode_Type; 188 189 /* Add a custom type */ 190 temp = PyType_FromSpec(&Example_Type_spec); 191 if (temp == NULL) 192 goto fail; 193 if (PyModule_AddObject(m, "Example", temp) != 0) 194 goto fail; 195 196 /* Add an exception type */ 197 temp = PyErr_NewException("_testimportexec.error", NULL, NULL); 198 if (temp == NULL) 199 goto fail; 200 if (PyModule_AddObject(m, "error", temp) != 0) 201 goto fail; 202 203 /* Add Str */ 204 temp = PyType_FromSpec(&Str_Type_spec); 205 if (temp == NULL) 206 goto fail; 207 if (PyModule_AddObject(m, "Str", temp) != 0) 208 goto fail; 209 210 if (PyModule_AddIntConstant(m, "int_const", 1969) != 0) 211 goto fail; 212 213 if (PyModule_AddStringConstant(m, "str_const", "something different") != 0) 214 goto fail; 215 216 return 0; 217 fail: 218 return -1; 219 } 220 221 /* Helper for module definitions; there'll be a lot of them */ 222 #define TEST_MODULE_DEF(name, slots, methods) { \ 223 PyModuleDef_HEAD_INIT, /* m_base */ \ 224 name, /* m_name */ \ 225 PyDoc_STR("Test module " name), /* m_doc */ \ 226 0, /* m_size */ \ 227 methods, /* m_methods */ \ 228 slots, /* m_slots */ \ 229 NULL, /* m_traverse */ \ 230 NULL, /* m_clear */ \ 231 NULL, /* m_free */ \ 232 } 233 234 PyModuleDef_Slot main_slots[] = { 235 {Py_mod_exec, execfunc}, 236 {0, NULL}, 237 }; 238 239 static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); 240 241 PyMODINIT_FUNC 242 PyInit__testmultiphase(PyObject *spec) 243 { 244 return PyModuleDef_Init(&main_def); 245 } 246 247 248 /**** Importing a non-module object ****/ 249 250 static PyModuleDef def_nonmodule; 251 static PyModuleDef def_nonmodule_with_methods; 252 253 /* Create a SimpleNamespace(three=3) */ 254 static PyObject* 255 createfunc_nonmodule(PyObject *spec, PyModuleDef *def) 256 { 257 PyObject *dct, *ns, *three; 258 259 if (def != &def_nonmodule && def != &def_nonmodule_with_methods) { 260 PyErr_SetString(PyExc_SystemError, "def does not match"); 261 return NULL; 262 } 263 264 dct = PyDict_New(); 265 if (dct == NULL) 266 return NULL; 267 268 three = PyLong_FromLong(3); 269 if (three == NULL) { 270 Py_DECREF(dct); 271 return NULL; 272 } 273 PyDict_SetItemString(dct, "three", three); 274 Py_DECREF(three); 275 276 ns = _PyNamespace_New(dct); 277 Py_DECREF(dct); 278 return ns; 279 } 280 281 static PyModuleDef_Slot slots_create_nonmodule[] = { 282 {Py_mod_create, createfunc_nonmodule}, 283 {0, NULL}, 284 }; 285 286 static PyModuleDef def_nonmodule = TEST_MODULE_DEF( 287 "_testmultiphase_nonmodule", slots_create_nonmodule, NULL); 288 289 PyMODINIT_FUNC 290 PyInit__testmultiphase_nonmodule(PyObject *spec) 291 { 292 return PyModuleDef_Init(&def_nonmodule); 293 } 294 295 PyDoc_STRVAR(nonmodule_bar_doc, 296 "bar(i,j)\n\ 297 \n\ 298 Return the difference of i - j."); 299 300 static PyObject * 301 nonmodule_bar(PyObject *self, PyObject *args) 302 { 303 long i, j; 304 long res; 305 if (!PyArg_ParseTuple(args, "ll:bar", &i, &j)) 306 return NULL; 307 res = i - j; 308 return PyLong_FromLong(res); 309 } 310 311 static PyMethodDef nonmodule_methods[] = { 312 {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc}, 313 {NULL, NULL} /* sentinel */ 314 }; 315 316 static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF( 317 "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods); 318 319 PyMODINIT_FUNC 320 PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec) 321 { 322 return PyModuleDef_Init(&def_nonmodule_with_methods); 323 } 324 325 /**** Non-ASCII-named modules ****/ 326 327 static PyModuleDef def_nonascii_latin = { \ 328 PyModuleDef_HEAD_INIT, /* m_base */ 329 "_testmultiphase_nonascii_latin", /* m_name */ 330 PyDoc_STR("Module named in Czech"), /* m_doc */ 331 0, /* m_size */ 332 NULL, /* m_methods */ 333 NULL, /* m_slots */ 334 NULL, /* m_traverse */ 335 NULL, /* m_clear */ 336 NULL, /* m_free */ 337 }; 338 339 PyMODINIT_FUNC 340 PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec) 341 { 342 return PyModuleDef_Init(&def_nonascii_latin); 343 } 344 345 static PyModuleDef def_nonascii_kana = { \ 346 PyModuleDef_HEAD_INIT, /* m_base */ 347 "_testmultiphase_nonascii_kana", /* m_name */ 348 PyDoc_STR("Module named in Japanese"), /* m_doc */ 349 0, /* m_size */ 350 NULL, /* m_methods */ 351 NULL, /* m_slots */ 352 NULL, /* m_traverse */ 353 NULL, /* m_clear */ 354 NULL, /* m_free */ 355 }; 356 357 PyMODINIT_FUNC 358 PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec) 359 { 360 return PyModuleDef_Init(&def_nonascii_kana); 361 } 362 363 /*** Module with a single-character name ***/ 364 365 PyMODINIT_FUNC 366 PyInit_x(PyObject *spec) 367 { 368 return PyModuleDef_Init(&main_def); 369 } 370 371 /**** Testing NULL slots ****/ 372 373 static PyModuleDef null_slots_def = TEST_MODULE_DEF( 374 "_testmultiphase_null_slots", NULL, NULL); 375 376 PyMODINIT_FUNC 377 PyInit__testmultiphase_null_slots(PyObject *spec) 378 { 379 return PyModuleDef_Init(&null_slots_def); 380 } 381 382 /**** Problematic modules ****/ 383 384 static PyModuleDef_Slot slots_bad_large[] = { 385 {_Py_mod_LAST_SLOT + 1, NULL}, 386 {0, NULL}, 387 }; 388 389 static PyModuleDef def_bad_large = TEST_MODULE_DEF( 390 "_testmultiphase_bad_slot_large", slots_bad_large, NULL); 391 392 PyMODINIT_FUNC 393 PyInit__testmultiphase_bad_slot_large(PyObject *spec) 394 { 395 return PyModuleDef_Init(&def_bad_large); 396 } 397 398 static PyModuleDef_Slot slots_bad_negative[] = { 399 {-1, NULL}, 400 {0, NULL}, 401 }; 402 403 static PyModuleDef def_bad_negative = TEST_MODULE_DEF( 404 "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL); 405 406 PyMODINIT_FUNC 407 PyInit__testmultiphase_bad_slot_negative(PyObject *spec) 408 { 409 return PyModuleDef_Init(&def_bad_negative); 410 } 411 412 static PyModuleDef def_create_int_with_state = { \ 413 PyModuleDef_HEAD_INIT, /* m_base */ 414 "create_with_state", /* m_name */ 415 PyDoc_STR("Not a PyModuleObject object, but requests per-module state"), 416 10, /* m_size */ 417 NULL, /* m_methods */ 418 slots_create_nonmodule, /* m_slots */ 419 NULL, /* m_traverse */ 420 NULL, /* m_clear */ 421 NULL, /* m_free */ 422 }; 423 424 PyMODINIT_FUNC 425 PyInit__testmultiphase_create_int_with_state(PyObject *spec) 426 { 427 return PyModuleDef_Init(&def_create_int_with_state); 428 } 429 430 431 static PyModuleDef def_negative_size = { \ 432 PyModuleDef_HEAD_INIT, /* m_base */ 433 "negative_size", /* m_name */ 434 PyDoc_STR("PyModuleDef with negative m_size"), 435 -1, /* m_size */ 436 NULL, /* m_methods */ 437 slots_create_nonmodule, /* m_slots */ 438 NULL, /* m_traverse */ 439 NULL, /* m_clear */ 440 NULL, /* m_free */ 441 }; 442 443 PyMODINIT_FUNC 444 PyInit__testmultiphase_negative_size(PyObject *spec) 445 { 446 return PyModuleDef_Init(&def_negative_size); 447 } 448 449 450 static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); 451 452 PyMODINIT_FUNC 453 PyInit__testmultiphase_export_uninitialized(PyObject *spec) 454 { 455 return (PyObject*) &uninitialized_def; 456 } 457 458 PyMODINIT_FUNC 459 PyInit__testmultiphase_export_null(PyObject *spec) 460 { 461 return NULL; 462 } 463 464 PyMODINIT_FUNC 465 PyInit__testmultiphase_export_raise(PyObject *spec) 466 { 467 PyErr_SetString(PyExc_SystemError, "bad export function"); 468 return NULL; 469 } 470 471 PyMODINIT_FUNC 472 PyInit__testmultiphase_export_unreported_exception(PyObject *spec) 473 { 474 PyErr_SetString(PyExc_SystemError, "bad export function"); 475 return PyModuleDef_Init(&main_def); 476 } 477 478 static PyObject* 479 createfunc_null(PyObject *spec, PyModuleDef *def) 480 { 481 return NULL; 482 } 483 484 PyModuleDef_Slot slots_create_null[] = { 485 {Py_mod_create, createfunc_null}, 486 {0, NULL}, 487 }; 488 489 static PyModuleDef def_create_null = TEST_MODULE_DEF( 490 "_testmultiphase_create_null", slots_create_null, NULL); 491 492 PyMODINIT_FUNC 493 PyInit__testmultiphase_create_null(PyObject *spec) 494 { 495 return PyModuleDef_Init(&def_create_null); 496 } 497 498 static PyObject* 499 createfunc_raise(PyObject *spec, PyModuleDef *def) 500 { 501 PyErr_SetString(PyExc_SystemError, "bad create function"); 502 return NULL; 503 } 504 505 static PyModuleDef_Slot slots_create_raise[] = { 506 {Py_mod_create, createfunc_raise}, 507 {0, NULL}, 508 }; 509 510 static PyModuleDef def_create_raise = TEST_MODULE_DEF( 511 "_testmultiphase_create_null", slots_create_raise, NULL); 512 513 PyMODINIT_FUNC 514 PyInit__testmultiphase_create_raise(PyObject *spec) 515 { 516 return PyModuleDef_Init(&def_create_raise); 517 } 518 519 static PyObject* 520 createfunc_unreported_exception(PyObject *spec, PyModuleDef *def) 521 { 522 PyErr_SetString(PyExc_SystemError, "bad create function"); 523 return PyModule_New("foo"); 524 } 525 526 static PyModuleDef_Slot slots_create_unreported_exception[] = { 527 {Py_mod_create, createfunc_unreported_exception}, 528 {0, NULL}, 529 }; 530 531 static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF( 532 "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL); 533 534 PyMODINIT_FUNC 535 PyInit__testmultiphase_create_unreported_exception(PyObject *spec) 536 { 537 return PyModuleDef_Init(&def_create_unreported_exception); 538 } 539 540 static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = { 541 {Py_mod_create, createfunc_nonmodule}, 542 {Py_mod_exec, execfunc}, 543 {0, NULL}, 544 }; 545 546 static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF( 547 "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL); 548 549 PyMODINIT_FUNC 550 PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec) 551 { 552 return PyModuleDef_Init(&def_nonmodule_with_exec_slots); 553 } 554 555 static int 556 execfunc_err(PyObject *mod) 557 { 558 return -1; 559 } 560 561 static PyModuleDef_Slot slots_exec_err[] = { 562 {Py_mod_exec, execfunc_err}, 563 {0, NULL}, 564 }; 565 566 static PyModuleDef def_exec_err = TEST_MODULE_DEF( 567 "_testmultiphase_exec_err", slots_exec_err, NULL); 568 569 PyMODINIT_FUNC 570 PyInit__testmultiphase_exec_err(PyObject *spec) 571 { 572 return PyModuleDef_Init(&def_exec_err); 573 } 574 575 static int 576 execfunc_raise(PyObject *spec) 577 { 578 PyErr_SetString(PyExc_SystemError, "bad exec function"); 579 return -1; 580 } 581 582 static PyModuleDef_Slot slots_exec_raise[] = { 583 {Py_mod_exec, execfunc_raise}, 584 {0, NULL}, 585 }; 586 587 static PyModuleDef def_exec_raise = TEST_MODULE_DEF( 588 "_testmultiphase_exec_raise", slots_exec_raise, NULL); 589 590 PyMODINIT_FUNC 591 PyInit__testmultiphase_exec_raise(PyObject *mod) 592 { 593 return PyModuleDef_Init(&def_exec_raise); 594 } 595 596 static int 597 execfunc_unreported_exception(PyObject *mod) 598 { 599 PyErr_SetString(PyExc_SystemError, "bad exec function"); 600 return 0; 601 } 602 603 static PyModuleDef_Slot slots_exec_unreported_exception[] = { 604 {Py_mod_exec, execfunc_unreported_exception}, 605 {0, NULL}, 606 }; 607 608 static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF( 609 "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL); 610 611 PyMODINIT_FUNC 612 PyInit__testmultiphase_exec_unreported_exception(PyObject *spec) 613 { 614 return PyModuleDef_Init(&def_exec_unreported_exception); 615 } 616 617 /*** Helper for imp test ***/ 618 619 static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods); 620 621 PyMODINIT_FUNC 622 PyInit_imp_dummy(PyObject *spec) 623 { 624 return PyModuleDef_Init(&imp_dummy_def); 625 } 626