Issue #16129: Py_SetStandardStreamEncoding cleanups

- 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
This commit is contained in:
Nick Coghlan 2013-10-18 23:11:47 +10:00
parent ac1a248968
commit 1805a62f1f
3 changed files with 22 additions and 9 deletions

View File

@ -93,12 +93,12 @@ Process-wide parameters
single: main() single: main()
triple: stdin; stdout; sdterr triple: stdin; stdout; sdterr
This function should be called before :c:func:`Py_Initialize`. It This function should be called before :c:func:`Py_Initialize`, if it is
specifies which encoding and error handling to use with standard io, called at all. It specifies which encoding and error handling to use
with the same meanings as in :func:`str.encode`. with standard IO, with the same meanings as in :func:`str.encode`.
It overrides :envvar:`PYTHONIOENCODING` values, and allows embedding code 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 ``encoding`` and/or ``errors`` may be NULL to use
:envvar:`PYTHONIOENCODING` and/or default values (depending on other :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 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`. 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) .. c:function:: void Py_SetProgramName(wchar_t *name)

View File

@ -28,8 +28,13 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *); PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); 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, PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
const char *errors); const char *errors);
#endif
PyAPI_FUNC(void) Py_Initialize(void); PyAPI_FUNC(void) Py_Initialize(void);
PyAPI_FUNC(void) Py_InitializeEx(int); PyAPI_FUNC(void) Py_InitializeEx(int);

View File

@ -148,11 +148,17 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
/* This is too late to have any effect */ /* This is too late to have any effect */
return -1; 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) { if (encoding) {
_Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
if (!_Py_StandardStreamEncoding) { if (!_Py_StandardStreamEncoding) {
PyErr_NoMemory(); return -2;
return -1;
} }
} }
if (errors) { if (errors) {
@ -161,8 +167,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
if (_Py_StandardStreamEncoding) { if (_Py_StandardStreamEncoding) {
PyMem_RawFree(_Py_StandardStreamEncoding); PyMem_RawFree(_Py_StandardStreamEncoding);
} }
PyErr_NoMemory(); return -3;
return -1;
} }
} }
return 0; return 0;