You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

910 lines
26 KiB

  1. #include "Python.h"
  2. #include "frameobject.h"
  3. #define MODULE_NAME "_warnings"
  4. PyDoc_STRVAR(warnings__doc__,
  5. MODULE_NAME " provides basic warning filtering support.\n"
  6. "It is a helper module to speed up interpreter start-up.");
  7. /* Both 'filters' and 'onceregistry' can be set in warnings.py;
  8. get_warnings_attr() will reset these variables accordingly. */
  9. static PyObject *_filters; /* List */
  10. static PyObject *_once_registry; /* Dict */
  11. static PyObject *_default_action; /* String */
  12. static int
  13. check_matched(PyObject *obj, PyObject *arg)
  14. {
  15. PyObject *result;
  16. int rc;
  17. if (obj == Py_None)
  18. return 1;
  19. result = PyObject_CallMethod(obj, "match", "O", arg);
  20. if (result == NULL)
  21. return -1;
  22. rc = PyObject_IsTrue(result);
  23. Py_DECREF(result);
  24. return rc;
  25. }
  26. /*
  27. Returns a new reference.
  28. A NULL return value can mean false or an error.
  29. */
  30. static PyObject *
  31. get_warnings_attr(const char *attr)
  32. {
  33. static PyObject *warnings_str = NULL;
  34. PyObject *all_modules;
  35. PyObject *warnings_module;
  36. int result;
  37. if (warnings_str == NULL) {
  38. warnings_str = PyString_InternFromString("warnings");
  39. if (warnings_str == NULL)
  40. return NULL;
  41. }
  42. all_modules = PyImport_GetModuleDict();
  43. result = PyDict_Contains(all_modules, warnings_str);
  44. if (result == -1 || result == 0)
  45. return NULL;
  46. warnings_module = PyDict_GetItem(all_modules, warnings_str);
  47. if (!PyObject_HasAttrString(warnings_module, attr))
  48. return NULL;
  49. return PyObject_GetAttrString(warnings_module, attr);
  50. }
  51. static PyObject *
  52. get_once_registry(void)
  53. {
  54. PyObject *registry;
  55. registry = get_warnings_attr("onceregistry");
  56. if (registry == NULL) {
  57. if (PyErr_Occurred())
  58. return NULL;
  59. return _once_registry;
  60. }
  61. Py_DECREF(_once_registry);
  62. _once_registry = registry;
  63. return registry;
  64. }
  65. static PyObject *
  66. get_default_action(void)
  67. {
  68. PyObject *default_action;
  69. default_action = get_warnings_attr("defaultaction");
  70. if (default_action == NULL) {
  71. if (PyErr_Occurred()) {
  72. return NULL;
  73. }
  74. return _default_action;
  75. }
  76. Py_DECREF(_default_action);
  77. _default_action = default_action;
  78. return default_action;
  79. }
  80. /* The item is a borrowed reference. */
  81. static const char *
  82. get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
  83. PyObject *module, PyObject **item)
  84. {
  85. PyObject *action;
  86. Py_ssize_t i;
  87. PyObject *warnings_filters;
  88. warnings_filters = get_warnings_attr("filters");
  89. if (warnings_filters == NULL) {
  90. if (PyErr_Occurred())
  91. return NULL;
  92. }
  93. else {
  94. Py_DECREF(_filters);
  95. _filters = warnings_filters;
  96. }
  97. if (!PyList_Check(_filters)) {
  98. PyErr_SetString(PyExc_ValueError,
  99. MODULE_NAME ".filters must be a list");
  100. return NULL;
  101. }
  102. /* _filters could change while we are iterating over it. */
  103. for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
  104. PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
  105. Py_ssize_t ln;
  106. int is_subclass, good_msg, good_mod;
  107. tmp_item = *item = PyList_GET_ITEM(_filters, i);
  108. if (PyTuple_Size(tmp_item) != 5) {
  109. PyErr_Format(PyExc_ValueError,
  110. MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
  111. return NULL;
  112. }
  113. /* Python code: action, msg, cat, mod, ln = item */
  114. action = PyTuple_GET_ITEM(tmp_item, 0);
  115. msg = PyTuple_GET_ITEM(tmp_item, 1);
  116. cat = PyTuple_GET_ITEM(tmp_item, 2);
  117. mod = PyTuple_GET_ITEM(tmp_item, 3);
  118. ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
  119. good_msg = check_matched(msg, text);
  120. good_mod = check_matched(mod, module);
  121. is_subclass = PyObject_IsSubclass(category, cat);
  122. ln = PyInt_AsSsize_t(ln_obj);
  123. if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
  124. (ln == -1 && PyErr_Occurred()))
  125. return NULL;
  126. if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
  127. return PyString_AsString(action);
  128. }
  129. action = get_default_action();
  130. if (action != NULL) {
  131. return PyString_AsString(action);
  132. }
  133. PyErr_SetString(PyExc_ValueError,
  134. MODULE_NAME ".defaultaction not found");
  135. return NULL;
  136. }
  137. static int
  138. already_warned(PyObject *registry, PyObject *key, int should_set)
  139. {
  140. PyObject *already_warned;
  141. if (key == NULL)
  142. return -1;
  143. already_warned = PyDict_GetItem(registry, key);
  144. if (already_warned != NULL) {
  145. int rc = PyObject_IsTrue(already_warned);
  146. if (rc != 0)
  147. return rc;
  148. }
  149. /* This warning wasn't found in the registry, set it. */
  150. if (should_set)
  151. return PyDict_SetItem(registry, key, Py_True);
  152. return 0;
  153. }
  154. /* New reference. */
  155. static PyObject *
  156. normalize_module(PyObject *filename)
  157. {
  158. PyObject *module;
  159. const char *mod_str;
  160. Py_ssize_t len;
  161. int rc = PyObject_IsTrue(filename);
  162. if (rc == -1)
  163. return NULL;
  164. else if (rc == 0)
  165. return PyString_FromString("<unknown>");
  166. mod_str = PyString_AsString(filename);
  167. if (mod_str == NULL)
  168. return NULL;
  169. len = PyString_Size(filename);
  170. if (len < 0)
  171. return NULL;
  172. if (len >= 3 &&
  173. strncmp(mod_str + (len - 3), ".py", 3) == 0) {
  174. module = PyString_FromStringAndSize(mod_str, len-3);
  175. }
  176. else {
  177. module = filename;
  178. Py_INCREF(module);
  179. }
  180. return module;
  181. }
  182. static int
  183. update_registry(PyObject *registry, PyObject *text, PyObject *category,
  184. int add_zero)
  185. {
  186. PyObject *altkey, *zero = NULL;
  187. int rc;
  188. if (add_zero) {
  189. zero = PyInt_FromLong(0);
  190. if (zero == NULL)
  191. return -1;
  192. altkey = PyTuple_Pack(3, text, category, zero);
  193. }
  194. else
  195. altkey = PyTuple_Pack(2, text, category);
  196. rc = already_warned(registry, altkey, 1);
  197. Py_XDECREF(zero);
  198. Py_XDECREF(altkey);
  199. return rc;
  200. }
  201. static void
  202. show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
  203. *category, PyObject *sourceline)
  204. {
  205. PyObject *f_stderr;
  206. PyObject *name;
  207. char lineno_str[128];
  208. PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
  209. name = PyObject_GetAttrString(category, "__name__");
  210. if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
  211. return;
  212. f_stderr = PySys_GetObject("stderr");
  213. if (f_stderr == NULL) {
  214. fprintf(stderr, "lost sys.stderr\n");
  215. Py_DECREF(name);
  216. return;
  217. }
  218. /* Print "filename:lineno: category: text\n" */
  219. PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW);
  220. PyFile_WriteString(lineno_str, f_stderr);
  221. PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW);
  222. PyFile_WriteString(": ", f_stderr);
  223. PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW);
  224. PyFile_WriteString("\n", f_stderr);
  225. Py_XDECREF(name);
  226. /* Print " source_line\n" */
  227. if (sourceline) {
  228. char *source_line_str = PyString_AS_STRING(sourceline);
  229. while (*source_line_str == ' ' || *source_line_str == '\t' ||
  230. *source_line_str == '\014')
  231. source_line_str++;
  232. PyFile_WriteString(source_line_str, f_stderr);
  233. PyFile_WriteString("\n", f_stderr);
  234. }
  235. else
  236. _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename),
  237. lineno, 2);
  238. PyErr_Clear();
  239. }
  240. static PyObject *
  241. warn_explicit(PyObject *category, PyObject *message,
  242. PyObject *filename, int lineno,
  243. PyObject *module, PyObject *registry, PyObject *sourceline)
  244. {
  245. PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
  246. PyObject *item = Py_None;
  247. const char *action;
  248. int rc;
  249. if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
  250. PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
  251. return NULL;
  252. }
  253. /* Normalize module. */
  254. if (module == NULL) {
  255. module = normalize_module(filename);
  256. if (module == NULL)
  257. return NULL;
  258. }
  259. else
  260. Py_INCREF(module);
  261. /* Normalize message. */
  262. Py_INCREF(message); /* DECREF'ed in cleanup. */
  263. rc = PyObject_IsInstance(message, PyExc_Warning);
  264. if (rc == -1) {
  265. goto cleanup;
  266. }
  267. if (rc == 1) {
  268. text = PyObject_Str(message);
  269. if (text == NULL)
  270. goto cleanup;
  271. category = (PyObject*)message->ob_type;
  272. }
  273. else {
  274. text = message;
  275. message = PyObject_CallFunction(category, "O", message);
  276. if (message == NULL)
  277. goto cleanup;
  278. }
  279. lineno_obj = PyInt_FromLong(lineno);
  280. if (lineno_obj == NULL)
  281. goto cleanup;
  282. /* Create key. */
  283. key = PyTuple_Pack(3, text, category, lineno_obj);
  284. if (key == NULL)
  285. goto cleanup;
  286. if ((registry != NULL) && (registry != Py_None)) {
  287. rc = already_warned(registry, key, 0);
  288. if (rc == -1)
  289. goto cleanup;
  290. else if (rc == 1)
  291. goto return_none;
  292. /* Else this warning hasn't been generated before. */
  293. }
  294. action = get_filter(category, text, lineno, module, &item);
  295. if (action == NULL)
  296. goto cleanup;
  297. if (strcmp(action, "error") == 0) {
  298. PyErr_SetObject(category, message);
  299. goto cleanup;
  300. }
  301. /* Store in the registry that we've been here, *except* when the action
  302. is "always". */
  303. rc = 0;
  304. if (strcmp(action, "always") != 0) {
  305. if (registry != NULL && registry != Py_None &&
  306. PyDict_SetItem(registry, key, Py_True) < 0)
  307. goto cleanup;
  308. else if (strcmp(action, "ignore") == 0)
  309. goto return_none;
  310. else if (strcmp(action, "once") == 0) {
  311. if (registry == NULL || registry == Py_None) {
  312. registry = get_once_registry();
  313. if (registry == NULL)
  314. goto cleanup;
  315. }
  316. /* _once_registry[(text, category)] = 1 */
  317. rc = update_registry(registry, text, category, 0);
  318. }
  319. else if (strcmp(action, "module") == 0) {
  320. /* registry[(text, category, 0)] = 1 */
  321. if (registry != NULL && registry != Py_None)
  322. rc = update_registry(registry, text, category, 0);
  323. }
  324. else if (strcmp(action, "default") != 0) {
  325. PyObject *to_str = PyObject_Str(item);
  326. const char *err_str = "???";
  327. if (to_str != NULL)
  328. err_str = PyString_AS_STRING(to_str);
  329. PyErr_Format(PyExc_RuntimeError,
  330. "Unrecognized action (%s) in warnings.filters:\n %s",
  331. action, err_str);
  332. Py_XDECREF(to_str);
  333. goto cleanup;
  334. }
  335. }
  336. if (rc == 1) /* Already warned for this module. */
  337. goto return_none;
  338. if (rc == 0) {
  339. PyObject *show_fxn = get_warnings_attr("showwarning");
  340. if (show_fxn == NULL) {
  341. if (PyErr_Occurred())
  342. goto cleanup;
  343. show_warning(filename, lineno, text, category, sourceline);
  344. }
  345. else {
  346. PyObject *res;
  347. if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) {
  348. PyErr_SetString(PyExc_TypeError,
  349. "warnings.showwarning() must be set to a "
  350. "function or method");
  351. Py_DECREF(show_fxn);
  352. goto cleanup;
  353. }
  354. res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
  355. filename, lineno_obj,
  356. NULL);
  357. Py_DECREF(show_fxn);
  358. Py_XDECREF(res);
  359. if (res == NULL)
  360. goto cleanup;
  361. }
  362. }
  363. else /* if (rc == -1) */
  364. goto cleanup;
  365. return_none:
  366. result = Py_None;
  367. Py_INCREF(result);
  368. cleanup:
  369. Py_XDECREF(key);
  370. Py_XDECREF(text);
  371. Py_XDECREF(lineno_obj);
  372. Py_DECREF(module);
  373. Py_XDECREF(message);
  374. return result; /* Py_None or NULL. */
  375. }
  376. /* filename, module, and registry are new refs, globals is borrowed */
  377. /* Returns 0 on error (no new refs), 1 on success */
  378. static int
  379. setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
  380. PyObject **module, PyObject **registry)
  381. {
  382. PyObject *globals;
  383. /* Setup globals and lineno. */
  384. PyFrameObject *f = PyThreadState_GET()->frame;
  385. while (--stack_level > 0 && f != NULL)
  386. f = f->f_back;
  387. if (f == NULL) {
  388. globals = PyThreadState_Get()->interp->sysdict;
  389. *lineno = 1;
  390. }
  391. else {
  392. globals = f->f_globals;
  393. *lineno = PyFrame_GetLineNumber(f);
  394. }
  395. *module = NULL;
  396. /* Setup registry. */
  397. assert(globals != NULL);
  398. assert(PyDict_Check(globals));
  399. *registry = PyDict_GetItemString(globals, "__warningregistry__");
  400. if (*registry == NULL) {
  401. int rc;
  402. *registry = PyDict_New();
  403. if (*registry == NULL)
  404. return 0;
  405. rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
  406. if (rc < 0)
  407. goto handle_error;
  408. }
  409. else
  410. Py_INCREF(*registry);
  411. /* Setup module. */
  412. *module = PyDict_GetItemString(globals, "__name__");
  413. if (*module == NULL) {
  414. *module = PyString_FromString("<string>");
  415. if (*module == NULL)
  416. goto handle_error;
  417. }
  418. else
  419. Py_INCREF(*module);
  420. /* Setup filename. */
  421. *filename = PyDict_GetItemString(globals, "__file__");
  422. if (*filename != NULL && PyString_Check(*filename)) {
  423. Py_ssize_t len = PyString_Size(*filename);
  424. const char *file_str = PyString_AsString(*filename);
  425. if (file_str == NULL || (len < 0 && PyErr_Occurred()))
  426. goto handle_error;
  427. /* if filename.lower().endswith((".pyc", ".pyo")): */
  428. if (len >= 4 &&
  429. file_str[len-4] == '.' &&
  430. tolower(file_str[len-3]) == 'p' &&
  431. tolower(file_str[len-2]) == 'y' &&
  432. (tolower(file_str[len-1]) == 'c' ||
  433. tolower(file_str[len-1]) == 'o'))
  434. {
  435. *filename = PyString_FromStringAndSize(file_str, len-1);
  436. if (*filename == NULL)
  437. goto handle_error;
  438. }
  439. else
  440. Py_INCREF(*filename);
  441. }
  442. else {
  443. const char *module_str = PyString_AsString(*module);
  444. *filename = NULL;
  445. if (module_str && strcmp(module_str, "__main__") == 0) {
  446. PyObject *argv = PySys_GetObject("argv");
  447. if (argv != NULL && PyList_Size(argv) > 0) {
  448. int is_true;
  449. *filename = PyList_GetItem(argv, 0);
  450. Py_INCREF(*filename);
  451. /* If sys.argv[0] is false, then use '__main__'. */
  452. is_true = PyObject_IsTrue(*filename);
  453. if (is_true < 0) {
  454. Py_DECREF(*filename);
  455. goto handle_error;
  456. }
  457. else if (!is_true) {
  458. Py_DECREF(*filename);
  459. *filename = PyString_FromString("__main__");
  460. if (*filename == NULL)
  461. goto handle_error;
  462. }
  463. }
  464. else {
  465. /* embedded interpreters don't have sys.argv, see bug #839151 */
  466. *filename = PyString_FromString("__main__");
  467. if (*filename == NULL)
  468. goto handle_error;
  469. }
  470. }
  471. if (*filename == NULL) {
  472. *filename = *module;
  473. Py_INCREF(*filename);
  474. }
  475. }
  476. return 1;
  477. handle_error:
  478. /* filename not XDECREF'ed here as there is no way to jump here with a
  479. dangling reference. */
  480. Py_XDECREF(*registry);
  481. Py_XDECREF(*module);
  482. return 0;
  483. }
  484. static PyObject *
  485. get_category(PyObject *message, PyObject *category)
  486. {
  487. int rc;
  488. /* Get category. */
  489. rc = PyObject_IsInstance(message, PyExc_Warning);
  490. if (rc == -1)
  491. return NULL;
  492. if (rc == 1)
  493. category = (PyObject*)message->ob_type;
  494. else if (category == NULL)
  495. category = PyExc_UserWarning;
  496. /* Validate category. */
  497. rc = PyObject_IsSubclass(category, PyExc_Warning);
  498. if (rc == -1)
  499. return NULL;
  500. if (rc == 0) {
  501. PyErr_SetString(PyExc_ValueError,
  502. "category is not a subclass of Warning");
  503. return NULL;
  504. }
  505. return category;
  506. }
  507. static PyObject *
  508. do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
  509. {
  510. PyObject *filename, *module, *registry, *res;
  511. int lineno;
  512. if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
  513. return NULL;
  514. res = warn_explicit(category, message, filename, lineno, module, registry,
  515. NULL);
  516. Py_DECREF(filename);
  517. Py_DECREF(registry);
  518. Py_DECREF(module);
  519. return res;
  520. }
  521. static PyObject *
  522. warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
  523. {
  524. static char *kw_list[] = { "message", "category", "stacklevel", 0 };
  525. PyObject *message, *category = NULL;
  526. Py_ssize_t stack_level = 1;
  527. if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
  528. &message, &category, &stack_level))
  529. return NULL;
  530. category = get_category(message, category);
  531. if (category == NULL)
  532. return NULL;
  533. return do_warn(message, category, stack_level);
  534. }
  535. static PyObject *
  536. warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
  537. {
  538. static char *kwd_list[] = {"message", "category", "filename", "lineno",
  539. "module", "registry", "module_globals", 0};
  540. PyObject *message;
  541. PyObject *category;
  542. PyObject *filename;
  543. int lineno;
  544. PyObject *module = NULL;
  545. PyObject *registry = NULL;
  546. PyObject *module_globals = NULL;
  547. if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit",
  548. kwd_list, &message, &category, &filename, &lineno, &module,
  549. &registry, &module_globals))
  550. return NULL;
  551. if (module_globals) {
  552. static PyObject *get_source_name = NULL;
  553. static PyObject *splitlines_name = NULL;
  554. PyObject *loader;
  555. PyObject *module_name;
  556. PyObject *source;
  557. PyObject *source_list;
  558. PyObject *source_line;
  559. PyObject *returned;
  560. if (get_source_name == NULL) {
  561. get_source_name = PyString_InternFromString("get_source");
  562. if (!get_source_name)
  563. return NULL;
  564. }
  565. if (splitlines_name == NULL) {
  566. splitlines_name = PyString_InternFromString("splitlines");
  567. if (!splitlines_name)
  568. return NULL;
  569. }
  570. /* Check/get the requisite pieces needed for the loader. */
  571. loader = PyDict_GetItemString(module_globals, "__loader__");
  572. module_name = PyDict_GetItemString(module_globals, "__name__");
  573. if (loader == NULL || module_name == NULL)
  574. goto standard_call;
  575. /* Make sure the loader implements the optional get_source() method. */
  576. if (!PyObject_HasAttrString(loader, "get_source"))
  577. goto standard_call;
  578. /* Call get_source() to get the source code. */
  579. source = PyObject_CallMethodObjArgs(loader, get_source_name,
  580. module_name, NULL);
  581. if (!source)
  582. return NULL;
  583. else if (source == Py_None) {
  584. Py_DECREF(Py_None);
  585. goto standard_call;
  586. }
  587. /* Split the source into lines. */
  588. source_list = PyObject_CallMethodObjArgs(source, splitlines_name,
  589. NULL);
  590. Py_DECREF(source);
  591. if (!source_list)
  592. return NULL;
  593. /* Get the source line. */
  594. source_line = PyList_GetItem(source_list, lineno-1);
  595. if (!source_line) {
  596. Py_DECREF(source_list);
  597. return NULL;
  598. }
  599. /* Handle the warning. */
  600. returned = warn_explicit(category, message, filename, lineno, module,
  601. registry, source_line);
  602. Py_DECREF(source_list);
  603. return returned;
  604. }
  605. standard_call:
  606. return warn_explicit(category, message, filename, lineno, module,
  607. registry, NULL);
  608. }
  609. /* Function to issue a warning message; may raise an exception. */
  610. int
  611. PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
  612. {
  613. PyObject *res;
  614. PyObject *message = PyString_FromString(text);
  615. if (message == NULL)
  616. return -1;
  617. if (category == NULL)
  618. category = PyExc_RuntimeWarning;
  619. res = do_warn(message, category, stack_level);
  620. Py_DECREF(message);
  621. if (res == NULL)
  622. return -1;
  623. Py_DECREF(res);
  624. return 0;
  625. }
  626. /* PyErr_Warn is only for backwards compatibility and will be removed.
  627. Use PyErr_WarnEx instead. */
  628. #undef PyErr_Warn
  629. PyAPI_FUNC(int)
  630. PyErr_Warn(PyObject *category, char *text)
  631. {
  632. return PyErr_WarnEx(category, text, 1);
  633. }
  634. /* Warning with explicit origin */
  635. int
  636. PyErr_WarnExplicit(PyObject *category, const char *text,
  637. const char *filename_str, int lineno,
  638. const char *module_str, PyObject *registry)
  639. {
  640. PyObject *res;
  641. PyObject *message = PyString_FromString(text);
  642. PyObject *filename = PyString_FromString(filename_str);
  643. PyObject *module = NULL;
  644. int ret = -1;
  645. if (message == NULL || filename == NULL)
  646. goto exit;
  647. if (module_str != NULL) {
  648. module = PyString_FromString(module_str);
  649. if (module == NULL)
  650. goto exit;
  651. }
  652. if (category == NULL)
  653. category = PyExc_RuntimeWarning;
  654. res = warn_explicit(category, message, filename, lineno, module, registry,
  655. NULL);
  656. if (res == NULL)
  657. goto exit;
  658. Py_DECREF(res);
  659. ret = 0;
  660. exit:
  661. Py_XDECREF(message);
  662. Py_XDECREF(module);
  663. Py_XDECREF(filename);
  664. return ret;
  665. }
  666. PyDoc_STRVAR(warn_doc,
  667. "Issue a warning, or maybe ignore it or raise an exception.");
  668. PyDoc_STRVAR(warn_explicit_doc,
  669. "Low-level inferface to warnings functionality.");
  670. static PyMethodDef warnings_functions[] = {
  671. {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
  672. warn_doc},
  673. {"warn_explicit", (PyCFunction)warnings_warn_explicit,
  674. METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
  675. /* XXX(brett.cannon): add showwarning? */
  676. /* XXX(brett.cannon): Reasonable to add formatwarning? */
  677. {NULL, NULL} /* sentinel */
  678. };
  679. static PyObject *
  680. create_filter(PyObject *category, const char *action)
  681. {
  682. static PyObject *ignore_str = NULL;
  683. static PyObject *error_str = NULL;
  684. static PyObject *default_str = NULL;
  685. PyObject *action_obj = NULL;
  686. PyObject *lineno, *result;
  687. if (!strcmp(action, "ignore")) {
  688. if (ignore_str == NULL) {
  689. ignore_str = PyString_InternFromString("ignore");
  690. if (ignore_str == NULL)
  691. return NULL;
  692. }
  693. action_obj = ignore_str;
  694. }
  695. else if (!strcmp(action, "error")) {
  696. if (error_str == NULL) {
  697. error_str = PyString_InternFromString("error");
  698. if (error_str == NULL)
  699. return NULL;
  700. }
  701. action_obj = error_str;
  702. }
  703. else if (!strcmp(action, "default")) {
  704. if (default_str == NULL) {
  705. default_str = PyString_InternFromString("default");
  706. if (default_str == NULL)
  707. return NULL;
  708. }
  709. action_obj = default_str;
  710. }
  711. else {
  712. Py_FatalError("unknown action");
  713. }
  714. /* This assumes the line number is zero for now. */
  715. lineno = PyInt_FromLong(0);
  716. if (lineno == NULL)
  717. return NULL;
  718. result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
  719. Py_DECREF(lineno);
  720. return result;
  721. }
  722. static PyObject *
  723. init_filters(void)
  724. {
  725. /* Don't silence DeprecationWarning if -3 or -Q were used. */
  726. PyObject *filters = PyList_New(Py_Py3kWarningFlag ||
  727. Py_DivisionWarningFlag ? 3 : 4);
  728. unsigned int pos = 0; /* Post-incremented in each use. */
  729. unsigned int x;
  730. const char *bytes_action;
  731. if (filters == NULL)
  732. return NULL;
  733. /* If guard changes, make sure to update 'filters' initialization above. */
  734. if (!Py_Py3kWarningFlag && !Py_DivisionWarningFlag) {
  735. PyList_SET_ITEM(filters, pos++,
  736. create_filter(PyExc_DeprecationWarning, "ignore"));
  737. }
  738. PyList_SET_ITEM(filters, pos++,
  739. create_filter(PyExc_PendingDeprecationWarning, "ignore"));
  740. PyList_SET_ITEM(filters, pos++,
  741. create_filter(PyExc_ImportWarning, "ignore"));
  742. if (Py_BytesWarningFlag > 1)
  743. bytes_action = "error";
  744. else if (Py_BytesWarningFlag)
  745. bytes_action = "default";
  746. else
  747. bytes_action = "ignore";
  748. PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
  749. bytes_action));
  750. for (x = 0; x < pos; x += 1) {
  751. if (PyList_GET_ITEM(filters, x) == NULL) {
  752. Py_DECREF(filters);
  753. return NULL;
  754. }
  755. }
  756. return filters;
  757. }
  758. PyMODINIT_FUNC
  759. _PyWarnings_Init(void)
  760. {
  761. PyObject *m;
  762. m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);
  763. if (m == NULL)
  764. return;
  765. _filters = init_filters();
  766. if (_filters == NULL)
  767. return;
  768. Py_INCREF(_filters);
  769. if (PyModule_AddObject(m, "filters", _filters) < 0)
  770. return;
  771. _once_registry = PyDict_New();
  772. if (_once_registry == NULL)
  773. return;
  774. Py_INCREF(_once_registry);
  775. if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
  776. return;
  777. _default_action = PyString_FromString("default");
  778. if (_default_action == NULL)
  779. return;
  780. if (PyModule_AddObject(m, "default_action", _default_action) < 0)
  781. return;
  782. }