Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b95de4f

Browse files
committed
Marc-Andre Lemburg: Error reporting in the codec registry and lookup
mechanism is enhanced to be more informative.
1 parent 52a644c commit b95de4f

2 files changed

Lines changed: 51 additions & 13 deletions

File tree

Lib/codecs.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111

1212
### Registry and builtin stateless codec functions
1313

14-
from _codecs import *
14+
try:
15+
from _codecs import *
16+
except ImportError,why:
17+
raise SystemError,\
18+
'Failed to load the builtin codecs: %s' % why
1519

1620
### Constants
1721

Python/codecs.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,61 @@ static int import_encodings_called = 0;
2727
This is done in a lazy way so that the Unicode implementation does
2828
not downgrade startup time of scripts not needing it.
2929
30-
Errors are silently ignored by this function. Only one try is made.
30+
ImportErrors are silently ignored by this function. Only one try is
31+
made.
3132
3233
*/
3334

3435
static
35-
void import_encodings()
36+
int import_encodings()
3637
{
3738
PyObject *mod;
3839

3940
import_encodings_called = 1;
4041
mod = PyImport_ImportModule("encodings");
4142
if (mod == NULL) {
42-
PyErr_Clear();
43-
return;
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;
4453
}
4554
Py_DECREF(mod);
55+
return 0;
4656
}
4757

4858
/* Register a new codec search function.
4959
60+
As side effect, this tries to load the encodings package, if not
61+
yet done, to make sure that it is always first in the list of
62+
search functions.
63+
5064
The search_function's refcount is incremented by this function. */
5165

5266
int PyCodec_Register(PyObject *search_function)
5367
{
54-
if (!import_encodings_called)
55-
import_encodings();
68+
if (!import_encodings_called) {
69+
if (import_encodings())
70+
goto onError;
71+
}
5672
if (search_function == NULL) {
5773
PyErr_BadArgument();
58-
return -1;
74+
goto onError;
5975
}
6076
if (!PyCallable_Check(search_function)) {
6177
PyErr_SetString(PyExc_TypeError,
6278
"argument must be callable");
63-
return -1;
79+
goto onError;
6480
}
6581
return PyList_Append(_PyCodec_SearchPath, search_function);
82+
83+
onError:
84+
return -1;
6685
}
6786

6887
static
@@ -89,20 +108,29 @@ PyObject *lowercasestring(const char *string)
89108
characters. This makes encodings looked up through this mechanism
90109
effectively case-insensitive.
91110
92-
If no codec is found, a KeyError is set and NULL returned. */
111+
If no codec is found, a KeyError is set and NULL returned.
112+
113+
As side effect, this tries to load the encodings package, if not
114+
yet done. This is part of the lazy load strategy for the encodings
115+
package.
116+
117+
*/
93118

94119
PyObject *_PyCodec_Lookup(const char *encoding)
95120
{
96121
PyObject *result, *args = NULL, *v;
97122
int i, len;
98123

99-
if (_PyCodec_SearchCache == NULL || _PyCodec_SearchPath == NULL) {
124+
if (_PyCodec_SearchCache == NULL ||
125+
_PyCodec_SearchPath == NULL) {
100126
PyErr_SetString(PyExc_SystemError,
101127
"codec module not properly initialized");
102128
goto onError;
103129
}
104-
if (!import_encodings_called)
105-
import_encodings();
130+
if (!import_encodings_called) {
131+
if (import_encodings())
132+
goto onError;
133+
}
106134

107135
/* Convert the encoding to a lower-cased Python string */
108136
v = lowercasestring(encoding);
@@ -127,6 +155,12 @@ PyObject *_PyCodec_Lookup(const char *encoding)
127155
len = PyList_Size(_PyCodec_SearchPath);
128156
if (len < 0)
129157
goto onError;
158+
if (len == 0) {
159+
PyErr_SetString(PyExc_LookupError,
160+
"no codec search functions registered: "
161+
"can't find encoding");
162+
goto onError;
163+
}
130164

131165
for (i = 0; i < len; i++) {
132166
PyObject *func;

0 commit comments

Comments
 (0)