]> granicus.if.org Git - python/commitdiff
Issue #16129: Py_SetStandardStreamEncoding cleanups
authorNick Coghlan <ncoghlan@gmail.com>
Fri, 18 Oct 2013 13:11:47 +0000 (23:11 +1000)
committerNick Coghlan <ncoghlan@gmail.com>
Fri, 18 Oct 2013 13:11:47 +0000 (23:11 +1000)
- don't call PyErr_NoMemory with interpreter is not initialised
- note that it's OK to call _PyMem_RawStrDup here
- don't include this in the limited API
- capitalise "IO"
- be explicit that a non-zero return indicates an error
- include versionadded marker in docs

Doc/c-api/init.rst
Include/pythonrun.h
Python/pythonrun.c

index 1a54321710951b38aa1df34828b32c89019030db..6439d7f11de32c0496dd8ab03c135baa99cb38ed 100644 (file)
@@ -93,12 +93,12 @@ Process-wide parameters
       single: main()
       triple: stdin; stdout; sdterr
 
-   This function should be called before :c:func:`Py_Initialize`. It
-   specifies which encoding and error handling to use with standard io,
-   with the same meanings as in :func:`str.encode`.
+   This function should be called before :c:func:`Py_Initialize`, if it is
+   called at all. It specifies which encoding and error handling to use
+   with standard IO, with the same meanings as in :func:`str.encode`.
 
    It overrides :envvar:`PYTHONIOENCODING` values, and allows embedding code
-   to control io encoding when the environment variable does not work.
+   to control IO encoding when the environment variable does not work.
 
    ``encoding`` and/or ``errors`` may be NULL to use
    :envvar:`PYTHONIOENCODING` and/or default values (depending on other
@@ -110,7 +110,10 @@ Process-wide parameters
    If :c:func:`Py_Finalize` is called, this function will need to be called
    again in order to affect subsequent calls to :c:func:`Py_Initialize`.
 
-   Returns 0 if successful.
+   Returns 0 if successful, a nonzero value on error (e.g. calling after the
+   interpreter has already been initialized).
+
+   .. versionadded:: 3.4
 
 
 .. c:function:: void Py_SetProgramName(wchar_t *name)
index 4cc4dcd07a9b050c9ec2cb6031c615edc0fe41f3..7f67ab7829763f0aec4e02646965ef249eb95faa 100644 (file)
@@ -28,8 +28,13 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
 PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
 PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
 
+#ifndef Py_LIMITED_API
+/* Only used by applications that embed the interpreter and need to
+ * override the standard encoding determination mechanism
+ */
 PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
                                              const char *errors);
+#endif
 
 PyAPI_FUNC(void) Py_Initialize(void);
 PyAPI_FUNC(void) Py_InitializeEx(int);
index 3bcc4742d1ed695156d24e4160be2861660844d8..b963ce1132600908ea078460f836e6d3c6d98b74 100644 (file)
@@ -148,11 +148,17 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
         /* This is too late to have any effect */
         return -1;
     }
+    /* Can't call PyErr_NoMemory() on errors, as Python hasn't been
+     * initialised yet.
+     *
+     * However, the raw memory allocators are initialised appropriately
+     * as C static variables, so _PyMem_RawStrdup is OK even though
+     * Py_Initialize hasn't been called yet.
+     */
     if (encoding) {
         _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
         if (!_Py_StandardStreamEncoding) {
-            PyErr_NoMemory();
-            return -1;
+            return -2;
         }
     }
     if (errors) {
@@ -161,8 +167,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
             if (_Py_StandardStreamEncoding) {
                 PyMem_RawFree(_Py_StandardStreamEncoding);
             }
-            PyErr_NoMemory();
-            return -1;
+            return -3;
         }
     }
     return 0;