@@ -11,14 +11,6 @@ Copyright (c) Corporation for National Research Initiatives.
1111#include "Python.h"
1212#include <ctype.h>
1313
14- /* --- Globals ------------------------------------------------------------ */
15-
16- static PyObject * _PyCodec_SearchPath ;
17- static PyObject * _PyCodec_SearchCache ;
18-
19- /* Flag used for lazy import of the standard encodings package */
20- static int import_encodings_called = 0 ;
21-
2214/* --- Codec Registry ----------------------------------------------------- */
2315
2416/* Import the standard encodings package which will register the first
@@ -32,35 +24,13 @@ static int import_encodings_called = 0;
3224
3325*/
3426
35- static
36- int import_encodings (void )
37- {
38- PyObject * mod ;
39-
40- import_encodings_called = 1 ;
41- mod = PyImport_ImportModuleEx ("encodings" , NULL , NULL , NULL );
42- if (mod == NULL ) {
43- if (PyErr_ExceptionMatches (PyExc_ImportError )) {
44- /* Ignore ImportErrors... this is done so that
45- distributions can disable the encodings package. Note
46- that other errors are not masked, e.g. SystemErrors
47- raised to inform the user of an error in the Python
48- configuration are still reported back to the user. */
49- PyErr_Clear ();
50- return 0 ;
51- }
52- return -1 ;
53- }
54- Py_DECREF (mod );
55- return 0 ;
56- }
27+ static int _PyCodecRegistry_Init (void ); /* Forward */
5728
5829int PyCodec_Register (PyObject * search_function )
5930{
60- if (!import_encodings_called ) {
61- if (import_encodings ())
62- goto onError ;
63- }
31+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
32+ if (interp -> codec_search_path == NULL && _PyCodecRegistry_Init ())
33+ goto onError ;
6434 if (search_function == NULL ) {
6535 PyErr_BadArgument ();
6636 goto onError ;
@@ -70,7 +40,7 @@ int PyCodec_Register(PyObject *search_function)
7040 "argument must be callable" );
7141 goto onError ;
7242 }
73- return PyList_Append (_PyCodec_SearchPath , search_function );
43+ return PyList_Append (interp -> codec_search_path , search_function );
7444
7545 onError :
7646 return -1 ;
@@ -124,23 +94,18 @@ PyObject *normalizestring(const char *string)
12494
12595PyObject * _PyCodec_Lookup (const char * encoding )
12696{
97+ PyInterpreterState * interp ;
12798 PyObject * result , * args = NULL , * v ;
12899 int i , len ;
129100
130101 if (encoding == NULL ) {
131102 PyErr_BadArgument ();
132103 goto onError ;
133104 }
134- if (_PyCodec_SearchCache == NULL ||
135- _PyCodec_SearchPath == NULL ) {
136- PyErr_SetString (PyExc_SystemError ,
137- "codec module not properly initialized" );
105+
106+ interp = PyThreadState_Get ()-> interp ;
107+ if (interp -> codec_search_path == NULL && _PyCodecRegistry_Init ())
138108 goto onError ;
139- }
140- if (!import_encodings_called ) {
141- if (import_encodings ())
142- goto onError ;
143- }
144109
145110 /* Convert the encoding to a normalized Python string: all
146111 characters are converted to lower case, spaces and hyphens are
@@ -151,7 +116,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
151116 PyString_InternInPlace (& v );
152117
153118 /* First, try to lookup the name in the registry dictionary */
154- result = PyDict_GetItem (_PyCodec_SearchCache , v );
119+ result = PyDict_GetItem (interp -> codec_search_cache , v );
155120 if (result != NULL ) {
156121 Py_INCREF (result );
157122 Py_DECREF (v );
@@ -164,7 +129,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
164129 goto onError ;
165130 PyTuple_SET_ITEM (args ,0 ,v );
166131
167- len = PyList_Size (_PyCodec_SearchPath );
132+ len = PyList_Size (interp -> codec_search_path );
168133 if (len < 0 )
169134 goto onError ;
170135 if (len == 0 ) {
@@ -177,7 +142,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
177142 for (i = 0 ; i < len ; i ++ ) {
178143 PyObject * func ;
179144
180- func = PyList_GetItem (_PyCodec_SearchPath , i );
145+ func = PyList_GetItem (interp -> codec_search_path , i );
181146 if (func == NULL )
182147 goto onError ;
183148 result = PyEval_CallObject (func , args );
@@ -203,7 +168,7 @@ PyObject *_PyCodec_Lookup(const char *encoding)
203168 }
204169
205170 /* Cache and return the result */
206- PyDict_SetItem (_PyCodec_SearchCache , v , result );
171+ PyDict_SetItem (interp -> codec_search_cache , v , result );
207172 Py_DECREF (args );
208173 return result ;
209174
@@ -422,8 +387,6 @@ PyObject *PyCodec_Decode(PyObject *object,
422387 return NULL ;
423388}
424389
425- static PyObject * _PyCodec_ErrorRegistry ;
426-
427390/* Register the error handling callback function error under the name
428391 name. This function will be called by the codec when it encounters
429392 an unencodable characters/undecodable bytes and doesn't know the
@@ -432,11 +395,15 @@ static PyObject *_PyCodec_ErrorRegistry;
432395 Return 0 on success, -1 on error */
433396int PyCodec_RegisterError (const char * name , PyObject * error )
434397{
398+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
399+ if (interp -> codec_search_path == NULL && _PyCodecRegistry_Init ())
400+ return -1 ;
435401 if (!PyCallable_Check (error )) {
436402 PyErr_SetString (PyExc_TypeError , "handler must be callable" );
437403 return -1 ;
438404 }
439- return PyDict_SetItemString ( _PyCodec_ErrorRegistry , (char * )name , error );
405+ return PyDict_SetItemString (interp -> codec_error_registry ,
406+ (char * )name , error );
440407}
441408
442409/* Lookup the error handling callback function registered under the
@@ -446,9 +413,13 @@ PyObject *PyCodec_LookupError(const char *name)
446413{
447414 PyObject * handler = NULL ;
448415
416+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
417+ if (interp -> codec_search_path == NULL && _PyCodecRegistry_Init ())
418+ return NULL ;
419+
449420 if (name == NULL )
450421 name = "strict" ;
451- handler = PyDict_GetItemString (_PyCodec_ErrorRegistry , (char * )name );
422+ handler = PyDict_GetItemString (interp -> codec_error_registry , (char * )name );
452423 if (!handler )
453424 PyErr_Format (PyExc_LookupError , "unknown error handler name '%.400s'" , name );
454425 else
@@ -762,8 +733,7 @@ static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
762733}
763734#endif
764735
765-
766- void _PyCodecRegistry_Init (void )
736+ static int _PyCodecRegistry_Init (void )
767737{
768738 static struct {
769739 char * name ;
@@ -813,38 +783,49 @@ void _PyCodecRegistry_Init(void)
813783 }
814784#endif
815785 };
816- if (_PyCodec_SearchPath == NULL )
817- _PyCodec_SearchPath = PyList_New (0 );
818- if (_PyCodec_SearchCache == NULL )
819- _PyCodec_SearchCache = PyDict_New ();
820- if (_PyCodec_ErrorRegistry == NULL ) {
821- int i ;
822- _PyCodec_ErrorRegistry = PyDict_New ();
823-
824- if (_PyCodec_ErrorRegistry ) {
825- for (i = 0 ; i < sizeof (methods )/sizeof (methods [0 ]); ++ i ) {
826- PyObject * func = PyCFunction_New (& methods [i ].def , NULL );
827- int res ;
828- if (!func )
829- Py_FatalError ("can't initialize codec error registry" );
830- res = PyCodec_RegisterError (methods [i ].name , func );
831- Py_DECREF (func );
832- if (res )
833- Py_FatalError ("can't initialize codec error registry" );
834- }
786+
787+ PyInterpreterState * interp = PyThreadState_Get ()-> interp ;
788+ PyObject * mod ;
789+ int i ;
790+
791+ if (interp -> codec_search_path != NULL )
792+ return 0 ;
793+
794+ interp -> codec_search_path = PyList_New (0 );
795+ interp -> codec_search_cache = PyDict_New ();
796+ interp -> codec_error_registry = PyDict_New ();
797+
798+ if (interp -> codec_error_registry ) {
799+ for (i = 0 ; i < sizeof (methods )/sizeof (methods [0 ]); ++ i ) {
800+ PyObject * func = PyCFunction_New (& methods [i ].def , NULL );
801+ int res ;
802+ if (!func )
803+ Py_FatalError ("can't initialize codec error registry" );
804+ res = PyCodec_RegisterError (methods [i ].name , func );
805+ Py_DECREF (func );
806+ if (res )
807+ Py_FatalError ("can't initialize codec error registry" );
835808 }
836809 }
837- if (_PyCodec_SearchPath == NULL ||
838- _PyCodec_SearchCache == NULL )
810+
811+ if (interp -> codec_search_path == NULL ||
812+ interp -> codec_search_cache == NULL ||
813+ interp -> codec_error_registry == NULL )
839814 Py_FatalError ("can't initialize codec registry" );
840- }
841815
842- void _PyCodecRegistry_Fini (void )
843- {
844- Py_XDECREF (_PyCodec_SearchPath );
845- _PyCodec_SearchPath = NULL ;
846- Py_XDECREF (_PyCodec_SearchCache );
847- _PyCodec_SearchCache = NULL ;
848- Py_XDECREF (_PyCodec_ErrorRegistry );
849- _PyCodec_ErrorRegistry = NULL ;
816+ mod = PyImport_ImportModuleEx ("encodings" , NULL , NULL , NULL );
817+ if (mod == NULL ) {
818+ if (PyErr_ExceptionMatches (PyExc_ImportError )) {
819+ /* Ignore ImportErrors... this is done so that
820+ distributions can disable the encodings package. Note
821+ that other errors are not masked, e.g. SystemErrors
822+ raised to inform the user of an error in the Python
823+ configuration are still reported back to the user. */
824+ PyErr_Clear ();
825+ return 0 ;
826+ }
827+ return -1 ;
828+ }
829+ Py_DECREF (mod );
830+ return 0 ;
850831}
0 commit comments