mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
Marc-Andre Lemburg: Error reporting in the codec registry and lookup
mechanism is enhanced to be more informative.
This commit is contained in:
parent
52a644cbda
commit
b95de4f847
2 changed files with 51 additions and 13 deletions
|
@ -11,7 +11,11 @@ import struct,types,__builtin__
|
||||||
|
|
||||||
### Registry and builtin stateless codec functions
|
### 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
|
### Constants
|
||||||
|
|
||||||
|
|
|
@ -27,42 +27,61 @@ static int import_encodings_called = 0;
|
||||||
This is done in a lazy way so that the Unicode implementation does
|
This is done in a lazy way so that the Unicode implementation does
|
||||||
not downgrade startup time of scripts not needing it.
|
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
|
static
|
||||||
void import_encodings()
|
int import_encodings()
|
||||||
{
|
{
|
||||||
PyObject *mod;
|
PyObject *mod;
|
||||||
|
|
||||||
import_encodings_called = 1;
|
import_encodings_called = 1;
|
||||||
mod = PyImport_ImportModule("encodings");
|
mod = PyImport_ImportModule("encodings");
|
||||||
if (mod == NULL) {
|
if (mod == NULL) {
|
||||||
PyErr_Clear();
|
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
|
||||||
return;
|
/* 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);
|
Py_DECREF(mod);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register a new codec search function.
|
/* 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. */
|
The search_function's refcount is incremented by this function. */
|
||||||
|
|
||||||
int PyCodec_Register(PyObject *search_function)
|
int PyCodec_Register(PyObject *search_function)
|
||||||
{
|
{
|
||||||
if (!import_encodings_called)
|
if (!import_encodings_called) {
|
||||||
import_encodings();
|
if (import_encodings())
|
||||||
|
goto onError;
|
||||||
|
}
|
||||||
if (search_function == NULL) {
|
if (search_function == NULL) {
|
||||||
PyErr_BadArgument();
|
PyErr_BadArgument();
|
||||||
return -1;
|
goto onError;
|
||||||
}
|
}
|
||||||
if (!PyCallable_Check(search_function)) {
|
if (!PyCallable_Check(search_function)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"argument must be callable");
|
"argument must be callable");
|
||||||
return -1;
|
goto onError;
|
||||||
}
|
}
|
||||||
return PyList_Append(_PyCodec_SearchPath, search_function);
|
return PyList_Append(_PyCodec_SearchPath, search_function);
|
||||||
|
|
||||||
|
onError:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -89,20 +108,29 @@ PyObject *lowercasestring(const char *string)
|
||||||
characters. This makes encodings looked up through this mechanism
|
characters. This makes encodings looked up through this mechanism
|
||||||
effectively case-insensitive.
|
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 *_PyCodec_Lookup(const char *encoding)
|
||||||
{
|
{
|
||||||
PyObject *result, *args = NULL, *v;
|
PyObject *result, *args = NULL, *v;
|
||||||
int i, len;
|
int i, len;
|
||||||
|
|
||||||
if (_PyCodec_SearchCache == NULL || _PyCodec_SearchPath == NULL) {
|
if (_PyCodec_SearchCache == NULL ||
|
||||||
|
_PyCodec_SearchPath == NULL) {
|
||||||
PyErr_SetString(PyExc_SystemError,
|
PyErr_SetString(PyExc_SystemError,
|
||||||
"codec module not properly initialized");
|
"codec module not properly initialized");
|
||||||
goto onError;
|
goto onError;
|
||||||
}
|
}
|
||||||
if (!import_encodings_called)
|
if (!import_encodings_called) {
|
||||||
import_encodings();
|
if (import_encodings())
|
||||||
|
goto onError;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert the encoding to a lower-cased Python string */
|
/* Convert the encoding to a lower-cased Python string */
|
||||||
v = lowercasestring(encoding);
|
v = lowercasestring(encoding);
|
||||||
|
@ -127,6 +155,12 @@ PyObject *_PyCodec_Lookup(const char *encoding)
|
||||||
len = PyList_Size(_PyCodec_SearchPath);
|
len = PyList_Size(_PyCodec_SearchPath);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
goto onError;
|
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++) {
|
for (i = 0; i < len; i++) {
|
||||||
PyObject *func;
|
PyObject *func;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue