Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4a2b7a1

Browse files
author
Victor Stinner
committed
Issue #9425: Create PyErr_WarnFormat() function
Similar to PyErr_WarnEx() but use PyUnicode_FromFormatV() to format the warning message. Strip also some trailing spaces.
1 parent b4b8eb9 commit 4a2b7a1

7 files changed

Lines changed: 74 additions & 34 deletions

File tree

Doc/c-api/exceptions.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,12 @@ in various ways. There is a separate error indicator for each thread.
302302
use.
303303

304304

305-
.. cfunction:: int PyErr_WarnEx(PyObject *category, char *message, int stacklevel)
305+
.. cfunction:: int PyErr_WarnEx(PyObject *category, char *message, int stack_level)
306306

307307
Issue a warning message. The *category* argument is a warning category (see
308-
below) or *NULL*; the *message* argument is a message string. *stacklevel* is a
308+
below) or *NULL*; the *message* argument is a message string. *stack_level* is a
309309
positive number giving a number of stack frames; the warning will be issued from
310-
the currently executing line of code in that stack frame. A *stacklevel* of 1
310+
the currently executing line of code in that stack frame. A *stack_level* of 1
311311
is the function calling :cfunc:`PyErr_WarnEx`, 2 is the function above that,
312312
and so forth.
313313

@@ -348,6 +348,13 @@ in various ways. There is a separate error indicator for each thread.
348348
described there.
349349

350350

351+
.. cfunction:: int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...)
352+
353+
Function similar to :cfunc:`PyErr_WarnEx`, but use
354+
:cfunc:`PyUnicode_FromFormatV` to format the warning message.
355+
356+
.. versionadded:: 3.2
357+
351358
.. cfunction:: int PyErr_CheckSignals()
352359

353360
.. index::

Include/warnings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern "C" {
77
PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
88

99
PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
10+
PyAPI_FUNC(int) PyErr_WarnFormat(PyObject *, Py_ssize_t, const char *, ...);
1011
PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int,
1112
const char *, PyObject *);
1213

Misc/NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #9425: Create PyErr_WarnFormat() function, similar to PyErr_WarnEx()
16+
but use PyUnicode_FromFormatV() to format the warning message.
17+
1518
- Issue #8530: Prevent stringlib fastsearch from reading beyond the front
1619
of an array.
1720

@@ -85,7 +88,7 @@ Library
8588
Thread-local objects involved in reference cycles will be deallocated
8689
timely by the cyclic GC, even if the underlying thread is still running.
8790

88-
- Issue #9452: Add read_file, read_string, and read_dict to the configparser
91+
- Issue #9452: Add read_file, read_string, and read_dict to the configparser
8992
API; new source attribute to exceptions.
9093

9194
- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the

Objects/moduleobject.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ PyModule_New(const char *name)
5656
return NULL;
5757
}
5858

59-
static char api_version_warning[] =
60-
"Python C API version mismatch for module %.100s:\
61-
This Python has API version %d, module %.100s has version %d.";
62-
6359
PyObject *
6460
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
6561
{
@@ -79,12 +75,13 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version)
7975
}
8076
name = module->m_name;
8177
if (module_api_version != PYTHON_API_VERSION) {
82-
char message[512];
83-
PyOS_snprintf(message, sizeof(message),
84-
api_version_warning, name,
85-
PYTHON_API_VERSION, name,
86-
module_api_version);
87-
if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1))
78+
int err;
79+
err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
80+
"Python C API version mismatch for module %.100s: "
81+
"This Python has API version %d, module %.100s has version %d.",
82+
name,
83+
PYTHON_API_VERSION, name, module_api_version);
84+
if (err)
8885
return NULL;
8986
}
9087
/* Make sure name is fully qualified.

Objects/typeobject.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3892,13 +3892,10 @@ PyType_Ready(PyTypeObject *type)
38923892
tp_reserved) but not tp_richcompare. */
38933893
if (type->tp_reserved && !type->tp_richcompare) {
38943894
int error;
3895-
char msg[240];
3896-
PyOS_snprintf(msg, sizeof(msg),
3897-
"Type %.100s defines tp_reserved (formerly "
3898-
"tp_compare) but not tp_richcompare. "
3899-
"Comparisons may not behave as intended.",
3900-
type->tp_name);
3901-
error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1);
3895+
error = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
3896+
"Type %.100s defines tp_reserved (formerly tp_compare) "
3897+
"but not tp_richcompare. Comparisons may not behave as intended.",
3898+
type->tp_name);
39023899
if (error == -1)
39033900
goto error;
39043901
}

Objects/unicodeobject.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
755755
char fmt[61]; /* should be enough for %0width.precisionlld */
756756
const char *copy;
757757

758-
Py_VA_COPY(count, vargs);
758+
Py_VA_COPY(count, vargs);
759759
/* step 1: count the number of %S/%R/%A/%s format specifications
760760
* (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/
761761
* PyUnicode_DecodeUTF8() for these objects once during step 3 and put the
@@ -1548,12 +1548,13 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
15481548

15491549
/* If the codec returns a buffer, raise a warning and convert to bytes */
15501550
if (PyByteArray_Check(v)) {
1551-
char msg[100];
1551+
int error;
15521552
PyObject *b;
1553-
PyOS_snprintf(msg, sizeof(msg),
1554-
"encoder %s returned buffer instead of bytes",
1555-
encoding);
1556-
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
1553+
1554+
error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
1555+
"encoder %s returned bytearray instead of bytes",
1556+
encoding);
1557+
if (error) {
15571558
Py_DECREF(v);
15581559
return NULL;
15591560
}
@@ -2279,7 +2280,7 @@ char utf8_code_length[256] = {
22792280
illegal prefix. See RFC 3629 for details */
22802281
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */
22812282
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2282-
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2283+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22832284
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22842285
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22852286
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

Python/_warnings.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -710,26 +710,60 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
710710

711711

712712
/* Function to issue a warning message; may raise an exception. */
713-
int
714-
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
713+
714+
static int
715+
warn_unicode(PyObject *category, PyObject *message,
716+
Py_ssize_t stack_level)
715717
{
716718
PyObject *res;
717-
PyObject *message = PyUnicode_FromString(text);
718-
if (message == NULL)
719-
return -1;
720719

721720
if (category == NULL)
722721
category = PyExc_RuntimeWarning;
723722

724723
res = do_warn(message, category, stack_level);
725-
Py_DECREF(message);
726724
if (res == NULL)
727725
return -1;
728726
Py_DECREF(res);
729727

730728
return 0;
731729
}
732730

731+
int
732+
PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level,
733+
const char *format, ...)
734+
{
735+
int ret;
736+
PyObject *message;
737+
va_list vargs;
738+
739+
#ifdef HAVE_STDARG_PROTOTYPES
740+
va_start(vargs, format);
741+
#else
742+
va_start(vargs);
743+
#endif
744+
message = PyUnicode_FromFormatV(format, vargs);
745+
if (message != NULL) {
746+
ret = warn_unicode(category, message, stack_level);
747+
Py_DECREF(message);
748+
}
749+
else
750+
ret = -1;
751+
va_end(vargs);
752+
return ret;
753+
}
754+
755+
int
756+
PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
757+
{
758+
int ret;
759+
PyObject *message = PyUnicode_FromString(text);
760+
if (message == NULL)
761+
return -1;
762+
ret = warn_unicode(category, message, stack_level);
763+
Py_DECREF(message);
764+
return ret;
765+
}
766+
733767
/* PyErr_Warn is only for backwards compatability and will be removed.
734768
Use PyErr_WarnEx instead. */
735769

0 commit comments

Comments
 (0)