From 6a27efa2d321c2b262c0cab3c2d4af3e2e8a9ead Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 30 Oct 2008 21:48:26 +0000 Subject: [PATCH] Issue 3723: Fixed initialization of subinterpreters The patch fixes several issues with Py_NewInterpreter as well as the demo for multiple subinterpreters. Most of the patch was written by MvL with help from Benjamin, Amaury and me. Graham Dumpleton has verified that this patch fixes an issue with mod_wsgi. --- Demo/embed/importexc.c | 8 +++++++- Include/pystate.h | 1 + Misc/NEWS | 2 ++ Objects/unicodeobject.c | 13 +++++++++++++ Python/bltinmodule.c | 2 +- Python/codecs.c | 1 + Python/pystate.c | 1 + Python/pythonrun.c | 16 ++++++++++++++++ Python/sysmodule.c | 2 +- 9 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c index 375ce1b686..59b1d01d87 100644 --- a/Demo/embed/importexc.c +++ b/Demo/embed/importexc.c @@ -1,14 +1,20 @@ #include -char* cmd = "import exceptions"; +#if 0 +char* cmd = "import codecs, encodings.utf_8, types; print(types)"; +#else +char* cmd = "import types; print(types)"; +#endif int main() { + printf("Initialize interpreter\n"); Py_Initialize(); PyEval_InitThreads(); PyRun_SimpleString(cmd); Py_EndInterpreter(PyThreadState_Get()); + printf("\nInitialize subinterpreter\n"); Py_NewInterpreter(); PyRun_SimpleString(cmd); Py_Finalize(); diff --git a/Include/pystate.h b/Include/pystate.h index 8508da0554..e02df88f8c 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -27,6 +27,7 @@ typedef struct _is { PyObject *codec_search_path; PyObject *codec_search_cache; PyObject *codec_error_registry; + int codecs_initialized; #ifdef HAVE_DLOPEN int dlopenflags; diff --git a/Misc/NEWS b/Misc/NEWS index 72a482eff6..b8d17c123c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -15,6 +15,8 @@ What's New in Python 3.0 beta 5 Core and Builtins ----------------- +- Issue 3723: Fixed initialization of subinterpreters. + - Issue #4213: The file system encoding is now normalized by the codec subsystem, for example UTF-8 is turned into utf-8. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ecd44cb788..2beb0984b4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1346,6 +1346,19 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, #endif else if (strcmp(encoding, "ascii") == 0) return PyUnicode_AsASCIIString(unicode); + /* During bootstrap, we may need to find the encodings + package, to load the file system encoding, and require the + file system encoding in order to load the encodings + package. + + Break out of this dependency by assuming that the path to + the encodings module is ASCII-only. XXX could try wcstombs + instead, if the file system encoding is the locale's + encoding. */ + else if (Py_FileSystemDefaultEncoding && + strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && + !PyThreadState_GET()->interp->codecs_initialized) + return PyUnicode_AsASCIIString(unicode); } /* Encode via the codec registry */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 8159fe84d5..d7f5084a58 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2282,7 +2282,7 @@ static struct PyModuleDef builtinsmodule = { PyModuleDef_HEAD_INIT, "builtins", builtin_doc, - 0, + -1, /* multiple "initialization" just copies the module dict. */ builtin_methods, NULL, NULL, diff --git a/Python/codecs.c b/Python/codecs.c index 66576c481c..ebddc09d7b 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -869,5 +869,6 @@ static int _PyCodecRegistry_Init(void) return -1; } Py_DECREF(mod); + interp->codecs_initialized = 1; return 0; } diff --git a/Python/pystate.c b/Python/pystate.c index 9479256718..2a9b7443f9 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -76,6 +76,7 @@ PyInterpreterState_New(void) interp->codec_search_path = NULL; interp->codec_search_cache = NULL; interp->codec_error_registry = NULL; + interp->codecs_initialized = 0; #ifdef HAVE_DLOPEN #ifdef RTLD_NOW interp->dlopenflags = RTLD_NOW; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 4fb2b3e40d..61cdf6d745 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -562,8 +562,13 @@ Py_NewInterpreter(void) goto handle_error; Py_INCREF(interp->builtins); } + + /* initialize builtin exceptions */ + _PyExc_Init(); + sysmod = _PyImport_FindExtension("sys", "sys"); if (bimod != NULL && sysmod != NULL) { + PyObject *pstderr; interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) goto handle_error; @@ -571,7 +576,18 @@ Py_NewInterpreter(void) PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + PySys_SetObject("stderr", pstderr); + PySys_SetObject("__stderr__", pstderr); + _PyImportHooks_Init(); + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); initmain(); if (!Py_NoSiteFlag) initsite(); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 952f7e5904..af960bc070 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1231,7 +1231,7 @@ static struct PyModuleDef sysmodule = { PyModuleDef_HEAD_INIT, "sys", sys_doc, - 0, + -1, /* multiple "initialization" just copies the module dict. */ sys_methods, NULL, NULL, -- 2.40.0