blob: 3313c59f4068bef8cd9675e93ca13ca118884b92 [file] [log] [blame]
Brett Cannone9746892008-04-12 23:44:07 +00001#include "Python.h"
Brett Cannon1eaf0742008-09-02 01:25:16 +00002#include "code.h" /* For DeprecationWarning about adding 'line'. */
Brett Cannone9746892008-04-12 23:44:07 +00003#include "frameobject.h"
4
5#define MODULE_NAME "_warnings"
6#define DEFAULT_ACTION_NAME "default_action"
7
8PyDoc_STRVAR(warnings__doc__,
9MODULE_NAME " provides basic warning filtering support.\n"
10"It is a helper module to speed up interpreter start-up.");
11
12/* Both 'filters' and 'onceregistry' can be set in warnings.py;
13 get_warnings_attr() will reset these variables accordingly. */
14static PyObject *_filters; /* List */
15static PyObject *_once_registry; /* Dict */
16
17
18static int
19check_matched(PyObject *obj, PyObject *arg)
20{
21 PyObject *result;
22 int rc;
23
24 if (obj == Py_None)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000025 return 1;
Brett Cannone9746892008-04-12 23:44:07 +000026 result = PyObject_CallMethod(obj, "match", "O", arg);
27 if (result == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000028 return -1;
Brett Cannone9746892008-04-12 23:44:07 +000029
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) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000048 warnings_str = PyString_InternFromString("warnings");
49 if (warnings_str == NULL)
50 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +000051 }
52
53 all_modules = PyImport_GetModuleDict();
54 result = PyDict_Contains(all_modules, warnings_str);
55 if (result == -1 || result == 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000056 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +000057
58 warnings_module = PyDict_GetItem(all_modules, warnings_str);
59 if (!PyObject_HasAttrString(warnings_module, attr))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000060 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +000061 return PyObject_GetAttrString(warnings_module, attr);
62}
63
64
Amaury Forgeot d'Arcf9e7ebe2008-04-14 20:07:48 +000065static PyObject *
Brett Cannone9746892008-04-12 23:44:07 +000066get_once_registry(void)
67{
68 PyObject *registry;
69
70 registry = get_warnings_attr("onceregistry");
71 if (registry == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000072 if (PyErr_Occurred())
73 return NULL;
74 return _once_registry;
Brett Cannone9746892008-04-12 23:44:07 +000075 }
76 Py_DECREF(_once_registry);
77 _once_registry = registry;
78 return registry;
79}
80
81
82/* The item is a borrowed reference. */
83static const char *
84get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
85 PyObject *module, PyObject **item)
86{
87 PyObject *action, *m, *d;
88 Py_ssize_t i;
89 PyObject *warnings_filters;
90
91 warnings_filters = get_warnings_attr("filters");
92 if (warnings_filters == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000093 if (PyErr_Occurred())
94 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +000095 }
96 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +000097 Py_DECREF(_filters);
98 _filters = warnings_filters;
Brett Cannone9746892008-04-12 23:44:07 +000099 }
100
101 if (!PyList_Check(_filters)) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000102 PyErr_SetString(PyExc_ValueError,
103 MODULE_NAME ".filters must be a list");
104 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000105 }
106
107 /* _filters could change while we are iterating over it. */
108 for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000109 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
110 Py_ssize_t ln;
111 int is_subclass, good_msg, good_mod;
Brett Cannone9746892008-04-12 23:44:07 +0000112
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000113 tmp_item = *item = PyList_GET_ITEM(_filters, i);
114 if (PyTuple_Size(tmp_item) != 5) {
115 PyErr_Format(PyExc_ValueError,
116 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
117 return NULL;
118 }
Brett Cannone9746892008-04-12 23:44:07 +0000119
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000120 /* Python code: action, msg, cat, mod, ln = item */
121 action = PyTuple_GET_ITEM(tmp_item, 0);
122 msg = PyTuple_GET_ITEM(tmp_item, 1);
123 cat = PyTuple_GET_ITEM(tmp_item, 2);
124 mod = PyTuple_GET_ITEM(tmp_item, 3);
125 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
Brett Cannone9746892008-04-12 23:44:07 +0000126
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000127 good_msg = check_matched(msg, text);
128 good_mod = check_matched(mod, module);
129 is_subclass = PyObject_IsSubclass(category, cat);
130 ln = PyInt_AsSsize_t(ln_obj);
131 if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||
132 (ln == -1 && PyErr_Occurred()))
133 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000134
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000135 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))
136 return PyString_AsString(action);
Brett Cannone9746892008-04-12 23:44:07 +0000137 }
138
139 m = PyImport_ImportModule(MODULE_NAME);
140 if (m == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000141 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000142 d = PyModule_GetDict(m);
143 Py_DECREF(m);
144 if (d == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000145 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000146 action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME);
147 if (action != NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000148 return PyString_AsString(action);
Brett Cannone9746892008-04-12 23:44:07 +0000149
150 PyErr_SetString(PyExc_ValueError,
151 MODULE_NAME "." DEFAULT_ACTION_NAME " not found");
152 return NULL;
153}
154
155static int
156already_warned(PyObject *registry, PyObject *key, int should_set)
157{
158 PyObject *already_warned;
159
160 if (key == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000161 return -1;
Brett Cannone9746892008-04-12 23:44:07 +0000162
163 already_warned = PyDict_GetItem(registry, key);
164 if (already_warned != NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000165 int rc = PyObject_IsTrue(already_warned);
166 if (rc != 0)
167 return rc;
Brett Cannone9746892008-04-12 23:44:07 +0000168 }
169
170 /* This warning wasn't found in the registry, set it. */
171 if (should_set)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000172 return PyDict_SetItem(registry, key, Py_True);
Brett Cannone9746892008-04-12 23:44:07 +0000173 return 0;
174}
175
176/* New reference. */
177static PyObject *
178normalize_module(PyObject *filename)
179{
180 PyObject *module;
181 const char *mod_str;
182 Py_ssize_t len;
183
184 int rc = PyObject_IsTrue(filename);
185 if (rc == -1)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000186 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000187 else if (rc == 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000188 return PyString_FromString("<unknown>");
Brett Cannone9746892008-04-12 23:44:07 +0000189
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000190 mod_str = PyString_AsString(filename);
Brett Cannone9746892008-04-12 23:44:07 +0000191 if (mod_str == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000192 return NULL;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000193 len = PyString_Size(filename);
Brett Cannone9746892008-04-12 23:44:07 +0000194 if (len < 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000195 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000196 if (len >= 3 &&
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000197 strncmp(mod_str + (len - 3), ".py", 3) == 0) {
198 module = PyString_FromStringAndSize(mod_str, len-3);
Brett Cannone9746892008-04-12 23:44:07 +0000199 }
200 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000201 module = filename;
202 Py_INCREF(module);
Brett Cannone9746892008-04-12 23:44:07 +0000203 }
204 return module;
205}
206
207static int
208update_registry(PyObject *registry, PyObject *text, PyObject *category,
209 int add_zero)
210{
211 PyObject *altkey, *zero = NULL;
212 int rc;
213
214 if (add_zero) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000215 zero = PyInt_FromLong(0);
216 if (zero == NULL)
217 return -1;
218 altkey = PyTuple_Pack(3, text, category, zero);
Brett Cannone9746892008-04-12 23:44:07 +0000219 }
220 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000221 altkey = PyTuple_Pack(2, text, category);
Brett Cannone9746892008-04-12 23:44:07 +0000222
223 rc = already_warned(registry, altkey, 1);
224 Py_XDECREF(zero);
225 Py_XDECREF(altkey);
226 return rc;
227}
228
229static void
230show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
231 *category, PyObject *sourceline)
232{
Brett Cannon8a232cc2008-05-05 05:32:07 +0000233 PyObject *f_stderr;
234 PyObject *name;
Brett Cannone9746892008-04-12 23:44:07 +0000235 char lineno_str[128];
236
237 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
238
239 name = PyObject_GetAttrString(category, "__name__");
240 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000241 return;
Brett Cannone9746892008-04-12 23:44:07 +0000242
243 f_stderr = PySys_GetObject("stderr");
244 if (f_stderr == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000245 fprintf(stderr, "lost sys.stderr\n");
246 Py_DECREF(name);
247 return;
Brett Cannone9746892008-04-12 23:44:07 +0000248 }
249
250 /* Print "filename:lineno: category: text\n" */
251 PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW);
252 PyFile_WriteString(lineno_str, f_stderr);
253 PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW);
254 PyFile_WriteString(": ", f_stderr);
255 PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW);
256 PyFile_WriteString("\n", f_stderr);
257 Py_XDECREF(name);
258
259 /* Print " source_line\n" */
Brett Cannone9746892008-04-12 23:44:07 +0000260 if (sourceline) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000261 char *source_line_str = PyString_AS_STRING(sourceline);
262 while (*source_line_str == ' ' || *source_line_str == '\t' ||
263 *source_line_str == '\014')
264 source_line_str++;
Brett Cannone9746892008-04-12 23:44:07 +0000265
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000266 PyFile_WriteString(source_line_str, f_stderr);
267 PyFile_WriteString("\n", f_stderr);
Brett Cannone9746892008-04-12 23:44:07 +0000268 }
269 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000270 _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename),
271 lineno, 2);
Brett Cannone9746892008-04-12 23:44:07 +0000272 PyErr_Clear();
273}
274
275static PyObject *
Brett Cannon8a232cc2008-05-05 05:32:07 +0000276warn_explicit(PyObject *category, PyObject *message,
Brett Cannone9746892008-04-12 23:44:07 +0000277 PyObject *filename, int lineno,
278 PyObject *module, PyObject *registry, PyObject *sourceline)
279{
280 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
281 PyObject *item = Py_None;
282 const char *action;
283 int rc;
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000284
Brett Cannondea1b562008-06-27 00:31:13 +0000285 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000286 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
287 return NULL;
Brett Cannondea1b562008-06-27 00:31:13 +0000288 }
Brett Cannone9746892008-04-12 23:44:07 +0000289
290 /* Normalize module. */
291 if (module == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000292 module = normalize_module(filename);
293 if (module == NULL)
294 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000295 }
296 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000297 Py_INCREF(module);
Brett Cannone9746892008-04-12 23:44:07 +0000298
299 /* Normalize message. */
300 Py_INCREF(message); /* DECREF'ed in cleanup. */
301 rc = PyObject_IsInstance(message, PyExc_Warning);
302 if (rc == -1) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000303 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000304 }
305 if (rc == 1) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000306 text = PyObject_Str(message);
307 if (text == NULL)
308 goto cleanup;
309 category = (PyObject*)message->ob_type;
Brett Cannone9746892008-04-12 23:44:07 +0000310 }
311 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000312 text = message;
313 message = PyObject_CallFunction(category, "O", message);
314 if (message == NULL)
315 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000316 }
317
318 lineno_obj = PyInt_FromLong(lineno);
319 if (lineno_obj == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000320 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000321
322 /* Create key. */
323 key = PyTuple_Pack(3, text, category, lineno_obj);
324 if (key == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000325 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000326
Brett Cannondea1b562008-06-27 00:31:13 +0000327 if ((registry != NULL) && (registry != Py_None)) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000328 rc = already_warned(registry, key, 0);
329 if (rc == -1)
330 goto cleanup;
331 else if (rc == 1)
332 goto return_none;
333 /* Else this warning hasn't been generated before. */
Brett Cannone9746892008-04-12 23:44:07 +0000334 }
335
336 action = get_filter(category, text, lineno, module, &item);
337 if (action == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000338 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000339
340 if (strcmp(action, "error") == 0) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000341 PyErr_SetObject(category, message);
342 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000343 }
344
345 /* Store in the registry that we've been here, *except* when the action
346 is "always". */
347 rc = 0;
348 if (strcmp(action, "always") != 0) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000349 if (registry != NULL && registry != Py_None &&
350 PyDict_SetItem(registry, key, Py_True) < 0)
351 goto cleanup;
352 else if (strcmp(action, "ignore") == 0)
353 goto return_none;
354 else if (strcmp(action, "once") == 0) {
355 if (registry == NULL || registry == Py_None) {
356 registry = get_once_registry();
357 if (registry == NULL)
Brett Cannone9746892008-04-12 23:44:07 +0000358 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000359 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000360 /* _once_registry[(text, category)] = 1 */
361 rc = update_registry(registry, text, category, 0);
362 }
363 else if (strcmp(action, "module") == 0) {
364 /* registry[(text, category, 0)] = 1 */
365 if (registry != NULL && registry != Py_None)
366 rc = update_registry(registry, text, category, 0);
367 }
368 else if (strcmp(action, "default") != 0) {
369 PyObject *to_str = PyObject_Str(item);
370 const char *err_str = "???";
Brett Cannone9746892008-04-12 23:44:07 +0000371
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000372 if (to_str != NULL)
373 err_str = PyString_AS_STRING(to_str);
374 PyErr_Format(PyExc_RuntimeError,
375 "Unrecognized action (%s) in warnings.filters:\n %s",
376 action, err_str);
377 Py_XDECREF(to_str);
378 goto cleanup;
379 }
Brett Cannone9746892008-04-12 23:44:07 +0000380 }
381
Christian Heimes4d8a6f42008-10-02 19:49:47 +0000382 if (rc == 1) /* Already warned for this module. */
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000383 goto return_none;
Brett Cannone9746892008-04-12 23:44:07 +0000384 if (rc == 0) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000385 PyObject *show_fxn = get_warnings_attr("showwarning");
386 if (show_fxn == NULL) {
387 if (PyErr_Occurred())
388 goto cleanup;
389 show_warning(filename, lineno, text, category, sourceline);
390 }
391 else {
392 const char *msg = "functions overriding warnings.showwarning() "
393 "must support the 'line' argument";
394 const char *text_char = PyString_AS_STRING(text);
395
396 if (strcmp(msg, text_char) == 0) {
397 /* Prevent infinite recursion by using built-in implementation
398 of showwarning(). */
399 show_warning(filename, lineno, text, category, sourceline);
Brett Cannone9746892008-04-12 23:44:07 +0000400 }
401 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000402 PyObject *check_fxn;
403 PyObject *defaults;
404 PyObject *res;
Brett Cannon8a232cc2008-05-05 05:32:07 +0000405
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000406 if (PyMethod_Check(show_fxn))
407 check_fxn = PyMethod_Function(show_fxn);
408 else if (PyFunction_Check(show_fxn))
409 check_fxn = show_fxn;
410 else {
411 PyErr_SetString(PyExc_TypeError,
412 "warnings.showwarning() must be set to a "
413 "function or method");
414 Py_DECREF(show_fxn);
415 goto cleanup;
416 }
Brett Cannon8a232cc2008-05-05 05:32:07 +0000417
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000418 defaults = PyFunction_GetDefaults(check_fxn);
419 /* A proper implementation of warnings.showwarning() should
420 have at least two default arguments. */
421 if ((defaults == NULL) || (PyTuple_Size(defaults) < 2)) {
422 PyCodeObject *code = (PyCodeObject *)
423 PyFunction_GetCode(check_fxn);
424 if (!(code->co_flags & CO_VARARGS)) {
425 if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1) <
426 0) {
Brett Cannon8a232cc2008-05-05 05:32:07 +0000427 Py_DECREF(show_fxn);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000428 goto cleanup;
429 }
Brett Cannon8a232cc2008-05-05 05:32:07 +0000430 }
Brett Cannone9746892008-04-12 23:44:07 +0000431 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000432 res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
433 filename, lineno_obj,
434 NULL);
435 Py_DECREF(show_fxn);
436 Py_XDECREF(res);
437 if (res == NULL)
438 goto cleanup;
439 }
440 }
Brett Cannone9746892008-04-12 23:44:07 +0000441 }
442 else /* if (rc == -1) */
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000443 goto cleanup;
Brett Cannone9746892008-04-12 23:44:07 +0000444
445 return_none:
446 result = Py_None;
447 Py_INCREF(result);
448
449 cleanup:
450 Py_XDECREF(key);
451 Py_XDECREF(text);
452 Py_XDECREF(lineno_obj);
453 Py_DECREF(module);
Brett Cannondea1b562008-06-27 00:31:13 +0000454 Py_XDECREF(message);
Brett Cannone9746892008-04-12 23:44:07 +0000455 return result; /* Py_None or NULL. */
456}
457
458/* filename, module, and registry are new refs, globals is borrowed */
459/* Returns 0 on error (no new refs), 1 on success */
460static int
461setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
462 PyObject **module, PyObject **registry)
463{
464 PyObject *globals;
465
466 /* Setup globals and lineno. */
467 PyFrameObject *f = PyThreadState_GET()->frame;
Brett Cannone3dcb012008-05-06 04:37:31 +0000468 while (--stack_level > 0 && f != NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000469 f = f->f_back;
Brett Cannone9746892008-04-12 23:44:07 +0000470
471 if (f == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000472 globals = PyThreadState_Get()->interp->sysdict;
473 *lineno = 1;
Brett Cannone9746892008-04-12 23:44:07 +0000474 }
475 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000476 globals = f->f_globals;
477 *lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
Brett Cannone9746892008-04-12 23:44:07 +0000478 }
479
480 *module = NULL;
481
482 /* Setup registry. */
483 assert(globals != NULL);
484 assert(PyDict_Check(globals));
485 *registry = PyDict_GetItemString(globals, "__warningregistry__");
486 if (*registry == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000487 int rc;
Brett Cannone9746892008-04-12 23:44:07 +0000488
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000489 *registry = PyDict_New();
490 if (*registry == NULL)
491 return 0;
Brett Cannone9746892008-04-12 23:44:07 +0000492
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000493 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
494 if (rc < 0)
495 goto handle_error;
Brett Cannone9746892008-04-12 23:44:07 +0000496 }
497 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000498 Py_INCREF(*registry);
Brett Cannone9746892008-04-12 23:44:07 +0000499
500 /* Setup module. */
501 *module = PyDict_GetItemString(globals, "__name__");
502 if (*module == NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000503 *module = PyString_FromString("<string>");
504 if (*module == NULL)
505 goto handle_error;
Brett Cannone9746892008-04-12 23:44:07 +0000506 }
507 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000508 Py_INCREF(*module);
Brett Cannone9746892008-04-12 23:44:07 +0000509
510 /* Setup filename. */
511 *filename = PyDict_GetItemString(globals, "__file__");
512 if (*filename != NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000513 Py_ssize_t len = PyString_Size(*filename);
514 const char *file_str = PyString_AsString(*filename);
515 if (file_str == NULL || (len < 0 && PyErr_Occurred()))
516 goto handle_error;
Brett Cannone9746892008-04-12 23:44:07 +0000517
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000518 /* if filename.lower().endswith((".pyc", ".pyo")): */
519 if (len >= 4 &&
520 file_str[len-4] == '.' &&
521 tolower(file_str[len-3]) == 'p' &&
522 tolower(file_str[len-2]) == 'y' &&
523 (tolower(file_str[len-1]) == 'c' ||
524 tolower(file_str[len-1]) == 'o'))
525 {
526 *filename = PyString_FromStringAndSize(file_str, len-1);
527 if (*filename == NULL)
528 goto handle_error;
529 }
530 else
531 Py_INCREF(*filename);
Brett Cannone9746892008-04-12 23:44:07 +0000532 }
533 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000534 const char *module_str = PyString_AsString(*module);
535 if (module_str && strcmp(module_str, "__main__") == 0) {
536 PyObject *argv = PySys_GetObject("argv");
537 if (argv != NULL && PyList_Size(argv) > 0) {
538 int is_true;
539 *filename = PyList_GetItem(argv, 0);
540 Py_INCREF(*filename);
541 /* If sys.argv[0] is false, then use '__main__'. */
542 is_true = PyObject_IsTrue(*filename);
543 if (is_true < 0) {
544 Py_DECREF(*filename);
545 goto handle_error;
Brett Cannone9746892008-04-12 23:44:07 +0000546 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000547 else if (!is_true) {
548 Py_DECREF(*filename);
549 *filename = PyString_FromString("__main__");
550 if (*filename == NULL)
551 goto handle_error;
Brett Cannone9746892008-04-12 23:44:07 +0000552 }
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000553 }
554 else {
555 /* embedded interpreters don't have sys.argv, see bug #839151 */
556 *filename = PyString_FromString("__main__");
557 if (*filename == NULL)
558 goto handle_error;
559 }
560 }
561 if (*filename == NULL) {
562 *filename = *module;
563 Py_INCREF(*filename);
564 }
Brett Cannone9746892008-04-12 23:44:07 +0000565 }
566
567 return 1;
568
569 handle_error:
570 /* filename not XDECREF'ed here as there is no way to jump here with a
571 dangling reference. */
572 Py_XDECREF(*registry);
573 Py_XDECREF(*module);
574 return 0;
575}
576
577static PyObject *
578get_category(PyObject *message, PyObject *category)
579{
580 int rc;
581
582 /* Get category. */
583 rc = PyObject_IsInstance(message, PyExc_Warning);
584 if (rc == -1)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000585 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000586
587 if (rc == 1)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000588 category = (PyObject*)message->ob_type;
Brett Cannone9746892008-04-12 23:44:07 +0000589 else if (category == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000590 category = PyExc_UserWarning;
Brett Cannone9746892008-04-12 23:44:07 +0000591
592 /* Validate category. */
593 rc = PyObject_IsSubclass(category, PyExc_Warning);
594 if (rc == -1)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000595 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000596 if (rc == 0) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000597 PyErr_SetString(PyExc_ValueError,
598 "category is not a subclass of Warning");
599 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000600 }
601
602 return category;
603}
604
605static PyObject *
606do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)
607{
608 PyObject *filename, *module, *registry, *res;
609 int lineno;
610
611 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000612 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000613
614 res = warn_explicit(category, message, filename, lineno, module, registry,
615 NULL);
616 Py_DECREF(filename);
617 Py_DECREF(registry);
618 Py_DECREF(module);
619 return res;
620}
621
622static PyObject *
623warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
624{
625 static char *kw_list[] = { "message", "category", "stacklevel", 0 };
626 PyObject *message, *category = NULL;
627 Py_ssize_t stack_level = 1;
628
Brett Cannon8a232cc2008-05-05 05:32:07 +0000629 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
Brett Cannone9746892008-04-12 23:44:07 +0000630 &message, &category, &stack_level))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000631 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000632
633 category = get_category(message, category);
634 if (category == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000635 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000636 return do_warn(message, category, stack_level);
637}
638
639static PyObject *
640warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
641{
642 static char *kwd_list[] = {"message", "category", "filename", "lineno",
643 "module", "registry", "module_globals", 0};
644 PyObject *message;
645 PyObject *category;
646 PyObject *filename;
647 int lineno;
648 PyObject *module = NULL;
649 PyObject *registry = NULL;
650 PyObject *module_globals = NULL;
651
652 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit",
653 kwd_list, &message, &category, &filename, &lineno, &module,
654 &registry, &module_globals))
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000655 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000656
657 if (module_globals) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000658 static PyObject *get_source_name = NULL;
659 static PyObject *splitlines_name = NULL;
660 PyObject *loader;
661 PyObject *module_name;
662 PyObject *source;
663 PyObject *source_list;
664 PyObject *source_line;
665 PyObject *returned;
Brett Cannone9746892008-04-12 23:44:07 +0000666
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000667 if (get_source_name == NULL) {
668 get_source_name = PyString_InternFromString("get_source");
669 if (!get_source_name)
670 return NULL;
671 }
672 if (splitlines_name == NULL) {
673 splitlines_name = PyString_InternFromString("splitlines");
674 if (!splitlines_name)
675 return NULL;
676 }
Brett Cannone9746892008-04-12 23:44:07 +0000677
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000678 /* Check/get the requisite pieces needed for the loader. */
679 loader = PyDict_GetItemString(module_globals, "__loader__");
680 module_name = PyDict_GetItemString(module_globals, "__name__");
Brett Cannone9746892008-04-12 23:44:07 +0000681
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000682 if (loader == NULL || module_name == NULL)
683 goto standard_call;
Brett Cannone9746892008-04-12 23:44:07 +0000684
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000685 /* Make sure the loader implements the optional get_source() method. */
686 if (!PyObject_HasAttrString(loader, "get_source"))
687 goto standard_call;
688 /* Call get_source() to get the source code. */
689 source = PyObject_CallMethodObjArgs(loader, get_source_name,
690 module_name, NULL);
691 if (!source)
692 return NULL;
693 else if (source == Py_None) {
694 Py_DECREF(Py_None);
695 goto standard_call;
696 }
Brett Cannone9746892008-04-12 23:44:07 +0000697
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000698 /* Split the source into lines. */
699 source_list = PyObject_CallMethodObjArgs(source, splitlines_name,
700 NULL);
701 Py_DECREF(source);
702 if (!source_list)
703 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000704
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000705 /* Get the source line. */
706 source_line = PyList_GetItem(source_list, lineno-1);
707 if (!source_line) {
Brett Cannone9746892008-04-12 23:44:07 +0000708 Py_DECREF(source_list);
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000709 return NULL;
710 }
711
712 /* Handle the warning. */
713 returned = warn_explicit(category, message, filename, lineno, module,
714 registry, source_line);
715 Py_DECREF(source_list);
716 return returned;
Brett Cannone9746892008-04-12 23:44:07 +0000717 }
718
719 standard_call:
720 return warn_explicit(category, message, filename, lineno, module,
721 registry, NULL);
722}
723
724
725/* Function to issue a warning message; may raise an exception. */
726int
727PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
728{
729 PyObject *res;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000730 PyObject *message = PyString_FromString(text);
Brett Cannone9746892008-04-12 23:44:07 +0000731 if (message == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000732 return -1;
Brett Cannone9746892008-04-12 23:44:07 +0000733
734 if (category == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000735 category = PyExc_RuntimeWarning;
Brett Cannone9746892008-04-12 23:44:07 +0000736
737 res = do_warn(message, category, stack_level);
738 Py_DECREF(message);
739 if (res == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000740 return -1;
Brett Cannone9746892008-04-12 23:44:07 +0000741 Py_DECREF(res);
742
743 return 0;
744}
745
746/* PyErr_Warn is only for backwards compatability and will be removed.
747 Use PyErr_WarnEx instead. */
748
749#undef PyErr_Warn
750
751PyAPI_FUNC(int)
752PyErr_Warn(PyObject *category, char *text)
753{
754 return PyErr_WarnEx(category, text, 1);
755}
756
757/* Warning with explicit origin */
758int
759PyErr_WarnExplicit(PyObject *category, const char *text,
760 const char *filename_str, int lineno,
761 const char *module_str, PyObject *registry)
762{
763 PyObject *res;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000764 PyObject *message = PyString_FromString(text);
765 PyObject *filename = PyString_FromString(filename_str);
Brett Cannone9746892008-04-12 23:44:07 +0000766 PyObject *module = NULL;
767 int ret = -1;
768
769 if (message == NULL || filename == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000770 goto exit;
Brett Cannone9746892008-04-12 23:44:07 +0000771 if (module_str != NULL) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000772 module = PyString_FromString(module_str);
773 if (module == NULL)
774 goto exit;
Brett Cannone9746892008-04-12 23:44:07 +0000775 }
776
777 if (category == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000778 category = PyExc_RuntimeWarning;
Brett Cannone9746892008-04-12 23:44:07 +0000779 res = warn_explicit(category, message, filename, lineno, module, registry,
780 NULL);
781 if (res == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000782 goto exit;
Brett Cannone9746892008-04-12 23:44:07 +0000783 Py_DECREF(res);
784 ret = 0;
785
786 exit:
787 Py_XDECREF(message);
788 Py_XDECREF(module);
789 Py_XDECREF(filename);
790 return ret;
791}
792
793
Brett Cannone9746892008-04-12 23:44:07 +0000794PyDoc_STRVAR(warn_doc,
795"Issue a warning, or maybe ignore it or raise an exception.");
796
797PyDoc_STRVAR(warn_explicit_doc,
798"Low-level inferface to warnings functionality.");
799
800static PyMethodDef warnings_functions[] = {
801 {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000802 warn_doc},
Brett Cannone9746892008-04-12 23:44:07 +0000803 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000804 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Christian Heimes4d8a6f42008-10-02 19:49:47 +0000805 /* XXX(brett.cannon): add showwarning? */
806 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000807 {NULL, NULL} /* sentinel */
Brett Cannone9746892008-04-12 23:44:07 +0000808};
809
810
811static PyObject *
812create_filter(PyObject *category, const char *action)
813{
814 static PyObject *ignore_str = NULL;
815 static PyObject *error_str = NULL;
816 static PyObject *default_str = NULL;
817 PyObject *action_obj = NULL;
818 PyObject *lineno, *result;
819
820 if (!strcmp(action, "ignore")) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000821 if (ignore_str == NULL) {
822 ignore_str = PyString_InternFromString("ignore");
823 if (ignore_str == NULL)
824 return NULL;
825 }
826 action_obj = ignore_str;
Brett Cannone9746892008-04-12 23:44:07 +0000827 }
828 else if (!strcmp(action, "error")) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000829 if (error_str == NULL) {
830 error_str = PyString_InternFromString("error");
831 if (error_str == NULL)
832 return NULL;
833 }
834 action_obj = error_str;
Brett Cannone9746892008-04-12 23:44:07 +0000835 }
836 else if (!strcmp(action, "default")) {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000837 if (default_str == NULL) {
838 default_str = PyString_InternFromString("default");
839 if (default_str == NULL)
840 return NULL;
841 }
842 action_obj = default_str;
Brett Cannone9746892008-04-12 23:44:07 +0000843 }
844 else {
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000845 Py_FatalError("unknown action");
Brett Cannone9746892008-04-12 23:44:07 +0000846 }
847
848 /* This assumes the line number is zero for now. */
849 lineno = PyInt_FromLong(0);
850 if (lineno == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000851 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000852 result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
853 Py_DECREF(lineno);
854 return result;
855}
856
857static PyObject *
858init_filters(void)
859{
860 PyObject *filters = PyList_New(3);
861 const char *bytes_action;
862 if (filters == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000863 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000864
865 PyList_SET_ITEM(filters, 0,
866 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
867 PyList_SET_ITEM(filters, 1, create_filter(PyExc_ImportWarning, "ignore"));
868 if (Py_BytesWarningFlag > 1)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000869 bytes_action = "error";
Brett Cannone9746892008-04-12 23:44:07 +0000870 else if (Py_BytesWarningFlag)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000871 bytes_action = "default";
Brett Cannone9746892008-04-12 23:44:07 +0000872 else
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000873 bytes_action = "ignore";
Brett Cannone9746892008-04-12 23:44:07 +0000874 PyList_SET_ITEM(filters, 2, create_filter(PyExc_BytesWarning,
875 bytes_action));
876
877 if (PyList_GET_ITEM(filters, 0) == NULL ||
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000878 PyList_GET_ITEM(filters, 1) == NULL ||
879 PyList_GET_ITEM(filters, 2) == NULL) {
880 Py_DECREF(filters);
881 return NULL;
Brett Cannone9746892008-04-12 23:44:07 +0000882 }
883
884 return filters;
885}
886
887
888PyMODINIT_FUNC
889_PyWarnings_Init(void)
890{
891 PyObject *m, *default_action;
892
893 m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);
894 if (m == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000895 return;
Brett Cannone9746892008-04-12 23:44:07 +0000896
897 _filters = init_filters();
898 if (_filters == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000899 return;
Brett Cannone9746892008-04-12 23:44:07 +0000900 Py_INCREF(_filters);
901 if (PyModule_AddObject(m, "filters", _filters) < 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000902 return;
Brett Cannone9746892008-04-12 23:44:07 +0000903
904 _once_registry = PyDict_New();
905 if (_once_registry == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000906 return;
Brett Cannone9746892008-04-12 23:44:07 +0000907 Py_INCREF(_once_registry);
908 if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000909 return;
Brett Cannone9746892008-04-12 23:44:07 +0000910
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000911 default_action = PyString_InternFromString("default");
Brett Cannone9746892008-04-12 23:44:07 +0000912 if (default_action == NULL)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000913 return;
Brett Cannone9746892008-04-12 23:44:07 +0000914 if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0)
Antoine Pitrouc7c96a92010-05-09 15:15:40 +0000915 return;
Brett Cannone9746892008-04-12 23:44:07 +0000916}