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