]> granicus.if.org Git - python/commitdiff
Issue #9425: Create PyErr_WarnFormat() function
authorVictor Stinner <victor.stinner@haypocalc.com>
Fri, 13 Aug 2010 14:03:48 +0000 (14:03 +0000)
committerVictor Stinner <victor.stinner@haypocalc.com>
Fri, 13 Aug 2010 14:03:48 +0000 (14:03 +0000)
Similar to PyErr_WarnEx() but use PyUnicode_FromFormatV() to format the warning
message.

Strip also some trailing spaces.

Doc/c-api/exceptions.rst
Include/warnings.h
Misc/NEWS
Objects/moduleobject.c
Objects/typeobject.c
Objects/unicodeobject.c
Python/_warnings.c

index 619f0f6398be8cb198871fea0013f9607ca6a1ed..fcbd50ba7ae6ddc72625abc8ce0948ad1a4e33f1 100644 (file)
@@ -302,12 +302,12 @@ in various ways.  There is a separate error indicator for each thread.
    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
-   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
-   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,
    and so forth.
 
@@ -348,6 +348,13 @@ in various ways.  There is a separate error indicator for each thread.
    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()
 
    .. index::
index f54eabd24544d4e4d60664661cb4e39830533e24..c84cb9f27433622cd671b08b489a673a936ea128 100644 (file)
@@ -7,6 +7,7 @@ extern "C" {
 PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
 
 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,
                                     const char *, PyObject *);
 
index 4f6d3b3556e6383d252aa3583911f703cafee75f..dc3191f6b257e4841e0df3da9e1492276cc299a5 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
 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
   of an array.
 
@@ -85,7 +88,7 @@ Library
   Thread-local objects involved in reference cycles will be deallocated
   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.
 
 - Issue #6231: Fix xml.etree.ElementInclude to include the tail of the
index 6c6eac1c8d4f9ce511f82a3b1de28bd569727a95..7b8e1b63c4af76a53b97f17edf58bbcd7fb1900b 100644 (file)
@@ -56,10 +56,6 @@ PyModule_New(const char *name)
     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 *
 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;
     if (module_api_version != PYTHON_API_VERSION) {
-        char message[512];
-        PyOS_snprintf(message, sizeof(message),
-                      api_version_warning, name,
-                      PYTHON_API_VERSION, name,
-                      module_api_version);
-        if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1))
+        int err;
+        err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
+            "Python C API version mismatch for module %.100s: "
+            "This Python has API version %d, module %.100s has version %d.",
+             name,
+             PYTHON_API_VERSION, name, module_api_version);
+        if (err)
             return NULL;
     }
     /* Make sure name is fully qualified.
index 268a9244bbf37a566f9cc5ac74a5ae4b3fa076bd..7bb686421bf845c3836a0d207a139dcbab96dec1 100644 (file)
@@ -3892,13 +3892,10 @@ PyType_Ready(PyTypeObject *type)
        tp_reserved) but not tp_richcompare. */
     if (type->tp_reserved && !type->tp_richcompare) {
         int error;
-        char msg[240];
-        PyOS_snprintf(msg, sizeof(msg),
-                      "Type %.100s defines tp_reserved (formerly "
-                      "tp_compare) but not tp_richcompare. "
-                      "Comparisons may not behave as intended.",
-                      type->tp_name);
-        error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1);
+        error = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+            "Type %.100s defines tp_reserved (formerly tp_compare) "
+            "but not tp_richcompare. Comparisons may not behave as intended.",
+            type->tp_name);
         if (error == -1)
             goto error;
     }
index 849f33e07604ecfb50924df5fe10c3cd0a074a0d..7c9b8827389f4efbba58e247ec0f4ad48eec6bfb 100644 (file)
@@ -755,7 +755,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
     char fmt[61]; /* should be enough for %0width.precisionlld */
     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
      * (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/
      * 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 (PyByteArray_Check(v)) {
-        char msg[100];
+        int error;
         PyObject *b;
-        PyOS_snprintf(msg, sizeof(msg),
-                      "encoder %s returned buffer instead of bytes",
-                      encoding);
-        if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
+
+        error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
+            "encoder %s returned bytearray instead of bytes",
+            encoding);
+        if (error) {
             Py_DECREF(v);
             return NULL;
         }
@@ -2279,7 +2280,7 @@ char utf8_code_length[256] = {
        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,
-    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,
index 6067ce3a47b51d598e484df52efe73a55e3cf288..63bcbffea9fddb22f501f94230d9e3bc592219f8 100644 (file)
@@ -710,19 +710,17 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
 
 
 /* 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 *message = PyUnicode_FromString(text);
-    if (message == NULL)
-        return -1;
 
     if (category == NULL)
         category = PyExc_RuntimeWarning;
 
     res = do_warn(message, category, stack_level);
-    Py_DECREF(message);
     if (res == NULL)
         return -1;
     Py_DECREF(res);
@@ -730,6 +728,42 @@ PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level)
     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.
    Use PyErr_WarnEx instead. */