ยปCore Development>Code coverage>Python/_warnings.c

Python code coverage for Python/_warnings.c

#countcontent
1n/a#include "Python.h"
2n/a#include "frameobject.h"
3n/a#include "clinic/_warnings.c.h"
4n/a
5n/a#define MODULE_NAME "_warnings"
6n/a
7n/aPyDoc_STRVAR(warnings__doc__,
8n/aMODULE_NAME " provides basic warning filtering support.\n"
9n/a"It is a helper module to speed up interpreter start-up.");
10n/a
11n/a/* Both 'filters' and 'onceregistry' can be set in warnings.py;
12n/a get_warnings_attr() will reset these variables accordingly. */
13n/astatic PyObject *_filters; /* List */
14n/astatic PyObject *_once_registry; /* Dict */
15n/astatic PyObject *_default_action; /* String */
16n/astatic long _filters_version;
17n/a
18n/a_Py_IDENTIFIER(argv);
19n/a_Py_IDENTIFIER(stderr);
20n/a
21n/astatic int
22n/acheck_matched(PyObject *obj, PyObject *arg)
23n/a{
24n/a PyObject *result;
25n/a _Py_IDENTIFIER(match);
26n/a int rc;
27n/a
28n/a if (obj == Py_None)
29n/a return 1;
30n/a result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
31n/a if (result == NULL)
32n/a return -1;
33n/a
34n/a rc = PyObject_IsTrue(result);
35n/a Py_DECREF(result);
36n/a return rc;
37n/a}
38n/a
39n/a/*
40n/a Returns a new reference.
41n/a A NULL return value can mean false or an error.
42n/a*/
43n/astatic PyObject *
44n/aget_warnings_attr(const char *attr, int try_import)
45n/a{
46n/a static PyObject *warnings_str = NULL;
47n/a PyObject *all_modules;
48n/a PyObject *warnings_module, *obj;
49n/a
50n/a if (warnings_str == NULL) {
51n/a warnings_str = PyUnicode_InternFromString("warnings");
52n/a if (warnings_str == NULL)
53n/a return NULL;
54n/a }
55n/a
56n/a /* don't try to import after the start of the Python finallization */
57n/a if (try_import && _Py_Finalizing == NULL) {
58n/a warnings_module = PyImport_Import(warnings_str);
59n/a if (warnings_module == NULL) {
60n/a /* Fallback to the C implementation if we cannot get
61n/a the Python implementation */
62n/a PyErr_Clear();
63n/a return NULL;
64n/a }
65n/a }
66n/a else {
67n/a all_modules = PyImport_GetModuleDict();
68n/a
69n/a warnings_module = PyDict_GetItem(all_modules, warnings_str);
70n/a if (warnings_module == NULL)
71n/a return NULL;
72n/a
73n/a Py_INCREF(warnings_module);
74n/a }
75n/a
76n/a if (!PyObject_HasAttrString(warnings_module, attr)) {
77n/a Py_DECREF(warnings_module);
78n/a return NULL;
79n/a }
80n/a
81n/a obj = PyObject_GetAttrString(warnings_module, attr);
82n/a Py_DECREF(warnings_module);
83n/a return obj;
84n/a}
85n/a
86n/a
87n/astatic PyObject *
88n/aget_once_registry(void)
89n/a{
90n/a PyObject *registry;
91n/a
92n/a registry = get_warnings_attr("onceregistry", 0);
93n/a if (registry == NULL) {
94n/a if (PyErr_Occurred())
95n/a return NULL;
96n/a return _once_registry;
97n/a }
98n/a Py_DECREF(_once_registry);
99n/a _once_registry = registry;
100n/a return registry;
101n/a}
102n/a
103n/a
104n/astatic PyObject *
105n/aget_default_action(void)
106n/a{
107n/a PyObject *default_action;
108n/a
109n/a default_action = get_warnings_attr("defaultaction", 0);
110n/a if (default_action == NULL) {
111n/a if (PyErr_Occurred()) {
112n/a return NULL;
113n/a }
114n/a return _default_action;
115n/a }
116n/a
117n/a Py_DECREF(_default_action);
118n/a _default_action = default_action;
119n/a return default_action;
120n/a}
121n/a
122n/a
123n/a/* The item is a new reference. */
124n/astatic PyObject*
125n/aget_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
126n/a PyObject *module, PyObject **item)
127n/a{
128n/a PyObject *action;
129n/a Py_ssize_t i;
130n/a PyObject *warnings_filters;
131n/a
132n/a warnings_filters = get_warnings_attr("filters", 0);
133n/a if (warnings_filters == NULL) {
134n/a if (PyErr_Occurred())
135n/a return NULL;
136n/a }
137n/a else {
138n/a Py_DECREF(_filters);
139n/a _filters = warnings_filters;
140n/a }
141n/a
142n/a if (_filters == NULL || !PyList_Check(_filters)) {
143n/a PyErr_SetString(PyExc_ValueError,
144n/a MODULE_NAME ".filters must be a list");
145n/a return NULL;
146n/a }
147n/a
148n/a /* _filters could change while we are iterating over it. */
149n/a for (i = 0; i < PyList_GET_SIZE(_filters); i++) {
150n/a PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;
151n/a Py_ssize_t ln;
152n/a int is_subclass, good_msg, good_mod;
153n/a
154n/a tmp_item = PyList_GET_ITEM(_filters, i);
155n/a if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) {
156n/a PyErr_Format(PyExc_ValueError,
157n/a MODULE_NAME ".filters item %zd isn't a 5-tuple", i);
158n/a return NULL;
159n/a }
160n/a
161n/a /* Python code: action, msg, cat, mod, ln = item */
162n/a Py_INCREF(tmp_item);
163n/a action = PyTuple_GET_ITEM(tmp_item, 0);
164n/a msg = PyTuple_GET_ITEM(tmp_item, 1);
165n/a cat = PyTuple_GET_ITEM(tmp_item, 2);
166n/a mod = PyTuple_GET_ITEM(tmp_item, 3);
167n/a ln_obj = PyTuple_GET_ITEM(tmp_item, 4);
168n/a
169n/a good_msg = check_matched(msg, text);
170n/a if (good_msg == -1) {
171n/a Py_DECREF(tmp_item);
172n/a return NULL;
173n/a }
174n/a
175n/a good_mod = check_matched(mod, module);
176n/a if (good_mod == -1) {
177n/a Py_DECREF(tmp_item);
178n/a return NULL;
179n/a }
180n/a
181n/a is_subclass = PyObject_IsSubclass(category, cat);
182n/a if (is_subclass == -1) {
183n/a Py_DECREF(tmp_item);
184n/a return NULL;
185n/a }
186n/a
187n/a ln = PyLong_AsSsize_t(ln_obj);
188n/a if (ln == -1 && PyErr_Occurred()) {
189n/a Py_DECREF(tmp_item);
190n/a return NULL;
191n/a }
192n/a
193n/a if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) {
194n/a *item = tmp_item;
195n/a return action;
196n/a }
197n/a
198n/a Py_DECREF(tmp_item);
199n/a }
200n/a
201n/a action = get_default_action();
202n/a if (action != NULL) {
203n/a Py_INCREF(Py_None);
204n/a *item = Py_None;
205n/a return action;
206n/a }
207n/a
208n/a PyErr_SetString(PyExc_ValueError,
209n/a MODULE_NAME ".defaultaction not found");
210n/a return NULL;
211n/a}
212n/a
213n/a
214n/astatic int
215n/aalready_warned(PyObject *registry, PyObject *key, int should_set)
216n/a{
217n/a PyObject *version_obj, *already_warned;
218n/a _Py_IDENTIFIER(version);
219n/a
220n/a if (key == NULL)
221n/a return -1;
222n/a
223n/a version_obj = _PyDict_GetItemId(registry, &PyId_version);
224n/a if (version_obj == NULL
225n/a || !PyLong_CheckExact(version_obj)
226n/a || PyLong_AsLong(version_obj) != _filters_version) {
227n/a PyDict_Clear(registry);
228n/a version_obj = PyLong_FromLong(_filters_version);
229n/a if (version_obj == NULL)
230n/a return -1;
231n/a if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) {
232n/a Py_DECREF(version_obj);
233n/a return -1;
234n/a }
235n/a Py_DECREF(version_obj);
236n/a }
237n/a else {
238n/a already_warned = PyDict_GetItem(registry, key);
239n/a if (already_warned != NULL) {
240n/a int rc = PyObject_IsTrue(already_warned);
241n/a if (rc != 0)
242n/a return rc;
243n/a }
244n/a }
245n/a
246n/a /* This warning wasn't found in the registry, set it. */
247n/a if (should_set)
248n/a return PyDict_SetItem(registry, key, Py_True);
249n/a return 0;
250n/a}
251n/a
252n/a/* New reference. */
253n/astatic PyObject *
254n/anormalize_module(PyObject *filename)
255n/a{
256n/a PyObject *module;
257n/a int kind;
258n/a void *data;
259n/a Py_ssize_t len;
260n/a
261n/a len = PyUnicode_GetLength(filename);
262n/a if (len < 0)
263n/a return NULL;
264n/a
265n/a if (len == 0)
266n/a return PyUnicode_FromString("<unknown>");
267n/a
268n/a kind = PyUnicode_KIND(filename);
269n/a data = PyUnicode_DATA(filename);
270n/a
271n/a /* if filename.endswith(".py"): */
272n/a if (len >= 3 &&
273n/a PyUnicode_READ(kind, data, len-3) == '.' &&
274n/a PyUnicode_READ(kind, data, len-2) == 'p' &&
275n/a PyUnicode_READ(kind, data, len-1) == 'y')
276n/a {
277n/a module = PyUnicode_Substring(filename, 0, len-3);
278n/a }
279n/a else {
280n/a module = filename;
281n/a Py_INCREF(module);
282n/a }
283n/a return module;
284n/a}
285n/a
286n/astatic int
287n/aupdate_registry(PyObject *registry, PyObject *text, PyObject *category,
288n/a int add_zero)
289n/a{
290n/a PyObject *altkey, *zero = NULL;
291n/a int rc;
292n/a
293n/a if (add_zero) {
294n/a zero = PyLong_FromLong(0);
295n/a if (zero == NULL)
296n/a return -1;
297n/a altkey = PyTuple_Pack(3, text, category, zero);
298n/a }
299n/a else
300n/a altkey = PyTuple_Pack(2, text, category);
301n/a
302n/a rc = already_warned(registry, altkey, 1);
303n/a Py_XDECREF(zero);
304n/a Py_XDECREF(altkey);
305n/a return rc;
306n/a}
307n/a
308n/astatic void
309n/ashow_warning(PyObject *filename, int lineno, PyObject *text,
310n/a PyObject *category, PyObject *sourceline)
311n/a{
312n/a PyObject *f_stderr;
313n/a PyObject *name;
314n/a char lineno_str[128];
315n/a _Py_IDENTIFIER(__name__);
316n/a
317n/a PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
318n/a
319n/a name = _PyObject_GetAttrId(category, &PyId___name__);
320n/a if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
321n/a goto error;
322n/a
323n/a f_stderr = _PySys_GetObjectId(&PyId_stderr);
324n/a if (f_stderr == NULL) {
325n/a fprintf(stderr, "lost sys.stderr\n");
326n/a goto error;
327n/a }
328n/a
329n/a /* Print "filename:lineno: category: text\n" */
330n/a if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0)
331n/a goto error;
332n/a if (PyFile_WriteString(lineno_str, f_stderr) < 0)
333n/a goto error;
334n/a if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0)
335n/a goto error;
336n/a if (PyFile_WriteString(": ", f_stderr) < 0)
337n/a goto error;
338n/a if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0)
339n/a goto error;
340n/a if (PyFile_WriteString("\n", f_stderr) < 0)
341n/a goto error;
342n/a Py_CLEAR(name);
343n/a
344n/a /* Print " source_line\n" */
345n/a if (sourceline) {
346n/a int kind;
347n/a void *data;
348n/a Py_ssize_t i, len;
349n/a Py_UCS4 ch;
350n/a PyObject *truncated;
351n/a
352n/a if (PyUnicode_READY(sourceline) < 1)
353n/a goto error;
354n/a
355n/a kind = PyUnicode_KIND(sourceline);
356n/a data = PyUnicode_DATA(sourceline);
357n/a len = PyUnicode_GET_LENGTH(sourceline);
358n/a for (i=0; i<len; i++) {
359n/a ch = PyUnicode_READ(kind, data, i);
360n/a if (ch != ' ' && ch != '\t' && ch != '\014')
361n/a break;
362n/a }
363n/a
364n/a truncated = PyUnicode_Substring(sourceline, i, len);
365n/a if (truncated == NULL)
366n/a goto error;
367n/a
368n/a PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW);
369n/a Py_DECREF(truncated);
370n/a PyFile_WriteString("\n", f_stderr);
371n/a }
372n/a else {
373n/a _Py_DisplaySourceLine(f_stderr, filename, lineno, 2);
374n/a }
375n/a
376n/aerror:
377n/a Py_XDECREF(name);
378n/a PyErr_Clear();
379n/a}
380n/a
381n/astatic int
382n/acall_show_warning(PyObject *category, PyObject *text, PyObject *message,
383n/a PyObject *filename, int lineno, PyObject *lineno_obj,
384n/a PyObject *sourceline, PyObject *source)
385n/a{
386n/a PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
387n/a
388n/a /* If the source parameter is set, try to get the Python implementation.
389n/a The Python implementation is able to log the traceback where the source
390n/a was allocated, whereas the C implementation doesnt. */
391n/a show_fn = get_warnings_attr("_showwarnmsg", source != NULL);
392n/a if (show_fn == NULL) {
393n/a if (PyErr_Occurred())
394n/a return -1;
395n/a show_warning(filename, lineno, text, category, sourceline);
396n/a return 0;
397n/a }
398n/a
399n/a if (!PyCallable_Check(show_fn)) {
400n/a PyErr_SetString(PyExc_TypeError,
401n/a "warnings._showwarnmsg() must be set to a callable");
402n/a goto error;
403n/a }
404n/a
405n/a warnmsg_cls = get_warnings_attr("WarningMessage", 0);
406n/a if (warnmsg_cls == NULL) {
407n/a PyErr_SetString(PyExc_RuntimeError,
408n/a "unable to get warnings.WarningMessage");
409n/a goto error;
410n/a }
411n/a
412n/a msg = PyObject_CallFunctionObjArgs(warnmsg_cls, message, category,
413n/a filename, lineno_obj, Py_None, Py_None, source,
414n/a NULL);
415n/a Py_DECREF(warnmsg_cls);
416n/a if (msg == NULL)
417n/a goto error;
418n/a
419n/a res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL);
420n/a Py_DECREF(show_fn);
421n/a Py_DECREF(msg);
422n/a
423n/a if (res == NULL)
424n/a return -1;
425n/a
426n/a Py_DECREF(res);
427n/a return 0;
428n/a
429n/aerror:
430n/a Py_XDECREF(show_fn);
431n/a return -1;
432n/a}
433n/a
434n/astatic PyObject *
435n/awarn_explicit(PyObject *category, PyObject *message,
436n/a PyObject *filename, int lineno,
437n/a PyObject *module, PyObject *registry, PyObject *sourceline,
438n/a PyObject *source)
439n/a{
440n/a PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;
441n/a PyObject *item = NULL;
442n/a PyObject *action;
443n/a int rc;
444n/a
445n/a /* module can be None if a warning is emitted late during Python shutdown.
446n/a In this case, the Python warnings module was probably unloaded, filters
447n/a are no more available to choose as action. It is safer to ignore the
448n/a warning and do nothing. */
449n/a if (module == Py_None)
450n/a Py_RETURN_NONE;
451n/a
452n/a if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
453n/a PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
454n/a return NULL;
455n/a }
456n/a
457n/a /* Normalize module. */
458n/a if (module == NULL) {
459n/a module = normalize_module(filename);
460n/a if (module == NULL)
461n/a return NULL;
462n/a }
463n/a else
464n/a Py_INCREF(module);
465n/a
466n/a /* Normalize message. */
467n/a Py_INCREF(message); /* DECREF'ed in cleanup. */
468n/a rc = PyObject_IsInstance(message, PyExc_Warning);
469n/a if (rc == -1) {
470n/a goto cleanup;
471n/a }
472n/a if (rc == 1) {
473n/a text = PyObject_Str(message);
474n/a if (text == NULL)
475n/a goto cleanup;
476n/a category = (PyObject*)message->ob_type;
477n/a }
478n/a else {
479n/a text = message;
480n/a message = PyObject_CallFunctionObjArgs(category, message, NULL);
481n/a if (message == NULL)
482n/a goto cleanup;
483n/a }
484n/a
485n/a lineno_obj = PyLong_FromLong(lineno);
486n/a if (lineno_obj == NULL)
487n/a goto cleanup;
488n/a
489n/a if (source == Py_None) {
490n/a source = NULL;
491n/a }
492n/a
493n/a /* Create key. */
494n/a key = PyTuple_Pack(3, text, category, lineno_obj);
495n/a if (key == NULL)
496n/a goto cleanup;
497n/a
498n/a if ((registry != NULL) && (registry != Py_None)) {
499n/a rc = already_warned(registry, key, 0);
500n/a if (rc == -1)
501n/a goto cleanup;
502n/a else if (rc == 1)
503n/a goto return_none;
504n/a /* Else this warning hasn't been generated before. */
505n/a }
506n/a
507n/a action = get_filter(category, text, lineno, module, &item);
508n/a if (action == NULL)
509n/a goto cleanup;
510n/a
511n/a if (_PyUnicode_EqualToASCIIString(action, "error")) {
512n/a PyErr_SetObject(category, message);
513n/a goto cleanup;
514n/a }
515n/a
516n/a /* Store in the registry that we've been here, *except* when the action
517n/a is "always". */
518n/a rc = 0;
519n/a if (!_PyUnicode_EqualToASCIIString(action, "always")) {
520n/a if (registry != NULL && registry != Py_None &&
521n/a PyDict_SetItem(registry, key, Py_True) < 0)
522n/a goto cleanup;
523n/a else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
524n/a goto return_none;
525n/a else if (_PyUnicode_EqualToASCIIString(action, "once")) {
526n/a if (registry == NULL || registry == Py_None) {
527n/a registry = get_once_registry();
528n/a if (registry == NULL)
529n/a goto cleanup;
530n/a }
531n/a /* _once_registry[(text, category)] = 1 */
532n/a rc = update_registry(registry, text, category, 0);
533n/a }
534n/a else if (_PyUnicode_EqualToASCIIString(action, "module")) {
535n/a /* registry[(text, category, 0)] = 1 */
536n/a if (registry != NULL && registry != Py_None)
537n/a rc = update_registry(registry, text, category, 0);
538n/a }
539n/a else if (!_PyUnicode_EqualToASCIIString(action, "default")) {
540n/a PyErr_Format(PyExc_RuntimeError,
541n/a "Unrecognized action (%R) in warnings.filters:\n %R",
542n/a action, item);
543n/a goto cleanup;
544n/a }
545n/a }
546n/a
547n/a if (rc == 1) /* Already warned for this module. */
548n/a goto return_none;
549n/a if (rc == 0) {
550n/a if (call_show_warning(category, text, message, filename, lineno,
551n/a lineno_obj, sourceline, source) < 0)
552n/a goto cleanup;
553n/a }
554n/a else /* if (rc == -1) */
555n/a goto cleanup;
556n/a
557n/a return_none:
558n/a result = Py_None;
559n/a Py_INCREF(result);
560n/a
561n/a cleanup:
562n/a Py_XDECREF(item);
563n/a Py_XDECREF(key);
564n/a Py_XDECREF(text);
565n/a Py_XDECREF(lineno_obj);
566n/a Py_DECREF(module);
567n/a Py_XDECREF(message);
568n/a return result; /* Py_None or NULL. */
569n/a}
570n/a
571n/astatic int
572n/ais_internal_frame(PyFrameObject *frame)
573n/a{
574n/a static PyObject *importlib_string = NULL;
575n/a static PyObject *bootstrap_string = NULL;
576n/a PyObject *filename;
577n/a int contains;
578n/a
579n/a if (importlib_string == NULL) {
580n/a importlib_string = PyUnicode_FromString("importlib");
581n/a if (importlib_string == NULL) {
582n/a return 0;
583n/a }
584n/a
585n/a bootstrap_string = PyUnicode_FromString("_bootstrap");
586n/a if (bootstrap_string == NULL) {
587n/a Py_DECREF(importlib_string);
588n/a return 0;
589n/a }
590n/a Py_INCREF(importlib_string);
591n/a Py_INCREF(bootstrap_string);
592n/a }
593n/a
594n/a if (frame == NULL || frame->f_code == NULL ||
595n/a frame->f_code->co_filename == NULL) {
596n/a return 0;
597n/a }
598n/a filename = frame->f_code->co_filename;
599n/a if (!PyUnicode_Check(filename)) {
600n/a return 0;
601n/a }
602n/a contains = PyUnicode_Contains(filename, importlib_string);
603n/a if (contains < 0) {
604n/a return 0;
605n/a }
606n/a else if (contains > 0) {
607n/a contains = PyUnicode_Contains(filename, bootstrap_string);
608n/a if (contains < 0) {
609n/a return 0;
610n/a }
611n/a else if (contains > 0) {
612n/a return 1;
613n/a }
614n/a }
615n/a
616n/a return 0;
617n/a}
618n/a
619n/astatic PyFrameObject *
620n/anext_external_frame(PyFrameObject *frame)
621n/a{
622n/a do {
623n/a frame = frame->f_back;
624n/a } while (frame != NULL && is_internal_frame(frame));
625n/a
626n/a return frame;
627n/a}
628n/a
629n/a/* filename, module, and registry are new refs, globals is borrowed */
630n/a/* Returns 0 on error (no new refs), 1 on success */
631n/astatic int
632n/asetup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
633n/a PyObject **module, PyObject **registry)
634n/a{
635n/a PyObject *globals;
636n/a
637n/a /* Setup globals and lineno. */
638n/a PyFrameObject *f = PyThreadState_GET()->frame;
639n/a // Stack level comparisons to Python code is off by one as there is no
640n/a // warnings-related stack level to avoid.
641n/a if (stack_level <= 0 || is_internal_frame(f)) {
642n/a while (--stack_level > 0 && f != NULL) {
643n/a f = f->f_back;
644n/a }
645n/a }
646n/a else {
647n/a while (--stack_level > 0 && f != NULL) {
648n/a f = next_external_frame(f);
649n/a }
650n/a }
651n/a
652n/a if (f == NULL) {
653n/a globals = PyThreadState_Get()->interp->sysdict;
654n/a *lineno = 1;
655n/a }
656n/a else {
657n/a globals = f->f_globals;
658n/a *lineno = PyFrame_GetLineNumber(f);
659n/a }
660n/a
661n/a *module = NULL;
662n/a
663n/a /* Setup registry. */
664n/a assert(globals != NULL);
665n/a assert(PyDict_Check(globals));
666n/a *registry = PyDict_GetItemString(globals, "__warningregistry__");
667n/a if (*registry == NULL) {
668n/a int rc;
669n/a
670n/a *registry = PyDict_New();
671n/a if (*registry == NULL)
672n/a return 0;
673n/a
674n/a rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);
675n/a if (rc < 0)
676n/a goto handle_error;
677n/a }
678n/a else
679n/a Py_INCREF(*registry);
680n/a
681n/a /* Setup module. */
682n/a *module = PyDict_GetItemString(globals, "__name__");
683n/a if (*module == NULL) {
684n/a *module = PyUnicode_FromString("<string>");
685n/a if (*module == NULL)
686n/a goto handle_error;
687n/a }
688n/a else
689n/a Py_INCREF(*module);
690n/a
691n/a /* Setup filename. */
692n/a *filename = PyDict_GetItemString(globals, "__file__");
693n/a if (*filename != NULL && PyUnicode_Check(*filename)) {
694n/a Py_ssize_t len;
695n/a int kind;
696n/a void *data;
697n/a
698n/a if (PyUnicode_READY(*filename))
699n/a goto handle_error;
700n/a
701n/a len = PyUnicode_GetLength(*filename);
702n/a kind = PyUnicode_KIND(*filename);
703n/a data = PyUnicode_DATA(*filename);
704n/a
705n/a#define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0)
706n/a /* if filename.lower().endswith(".pyc"): */
707n/a if (len >= 4 &&
708n/a PyUnicode_READ(kind, data, len-4) == '.' &&
709n/a ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' &&
710n/a ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' &&
711n/a ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c')
712n/a {
713n/a *filename = PyUnicode_Substring(*filename, 0,
714n/a PyUnicode_GET_LENGTH(*filename)-1);
715n/a if (*filename == NULL)
716n/a goto handle_error;
717n/a }
718n/a else
719n/a Py_INCREF(*filename);
720n/a }
721n/a else {
722n/a *filename = NULL;
723n/a if (*module != Py_None && _PyUnicode_EqualToASCIIString(*module, "__main__")) {
724n/a PyObject *argv = _PySys_GetObjectId(&PyId_argv);
725n/a /* PyList_Check() is needed because sys.argv is set to None during
726n/a Python finalization */
727n/a if (argv != NULL && PyList_Check(argv) && PyList_Size(argv) > 0) {
728n/a int is_true;
729n/a *filename = PyList_GetItem(argv, 0);
730n/a Py_INCREF(*filename);
731n/a /* If sys.argv[0] is false, then use '__main__'. */
732n/a is_true = PyObject_IsTrue(*filename);
733n/a if (is_true < 0) {
734n/a Py_DECREF(*filename);
735n/a goto handle_error;
736n/a }
737n/a else if (!is_true) {
738n/a Py_SETREF(*filename, PyUnicode_FromString("__main__"));
739n/a if (*filename == NULL)
740n/a goto handle_error;
741n/a }
742n/a }
743n/a else {
744n/a /* embedded interpreters don't have sys.argv, see bug #839151 */
745n/a *filename = PyUnicode_FromString("__main__");
746n/a if (*filename == NULL)
747n/a goto handle_error;
748n/a }
749n/a }
750n/a if (*filename == NULL) {
751n/a *filename = *module;
752n/a Py_INCREF(*filename);
753n/a }
754n/a }
755n/a
756n/a return 1;
757n/a
758n/a handle_error:
759n/a /* filename not XDECREF'ed here as there is no way to jump here with a
760n/a dangling reference. */
761n/a Py_XDECREF(*registry);
762n/a Py_XDECREF(*module);
763n/a return 0;
764n/a}
765n/a
766n/astatic PyObject *
767n/aget_category(PyObject *message, PyObject *category)
768n/a{
769n/a int rc;
770n/a
771n/a /* Get category. */
772n/a rc = PyObject_IsInstance(message, PyExc_Warning);
773n/a if (rc == -1)
774n/a return NULL;
775n/a
776n/a if (rc == 1)
777n/a category = (PyObject*)message->ob_type;
778n/a else if (category == NULL || category == Py_None)
779n/a category = PyExc_UserWarning;
780n/a
781n/a /* Validate category. */
782n/a rc = PyObject_IsSubclass(category, PyExc_Warning);
783n/a /* category is not a subclass of PyExc_Warning or
784n/a PyObject_IsSubclass raised an error */
785n/a if (rc == -1 || rc == 0) {
786n/a PyErr_Format(PyExc_TypeError,
787n/a "category must be a Warning subclass, not '%s'",
788n/a Py_TYPE(category)->tp_name);
789n/a return NULL;
790n/a }
791n/a
792n/a return category;
793n/a}
794n/a
795n/astatic PyObject *
796n/ado_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
797n/a PyObject *source)
798n/a{
799n/a PyObject *filename, *module, *registry, *res;
800n/a int lineno;
801n/a
802n/a if (!setup_context(stack_level, &filename, &lineno, &module, &registry))
803n/a return NULL;
804n/a
805n/a res = warn_explicit(category, message, filename, lineno, module, registry,
806n/a NULL, source);
807n/a Py_DECREF(filename);
808n/a Py_DECREF(registry);
809n/a Py_DECREF(module);
810n/a return res;
811n/a}
812n/a
813n/a/*[clinic input]
814n/awarn as warnings_warn
815n/a
816n/a message: object
817n/a category: object = None
818n/a stacklevel: Py_ssize_t = 1
819n/a source: object = None
820n/a
821n/aIssue a warning, or maybe ignore it or raise an exception.
822n/a[clinic start generated code]*/
823n/a
824n/astatic PyObject *
825n/awarnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
826n/a Py_ssize_t stacklevel, PyObject *source)
827n/a/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/
828n/a{
829n/a category = get_category(message, category);
830n/a if (category == NULL)
831n/a return NULL;
832n/a return do_warn(message, category, stacklevel, source);
833n/a}
834n/a
835n/astatic PyObject *
836n/awarnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
837n/a{
838n/a static char *kwd_list[] = {"message", "category", "filename", "lineno",
839n/a "module", "registry", "module_globals",
840n/a "source", 0};
841n/a PyObject *message;
842n/a PyObject *category;
843n/a PyObject *filename;
844n/a int lineno;
845n/a PyObject *module = NULL;
846n/a PyObject *registry = NULL;
847n/a PyObject *module_globals = NULL;
848n/a PyObject *sourceobj = NULL;
849n/a
850n/a if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
851n/a kwd_list, &message, &category, &filename, &lineno, &module,
852n/a &registry, &module_globals, &sourceobj))
853n/a return NULL;
854n/a
855n/a if (module_globals) {
856n/a _Py_IDENTIFIER(get_source);
857n/a _Py_IDENTIFIER(splitlines);
858n/a PyObject *tmp;
859n/a PyObject *loader;
860n/a PyObject *module_name;
861n/a PyObject *source;
862n/a PyObject *source_list;
863n/a PyObject *source_line;
864n/a PyObject *returned;
865n/a
866n/a if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
867n/a return NULL;
868n/a if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
869n/a return NULL;
870n/a
871n/a /* Check/get the requisite pieces needed for the loader. */
872n/a loader = PyDict_GetItemString(module_globals, "__loader__");
873n/a module_name = PyDict_GetItemString(module_globals, "__name__");
874n/a
875n/a if (loader == NULL || module_name == NULL)
876n/a goto standard_call;
877n/a
878n/a /* Make sure the loader implements the optional get_source() method. */
879n/a if (!_PyObject_HasAttrId(loader, &PyId_get_source))
880n/a goto standard_call;
881n/a /* Call get_source() to get the source code. */
882n/a source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
883n/a module_name, NULL);
884n/a if (!source)
885n/a return NULL;
886n/a else if (source == Py_None) {
887n/a Py_DECREF(Py_None);
888n/a goto standard_call;
889n/a }
890n/a
891n/a /* Split the source into lines. */
892n/a source_list = PyObject_CallMethodObjArgs(source,
893n/a PyId_splitlines.object,
894n/a NULL);
895n/a Py_DECREF(source);
896n/a if (!source_list)
897n/a return NULL;
898n/a
899n/a /* Get the source line. */
900n/a source_line = PyList_GetItem(source_list, lineno-1);
901n/a if (!source_line) {
902n/a Py_DECREF(source_list);
903n/a return NULL;
904n/a }
905n/a
906n/a /* Handle the warning. */
907n/a returned = warn_explicit(category, message, filename, lineno, module,
908n/a registry, source_line, sourceobj);
909n/a Py_DECREF(source_list);
910n/a return returned;
911n/a }
912n/a
913n/a standard_call:
914n/a return warn_explicit(category, message, filename, lineno, module,
915n/a registry, NULL, sourceobj);
916n/a}
917n/a
918n/astatic PyObject *
919n/awarnings_filters_mutated(PyObject *self, PyObject *args)
920n/a{
921n/a _filters_version++;
922n/a Py_RETURN_NONE;
923n/a}
924n/a
925n/a
926n/a/* Function to issue a warning message; may raise an exception. */
927n/a
928n/astatic int
929n/awarn_unicode(PyObject *category, PyObject *message,
930n/a Py_ssize_t stack_level, PyObject *source)
931n/a{
932n/a PyObject *res;
933n/a
934n/a if (category == NULL)
935n/a category = PyExc_RuntimeWarning;
936n/a
937n/a res = do_warn(message, category, stack_level, source);
938n/a if (res == NULL)
939n/a return -1;
940n/a Py_DECREF(res);
941n/a
942n/a return 0;
943n/a}
944n/a
945n/astatic int
946n/a_PyErr_WarnFormatV(PyObject *source,
947n/a PyObject *category, Py_ssize_t stack_level,
948n/a const char *format, va_list vargs)
949n/a{
950n/a PyObject *message;
951n/a int res;
952n/a
953n/a message = PyUnicode_FromFormatV(format, vargs);
954n/a if (message == NULL)
955n/a return -1;
956n/a
957n/a res = warn_unicode(category, message, stack_level, source);
958n/a Py_DECREF(message);
959n/a return res;
960n/a}
961n/a
962n/aint
963n/aPyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
964n/a const char *format, ...)
965n/a{
966n/a int res;
967n/a va_list vargs;
968n/a
969n/a#ifdef HAVE_STDARG_PROTOTYPES
970n/a va_start(vargs, format);
971n/a#else
972n/a va_start(vargs);
973n/a#endif
974n/a res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs);
975n/a va_end(vargs);
976n/a return res;
977n/a}
978n/a
979n/aint
980n/aPyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level,
981n/a const char *format, ...)
982n/a{
983n/a int res;
984n/a va_list vargs;
985n/a
986n/a#ifdef HAVE_STDARG_PROTOTYPES
987n/a va_start(vargs, format);
988n/a#else
989n/a va_start(vargs);
990n/a#endif
991n/a res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning,
992n/a stack_level, format, vargs);
993n/a va_end(vargs);
994n/a return res;
995n/a}
996n/a
997n/a
998n/aint
999n/aPyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
1000n/a{
1001n/a int ret;
1002n/a PyObject *message = PyUnicode_FromString(text);
1003n/a if (message == NULL)
1004n/a return -1;
1005n/a ret = warn_unicode(category, message, stack_level, NULL);
1006n/a Py_DECREF(message);
1007n/a return ret;
1008n/a}
1009n/a
1010n/a/* PyErr_Warn is only for backwards compatibility and will be removed.
1011n/a Use PyErr_WarnEx instead. */
1012n/a
1013n/a#undef PyErr_Warn
1014n/a
1015n/aPyAPI_FUNC(int)
1016n/aPyErr_Warn(PyObject *category, const char *text)
1017n/a{
1018n/a return PyErr_WarnEx(category, text, 1);
1019n/a}
1020n/a
1021n/a/* Warning with explicit origin */
1022n/aint
1023n/aPyErr_WarnExplicitObject(PyObject *category, PyObject *message,
1024n/a PyObject *filename, int lineno,
1025n/a PyObject *module, PyObject *registry)
1026n/a{
1027n/a PyObject *res;
1028n/a if (category == NULL)
1029n/a category = PyExc_RuntimeWarning;
1030n/a res = warn_explicit(category, message, filename, lineno,
1031n/a module, registry, NULL, NULL);
1032n/a if (res == NULL)
1033n/a return -1;
1034n/a Py_DECREF(res);
1035n/a return 0;
1036n/a}
1037n/a
1038n/aint
1039n/aPyErr_WarnExplicit(PyObject *category, const char *text,
1040n/a const char *filename_str, int lineno,
1041n/a const char *module_str, PyObject *registry)
1042n/a{
1043n/a PyObject *message = PyUnicode_FromString(text);
1044n/a PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1045n/a PyObject *module = NULL;
1046n/a int ret = -1;
1047n/a
1048n/a if (message == NULL || filename == NULL)
1049n/a goto exit;
1050n/a if (module_str != NULL) {
1051n/a module = PyUnicode_FromString(module_str);
1052n/a if (module == NULL)
1053n/a goto exit;
1054n/a }
1055n/a
1056n/a ret = PyErr_WarnExplicitObject(category, message, filename, lineno,
1057n/a module, registry);
1058n/a
1059n/a exit:
1060n/a Py_XDECREF(message);
1061n/a Py_XDECREF(module);
1062n/a Py_XDECREF(filename);
1063n/a return ret;
1064n/a}
1065n/a
1066n/aint
1067n/aPyErr_WarnExplicitFormat(PyObject *category,
1068n/a const char *filename_str, int lineno,
1069n/a const char *module_str, PyObject *registry,
1070n/a const char *format, ...)
1071n/a{
1072n/a PyObject *message;
1073n/a PyObject *module = NULL;
1074n/a PyObject *filename = PyUnicode_DecodeFSDefault(filename_str);
1075n/a int ret = -1;
1076n/a va_list vargs;
1077n/a
1078n/a if (filename == NULL)
1079n/a goto exit;
1080n/a if (module_str != NULL) {
1081n/a module = PyUnicode_FromString(module_str);
1082n/a if (module == NULL)
1083n/a goto exit;
1084n/a }
1085n/a
1086n/a#ifdef HAVE_STDARG_PROTOTYPES
1087n/a va_start(vargs, format);
1088n/a#else
1089n/a va_start(vargs);
1090n/a#endif
1091n/a message = PyUnicode_FromFormatV(format, vargs);
1092n/a if (message != NULL) {
1093n/a PyObject *res;
1094n/a res = warn_explicit(category, message, filename, lineno,
1095n/a module, registry, NULL, NULL);
1096n/a Py_DECREF(message);
1097n/a if (res != NULL) {
1098n/a Py_DECREF(res);
1099n/a ret = 0;
1100n/a }
1101n/a }
1102n/a va_end(vargs);
1103n/aexit:
1104n/a Py_XDECREF(module);
1105n/a Py_XDECREF(filename);
1106n/a return ret;
1107n/a}
1108n/a
1109n/a
1110n/aPyDoc_STRVAR(warn_explicit_doc,
1111n/a"Low-level inferface to warnings functionality.");
1112n/a
1113n/astatic PyMethodDef warnings_functions[] = {
1114n/a WARNINGS_WARN_METHODDEF
1115n/a {"warn_explicit", (PyCFunction)warnings_warn_explicit,
1116n/a METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},
1117n/a {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS,
1118n/a NULL},
1119n/a /* XXX(brett.cannon): add showwarning? */
1120n/a /* XXX(brett.cannon): Reasonable to add formatwarning? */
1121n/a {NULL, NULL} /* sentinel */
1122n/a};
1123n/a
1124n/a
1125n/astatic PyObject *
1126n/acreate_filter(PyObject *category, const char *action)
1127n/a{
1128n/a static PyObject *ignore_str = NULL;
1129n/a static PyObject *error_str = NULL;
1130n/a static PyObject *default_str = NULL;
1131n/a static PyObject *always_str = NULL;
1132n/a PyObject *action_obj = NULL;
1133n/a PyObject *lineno, *result;
1134n/a
1135n/a if (!strcmp(action, "ignore")) {
1136n/a if (ignore_str == NULL) {
1137n/a ignore_str = PyUnicode_InternFromString("ignore");
1138n/a if (ignore_str == NULL)
1139n/a return NULL;
1140n/a }
1141n/a action_obj = ignore_str;
1142n/a }
1143n/a else if (!strcmp(action, "error")) {
1144n/a if (error_str == NULL) {
1145n/a error_str = PyUnicode_InternFromString("error");
1146n/a if (error_str == NULL)
1147n/a return NULL;
1148n/a }
1149n/a action_obj = error_str;
1150n/a }
1151n/a else if (!strcmp(action, "default")) {
1152n/a if (default_str == NULL) {
1153n/a default_str = PyUnicode_InternFromString("default");
1154n/a if (default_str == NULL)
1155n/a return NULL;
1156n/a }
1157n/a action_obj = default_str;
1158n/a }
1159n/a else if (!strcmp(action, "always")) {
1160n/a if (always_str == NULL) {
1161n/a always_str = PyUnicode_InternFromString("always");
1162n/a if (always_str == NULL)
1163n/a return NULL;
1164n/a }
1165n/a action_obj = always_str;
1166n/a }
1167n/a else {
1168n/a Py_FatalError("unknown action");
1169n/a }
1170n/a
1171n/a /* This assumes the line number is zero for now. */
1172n/a lineno = PyLong_FromLong(0);
1173n/a if (lineno == NULL)
1174n/a return NULL;
1175n/a result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);
1176n/a Py_DECREF(lineno);
1177n/a return result;
1178n/a}
1179n/a
1180n/astatic PyObject *
1181n/ainit_filters(void)
1182n/a{
1183n/a PyObject *filters = PyList_New(5);
1184n/a unsigned int pos = 0; /* Post-incremented in each use. */
1185n/a unsigned int x;
1186n/a const char *bytes_action, *resource_action;
1187n/a
1188n/a if (filters == NULL)
1189n/a return NULL;
1190n/a
1191n/a PyList_SET_ITEM(filters, pos++,
1192n/a create_filter(PyExc_DeprecationWarning, "ignore"));
1193n/a PyList_SET_ITEM(filters, pos++,
1194n/a create_filter(PyExc_PendingDeprecationWarning, "ignore"));
1195n/a PyList_SET_ITEM(filters, pos++,
1196n/a create_filter(PyExc_ImportWarning, "ignore"));
1197n/a if (Py_BytesWarningFlag > 1)
1198n/a bytes_action = "error";
1199n/a else if (Py_BytesWarningFlag)
1200n/a bytes_action = "default";
1201n/a else
1202n/a bytes_action = "ignore";
1203n/a PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,
1204n/a bytes_action));
1205n/a /* resource usage warnings are enabled by default in pydebug mode */
1206n/a#ifdef Py_DEBUG
1207n/a resource_action = "always";
1208n/a#else
1209n/a resource_action = "ignore";
1210n/a#endif
1211n/a PyList_SET_ITEM(filters, pos++, create_filter(PyExc_ResourceWarning,
1212n/a resource_action));
1213n/a for (x = 0; x < pos; x += 1) {
1214n/a if (PyList_GET_ITEM(filters, x) == NULL) {
1215n/a Py_DECREF(filters);
1216n/a return NULL;
1217n/a }
1218n/a }
1219n/a
1220n/a return filters;
1221n/a}
1222n/a
1223n/astatic struct PyModuleDef warningsmodule = {
1224n/a PyModuleDef_HEAD_INIT,
1225n/a MODULE_NAME,
1226n/a warnings__doc__,
1227n/a 0,
1228n/a warnings_functions,
1229n/a NULL,
1230n/a NULL,
1231n/a NULL,
1232n/a NULL
1233n/a};
1234n/a
1235n/a
1236n/aPyMODINIT_FUNC
1237n/a_PyWarnings_Init(void)
1238n/a{
1239n/a PyObject *m;
1240n/a
1241n/a m = PyModule_Create(&warningsmodule);
1242n/a if (m == NULL)
1243n/a return NULL;
1244n/a
1245n/a if (_filters == NULL) {
1246n/a _filters = init_filters();
1247n/a if (_filters == NULL)
1248n/a return NULL;
1249n/a }
1250n/a Py_INCREF(_filters);
1251n/a if (PyModule_AddObject(m, "filters", _filters) < 0)
1252n/a return NULL;
1253n/a
1254n/a if (_once_registry == NULL) {
1255n/a _once_registry = PyDict_New();
1256n/a if (_once_registry == NULL)
1257n/a return NULL;
1258n/a }
1259n/a Py_INCREF(_once_registry);
1260n/a if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
1261n/a return NULL;
1262n/a
1263n/a if (_default_action == NULL) {
1264n/a _default_action = PyUnicode_FromString("default");
1265n/a if (_default_action == NULL)
1266n/a return NULL;
1267n/a }
1268n/a Py_INCREF(_default_action);
1269n/a if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
1270n/a return NULL;
1271n/a
1272n/a _filters_version = 0;
1273n/a return m;
1274n/a}