blob: 7b2bdd5462cd32445cc0cb6e81cf788d95a2d8de [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);
Victor Stinner747f48e2017-12-12 22:59:48 +010014#ifndef Py_DEBUG
Victor Stinnerb98f1712017-11-23 17:13:44 +010015_Py_IDENTIFIER(ignore);
Victor Stinner747f48e2017-12-12 22:59:48 +010016#endif
Christian Heimes33fe8092008-04-13 13:53:33 +000017
18static int
19check_matched(PyObject *obj, PyObject *arg)
20{
21 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022 _Py_IDENTIFIER(match);
Christian Heimes33fe8092008-04-13 13:53:33 +000023 int rc;
24
25 if (obj == Py_None)
26 return 1;
Victor Stinner55ba38a2016-12-09 16:09:30 +010027 result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
Christian Heimes33fe8092008-04-13 13:53:33 +000028 if (result == NULL)
29 return -1;
30
31 rc = PyObject_IsTrue(result);
32 Py_DECREF(result);
33 return rc;
34}
35
36/*
37 Returns a new reference.
38 A NULL return value can mean false or an error.
39*/
40static PyObject *
Victor Stinner82656272017-11-22 23:51:42 +010041get_warnings_attr(_Py_Identifier *attr_id, int try_import)
Christian Heimes33fe8092008-04-13 13:53:33 +000042{
Victor Stinner82656272017-11-22 23:51:42 +010043 PyObject *warnings_str;
Victor Stinnere98445a2016-03-23 00:54:48 +010044 PyObject *warnings_module, *obj;
Victor Stinner82656272017-11-22 23:51:42 +010045 _Py_IDENTIFIER(warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +000046
Victor Stinner82656272017-11-22 23:51:42 +010047 warnings_str = _PyUnicode_FromId(&PyId_warnings);
Christian Heimes33fe8092008-04-13 13:53:33 +000048 if (warnings_str == NULL) {
Victor Stinner82656272017-11-22 23:51:42 +010049 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +000050 }
51
Victor Stinnere98445a2016-03-23 00:54:48 +010052 /* don't try to import after the start of the Python finallization */
Eric Snow2ebc5ce2017-09-07 23:51:28 -060053 if (try_import && !_Py_IsFinalizing()) {
Victor Stinnere98445a2016-03-23 00:54:48 +010054 warnings_module = PyImport_Import(warnings_str);
55 if (warnings_module == NULL) {
56 /* Fallback to the C implementation if we cannot get
57 the Python implementation */
Serhiy Storchakad4f84802017-11-11 15:19:47 +020058 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
59 PyErr_Clear();
60 }
Christian Heimes33fe8092008-04-13 13:53:33 +000061 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010062 }
63 }
64 else {
Eric Snow3f9eee62017-09-15 16:35:20 -060065 warnings_module = PyImport_GetModule(warnings_str);
Victor Stinner023654f2016-03-23 17:48:22 +010066 if (warnings_module == NULL)
67 return NULL;
Victor Stinnere98445a2016-03-23 00:54:48 +010068 }
69
Victor Stinner82656272017-11-22 23:51:42 +010070 obj = _PyObject_GetAttrId(warnings_module, attr_id);
Victor Stinnere98445a2016-03-23 00:54:48 +010071 Py_DECREF(warnings_module);
Serhiy Storchakad4f84802017-11-11 15:19:47 +020072 if (obj == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
73 PyErr_Clear();
74 }
Victor Stinnere98445a2016-03-23 00:54:48 +010075 return obj;
Christian Heimes33fe8092008-04-13 13:53:33 +000076}
77
78
Neal Norwitz32dde222008-04-15 06:43:13 +000079static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +000080get_once_registry(void)
81{
82 PyObject *registry;
Victor Stinner82656272017-11-22 23:51:42 +010083 _Py_IDENTIFIER(onceregistry);
Christian Heimes33fe8092008-04-13 13:53:33 +000084
Victor Stinner82656272017-11-22 23:51:42 +010085 registry = get_warnings_attr(&PyId_onceregistry, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +000086 if (registry == NULL) {
87 if (PyErr_Occurred())
88 return NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +020089 assert(_PyRuntime.warnings.once_registry);
Eric Snow2ebc5ce2017-09-07 23:51:28 -060090 return _PyRuntime.warnings.once_registry;
Christian Heimes33fe8092008-04-13 13:53:33 +000091 }
Oren Milman252033d2017-09-11 09:28:39 +030092 if (!PyDict_Check(registry)) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +020093 PyErr_Format(PyExc_TypeError,
94 MODULE_NAME ".onceregistry must be a dict, "
95 "not '%.200s'",
96 Py_TYPE(registry)->tp_name);
Oren Milman252033d2017-09-11 09:28:39 +030097 Py_DECREF(registry);
98 return NULL;
99 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200100 Py_SETREF(_PyRuntime.warnings.once_registry, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +0000101 return registry;
102}
103
104
Brett Cannon0759dd62009-04-01 18:13:07 +0000105static PyObject *
106get_default_action(void)
107{
108 PyObject *default_action;
Victor Stinner82656272017-11-22 23:51:42 +0100109 _Py_IDENTIFIER(defaultaction);
Brett Cannon0759dd62009-04-01 18:13:07 +0000110
Victor Stinner82656272017-11-22 23:51:42 +0100111 default_action = get_warnings_attr(&PyId_defaultaction, 0);
Brett Cannon0759dd62009-04-01 18:13:07 +0000112 if (default_action == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 if (PyErr_Occurred()) {
114 return NULL;
115 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200116 assert(_PyRuntime.warnings.default_action);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600117 return _PyRuntime.warnings.default_action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000118 }
Oren Milman9d984fd2017-09-12 00:18:09 +0300119 if (!PyUnicode_Check(default_action)) {
120 PyErr_Format(PyExc_TypeError,
121 MODULE_NAME ".defaultaction must be a string, "
122 "not '%.200s'",
123 Py_TYPE(default_action)->tp_name);
124 Py_DECREF(default_action);
125 return NULL;
126 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200127 Py_SETREF(_PyRuntime.warnings.default_action, default_action);
Brett Cannon0759dd62009-04-01 18:13:07 +0000128 return default_action;
129}
130
131
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400132/* The item is a new reference. */
Victor Stinnera4c704b2013-10-29 23:43:41 +0100133static PyObject*
Christian Heimes33fe8092008-04-13 13:53:33 +0000134get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
135 PyObject *module, PyObject **item)
136{
Brett Cannon0759dd62009-04-01 18:13:07 +0000137 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000138 Py_ssize_t i;
139 PyObject *warnings_filters;
Victor Stinner82656272017-11-22 23:51:42 +0100140 _Py_IDENTIFIER(filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000141
Victor Stinner82656272017-11-22 23:51:42 +0100142 warnings_filters = get_warnings_attr(&PyId_filters, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000143 if (warnings_filters == NULL) {
144 if (PyErr_Occurred())
145 return NULL;
146 }
147 else {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200148 Py_SETREF(_PyRuntime.warnings.filters, warnings_filters);
Christian Heimes33fe8092008-04-13 13:53:33 +0000149 }
150
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600151 PyObject *filters = _PyRuntime.warnings.filters;
152 if (filters == NULL || !PyList_Check(filters)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000153 PyErr_SetString(PyExc_ValueError,
154 MODULE_NAME ".filters must be a list");
155 return NULL;
156 }
157
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600158 /* _PyRuntime.warnings.filters could change while we are iterating over it. */
159 for (i = 0; i < PyList_GET_SIZE(filters); i++) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000160 PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
161 Py_ssize_t ln;
162 int is_subclass, good_msg, good_mod;
163
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600164 tmp_item = PyList_GET_ITEM(filters, i);
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400165 if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000166 PyErr_Format(PyExc_ValueError,
167 MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
168 return NULL;
169 }
170
171 /* Python code: action, msg, cat, mod, ln = item */
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400172 Py_INCREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000173 action = PyTuple_GET_ITEM(tmp_item, 0);
174 msg = PyTuple_GET_ITEM(tmp_item, 1);
175 cat = PyTuple_GET_ITEM(tmp_item, 2);
176 mod = PyTuple_GET_ITEM(tmp_item, 3);
177 ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
178
Oren Milman9d984fd2017-09-12 00:18:09 +0300179 if (!PyUnicode_Check(action)) {
180 PyErr_Format(PyExc_TypeError,
181 "action must be a string, not '%.200s'",
182 Py_TYPE(action)->tp_name);
183 Py_DECREF(tmp_item);
184 return NULL;
185 }
186
Christian Heimes33fe8092008-04-13 13:53:33 +0000187 good_msg = check_matched(msg, text);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400188 if (good_msg == -1) {
189 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100190 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400191 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100192
Christian Heimes33fe8092008-04-13 13:53:33 +0000193 good_mod = check_matched(mod, module);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400194 if (good_mod == -1) {
195 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100196 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400197 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100198
Christian Heimes33fe8092008-04-13 13:53:33 +0000199 is_subclass = PyObject_IsSubclass(category, cat);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400200 if (is_subclass == -1) {
201 Py_DECREF(tmp_item);
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100202 return NULL;
Benjamin Peterson8c598162015-05-03 11:28:46 -0400203 }
Victor Stinner3cd04aa2013-10-31 14:46:00 +0100204
Christian Heimes33fe8092008-04-13 13:53:33 +0000205 ln = PyLong_AsSsize_t(ln_obj);
Benjamin Peterson8c598162015-05-03 11:28:46 -0400206 if (ln == -1 && PyErr_Occurred()) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400207 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000208 return NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400209 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000210
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400211 if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
212 *item = tmp_item;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100213 return action;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400214 }
215
216 Py_DECREF(tmp_item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000217 }
218
Brett Cannon0759dd62009-04-01 18:13:07 +0000219 action = get_default_action();
220 if (action != NULL) {
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400221 Py_INCREF(Py_None);
222 *item = Py_None;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100223 return action;
Brett Cannon0759dd62009-04-01 18:13:07 +0000224 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000225
Christian Heimes33fe8092008-04-13 13:53:33 +0000226 return NULL;
227}
228
Brett Cannon0759dd62009-04-01 18:13:07 +0000229
Christian Heimes33fe8092008-04-13 13:53:33 +0000230static int
231already_warned(PyObject *registry, PyObject *key, int should_set)
232{
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200233 PyObject *version_obj, *already_warned;
234 _Py_IDENTIFIER(version);
Christian Heimes33fe8092008-04-13 13:53:33 +0000235
236 if (key == NULL)
237 return -1;
238
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200239 version_obj = _PyDict_GetItemId(registry, &PyId_version);
240 if (version_obj == NULL
241 || !PyLong_CheckExact(version_obj)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600242 || PyLong_AsLong(version_obj) != _PyRuntime.warnings.filters_version) {
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200243 PyDict_Clear(registry);
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600244 version_obj = PyLong_FromLong(_PyRuntime.warnings.filters_version);
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200245 if (version_obj == NULL)
246 return -1;
247 if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
248 Py_DECREF(version_obj);
249 return -1;
250 }
251 Py_DECREF(version_obj);
252 }
253 else {
254 already_warned = PyDict_GetItem(registry, key);
255 if (already_warned != NULL) {
256 int rc = PyObject_IsTrue(already_warned);
257 if (rc != 0)
258 return rc;
259 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000260 }
261
262 /* This warning wasn't found in the registry, set it. */
263 if (should_set)
264 return PyDict_SetItem(registry, key, Py_True);
265 return 0;
266}
267
268/* New reference. */
269static PyObject *
270normalize_module(PyObject *filename)
271{
272 PyObject *module;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100273 int kind;
274 void *data;
Christian Heimes33fe8092008-04-13 13:53:33 +0000275 Py_ssize_t len;
276
Victor Stinner9e30aa52011-11-21 02:49:52 +0100277 len = PyUnicode_GetLength(filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000278 if (len < 0)
279 return NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100280
281 if (len == 0)
282 return PyUnicode_FromString("<unknown>");
283
284 kind = PyUnicode_KIND(filename);
285 data = PyUnicode_DATA(filename);
286
287 /* if filename.endswith(".py"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000288 if (len >= 3 &&
Victor Stinnera4c704b2013-10-29 23:43:41 +0100289 PyUnicode_READ(kind, data, len-3) == '.' &&
290 PyUnicode_READ(kind, data, len-2) == 'p' &&
291 PyUnicode_READ(kind, data, len-1) == 'y')
292 {
Victor Stinner9e30aa52011-11-21 02:49:52 +0100293 module = PyUnicode_Substring(filename, 0, len-3);
Christian Heimes33fe8092008-04-13 13:53:33 +0000294 }
295 else {
296 module = filename;
297 Py_INCREF(module);
298 }
299 return module;
300}
301
302static int
303update_registry(PyObject *registry, PyObject *text, PyObject *category,
304 int add_zero)
305{
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300306 PyObject *altkey;
Christian Heimes33fe8092008-04-13 13:53:33 +0000307 int rc;
308
Serhiy Storchakaba85d692017-03-30 09:09:41 +0300309 if (add_zero)
310 altkey = PyTuple_Pack(3, text, category, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +0000311 else
312 altkey = PyTuple_Pack(2, text, category);
313
314 rc = already_warned(registry, altkey, 1);
Christian Heimes33fe8092008-04-13 13:53:33 +0000315 Py_XDECREF(altkey);
316 return rc;
317}
318
319static void
Victor Stinner914cde82016-03-19 01:03:51 +0100320show_warning(PyObject *filename, int lineno, PyObject *text,
321 PyObject *category, PyObject *sourceline)
Christian Heimes33fe8092008-04-13 13:53:33 +0000322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 PyObject *f_stderr;
324 PyObject *name;
Christian Heimes33fe8092008-04-13 13:53:33 +0000325 char lineno_str[128];
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200326 _Py_IDENTIFIER(__name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000327
328 PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
329
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200330 name = _PyObject_GetAttrId(category, &PyId___name__);
Christian Heimes33fe8092008-04-13 13:53:33 +0000331 if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100332 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000333
Victor Stinnerbd303c12013-11-07 23:07:29 +0100334 f_stderr = _PySys_GetObjectId(&PyId_stderr);
Christian Heimes33fe8092008-04-13 13:53:33 +0000335 if (f_stderr == NULL) {
336 fprintf(stderr, "lost sys.stderr\n");
Victor Stinnerae233ea2013-10-31 14:51:38 +0100337 goto error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000338 }
339
340 /* Print "filename:lineno: category: text\n" */
Victor Stinnerae233ea2013-10-31 14:51:38 +0100341 if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
342 goto error;
343 if (PyFile_WriteString(lineno_str, f_stderr) < 0)
344 goto error;
345 if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
346 goto error;
347 if (PyFile_WriteString(": ", f_stderr) < 0)
348 goto error;
349 if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
350 goto error;
351 if (PyFile_WriteString("\n", f_stderr) < 0)
352 goto error;
353 Py_CLEAR(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000354
355 /* Print " source_line\n" */
Christian Heimes33fe8092008-04-13 13:53:33 +0000356 if (sourceline) {
Victor Stinnera4c704b2013-10-29 23:43:41 +0100357 int kind;
358 void *data;
359 Py_ssize_t i, len;
360 Py_UCS4 ch;
361 PyObject *truncated;
Christian Heimes33fe8092008-04-13 13:53:33 +0000362
Victor Stinnera4c704b2013-10-29 23:43:41 +0100363 if (PyUnicode_READY(sourceline) < 1)
364 goto error;
365
366 kind = PyUnicode_KIND(sourceline);
367 data = PyUnicode_DATA(sourceline);
368 len = PyUnicode_GET_LENGTH(sourceline);
369 for (i=0; i<len; i++) {
370 ch = PyUnicode_READ(kind, data, i);
371 if (ch != ' ' && ch != '\t' && ch != '\014')
372 break;
373 }
374
375 truncated = PyUnicode_Substring(sourceline, i, len);
376 if (truncated == NULL)
377 goto error;
378
379 PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
380 Py_DECREF(truncated);
Christian Heimes33fe8092008-04-13 13:53:33 +0000381 PyFile_WriteString("\n", f_stderr);
382 }
Victor Stinner78e2c982013-07-16 01:54:37 +0200383 else {
384 _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
385 }
Victor Stinnera4c704b2013-10-29 23:43:41 +0100386
387error:
Victor Stinnerae233ea2013-10-31 14:51:38 +0100388 Py_XDECREF(name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000389 PyErr_Clear();
390}
391
Victor Stinner1231a462016-03-19 00:47:17 +0100392static int
393call_show_warning(PyObject *category, PyObject *text, PyObject *message,
394 PyObject *filename, int lineno, PyObject *lineno_obj,
Victor Stinner914cde82016-03-19 01:03:51 +0100395 PyObject *sourceline, PyObject *source)
Victor Stinner1231a462016-03-19 00:47:17 +0100396{
397 PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
Victor Stinner82656272017-11-22 23:51:42 +0100398 _Py_IDENTIFIER(_showwarnmsg);
399 _Py_IDENTIFIER(WarningMessage);
Victor Stinner1231a462016-03-19 00:47:17 +0100400
Victor Stinnere98445a2016-03-23 00:54:48 +0100401 /* If the source parameter is set, try to get the Python implementation.
402 The Python implementation is able to log the traceback where the source
luzpaza5293b42017-11-05 07:37:50 -0600403 was allocated, whereas the C implementation doesn't. */
Victor Stinner82656272017-11-22 23:51:42 +0100404 show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100405 if (show_fn == NULL) {
406 if (PyErr_Occurred())
407 return -1;
408 show_warning(filename, lineno, text, category, sourceline);
409 return 0;
410 }
411
412 if (!PyCallable_Check(show_fn)) {
413 PyErr_SetString(PyExc_TypeError,
414 "warnings._showwarnmsg() must be set to a callable");
415 goto error;
416 }
417
Victor Stinner82656272017-11-22 23:51:42 +0100418 warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0);
Victor Stinner1231a462016-03-19 00:47:17 +0100419 if (warnmsg_cls == NULL) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200420 if (!PyErr_Occurred()) {
421 PyErr_SetString(PyExc_RuntimeError,
422 "unable to get warnings.WarningMessage");
423 }
Victor Stinner1231a462016-03-19 00:47:17 +0100424 goto error;
425 }
426
427 msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
Victor Stinner914cde82016-03-19 01:03:51 +0100428 filename, lineno_obj, Py_None, Py_None, source,
Victor Stinner1231a462016-03-19 00:47:17 +0100429 NULL);
430 Py_DECREF(warnmsg_cls);
431 if (msg == NULL)
432 goto error;
433
Victor Stinnerde4ae3d2016-12-04 22:59:09 +0100434 res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
Victor Stinner1231a462016-03-19 00:47:17 +0100435 Py_DECREF(show_fn);
436 Py_DECREF(msg);
437
438 if (res == NULL)
439 return -1;
440
441 Py_DECREF(res);
442 return 0;
443
444error:
445 Py_XDECREF(show_fn);
446 return -1;
447}
448
Christian Heimes33fe8092008-04-13 13:53:33 +0000449static PyObject *
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450warn_explicit(PyObject *category, PyObject *message,
Christian Heimes33fe8092008-04-13 13:53:33 +0000451 PyObject *filename, int lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100452 PyObject *module, PyObject *registry, PyObject *sourceline,
453 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000454{
455 PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400456 PyObject *item = NULL;
Victor Stinnera4c704b2013-10-29 23:43:41 +0100457 PyObject *action;
Christian Heimes33fe8092008-04-13 13:53:33 +0000458 int rc;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100460 /* module can be None if a warning is emitted late during Python shutdown.
461 In this case, the Python warnings module was probably unloaded, filters
462 are no more available to choose as action. It is safer to ignore the
463 warning and do nothing. */
464 if (module == Py_None)
465 Py_RETURN_NONE;
466
Brett Cannondb734912008-06-27 00:52:15 +0000467 if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
Oren Milman252033d2017-09-11 09:28:39 +0300468 PyErr_SetString(PyExc_TypeError, "'registry' must be a dict or None");
Brett Cannondb734912008-06-27 00:52:15 +0000469 return NULL;
470 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000471
472 /* Normalize module. */
473 if (module == NULL) {
474 module = normalize_module(filename);
475 if (module == NULL)
476 return NULL;
477 }
478 else
479 Py_INCREF(module);
480
481 /* Normalize message. */
482 Py_INCREF(message); /* DECREF'ed in cleanup. */
483 rc = PyObject_IsInstance(message, PyExc_Warning);
484 if (rc == -1) {
485 goto cleanup;
486 }
487 if (rc == 1) {
488 text = PyObject_Str(message);
Hirokazu Yamamoto1c0c0032009-07-17 06:55:42 +0000489 if (text == NULL)
490 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000491 category = (PyObject*)message->ob_type;
492 }
493 else {
494 text = message;
Victor Stinner7bfb42d2016-12-05 17:04:32 +0100495 message = PyObject_CallFunctionObjArgs(category, message, NULL);
Brett Cannondb734912008-06-27 00:52:15 +0000496 if (message == NULL)
497 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000498 }
499
500 lineno_obj = PyLong_FromLong(lineno);
501 if (lineno_obj == NULL)
502 goto cleanup;
503
Victor Stinner22f18752016-12-09 18:08:18 +0100504 if (source == Py_None) {
505 source = NULL;
506 }
507
Christian Heimes33fe8092008-04-13 13:53:33 +0000508 /* Create key. */
509 key = PyTuple_Pack(3, text, category, lineno_obj);
510 if (key == NULL)
511 goto cleanup;
512
Brett Cannondb734912008-06-27 00:52:15 +0000513 if ((registry != NULL) && (registry != Py_None)) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000514 rc = already_warned(registry, key, 0);
515 if (rc == -1)
516 goto cleanup;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 else if (rc == 1)
Christian Heimes33fe8092008-04-13 13:53:33 +0000518 goto return_none;
519 /* Else this warning hasn't been generated before. */
520 }
521
522 action = get_filter(category, text, lineno, module, &item);
523 if (action == NULL)
524 goto cleanup;
525
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200526 if (_PyUnicode_EqualToASCIIString(action, "error")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000527 PyErr_SetObject(category, message);
528 goto cleanup;
529 }
530
Victor Stinnerc9758782017-11-27 16:57:07 +0100531 if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
532 goto return_none;
533 }
534
Christian Heimes33fe8092008-04-13 13:53:33 +0000535 /* Store in the registry that we've been here, *except* when the action
536 is "always". */
537 rc = 0;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200538 if (!_PyUnicode_EqualToASCIIString(action, "always")) {
Brett Cannondb734912008-06-27 00:52:15 +0000539 if (registry != NULL && registry != Py_None &&
Victor Stinnerc9758782017-11-27 16:57:07 +0100540 PyDict_SetItem(registry, key, Py_True) < 0)
541 {
Christian Heimes33fe8092008-04-13 13:53:33 +0000542 goto cleanup;
Victor Stinnerc9758782017-11-27 16:57:07 +0100543 }
544
545 if (_PyUnicode_EqualToASCIIString(action, "once")) {
Brett Cannondb734912008-06-27 00:52:15 +0000546 if (registry == NULL || registry == Py_None) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000547 registry = get_once_registry();
548 if (registry == NULL)
549 goto cleanup;
550 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600551 /* _PyRuntime.warnings.once_registry[(text, category)] = 1 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000553 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200554 else if (_PyUnicode_EqualToASCIIString(action, "module")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000555 /* registry[(text, category, 0)] = 1 */
Brett Cannondb734912008-06-27 00:52:15 +0000556 if (registry != NULL && registry != Py_None)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 rc = update_registry(registry, text, category, 0);
Christian Heimes33fe8092008-04-13 13:53:33 +0000558 }
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200559 else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000560 PyErr_Format(PyExc_RuntimeError,
Victor Stinnera4c704b2013-10-29 23:43:41 +0100561 "Unrecognized action (%R) in warnings.filters:\n %R",
562 action, item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000563 goto cleanup;
564 }
565 }
566
Christian Heimes1a8501c2008-10-02 19:56:01 +0000567 if (rc == 1) /* Already warned for this module. */
Christian Heimes33fe8092008-04-13 13:53:33 +0000568 goto return_none;
569 if (rc == 0) {
Victor Stinner1231a462016-03-19 00:47:17 +0100570 if (call_show_warning(category, text, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +0100571 lineno_obj, sourceline, source) < 0)
Victor Stinner1231a462016-03-19 00:47:17 +0100572 goto cleanup;
Christian Heimes33fe8092008-04-13 13:53:33 +0000573 }
574 else /* if (rc == -1) */
575 goto cleanup;
576
577 return_none:
578 result = Py_None;
579 Py_INCREF(result);
580
581 cleanup:
Benjamin Petersondeff2b72015-05-03 11:23:37 -0400582 Py_XDECREF(item);
Christian Heimes33fe8092008-04-13 13:53:33 +0000583 Py_XDECREF(key);
584 Py_XDECREF(text);
585 Py_XDECREF(lineno_obj);
586 Py_DECREF(module);
Brett Cannondb734912008-06-27 00:52:15 +0000587 Py_XDECREF(message);
Christian Heimes33fe8092008-04-13 13:53:33 +0000588 return result; /* Py_None or NULL. */
589}
590
Larry Hastings714e4932015-09-06 00:39:37 -0700591static int
592is_internal_frame(PyFrameObject *frame)
593{
594 static PyObject *importlib_string = NULL;
595 static PyObject *bootstrap_string = NULL;
596 PyObject *filename;
597 int contains;
598
599 if (importlib_string == NULL) {
600 importlib_string = PyUnicode_FromString("importlib");
601 if (importlib_string == NULL) {
602 return 0;
603 }
604
605 bootstrap_string = PyUnicode_FromString("_bootstrap");
606 if (bootstrap_string == NULL) {
607 Py_DECREF(importlib_string);
608 return 0;
609 }
610 Py_INCREF(importlib_string);
611 Py_INCREF(bootstrap_string);
612 }
613
614 if (frame == NULL || frame->f_code == NULL ||
615 frame->f_code->co_filename == NULL) {
616 return 0;
617 }
618 filename = frame->f_code->co_filename;
619 if (!PyUnicode_Check(filename)) {
620 return 0;
621 }
622 contains = PyUnicode_Contains(filename, importlib_string);
623 if (contains < 0) {
624 return 0;
625 }
626 else if (contains > 0) {
627 contains = PyUnicode_Contains(filename, bootstrap_string);
628 if (contains < 0) {
629 return 0;
630 }
631 else if (contains > 0) {
632 return 1;
633 }
634 }
635
636 return 0;
637}
638
639static PyFrameObject *
640next_external_frame(PyFrameObject *frame)
641{
642 do {
643 frame = frame->f_back;
644 } while (frame != NULL && is_internal_frame(frame));
645
646 return frame;
647}
648
Christian Heimes33fe8092008-04-13 13:53:33 +0000649/* filename, module, and registry are new refs, globals is borrowed */
650/* Returns 0 on error (no new refs), 1 on success */
651static int
652setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
653 PyObject **module, PyObject **registry)
654{
655 PyObject *globals;
656
657 /* Setup globals and lineno. */
658 PyFrameObject *f = PyThreadState_GET()->frame;
Larry Hastings714e4932015-09-06 00:39:37 -0700659 // Stack level comparisons to Python code is off by one as there is no
660 // warnings-related stack level to avoid.
661 if (stack_level <= 0 || is_internal_frame(f)) {
662 while (--stack_level > 0 && f != NULL) {
663 f = f->f_back;
664 }
665 }
666 else {
667 while (--stack_level > 0 && f != NULL) {
668 f = next_external_frame(f);
669 }
670 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000671
672 if (f == NULL) {
673 globals = PyThreadState_Get()->interp->sysdict;
674 *lineno = 1;
675 }
676 else {
677 globals = f->f_globals;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000678 *lineno = PyFrame_GetLineNumber(f);
Christian Heimes33fe8092008-04-13 13:53:33 +0000679 }
680
681 *module = NULL;
682
683 /* Setup registry. */
684 assert(globals != NULL);
685 assert(PyDict_Check(globals));
686 *registry = PyDict_GetItemString(globals, "__warningregistry__");
687 if (*registry == NULL) {
688 int rc;
689
690 *registry = PyDict_New();
691 if (*registry == NULL)
692 return 0;
693
694 rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
695 if (rc < 0)
696 goto handle_error;
697 }
698 else
699 Py_INCREF(*registry);
700
701 /* Setup module. */
702 *module = PyDict_GetItemString(globals, "__name__");
Oren Milman5d3e8002017-09-24 21:28:42 +0300703 if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
704 Py_INCREF(*module);
705 }
706 else {
Christian Heimes33fe8092008-04-13 13:53:33 +0000707 *module = PyUnicode_FromString("<string>");
708 if (*module == NULL)
709 goto handle_error;
710 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000711
712 /* Setup filename. */
713 *filename = PyDict_GetItemString(globals, "__file__");
Victor Stinner8b0508e2011-07-04 02:43:09 +0200714 if (*filename != NULL && PyUnicode_Check(*filename)) {
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200715 Py_ssize_t len;
716 int kind;
717 void *data;
718
719 if (PyUnicode_READY(*filename))
720 goto handle_error;
721
Victor Stinner9e30aa52011-11-21 02:49:52 +0100722 len = PyUnicode_GetLength(*filename);
Victor Stinnerb62a7b22011-10-06 02:34:51 +0200723 kind = PyUnicode_KIND(*filename);
724 data = PyUnicode_DATA(*filename);
Christian Heimes33fe8092008-04-13 13:53:33 +0000725
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500726#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
Brett Cannonf299abd2015-04-13 14:21:02 -0400727 /* if filename.lower().endswith(".pyc"): */
Christian Heimes33fe8092008-04-13 13:53:33 +0000728 if (len >= 4 &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200729 PyUnicode_READ(kind, data, len-4) == '.' &&
Benjamin Peterson21e0da22012-01-11 21:00:42 -0500730 ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
731 ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
Brett Cannonf299abd2015-04-13 14:21:02 -0400732 ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000733 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200734 *filename = PyUnicode_Substring(*filename, 0,
735 PyUnicode_GET_LENGTH(*filename)-1);
Victor Stinner2e5f1172010-08-08 22:12:45 +0000736 if (*filename == NULL)
737 goto handle_error;
738 }
739 else
Christian Heimes33fe8092008-04-13 13:53:33 +0000740 Py_INCREF(*filename);
741 }
742 else {
Benjamin Petersonbb4a7472011-07-04 22:27:16 -0500743 *filename = NULL;
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +0200744 if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
Victor Stinnerbd303c12013-11-07 23:07:29 +0100745 PyObject *argv = _PySys_GetObjectId(&PyId_argv);
Victor Stinnerce5f4fb2013-10-28 18:47:22 +0100746 /* PyList_Check() is needed because sys.argv is set to None during
747 Python finalization */
748 if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000749 int is_true;
Christian Heimes33fe8092008-04-13 13:53:33 +0000750 *filename = PyList_GetItem(argv, 0);
751 Py_INCREF(*filename);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000752 /* If sys.argv[0] is false, then use '__main__'. */
753 is_true = PyObject_IsTrue(*filename);
754 if (is_true < 0) {
755 Py_DECREF(*filename);
756 goto handle_error;
757 }
758 else if (!is_true) {
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300759 Py_SETREF(*filename, PyUnicode_FromString("__main__"));
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000760 if (*filename == NULL)
761 goto handle_error;
762 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000763 }
764 else {
765 /* embedded interpreters don't have sys.argv, see bug #839151 */
766 *filename = PyUnicode_FromString("__main__");
Victor Stinner856f45f2013-10-30 00:04:59 +0100767 if (*filename == NULL)
768 goto handle_error;
Christian Heimes33fe8092008-04-13 13:53:33 +0000769 }
770 }
771 if (*filename == NULL) {
772 *filename = *module;
773 Py_INCREF(*filename);
774 }
775 }
776
777 return 1;
778
779 handle_error:
780 /* filename not XDECREF'ed here as there is no way to jump here with a
781 dangling reference. */
782 Py_XDECREF(*registry);
783 Py_XDECREF(*module);
784 return 0;
785}
786
787static PyObject *
788get_category(PyObject *message, PyObject *category)
789{
790 int rc;
791
792 /* Get category. */
793 rc = PyObject_IsInstance(message, PyExc_Warning);
794 if (rc == -1)
795 return NULL;
796
797 if (rc == 1)
798 category = (PyObject*)message->ob_type;
Berker Peksagd8089e02014-07-11 19:50:25 +0300799 else if (category == NULL || category == Py_None)
Christian Heimes33fe8092008-04-13 13:53:33 +0000800 category = PyExc_UserWarning;
801
802 /* Validate category. */
803 rc = PyObject_IsSubclass(category, PyExc_Warning);
Berker Peksagd8089e02014-07-11 19:50:25 +0300804 /* category is not a subclass of PyExc_Warning or
805 PyObject_IsSubclass raised an error */
806 if (rc == -1 || rc == 0) {
807 PyErr_Format(PyExc_TypeError,
808 "category must be a Warning subclass, not '%s'",
809 Py_TYPE(category)->tp_name);
Christian Heimes33fe8092008-04-13 13:53:33 +0000810 return NULL;
811 }
812
813 return category;
814}
815
816static PyObject *
Victor Stinner914cde82016-03-19 01:03:51 +0100817do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
818 PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000819{
820 PyObject *filename, *module, *registry, *res;
821 int lineno;
822
823 if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
824 return NULL;
825
Victor Stinnerdcdd05b2013-11-01 00:55:30 +0100826 res = warn_explicit(category, message, filename, lineno, module, registry,
Victor Stinner914cde82016-03-19 01:03:51 +0100827 NULL, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000828 Py_DECREF(filename);
829 Py_DECREF(registry);
830 Py_DECREF(module);
831 return res;
832}
833
Victor Stinner22f18752016-12-09 18:08:18 +0100834/*[clinic input]
835warn as warnings_warn
836
837 message: object
838 category: object = None
839 stacklevel: Py_ssize_t = 1
840 source: object = None
841
842Issue a warning, or maybe ignore it or raise an exception.
843[clinic start generated code]*/
844
Christian Heimes33fe8092008-04-13 13:53:33 +0000845static PyObject *
Victor Stinner22f18752016-12-09 18:08:18 +0100846warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
847 Py_ssize_t stacklevel, PyObject *source)
848/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
Christian Heimes33fe8092008-04-13 13:53:33 +0000849{
Christian Heimes33fe8092008-04-13 13:53:33 +0000850 category = get_category(message, category);
851 if (category == NULL)
852 return NULL;
Victor Stinner22f18752016-12-09 18:08:18 +0100853 return do_warn(message, category, stacklevel, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000854}
855
856static PyObject *
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200857get_source_line(PyObject *module_globals, int lineno)
858{
859 _Py_IDENTIFIER(get_source);
860 _Py_IDENTIFIER(__loader__);
861 _Py_IDENTIFIER(__name__);
862 PyObject *loader;
863 PyObject *module_name;
864 PyObject *get_source;
865 PyObject *source;
866 PyObject *source_list;
867 PyObject *source_line;
868
869 /* Check/get the requisite pieces needed for the loader. */
870 loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
871 if (loader == NULL) {
872 return NULL;
873 }
874 Py_INCREF(loader);
875 module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
876 if (!module_name) {
877 Py_DECREF(loader);
878 return NULL;
879 }
880 Py_INCREF(module_name);
881
882 /* Make sure the loader implements the optional get_source() method. */
883 get_source = _PyObject_GetAttrId(loader, &PyId_get_source);
884 Py_DECREF(loader);
885 if (!get_source) {
886 Py_DECREF(module_name);
887 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
888 PyErr_Clear();
889 }
890 return NULL;
891 }
892 /* Call get_source() to get the source code. */
893 source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
894 Py_DECREF(get_source);
895 Py_DECREF(module_name);
896 if (!source) {
897 return NULL;
898 }
899 if (source == Py_None) {
900 Py_DECREF(source);
901 return NULL;
902 }
903
904 /* Split the source into lines. */
905 source_list = PyUnicode_Splitlines(source, 0);
906 Py_DECREF(source);
907 if (!source_list) {
908 return NULL;
909 }
910
911 /* Get the source line. */
912 source_line = PyList_GetItem(source_list, lineno-1);
913 Py_XINCREF(source_line);
914 Py_DECREF(source_list);
915 return source_line;
916}
917
918static PyObject *
Christian Heimes33fe8092008-04-13 13:53:33 +0000919warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
920{
921 static char *kwd_list[] = {"message", "category", "filename", "lineno",
Victor Stinner914cde82016-03-19 01:03:51 +0100922 "module", "registry", "module_globals",
923 "source", 0};
Christian Heimes33fe8092008-04-13 13:53:33 +0000924 PyObject *message;
925 PyObject *category;
926 PyObject *filename;
927 int lineno;
928 PyObject *module = NULL;
929 PyObject *registry = NULL;
930 PyObject *module_globals = NULL;
Victor Stinner914cde82016-03-19 01:03:51 +0100931 PyObject *sourceobj = NULL;
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200932 PyObject *source_line = NULL;
933 PyObject *returned;
Christian Heimes33fe8092008-04-13 13:53:33 +0000934
Victor Stinner914cde82016-03-19 01:03:51 +0100935 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
Christian Heimes33fe8092008-04-13 13:53:33 +0000936 kwd_list, &message, &category, &filename, &lineno, &module,
Victor Stinner914cde82016-03-19 01:03:51 +0100937 &registry, &module_globals, &sourceobj))
Christian Heimes33fe8092008-04-13 13:53:33 +0000938 return NULL;
939
940 if (module_globals) {
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200941 source_line = get_source_line(module_globals, lineno);
942 if (source_line == NULL && PyErr_Occurred()) {
Christian Heimes33fe8092008-04-13 13:53:33 +0000943 return NULL;
944 }
Christian Heimes33fe8092008-04-13 13:53:33 +0000945 }
Serhiy Storchakad4f84802017-11-11 15:19:47 +0200946 returned = warn_explicit(category, message, filename, lineno, module,
947 registry, source_line, sourceobj);
948 Py_XDECREF(source_line);
949 return returned;
Christian Heimes33fe8092008-04-13 13:53:33 +0000950}
951
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200952static PyObject *
953warnings_filters_mutated(PyObject *self, PyObject *args)
954{
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600955 _PyRuntime.warnings.filters_version++;
Antoine Pitroucb0a0062014-09-18 02:40:46 +0200956 Py_RETURN_NONE;
957}
958
Christian Heimes33fe8092008-04-13 13:53:33 +0000959
960/* Function to issue a warning message; may raise an exception. */
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000961
962static int
963warn_unicode(PyObject *category, PyObject *message,
Victor Stinner914cde82016-03-19 01:03:51 +0100964 Py_ssize_t stack_level, PyObject *source)
Christian Heimes33fe8092008-04-13 13:53:33 +0000965{
966 PyObject *res;
Christian Heimes33fe8092008-04-13 13:53:33 +0000967
968 if (category == NULL)
969 category = PyExc_RuntimeWarning;
970
Victor Stinner914cde82016-03-19 01:03:51 +0100971 res = do_warn(message, category, stack_level, source);
Christian Heimes33fe8092008-04-13 13:53:33 +0000972 if (res == NULL)
973 return -1;
974 Py_DECREF(res);
975
976 return 0;
977}
978
Victor Stinner914cde82016-03-19 01:03:51 +0100979static int
980_PyErr_WarnFormatV(PyObject *source,
981 PyObject *category, Py_ssize_t stack_level,
982 const char *format, va_list vargs)
983{
984 PyObject *message;
985 int res;
986
987 message = PyUnicode_FromFormatV(format, vargs);
988 if (message == NULL)
989 return -1;
990
991 res = warn_unicode(category, message, stack_level, source);
992 Py_DECREF(message);
993 return res;
994}
995
Victor Stinner4a2b7a12010-08-13 14:03:48 +0000996int
997PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
998 const char *format, ...)
999{
Victor Stinner914cde82016-03-19 01:03:51 +01001000 int res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001001 va_list vargs;
1002
1003#ifdef HAVE_STDARG_PROTOTYPES
1004 va_start(vargs, format);
1005#else
1006 va_start(vargs);
1007#endif
Victor Stinner914cde82016-03-19 01:03:51 +01001008 res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001009 va_end(vargs);
Victor Stinner914cde82016-03-19 01:03:51 +01001010 return res;
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001011}
1012
1013int
Victor Stinner914cde82016-03-19 01:03:51 +01001014PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
1015 const char *format, ...)
1016{
1017 int res;
1018 va_list vargs;
1019
1020#ifdef HAVE_STDARG_PROTOTYPES
1021 va_start(vargs, format);
1022#else
1023 va_start(vargs);
1024#endif
1025 res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
1026 stack_level, format, vargs);
1027 va_end(vargs);
1028 return res;
1029}
1030
1031
1032int
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001033PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1034{
1035 int ret;
1036 PyObject *message = PyUnicode_FromString(text);
1037 if (message == NULL)
1038 return -1;
Victor Stinner914cde82016-03-19 01:03:51 +01001039 ret = warn_unicode(category, message, stack_level, NULL);
Victor Stinner4a2b7a12010-08-13 14:03:48 +00001040 Py_DECREF(message);
1041 return ret;
1042}
1043
Ezio Melotti42da6632011-03-15 05:18:48 +02001044/* PyErr_Warn is only for backwards compatibility and will be removed.
Christian Heimes33fe8092008-04-13 13:53:33 +00001045 Use PyErr_WarnEx instead. */
1046
1047#undef PyErr_Warn
1048
1049PyAPI_FUNC(int)
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001050PyErr_Warn(PyObject *category, const char *text)
Christian Heimes33fe8092008-04-13 13:53:33 +00001051{
1052 return PyErr_WarnEx(category, text, 1);
1053}
1054
1055/* Warning with explicit origin */
1056int
Victor Stinner14e461d2013-08-26 22:28:21 +02001057PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1058 PyObject *filename, int lineno,
1059 PyObject *module, PyObject *registry)
1060{
1061 PyObject *res;
1062 if (category == NULL)
1063 category = PyExc_RuntimeWarning;
1064 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001065 module, registry, NULL, NULL);
Victor Stinner14e461d2013-08-26 22:28:21 +02001066 if (res == NULL)
1067 return -1;
1068 Py_DECREF(res);
1069 return 0;
1070}
1071
1072int
Christian Heimes33fe8092008-04-13 13:53:33 +00001073PyErr_WarnExplicit(PyObject *category, const char *text,
1074 const char *filename_str, int lineno,
1075 const char *module_str, PyObject *registry)
1076{
Christian Heimes33fe8092008-04-13 13:53:33 +00001077 PyObject *message = PyUnicode_FromString(text);
Victor Stinnercb428f02010-12-27 20:10:36 +00001078 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
Christian Heimes33fe8092008-04-13 13:53:33 +00001079 PyObject *module = NULL;
1080 int ret = -1;
1081
1082 if (message == NULL || filename == NULL)
1083 goto exit;
1084 if (module_str != NULL) {
1085 module = PyUnicode_FromString(module_str);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001086 if (module == NULL)
1087 goto exit;
Christian Heimes33fe8092008-04-13 13:53:33 +00001088 }
1089
Victor Stinner14e461d2013-08-26 22:28:21 +02001090 ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1091 module, registry);
Christian Heimes33fe8092008-04-13 13:53:33 +00001092
1093 exit:
1094 Py_XDECREF(message);
1095 Py_XDECREF(module);
1096 Py_XDECREF(filename);
1097 return ret;
1098}
1099
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001100int
1101PyErr_WarnExplicitFormat(PyObject *category,
1102 const char *filename_str, int lineno,
1103 const char *module_str, PyObject *registry,
1104 const char *format, ...)
1105{
1106 PyObject *message;
1107 PyObject *module = NULL;
1108 PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1109 int ret = -1;
1110 va_list vargs;
1111
1112 if (filename == NULL)
1113 goto exit;
1114 if (module_str != NULL) {
1115 module = PyUnicode_FromString(module_str);
1116 if (module == NULL)
1117 goto exit;
1118 }
1119
1120#ifdef HAVE_STDARG_PROTOTYPES
1121 va_start(vargs, format);
1122#else
1123 va_start(vargs);
1124#endif
1125 message = PyUnicode_FromFormatV(format, vargs);
1126 if (message != NULL) {
1127 PyObject *res;
1128 res = warn_explicit(category, message, filename, lineno,
Victor Stinner914cde82016-03-19 01:03:51 +01001129 module, registry, NULL, NULL);
Antoine Pitrou070cb3c2013-05-08 13:23:25 +02001130 Py_DECREF(message);
1131 if (res != NULL) {
1132 Py_DECREF(res);
1133 ret = 0;
1134 }
1135 }
1136 va_end(vargs);
1137exit:
1138 Py_XDECREF(module);
1139 Py_XDECREF(filename);
1140 return ret;
1141}
1142
Christian Heimes33fe8092008-04-13 13:53:33 +00001143
Christian Heimes33fe8092008-04-13 13:53:33 +00001144PyDoc_STRVAR(warn_explicit_doc,
1145"Low-level inferface to warnings functionality.");
1146
1147static PyMethodDef warnings_functions[] = {
Victor Stinner22f18752016-12-09 18:08:18 +01001148 WARNINGS_WARN_METHODDEF
Christian Heimes33fe8092008-04-13 13:53:33 +00001149 {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1150 METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001151 {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1152 NULL},
Christian Heimes1a8501c2008-10-02 19:56:01 +00001153 /* XXX(brett.cannon): add showwarning? */
1154 /* XXX(brett.cannon): Reasonable to add formatwarning? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 {NULL, NULL} /* sentinel */
Christian Heimes33fe8092008-04-13 13:53:33 +00001156};
1157
1158
Victor Stinner747f48e2017-12-12 22:59:48 +01001159#ifndef Py_DEBUG
Christian Heimes33fe8092008-04-13 13:53:33 +00001160static PyObject *
Victor Stinnerb98f1712017-11-23 17:13:44 +01001161create_filter(PyObject *category, _Py_Identifier *id)
Christian Heimes33fe8092008-04-13 13:53:33 +00001162{
Victor Stinner82656272017-11-22 23:51:42 +01001163 PyObject *action_str = _PyUnicode_FromId(id);
1164 if (action_str == NULL) {
1165 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001166 }
1167
1168 /* This assumes the line number is zero for now. */
Victor Stinner82656272017-11-22 23:51:42 +01001169 return PyTuple_Pack(5, action_str, Py_None,
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001170 category, Py_None, _PyLong_Zero);
Christian Heimes33fe8092008-04-13 13:53:33 +00001171}
Victor Stinner747f48e2017-12-12 22:59:48 +01001172#endif
1173
Christian Heimes33fe8092008-04-13 13:53:33 +00001174
1175static PyObject *
Victor Stinner1f151112017-11-23 10:43:14 +01001176init_filters(const _PyCoreConfig *config)
Christian Heimes33fe8092008-04-13 13:53:33 +00001177{
Victor Stinner747f48e2017-12-12 22:59:48 +01001178#ifdef Py_DEBUG
1179 /* Py_DEBUG builds show all warnings by default */
1180 return PyList_New(0);
1181#else
1182 /* Other builds ignore a number of warning categories by default */
1183 PyObject *filters = PyList_New(4);
1184 if (filters == NULL) {
Christian Heimes33fe8092008-04-13 13:53:33 +00001185 return NULL;
Victor Stinner747f48e2017-12-12 22:59:48 +01001186 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001187
Victor Stinnerb98f1712017-11-23 17:13:44 +01001188 size_t pos = 0; /* Post-incremented in each use. */
Victor Stinner747f48e2017-12-12 22:59:48 +01001189 PyList_SET_ITEM(filters, pos++,
1190 create_filter(PyExc_DeprecationWarning, &PyId_ignore));
1191 PyList_SET_ITEM(filters, pos++,
1192 create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore));
1193 PyList_SET_ITEM(filters, pos++,
1194 create_filter(PyExc_ImportWarning, &PyId_ignore));
1195 PyList_SET_ITEM(filters, pos++,
1196 create_filter(PyExc_ResourceWarning, &PyId_ignore));
Victor Stinner09f3a8a2017-11-20 17:32:40 -08001197
Victor Stinnerb98f1712017-11-23 17:13:44 +01001198 for (size_t x = 0; x < pos; x++) {
Benjamin Peterson7ab4b8d2010-06-28 00:01:59 +00001199 if (PyList_GET_ITEM(filters, x) == NULL) {
1200 Py_DECREF(filters);
1201 return NULL;
1202 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001203 }
Christian Heimes33fe8092008-04-13 13:53:33 +00001204 return filters;
Victor Stinner747f48e2017-12-12 22:59:48 +01001205#endif
Christian Heimes33fe8092008-04-13 13:53:33 +00001206}
1207
Martin v. Löwis1a214512008-06-11 05:26:20 +00001208static struct PyModuleDef warningsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 PyModuleDef_HEAD_INIT,
1210 MODULE_NAME,
1211 warnings__doc__,
1212 0,
1213 warnings_functions,
1214 NULL,
1215 NULL,
1216 NULL,
1217 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001218};
1219
Christian Heimes33fe8092008-04-13 13:53:33 +00001220
Victor Stinner1f151112017-11-23 10:43:14 +01001221PyObject*
1222_PyWarnings_InitWithConfig(const _PyCoreConfig *config)
Christian Heimes33fe8092008-04-13 13:53:33 +00001223{
Brett Cannon0759dd62009-04-01 18:13:07 +00001224 PyObject *m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001225
Martin v. Löwis1a214512008-06-11 05:26:20 +00001226 m = PyModule_Create(&warningsmodule);
Christian Heimes33fe8092008-04-13 13:53:33 +00001227 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001228 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001229
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001230 if (_PyRuntime.warnings.filters == NULL) {
Victor Stinner1f151112017-11-23 10:43:14 +01001231 _PyRuntime.warnings.filters = init_filters(config);
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001232 if (_PyRuntime.warnings.filters == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001233 return NULL;
1234 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001235 Py_INCREF(_PyRuntime.warnings.filters);
1236 if (PyModule_AddObject(m, "filters", _PyRuntime.warnings.filters) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001237 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001238
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001239 if (_PyRuntime.warnings.once_registry == NULL) {
1240 _PyRuntime.warnings.once_registry = PyDict_New();
1241 if (_PyRuntime.warnings.once_registry == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001242 return NULL;
1243 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001244 Py_INCREF(_PyRuntime.warnings.once_registry);
1245 if (PyModule_AddObject(m, "_onceregistry",
1246 _PyRuntime.warnings.once_registry) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001247 return NULL;
Christian Heimes33fe8092008-04-13 13:53:33 +00001248
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001249 if (_PyRuntime.warnings.default_action == NULL) {
1250 _PyRuntime.warnings.default_action = PyUnicode_FromString("default");
1251 if (_PyRuntime.warnings.default_action == NULL)
Antoine Pitrouaa5c5c62012-01-18 21:45:15 +01001252 return NULL;
1253 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001254 Py_INCREF(_PyRuntime.warnings.default_action);
1255 if (PyModule_AddObject(m, "_defaultaction",
1256 _PyRuntime.warnings.default_action) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001257 return NULL;
Antoine Pitroucb0a0062014-09-18 02:40:46 +02001258
Eric Snow2ebc5ce2017-09-07 23:51:28 -06001259 _PyRuntime.warnings.filters_version = 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +00001260 return m;
Christian Heimes33fe8092008-04-13 13:53:33 +00001261}
Victor Stinner1f151112017-11-23 10:43:14 +01001262
1263
1264PyMODINIT_FUNC
1265_PyWarnings_Init(void)
1266{
1267 PyInterpreterState *interp = PyThreadState_GET()->interp;
1268 const _PyCoreConfig *config = &interp->core_config;
1269 return _PyWarnings_InitWithConfig(config);
1270}