Marc-Andre Lemburg: Error reporting in the codec registry and lookup
mechanism is enhanced to be more informative.
diff --git a/Lib/codecs.py b/Lib/codecs.py
index c09f804..5c669c0 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -11,7 +11,11 @@
 
 ### Registry and builtin stateless codec functions
 
-from _codecs import *
+try:
+    from _codecs import *
+except ImportError,why:
+    raise SystemError,\
+          'Failed to load the builtin codecs: %s' % why
 
 ### Constants
 
diff --git a/Python/codecs.c b/Python/codecs.c
index b2a19b8..b9a6461 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -27,42 +27,61 @@
    This is done in a lazy way so that the Unicode implementation does
    not downgrade startup time of scripts not needing it.
 
-   Errors are silently ignored by this function. Only one try is made.
+   ImportErrors are silently ignored by this function. Only one try is
+   made.
 
 */
 
 static
-void import_encodings() 
+int import_encodings() 
 {
     PyObject *mod;
     
     import_encodings_called = 1;
     mod = PyImport_ImportModule("encodings");
     if (mod == NULL) {
-	PyErr_Clear();
-	return;
+	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;
 }
 
 /* Register a new codec search function.
 
+   As side effect, this tries to load the encodings package, if not
+   yet done, to make sure that it is always first in the list of
+   search functions.
+
    The search_function's refcount is incremented by this function. */
 
 int PyCodec_Register(PyObject *search_function)
 {
-    if (!import_encodings_called)
-	import_encodings();
+    if (!import_encodings_called) {
+	if (import_encodings())
+	    goto onError;
+    }
     if (search_function == NULL) {
 	PyErr_BadArgument();
-	return -1;
+	goto onError;
     }
     if (!PyCallable_Check(search_function)) {
 	PyErr_SetString(PyExc_TypeError,
 			"argument must be callable");
-	return -1;
+	goto onError;
     }
     return PyList_Append(_PyCodec_SearchPath, search_function);
+
+ onError:
+    return -1;
 }
 
 static
@@ -89,20 +108,29 @@
    characters. This makes encodings looked up through this mechanism
    effectively case-insensitive.
 
-   If no codec is found, a KeyError is set and NULL returned.  */
+   If no codec is found, a KeyError is set and NULL returned. 
+
+   As side effect, this tries to load the encodings package, if not
+   yet done. This is part of the lazy load strategy for the encodings
+   package.
+
+*/
 
 PyObject *_PyCodec_Lookup(const char *encoding)
 {
     PyObject *result, *args = NULL, *v;
     int i, len;
 
-    if (_PyCodec_SearchCache == NULL || _PyCodec_SearchPath == NULL) {
+    if (_PyCodec_SearchCache == NULL || 
+	_PyCodec_SearchPath == NULL) {
 	PyErr_SetString(PyExc_SystemError,
 			"codec module not properly initialized");
 	goto onError;
     }
-    if (!import_encodings_called)
-	import_encodings();
+    if (!import_encodings_called) {
+	if (import_encodings())
+	    goto onError;
+    }
 
     /* Convert the encoding to a lower-cased Python string */
     v = lowercasestring(encoding);
@@ -127,6 +155,12 @@
     len = PyList_Size(_PyCodec_SearchPath);
     if (len < 0)
 	goto onError;
+    if (len == 0) {
+	PyErr_SetString(PyExc_LookupError,
+			"no codec search functions registered: "
+			"can't find encoding");
+	goto onError;
+    }
 
     for (i = 0; i < len; i++) {
 	PyObject *func;