blob: e88f6460895ff1016a810f9f02fe1f629ab85fdd [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
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100336 /* module can be None if a warning is emitted late during Python shutdown.
337 In this case, the Python warnings module was probably unloaded, filters
338 are no more available to choose as action. It is safer to ignore the
339 warning and do nothing. */
340 if (module == Py_None)
341 Py_RETURN_NONE;
342
Brett Cannondb734912008-06-27 00:52:15 +0000343 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
344 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
345 return NULL;
346 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000347
348 /* Normalize module. */
349 if (module == NULL) {
350 module = normalize_module(filename);
351 if (module == NULL)
352 return NULL;
353 }
354 else
355 Py_INCREF(module);
356
357 /* Normalize message. */
358 Py_INCREF(message); /* DECREF'ed in cleanup. */
359 rc = PyObject_IsInstance(message, PyExc_Warning);
360 if (rc == -1) {
361 goto cleanup;
362 }
363 if (rc == 1) {
364 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000365 if (text == NULL)
366 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000367 category = (PyObject*)message->ob_type;
368 }
369 else {
370 text = message;
371 message = PyObject_CallFunction(category, "O", message);
Brett Cannondb734912008-06-27 00:52:15 +0000372 if (message == NULL)
373 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000374 }
375
376 lineno_obj = PyLong_FromLong(lineno);
377 if (lineno_obj == NULL)
378 goto cleanup;
379
380 /* Create key. */
381 key = PyTuple_Pack(3, text, category, lineno_obj);
382 if (key == NULL)
383 goto cleanup;
384
Brett Cannondb734912008-06-27 00:52:15 +0000385 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000386 rc = already_warned(registry, key, 0);
387 if (rc == -1)
388 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000390 goto return_none;
391 /* Else this warning hasn't been generated before. */
392 }
393
394 action = get_filter(category, text, lineno, module, &item);
395 if (action == NULL)
396 goto cleanup;
397
Victor Stinnera4c704b2013-10-29 23:43:41 +0100398 if (PyUnicode_CompareWithASCIIString(action, "error") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000399 PyErr_SetObject(category, message);
400 goto cleanup;
401 }
402
403 /* Store in the registry that we've been here, *except* when the action
404 is "always". */
405 rc = 0;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100406 if (PyUnicode_CompareWithASCIIString(action, "always") != 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000407 if (registry != NULL && registry != Py_None &&
408 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000409 goto cleanup;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100410 else if (PyUnicode_CompareWithASCIIString(action, "ignore") == 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000411 goto return_none;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100412 else if (PyUnicode_CompareWithASCIIString(action, "once") == 0) {
Brett Cannondb734912008-06-27 00:52:15 +0000413 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000414 registry = get_once_registry();
415 if (registry == NULL)
416 goto cleanup;
417 }
418 /* _once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000420 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100421 else if (PyUnicode_CompareWithASCIIString(action, "module") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000422 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000423 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000425 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100426 else if (PyUnicode_CompareWithASCIIString(action, "default") != 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000427 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100428 "Unrecognized action (%R) in warnings.filters:\n %R",
429 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000430 goto cleanup;
431 }
432 }
433
Christian Heimes1a8501c2008-10-02 19:56:01 +0000434 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000435 goto return_none;
436 if (rc == 0) {
437 PyObject *show_fxn = get_warnings_attr("showwarning");
438 if (show_fxn == NULL) {
439 if (PyErr_Occurred())
440 goto cleanup;
441 show_warning(filename, lineno, text, category, sourceline);
442 }
443 else {
Brett Cannonec92e182008-09-02 02:46:59 +0000444 PyObject *res;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000445
Brett Cannon52a7d982011-07-17 19:17:55 -0700446 if (!PyCallable_Check(show_fxn)) {
Brett Cannonec92e182008-09-02 02:46:59 +0000447 PyErr_SetString(PyExc_TypeError,
448 "warnings.showwarning() must be set to a "
Brett Cannon52a7d982011-07-17 19:17:55 -0700449 "callable");
Christian Heimes8dc226f2008-05-06 23:45:46 +0000450 Py_DECREF(show_fxn);
Brett Cannonec92e182008-09-02 02:46:59 +0000451 goto cleanup;
Christian Heimes8dc226f2008-05-06 23:45:46 +0000452 }
Brett Cannonec92e182008-09-02 02:46:59 +0000453
454 res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
455 filename, lineno_obj,
456 NULL);
457 Py_DECREF(show_fxn);
458 Py_XDECREF(res);
459 if (res == NULL)
460 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000461 }
462 }
463 else /* if (rc == -1) */
464 goto cleanup;
465
466 return_none:
467 result = Py_None;
468 Py_INCREF(result);
469
470 cleanup:
471 Py_XDECREF(key);
472 Py_XDECREF(text);
473 Py_XDECREF(lineno_obj);
474 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000475 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000476 return result; /* Py_None or NULL. */
477}
478
479/* filename, module, and registry are new refs, globals is borrowed */
480/* Returns 0 on error (no new refs), 1 on success */
481static int
482setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
483 PyObject **module, PyObject **registry)
484{
485 PyObject *globals;
486
487 /* Setup globals and lineno. */
488 PyFrameObject *f = PyThreadState_GET()->frame;
Christian Heimes5d8da202008-05-06 13:58:24 +0000489 while (--stack_level > 0 && f != NULL)
Christian Heimes33fe8092008-04-13 13:53:33 +0000490 f = f->f_back;
Christian Heimes33fe8092008-04-13 13:53:33 +0000491
492 if (f == NULL) {
493 globals = PyThreadState_Get()->interp->sysdict;
494 *lineno = 1;
495 }
496 else {
497 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000498 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000499 }
500
501 *module = NULL;
502
503 /* Setup registry. */
504 assert(globals != NULL);
505 assert(PyDict_Check(globals));
506 *registry = PyDict_GetItemString(globals, "__warningregistry__");
507 if (*registry == NULL) {
508 int rc;
509
510 *registry = PyDict_New();
511 if (*registry == NULL)
512 return 0;
513
514 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
515 if (rc < 0)
516 goto handle_error;
517 }
518 else
519 Py_INCREF(*registry);
520
521 /* Setup module. */
522 *module = PyDict_GetItemString(globals, "__name__");
523 if (*module == NULL) {
524 *module = PyUnicode_FromString("<string>");
525 if (*module == NULL)
526 goto handle_error;
527 }
528 else
529 Py_INCREF(*module);
530
531 /* Setup filename. */
532 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200533 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200534 Py_ssize_t len;
535 int kind;
536 void *data;
537
538 if (PyUnicode_READY(*filename))
539 goto handle_error;
540
Victor Stinner9e30aa52011-11-21 02:49:52 +0100541 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200542 kind = PyUnicode_KIND(*filename);
543 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000544
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500545#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000546 /* if filename.lower().endswith((".pyc", ".pyo")): */
547 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200548 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500549 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
550 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
551 (ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c' ||
552 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'o'))
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000553 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200554 *filename = PyUnicode_Substring(*filename, 0,
555 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000556 if (*filename == NULL)
557 goto handle_error;
558 }
559 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000560 Py_INCREF(*filename);
561 }
562 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500563 *filename = NULL;
Victor Stinner856f45f2013-10-30 00:04:59 +0100564 if (*module != Py_None && PyUnicode_CompareWithASCIIString(*module, "__main__") == 0) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000565 PyObject *argv = PySys_GetObject("argv");
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100566 /* PyList_Check() is needed because sys.argv is set to None during
567 Python finalization */
568 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000569 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000570 *filename = PyList_GetItem(argv, 0);
571 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000572 /* If sys.argv[0] is false, then use '__main__'. */
573 is_true = PyObject_IsTrue(*filename);
574 if (is_true < 0) {
575 Py_DECREF(*filename);
576 goto handle_error;
577 }
578 else if (!is_true) {
579 Py_DECREF(*filename);
Benjamin Peterson9f4bf1d2008-05-04 23:22:13 +0000580 *filename = PyUnicode_FromString("__main__");
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000581 if (*filename == NULL)
582 goto handle_error;
583 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000584 }
585 else {
586 /* embedded interpreters don't have sys.argv, see bug #839151 */
587 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100588 if (*filename == NULL)
589 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000590 }
591 }
592 if (*filename == NULL) {
593 *filename = *module;
594 Py_INCREF(*filename);
595 }
596 }
597
598 return 1;
599
600 handle_error:
601 /* filename not XDECREF'ed here as there is no way to jump here with a
602 dangling reference. */
603 Py_XDECREF(*registry);
604 Py_XDECREF(*module);
605 return 0;
606}
607
608static PyObject *
609get_category(PyObject *message, PyObject *category)
610{
611 int rc;
612
613 /* Get category. */
614 rc = PyObject_IsInstance(message, PyExc_Warning);
615 if (rc == -1)
616 return NULL;
617
618 if (rc == 1)
619 category = (PyObject*)message->ob_type;
620 else if (category == NULL)
621 category = PyExc_UserWarning;
622
623 /* Validate category. */
624 rc = PyObject_IsSubclass(category, PyExc_Warning);
625 if (rc == -1)
626 return NULL;
627 if (rc == 0) {
628 PyErr_SetString(PyExc_ValueError,
629 "category is not a subclass of Warning");
630 return NULL;
631 }
632
633 return category;
634}
635
636static PyObject *
637do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
638{
639 PyObject *filename, *module, *registry, *res;
640 int lineno;
641
642 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
643 return NULL;
644
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100645 res = warn_explicit(category, message, filename, lineno, module, registry,
646 NULL);
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}