blob: d9f3297dd3d1246f1f70721f1257e67e6024ef09 [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
Christian Heimes33fe8092008-04-13 13:53:33 +0000101/* The item is a borrowed reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100102static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000103get_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
132 tmp_item = *item = PyList_GET_ITEM(_filters, i);
133 if (PyTuple_Size(tmp_item) != 5) {
134 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 */
140 action = PyTuple_GET_ITEM(tmp_item, 0);
141 msg = PyTuple_GET_ITEM(tmp_item, 1);
142 cat = PyTuple_GET_ITEM(tmp_item, 2);
143 mod = PyTuple_GET_ITEM(tmp_item, 3);
144 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
145
146 good_msg = check_matched(msg, text);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100147 if (good_msg == -1)
148 return NULL;
149
Christian Heimes33fe8092008-04-13 13:53:33 +0000150 good_mod = check_matched(mod, module);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100151 if (good_mod == -1)
152 return NULL;
153
Christian Heimes33fe8092008-04-13 13:53:33 +0000154 is_subclass = PyObject_IsSubclass(category, cat);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100155 if (is_subclass == -1)
156 return NULL;
157
Christian Heimes33fe8092008-04-13 13:53:33 +0000158 ln = PyLong_AsSsize_t(ln_obj);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100159 if (ln == -1 && PyErr_Occurred())
Christian Heimes33fe8092008-04-13 13:53:33 +0000160 return NULL;
161
162 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
Victor Stinnera4c704b2013-10-29 23:43:41 +0100163 return action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000164 }
165
Brett Cannon0759dd62009-04-01 18:13:07 +0000166 action = get_default_action();
Victor Stinnera4c704b2013-10-29 23:43:41 +0100167 if (action != NULL)
168 return action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000169
170 PyErr_SetString(PyExc_ValueError,
Brett Cannon0759dd62009-04-01 18:13:07 +0000171 MODULE_NAME ".defaultaction not found");
Christian Heimes33fe8092008-04-13 13:53:33 +0000172 return NULL;
173}
174
Brett Cannon0759dd62009-04-01 18:13:07 +0000175
Christian Heimes33fe8092008-04-13 13:53:33 +0000176static int
177already_warned(PyObject *registry, PyObject *key, int should_set)
178{
179 PyObject *already_warned;
180
181 if (key == NULL)
182 return -1;
183
184 already_warned = PyDict_GetItem(registry, key);
185 if (already_warned != NULL) {
186 int rc = PyObject_IsTrue(already_warned);
187 if (rc != 0)
188 return rc;
189 }
190
191 /* This warning wasn't found in the registry, set it. */
192 if (should_set)
193 return PyDict_SetItem(registry, key, Py_True);
194 return 0;
195}
196
197/* New reference. */
198static PyObject *
199normalize_module(PyObject *filename)
200{
201 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100202 int kind;
203 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000204 Py_ssize_t len;
205
Victor Stinner9e30aa52011-11-21 02:49:52 +0100206 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000207 if (len < 0)
208 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100209
210 if (len == 0)
211 return PyUnicode_FromString("<unknown>");
212
213 kind = PyUnicode_KIND(filename);
214 data = PyUnicode_DATA(filename);
215
216 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000217 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100218 PyUnicode_READ(kind, data, len-3) == '.' &&
219 PyUnicode_READ(kind, data, len-2) == 'p' &&
220 PyUnicode_READ(kind, data, len-1) == 'y')
221 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100222 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000223 }
224 else {
225 module = filename;
226 Py_INCREF(module);
227 }
228 return module;
229}
230
231static int
232update_registry(PyObject *registry, PyObject *text, PyObject *category,
233 int add_zero)
234{
235 PyObject *altkey, *zero = NULL;
236 int rc;
237
238 if (add_zero) {
239 zero = PyLong_FromLong(0);
240 if (zero == NULL)
241 return -1;
242 altkey = PyTuple_Pack(3, text, category, zero);
243 }
244 else
245 altkey = PyTuple_Pack(2, text, category);
246
247 rc = already_warned(registry, altkey, 1);
248 Py_XDECREF(zero);
249 Py_XDECREF(altkey);
250 return rc;
251}
252
253static void
254show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
255 *category, PyObject *sourceline)
256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 PyObject *f_stderr;
258 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000259 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200260 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000261
262 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
263
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200264 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000265 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100266 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000267
268 f_stderr = PySys_GetObject("stderr");
269 if (f_stderr == NULL) {
270 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100271 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000272 }
273
274 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100275 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
276 goto error;
277 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
278 goto error;
279 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
280 goto error;
281 if (PyFile_WriteString(": ", f_stderr) < 0)
282 goto error;
283 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
284 goto error;
285 if (PyFile_WriteString("\n", f_stderr) < 0)
286 goto error;
287 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000288
289 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000290 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100291 int kind;
292 void *data;
293 Py_ssize_t i, len;
294 Py_UCS4 ch;
295 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000296
Victor Stinnera4c704b2013-10-29 23:43:41 +0100297 if (PyUnicode_READY(sourceline) < 1)
298 goto error;
299
300 kind = PyUnicode_KIND(sourceline);
301 data = PyUnicode_DATA(sourceline);
302 len = PyUnicode_GET_LENGTH(sourceline);
303 for (i=0; i<len; i++) {
304 ch = PyUnicode_READ(kind, data, i);
305 if (ch != ' ' && ch != '\t' && ch != '\014')
306 break;
307 }
308
309 truncated = PyUnicode_Substring(sourceline, i, len);
310 if (truncated == NULL)
311 goto error;
312
313 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
314 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000315 PyFile_WriteString("\n", f_stderr);
316 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200317 else {
318 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
319 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100320
321error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100322 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000323 PyErr_Clear();
324}
325
326static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000328 PyObject *filename, int lineno,
329 PyObject *module, PyObject *registry, PyObject *sourceline)
330{
331 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
332 PyObject *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100333 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000334 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335
Brett Cannondb734912008-06-27 00:52:15 +0000336 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
337 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
338 return NULL;
339 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000340
341 /* Normalize module. */
342 if (module == NULL) {
343 module = normalize_module(filename);
344 if (module == NULL)
345 return NULL;
346 }
347 else
348 Py_INCREF(module);
349
350 /* Normalize message. */
351 Py_INCREF(message); /* DECREF'ed in cleanup. */
352 rc = PyObject_IsInstance(message, PyExc_Warning);
353 if (rc == -1) {
354 goto cleanup;
355 }
356 if (rc == 1) {
357 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000358 if (text == NULL)
359 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000360 category = (PyObject*)message->ob_type;
361 }
362 else {
363 text = message;
364 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000365 if (message == NULL)
366 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000367 }
368
369 lineno_obj = PyLong_FromLong(lineno);
370 if (lineno_obj == NULL)
371 goto cleanup;
372
373 /* Create key. */
374 key = PyTuple_Pack(3, text, category, lineno_obj);
375 if (key == NULL)
376 goto cleanup;
377
Brett Cannondb734912008-06-27 00:52:15 +0000378 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000379 rc = already_warned(registry, key, 0);
380 if (rc == -1)
381 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000383 goto return_none;
384 /* Else this warning hasn't been generated before. */
385 }
386
387 action = get_filter(category, text, lineno, module, &item);
388 if (action == NULL)
389 goto cleanup;
390
Victor Stinnera4c704b2013-10-29 23:43:41 +0100391 if (PyUnicode_CompareWithASCIIString(action, "error") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000392 PyErr_SetObject(category, message);
393 goto cleanup;
394 }
395
396 /* Store in the registry that we've been here, *except* when the action
397 is "always". */
398 rc = 0;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100399 if (PyUnicode_CompareWithASCIIString(action, "always") != 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000400 if (registry != NULL && registry != Py_None &&
401 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000402 goto cleanup;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100403 else if (PyUnicode_CompareWithASCIIString(action, "ignore") == 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000404 goto return_none;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100405 else if (PyUnicode_CompareWithASCIIString(action, "once") == 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000406 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000407 registry = get_once_registry();
408 if (registry == NULL)
409 goto cleanup;
410 }
411 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000413 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100414 else if (PyUnicode_CompareWithASCIIString(action, "module") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000415 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000416 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000418 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100419 else if (PyUnicode_CompareWithASCIIString(action, "default") != 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000420 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100421 "Unrecognized action (%R) in warnings.filters:\n %R",
422 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000423 goto cleanup;
424 }
425 }
426
Christian Heimes1a8501c2008-10-02 19:56:01 +0000427 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000428 goto return_none;
429 if (rc == 0) {
430 PyObject *show_fxn = get_warnings_attr("showwarning");
431 if (show_fxn == NULL) {
432 if (PyErr_Occurred())
433 goto cleanup;
434 show_warning(filename, lineno, text, category, sourceline);
435 }
436 else {
Brett Cannonec92e182008-09-02 02:46:59 +0000437 PyObject *res;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000438
Brett Cannon52a7d982011-07-17 19:17:55 -0700439 if (!PyCallable_Check(show_fxn)) {
Brett Cannonec92e182008-09-02 02:46:59 +0000440 PyErr_SetString(PyExc_TypeError,
441 "warnings.showwarning() must be set to a "
Brett Cannon52a7d982011-07-17 19:17:55 -0700442 "callable");
Christian Heimes8dc226f2008-05-06 23:45:46 +0000443 Py_DECREF(show_fxn);
Brett Cannonec92e182008-09-02 02:46:59 +0000444 goto cleanup;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000445 }
Brett Cannonec92e182008-09-02 02:46:59 +0000446
447 res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
448 filename, lineno_obj,
449 NULL);
450 Py_DECREF(show_fxn);
451 Py_XDECREF(res);
452 if (res == NULL)
453 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000454 }
455 }
456 else /* if (rc == -1) */
457 goto cleanup;
458
459 return_none:
460 result = Py_None;
461 Py_INCREF(result);
462
463 cleanup:
464 Py_XDECREF(key);
465 Py_XDECREF(text);
466 Py_XDECREF(lineno_obj);
467 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000468 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000469 return result; /* Py_None or NULL. */
470}
471
472/* filename, module, and registry are new refs, globals is borrowed */
473/* Returns 0 on error (no new refs), 1 on success */
474static int
475setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
476 PyObject **module, PyObject **registry)
477{
478 PyObject *globals;
479
480 /* Setup globals and lineno. */
481 PyFrameObject *f = PyThreadState_GET()->frame;
Christian Heimes5d8da202008-05-06 13:58:24 +0000482 while (--stack_level > 0 && f != NULL)
Christian Heimes33fe8092008-04-13 13:53:33 +0000483 f = f->f_back;
Christian Heimes33fe8092008-04-13 13:53:33 +0000484
485 if (f == NULL) {
486 globals = PyThreadState_Get()->interp->sysdict;
487 *lineno = 1;
488 }
489 else {
490 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000491 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000492 }
493
494 *module = NULL;
495
496 /* Setup registry. */
497 assert(globals != NULL);
498 assert(PyDict_Check(globals));
499 *registry = PyDict_GetItemString(globals, "__warningregistry__");
500 if (*registry == NULL) {
501 int rc;
502
503 *registry = PyDict_New();
504 if (*registry == NULL)
505 return 0;
506
507 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
508 if (rc < 0)
509 goto handle_error;
510 }
511 else
512 Py_INCREF(*registry);
513
514 /* Setup module. */
515 *module = PyDict_GetItemString(globals, "__name__");
516 if (*module == NULL) {
517 *module = PyUnicode_FromString("<string>");
518 if (*module == NULL)
519 goto handle_error;
520 }
521 else
522 Py_INCREF(*module);
523
524 /* Setup filename. */
525 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200526 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200527 Py_ssize_t len;
528 int kind;
529 void *data;
530
531 if (PyUnicode_READY(*filename))
532 goto handle_error;
533
Victor Stinner9e30aa52011-11-21 02:49:52 +0100534 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200535 kind = PyUnicode_KIND(*filename);
536 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000537
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500538#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000539 /* if filename.lower().endswith((".pyc", ".pyo")): */
540 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200541 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500542 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
543 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
544 (ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c' ||
545 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'o'))
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000546 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200547 *filename = PyUnicode_Substring(*filename, 0,
548 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000549 if (*filename == NULL)
550 goto handle_error;
551 }
552 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000553 Py_INCREF(*filename);
554 }
555 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500556 *filename = NULL;
Victor Stinner856f45f2013-10-30 00:04:59 +0100557 if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000558 PyObject *argv = PySys_GetObject("argv");
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100559 /* PyList_Check() is needed because sys.argv is set to None during
560 Python finalization */
561 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000562 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000563 *filename = PyList_GetItem(argv, 0);
564 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000565 /* If sys.argv[0] is false, then use '__main__'. */
566 is_true = PyObject_IsTrue(*filename);
567 if (is_true < 0) {
568 Py_DECREF(*filename);
569 goto handle_error;
570 }
571 else if (!is_true) {
572 Py_DECREF(*filename);
Benjamin Peterson9f4bf1d2008-05-04 23:22:13 +0000573 *filename = PyUnicode_FromString("__main__");
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000574 if (*filename == NULL)
575 goto handle_error;
576 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000577 }
578 else {
579 /* embedded interpreters don't have sys.argv, see bug #839151 */
580 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100581 if (*filename == NULL)
582 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000583 }
584 }
585 if (*filename == NULL) {
586 *filename = *module;
587 Py_INCREF(*filename);
588 }
589 }
590
591 return 1;
592
593 handle_error:
594 /* filename not XDECREF'ed here as there is no way to jump here with a
595 dangling reference. */
596 Py_XDECREF(*registry);
597 Py_XDECREF(*module);
598 return 0;
599}
600
601static PyObject *
602get_category(PyObject *message, PyObject *category)
603{
604 int rc;
605
606 /* Get category. */
607 rc = PyObject_IsInstance(message, PyExc_Warning);
608 if (rc == -1)
609 return NULL;
610
611 if (rc == 1)
612 category = (PyObject*)message->ob_type;
613 else if (category == NULL)
614 category = PyExc_UserWarning;
615
616 /* Validate category. */
617 rc = PyObject_IsSubclass(category, PyExc_Warning);
618 if (rc == -1)
619 return NULL;
620 if (rc == 0) {
621 PyErr_SetString(PyExc_ValueError,
622 "category is not a subclass of Warning");
623 return NULL;
624 }
625
626 return category;
627}
628
629static PyObject *
630do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
631{
632 PyObject *filename, *module, *registry, *res;
633 int lineno;
634
635 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
636 return NULL;
637
Victor Stinner856f45f2013-10-30 00:04:59 +0100638 if (module != Py_None) {
639 res = warn_explicit(category, message, filename, lineno, module, registry,
640 NULL);
641 }
642 else {
643 /* FIXME: emitting warnings at exit does crash Python */
644 res = Py_None;
645 Py_INCREF(res);
646 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000647 Py_DECREF(filename);
648 Py_DECREF(registry);
649 Py_DECREF(module);
650 return res;
651}
652
653static PyObject *
654warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
655{
656 static char *kw_list[] = { "message", "category", "stacklevel", 0 };
657 PyObject *message, *category = NULL;
658 Py_ssize_t stack_level = 1;
659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
Christian Heimes33fe8092008-04-13 13:53:33 +0000661 &message, &category, &stack_level))
662 return NULL;
663
664 category = get_category(message, category);
665 if (category == NULL)
666 return NULL;
667 return do_warn(message, category, stack_level);
668}
669
670static PyObject *
671warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
672{
673 static char *kwd_list[] = {"message", "category", "filename", "lineno",
674 "module", "registry", "module_globals", 0};
675 PyObject *message;
676 PyObject *category;
677 PyObject *filename;
678 int lineno;
679 PyObject *module = NULL;
680 PyObject *registry = NULL;
681 PyObject *module_globals = NULL;
682
Victor Stinnera4c704b2013-10-29 23:43:41 +0100683 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000684 kwd_list, &message, &category, &filename, &lineno, &module,
685 &registry, &module_globals))
686 return NULL;
687
688 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200689 _Py_IDENTIFIER(get_source);
690 _Py_IDENTIFIER(splitlines);
691 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000692 PyObject *loader;
693 PyObject *module_name;
694 PyObject *source;
695 PyObject *source_list;
696 PyObject *source_line;
697 PyObject *returned;
698
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200699 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
700 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200701 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
702 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000703
704 /* Check/get the requisite pieces needed for the loader. */
705 loader = PyDict_GetItemString(module_globals, "__loader__");
706 module_name = PyDict_GetItemString(module_globals, "__name__");
707
708 if (loader == NULL || module_name == NULL)
709 goto standard_call;
710
711 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200712 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000713 goto standard_call;
714 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200715 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
716 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000717 if (!source)
718 return NULL;
719 else if (source == Py_None) {
720 Py_DECREF(Py_None);
721 goto standard_call;
722 }
723
724 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100725 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200726 PyId_splitlines.object,
727 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000728 Py_DECREF(source);
729 if (!source_list)
730 return NULL;
731
732 /* Get the source line. */
733 source_line = PyList_GetItem(source_list, lineno-1);
734 if (!source_line) {
735 Py_DECREF(source_list);
736 return NULL;
737 }
738
739 /* Handle the warning. */
740 returned = warn_explicit(category, message, filename, lineno, module,
Victor Stinner14e461d2013-08-26 22:28:21 +0200741 registry, source_line);
Christian Heimes33fe8092008-04-13 13:53:33 +0000742 Py_DECREF(source_list);
743 return returned;
744 }
745
746 standard_call:
747 return warn_explicit(category, message, filename, lineno, module,
Victor Stinner14e461d2013-08-26 22:28:21 +0200748 registry, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000749}
750
751
752/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000753
754static int
755warn_unicode(PyObject *category, PyObject *message,
756 Py_ssize_t stack_level)
Christian Heimes33fe8092008-04-13 13:53:33 +0000757{
758 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000759
760 if (category == NULL)
761 category = PyExc_RuntimeWarning;
762
763 res = do_warn(message, category, stack_level);
Christian Heimes33fe8092008-04-13 13:53:33 +0000764 if (res == NULL)
765 return -1;
766 Py_DECREF(res);
767
768 return 0;
769}
770
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000771int
772PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
773 const char *format, ...)
774{
775 int ret;
776 PyObject *message;
777 va_list vargs;
778
779#ifdef HAVE_STDARG_PROTOTYPES
780 va_start(vargs, format);
781#else
782 va_start(vargs);
783#endif
784 message = PyUnicode_FromFormatV(format, vargs);
785 if (message != NULL) {
786 ret = warn_unicode(category, message, stack_level);
787 Py_DECREF(message);
788 }
789 else
790 ret = -1;
791 va_end(vargs);
792 return ret;
793}
794
795int
796PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
797{
798 int ret;
799 PyObject *message = PyUnicode_FromString(text);
800 if (message == NULL)
801 return -1;
802 ret = warn_unicode(category, message, stack_level);
803 Py_DECREF(message);
804 return ret;
805}
806
Ezio Melotti42da6632011-03-15 05:18:48 +0200807/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +0000808 Use PyErr_WarnEx instead. */
809
810#undef PyErr_Warn
811
812PyAPI_FUNC(int)
813PyErr_Warn(PyObject *category, char *text)
814{
815 return PyErr_WarnEx(category, text, 1);
816}
817
818/* Warning with explicit origin */
819int
Victor Stinner14e461d2013-08-26 22:28:21 +0200820PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
821 PyObject *filename, int lineno,
822 PyObject *module, PyObject *registry)
823{
824 PyObject *res;
825 if (category == NULL)
826 category = PyExc_RuntimeWarning;
827 res = warn_explicit(category, message, filename, lineno,
828 module, registry, NULL);
829 if (res == NULL)
830 return -1;
831 Py_DECREF(res);
832 return 0;
833}
834
835int
Christian Heimes33fe8092008-04-13 13:53:33 +0000836PyErr_WarnExplicit(PyObject *category, const char *text,
837 const char *filename_str, int lineno,
838 const char *module_str, PyObject *registry)
839{
Christian Heimes33fe8092008-04-13 13:53:33 +0000840 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +0000841 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +0000842 PyObject *module = NULL;
843 int ret = -1;
844
845 if (message == NULL || filename == NULL)
846 goto exit;
847 if (module_str != NULL) {
848 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +0200849 if (module == NULL)
850 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +0000851 }
852
Victor Stinner14e461d2013-08-26 22:28:21 +0200853 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
854 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000855
856 exit:
857 Py_XDECREF(message);
858 Py_XDECREF(module);
859 Py_XDECREF(filename);
860 return ret;
861}
862
Antoine Pitrou070cb3c2013-05-08 13:23:25 +0200863int
864PyErr_WarnExplicitFormat(PyObject *category,
865 const char *filename_str, int lineno,
866 const char *module_str, PyObject *registry,
867 const char *format, ...)
868{
869 PyObject *message;
870 PyObject *module = NULL;
871 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
872 int ret = -1;
873 va_list vargs;
874
875 if (filename == NULL)
876 goto exit;
877 if (module_str != NULL) {
878 module = PyUnicode_FromString(module_str);
879 if (module == NULL)
880 goto exit;
881 }
882
883#ifdef HAVE_STDARG_PROTOTYPES
884 va_start(vargs, format);
885#else
886 va_start(vargs);
887#endif
888 message = PyUnicode_FromFormatV(format, vargs);
889 if (message != NULL) {
890 PyObject *res;
891 res = warn_explicit(category, message, filename, lineno,
892 module, registry, NULL);
893 Py_DECREF(message);
894 if (res != NULL) {
895 Py_DECREF(res);
896 ret = 0;
897 }
898 }
899 va_end(vargs);
900exit:
901 Py_XDECREF(module);
902 Py_XDECREF(filename);
903 return ret;
904}
905
Christian Heimes33fe8092008-04-13 13:53:33 +0000906
907PyDoc_STRVAR(warn_doc,
908"Issue a warning, or maybe ignore it or raise an exception.");
909
910PyDoc_STRVAR(warn_explicit_doc,
911"Low-level inferface to warnings functionality.");
912
913static PyMethodDef warnings_functions[] = {
914 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
915 warn_doc},
916 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
917 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Christian Heimes1a8501c2008-10-02 19:56:01 +0000918 /* XXX(brett.cannon): add showwarning? */
919 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +0000921};
922
923
924static PyObject *
925create_filter(PyObject *category, const char *action)
926{
927 static PyObject *ignore_str = NULL;
928 static PyObject *error_str = NULL;
929 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +0000930 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000931 PyObject *action_obj = NULL;
932 PyObject *lineno, *result;
933
934 if (!strcmp(action, "ignore")) {
935 if (ignore_str == NULL) {
936 ignore_str = PyUnicode_InternFromString("ignore");
937 if (ignore_str == NULL)
938 return NULL;
939 }
940 action_obj = ignore_str;
941 }
942 else if (!strcmp(action, "error")) {
943 if (error_str == NULL) {
944 error_str = PyUnicode_InternFromString("error");
945 if (error_str == NULL)
946 return NULL;
947 }
948 action_obj = error_str;
949 }
950 else if (!strcmp(action, "default")) {
951 if (default_str == NULL) {
952 default_str = PyUnicode_InternFromString("default");
953 if (default_str == NULL)
954 return NULL;
955 }
956 action_obj = default_str;
957 }
Georg Brandl08be72d2010-10-24 15:11:22 +0000958 else if (!strcmp(action, "always")) {
959 if (always_str == NULL) {
960 always_str = PyUnicode_InternFromString("always");
961 if (always_str == NULL)
962 return NULL;
963 }
964 action_obj = always_str;
965 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000966 else {
967 Py_FatalError("unknown action");
968 }
969
970 /* This assumes the line number is zero for now. */
971 lineno = PyLong_FromLong(0);
972 if (lineno == NULL)
973 return NULL;
974 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
975 Py_DECREF(lineno);
976 return result;
977}
978
979static PyObject *
980init_filters(void)
981{
Georg Brandl08be72d2010-10-24 15:11:22 +0000982 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000983 unsigned int pos = 0; /* Post-incremented in each use. */
984 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +0000985 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000986
Christian Heimes33fe8092008-04-13 13:53:33 +0000987 if (filters == NULL)
988 return NULL;
989
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000990 PyList_SET_ITEM(filters, pos++,
991 create_filter(PyExc_DeprecationWarning, "ignore"));
992 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +0000993 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +0000994 PyList_SET_ITEM(filters, pos++,
995 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +0000996 if (Py_BytesWarningFlag > 1)
997 bytes_action = "error";
998 else if (Py_BytesWarningFlag)
999 bytes_action = "default";
1000 else
1001 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001002 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001003 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +00001004 /* resource usage warnings are enabled by default in pydebug mode */
1005#ifdef Py_DEBUG
1006 resource_action = "always";
1007#else
1008 resource_action = "ignore";
1009#endif
1010 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1011 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001012 for (x = 0; x < pos; x += 1) {
1013 if (PyList_GET_ITEM(filters, x) == NULL) {
1014 Py_DECREF(filters);
1015 return NULL;
1016 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001017 }
1018
1019 return filters;
1020}
1021
Martin v. Löwis1a214512008-06-11 05:26:20 +00001022static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyModuleDef_HEAD_INIT,
1024 MODULE_NAME,
1025 warnings__doc__,
1026 0,
1027 warnings_functions,
1028 NULL,
1029 NULL,
1030 NULL,
1031 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001032};
1033
Christian Heimes33fe8092008-04-13 13:53:33 +00001034
1035PyMODINIT_FUNC
1036_PyWarnings_Init(void)
1037{
Brett Cannon0759dd62009-04-01 18:13:07 +00001038 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001039
Martin v. Löwis1a214512008-06-11 05:26:20 +00001040 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001041 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001042 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001043
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001044 if (_filters == NULL) {
1045 _filters = init_filters();
1046 if (_filters == NULL)
1047 return NULL;
1048 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001049 Py_INCREF(_filters);
1050 if (PyModule_AddObject(m, "filters", _filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001051 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001052
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001053 if (_once_registry == NULL) {
1054 _once_registry = PyDict_New();
1055 if (_once_registry == NULL)
1056 return NULL;
1057 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001058 Py_INCREF(_once_registry);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001059 if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001060 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001061
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001062 if (_default_action == NULL) {
1063 _default_action = PyUnicode_FromString("default");
1064 if (_default_action == NULL)
1065 return NULL;
1066 }
1067 Py_INCREF(_default_action);
Brett Cannonef0e6c32010-09-04 18:24:04 +00001068 if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001069 return NULL;
1070 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001071}