From 1805a62f1fe551b73b80d87a429ef496c1701b07 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Fri, 18 Oct 2013 23:11:47 +1000 Subject: 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 --- Doc/c-api/init.rst | 13 ++++++++----- Include/pythonrun.h | 5 +++++ Python/pythonrun.c | 13 +++++++++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 1a54321..6439d7f 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -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) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 4cc4dcd..7f67ab7 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -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); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3bcc474..b963ce1 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -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; -- cgit v0.12