/Python/_warnings.c

http://unladen-swallow.googlecode.com/ · C · 916 lines · 742 code · 123 blank · 51 comment · 302 complexity · 633f7c446506233a4c4d8ed48ba07936 MD5 · raw file

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