blob: 078bdcb0399321ecf43debbddee93ca6027d646d [file] [log] [blame]
Christian Heimes33fe8092008-04-13 13:53:33 +00001#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06002#include "internal/pystate.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00003#include "frameobject.h"
Victor Stinner22f18752016-12-09 18:08:18 +01004#include "clinic/_warnings.c.h"
Christian Heimes33fe8092008-04-13 13:53:33 +00005
6#define MODULE_NAME "_warnings"
Christian Heimes33fe8092008-04-13 13:53:33 +00007
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
Victor Stinnerbd303c12013-11-07 23:07:29 +010012_Py_IDENTIFIER(argv);
13_Py_IDENTIFIER(stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +000014
15static int
16check_matched(PyObject *obj, PyObject *arg)
17{
18 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020019 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +000020 int rc;
21
22 if (obj == Py_None)
23 return 1;
Victor Stinner55ba38a2016-12-09 16:09:30 +010024 result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +000025 if (result == NULL)
26 return -1;
27
28 rc = PyObject_IsTrue(result);
29 Py_DECREF(result);
30 return rc;
31}
32
33/*
34 Returns a new reference.
35 A NULL return value can mean false or an error.
36*/
37static PyObject *
Victor Stinnere98445a2016-03-23 00:54:48 +010038get_warnings_attr(const char *attr, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +000039{
40 static PyObject *warnings_str = NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010041 PyObject *warnings_module, *obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000042
43 if (warnings_str == NULL) {
44 warnings_str = PyUnicode_InternFromString("warnings");
45 if (warnings_str == NULL)
46 return NULL;
47 }
48
Victor Stinnere98445a2016-03-23 00:54:48 +010049 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -060050 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +010051 warnings_module = PyImport_Import(warnings_str);
52 if (warnings_module == NULL) {
53 /* Fallback to the C implementation if we cannot get
54 the Python implementation */
55 PyErr_Clear();
Christian Heimes33fe8092008-04-13 13:53:33 +000056 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010057 }
58 }
59 else {
Eric Snow86b7afd2017-09-04 17:54:09 -060060 warnings_module = _PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +010061 if (warnings_module == NULL)
62 return NULL;
63
Victor Stinnere98445a2016-03-23 00:54:48 +010064 Py_INCREF(warnings_module);
65 }
66
67 if (!PyObject_HasAttrString(warnings_module, attr)) {
68 Py_DECREF(warnings_module);
69 return NULL;
70 }
71
72 obj = PyObject_GetAttrString(warnings_module, attr);
73 Py_DECREF(warnings_module);
74 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000075}
76
77
Neal Norwitz32dde222008-04-15 06:43:13 +000078static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000079get_once_registry(void)
80{
81 PyObject *registry;
82
Victor Stinnere98445a2016-03-23 00:54:48 +010083 registry = get_warnings_attr("onceregistry", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +000084 if (registry == NULL) {
85 if (PyErr_Occurred())
86 return NULL;
Eric Snow2ebc5ce2017-09-07 23:51:28 -060087 return _PyRuntime.warnings.once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +000088 }
Oren Milman252033d2017-09-11 09:28:39 +030089 if (!PyDict_Check(registry)) {
90 PyErr_SetString(PyExc_TypeError,
91 "warnings.onceregistry must be a dict");
92 Py_DECREF(registry);
93 return NULL;
94 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -060095 Py_DECREF(_PyRuntime.warnings.once_registry);
96 _PyRuntime.warnings.once_registry = registry;
Christian Heimes33fe8092008-04-13 13:53:33 +000097 return registry;
98}
99
100
Brett Cannon0759dd62009-04-01 18:13:07 +0000101static PyObject *
102get_default_action(void)
103{
104 PyObject *default_action;
105
Victor Stinnere98445a2016-03-23 00:54:48 +0100106 default_action = get_warnings_attr("defaultaction", 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000107 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 if (PyErr_Occurred()) {
109 return NULL;
110 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600111 return _PyRuntime.warnings.default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000112 }
113
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600114 Py_DECREF(_PyRuntime.warnings.default_action);
115 _PyRuntime.warnings.default_action = default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000116 return default_action;
117}
118
119
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400120/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100121static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000122get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
123 PyObject *module, PyObject **item)
124{
Brett Cannon0759dd62009-04-01 18:13:07 +0000125 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000126 Py_ssize_t i;
127 PyObject *warnings_filters;
128
Victor Stinnere98445a2016-03-23 00:54:48 +0100129 warnings_filters = get_warnings_attr("filters", 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000130 if (warnings_filters == NULL) {
131 if (PyErr_Occurred())
132 return NULL;
133 }
134 else {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600135 Py_DECREF(_PyRuntime.warnings.filters);
136 _PyRuntime.warnings.filters = warnings_filters;
Christian Heimes33fe8092008-04-13 13:53:33 +0000137 }
138
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600139 PyObject *filters = _PyRuntime.warnings.filters;
140 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000141 PyErr_SetString(PyExc_ValueError,
142 MODULE_NAME ".filters must be a list");
143 return NULL;
144 }
145
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600146 /* _PyRuntime.warnings.filters could change while we are iterating over it. */
147 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000148 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
149 Py_ssize_t ln;
150 int is_subclass, good_msg, good_mod;
151
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600152 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400153 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000154 PyErr_Format(PyExc_ValueError,
155 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
156 return NULL;
157 }
158
159 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400160 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000161 action = PyTuple_GET_ITEM(tmp_item, 0);
162 msg = PyTuple_GET_ITEM(tmp_item, 1);
163 cat = PyTuple_GET_ITEM(tmp_item, 2);
164 mod = PyTuple_GET_ITEM(tmp_item, 3);
165 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
166
167 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400168 if (good_msg == -1) {
169 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100170 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400171 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100172
Christian Heimes33fe8092008-04-13 13:53:33 +0000173 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400174 if (good_mod == -1) {
175 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100176 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400177 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100178
Christian Heimes33fe8092008-04-13 13:53:33 +0000179 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400180 if (is_subclass == -1) {
181 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100182 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400183 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100184
Christian Heimes33fe8092008-04-13 13:53:33 +0000185 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400186 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400187 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000188 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400189 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000190
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400191 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
192 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100193 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400194 }
195
196 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000197 }
198
Brett Cannon0759dd62009-04-01 18:13:07 +0000199 action = get_default_action();
200 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400201 Py_INCREF(Py_None);
202 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100203 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000204 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000205
206 PyErr_SetString(PyExc_ValueError,
Brett Cannon0759dd62009-04-01 18:13:07 +0000207 MODULE_NAME ".defaultaction not found");
Christian Heimes33fe8092008-04-13 13:53:33 +0000208 return NULL;
209}
210
Brett Cannon0759dd62009-04-01 18:13:07 +0000211
Christian Heimes33fe8092008-04-13 13:53:33 +0000212static int
213already_warned(PyObject *registry, PyObject *key, int should_set)
214{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200215 PyObject *version_obj, *already_warned;
216 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000217
218 if (key == NULL)
219 return -1;
220
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200221 version_obj = _PyDict_GetItemId(registry, &PyId_version);
222 if (version_obj == NULL
223 || !PyLong_CheckExact(version_obj)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600224 || PyLong_AsLong(version_obj) != _PyRuntime.warnings.filters_version) {
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200225 PyDict_Clear(registry);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600226 version_obj = PyLong_FromLong(_PyRuntime.warnings.filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200227 if (version_obj == NULL)
228 return -1;
229 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
230 Py_DECREF(version_obj);
231 return -1;
232 }
233 Py_DECREF(version_obj);
234 }
235 else {
236 already_warned = PyDict_GetItem(registry, key);
237 if (already_warned != NULL) {
238 int rc = PyObject_IsTrue(already_warned);
239 if (rc != 0)
240 return rc;
241 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000242 }
243
244 /* This warning wasn't found in the registry, set it. */
245 if (should_set)
246 return PyDict_SetItem(registry, key, Py_True);
247 return 0;
248}
249
250/* New reference. */
251static PyObject *
252normalize_module(PyObject *filename)
253{
254 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100255 int kind;
256 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000257 Py_ssize_t len;
258
Victor Stinner9e30aa52011-11-21 02:49:52 +0100259 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000260 if (len < 0)
261 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100262
263 if (len == 0)
264 return PyUnicode_FromString("<unknown>");
265
266 kind = PyUnicode_KIND(filename);
267 data = PyUnicode_DATA(filename);
268
269 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000270 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100271 PyUnicode_READ(kind, data, len-3) == '.' &&
272 PyUnicode_READ(kind, data, len-2) == 'p' &&
273 PyUnicode_READ(kind, data, len-1) == 'y')
274 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100275 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000276 }
277 else {
278 module = filename;
279 Py_INCREF(module);
280 }
281 return module;
282}
283
284static int
285update_registry(PyObject *registry, PyObject *text, PyObject *category,
286 int add_zero)
287{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300288 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000289 int rc;
290
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300291 if (add_zero)
292 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000293 else
294 altkey = PyTuple_Pack(2, text, category);
295
296 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000297 Py_XDECREF(altkey);
298 return rc;
299}
300
301static void
Victor Stinner914cde82016-03-19 01:03:51 +0100302show_warning(PyObject *filename, int lineno, PyObject *text,
303 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 PyObject *f_stderr;
306 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000307 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200308 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000309
310 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
311
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200312 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000313 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100314 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000315
Victor Stinnerbd303c12013-11-07 23:07:29 +0100316 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000317 if (f_stderr == NULL) {
318 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100319 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000320 }
321
322 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100323 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
324 goto error;
325 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
326 goto error;
327 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
328 goto error;
329 if (PyFile_WriteString(": ", f_stderr) < 0)
330 goto error;
331 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
332 goto error;
333 if (PyFile_WriteString("\n", f_stderr) < 0)
334 goto error;
335 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000336
337 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000338 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100339 int kind;
340 void *data;
341 Py_ssize_t i, len;
342 Py_UCS4 ch;
343 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000344
Victor Stinnera4c704b2013-10-29 23:43:41 +0100345 if (PyUnicode_READY(sourceline) < 1)
346 goto error;
347
348 kind = PyUnicode_KIND(sourceline);
349 data = PyUnicode_DATA(sourceline);
350 len = PyUnicode_GET_LENGTH(sourceline);
351 for (i=0; i<len; i++) {
352 ch = PyUnicode_READ(kind, data, i);
353 if (ch != ' ' && ch != '\t' && ch != '\014')
354 break;
355 }
356
357 truncated = PyUnicode_Substring(sourceline, i, len);
358 if (truncated == NULL)
359 goto error;
360
361 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
362 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000363 PyFile_WriteString("\n", f_stderr);
364 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200365 else {
366 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
367 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100368
369error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100370 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000371 PyErr_Clear();
372}
373
Victor Stinner1231a462016-03-19 00:47:17 +0100374static int
375call_show_warning(PyObject *category, PyObject *text, PyObject *message,
376 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100377 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100378{
379 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
380
Victor Stinnere98445a2016-03-23 00:54:48 +0100381 /* If the source parameter is set, try to get the Python implementation.
382 The Python implementation is able to log the traceback where the source
383 was allocated, whereas the C implementation doesnt. */
384 show_fn = get_warnings_attr("_showwarnmsg", source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100385 if (show_fn == NULL) {
386 if (PyErr_Occurred())
387 return -1;
388 show_warning(filename, lineno, text, category, sourceline);
389 return 0;
390 }
391
392 if (!PyCallable_Check(show_fn)) {
393 PyErr_SetString(PyExc_TypeError,
394 "warnings._showwarnmsg() must be set to a callable");
395 goto error;
396 }
397
Victor Stinnere98445a2016-03-23 00:54:48 +0100398 warnmsg_cls = get_warnings_attr("WarningMessage", 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100399 if (warnmsg_cls == NULL) {
400 PyErr_SetString(PyExc_RuntimeError,
401 "unable to get warnings.WarningMessage");
402 goto error;
403 }
404
405 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100406 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100407 NULL);
408 Py_DECREF(warnmsg_cls);
409 if (msg == NULL)
410 goto error;
411
Victor Stinnerde4ae3d2016-12-04 22:59:09 +0100412 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100413 Py_DECREF(show_fn);
414 Py_DECREF(msg);
415
416 if (res == NULL)
417 return -1;
418
419 Py_DECREF(res);
420 return 0;
421
422error:
423 Py_XDECREF(show_fn);
424 return -1;
425}
426
Christian Heimes33fe8092008-04-13 13:53:33 +0000427static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000429 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100430 PyObject *module, PyObject *registry, PyObject *sourceline,
431 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000432{
433 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400434 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100435 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000436 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100438 /* module can be None if a warning is emitted late during Python shutdown.
439 In this case, the Python warnings module was probably unloaded, filters
440 are no more available to choose as action. It is safer to ignore the
441 warning and do nothing. */
442 if (module == Py_None)
443 Py_RETURN_NONE;
444
Brett Cannondb734912008-06-27 00:52:15 +0000445 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300446 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000447 return NULL;
448 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000449
450 /* Normalize module. */
451 if (module == NULL) {
452 module = normalize_module(filename);
453 if (module == NULL)
454 return NULL;
455 }
456 else
457 Py_INCREF(module);
458
459 /* Normalize message. */
460 Py_INCREF(message); /* DECREF'ed in cleanup. */
461 rc = PyObject_IsInstance(message, PyExc_Warning);
462 if (rc == -1) {
463 goto cleanup;
464 }
465 if (rc == 1) {
466 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000467 if (text == NULL)
468 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000469 category = (PyObject*)message->ob_type;
470 }
471 else {
472 text = message;
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100473 message = PyObject_CallFunctionObjArgs(category, message, NULL);
Brett Cannondb734912008-06-27 00:52:15 +0000474 if (message == NULL)
475 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000476 }
477
478 lineno_obj = PyLong_FromLong(lineno);
479 if (lineno_obj == NULL)
480 goto cleanup;
481
Victor Stinner22f18752016-12-09 18:08:18 +0100482 if (source == Py_None) {
483 source = NULL;
484 }
485
Christian Heimes33fe8092008-04-13 13:53:33 +0000486 /* Create key. */
487 key = PyTuple_Pack(3, text, category, lineno_obj);
488 if (key == NULL)
489 goto cleanup;
490
Brett Cannondb734912008-06-27 00:52:15 +0000491 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000492 rc = already_warned(registry, key, 0);
493 if (rc == -1)
494 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000496 goto return_none;
497 /* Else this warning hasn't been generated before. */
498 }
499
500 action = get_filter(category, text, lineno, module, &item);
501 if (action == NULL)
502 goto cleanup;
503
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200504 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000505 PyErr_SetObject(category, message);
506 goto cleanup;
507 }
508
509 /* Store in the registry that we've been here, *except* when the action
510 is "always". */
511 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200512 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000513 if (registry != NULL && registry != Py_None &&
514 PyDict_SetItem(registry, key, Py_True) < 0)
Christian Heimes33fe8092008-04-13 13:53:33 +0000515 goto cleanup;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200516 else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
Christian Heimes33fe8092008-04-13 13:53:33 +0000517 goto return_none;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200518 else if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000519 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000520 registry = get_once_registry();
521 if (registry == NULL)
522 goto cleanup;
523 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600524 /* _PyRuntime.warnings.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000526 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200527 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000528 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000529 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000531 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200532 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000533 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100534 "Unrecognized action (%R) in warnings.filters:\n %R",
535 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000536 goto cleanup;
537 }
538 }
539
Christian Heimes1a8501c2008-10-02 19:56:01 +0000540 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000541 goto return_none;
542 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100543 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100544 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100545 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000546 }
547 else /* if (rc == -1) */
548 goto cleanup;
549
550 return_none:
551 result = Py_None;
552 Py_INCREF(result);
553
554 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400555 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000556 Py_XDECREF(key);
557 Py_XDECREF(text);
558 Py_XDECREF(lineno_obj);
559 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000560 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000561 return result; /* Py_None or NULL. */
562}
563
Larry Hastings714e4932015-09-06 00:39:37 -0700564static int
565is_internal_frame(PyFrameObject *frame)
566{
567 static PyObject *importlib_string = NULL;
568 static PyObject *bootstrap_string = NULL;
569 PyObject *filename;
570 int contains;
571
572 if (importlib_string == NULL) {
573 importlib_string = PyUnicode_FromString("importlib");
574 if (importlib_string == NULL) {
575 return 0;
576 }
577
578 bootstrap_string = PyUnicode_FromString("_bootstrap");
579 if (bootstrap_string == NULL) {
580 Py_DECREF(importlib_string);
581 return 0;
582 }
583 Py_INCREF(importlib_string);
584 Py_INCREF(bootstrap_string);
585 }
586
587 if (frame == NULL || frame->f_code == NULL ||
588 frame->f_code->co_filename == NULL) {
589 return 0;
590 }
591 filename = frame->f_code->co_filename;
592 if (!PyUnicode_Check(filename)) {
593 return 0;
594 }
595 contains = PyUnicode_Contains(filename, importlib_string);
596 if (contains < 0) {
597 return 0;
598 }
599 else if (contains > 0) {
600 contains = PyUnicode_Contains(filename, bootstrap_string);
601 if (contains < 0) {
602 return 0;
603 }
604 else if (contains > 0) {
605 return 1;
606 }
607 }
608
609 return 0;
610}
611
612static PyFrameObject *
613next_external_frame(PyFrameObject *frame)
614{
615 do {
616 frame = frame->f_back;
617 } while (frame != NULL && is_internal_frame(frame));
618
619 return frame;
620}
621
Christian Heimes33fe8092008-04-13 13:53:33 +0000622/* filename, module, and registry are new refs, globals is borrowed */
623/* Returns 0 on error (no new refs), 1 on success */
624static int
625setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
626 PyObject **module, PyObject **registry)
627{
628 PyObject *globals;
629
630 /* Setup globals and lineno. */
631 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700632 // Stack level comparisons to Python code is off by one as there is no
633 // warnings-related stack level to avoid.
634 if (stack_level <= 0 || is_internal_frame(f)) {
635 while (--stack_level > 0 && f != NULL) {
636 f = f->f_back;
637 }
638 }
639 else {
640 while (--stack_level > 0 && f != NULL) {
641 f = next_external_frame(f);
642 }
643 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000644
645 if (f == NULL) {
646 globals = PyThreadState_Get()->interp->sysdict;
647 *lineno = 1;
648 }
649 else {
650 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000651 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000652 }
653
654 *module = NULL;
655
656 /* Setup registry. */
657 assert(globals != NULL);
658 assert(PyDict_Check(globals));
659 *registry = PyDict_GetItemString(globals, "__warningregistry__");
660 if (*registry == NULL) {
661 int rc;
662
663 *registry = PyDict_New();
664 if (*registry == NULL)
665 return 0;
666
667 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
668 if (rc < 0)
669 goto handle_error;
670 }
671 else
672 Py_INCREF(*registry);
673
674 /* Setup module. */
675 *module = PyDict_GetItemString(globals, "__name__");
676 if (*module == NULL) {
677 *module = PyUnicode_FromString("<string>");
678 if (*module == NULL)
679 goto handle_error;
680 }
681 else
682 Py_INCREF(*module);
683
684 /* Setup filename. */
685 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200686 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200687 Py_ssize_t len;
688 int kind;
689 void *data;
690
691 if (PyUnicode_READY(*filename))
692 goto handle_error;
693
Victor Stinner9e30aa52011-11-21 02:49:52 +0100694 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200695 kind = PyUnicode_KIND(*filename);
696 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000697
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500698#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400699 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000700 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200701 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500702 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
703 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400704 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000705 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200706 *filename = PyUnicode_Substring(*filename, 0,
707 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000708 if (*filename == NULL)
709 goto handle_error;
710 }
711 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000712 Py_INCREF(*filename);
713 }
714 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500715 *filename = NULL;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200716 if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100717 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100718 /* PyList_Check() is needed because sys.argv is set to None during
719 Python finalization */
720 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000721 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000722 *filename = PyList_GetItem(argv, 0);
723 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000724 /* If sys.argv[0] is false, then use '__main__'. */
725 is_true = PyObject_IsTrue(*filename);
726 if (is_true < 0) {
727 Py_DECREF(*filename);
728 goto handle_error;
729 }
730 else if (!is_true) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300731 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000732 if (*filename == NULL)
733 goto handle_error;
734 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000735 }
736 else {
737 /* embedded interpreters don't have sys.argv, see bug #839151 */
738 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100739 if (*filename == NULL)
740 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000741 }
742 }
743 if (*filename == NULL) {
744 *filename = *module;
745 Py_INCREF(*filename);
746 }
747 }
748
749 return 1;
750
751 handle_error:
752 /* filename not XDECREF'ed here as there is no way to jump here with a
753 dangling reference. */
754 Py_XDECREF(*registry);
755 Py_XDECREF(*module);
756 return 0;
757}
758
759static PyObject *
760get_category(PyObject *message, PyObject *category)
761{
762 int rc;
763
764 /* Get category. */
765 rc = PyObject_IsInstance(message, PyExc_Warning);
766 if (rc == -1)
767 return NULL;
768
769 if (rc == 1)
770 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300771 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000772 category = PyExc_UserWarning;
773
774 /* Validate category. */
775 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300776 /* category is not a subclass of PyExc_Warning or
777 PyObject_IsSubclass raised an error */
778 if (rc == -1 || rc == 0) {
779 PyErr_Format(PyExc_TypeError,
780 "category must be a Warning subclass, not '%s'",
781 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000782 return NULL;
783 }
784
785 return category;
786}
787
788static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100789do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
790 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000791{
792 PyObject *filename, *module, *registry, *res;
793 int lineno;
794
795 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
796 return NULL;
797
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100798 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100799 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000800 Py_DECREF(filename);
801 Py_DECREF(registry);
802 Py_DECREF(module);
803 return res;
804}
805
Victor Stinner22f18752016-12-09 18:08:18 +0100806/*[clinic input]
807warn as warnings_warn
808
809 message: object
810 category: object = None
811 stacklevel: Py_ssize_t = 1
812 source: object = None
813
814Issue a warning, or maybe ignore it or raise an exception.
815[clinic start generated code]*/
816
Christian Heimes33fe8092008-04-13 13:53:33 +0000817static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100818warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
819 Py_ssize_t stacklevel, PyObject *source)
820/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000821{
Christian Heimes33fe8092008-04-13 13:53:33 +0000822 category = get_category(message, category);
823 if (category == NULL)
824 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100825 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000826}
827
828static PyObject *
829warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
830{
831 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +0100832 "module", "registry", "module_globals",
833 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +0000834 PyObject *message;
835 PyObject *category;
836 PyObject *filename;
837 int lineno;
838 PyObject *module = NULL;
839 PyObject *registry = NULL;
840 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +0100841 PyObject *sourceobj = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000842
Victor Stinner914cde82016-03-19 01:03:51 +0100843 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000844 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +0100845 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +0000846 return NULL;
847
848 if (module_globals) {
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200849 _Py_IDENTIFIER(get_source);
850 _Py_IDENTIFIER(splitlines);
851 PyObject *tmp;
Christian Heimes33fe8092008-04-13 13:53:33 +0000852 PyObject *loader;
853 PyObject *module_name;
854 PyObject *source;
855 PyObject *source_list;
856 PyObject *source_line;
857 PyObject *returned;
858
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200859 if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
860 return NULL;
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200861 if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
862 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +0000863
864 /* Check/get the requisite pieces needed for the loader. */
865 loader = PyDict_GetItemString(module_globals, "__loader__");
866 module_name = PyDict_GetItemString(module_globals, "__name__");
867
868 if (loader == NULL || module_name == NULL)
869 goto standard_call;
870
871 /* Make sure the loader implements the optional get_source() method. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200872 if (!_PyObject_HasAttrId(loader, &PyId_get_source))
Christian Heimes33fe8092008-04-13 13:53:33 +0000873 goto standard_call;
874 /* Call get_source() to get the source code. */
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200875 source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
876 module_name, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000877 if (!source)
878 return NULL;
879 else if (source == Py_None) {
880 Py_DECREF(Py_None);
881 goto standard_call;
882 }
883
884 /* Split the source into lines. */
Victor Stinner9e30aa52011-11-21 02:49:52 +0100885 source_list = PyObject_CallMethodObjArgs(source,
Martin v. Löwis1c67dd92011-10-14 15:16:45 +0200886 PyId_splitlines.object,
887 NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +0000888 Py_DECREF(source);
889 if (!source_list)
890 return NULL;
891
892 /* Get the source line. */
893 source_line = PyList_GetItem(source_list, lineno-1);
894 if (!source_line) {
895 Py_DECREF(source_list);
896 return NULL;
897 }
898
899 /* Handle the warning. */
900 returned = warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100901 registry, source_line, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000902 Py_DECREF(source_list);
903 return returned;
904 }
905
906 standard_call:
907 return warn_explicit(category, message, filename, lineno, module,
Victor Stinner914cde82016-03-19 01:03:51 +0100908 registry, NULL, sourceobj);
Christian Heimes33fe8092008-04-13 13:53:33 +0000909}
910
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200911static PyObject *
912warnings_filters_mutated(PyObject *self, PyObject *args)
913{
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600914 _PyRuntime.warnings.filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200915 Py_RETURN_NONE;
916}
917
Christian Heimes33fe8092008-04-13 13:53:33 +0000918
919/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000920
921static int
922warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +0100923 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000924{
925 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000926
927 if (category == NULL)
928 category = PyExc_RuntimeWarning;
929
Victor Stinner914cde82016-03-19 01:03:51 +0100930 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000931 if (res == NULL)
932 return -1;
933 Py_DECREF(res);
934
935 return 0;
936}
937
Victor Stinner914cde82016-03-19 01:03:51 +0100938static int
939_PyErr_WarnFormatV(PyObject *source,
940 PyObject *category, Py_ssize_t stack_level,
941 const char *format, va_list vargs)
942{
943 PyObject *message;
944 int res;
945
946 message = PyUnicode_FromFormatV(format, vargs);
947 if (message == NULL)
948 return -1;
949
950 res = warn_unicode(category, message, stack_level, source);
951 Py_DECREF(message);
952 return res;
953}
954
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000955int
956PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
957 const char *format, ...)
958{
Victor Stinner914cde82016-03-19 01:03:51 +0100959 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000960 va_list vargs;
961
962#ifdef HAVE_STDARG_PROTOTYPES
963 va_start(vargs, format);
964#else
965 va_start(vargs);
966#endif
Victor Stinner914cde82016-03-19 01:03:51 +0100967 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000968 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +0100969 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000970}
971
972int
Victor Stinner914cde82016-03-19 01:03:51 +0100973PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
974 const char *format, ...)
975{
976 int res;
977 va_list vargs;
978
979#ifdef HAVE_STDARG_PROTOTYPES
980 va_start(vargs, format);
981#else
982 va_start(vargs);
983#endif
984 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
985 stack_level, format, vargs);
986 va_end(vargs);
987 return res;
988}
989
990
991int
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000992PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
993{
994 int ret;
995 PyObject *message = PyUnicode_FromString(text);
996 if (message == NULL)
997 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +0100998 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000999 Py_DECREF(message);
1000 return ret;
1001}
1002
Ezio Melotti42da6632011-03-15 05:18:48 +02001003/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001004 Use PyErr_WarnEx instead. */
1005
1006#undef PyErr_Warn
1007
1008PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001009PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001010{
1011 return PyErr_WarnEx(category, text, 1);
1012}
1013
1014/* Warning with explicit origin */
1015int
Victor Stinner14e461d2013-08-26 22:28:21 +02001016PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1017 PyObject *filename, int lineno,
1018 PyObject *module, PyObject *registry)
1019{
1020 PyObject *res;
1021 if (category == NULL)
1022 category = PyExc_RuntimeWarning;
1023 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001024 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001025 if (res == NULL)
1026 return -1;
1027 Py_DECREF(res);
1028 return 0;
1029}
1030
1031int
Christian Heimes33fe8092008-04-13 13:53:33 +00001032PyErr_WarnExplicit(PyObject *category, const char *text,
1033 const char *filename_str, int lineno,
1034 const char *module_str, PyObject *registry)
1035{
Christian Heimes33fe8092008-04-13 13:53:33 +00001036 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001037 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001038 PyObject *module = NULL;
1039 int ret = -1;
1040
1041 if (message == NULL || filename == NULL)
1042 goto exit;
1043 if (module_str != NULL) {
1044 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001045 if (module == NULL)
1046 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001047 }
1048
Victor Stinner14e461d2013-08-26 22:28:21 +02001049 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1050 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001051
1052 exit:
1053 Py_XDECREF(message);
1054 Py_XDECREF(module);
1055 Py_XDECREF(filename);
1056 return ret;
1057}
1058
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001059int
1060PyErr_WarnExplicitFormat(PyObject *category,
1061 const char *filename_str, int lineno,
1062 const char *module_str, PyObject *registry,
1063 const char *format, ...)
1064{
1065 PyObject *message;
1066 PyObject *module = NULL;
1067 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1068 int ret = -1;
1069 va_list vargs;
1070
1071 if (filename == NULL)
1072 goto exit;
1073 if (module_str != NULL) {
1074 module = PyUnicode_FromString(module_str);
1075 if (module == NULL)
1076 goto exit;
1077 }
1078
1079#ifdef HAVE_STDARG_PROTOTYPES
1080 va_start(vargs, format);
1081#else
1082 va_start(vargs);
1083#endif
1084 message = PyUnicode_FromFormatV(format, vargs);
1085 if (message != NULL) {
1086 PyObject *res;
1087 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001088 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001089 Py_DECREF(message);
1090 if (res != NULL) {
1091 Py_DECREF(res);
1092 ret = 0;
1093 }
1094 }
1095 va_end(vargs);
1096exit:
1097 Py_XDECREF(module);
1098 Py_XDECREF(filename);
1099 return ret;
1100}
1101
Christian Heimes33fe8092008-04-13 13:53:33 +00001102
Christian Heimes33fe8092008-04-13 13:53:33 +00001103PyDoc_STRVAR(warn_explicit_doc,
1104"Low-level inferface to warnings functionality.");
1105
1106static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001107 WARNINGS_WARN_METHODDEF
Christian Heimes33fe8092008-04-13 13:53:33 +00001108 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1109 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001110 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1111 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001112 /* XXX(brett.cannon): add showwarning? */
1113 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001115};
1116
1117
1118static PyObject *
1119create_filter(PyObject *category, const char *action)
1120{
1121 static PyObject *ignore_str = NULL;
1122 static PyObject *error_str = NULL;
1123 static PyObject *default_str = NULL;
Georg Brandl08be72d2010-10-24 15:11:22 +00001124 static PyObject *always_str = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001125 PyObject *action_obj = NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001126
1127 if (!strcmp(action, "ignore")) {
1128 if (ignore_str == NULL) {
1129 ignore_str = PyUnicode_InternFromString("ignore");
1130 if (ignore_str == NULL)
1131 return NULL;
1132 }
1133 action_obj = ignore_str;
1134 }
1135 else if (!strcmp(action, "error")) {
1136 if (error_str == NULL) {
1137 error_str = PyUnicode_InternFromString("error");
1138 if (error_str == NULL)
1139 return NULL;
1140 }
1141 action_obj = error_str;
1142 }
1143 else if (!strcmp(action, "default")) {
1144 if (default_str == NULL) {
1145 default_str = PyUnicode_InternFromString("default");
1146 if (default_str == NULL)
1147 return NULL;
1148 }
1149 action_obj = default_str;
1150 }
Georg Brandl08be72d2010-10-24 15:11:22 +00001151 else if (!strcmp(action, "always")) {
1152 if (always_str == NULL) {
1153 always_str = PyUnicode_InternFromString("always");
1154 if (always_str == NULL)
1155 return NULL;
1156 }
1157 action_obj = always_str;
1158 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001159 else {
1160 Py_FatalError("unknown action");
1161 }
1162
1163 /* This assumes the line number is zero for now. */
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001164 return PyTuple_Pack(5, action_obj, Py_None,
1165 category, Py_None, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +00001166}
1167
1168static PyObject *
1169init_filters(void)
1170{
Georg Brandl08be72d2010-10-24 15:11:22 +00001171 PyObject *filters = PyList_New(5);
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001172 unsigned int pos = 0; /* Post-incremented in each use. */
1173 unsigned int x;
Georg Brandl08be72d2010-10-24 15:11:22 +00001174 const char *bytes_action, *resource_action;
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001175
Christian Heimes33fe8092008-04-13 13:53:33 +00001176 if (filters == NULL)
1177 return NULL;
1178
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001179 PyList_SET_ITEM(filters, pos++,
1180 create_filter(PyExc_DeprecationWarning, "ignore"));
1181 PyList_SET_ITEM(filters, pos++,
Christian Heimes33fe8092008-04-13 13:53:33 +00001182 create_filter(PyExc_PendingDeprecationWarning, "ignore"));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001183 PyList_SET_ITEM(filters, pos++,
1184 create_filter(PyExc_ImportWarning, "ignore"));
Christian Heimes33fe8092008-04-13 13:53:33 +00001185 if (Py_BytesWarningFlag > 1)
1186 bytes_action = "error";
1187 else if (Py_BytesWarningFlag)
1188 bytes_action = "default";
1189 else
1190 bytes_action = "ignore";
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001191 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
Christian Heimes33fe8092008-04-13 13:53:33 +00001192 bytes_action));
Georg Brandl08be72d2010-10-24 15:11:22 +00001193 /* resource usage warnings are enabled by default in pydebug mode */
1194#ifdef Py_DEBUG
1195 resource_action = "always";
1196#else
1197 resource_action = "ignore";
1198#endif
1199 PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1200 resource_action));
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001201 for (x = 0; x < pos; x += 1) {
1202 if (PyList_GET_ITEM(filters, x) == NULL) {
1203 Py_DECREF(filters);
1204 return NULL;
1205 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001206 }
1207
1208 return filters;
1209}
1210
Martin v. Löwis1a214512008-06-11 05:26:20 +00001211static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 PyModuleDef_HEAD_INIT,
1213 MODULE_NAME,
1214 warnings__doc__,
1215 0,
1216 warnings_functions,
1217 NULL,
1218 NULL,
1219 NULL,
1220 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001221};
1222
Christian Heimes33fe8092008-04-13 13:53:33 +00001223
1224PyMODINIT_FUNC
1225_PyWarnings_Init(void)
1226{
Brett Cannon0759dd62009-04-01 18:13:07 +00001227 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001228
Martin v. Löwis1a214512008-06-11 05:26:20 +00001229 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001230 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001231 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001232
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001233 if (_PyRuntime.warnings.filters == NULL) {
1234 _PyRuntime.warnings.filters = init_filters();
1235 if (_PyRuntime.warnings.filters == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001236 return NULL;
1237 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001238 Py_INCREF(_PyRuntime.warnings.filters);
1239 if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001240 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001241
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001242 if (_PyRuntime.warnings.once_registry == NULL) {
1243 _PyRuntime.warnings.once_registry = PyDict_New();
1244 if (_PyRuntime.warnings.once_registry == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001245 return NULL;
1246 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001247 Py_INCREF(_PyRuntime.warnings.once_registry);
1248 if (PyModule_AddObject(m, "_onceregistry",
1249 _PyRuntime.warnings.once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001250 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001251
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001252 if (_PyRuntime.warnings.default_action == NULL) {
1253 _PyRuntime.warnings.default_action = PyUnicode_FromString("default");
1254 if (_PyRuntime.warnings.default_action == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001255 return NULL;
1256 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001257 Py_INCREF(_PyRuntime.warnings.default_action);
1258 if (PyModule_AddObject(m, "_defaultaction",
1259 _PyRuntime.warnings.default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001260 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001261
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001262 _PyRuntime.warnings.filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001263 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001264}