FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

bpo-31572: Get rid of _PyObject_HasAttrId() and PyDict_GetItemString() in warnings. by serhiy-storchaka · Pull Request #3731 · python/cpython · GitHub

/ cpython Public
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
157 changes: 89 additions & 68 deletions Python/_warnings.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ get_warnings_attr(const char *attr, int try_import)
if (warnings_module == NULL) {
/* Fallback to the C implementation if we cannot get
the Python implementation */
PyErr_Clear();
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
PyErr_Clear();
}
return NULL;
}
}
Expand All @@ -62,13 +64,11 @@ get_warnings_attr(const char *attr, int try_import)
return NULL;
}

if (!PyObject_HasAttrString(warnings_module, attr)) {
Py_DECREF(warnings_module);
return NULL;
}

obj = PyObject_GetAttrString(warnings_module, attr);
Py_DECREF(warnings_module);
if (obj == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_Clear();
}
return obj;
}

Expand All @@ -82,16 +82,18 @@ get_once_registry(void)
if (registry == NULL) {
if (PyErr_Occurred())
return NULL;
assert(_PyRuntime.warnings.once_registry);
return _PyRuntime.warnings.once_registry;
}
if (!PyDict_Check(registry)) {
PyErr_SetString(PyExc_TypeError,
"warnings.onceregistry must be a dict");
PyErr_Format(PyExc_TypeError,
MODULE_NAME ".onceregistry must be a dict, "
"not '%.200s'",
Py_TYPE(registry)->tp_name);
Py_DECREF(registry);
return NULL;
}
Py_DECREF(_PyRuntime.warnings.once_registry);
_PyRuntime.warnings.once_registry = registry;
Py_SETREF(_PyRuntime.warnings.once_registry, registry);
return registry;
}

Expand All @@ -106,6 +108,7 @@ get_default_action(void)
if (PyErr_Occurred()) {
return NULL;
}
assert(_PyRuntime.warnings.default_action);
return _PyRuntime.warnings.default_action;
}
if (!PyUnicode_Check(default_action)) {
Expand All @@ -116,8 +119,7 @@ get_default_action(void)
Py_DECREF(default_action);
return NULL;
}
Py_DECREF(_PyRuntime.warnings.default_action);
_PyRuntime.warnings.default_action = default_action;
Py_SETREF(_PyRuntime.warnings.default_action, default_action);
return default_action;
}

Expand All @@ -137,8 +139,7 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
return NULL;
}
else {
Py_DECREF(_PyRuntime.warnings.filters);
_PyRuntime.warnings.filters = warnings_filters;
Py_SETREF(_PyRuntime.warnings.filters, warnings_filters);
}

PyObject *filters = _PyRuntime.warnings.filters;
Expand Down Expand Up @@ -408,8 +409,10 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message,

warnmsg_cls = get_warnings_attr("WarningMessage", 0);
if (warnmsg_cls == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"unable to get warnings.WarningMessage");
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
"unable to get warnings.WarningMessage");
}
goto error;
}

Expand Down Expand Up @@ -837,6 +840,68 @@ warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category,
return do_warn(message, category, stacklevel, source);
}

static PyObject *
get_source_line(PyObject *module_globals, int lineno)
{
_Py_IDENTIFIER(get_source);
_Py_IDENTIFIER(__loader__);
_Py_IDENTIFIER(__name__);
PyObject *loader;
PyObject *module_name;
PyObject *get_source;
PyObject *source;
PyObject *source_list;
PyObject *source_line;

/* Check/get the requisite pieces needed for the loader. */
loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__);
if (loader == NULL) {
return NULL;
}
Py_INCREF(loader);
module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__);
if (!module_name) {
Py_DECREF(loader);
return NULL;
}
Py_INCREF(module_name);

/* Make sure the loader implements the optional get_source() method. */
get_source = _PyObject_GetAttrId(loader, &PyId_get_source);
Py_DECREF(loader);
if (!get_source) {
Py_DECREF(module_name);
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_Clear();
}
return NULL;
}
/* Call get_source() to get the source code. */
source = PyObject_CallFunctionObjArgs(get_source, module_name, NULL);
Py_DECREF(get_source);
Py_DECREF(module_name);
if (!source) {
return NULL;
}
if (source == Py_None) {
Py_DECREF(source);
return NULL;
}

/* Split the source into lines. */
source_list = PyUnicode_Splitlines(source, 0);
Py_DECREF(source);
if (!source_list) {
return NULL;
}

/* Get the source line. */
source_line = PyList_GetItem(source_list, lineno-1);
Py_XINCREF(source_line);
Py_DECREF(source_list);
return source_line;
}

static PyObject *
warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
{
Expand All @@ -851,68 +916,24 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *registry = NULL;
PyObject *module_globals = NULL;
PyObject *sourceobj = NULL;
PyObject *source_line = NULL;
PyObject *returned;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit",
kwd_list, &message, &category, &filename, &lineno, &module,
&registry, &module_globals, &sourceobj))
return NULL;

if (module_globals) {
_Py_IDENTIFIER(get_source);
PyObject *tmp;
PyObject *loader;
PyObject *module_name;
PyObject *source;
PyObject *source_list;
PyObject *source_line;
PyObject *returned;

if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
return NULL;

/* Check/get the requisite pieces needed for the loader. */
loader = PyDict_GetItemString(module_globals, "__loader__");
module_name = PyDict_GetItemString(module_globals, "__name__");

if (loader == NULL || module_name == NULL)
goto standard_call;

/* Make sure the loader implements the optional get_source() method. */
if (!_PyObject_HasAttrId(loader, &PyId_get_source))
goto standard_call;
/* Call get_source() to get the source code. */
source = PyObject_CallMethodObjArgs(loader, PyId_get_source.object,
module_name, NULL);
if (!source)
source_line = get_source_line(module_globals, lineno);
if (source_line == NULL && PyErr_Occurred()) {
return NULL;
else if (source == Py_None) {
Py_DECREF(Py_None);
goto standard_call;
}

/* Split the source into lines. */
source_list = PyUnicode_Splitlines(source, 0);
Py_DECREF(source);
if (!source_list)
return NULL;

/* Get the source line. */
source_line = PyList_GetItem(source_list, lineno-1);
if (!source_line) {
Py_DECREF(source_list);
return NULL;
}

/* Handle the warning. */
returned = warn_explicit(category, message, filename, lineno, module,
registry, source_line, sourceobj);
Py_DECREF(source_list);
return returned;
}

standard_call:
return warn_explicit(category, message, filename, lineno, module,
registry, NULL, sourceobj);
returned = warn_explicit(category, message, filename, lineno, module,
registry, source_line, sourceobj);
Py_XDECREF(source_line);
return returned;
}

static PyObject *
Expand Down

Back | FazBrowse Home | New Git URL