From b95de4f847c04f2b82f75e27e477afd229a189b1 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 31 Mar 2000 17:25:23 +0000 Subject: Marc-Andre Lemburg: Error reporting in the codec registry and lookup mechanism is enhanced to be more informative. --- Lib/codecs.py | 6 +++++- Python/codecs.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 13 deletions(-) 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 @@ import struct,types,__builtin__ ### 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 @@ static int import_encodings_called = 0; 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 @@ PyObject *lowercasestring(const char *string) 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 @@ PyObject *_PyCodec_Lookup(const char *encoding) 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; -- cgit v0.12