+++ /dev/null
-#include "Python.h"\r
-#include "frameobject.h"\r
-\r
-#define MODULE_NAME "_warnings"\r
-\r
-PyDoc_STRVAR(warnings__doc__,\r
-MODULE_NAME " provides basic warning filtering support.\n"\r
-"It is a helper module to speed up interpreter start-up.");\r
-\r
-/* Both 'filters' and 'onceregistry' can be set in warnings.py;\r
- get_warnings_attr() will reset these variables accordingly. */\r
-static PyObject *_filters; /* List */\r
-static PyObject *_once_registry; /* Dict */\r
-static PyObject *_default_action; /* String */\r
-\r
-\r
-static int\r
-check_matched(PyObject *obj, PyObject *arg)\r
-{\r
- PyObject *result;\r
- int rc;\r
-\r
- if (obj == Py_None)\r
- return 1;\r
- result = PyObject_CallMethod(obj, "match", "O", arg);\r
- if (result == NULL)\r
- return -1;\r
-\r
- rc = PyObject_IsTrue(result);\r
- Py_DECREF(result);\r
- return rc;\r
-}\r
-\r
-/*\r
- Returns a new reference.\r
- A NULL return value can mean false or an error.\r
-*/\r
-static PyObject *\r
-get_warnings_attr(const char *attr)\r
-{\r
- static PyObject *warnings_str = NULL;\r
- PyObject *all_modules;\r
- PyObject *warnings_module;\r
- int result;\r
-\r
- if (warnings_str == NULL) {\r
- warnings_str = PyString_InternFromString("warnings");\r
- if (warnings_str == NULL)\r
- return NULL;\r
- }\r
-\r
- all_modules = PyImport_GetModuleDict();\r
- result = PyDict_Contains(all_modules, warnings_str);\r
- if (result == -1 || result == 0)\r
- return NULL;\r
-\r
- warnings_module = PyDict_GetItem(all_modules, warnings_str);\r
- if (!PyObject_HasAttrString(warnings_module, attr))\r
- return NULL;\r
- return PyObject_GetAttrString(warnings_module, attr);\r
-}\r
-\r
-\r
-static PyObject *\r
-get_once_registry(void)\r
-{\r
- PyObject *registry;\r
-\r
- registry = get_warnings_attr("onceregistry");\r
- if (registry == NULL) {\r
- if (PyErr_Occurred())\r
- return NULL;\r
- return _once_registry;\r
- }\r
- Py_DECREF(_once_registry);\r
- _once_registry = registry;\r
- return registry;\r
-}\r
-\r
-\r
-static PyObject *\r
-get_default_action(void)\r
-{\r
- PyObject *default_action;\r
-\r
- default_action = get_warnings_attr("defaultaction");\r
- if (default_action == NULL) {\r
- if (PyErr_Occurred()) {\r
- return NULL;\r
- }\r
- return _default_action;\r
- }\r
-\r
- Py_DECREF(_default_action);\r
- _default_action = default_action;\r
- return default_action;\r
-}\r
-\r
-\r
-/* The item is a borrowed reference. */\r
-static const char *\r
-get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,\r
- PyObject *module, PyObject **item)\r
-{\r
- PyObject *action;\r
- Py_ssize_t i;\r
- PyObject *warnings_filters;\r
-\r
- warnings_filters = get_warnings_attr("filters");\r
- if (warnings_filters == NULL) {\r
- if (PyErr_Occurred())\r
- return NULL;\r
- }\r
- else {\r
- Py_DECREF(_filters);\r
- _filters = warnings_filters;\r
- }\r
-\r
- if (!PyList_Check(_filters)) {\r
- PyErr_SetString(PyExc_ValueError,\r
- MODULE_NAME ".filters must be a list");\r
- return NULL;\r
- }\r
-\r
- /* _filters could change while we are iterating over it. */\r
- for (i = 0; i < PyList_GET_SIZE(_filters); i++) {\r
- PyObject *tmp_item, *action, *msg, *cat, *mod, *ln_obj;\r
- Py_ssize_t ln;\r
- int is_subclass, good_msg, good_mod;\r
-\r
- tmp_item = *item = PyList_GET_ITEM(_filters, i);\r
- if (PyTuple_Size(tmp_item) != 5) {\r
- PyErr_Format(PyExc_ValueError,\r
- MODULE_NAME ".filters item %zd isn't a 5-tuple", i);\r
- return NULL;\r
- }\r
-\r
- /* Python code: action, msg, cat, mod, ln = item */\r
- action = PyTuple_GET_ITEM(tmp_item, 0);\r
- msg = PyTuple_GET_ITEM(tmp_item, 1);\r
- cat = PyTuple_GET_ITEM(tmp_item, 2);\r
- mod = PyTuple_GET_ITEM(tmp_item, 3);\r
- ln_obj = PyTuple_GET_ITEM(tmp_item, 4);\r
-\r
- good_msg = check_matched(msg, text);\r
- good_mod = check_matched(mod, module);\r
- is_subclass = PyObject_IsSubclass(category, cat);\r
- ln = PyInt_AsSsize_t(ln_obj);\r
- if (good_msg == -1 || good_mod == -1 || is_subclass == -1 ||\r
- (ln == -1 && PyErr_Occurred()))\r
- return NULL;\r
-\r
- if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln))\r
- return PyString_AsString(action);\r
- }\r
-\r
- action = get_default_action();\r
- if (action != NULL) {\r
- return PyString_AsString(action);\r
- }\r
-\r
- PyErr_SetString(PyExc_ValueError,\r
- MODULE_NAME ".defaultaction not found");\r
- return NULL;\r
-}\r
-\r
-\r
-static int\r
-already_warned(PyObject *registry, PyObject *key, int should_set)\r
-{\r
- PyObject *already_warned;\r
-\r
- if (key == NULL)\r
- return -1;\r
-\r
- already_warned = PyDict_GetItem(registry, key);\r
- if (already_warned != NULL) {\r
- int rc = PyObject_IsTrue(already_warned);\r
- if (rc != 0)\r
- return rc;\r
- }\r
-\r
- /* This warning wasn't found in the registry, set it. */\r
- if (should_set)\r
- return PyDict_SetItem(registry, key, Py_True);\r
- return 0;\r
-}\r
-\r
-/* New reference. */\r
-static PyObject *\r
-normalize_module(PyObject *filename)\r
-{\r
- PyObject *module;\r
- const char *mod_str;\r
- Py_ssize_t len;\r
-\r
- int rc = PyObject_IsTrue(filename);\r
- if (rc == -1)\r
- return NULL;\r
- else if (rc == 0)\r
- return PyString_FromString("<unknown>");\r
-\r
- mod_str = PyString_AsString(filename);\r
- if (mod_str == NULL)\r
- return NULL;\r
- len = PyString_Size(filename);\r
- if (len < 0)\r
- return NULL;\r
- if (len >= 3 &&\r
- strncmp(mod_str + (len - 3), ".py", 3) == 0) {\r
- module = PyString_FromStringAndSize(mod_str, len-3);\r
- }\r
- else {\r
- module = filename;\r
- Py_INCREF(module);\r
- }\r
- return module;\r
-}\r
-\r
-static int\r
-update_registry(PyObject *registry, PyObject *text, PyObject *category,\r
- int add_zero)\r
-{\r
- PyObject *altkey, *zero = NULL;\r
- int rc;\r
-\r
- if (add_zero) {\r
- zero = PyInt_FromLong(0);\r
- if (zero == NULL)\r
- return -1;\r
- altkey = PyTuple_Pack(3, text, category, zero);\r
- }\r
- else\r
- altkey = PyTuple_Pack(2, text, category);\r
-\r
- rc = already_warned(registry, altkey, 1);\r
- Py_XDECREF(zero);\r
- Py_XDECREF(altkey);\r
- return rc;\r
-}\r
-\r
-static void\r
-show_warning(PyObject *filename, int lineno, PyObject *text, PyObject\r
- *category, PyObject *sourceline)\r
-{\r
- PyObject *f_stderr;\r
- PyObject *name;\r
- char lineno_str[128];\r
-\r
- PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);\r
-\r
- name = PyObject_GetAttrString(category, "__name__");\r
- if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */\r
- return;\r
-\r
- f_stderr = PySys_GetObject("stderr");\r
- if (f_stderr == NULL) {\r
- fprintf(stderr, "lost sys.stderr\n");\r
- Py_DECREF(name);\r
- return;\r
- }\r
-\r
- /* Print "filename:lineno: category: text\n" */\r
- PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW);\r
- PyFile_WriteString(lineno_str, f_stderr);\r
- PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW);\r
- PyFile_WriteString(": ", f_stderr);\r
- PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW);\r
- PyFile_WriteString("\n", f_stderr);\r
- Py_XDECREF(name);\r
-\r
- /* Print " source_line\n" */\r
- if (sourceline) {\r
- char *source_line_str = PyString_AS_STRING(sourceline);\r
- while (*source_line_str == ' ' || *source_line_str == '\t' ||\r
- *source_line_str == '\014')\r
- source_line_str++;\r
-\r
- PyFile_WriteString(source_line_str, f_stderr);\r
- PyFile_WriteString("\n", f_stderr);\r
- }\r
- else\r
- _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename),\r
- lineno, 2);\r
- PyErr_Clear();\r
-}\r
-\r
-static PyObject *\r
-warn_explicit(PyObject *category, PyObject *message,\r
- PyObject *filename, int lineno,\r
- PyObject *module, PyObject *registry, PyObject *sourceline)\r
-{\r
- PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL;\r
- PyObject *item = Py_None;\r
- const char *action;\r
- int rc;\r
-\r
- if (registry && !PyDict_Check(registry) && (registry != Py_None)) {\r
- PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");\r
- return NULL;\r
- }\r
-\r
- /* Normalize module. */\r
- if (module == NULL) {\r
- module = normalize_module(filename);\r
- if (module == NULL)\r
- return NULL;\r
- }\r
- else\r
- Py_INCREF(module);\r
-\r
- /* Normalize message. */\r
- Py_INCREF(message); /* DECREF'ed in cleanup. */\r
- rc = PyObject_IsInstance(message, PyExc_Warning);\r
- if (rc == -1) {\r
- goto cleanup;\r
- }\r
- if (rc == 1) {\r
- text = PyObject_Str(message);\r
- if (text == NULL)\r
- goto cleanup;\r
- category = (PyObject*)message->ob_type;\r
- }\r
- else {\r
- text = message;\r
- message = PyObject_CallFunction(category, "O", message);\r
- if (message == NULL)\r
- goto cleanup;\r
- }\r
-\r
- lineno_obj = PyInt_FromLong(lineno);\r
- if (lineno_obj == NULL)\r
- goto cleanup;\r
-\r
- /* Create key. */\r
- key = PyTuple_Pack(3, text, category, lineno_obj);\r
- if (key == NULL)\r
- goto cleanup;\r
-\r
- if ((registry != NULL) && (registry != Py_None)) {\r
- rc = already_warned(registry, key, 0);\r
- if (rc == -1)\r
- goto cleanup;\r
- else if (rc == 1)\r
- goto return_none;\r
- /* Else this warning hasn't been generated before. */\r
- }\r
-\r
- action = get_filter(category, text, lineno, module, &item);\r
- if (action == NULL)\r
- goto cleanup;\r
-\r
- if (strcmp(action, "error") == 0) {\r
- PyErr_SetObject(category, message);\r
- goto cleanup;\r
- }\r
-\r
- /* Store in the registry that we've been here, *except* when the action\r
- is "always". */\r
- rc = 0;\r
- if (strcmp(action, "always") != 0) {\r
- if (registry != NULL && registry != Py_None &&\r
- PyDict_SetItem(registry, key, Py_True) < 0)\r
- goto cleanup;\r
- else if (strcmp(action, "ignore") == 0)\r
- goto return_none;\r
- else if (strcmp(action, "once") == 0) {\r
- if (registry == NULL || registry == Py_None) {\r
- registry = get_once_registry();\r
- if (registry == NULL)\r
- goto cleanup;\r
- }\r
- /* _once_registry[(text, category)] = 1 */\r
- rc = update_registry(registry, text, category, 0);\r
- }\r
- else if (strcmp(action, "module") == 0) {\r
- /* registry[(text, category, 0)] = 1 */\r
- if (registry != NULL && registry != Py_None)\r
- rc = update_registry(registry, text, category, 0);\r
- }\r
- else if (strcmp(action, "default") != 0) {\r
- PyObject *to_str = PyObject_Str(item);\r
- const char *err_str = "???";\r
-\r
- if (to_str != NULL)\r
- err_str = PyString_AS_STRING(to_str);\r
- PyErr_Format(PyExc_RuntimeError,\r
- "Unrecognized action (%s) in warnings.filters:\n %s",\r
- action, err_str);\r
- Py_XDECREF(to_str);\r
- goto cleanup;\r
- }\r
- }\r
-\r
- if (rc == 1) /* Already warned for this module. */\r
- goto return_none;\r
- if (rc == 0) {\r
- PyObject *show_fxn = get_warnings_attr("showwarning");\r
- if (show_fxn == NULL) {\r
- if (PyErr_Occurred())\r
- goto cleanup;\r
- show_warning(filename, lineno, text, category, sourceline);\r
- }\r
- else {\r
- PyObject *res;\r
-\r
- if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "warnings.showwarning() must be set to a "\r
- "function or method");\r
- Py_DECREF(show_fxn);\r
- goto cleanup;\r
- }\r
-\r
- res = PyObject_CallFunctionObjArgs(show_fxn, message, category,\r
- filename, lineno_obj,\r
- NULL);\r
- Py_DECREF(show_fxn);\r
- Py_XDECREF(res);\r
- if (res == NULL)\r
- goto cleanup;\r
- }\r
- }\r
- else /* if (rc == -1) */\r
- goto cleanup;\r
-\r
- return_none:\r
- result = Py_None;\r
- Py_INCREF(result);\r
-\r
- cleanup:\r
- Py_XDECREF(key);\r
- Py_XDECREF(text);\r
- Py_XDECREF(lineno_obj);\r
- Py_DECREF(module);\r
- Py_XDECREF(message);\r
- return result; /* Py_None or NULL. */\r
-}\r
-\r
-/* filename, module, and registry are new refs, globals is borrowed */\r
-/* Returns 0 on error (no new refs), 1 on success */\r
-static int\r
-setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,\r
- PyObject **module, PyObject **registry)\r
-{\r
- PyObject *globals;\r
-\r
- /* Setup globals and lineno. */\r
- PyFrameObject *f = PyThreadState_GET()->frame;\r
- while (--stack_level > 0 && f != NULL)\r
- f = f->f_back;\r
-\r
- if (f == NULL) {\r
- globals = PyThreadState_Get()->interp->sysdict;\r
- *lineno = 1;\r
- }\r
- else {\r
- globals = f->f_globals;\r
- *lineno = PyFrame_GetLineNumber(f);\r
- }\r
-\r
- *module = NULL;\r
-\r
- /* Setup registry. */\r
- assert(globals != NULL);\r
- assert(PyDict_Check(globals));\r
- *registry = PyDict_GetItemString(globals, "__warningregistry__");\r
- if (*registry == NULL) {\r
- int rc;\r
-\r
- *registry = PyDict_New();\r
- if (*registry == NULL)\r
- return 0;\r
-\r
- rc = PyDict_SetItemString(globals, "__warningregistry__", *registry);\r
- if (rc < 0)\r
- goto handle_error;\r
- }\r
- else\r
- Py_INCREF(*registry);\r
-\r
- /* Setup module. */\r
- *module = PyDict_GetItemString(globals, "__name__");\r
- if (*module == NULL) {\r
- *module = PyString_FromString("<string>");\r
- if (*module == NULL)\r
- goto handle_error;\r
- }\r
- else\r
- Py_INCREF(*module);\r
-\r
- /* Setup filename. */\r
- *filename = PyDict_GetItemString(globals, "__file__");\r
- if (*filename != NULL && PyString_Check(*filename)) {\r
- Py_ssize_t len = PyString_Size(*filename);\r
- const char *file_str = PyString_AsString(*filename);\r
- if (file_str == NULL || (len < 0 && PyErr_Occurred()))\r
- goto handle_error;\r
-\r
- /* if filename.lower().endswith((".pyc", ".pyo")): */\r
- if (len >= 4 &&\r
- file_str[len-4] == '.' &&\r
- tolower(file_str[len-3]) == 'p' &&\r
- tolower(file_str[len-2]) == 'y' &&\r
- (tolower(file_str[len-1]) == 'c' ||\r
- tolower(file_str[len-1]) == 'o'))\r
- {\r
- *filename = PyString_FromStringAndSize(file_str, len-1);\r
- if (*filename == NULL)\r
- goto handle_error;\r
- }\r
- else\r
- Py_INCREF(*filename);\r
- }\r
- else {\r
- const char *module_str = PyString_AsString(*module);\r
- *filename = NULL;\r
- if (module_str && strcmp(module_str, "__main__") == 0) {\r
- PyObject *argv = PySys_GetObject("argv");\r
- if (argv != NULL && PyList_Size(argv) > 0) {\r
- int is_true;\r
- *filename = PyList_GetItem(argv, 0);\r
- Py_INCREF(*filename);\r
- /* If sys.argv[0] is false, then use '__main__'. */\r
- is_true = PyObject_IsTrue(*filename);\r
- if (is_true < 0) {\r
- Py_DECREF(*filename);\r
- goto handle_error;\r
- }\r
- else if (!is_true) {\r
- Py_DECREF(*filename);\r
- *filename = PyString_FromString("__main__");\r
- if (*filename == NULL)\r
- goto handle_error;\r
- }\r
- }\r
- else {\r
- /* embedded interpreters don't have sys.argv, see bug #839151 */\r
- *filename = PyString_FromString("__main__");\r
- if (*filename == NULL)\r
- goto handle_error;\r
- }\r
- }\r
- if (*filename == NULL) {\r
- *filename = *module;\r
- Py_INCREF(*filename);\r
- }\r
- }\r
-\r
- return 1;\r
-\r
- handle_error:\r
- /* filename not XDECREF'ed here as there is no way to jump here with a\r
- dangling reference. */\r
- Py_XDECREF(*registry);\r
- Py_XDECREF(*module);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-get_category(PyObject *message, PyObject *category)\r
-{\r
- int rc;\r
-\r
- /* Get category. */\r
- rc = PyObject_IsInstance(message, PyExc_Warning);\r
- if (rc == -1)\r
- return NULL;\r
-\r
- if (rc == 1)\r
- category = (PyObject*)message->ob_type;\r
- else if (category == NULL)\r
- category = PyExc_UserWarning;\r
-\r
- /* Validate category. */\r
- rc = PyObject_IsSubclass(category, PyExc_Warning);\r
- if (rc == -1)\r
- return NULL;\r
- if (rc == 0) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "category is not a subclass of Warning");\r
- return NULL;\r
- }\r
-\r
- return category;\r
-}\r
-\r
-static PyObject *\r
-do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level)\r
-{\r
- PyObject *filename, *module, *registry, *res;\r
- int lineno;\r
-\r
- if (!setup_context(stack_level, &filename, &lineno, &module, ®istry))\r
- return NULL;\r
-\r
- res = warn_explicit(category, message, filename, lineno, module, registry,\r
- NULL);\r
- Py_DECREF(filename);\r
- Py_DECREF(registry);\r
- Py_DECREF(module);\r
- return res;\r
-}\r
-\r
-static PyObject *\r
-warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)\r
-{\r
- static char *kw_list[] = { "message", "category", "stacklevel", 0 };\r
- PyObject *message, *category = NULL;\r
- Py_ssize_t stack_level = 1;\r
-\r
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,\r
- &message, &category, &stack_level))\r
- return NULL;\r
-\r
- category = get_category(message, category);\r
- if (category == NULL)\r
- return NULL;\r
- return do_warn(message, category, stack_level);\r
-}\r
-\r
-static PyObject *\r
-warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)\r
-{\r
- static char *kwd_list[] = {"message", "category", "filename", "lineno",\r
- "module", "registry", "module_globals", 0};\r
- PyObject *message;\r
- PyObject *category;\r
- PyObject *filename;\r
- int lineno;\r
- PyObject *module = NULL;\r
- PyObject *registry = NULL;\r
- PyObject *module_globals = NULL;\r
-\r
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOi|OOO:warn_explicit",\r
- kwd_list, &message, &category, &filename, &lineno, &module,\r
- ®istry, &module_globals))\r
- return NULL;\r
-\r
- if (module_globals) {\r
- static PyObject *get_source_name = NULL;\r
- static PyObject *splitlines_name = NULL;\r
- PyObject *loader;\r
- PyObject *module_name;\r
- PyObject *source;\r
- PyObject *source_list;\r
- PyObject *source_line;\r
- PyObject *returned;\r
-\r
- if (get_source_name == NULL) {\r
- get_source_name = PyString_InternFromString("get_source");\r
- if (!get_source_name)\r
- return NULL;\r
- }\r
- if (splitlines_name == NULL) {\r
- splitlines_name = PyString_InternFromString("splitlines");\r
- if (!splitlines_name)\r
- return NULL;\r
- }\r
-\r
- /* Check/get the requisite pieces needed for the loader. */\r
- loader = PyDict_GetItemString(module_globals, "__loader__");\r
- module_name = PyDict_GetItemString(module_globals, "__name__");\r
-\r
- if (loader == NULL || module_name == NULL)\r
- goto standard_call;\r
-\r
- /* Make sure the loader implements the optional get_source() method. */\r
- if (!PyObject_HasAttrString(loader, "get_source"))\r
- goto standard_call;\r
- /* Call get_source() to get the source code. */\r
- source = PyObject_CallMethodObjArgs(loader, get_source_name,\r
- module_name, NULL);\r
- if (!source)\r
- return NULL;\r
- else if (source == Py_None) {\r
- Py_DECREF(Py_None);\r
- goto standard_call;\r
- }\r
-\r
- /* Split the source into lines. */\r
- source_list = PyObject_CallMethodObjArgs(source, splitlines_name,\r
- NULL);\r
- Py_DECREF(source);\r
- if (!source_list)\r
- return NULL;\r
-\r
- /* Get the source line. */\r
- source_line = PyList_GetItem(source_list, lineno-1);\r
- if (!source_line) {\r
- Py_DECREF(source_list);\r
- return NULL;\r
- }\r
-\r
- /* Handle the warning. */\r
- returned = warn_explicit(category, message, filename, lineno, module,\r
- registry, source_line);\r
- Py_DECREF(source_list);\r
- return returned;\r
- }\r
-\r
- standard_call:\r
- return warn_explicit(category, message, filename, lineno, module,\r
- registry, NULL);\r
-}\r
-\r
-\r
-/* Function to issue a warning message; may raise an exception. */\r
-int\r
-PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)\r
-{\r
- PyObject *res;\r
- PyObject *message = PyString_FromString(text);\r
- if (message == NULL)\r
- return -1;\r
-\r
- if (category == NULL)\r
- category = PyExc_RuntimeWarning;\r
-\r
- res = do_warn(message, category, stack_level);\r
- Py_DECREF(message);\r
- if (res == NULL)\r
- return -1;\r
- Py_DECREF(res);\r
-\r
- return 0;\r
-}\r
-\r
-/* PyErr_Warn is only for backwards compatibility and will be removed.\r
- Use PyErr_WarnEx instead. */\r
-\r
-#undef PyErr_Warn\r
-\r
-PyAPI_FUNC(int)\r
-PyErr_Warn(PyObject *category, char *text)\r
-{\r
- return PyErr_WarnEx(category, text, 1);\r
-}\r
-\r
-/* Warning with explicit origin */\r
-int\r
-PyErr_WarnExplicit(PyObject *category, const char *text,\r
- const char *filename_str, int lineno,\r
- const char *module_str, PyObject *registry)\r
-{\r
- PyObject *res;\r
- PyObject *message = PyString_FromString(text);\r
- PyObject *filename = PyString_FromString(filename_str);\r
- PyObject *module = NULL;\r
- int ret = -1;\r
-\r
- if (message == NULL || filename == NULL)\r
- goto exit;\r
- if (module_str != NULL) {\r
- module = PyString_FromString(module_str);\r
- if (module == NULL)\r
- goto exit;\r
- }\r
-\r
- if (category == NULL)\r
- category = PyExc_RuntimeWarning;\r
- res = warn_explicit(category, message, filename, lineno, module, registry,\r
- NULL);\r
- if (res == NULL)\r
- goto exit;\r
- Py_DECREF(res);\r
- ret = 0;\r
-\r
- exit:\r
- Py_XDECREF(message);\r
- Py_XDECREF(module);\r
- Py_XDECREF(filename);\r
- return ret;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(warn_doc,\r
-"Issue a warning, or maybe ignore it or raise an exception.");\r
-\r
-PyDoc_STRVAR(warn_explicit_doc,\r
-"Low-level inferface to warnings functionality.");\r
-\r
-static PyMethodDef warnings_functions[] = {\r
- {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS,\r
- warn_doc},\r
- {"warn_explicit", (PyCFunction)warnings_warn_explicit,\r
- METH_VARARGS | METH_KEYWORDS, warn_explicit_doc},\r
- /* XXX(brett.cannon): add showwarning? */\r
- /* XXX(brett.cannon): Reasonable to add formatwarning? */\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-\r
-static PyObject *\r
-create_filter(PyObject *category, const char *action)\r
-{\r
- static PyObject *ignore_str = NULL;\r
- static PyObject *error_str = NULL;\r
- static PyObject *default_str = NULL;\r
- PyObject *action_obj = NULL;\r
- PyObject *lineno, *result;\r
-\r
- if (!strcmp(action, "ignore")) {\r
- if (ignore_str == NULL) {\r
- ignore_str = PyString_InternFromString("ignore");\r
- if (ignore_str == NULL)\r
- return NULL;\r
- }\r
- action_obj = ignore_str;\r
- }\r
- else if (!strcmp(action, "error")) {\r
- if (error_str == NULL) {\r
- error_str = PyString_InternFromString("error");\r
- if (error_str == NULL)\r
- return NULL;\r
- }\r
- action_obj = error_str;\r
- }\r
- else if (!strcmp(action, "default")) {\r
- if (default_str == NULL) {\r
- default_str = PyString_InternFromString("default");\r
- if (default_str == NULL)\r
- return NULL;\r
- }\r
- action_obj = default_str;\r
- }\r
- else {\r
- Py_FatalError("unknown action");\r
- }\r
-\r
- /* This assumes the line number is zero for now. */\r
- lineno = PyInt_FromLong(0);\r
- if (lineno == NULL)\r
- return NULL;\r
- result = PyTuple_Pack(5, action_obj, Py_None, category, Py_None, lineno);\r
- Py_DECREF(lineno);\r
- return result;\r
-}\r
-\r
-static PyObject *\r
-init_filters(void)\r
-{\r
- /* Don't silence DeprecationWarning if -3 or -Q were used. */\r
- PyObject *filters = PyList_New(Py_Py3kWarningFlag ||\r
- Py_DivisionWarningFlag ? 3 : 4);\r
- unsigned int pos = 0; /* Post-incremented in each use. */\r
- unsigned int x;\r
- const char *bytes_action;\r
-\r
- if (filters == NULL)\r
- return NULL;\r
-\r
- /* If guard changes, make sure to update 'filters' initialization above. */\r
- if (!Py_Py3kWarningFlag && !Py_DivisionWarningFlag) {\r
- PyList_SET_ITEM(filters, pos++,\r
- create_filter(PyExc_DeprecationWarning, "ignore"));\r
- }\r
- PyList_SET_ITEM(filters, pos++,\r
- create_filter(PyExc_PendingDeprecationWarning, "ignore"));\r
- PyList_SET_ITEM(filters, pos++,\r
- create_filter(PyExc_ImportWarning, "ignore"));\r
- if (Py_BytesWarningFlag > 1)\r
- bytes_action = "error";\r
- else if (Py_BytesWarningFlag)\r
- bytes_action = "default";\r
- else\r
- bytes_action = "ignore";\r
- PyList_SET_ITEM(filters, pos++, create_filter(PyExc_BytesWarning,\r
- bytes_action));\r
-\r
- for (x = 0; x < pos; x += 1) {\r
- if (PyList_GET_ITEM(filters, x) == NULL) {\r
- Py_DECREF(filters);\r
- return NULL;\r
- }\r
- }\r
-\r
- return filters;\r
-}\r
-\r
-\r
-PyMODINIT_FUNC\r
-_PyWarnings_Init(void)\r
-{\r
- PyObject *m;\r
-\r
- m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);\r
- if (m == NULL)\r
- return;\r
-\r
- _filters = init_filters();\r
- if (_filters == NULL)\r
- return;\r
- Py_INCREF(_filters);\r
- if (PyModule_AddObject(m, "filters", _filters) < 0)\r
- return;\r
-\r
- _once_registry = PyDict_New();\r
- if (_once_registry == NULL)\r
- return;\r
- Py_INCREF(_once_registry);\r
- if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)\r
- return;\r
-\r
- _default_action = PyString_FromString("default");\r
- if (_default_action == NULL)\r
- return;\r
- Py_INCREF(_default_action);\r
- if (PyModule_AddObject(m, "default_action", _default_action) < 0)\r
- return;\r
-}\r