[Python-checkins] python/dist/src/Python codecs.c,2.20,2.21 pystate.c,2.23,2.24 pythonrun.c,2.181,2.182

niemeyer@users.sourceforge.net niemeyer@users.sourceforge.net
Tue, 18 Mar 2003 16:35:38 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv14162/Python

Modified Files:
	codecs.c pystate.c pythonrun.c 
Log Message:
Fixed SF bug #663074. The codec system was using global static
variables to store internal data. As a result, any atempts to use the
unicode system with multiple active interpreters, or successive
interpreter executions, would fail.

Now that information is stored into members of the PyInterpreterState
structure.


Index: codecs.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/codecs.c,v
retrieving revision 2.20
retrieving revision 2.21
diff -C2 -d -r2.20 -r2.21
*** codecs.c	14 Feb 2003 20:25:56 -0000	2.20
--- codecs.c	19 Mar 2003 00:35:35 -0000	2.21
***************
*** 12,23 ****
  #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 ----------------------------------------------------- */
  
--- 12,15 ----
***************
*** 33,65 ****
  */
  
! static
! int import_encodings(void)
! {
!     PyObject *mod;
!     
!     import_encodings_called = 1;
!     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;
! }
  
  int PyCodec_Register(PyObject *search_function)
  {
!     if (!import_encodings_called) {
! 	if (import_encodings())
! 	    goto onError;
!     }
      if (search_function == NULL) {
  	PyErr_BadArgument();
--- 25,35 ----
  */
  
! static int _PyCodecRegistry_Init(void); /* Forward */
  
  int PyCodec_Register(PyObject *search_function)
  {
!     PyInterpreterState *interp = PyThreadState_Get()->interp;
!     if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
! 	goto onError;
      if (search_function == NULL) {
  	PyErr_BadArgument();
***************
*** 71,75 ****
  	goto onError;
      }
!     return PyList_Append(_PyCodec_SearchPath, search_function);
  
   onError:
--- 41,45 ----
  	goto onError;
      }
!     return PyList_Append(interp->codec_search_path, search_function);
  
   onError:
***************
*** 125,128 ****
--- 95,99 ----
  PyObject *_PyCodec_Lookup(const char *encoding)
  {
+     PyInterpreterState *interp;
      PyObject *result, *args = NULL, *v;
      int i, len;
***************
*** 132,145 ****
  	goto onError;
      }
!     if (_PyCodec_SearchCache == NULL || 
! 	_PyCodec_SearchPath == NULL) {
! 	PyErr_SetString(PyExc_SystemError,
! 			"codec module not properly initialized");
  	goto onError;
-     }
-     if (!import_encodings_called) {
- 	if (import_encodings())
- 	    goto onError;
-     }
  
      /* Convert the encoding to a normalized Python string: all
--- 103,110 ----
  	goto onError;
      }
! 
!     interp = PyThreadState_Get()->interp;
!     if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
  	goto onError;
  
      /* Convert the encoding to a normalized Python string: all
***************
*** 152,156 ****
  
      /* First, try to lookup the name in the registry dictionary */
!     result = PyDict_GetItem(_PyCodec_SearchCache, v);
      if (result != NULL) {
  	Py_INCREF(result);
--- 117,121 ----
  
      /* First, try to lookup the name in the registry dictionary */
!     result = PyDict_GetItem(interp->codec_search_cache, v);
      if (result != NULL) {
  	Py_INCREF(result);
***************
*** 165,169 ****
      PyTuple_SET_ITEM(args,0,v);
  
!     len = PyList_Size(_PyCodec_SearchPath);
      if (len < 0)
  	goto onError;
--- 130,134 ----
      PyTuple_SET_ITEM(args,0,v);
  
!     len = PyList_Size(interp->codec_search_path);
      if (len < 0)
  	goto onError;
***************
*** 178,182 ****
  	PyObject *func;
  	
! 	func = PyList_GetItem(_PyCodec_SearchPath, i);
  	if (func == NULL)
  	    goto onError;
--- 143,147 ----
  	PyObject *func;
  	
! 	func = PyList_GetItem(interp->codec_search_path, i);
  	if (func == NULL)
  	    goto onError;
***************
*** 204,208 ****
  
      /* Cache and return the result */
!     PyDict_SetItem(_PyCodec_SearchCache, v, result);
      Py_DECREF(args);
      return result;
--- 169,173 ----
  
      /* Cache and return the result */
!     PyDict_SetItem(interp->codec_search_cache, v, result);
      Py_DECREF(args);
      return result;
***************
*** 423,428 ****
  }
  
- static PyObject *_PyCodec_ErrorRegistry;
- 
  /* Register the error handling callback function error under the name
     name. This function will be called by the codec when it encounters
--- 388,391 ----
***************
*** 433,441 ****
  int PyCodec_RegisterError(const char *name, PyObject *error)
  {
      if (!PyCallable_Check(error)) {
  	PyErr_SetString(PyExc_TypeError, "handler must be callable");
  	return -1;
      }
!     return PyDict_SetItemString( _PyCodec_ErrorRegistry, (char *)name, error);
  }
  
--- 396,408 ----
  int PyCodec_RegisterError(const char *name, PyObject *error)
  {
+     PyInterpreterState *interp = PyThreadState_Get()->interp;
+     if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+ 	return -1;
      if (!PyCallable_Check(error)) {
  	PyErr_SetString(PyExc_TypeError, "handler must be callable");
  	return -1;
      }
!     return PyDict_SetItemString(interp->codec_error_registry,
! 	    			(char *)name, error);
  }
  
***************
*** 447,453 ****
      PyObject *handler = NULL;
  
      if (name==NULL)
  	name = "strict";
!     handler = PyDict_GetItemString(_PyCodec_ErrorRegistry, (char *)name);
      if (!handler)
  	PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
--- 414,424 ----
      PyObject *handler = NULL;
  
+     PyInterpreterState *interp = PyThreadState_Get()->interp;
+     if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
+ 	return NULL;
+ 
      if (name==NULL)
  	name = "strict";
!     handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name);
      if (!handler)
  	PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
***************
*** 763,768 ****
  #endif
  
! 
! void _PyCodecRegistry_Init(void)
  {
      static struct {
--- 734,738 ----
  #endif
  
! static int _PyCodecRegistry_Init(void)
  {
      static struct {
***************
*** 814,850 ****
  #endif
      };
-     if (_PyCodec_SearchPath == NULL)
- 	_PyCodec_SearchPath = PyList_New(0);
-     if (_PyCodec_SearchCache == NULL)
- 	_PyCodec_SearchCache = PyDict_New();
-     if (_PyCodec_ErrorRegistry == NULL) {
- 	int i;
- 	_PyCodec_ErrorRegistry = PyDict_New();
  
! 	if (_PyCodec_ErrorRegistry) {
! 	    for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) {
! 		PyObject *func = PyCFunction_New(&methods[i].def, NULL);
! 		int res;
! 		if (!func)
! 		    Py_FatalError("can't initialize codec error registry");
! 		res = PyCodec_RegisterError(methods[i].name, func);
! 		Py_DECREF(func);
! 		if (res)
! 		    Py_FatalError("can't initialize codec error registry");
! 	    }
  	}
      }
!     if (_PyCodec_SearchPath == NULL || 
! 	_PyCodec_SearchCache == 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;
!     Py_XDECREF(_PyCodec_ErrorRegistry);
!     _PyCodec_ErrorRegistry = NULL;
  }
--- 784,831 ----
  #endif
      };
  
!     PyInterpreterState *interp = PyThreadState_Get()->interp;
!     PyObject *mod;
!     int i;
! 
!     if (interp->codec_search_path != NULL)
! 	return 0;
! 
!     interp->codec_search_path = PyList_New(0);
!     interp->codec_search_cache = PyDict_New();
!     interp->codec_error_registry = PyDict_New();
! 
!     if (interp->codec_error_registry) {
! 	for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) {
! 	    PyObject *func = PyCFunction_New(&methods[i].def, NULL);
! 	    int res;
! 	    if (!func)
! 		Py_FatalError("can't initialize codec error registry");
! 	    res = PyCodec_RegisterError(methods[i].name, func);
! 	    Py_DECREF(func);
! 	    if (res)
! 		Py_FatalError("can't initialize codec error registry");
  	}
      }
! 
!     if (interp->codec_search_path == NULL ||
! 	interp->codec_search_cache == NULL ||
! 	interp->codec_error_registry == NULL)
  	Py_FatalError("can't initialize codec registry");
  
!     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: pystate.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v
retrieving revision 2.23
retrieving revision 2.24
diff -C2 -d -r2.23 -r2.24
*** pystate.c	19 Feb 2003 15:53:17 -0000	2.23
--- pystate.c	19 Mar 2003 00:35:36 -0000	2.24
***************
*** 50,53 ****
--- 50,56 ----
  		interp->builtins = NULL;
  		interp->tstate_head = NULL;
+ 		interp->codec_search_path = NULL;
+ 		interp->codec_search_cache = NULL;
+ 		interp->codec_error_registry = NULL;
  #ifdef HAVE_DLOPEN
  #ifdef RTLD_NOW
***************
*** 76,79 ****
--- 79,85 ----
  		PyThreadState_Clear(p);
  	HEAD_UNLOCK();
+ 	ZAP(interp->codec_search_path);
+ 	ZAP(interp->codec_search_cache);
+ 	ZAP(interp->codec_error_registry);
  	ZAP(interp->modules);
  	ZAP(interp->sysdict);

Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.181
retrieving revision 2.182
diff -C2 -d -r2.181 -r2.182
*** pythonrun.c	5 Mar 2003 17:31:21 -0000	2.181
--- pythonrun.c	19 Mar 2003 00:35:36 -0000	2.182
***************
*** 50,55 ****
  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 */
--- 50,53 ----
***************
*** 145,151 ****
  		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 */
--- 143,146 ----
***************
*** 257,263 ****
  	/* Disable signal handling */
  	PyOS_FiniInterrupts();
- 
- 	/* Cleanup Codec registry */
- 	_PyCodecRegistry_Fini();
  
  	/* drop module references we saved */
--- 252,255 ----