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