Issue #10914: Initialize correctly the filesystem codec when creating a new
subinterpreter to fix a bootstrap issue with codecs implemented in Python, as the ISO-8859-15 codec. Add fscodec_initialized attribute to the PyInterpreterState structure.
This commit is contained in:
parent
1188935af9
commit
3cbf14bfb1
|
@ -31,6 +31,7 @@ typedef struct _is {
|
||||||
PyObject *codec_search_cache;
|
PyObject *codec_search_cache;
|
||||||
PyObject *codec_error_registry;
|
PyObject *codec_error_registry;
|
||||||
int codecs_initialized;
|
int codecs_initialized;
|
||||||
|
int fscodec_initialized;
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
int dlopenflags;
|
int dlopenflags;
|
||||||
|
|
|
@ -10,6 +10,10 @@ What's New in Python 3.2.1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #10914: Initialize correctly the filesystem codec when creating a new
|
||||||
|
subinterpreter to fix a bootstrap issue with codecs implemented in Python, as
|
||||||
|
the ISO-8859-15 codec.
|
||||||
|
|
||||||
- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*
|
- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*
|
||||||
APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch
|
APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch
|
||||||
by Charles-François Natali.
|
by Charles-François Natali.
|
||||||
|
|
|
@ -1626,7 +1626,17 @@ PyUnicode_EncodeFSDefault(PyObject *unicode)
|
||||||
PyUnicode_GET_SIZE(unicode),
|
PyUnicode_GET_SIZE(unicode),
|
||||||
"surrogateescape");
|
"surrogateescape");
|
||||||
#else
|
#else
|
||||||
if (Py_FileSystemDefaultEncoding) {
|
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
||||||
|
/* Bootstrap check: if the filesystem codec is implemented in Python, we
|
||||||
|
cannot use it to encode and decode filenames before it is loaded. Load
|
||||||
|
the Python codec requires to encode at least its own filename. Use the C
|
||||||
|
version of the locale codec until the codec registry is initialized and
|
||||||
|
the Python codec is loaded.
|
||||||
|
|
||||||
|
Py_FileSystemDefaultEncoding is shared between all interpreters, we
|
||||||
|
cannot only rely on it: check also interp->fscodec_initialized for
|
||||||
|
subinterpreters. */
|
||||||
|
if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
|
||||||
return PyUnicode_AsEncodedString(unicode,
|
return PyUnicode_AsEncodedString(unicode,
|
||||||
Py_FileSystemDefaultEncoding,
|
Py_FileSystemDefaultEncoding,
|
||||||
"surrogateescape");
|
"surrogateescape");
|
||||||
|
@ -1818,12 +1828,17 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
return PyUnicode_DecodeUTF8(s, size, "surrogateescape");
|
return PyUnicode_DecodeUTF8(s, size, "surrogateescape");
|
||||||
#else
|
#else
|
||||||
/* During the early bootstrapping process, Py_FileSystemDefaultEncoding
|
PyInterpreterState *interp = PyThreadState_GET()->interp;
|
||||||
can be undefined. If it is case, decode using UTF-8. The following assumes
|
/* Bootstrap check: if the filesystem codec is implemented in Python, we
|
||||||
that Py_FileSystemDefaultEncoding is set to a built-in encoding during the
|
cannot use it to encode and decode filenames before it is loaded. Load
|
||||||
bootstrapping process where the codecs aren't ready yet.
|
the Python codec requires to encode at least its own filename. Use the C
|
||||||
*/
|
version of the locale codec until the codec registry is initialized and
|
||||||
if (Py_FileSystemDefaultEncoding) {
|
the Python codec is loaded.
|
||||||
|
|
||||||
|
Py_FileSystemDefaultEncoding is shared between all interpreters, we
|
||||||
|
cannot only rely on it: check also interp->fscodec_initialized for
|
||||||
|
subinterpreters. */
|
||||||
|
if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
|
||||||
return PyUnicode_Decode(s, size,
|
return PyUnicode_Decode(s, size,
|
||||||
Py_FileSystemDefaultEncoding,
|
Py_FileSystemDefaultEncoding,
|
||||||
"surrogateescape");
|
"surrogateescape");
|
||||||
|
|
|
@ -79,6 +79,7 @@ PyInterpreterState_New(void)
|
||||||
interp->codec_search_cache = NULL;
|
interp->codec_search_cache = NULL;
|
||||||
interp->codec_error_registry = NULL;
|
interp->codec_error_registry = NULL;
|
||||||
interp->codecs_initialized = 0;
|
interp->codecs_initialized = 0;
|
||||||
|
interp->fscodec_initialized = 0;
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
#ifdef RTLD_NOW
|
#ifdef RTLD_NOW
|
||||||
interp->dlopenflags = RTLD_NOW;
|
interp->dlopenflags = RTLD_NOW;
|
||||||
|
|
|
@ -53,7 +53,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static void initmain(void);
|
static void initmain(void);
|
||||||
static void initfsencoding(void);
|
static int initfsencoding(PyInterpreterState *interp);
|
||||||
static void initsite(void);
|
static void initsite(void);
|
||||||
static int initstdio(void);
|
static int initstdio(void);
|
||||||
static void flush_io(void);
|
static void flush_io(void);
|
||||||
|
@ -291,7 +291,8 @@ Py_InitializeEx(int install_sigs)
|
||||||
|
|
||||||
_PyTime_Init();
|
_PyTime_Init();
|
||||||
|
|
||||||
initfsencoding();
|
if (initfsencoding(interp) < 0)
|
||||||
|
Py_FatalError("Py_Initialize: unable to load the file system codec");
|
||||||
|
|
||||||
if (install_sigs)
|
if (install_sigs)
|
||||||
initsigs(); /* Signal handling stuff, including initintr() */
|
initsigs(); /* Signal handling stuff, including initintr() */
|
||||||
|
@ -608,6 +609,10 @@ Py_NewInterpreter(void)
|
||||||
Py_DECREF(pstderr);
|
Py_DECREF(pstderr);
|
||||||
|
|
||||||
_PyImportHooks_Init();
|
_PyImportHooks_Init();
|
||||||
|
|
||||||
|
if (initfsencoding(interp) < 0)
|
||||||
|
goto handle_error;
|
||||||
|
|
||||||
if (initstdio() < 0)
|
if (initstdio() < 0)
|
||||||
Py_FatalError(
|
Py_FatalError(
|
||||||
"Py_Initialize: can't initialize sys standard streams");
|
"Py_Initialize: can't initialize sys standard streams");
|
||||||
|
@ -720,8 +725,8 @@ initmain(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
initfsencoding(void)
|
initfsencoding(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
PyObject *codec;
|
PyObject *codec;
|
||||||
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
|
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
|
||||||
|
@ -738,7 +743,8 @@ initfsencoding(void)
|
||||||
|
|
||||||
Py_FileSystemDefaultEncoding = codeset;
|
Py_FileSystemDefaultEncoding = codeset;
|
||||||
Py_HasFileSystemDefaultEncoding = 0;
|
Py_HasFileSystemDefaultEncoding = 0;
|
||||||
return;
|
interp->fscodec_initialized = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -748,10 +754,11 @@ initfsencoding(void)
|
||||||
/* Such error can only occurs in critical situations: no more
|
/* Such error can only occurs in critical situations: no more
|
||||||
* memory, import a module of the standard library failed,
|
* memory, import a module of the standard library failed,
|
||||||
* etc. */
|
* etc. */
|
||||||
Py_FatalError("Py_Initialize: unable to load the file system codec");
|
return -1;
|
||||||
} else {
|
|
||||||
Py_DECREF(codec);
|
|
||||||
}
|
}
|
||||||
|
Py_DECREF(codec);
|
||||||
|
interp->fscodec_initialized = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Import the site module (not into __main__ though) */
|
/* Import the site module (not into __main__ though) */
|
||||||
|
|
Loading…
Reference in New Issue