blob: d274789f4a677c10a4ded78d897852e668e84473 [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
2#include "frameobject.h"
3
4#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00005
6PyDoc_STRVAR(warnings__doc__,
7MODULE_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. */
12static PyObject *_filters; /* List */
13static PyObject *_once_registry; /* Dict */
Brett Cannon0759dd62009-04-01 18:13:07 +000014static PyObject *_default_action; /* String */
Christian Heimes33fe8092008-04-13 13:53:33 +000015
16
17static int
18check_matched(PyObject *obj, PyObject *arg)
19{
20 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020021 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +000022 int rc;
23
24 if (obj == Py_None)
25 return 1;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020026 result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg);
Christian Heimes33fe8092008-04-13 13:53:33 +000027 if (result == NULL)
28 return -1;
29
30 rc = PyObject_IsTrue(result);
31 Py_DECREF(result);
32 return rc;
33}
34
35/*
36 Returns a new reference.
37 A NULL return value can mean false or an error.
38*/
39static PyObject *
40get_warnings_attr(const char *attr)
41{
42 static PyObject *warnings_str = NULL;
43 PyObject *all_modules;
44 PyObject *warnings_module;
45 int result;
46
47 if (warnings_str == NULL) {
48 warnings_str = PyUnicode_InternFromString("warnings");
49 if (warnings_str == NULL)
50 return NULL;
51 }
52
53 all_modules = PyImport_GetModuleDict();
54 result = PyDict_Contains(all_modules, warnings_str);
55 if (result == -1 || result == 0)
56 return NULL;
57
58 warnings_module = PyDict_GetItem(all_modules, warnings_str);
59 if (!PyObject_HasAttrString(warnings_module, attr))
60 return NULL;
61 return PyObject_GetAttrString(warnings_module, attr);
62}
63
64
Neal Norwitz32dde222008-04-15 06:43:13 +000065static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000066get_once_registry(void)
67{
68 PyObject *registry;
69
70 registry = get_warnings_attr("onceregistry");
71 if (registry == NULL) {
72 if (PyErr_Occurred())
73 return NULL;
74 return _once_registry;
75 }
76 Py_DECREF(_once_registry);
77 _once_registry = registry;
78 return registry;
79}
80
81
Brett Cannon0759dd62009-04-01 18:13:07 +000082static PyObject *
83get_default_action(void)
84{
85 PyObject *default_action;
86
87 default_action = get_warnings_attr("defaultaction");
88 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 if (PyErr_Occurred()) {
90 return NULL;
91 }
92 return _default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +000093 }
94
95 Py_DECREF(_default_action);
96 _default_action = default_action;
97 return default_action;
98}
99
100
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400101/* The item is a new reference. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000102static const char *
103get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
104 PyObject *module, PyObject **item)
105{
Brett Cannon0759dd62009-04-01 18:13:07 +0000106 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000107 Py_ssize_t i;
108 PyObject *warnings_filters;
109
110 warnings_filters = get_warnings_attr("filters");
111 if (warnings_filters == NULL) {
112 if (PyErr_Occurred())
113 return NULL;
114 }
115 else {
116 Py_DECREF(_filters);
117 _filters = warnings_filters;
118 }
119
Victor Stinner7d79b8b2010-05-19 20:40:50 +0000120 if (_filters == NULL || !PyList_Check(_filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000121 PyErr_SetString(PyExc_ValueError,
122 MODULE_NAME ".filters must be a list");
123 return NULL;
124 }
125
126 /* _filters could change while we are iterating over it. */
127 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
128 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
129 Py_ssize_t ln;
130 int is_subclass, good_msg, good_mod;
131
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400132 tmp_item = PyList_GET_ITEM(_filters, i);
133 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000134 PyErr_Format(PyExc_ValueError,
135 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
136 return NULL;
137 }
138
139 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400140 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000141 action = PyTuple_GET_ITEM(tmp_item, 0);
142 msg = PyTuple_GET_ITEM(tmp_item, 1);
143 cat = PyTuple_GET_ITEM(tmp_item, 2);
144 mod = PyTuple_GET_ITEM(tmp_item, 3);
145 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
146
147 good_msg = check_matched(msg, text);
148 good_mod = check_matched(mod, module);
149 is_subclass = PyObject_IsSubclass(category, cat);
150 ln = PyLong_AsSsize_t(ln_obj);
151 if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400152 (ln == -1 && PyErr_Occurred())) {
153 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000154 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400155 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000156
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400157 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
158 *item = tmp_item;
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000159 return _PyUnicode_AsString(action);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400160 }
161
162 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000163 }
164
Brett Cannon0759dd62009-04-01 18:13:07 +0000165 action = get_default_action();
166 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400167 Py_INCREF(Py_None);
168 *item = Py_None;
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000169 return _PyUnicode_AsString(action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000170 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000171
172 PyErr_SetString(PyExc_ValueError,
Brett Cannon0759dd62009-04-01 18:13:07 +0000173 MODULE_NAME ".defaultaction not found");
Christian Heimes33fe8092008-04-13 13:53:33 +0000174 return NULL;
175}
176
Brett Cannon0759dd62009-04-01 18:13:07 +0000177
Christian Heimes33fe8092008-04-13 13:53:33 +0000178static int
179already_warned(PyObject *registry, PyObject *key, int should_set)
180{
181 PyObject *already_warned;
182
183 if (key == NULL)
184 return -1;
185
186 already_warned = PyDict_GetItem(registry, key);
187 if (already_warned != NULL) {
188 int rc = PyObject_IsTrue(already_warned);
189 if (rc != 0)
190 return rc;
191 }
192
193 /* This warning wasn't found in the registry, set it. */
194 if (should_set)
195 return PyDict_SetItem(registry, key, Py_True);
196 return 0;
197}
198
199/* New reference. */
200static PyObject *
201normalize_module(PyObject *filename)
202{
203 PyObject *module;
204 const char *mod_str;
205 Py_ssize_t len;
206
207 int rc = PyObject_IsTrue(filename);
208 if (rc == -1)
209 return NULL;
210 else if (rc == 0)
211 return PyUnicode_FromString("<unknown>");
212
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000213 mod_str = _PyUnicode_AsString(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000214 if (mod_str == NULL)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100215 return NULL;
216 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000217 if (len < 0)
218 return NULL;
219 if (len >= 3 &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 strncmp(mod_str + (len - 3), ".py", 3) == 0) {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100221 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000222 }
223 else {
224 module = filename;
225 Py_INCREF(module);
226 }
227 return module;
228}
229
230static int
231update_registry(PyObject *registry, PyObject *text, PyObject *category,
232 int add_zero)
233{
234 PyObject *altkey, *zero = NULL;
235 int rc;
236
237 if (add_zero) {
238 zero = PyLong_FromLong(0);
239 if (zero == NULL)
240 return -1;
241 altkey = PyTuple_Pack(3, text, category, zero);
242 }
243 else
244 altkey = PyTuple_Pack(2, text, category);
245
246 rc = already_warned(registry, altkey, 1);
247 Py_XDECREF(zero);
248 Py_XDECREF(altkey);
249 return rc;
250}
251
252static void
253show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
254 *category, PyObject *sourceline)
255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 PyObject *f_stderr;
257 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000258 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200259 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000260
261 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
262
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200263 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000264 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000265 return;
Christian Heimes33fe8092008-04-13 13:53:33 +0000266
267 f_stderr = PySys_GetObject("stderr");
268 if (f_stderr == NULL) {
269 fprintf(stderr, "lost sys.stderr\n");
270 Py_DECREF(name);
271 return;
272 }
273
274 /* Print "filename:lineno: category: text\n" */
275 PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW);
276 PyFile_WriteString(lineno_str, f_stderr);
277 PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW);
278 PyFile_WriteString(": ", f_stderr);
279 PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW);
280 PyFile_WriteString("\n", f_stderr);
281 Py_XDECREF(name);
282
283 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000284 if (sourceline) {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000285 char *source_line_str = _PyUnicode_AsString(sourceline);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 if (source_line_str == NULL)
287 return;
Christian Heimes33fe8092008-04-13 13:53:33 +0000288 while (*source_line_str == ' ' || *source_line_str == '\t' ||
289 *source_line_str == '\014')
290 source_line_str++;
291
292 PyFile_WriteString(source_line_str, f_stderr);
293 PyFile_WriteString("\n", f_stderr);
294 }
295 else
Victor Stinner0fe25a42010-06-17 23:08:50 +0000296 if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 return;
Christian Heimes33fe8092008-04-13 13:53:33 +0000298 PyErr_Clear();
299}
300
301static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000303 PyObject *filename, int lineno,
304 PyObject *module, PyObject *registry, PyObject *sourceline)
305{
306 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400307 PyObject *item = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000308 const char *action;
309 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310
Brett Cannondb734912008-06-27 00:52:15 +0000311 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
312 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
313 return NULL;
314 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000315
316 /* Normalize module. */
317 if (module == NULL) {
318 module = normalize_module(filename);
319 if (module == NULL)
320 return NULL;
321 }
322 else
323 Py_INCREF(module);
324
325 /* Normalize message. */
326 Py_INCREF(message); /* DECREF'ed in cleanup. */
327 rc = PyObject_IsInstance(message, PyExc_Warning);
328 if (rc == -1) {
329 goto cleanup;
330 }
331 if (rc == 1) {
332 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000333 if (text == NULL)
334 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000335 category = (PyObject*)message->ob_type;
336 }
337 else {
338 text = message;
339 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000340 if (message == NULL)
341 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000342 }
343
344 lineno_obj = PyLong_FromLong(lineno);
345 if (lineno_obj == NULL)
346 goto cleanup;
347
348 /* Create key. */
349 key = PyTuple_Pack(3, text, category, lineno_obj);
350 if (key == NULL)
351 goto cleanup;
352
Brett Cannondb734912008-06-27 00:52:15 +0000353 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000354 rc = already_warned(registry, key, 0);
355 if (rc == -1)
356 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000358 goto return_none;
359 /* Else this warning hasn't been generated before. */
360 }
361
362 action = get_filter(category, text, lineno, module, &item);
363 if (action == NULL)
364 goto cleanup;
365
366 if (strcmp(action, "error") == 0) {
367 PyErr_SetObject(category, message);
368 goto cleanup;
369 }
370
371 /* Store in the registry that we've been here, *except* when the action
372 is "always". */
373 rc = 0;
374 if (strcmp(action, "always") != 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000375 if (registry != NULL && registry != Py_None &&
376 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000377 goto cleanup;
378 else if (strcmp(action, "ignore") == 0)
379 goto return_none;
380 else if (strcmp(action, "once") == 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000381 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000382 registry = get_once_registry();
383 if (registry == NULL)
384 goto cleanup;
385 }
386 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000388 }
389 else if (strcmp(action, "module") == 0) {
390 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000391 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000393 }
394 else if (strcmp(action, "default") != 0) {
395 PyObject *to_str = PyObject_Str(item);
396 const char *err_str = "???";
397
Brett Cannon54bd41d2008-09-02 04:01:42 +0000398 if (to_str != NULL) {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000399 err_str = _PyUnicode_AsString(to_str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 if (err_str == NULL)
401 goto cleanup;
402 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000403 PyErr_Format(PyExc_RuntimeError,
404 "Unrecognized action (%s) in warnings.filters:\n %s",
405 action, err_str);
406 Py_XDECREF(to_str);
407 goto cleanup;
408 }
409 }
410
Christian Heimes1a8501c2008-10-02 19:56:01 +0000411 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000412 goto return_none;
413 if (rc == 0) {
414 PyObject *show_fxn = get_warnings_attr("showwarning");
415 if (show_fxn == NULL) {
416 if (PyErr_Occurred())
417 goto cleanup;
418 show_warning(filename, lineno, text, category, sourceline);
419 }
420 else {
Brett Cannonec92e182008-09-02 02:46:59 +0000421 PyObject *res;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000422
Brett Cannon52a7d982011-07-17 19:17:55 -0700423 if (!PyCallable_Check(show_fxn)) {
Brett Cannonec92e182008-09-02 02:46:59 +0000424 PyErr_SetString(PyExc_TypeError,
425 "warnings.showwarning() must be set to a "
Brett Cannon52a7d982011-07-17 19:17:55 -0700426 "callable");
Christian Heimes8dc226f2008-05-06 23:45:46 +0000427 Py_DECREF(show_fxn);
Brett Cannonec92e182008-09-02 02:46:59 +0000428 goto cleanup;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000429 }
Brett Cannonec92e182008-09-02 02:46:59 +0000430
431 res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
432 filename, lineno_obj,
433 NULL);
434 Py_DECREF(show_fxn);
435 Py_XDECREF(res);
436 if (res == NULL)
437 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000438 }
439 }
440 else /* if (rc == -1) */
441 goto cleanup;
442
443 return_none:
444 result = Py_None;
445 Py_INCREF(result);
446
447 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400448 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000449 Py_XDECREF(key);
450 Py_XDECREF(text);
451 Py_XDECREF(lineno_obj);
452 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000453 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000454 return result; /* Py_None or NULL. */
455}
456
457/* filename, module, and registry are new refs, globals is borrowed */
458/* Returns 0 on error (no new refs), 1 on success */
459static int
460setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
461 PyObject **module, PyObject **registry)
462{
463 PyObject *globals;
464
465 /* Setup globals and lineno. */
466 PyFrameObject *f = PyThreadState_GET()->frame;
Christian Heimes5d8da202008-05-06 13:58:24 +0000467 while (--stack_level > 0 && f != NULL)
Christian Heimes33fe8092008-04-13 13:53:33 +0000468 f = f->f_back;
Christian Heimes33fe8092008-04-13 13:53:33 +0000469
470 if (f == NULL) {
471 globals = PyThreadState_Get()->interp->sysdict;
472 *lineno = 1;
473 }
474 else {
475 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000476 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000477 }
478
479 *module = NULL;
480
481 /* Setup registry. */
482 assert(globals != NULL);
483 assert(PyDict_Check(globals));
484 *registry = PyDict_GetItemString(globals, "__warningregistry__");
485 if (*registry == NULL) {
486 int rc;
487
488 *registry = PyDict_New();
489 if (*registry == NULL)
490 return 0;
491
492 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
493 if (rc < 0)
494 goto handle_error;
495 }
496 else
497 Py_INCREF(*registry);
498
499 /* Setup module. */
500 *module = PyDict_GetItemString(globals, "__name__");
501 if (*module == NULL) {
502 *module = PyUnicode_FromString("<string>");
503 if (*module == NULL)
504 goto handle_error;
505 }
506 else
507 Py_INCREF(*module);
508
509 /* Setup filename. */
510 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200511 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200512 Py_ssize_t len;
513 int kind;
514 void *data;
515
516 if (PyUnicode_READY(*filename))
517 goto handle_error;
518
Victor Stinner9e30aa52011-11-21 02:49:52 +0100519 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200520 kind = PyUnicode_KIND(*filename);
521 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000522
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500523#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000524 /* if filename.lower().endswith((".pyc", ".pyo")): */
525 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200526 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500527 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
528 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
529 (ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c' ||
530 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'o'))
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000531 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200532 *filename = PyUnicode_Substring(*filename, 0,
533 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000534 if (*filename == NULL)
535 goto handle_error;
536 }
537 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000538 Py_INCREF(*filename);
539 }
540 else {
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000541 const char *module_str = _PyUnicode_AsString(*module);
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500542 *filename = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 if (module_str == NULL)
544 goto handle_error;
Brett Cannon54bd41d2008-09-02 04:01:42 +0000545 if (strcmp(module_str, "__main__") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000546 PyObject *argv = PySys_GetObject("argv");
547 if (argv != NULL && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000548 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000549 *filename = PyList_GetItem(argv, 0);
550 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000551 /* If sys.argv[0] is false, then use '__main__'. */
552 is_true = PyObject_IsTrue(*filename);
553 if (is_true < 0) {
554 Py_DECREF(*filename);
555 goto handle_error;
556 }
557 else if (!is_true) {
558 Py_DECREF(*filename);
Benjamin Peterson9f4bf1d2008-05-04 23:22:13 +0000559 *filename = PyUnicode_FromString("__main__");
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000560 if (*filename == NULL)
561 goto handle_error;
562 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000563 }
564 else {
565 /* embedded interpreters don't have sys.argv, see bug #839151 */
566 *filename = PyUnicode_FromString("__main__");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 if (*filename == NULL)
568 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000569 }
570 }
571 if (*filename == NULL) {
572 *filename = *module;
573 Py_INCREF(*filename);
574 }
575 }
576
577 return 1;
578
579 handle_error:
580 /* filename not XDECREF'ed here as there is no way to jump here with a
581 dangling reference. */
582 Py_XDECREF(*registry);
583 Py_XDECREF(*module);
584 return 0;
585}
586
587static PyObject *
588get_category(PyObject *message, PyObject *category)
589{
590 int rc;
591
592 /* Get category. */
593 rc = PyObject_IsInstance(message, PyExc_Warning);
594 if (rc == -1)
595 return NULL;
596
597 if (rc == 1)
598 category = (PyObject*)message->ob_type;
599 else if (category == NULL)
600 category = PyExc_UserWarning;
601
602 /* Validate category. */
603 rc = PyObject_IsSubclass(category, PyExc_Warning);
604 if (rc == -1)
605 return NULL;
606 if (rc == 0) {
607 PyErr_SetString(PyExc_ValueError,
608 "category is not a subclass of Warning");
609 return NULL;
610 }
611
612 return category;
613}
614
615static PyObject *
616do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
617{
618 PyObject *filename, *module, *registry, *res;
619 int lineno;
620
621 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
622 return NULL;
623
624 res = warn_explicit(category, message, filename, lineno, module, registry,
625 NULL);
626 Py_DECREF(filename);
627 Py_DECREF(registry);
628 Py_DECREF(module);
629 return res;
630}
631
632static PyObject *
633warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
634{
635 static char *kw_list[] = { "message", "category", "stacklevel", 0 };
636 PyObject *message, *category = NULL;
637 Py_ssize_t stack_level = 1;
638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
Christian Heimes33fe8092008-04-13 13:53:33 +0000640 &message, &category, &stack_level))
641 return NULL;
642
643 category = get_category(message, category);
644 if (category == NULL)
645 return NULL;
646 return do_warn(message, category, stack_level);
647}
648
649static PyObject *
650warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
651{
652 static char *kwd_list[] = {"message", "category", "filename", "lineno",
653 "module", "registry", "module_globals", 0};
654 PyObject *message;
655 PyObject *category;
656 PyObject *filename;
657 int lineno;
658 PyObject *module = NULL;
659 PyObject *registry = NULL;
660 PyObject *module_globals = NULL;
661
662 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit",
663 kwd_list, &message, &category, &filename, &lineno, &module,
664 &registry, &module_globals))
665 return NULL;
666
667 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200668 _Py_IDENTIFIER(get_source);
669 _Py_IDENTIFIER(splitlines);
670 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000671 PyObject *loader;
672 PyObject *module_name;
673 PyObject *source;
674 PyObject *source_list;
675 PyObject *source_line;
676 PyObject *returned;
677
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200678 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
679 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200680 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
681 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000682
683 /* Check/get the requisite pieces needed for the loader. */
684 loader = PyDict_GetItemString(module_globals, "__loader__");
685 module_name = PyDict_GetItemString(module_globals, "__name__");
686
687 if (loader == NULL || module_name == NULL)
688 goto standard_call;
689
690 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200691 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000692 goto standard_call;
693 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200694 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
695 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000696 if (!source)
697 return NULL;
698 else if (source == Py_None) {
699 Py_DECREF(Py_None);
700 goto standard_call;
701 }
702
703 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100704 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200705 PyId_splitlines.object,
706 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000707 Py_DECREF(source);
708 if (!source_list)
709 return NULL;
710
711 /* Get the source line. */
712 source_line = PyList_GetItem(source_list, lineno-1);
713 if (!source_line) {
714 Py_DECREF(source_list);
715 return NULL;
716 }
717
718 /* Handle the warning. */
719 returned = warn_explicit(category, message, filename, lineno, module,
720 registry, source_line);
721 Py_DECREF(source_list);
722 return returned;
723 }
724
725 standard_call:
726 return warn_explicit(category, message, filename, lineno, module,
727 registry, NULL);
728}
729
730
731/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000732
733static int
734warn_unicode(PyObject *category, PyObject *message,
735 Py_ssize_t stack_level)
Christian Heimes33fe8092008-04-13 13:53:33 +0000736{
737 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000738
739 if (category == NULL)
740 category = PyExc_RuntimeWarning;
741
742 res = do_warn(message, category, stack_level);
Christian Heimes33fe8092008-04-13 13:53:33 +0000743 if (res == NULL)
744 return -1;
745 Py_DECREF(res);
746
747 return 0;
748}
749
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000750int
751PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
752 const char *format, ...)
753{
754 int ret;
755 PyObject *message;
756 va_list vargs;
757
758#ifdef HAVE_STDARG_PROTOTYPES
759 va_start(vargs, format);
760#else
761 va_start(vargs);
762#endif
763 message = PyUnicode_FromFormatV(format, vargs);
764 if (message != NULL) {
765 ret = warn_unicode(category, message, stack_level);
766 Py_DECREF(message);
767 }
768 else
769 ret = -1;
770 va_end(vargs);
771 return ret;
772}
773
774int
775PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
776{
777 int ret;
778 PyObject *message = PyUnicode_FromString(text);
779 if (message == NULL)
780 return -1;
781 ret = warn_unicode(category, message, stack_level);
782 Py_DECREF(message);
783 return ret;
784}
785
Ezio Melotti42da6632011-03-15 05:18:48 +0200786/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +0000787 Use PyErr_WarnEx instead. */
788
789#undef PyErr_Warn
790
791PyAPI_FUNC(int)
792PyErr_Warn(PyObject *category, char *text)
793{
794 return PyErr_WarnEx(category, text, 1);
795}
796
797/* Warning with explicit origin */
798int
799PyErr_WarnExplicit(PyObject *category, const char *text,
800 const char *filename_str, int lineno,
801 const char *module_str, PyObject *registry)
802{
803 PyObject *res;
804 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +0000805 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +0000806 PyObject *module = NULL;
807 int ret = -1;
808
809 if (message == NULL || filename == NULL)
810 goto exit;
811 if (module_str != NULL) {
812 module = PyUnicode_FromString(module_str);
813 if (module == NULL)
814 goto exit;
815 }
816
817 if (category == NULL)
818 category = PyExc_RuntimeWarning;
819 res = warn_explicit(category, message, filename, lineno, module, registry,
820 NULL);
821 if (res == NULL)
822 goto exit;
823 Py_DECREF(res);
824 ret = 0;
825
826 exit:
827 Py_XDECREF(message);
828 Py_XDECREF(module);
829 Py_XDECREF(filename);
830 return ret;
831}
832
833
834PyDoc_STRVAR(warn_doc,
835"Issue a warning, or maybe ignore it or raise an exception.");
836
837PyDoc_STRVAR(warn_explicit_doc,
838"Low-level inferface to warnings functionality.");
839
840static PyMethodDef warnings_functions[] = {
841 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
842 warn_doc},
843 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
844 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Christian Heimes1a8501c2008-10-02 19:56:01 +0000845 /* XXX(brett.cannon): add showwarning? */
846 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +0000848};
849
850
851static PyObject *
852create_filter(PyObject *category, const char *action)
853{
854 static PyObject *ignore_str = NULL;
855 static PyObject *error_str = NULL;
856 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +0000857 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000858 PyObject *action_obj = NULL;
859 PyObject *lineno, *result;
860
861 if (!strcmp(action, "ignore")) {
862 if (ignore_str == NULL) {
863 ignore_str = PyUnicode_InternFromString("ignore");
864 if (ignore_str == NULL)
865 return NULL;
866 }
867 action_obj = ignore_str;
868 }
869 else if (!strcmp(action, "error")) {
870 if (error_str == NULL) {
871 error_str = PyUnicode_InternFromString("error");
872 if (error_str == NULL)
873 return NULL;
874 }
875 action_obj = error_str;
876 }
877 else if (!strcmp(action, "default")) {
878 if (default_str == NULL) {
879 default_str = PyUnicode_InternFromString("default");
880 if (default_str == NULL)
881 return NULL;
882 }
883 action_obj = default_str;
884 }
Georg Brandl08be72d2010-10-24 15:11:22 +0000885 else if (!strcmp(action, "always")) {
886 if (always_str == NULL) {
887 always_str = PyUnicode_InternFromString("always");
888 if (always_str == NULL)
889 return NULL;
890 }
891 action_obj = always_str;
892 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000893 else {
894 Py_FatalError("unknown action");
895 }
896
897 /* This assumes the line number is zero for now. */
898 lineno = PyLong_FromLong(0);
899 if (lineno == NULL)
900 return NULL;
901 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
902 Py_DECREF(lineno);
903 return result;
904}
905
906static PyObject *
907init_filters(void)
908{
Georg Brandl08be72d2010-10-24 15:11:22 +0000909 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000910 unsigned int pos = 0; /* Post-incremented in each use. */
911 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +0000912 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000913
Christian Heimes33fe8092008-04-13 13:53:33 +0000914 if (filters == NULL)
915 return NULL;
916
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000917 PyList_SET_ITEM(filters, pos++,
918 create_filter(PyExc_DeprecationWarning, "ignore"));
919 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +0000920 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000921 PyList_SET_ITEM(filters, pos++,
922 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +0000923 if (Py_BytesWarningFlag > 1)
924 bytes_action = "error";
925 else if (Py_BytesWarningFlag)
926 bytes_action = "default";
927 else
928 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000929 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +0000930 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +0000931 /* resource usage warnings are enabled by default in pydebug mode */
932#ifdef Py_DEBUG
933 resource_action = "always";
934#else
935 resource_action = "ignore";
936#endif
937 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
938 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000939 for (x = 0; x < pos; x += 1) {
940 if (PyList_GET_ITEM(filters, x) == NULL) {
941 Py_DECREF(filters);
942 return NULL;
943 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000944 }
945
946 return filters;
947}
948
Martin v. Löwis1a214512008-06-11 05:26:20 +0000949static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 PyModuleDef_HEAD_INIT,
951 MODULE_NAME,
952 warnings__doc__,
953 0,
954 warnings_functions,
955 NULL,
956 NULL,
957 NULL,
958 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000959};
960
Christian Heimes33fe8092008-04-13 13:53:33 +0000961
962PyMODINIT_FUNC
963_PyWarnings_Init(void)
964{
Brett Cannon0759dd62009-04-01 18:13:07 +0000965 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +0000966
Martin v. Löwis1a214512008-06-11 05:26:20 +0000967 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +0000968 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000969 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000970
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +0100971 if (_filters == NULL) {
972 _filters = init_filters();
973 if (_filters == NULL)
974 return NULL;
975 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000976 Py_INCREF(_filters);
977 if (PyModule_AddObject(m, "filters", _filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000978 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000979
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +0100980 if (_once_registry == NULL) {
981 _once_registry = PyDict_New();
982 if (_once_registry == NULL)
983 return NULL;
984 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000985 Py_INCREF(_once_registry);
Brett Cannonef0e6c32010-09-04 18:24:04 +0000986 if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000987 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000988
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +0100989 if (_default_action == NULL) {
990 _default_action = PyUnicode_FromString("default");
991 if (_default_action == NULL)
992 return NULL;
993 }
994 Py_INCREF(_default_action);
Brett Cannonef0e6c32010-09-04 18:24:04 +0000995 if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000996 return NULL;
997 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +0000998}