]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Patch #710576: Implement per-interpreter-state codec registries.
authorMartin v. Löwis <martin@v.loewis.de>
Sun, 30 Mar 2003 20:57:31 +0000 (20:57 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sun, 30 Mar 2003 20:57:31 +0000 (20:57 +0000)
Include/pystate.h
Misc/NEWS
Python/codecs.c
Python/pystate.c
Python/pythonrun.c

index 9aa8ec8d577bc9c6610546b241098cd189ea43c3..40d2d0d77e0fa393be659620a20fe575e3c0ba01 100644 (file)
@@ -27,6 +27,9 @@ typedef struct _is {
     int dlopenflags;
 #endif
 
+    PyObject *codec_search_path;
+    PyObject *codec_search_cache;
+
 } PyInterpreterState;
 
 
index 56f0a80384b5d926e36077d887f9baaad251e92e..bff0d0cedcb76a5d60843eb755796256fab6023e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,10 @@ What's New in Python 2.2.3 ?
 Release date: XX-XXX-2003
 ============================
 
+- SF #710576: Backport of fix for #663074, to implement per-interpreter
+  codecs registries. This adds new members at the end of
+  PyInterpreterState.
+
 - SF #705836: The platform-independent routines for packing floats in
   IEEE formats (struct.pack's <f, >f, <d, and >d codes; pickle and
   cPickle's protocol 1 pickling of floats) ignored that rounding can
index cc0fabcb1898534165b6a3fbc43e91135f2eb87d..c7acd55fb7e343b1a8a2887b80642735c05f1cef 100644 (file)
@@ -11,14 +11,6 @@ Copyright (c) Corporation for National Research Initiatives.
 #include "Python.h"
 #include <ctype.h>
 
-/* --- Globals ------------------------------------------------------------ */
-
-static PyObject *_PyCodec_SearchPath;
-static PyObject *_PyCodec_SearchCache;
-
-/* Flag used for lazy import of the standard encodings package */
-static int import_encodings_called = 0;
-
 /* --- Codec Registry ----------------------------------------------------- */
 
 /* Import the standard encodings package which will register the first
@@ -32,35 +24,13 @@ static int import_encodings_called = 0;
 
 */
 
-static
-int import_encodings(void)
-{
-    PyObject *mod;
-    
-    import_encodings_called = 1;
-    mod = PyImport_ImportModule("encodings");
-    if (mod == NULL) {
-       if (PyErr_ExceptionMatches(PyExc_ImportError)) {
-           /* Ignore ImportErrors... this is done so that
-              distributions can disable the encodings package. Note
-              that other errors are not masked, e.g. SystemErrors
-              raised to inform the user of an error in the Python
-              configuration are still reported back to the user. */
-           PyErr_Clear();
-           return 0;
-       }
-       return -1;
-    }
-    Py_DECREF(mod);
-    return 0;
-}
+static int _PyCodecRegistry_Init(void); /* Forward */
 
 int PyCodec_Register(PyObject *search_function)
 {
-    if (!import_encodings_called) {
-       if (import_encodings())
-           goto onError;
-    }
+    PyInterpreterState *interp = PyThreadState_Get()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+       goto onError;
     if (search_function == NULL) {
        PyErr_BadArgument();
        goto onError;
@@ -70,7 +40,7 @@ int PyCodec_Register(PyObject *search_function)
                        "argument must be callable");
        goto onError;
     }
-    return PyList_Append(_PyCodec_SearchPath, search_function);
+    return PyList_Append(interp->codec_search_path, search_function);
 
  onError:
     return -1;
@@ -124,6 +94,7 @@ PyObject *normalizestring(const char *string)
 
 PyObject *_PyCodec_Lookup(const char *encoding)
 {
+    PyInterpreterState *interp;
     PyObject *result, *args = NULL, *v;
     int i, len;
 
@@ -131,16 +102,10 @@ PyObject *_PyCodec_Lookup(const char *encoding)
        PyErr_BadArgument();
        goto onError;
     }
-    if (_PyCodec_SearchCache == NULL || 
-       _PyCodec_SearchPath == NULL) {
-       PyErr_SetString(PyExc_SystemError,
-                       "codec module not properly initialized");
+
+    interp = PyThreadState_Get()->interp;
+    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
        goto onError;
-    }
-    if (!import_encodings_called) {
-       if (import_encodings())
-           goto onError;
-    }
 
     /* Convert the encoding to a normalized Python string: all
        characters are converted to lower case, spaces and hyphens are
@@ -151,7 +116,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
     PyString_InternInPlace(&v);
 
     /* First, try to lookup the name in the registry dictionary */
-    result = PyDict_GetItem(_PyCodec_SearchCache, v);
+    result = PyDict_GetItem(interp->codec_search_cache, v);
     if (result != NULL) {
        Py_INCREF(result);
        Py_DECREF(v);
@@ -164,7 +129,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
        goto onError;
     PyTuple_SET_ITEM(args,0,v);
 
-    len = PyList_Size(_PyCodec_SearchPath);
+    len = PyList_Size(interp->codec_search_path);
     if (len < 0)
        goto onError;
     if (len == 0) {
@@ -177,7 +142,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
     for (i = 0; i < len; i++) {
        PyObject *func;
        
-       func = PyList_GetItem(_PyCodec_SearchPath, i);
+       func = PyList_GetItem(interp->codec_search_path, i);
        if (func == NULL)
            goto onError;
        result = PyEval_CallObject(func, args);
@@ -203,7 +168,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
     }
 
     /* Cache and return the result */
-    PyDict_SetItem(_PyCodec_SearchCache, v, result);
+    PyDict_SetItem(interp->codec_search_cache, v, result);
     Py_DECREF(args);
     return result;
 
@@ -422,21 +387,34 @@ PyObject *PyCodec_Decode(PyObject *object,
     return NULL;
 }
 
-void _PyCodecRegistry_Init(void)
+static int _PyCodecRegistry_Init(void)
 {
-    if (_PyCodec_SearchPath == NULL)
-       _PyCodec_SearchPath = PyList_New(0);
-    if (_PyCodec_SearchCache == NULL)
-       _PyCodec_SearchCache = PyDict_New();
-    if (_PyCodec_SearchPath == NULL || 
-       _PyCodec_SearchCache == NULL)
+    PyInterpreterState *interp = PyThreadState_Get()->interp;
+    PyObject *mod;
+
+    if (interp->codec_search_path != NULL)
+       return 0;
+
+    interp->codec_search_path = PyList_New(0);
+    interp->codec_search_cache = PyDict_New();
+
+    if (interp->codec_search_path == NULL ||
+       interp->codec_search_cache == NULL)
        Py_FatalError("can't initialize codec registry");
-}
 
-void _PyCodecRegistry_Fini(void)
-{
-    Py_XDECREF(_PyCodec_SearchPath);
-    _PyCodec_SearchPath = NULL;
-    Py_XDECREF(_PyCodec_SearchCache);
-    _PyCodec_SearchCache = NULL;
+    mod = PyImport_ImportModuleEx("encodings", NULL, NULL, NULL);
+    if (mod == NULL) {
+       if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+           /* Ignore ImportErrors... this is done so that
+              distributions can disable the encodings package. Note
+              that other errors are not masked, e.g. SystemErrors
+              raised to inform the user of an error in the Python
+              configuration are still reported back to the user. */
+           PyErr_Clear();
+           return 0;
+       }
+       return -1;
+    }
+    Py_DECREF(mod);
+    return 0;
 }
index e6b0d84f2daee2b53532b8dece6bc11c91868b91..57fffc73e8cb5bd714133270fdfaefa10b9a4d23 100644 (file)
@@ -50,6 +50,8 @@ PyInterpreterState_New(void)
                interp->builtins = NULL;
                interp->checkinterval = 10;
                interp->tstate_head = NULL;
+               interp->codec_search_path = NULL;
+               interp->codec_search_cache = NULL;
 #ifdef HAVE_DLOPEN
 #ifdef RTLD_NOW
                 interp->dlopenflags = RTLD_NOW;
@@ -76,6 +78,8 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
        for (p = interp->tstate_head; p != NULL; p = p->next)
                PyThreadState_Clear(p);
        HEAD_UNLOCK();
+       ZAP(interp->codec_search_path);
+       ZAP(interp->codec_search_cache);
        ZAP(interp->modules);
        ZAP(interp->sysdict);
        ZAP(interp->builtins);
index 51d71e0da453888c0e08c538a96dbc27f2402971..2f25bfb92101121f830b4f8c9948f5319d845b9c 100644 (file)
@@ -49,8 +49,6 @@ int _Py_AskYesNo(char *prompt);
 
 extern void _PyUnicode_Init(void);
 extern void _PyUnicode_Fini(void);
-extern void _PyCodecRegistry_Init(void);
-extern void _PyCodecRegistry_Fini(void);
 
 int Py_DebugFlag; /* Needed by parser.c */
 int Py_VerboseFlag; /* Needed by import.c */
@@ -133,9 +131,6 @@ Py_Initialize(void)
        if (interp->modules == NULL)
                Py_FatalError("Py_Initialize: can't make modules dictionary");
 
-       /* Init codec registry */
-       _PyCodecRegistry_Init();
-
 #ifdef Py_USING_UNICODE
        /* Init Unicode implementation; relies on the codec registry */
        _PyUnicode_Init();
@@ -219,9 +214,6 @@ Py_Finalize(void)
        /* Disable signal handling */
        PyOS_FiniInterrupts();
 
-       /* Cleanup Codec registry */
-       _PyCodecRegistry_Fini();
-
        /* Destroy all modules */
        PyImport_Cleanup();