[Python-checkins] r84094 - in python/branches/py3k: Doc/c-api/sys.rst Include/sysmodule.h Misc/NEWS Python/sysmodule.c

victor.stinner python-checkins at python.org
Mon Aug 16 19:36:43 CEST 2010


Author: victor.stinner
Date: Mon Aug 16 19:36:42 2010
New Revision: 84094

Log:
Issue #9599: Create PySys_FormatStdout() and PySys_FormatStderr()

Write a message formatted by PyUnicode_FromFormatV() to sys.stdout and
sys.stderr.

Modified:
   python/branches/py3k/Doc/c-api/sys.rst
   python/branches/py3k/Include/sysmodule.h
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Doc/c-api/sys.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/sys.rst	(original)
+++ python/branches/py3k/Doc/c-api/sys.rst	Mon Aug 16 19:36:42 2010
@@ -109,8 +109,19 @@
 
 .. cfunction:: void PySys_WriteStderr(const char *format, ...)
 
-   As above, but write to :data:`sys.stderr` or *stderr* instead.
+   As :cfunc:`PySys_WriteStdout`, but write to :data:`sys.stderr` or *stderr*
+   instead.
 
+.. cfunction:: void PySys_FormatStdout(const char *format, ...)
+
+   Function similar to PySys_WriteStdout() but format the message using
+   :cfunc:`PyUnicode_FromFormatV` and don't truncate the message to an
+   arbitrary length.
+
+.. cfunction:: void PySys_FormatStderr(const char *format, ...)
+
+   As :cfunc:`PySys_FormatStdout`, but write to :data:`sys.stderr` or *stderr*
+   instead.
 
 .. _processcontrol:
 

Modified: python/branches/py3k/Include/sysmodule.h
==============================================================================
--- python/branches/py3k/Include/sysmodule.h	(original)
+++ python/branches/py3k/Include/sysmodule.h	Mon Aug 16 19:36:42 2010
@@ -14,9 +14,11 @@
 PyAPI_FUNC(void) PySys_SetPath(const wchar_t *);
 
 PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
-			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+                 Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
 PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
-			Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+                 Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
+PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...);
+PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...);
 
 PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc;
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Aug 16 19:36:42 2010
@@ -12,6 +12,10 @@
 Core and Builtins
 -----------------
 
+- Issue #9599: Create PySys_FormatStdout() and PySys_FormatStderr() functions
+  to write a message formatted by PyUnicode_FromFormatV() to sys.stdout and
+  sys.stderr.
+
 - Issue #9542: Create PyUnicode_FSDecoder() function, a ParseTuple converter:
   decode bytes objects to unicode using PyUnicode_DecodeFSDefaultAndSize();
   str objects are output as-is.

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Mon Aug 16 19:36:42 2010
@@ -1834,18 +1834,14 @@
    PyErr_CheckSignals(): avoid the call to PyObject_Str(). */
 
 static int
-sys_pyfile_write(const char *text, PyObject *file)
+sys_pyfile_write_unicode(PyObject *unicode, PyObject *file)
 {
-    PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL;
+    PyObject *writer = NULL, *args = NULL, *result = NULL;
     int err;
 
     if (file == NULL)
         return -1;
 
-    unicode = PyUnicode_FromString(text);
-    if (unicode == NULL)
-        goto error;
-
     writer = PyObject_GetAttrString(file, "write");
     if (writer == NULL)
         goto error;
@@ -1865,13 +1861,29 @@
 error:
     err = -1;
 finally:
-    Py_XDECREF(unicode);
     Py_XDECREF(writer);
     Py_XDECREF(args);
     Py_XDECREF(result);
     return err;
 }
 
+static int
+sys_pyfile_write(const char *text, PyObject *file)
+{
+    PyObject *unicode = NULL;
+    int err;
+
+    if (file == NULL)
+        return -1;
+
+    unicode = PyUnicode_FromString(text);
+    if (unicode == NULL)
+        return -1;
+
+    err = sys_pyfile_write_unicode(unicode, file);
+    Py_DECREF(unicode);
+    return err;
+}
 
 /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
    Adapted from code submitted by Just van Rossum.
@@ -1884,8 +1896,8 @@
       no exceptions are raised.
 
       PyErr_CheckSignals() is not called to avoid the execution of the Python
-      signal handlers: they may raise a new exception whereas mywrite() ignores
-      all exceptions.
+      signal handlers: they may raise a new exception whereas sys_write()
+      ignores all exceptions.
 
       Both take a printf-style format string as their first argument followed
       by a variable length argument list determined by the format string.
@@ -1902,7 +1914,7 @@
  */
 
 static void
-mywrite(char *name, FILE *fp, const char *format, va_list va)
+sys_write(char *name, FILE *fp, const char *format, va_list va)
 {
     PyObject *file;
     PyObject *error_type, *error_value, *error_traceback;
@@ -1918,10 +1930,8 @@
     }
     if (written < 0 || (size_t)written >= sizeof(buffer)) {
         const char *truncated = "... truncated";
-        if (sys_pyfile_write(truncated, file) != 0) {
-            PyErr_Clear();
+        if (sys_pyfile_write(truncated, file) != 0)
             fputs(truncated, fp);
-        }
     }
     PyErr_Restore(error_type, error_value, error_traceback);
 }
@@ -1932,7 +1942,7 @@
     va_list va;
 
     va_start(va, format);
-    mywrite("stdout", stdout, format, va);
+    sys_write("stdout", stdout, format, va);
     va_end(va);
 }
 
@@ -1942,6 +1952,48 @@
     va_list va;
 
     va_start(va, format);
-    mywrite("stderr", stderr, format, va);
+    sys_write("stderr", stderr, format, va);
+    va_end(va);
+}
+
+static void
+sys_format(char *name, FILE *fp, const char *format, va_list va)
+{
+    PyObject *file, *message;
+    PyObject *error_type, *error_value, *error_traceback;
+    char *utf8;
+
+    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    file = PySys_GetObject(name);
+    message = PyUnicode_FromFormatV(format, va);
+    if (message != NULL) {
+        if (sys_pyfile_write_unicode(message, file) != 0) {
+            PyErr_Clear();
+            utf8 = _PyUnicode_AsString(message);
+            if (utf8 != NULL)
+                fputs(utf8, fp);
+        }
+        Py_DECREF(message);
+    }
+    PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+void
+PySys_FormatStdout(const char *format, ...)
+{
+    va_list va;
+
+    va_start(va, format);
+    sys_format("stdout", stdout, format, va);
+    va_end(va);
+}
+
+void
+PySys_FormatStderr(const char *format, ...)
+{
+    va_list va;
+
+    va_start(va, format);
+    sys_format("stderr", stderr, format, va);
     va_end(va);
 }


More information about the Python-checkins mailing list