Issue #9425: Create PyErr_WarnFormat() function
Similar to PyErr_WarnEx() but use PyUnicode_FromFormatV() to format the warning message. Strip also some trailing spaces.
This commit is contained in:
parent
b4b8eb9163
commit
4a2b7a1b14
|
@ -302,12 +302,12 @@ in various ways. There is a separate error indicator for each thread.
|
||||||
use.
|
use.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: int PyErr_WarnEx(PyObject *category, char *message, int stacklevel)
|
.. cfunction:: int PyErr_WarnEx(PyObject *category, char *message, int stack_level)
|
||||||
|
|
||||||
Issue a warning message. The *category* argument is a warning category (see
|
Issue a warning message. The *category* argument is a warning category (see
|
||||||
below) or *NULL*; the *message* argument is a message string. *stacklevel* is a
|
below) or *NULL*; the *message* argument is a message string. *stack_level* is a
|
||||||
positive number giving a number of stack frames; the warning will be issued from
|
positive number giving a number of stack frames; the warning will be issued from
|
||||||
the currently executing line of code in that stack frame. A *stacklevel* of 1
|
the currently executing line of code in that stack frame. A *stack_level* of 1
|
||||||
is the function calling :cfunc:`PyErr_WarnEx`, 2 is the function above that,
|
is the function calling :cfunc:`PyErr_WarnEx`, 2 is the function above that,
|
||||||
and so forth.
|
and so forth.
|
||||||
|
|
||||||
|
@ -348,6 +348,13 @@ in various ways. There is a separate error indicator for each thread.
|
||||||
described there.
|
described there.
|
||||||
|
|
||||||
|
|
||||||
|
.. cfunction:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
|
||||||
|
|
||||||
|
Function similar to :cfunc:`PyErr_WarnEx`, but use
|
||||||
|
:cfunc:`PyUnicode_FromFormatV` to format the warning message.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
.. cfunction:: int PyErr_CheckSignals()
|
.. cfunction:: int PyErr_CheckSignals()
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
|
|
|
@ -7,6 +7,7 @@ extern "C" {
|
||||||
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
|
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
|
PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
|
||||||
|
PyAPI_FUNC(int) PyErr_WarnFormat(PyObject *, Py_ssize_t, const char *, ...);
|
||||||
PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int,
|
PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int,
|
||||||
const char *, PyObject *);
|
const char *, PyObject *);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #9425: Create PyErr_WarnFormat() function, similar to PyErr_WarnEx()
|
||||||
|
but use PyUnicode_FromFormatV() to format the warning message.
|
||||||
|
|
||||||
- Issue #8530: Prevent stringlib fastsearch from reading beyond the front
|
- Issue #8530: Prevent stringlib fastsearch from reading beyond the front
|
||||||
of an array.
|
of an array.
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ Library
|
||||||
Thread-local objects involved in reference cycles will be deallocated
|
Thread-local objects involved in reference cycles will be deallocated
|
||||||
timely by the cyclic GC, even if the underlying thread is still running.
|
timely by the cyclic GC, even if the underlying thread is still running.
|
||||||
|
|
||||||
- Issue #9452: Add read_file, read_string, and read_dict to the configparser
|
- Issue #9452: Add read_file, read_string, and read_dict to the configparser
|
||||||
API; new source attribute to exceptions.
|
API; new source attribute to exceptions.
|
||||||
|
|
||||||
- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the
|
- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the
|
||||||
|
|
|
@ -56,10 +56,6 @@ PyModule_New(const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char api_version_warning[] =
|
|
||||||
"Python C API version mismatch for module %.100s:\
|
|
||||||
This Python has API version %d, module %.100s has version %d.";
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
|
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
|
||||||
{
|
{
|
||||||
|
@ -79,12 +75,13 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version)
|
||||||
}
|
}
|
||||||
name = module->m_name;
|
name = module->m_name;
|
||||||
if (module_api_version != PYTHON_API_VERSION) {
|
if (module_api_version != PYTHON_API_VERSION) {
|
||||||
char message[512];
|
int err;
|
||||||
PyOS_snprintf(message, sizeof(message),
|
err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
|
||||||
api_version_warning, name,
|
"Python C API version mismatch for module %.100s: "
|
||||||
PYTHON_API_VERSION, name,
|
"This Python has API version %d, module %.100s has version %d.",
|
||||||
module_api_version);
|
name,
|
||||||
if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1))
|
PYTHON_API_VERSION, name, module_api_version);
|
||||||
|
if (err)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Make sure name is fully qualified.
|
/* Make sure name is fully qualified.
|
||||||
|
|
|
@ -3892,13 +3892,10 @@ PyType_Ready(PyTypeObject *type)
|
||||||
tp_reserved) but not tp_richcompare. */
|
tp_reserved) but not tp_richcompare. */
|
||||||
if (type->tp_reserved && !type->tp_richcompare) {
|
if (type->tp_reserved && !type->tp_richcompare) {
|
||||||
int error;
|
int error;
|
||||||
char msg[240];
|
error = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
|
||||||
PyOS_snprintf(msg, sizeof(msg),
|
"Type %.100s defines tp_reserved (formerly tp_compare) "
|
||||||
"Type %.100s defines tp_reserved (formerly "
|
"but not tp_richcompare. Comparisons may not behave as intended.",
|
||||||
"tp_compare) but not tp_richcompare. "
|
type->tp_name);
|
||||||
"Comparisons may not behave as intended.",
|
|
||||||
type->tp_name);
|
|
||||||
error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1);
|
|
||||||
if (error == -1)
|
if (error == -1)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,7 +755,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
char fmt[61]; /* should be enough for %0width.precisionlld */
|
char fmt[61]; /* should be enough for %0width.precisionlld */
|
||||||
const char *copy;
|
const char *copy;
|
||||||
|
|
||||||
Py_VA_COPY(count, vargs);
|
Py_VA_COPY(count, vargs);
|
||||||
/* step 1: count the number of %S/%R/%A/%s format specifications
|
/* step 1: count the number of %S/%R/%A/%s format specifications
|
||||||
* (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/
|
* (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/
|
||||||
* PyUnicode_DecodeUTF8() for these objects once during step 3 and put the
|
* PyUnicode_DecodeUTF8() for these objects once during step 3 and put the
|
||||||
|
@ -1548,12 +1548,13 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
|
||||||
|
|
||||||
/* If the codec returns a buffer, raise a warning and convert to bytes */
|
/* If the codec returns a buffer, raise a warning and convert to bytes */
|
||||||
if (PyByteArray_Check(v)) {
|
if (PyByteArray_Check(v)) {
|
||||||
char msg[100];
|
int error;
|
||||||
PyObject *b;
|
PyObject *b;
|
||||||
PyOS_snprintf(msg, sizeof(msg),
|
|
||||||
"encoder %s returned buffer instead of bytes",
|
error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
|
||||||
encoding);
|
"encoder %s returned bytearray instead of bytes",
|
||||||
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
|
encoding);
|
||||||
|
if (error) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2279,7 +2280,7 @@ char utf8_code_length[256] = {
|
||||||
illegal prefix. See RFC 3629 for details */
|
illegal prefix. See RFC 3629 for details */
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
|
|
@ -710,19 +710,17 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
|
|
||||||
|
|
||||||
/* Function to issue a warning message; may raise an exception. */
|
/* Function to issue a warning message; may raise an exception. */
|
||||||
int
|
|
||||||
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
|
static int
|
||||||
|
warn_unicode(PyObject *category, PyObject *message,
|
||||||
|
Py_ssize_t stack_level)
|
||||||
{
|
{
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
PyObject *message = PyUnicode_FromString(text);
|
|
||||||
if (message == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (category == NULL)
|
if (category == NULL)
|
||||||
category = PyExc_RuntimeWarning;
|
category = PyExc_RuntimeWarning;
|
||||||
|
|
||||||
res = do_warn(message, category, stack_level);
|
res = do_warn(message, category, stack_level);
|
||||||
Py_DECREF(message);
|
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
Py_DECREF(res);
|
Py_DECREF(res);
|
||||||
|
@ -730,6 +728,42 @@ PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
|
||||||
|
const char *format, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
PyObject *message;
|
||||||
|
va_list vargs;
|
||||||
|
|
||||||
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
va_start(vargs, format);
|
||||||
|
#else
|
||||||
|
va_start(vargs);
|
||||||
|
#endif
|
||||||
|
message = PyUnicode_FromFormatV(format, vargs);
|
||||||
|
if (message != NULL) {
|
||||||
|
ret = warn_unicode(category, message, stack_level);
|
||||||
|
Py_DECREF(message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = -1;
|
||||||
|
va_end(vargs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
PyObject *message = PyUnicode_FromString(text);
|
||||||
|
if (message == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = warn_unicode(category, message, stack_level);
|
||||||
|
Py_DECREF(message);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* PyErr_Warn is only for backwards compatability and will be removed.
|
/* PyErr_Warn is only for backwards compatability and will be removed.
|
||||||
Use PyErr_WarnEx instead. */
|
Use PyErr_WarnEx instead. */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue