Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3cbf14b

Browse files
author
Victor Stinner
committed
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.
1 parent 1188935 commit 3cbf14b

5 files changed

Lines changed: 43 additions & 15 deletions

File tree

Include/pystate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ typedef struct _is {
3131
PyObject *codec_search_cache;
3232
PyObject *codec_error_registry;
3333
int codecs_initialized;
34+
int fscodec_initialized;
3435

3536
#ifdef HAVE_DLOPEN
3637
int dlopenflags;

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ What's New in Python 3.2.1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #10914: Initialize correctly the filesystem codec when creating a new
14+
subinterpreter to fix a bootstrap issue with codecs implemented in Python, as
15+
the ISO-8859-15 codec.
16+
1317
- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_*
1418
APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch
1519
by Charles-François Natali.

Objects/unicodeobject.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,17 @@ PyUnicode_EncodeFSDefault(PyObject *unicode)
16261626
PyUnicode_GET_SIZE(unicode),
16271627
"surrogateescape");
16281628
#else
1629-
if (Py_FileSystemDefaultEncoding) {
1629+
PyInterpreterState *interp = PyThreadState_GET()->interp;
1630+
/* Bootstrap check: if the filesystem codec is implemented in Python, we
1631+
cannot use it to encode and decode filenames before it is loaded. Load
1632+
the Python codec requires to encode at least its own filename. Use the C
1633+
version of the locale codec until the codec registry is initialized and
1634+
the Python codec is loaded.
1635+
1636+
Py_FileSystemDefaultEncoding is shared between all interpreters, we
1637+
cannot only rely on it: check also interp->fscodec_initialized for
1638+
subinterpreters. */
1639+
if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
16301640
return PyUnicode_AsEncodedString(unicode,
16311641
Py_FileSystemDefaultEncoding,
16321642
"surrogateescape");
@@ -1818,12 +1828,17 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
18181828
#elif defined(__APPLE__)
18191829
return PyUnicode_DecodeUTF8(s, size, "surrogateescape");
18201830
#else
1821-
/* During the early bootstrapping process, Py_FileSystemDefaultEncoding
1822-
can be undefined. If it is case, decode using UTF-8. The following assumes
1823-
that Py_FileSystemDefaultEncoding is set to a built-in encoding during the
1824-
bootstrapping process where the codecs aren't ready yet.
1825-
*/
1826-
if (Py_FileSystemDefaultEncoding) {
1831+
PyInterpreterState *interp = PyThreadState_GET()->interp;
1832+
/* Bootstrap check: if the filesystem codec is implemented in Python, we
1833+
cannot use it to encode and decode filenames before it is loaded. Load
1834+
the Python codec requires to encode at least its own filename. Use the C
1835+
version of the locale codec until the codec registry is initialized and
1836+
the Python codec is loaded.
1837+
1838+
Py_FileSystemDefaultEncoding is shared between all interpreters, we
1839+
cannot only rely on it: check also interp->fscodec_initialized for
1840+
subinterpreters. */
1841+
if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
18271842
return PyUnicode_Decode(s, size,
18281843
Py_FileSystemDefaultEncoding,
18291844
"surrogateescape");

Python/pystate.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ PyInterpreterState_New(void)
7979
interp->codec_search_cache = NULL;
8080
interp->codec_error_registry = NULL;
8181
interp->codecs_initialized = 0;
82+
interp->fscodec_initialized = 0;
8283
#ifdef HAVE_DLOPEN
8384
#ifdef RTLD_NOW
8485
interp->dlopenflags = RTLD_NOW;

Python/pythonrun.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */
5353

5454
/* Forward */
5555
static void initmain(void);
56-
static void initfsencoding(void);
56+
static int initfsencoding(PyInterpreterState *interp);
5757
static void initsite(void);
5858
static int initstdio(void);
5959
static void flush_io(void);
@@ -291,7 +291,8 @@ Py_InitializeEx(int install_sigs)
291291

292292
_PyTime_Init();
293293

294-
initfsencoding();
294+
if (initfsencoding(interp) < 0)
295+
Py_FatalError("Py_Initialize: unable to load the file system codec");
295296

296297
if (install_sigs)
297298
initsigs(); /* Signal handling stuff, including initintr() */
@@ -608,6 +609,10 @@ Py_NewInterpreter(void)
608609
Py_DECREF(pstderr);
609610

610611
_PyImportHooks_Init();
612+
613+
if (initfsencoding(interp) < 0)
614+
goto handle_error;
615+
611616
if (initstdio() < 0)
612617
Py_FatalError(
613618
"Py_Initialize: can't initialize sys standard streams");
@@ -720,8 +725,8 @@ initmain(void)
720725
}
721726
}
722727

723-
static void
724-
initfsencoding(void)
728+
static int
729+
initfsencoding(PyInterpreterState *interp)
725730
{
726731
PyObject *codec;
727732
#if defined(HAVE_LANGINFO_H) && defined(CODESET)
@@ -738,7 +743,8 @@ initfsencoding(void)
738743

739744
Py_FileSystemDefaultEncoding = codeset;
740745
Py_HasFileSystemDefaultEncoding = 0;
741-
return;
746+
interp->fscodec_initialized = 1;
747+
return 0;
742748
}
743749
#endif
744750

@@ -748,10 +754,11 @@ initfsencoding(void)
748754
/* Such error can only occurs in critical situations: no more
749755
* memory, import a module of the standard library failed,
750756
* etc. */
751-
Py_FatalError("Py_Initialize: unable to load the file system codec");
752-
} else {
753-
Py_DECREF(codec);
757+
return -1;
754758
}
759+
Py_DECREF(codec);
760+
interp->fscodec_initialized = 1;
761+
return 0;
755762
}
756763

757764
/* Import the site module (not into __main__ though) */

0 commit comments

Comments
 (0)