summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorWalter Dörwald <walter@livinglogic.de>2002-09-02 13:14:32 (GMT)
committerWalter Dörwald <walter@livinglogic.de>2002-09-02 13:14:32 (GMT)
commit3aeb632c3152fa082132ce55b9a880e0d16b04ae (patch)
tree192bc1543ea77a826d0c940d024dbc8ebba82156 /Python
parent94fab762de532de551987e1f48a125145f85304b (diff)
downloadcpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.zip
cpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.tar.gz
cpython-3aeb632c3152fa082132ce55b9a880e0d16b04ae.tar.bz2
PEP 293 implemention (from SF patch http://www.python.org/sf/432401)
Diffstat (limited to 'Python')
-rw-r--r--Python/codecs.c399
-rw-r--r--Python/exceptions.c603
2 files changed, 1002 insertions, 0 deletions
diff --git a/Python/codecs.c b/Python/codecs.c
index 3e54d8f..09cba75 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -422,12 +422,409 @@ PyObject *PyCodec_Decode(PyObject *object,
return NULL;
}
+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
+ an unencodable characters/undecodable bytes and doesn't know the
+ callback name, when name is specified as the error parameter
+ in the call to the encode/decode function.
+ Return 0 on success, -1 on error */
+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);
+}
+
+/* Lookup the error handling callback function registered under the
+ name error. As a special case NULL can be passed, in which case
+ the error handling callback for strict encoding will be returned. */
+PyObject *PyCodec_LookupError(const char *name)
+{
+ 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);
+ else
+ Py_INCREF(handler);
+ return handler;
+}
+
+static void wrong_exception_type(PyObject *exc)
+{
+ PyObject *type = PyObject_GetAttrString(exc, "__class__");
+ if (type != NULL) {
+ PyObject *name = PyObject_GetAttrString(type, "__name__");
+ Py_DECREF(type);
+ if (name != NULL) {
+ PyObject *string = PyObject_Str(name);
+ Py_DECREF(name);
+ PyErr_Format(PyExc_TypeError, "don't know how to handle %.400s in error callback",
+ PyString_AS_STRING(string));
+ Py_DECREF(string);
+ }
+ }
+}
+
+PyObject *PyCodec_StrictErrors(PyObject *exc)
+{
+ if (PyInstance_Check(exc))
+ PyErr_SetObject((PyObject*)((PyInstanceObject*)exc)->in_class,
+ exc);
+ else
+ PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
+ return NULL;
+}
+
+
+PyObject *PyCodec_IgnoreErrors(PyObject *exc)
+{
+ int end;
+ if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
+ if (PyUnicodeTranslateError_GetEnd(exc, &end))
+ return NULL;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+ /* ouch: passing NULL, 0, pos gives None instead of u'' */
+ return Py_BuildValue("(u#i)", &end, 0, end);
+}
+
+
+PyObject *PyCodec_ReplaceErrors(PyObject *exc)
+{
+ PyObject *restuple;
+ int start;
+ int end;
+ int i;
+
+ if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+ PyObject *res;
+ Py_UNICODE *p;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ res = PyUnicode_FromUnicode(NULL, end-start);
+ if (res == NULL)
+ return NULL;
+ for (p = PyUnicode_AS_UNICODE(res), i = start;
+ i<end; ++p, ++i)
+ *p = '?';
+ restuple = Py_BuildValue("(Oi)", res, end);
+ Py_DECREF(res);
+ return restuple;
+ }
+ else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
+ Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER;
+ if (PyUnicodeDecodeError_GetEnd(exc, &end))
+ return NULL;
+ return Py_BuildValue("(u#i)", &res, 1, end);
+ }
+ else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
+ PyObject *res;
+ Py_UNICODE *p;
+ if (PyUnicodeTranslateError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeTranslateError_GetEnd(exc, &end))
+ return NULL;
+ res = PyUnicode_FromUnicode(NULL, end-start);
+ if (res == NULL)
+ return NULL;
+ for (p = PyUnicode_AS_UNICODE(res), i = start;
+ i<end; ++p, ++i)
+ *p = Py_UNICODE_REPLACEMENT_CHARACTER;
+ restuple = Py_BuildValue("(Oi)", res, end);
+ Py_DECREF(res);
+ return restuple;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
+{
+ if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+ PyObject *restuple;
+ PyObject *object;
+ int start;
+ int end;
+ PyObject *res;
+ Py_UNICODE *p;
+ Py_UNICODE *startp;
+ Py_UNICODE *outp;
+ int ressize;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ startp = PyUnicode_AS_UNICODE(object);
+ for (p = startp+start, ressize = 0; p < startp+end; ++p) {
+ if (*p<10)
+ ressize += 2+1+1;
+ else if (*p<100)
+ ressize += 2+2+1;
+ else if (*p<1000)
+ ressize += 2+3+1;
+ else if (*p<10000)
+ ressize += 2+4+1;
+ else if (*p<100000)
+ ressize += 2+5+1;
+ else if (*p<1000000)
+ ressize += 2+6+1;
+ else
+ ressize += 2+7+1;
+ }
+ /* allocate replacement */
+ res = PyUnicode_FromUnicode(NULL, ressize);
+ if (res == NULL) {
+ Py_DECREF(object);
+ return NULL;
+ }
+ /* generate replacement */
+ for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
+ p < startp+end; ++p) {
+ Py_UNICODE c = *p;
+ int digits;
+ int base;
+ *outp++ = '&';
+ *outp++ = '#';
+ if (*p<10) {
+ digits = 1;
+ base = 1;
+ }
+ else if (*p<100) {
+ digits = 2;
+ base = 10;
+ }
+ else if (*p<1000) {
+ digits = 3;
+ base = 100;
+ }
+ else if (*p<10000) {
+ digits = 4;
+ base = 1000;
+ }
+ else if (*p<100000) {
+ digits = 5;
+ base = 10000;
+ }
+ else if (*p<1000000) {
+ digits = 6;
+ base = 100000;
+ }
+ else {
+ digits = 7;
+ base = 1000000;
+ }
+ while (digits-->0) {
+ *outp++ = '0' + c/base;
+ c %= base;
+ base /= 10;
+ }
+ *outp++ = ';';
+ }
+ restuple = Py_BuildValue("(Oi)", res, end);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+static Py_UNICODE hexdigits[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
+{
+ if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
+ PyObject *restuple;
+ PyObject *object;
+ int start;
+ int end;
+ PyObject *res;
+ Py_UNICODE *p;
+ Py_UNICODE *startp;
+ Py_UNICODE *outp;
+ int ressize;
+ if (PyUnicodeEncodeError_GetStart(exc, &start))
+ return NULL;
+ if (PyUnicodeEncodeError_GetEnd(exc, &end))
+ return NULL;
+ if (!(object = PyUnicodeEncodeError_GetObject(exc)))
+ return NULL;
+ startp = PyUnicode_AS_UNICODE(object);
+ for (p = startp+start, ressize = 0; p < startp+end; ++p) {
+ if (*p >= 0x00010000)
+ ressize += 1+1+8;
+ else if (*p >= 0x100) {
+ ressize += 1+1+4;
+ }
+ else
+ ressize += 1+1+2;
+ }
+ res = PyUnicode_FromUnicode(NULL, ressize);
+ if (res==NULL)
+ return NULL;
+ for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
+ p < startp+end; ++p) {
+ Py_UNICODE c = *p;
+ *outp++ = '\\';
+ if (c >= 0x00010000) {
+ *outp++ = 'U';
+ *outp++ = hexdigits[(c>>28)&0xf];
+ *outp++ = hexdigits[(c>>24)&0xf];
+ *outp++ = hexdigits[(c>>20)&0xf];
+ *outp++ = hexdigits[(c>>16)&0xf];
+ *outp++ = hexdigits[(c>>12)&0xf];
+ *outp++ = hexdigits[(c>>8)&0xf];
+ }
+ else if (c >= 0x100) {
+ *outp++ = 'u';
+ *outp++ = hexdigits[(c>>12)&0xf];
+ *outp++ = hexdigits[(c>>8)&0xf];
+ }
+ else
+ *outp++ = 'x';
+ *outp++ = hexdigits[(c>>4)&0xf];
+ *outp++ = hexdigits[c&0xf];
+ }
+
+ restuple = Py_BuildValue("(Oi)", res, end);
+ Py_DECREF(res);
+ Py_DECREF(object);
+ return restuple;
+ }
+ else {
+ wrong_exception_type(exc);
+ return NULL;
+ }
+}
+
+static PyObject *strict_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_StrictErrors(exc);
+}
+
+
+static PyObject *ignore_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_IgnoreErrors(exc);
+}
+
+
+static PyObject *replace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_ReplaceErrors(exc);
+}
+
+
+static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_XMLCharRefReplaceErrors(exc);
+}
+
+
+static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
+{
+ return PyCodec_BackslashReplaceErrors(exc);
+}
+
+
void _PyCodecRegistry_Init(void)
{
+ static struct {
+ char *name;
+ PyMethodDef def;
+ } methods[] =
+ {
+ {
+ "strict",
+ {
+ "strict_errors",
+ strict_errors,
+ METH_O
+ }
+ },
+ {
+ "ignore",
+ {
+ "ignore_errors",
+ ignore_errors,
+ METH_O
+ }
+ },
+ {
+ "replace",
+ {
+ "replace_errors",
+ replace_errors,
+ METH_O
+ }
+ },
+ {
+ "xmlcharrefreplace",
+ {
+ "xmlcharrefreplace_errors",
+ xmlcharrefreplace_errors,
+ METH_O
+ }
+ },
+ {
+ "backslashreplace",
+ {
+ "backslashreplace_errors",
+ backslashreplace_errors,
+ METH_O
+ }
+ }
+ };
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 < 5; ++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");
@@ -439,4 +836,6 @@ void _PyCodecRegistry_Fini(void)
_PyCodec_SearchPath = NULL;
Py_XDECREF(_PyCodec_SearchCache);
_PyCodec_SearchCache = NULL;
+ Py_XDECREF(_PyCodec_ErrorRegistry);
+ _PyCodec_ErrorRegistry = NULL;
}
diff --git a/Python/exceptions.c b/Python/exceptions.c
index c4bd626..1667cd9 100644
--- a/Python/exceptions.c
+++ b/Python/exceptions.c
@@ -100,6 +100,10 @@ Exception\n\
| +-- ValueError\n\
| | |\n\
| | +-- UnicodeError\n\
+ | | |\n\
+ | | +-- UnicodeEncodeError\n\
+ | | +-- UnicodeDecodeError\n\
+ | | +-- UnicodeTranslateError\n\
| |\n\
| +-- ReferenceError\n\
| +-- SystemError\n\
@@ -840,6 +844,590 @@ static PyMethodDef SyntaxError_methods[] = {
};
+static
+int get_int(PyObject *exc, const char *name, int *value)
+{
+ PyObject *attr = PyObject_GetAttrString(exc, (char *)name);
+
+ if (!attr)
+ return -1;
+ if (!PyInt_Check(attr)) {
+ PyErr_Format(PyExc_TypeError, "%s attribute must be int", name);
+ Py_DECREF(attr);
+ return -1;
+ }
+ *value = PyInt_AS_LONG(attr);
+ Py_DECREF(attr);
+ return 0;
+}
+
+
+static
+int set_int(PyObject *exc, const char *name, int value)
+{
+ PyObject *obj = PyInt_FromLong(value);
+ int result;
+
+ if (!obj)
+ return -1;
+ result = PyObject_SetAttrString(exc, (char *)name, obj);
+ Py_DECREF(obj);
+ return result;
+}
+
+
+static
+PyObject *get_string(PyObject *exc, const char *name)
+{
+ PyObject *attr = PyObject_GetAttrString(exc, (char *)name);
+
+ if (!attr)
+ return NULL;
+ if (!PyString_Check(attr)) {
+ PyErr_Format(PyExc_TypeError, "%s attribute must be str", name);
+ Py_DECREF(attr);
+ return NULL;
+ }
+ return attr;
+}
+
+
+static
+int set_string(PyObject *exc, const char *name, const char *value)
+{
+ PyObject *obj = PyString_FromString(value);
+ int result;
+
+ if (!obj)
+ return -1;
+ result = PyObject_SetAttrString(exc, (char *)name, obj);
+ Py_DECREF(obj);
+ return result;
+}
+
+
+static
+PyObject *get_unicode(PyObject *exc, const char *name)
+{
+ PyObject *attr = PyObject_GetAttrString(exc, (char *)name);
+
+ if (!attr)
+ return NULL;
+ if (!PyUnicode_Check(attr)) {
+ PyErr_Format(PyExc_TypeError, "%s attribute must be unicode", name);
+ Py_DECREF(attr);
+ return NULL;
+ }
+ return attr;
+}
+
+PyObject * PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+{
+ return get_string(exc, "encoding");
+}
+
+PyObject * PyUnicodeDecodeError_GetEncoding(PyObject *exc)
+{
+ return get_string(exc, "encoding");
+}
+
+PyObject * PyUnicodeTranslateError_GetEncoding(PyObject *exc)
+{
+ return get_string(exc, "encoding");
+}
+
+PyObject *PyUnicodeEncodeError_GetObject(PyObject *exc)
+{
+ return get_unicode(exc, "object");
+}
+
+PyObject *PyUnicodeDecodeError_GetObject(PyObject *exc)
+{
+ return get_string(exc, "object");
+}
+
+PyObject *PyUnicodeTranslateError_GetObject(PyObject *exc)
+{
+ return get_unicode(exc, "object");
+}
+
+int PyUnicodeEncodeError_GetStart(PyObject *exc, int *start)
+{
+ if (!get_int(exc, "start", start)) {
+ PyObject *object = PyUnicodeEncodeError_GetObject(exc);
+ int size;
+ if (!object)
+ return -1;
+ size = PyUnicode_GET_SIZE(object);
+ if (*start<0)
+ *start = 0;
+ if (*start>=size)
+ *start = size-1;
+ Py_DECREF(object);
+ return 0;
+ }
+ return -1;
+}
+
+
+int PyUnicodeDecodeError_GetStart(PyObject *exc, int *start)
+{
+ if (!get_int(exc, "start", start)) {
+ PyObject *object = PyUnicodeDecodeError_GetObject(exc);
+ int size;
+ if (!object)
+ return -1;
+ size = PyString_GET_SIZE(object);
+ if (*start<0)
+ *start = 0;
+ if (*start>=size)
+ *start = size-1;
+ Py_DECREF(object);
+ return 0;
+ }
+ return -1;
+}
+
+
+int PyUnicodeTranslateError_GetStart(PyObject *exc, int *start)
+{
+ return PyUnicodeEncodeError_GetStart(exc, start);
+}
+
+
+int PyUnicodeEncodeError_SetStart(PyObject *exc, int start)
+{
+ return set_int(exc, "start", start);
+}
+
+
+int PyUnicodeDecodeError_SetStart(PyObject *exc, int start)
+{
+ return set_int(exc, "start", start);
+}
+
+
+int PyUnicodeTranslateError_SetStart(PyObject *exc, int start)
+{
+ return set_int(exc, "start", start);
+}
+
+
+int PyUnicodeEncodeError_GetEnd(PyObject *exc, int *end)
+{
+ if (!get_int(exc, "end", end)) {
+ PyObject *object = PyUnicodeEncodeError_GetObject(exc);
+ int size;
+ if (!object)
+ return -1;
+ size = PyUnicode_GET_SIZE(object);
+ if (*end<1)
+ *end = 1;
+ if (*end>size)
+ *end = size;
+ Py_DECREF(object);
+ return 0;
+ }
+ return -1;
+}
+
+
+int PyUnicodeDecodeError_GetEnd(PyObject *exc, int *end)
+{
+ if (!get_int(exc, "end", end)) {
+ PyObject *object = PyUnicodeDecodeError_GetObject(exc);
+ int size;
+ if (!object)
+ return -1;
+ size = PyString_GET_SIZE(object);
+ if (*end<1)
+ *end = 1;
+ if (*end>size)
+ *end = size;
+ Py_DECREF(object);
+ return 0;
+ }
+ return -1;
+}
+
+
+int PyUnicodeTranslateError_GetEnd(PyObject *exc, int *start)
+{
+ return PyUnicodeEncodeError_GetEnd(exc, start);
+}
+
+
+int PyUnicodeEncodeError_SetEnd(PyObject *exc, int end)
+{
+ return set_int(exc, "end", end);
+}
+
+
+int PyUnicodeDecodeError_SetEnd(PyObject *exc, int end)
+{
+ return set_int(exc, "end", end);
+}
+
+
+int PyUnicodeTranslateError_SetEnd(PyObject *exc, int end)
+{
+ return set_int(exc, "end", end);
+}
+
+
+PyObject *PyUnicodeEncodeError_GetReason(PyObject *exc)
+{
+ return get_string(exc, "reason");
+}
+
+
+PyObject *PyUnicodeDecodeError_GetReason(PyObject *exc)
+{
+ return get_string(exc, "reason");
+}
+
+
+PyObject *PyUnicodeTranslateError_GetReason(PyObject *exc)
+{
+ return get_string(exc, "reason");
+}
+
+
+int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(exc, "reason", reason);
+}
+
+
+int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(exc, "reason", reason);
+}
+
+
+int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(exc, "reason", reason);
+}
+
+
+static PyObject *
+UnicodeError__init__(PyObject *self, PyObject *args, PyTypeObject *objecttype)
+{
+ PyObject *rtnval = NULL;
+ PyObject *encoding;
+ PyObject *object;
+ PyObject *start;
+ PyObject *end;
+ PyObject *reason;
+
+ if (!(self = get_self(args)))
+ return NULL;
+
+ if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
+ &PyString_Type, &encoding,
+ objecttype, &object,
+ &PyInt_Type, &start,
+ &PyInt_Type, &end,
+ &PyString_Type, &reason))
+ return NULL;
+
+ if (PyObject_SetAttrString(self, "args", args))
+ goto finally;
+
+ if (PyObject_SetAttrString(self, "encoding", encoding))
+ goto finally;
+ if (PyObject_SetAttrString(self, "object", object))
+ goto finally;
+ if (PyObject_SetAttrString(self, "start", start))
+ goto finally;
+ if (PyObject_SetAttrString(self, "end", end))
+ goto finally;
+ if (PyObject_SetAttrString(self, "reason", reason))
+ goto finally;
+
+ Py_INCREF(Py_None);
+ rtnval = Py_None;
+
+ finally:
+ Py_DECREF(args);
+ return rtnval;
+}
+
+
+static PyObject *
+UnicodeEncodeError__init__(PyObject *self, PyObject *args)
+{
+ return UnicodeError__init__(self, args, &PyUnicode_Type);
+}
+
+static PyObject *
+UnicodeEncodeError__str__(PyObject *self, PyObject *arg)
+{
+ PyObject *encodingObj = NULL;
+ PyObject *objectObj = NULL;
+ int length;
+ int start;
+ int end;
+ PyObject *reasonObj = NULL;
+ char buffer[1000];
+ PyObject *result = NULL;
+
+ self = arg;
+
+ if (!(encodingObj = PyUnicodeEncodeError_GetEncoding(self)))
+ goto error;
+
+ if (!(objectObj = PyUnicodeEncodeError_GetObject(self)))
+ goto error;
+
+ length = PyUnicode_GET_SIZE(objectObj);
+
+ if (PyUnicodeEncodeError_GetStart(self, &start))
+ goto error;
+
+ if (PyUnicodeEncodeError_GetEnd(self, &end))
+ goto error;
+
+ if (!(reasonObj = PyUnicodeEncodeError_GetReason(self)))
+ goto error;
+
+ if (end==start+1) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "'%.400s' codec can't encode character '\\u%x' in position %d: %.400s",
+ PyString_AS_STRING(encodingObj),
+ (int)PyUnicode_AS_UNICODE(objectObj)[start],
+ start,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "'%.400s' codec can't encode characters in position %d-%d: %.400s",
+ PyString_AS_STRING(encodingObj),
+ start,
+ end-1,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ result = PyString_FromString(buffer);
+
+error:
+ Py_XDECREF(reasonObj);
+ Py_XDECREF(objectObj);
+ Py_XDECREF(encodingObj);
+ return result;
+}
+
+static PyMethodDef UnicodeEncodeError_methods[] = {
+ {"__init__", UnicodeEncodeError__init__, METH_VARARGS},
+ {"__str__", UnicodeEncodeError__str__, METH_O},
+ {NULL, NULL}
+};
+
+
+PyObject * PyUnicodeEncodeError_Create(
+ const char *encoding, const Py_UNICODE *object, int length,
+ int start, int end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#iis",
+ encoding, object, length, start, end, reason);
+}
+
+
+static PyObject *
+UnicodeDecodeError__init__(PyObject *self, PyObject *args)
+{
+ return UnicodeError__init__(self, args, &PyString_Type);
+}
+
+static PyObject *
+UnicodeDecodeError__str__(PyObject *self, PyObject *arg)
+{
+ PyObject *encodingObj = NULL;
+ PyObject *objectObj = NULL;
+ int length;
+ int start;
+ int end;
+ PyObject *reasonObj = NULL;
+ char buffer[1000];
+ PyObject *result = NULL;
+
+ self = arg;
+
+ if (!(encodingObj = PyUnicodeDecodeError_GetEncoding(self)))
+ goto error;
+
+ if (!(objectObj = PyUnicodeDecodeError_GetObject(self)))
+ goto error;
+
+ length = PyString_GET_SIZE(objectObj);
+
+ if (PyUnicodeDecodeError_GetStart(self, &start))
+ goto error;
+
+ if (PyUnicodeDecodeError_GetEnd(self, &end))
+ goto error;
+
+ if (!(reasonObj = PyUnicodeDecodeError_GetReason(self)))
+ goto error;
+
+ if (end==start+1) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "'%.400s' codec can't decode byte 0x%x in position %d: %.400s",
+ PyString_AS_STRING(encodingObj),
+ ((int)PyString_AS_STRING(objectObj)[start])&0xff,
+ start,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "'%.400s' codec can't decode bytes in position %d-%d: %.400s",
+ PyString_AS_STRING(encodingObj),
+ start,
+ end-1,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ result = PyString_FromString(buffer);
+
+error:
+ Py_XDECREF(reasonObj);
+ Py_XDECREF(objectObj);
+ Py_XDECREF(encodingObj);
+ return result;
+}
+
+static PyMethodDef UnicodeDecodeError_methods[] = {
+ {"__init__", UnicodeDecodeError__init__, METH_VARARGS},
+ {"__str__", UnicodeDecodeError__str__, METH_O},
+ {NULL, NULL}
+};
+
+
+PyObject * PyUnicodeDecodeError_Create(
+ const char *encoding, const char *object, int length,
+ int start, int end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#iis",
+ encoding, object, length, start, end, reason);
+}
+
+
+static PyObject *
+UnicodeTranslateError__init__(PyObject *self, PyObject *args)
+{
+ PyObject *rtnval = NULL;
+ PyObject *object;
+ PyObject *start;
+ PyObject *end;
+ PyObject *reason;
+
+ if (!(self = get_self(args)))
+ return NULL;
+
+ if (!(args = PySequence_GetSlice(args, 1, PySequence_Size(args))))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O!O!O!O!",
+ &PyUnicode_Type, &object,
+ &PyInt_Type, &start,
+ &PyInt_Type, &end,
+ &PyString_Type, &reason))
+ goto finally;
+
+ if (PyObject_SetAttrString(self, "args", args))
+ goto finally;
+
+ if (PyObject_SetAttrString(self, "object", object))
+ goto finally;
+ if (PyObject_SetAttrString(self, "start", start))
+ goto finally;
+ if (PyObject_SetAttrString(self, "end", end))
+ goto finally;
+ if (PyObject_SetAttrString(self, "reason", reason))
+ goto finally;
+
+ Py_INCREF(Py_None);
+ rtnval = Py_None;
+
+ finally:
+ Py_DECREF(args);
+ return rtnval;
+}
+
+
+static PyObject *
+UnicodeTranslateError__str__(PyObject *self, PyObject *arg)
+{
+ PyObject *objectObj = NULL;
+ int length;
+ int start;
+ int end;
+ PyObject *reasonObj = NULL;
+ char buffer[1000];
+ PyObject *result = NULL;
+
+ self = arg;
+
+ if (!(objectObj = PyUnicodeTranslateError_GetObject(self)))
+ goto error;
+
+ length = PyUnicode_GET_SIZE(objectObj);
+
+ if (PyUnicodeTranslateError_GetStart(self, &start))
+ goto error;
+
+ if (PyUnicodeTranslateError_GetEnd(self, &end))
+ goto error;
+
+ if (!(reasonObj = PyUnicodeTranslateError_GetReason(self)))
+ goto error;
+
+ if (end==start+1) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "can't translate character '\\u%x' in position %d: %.400s",
+ (int)PyUnicode_AS_UNICODE(objectObj)[start],
+ start,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "can't translate characters in position %d-%d: %.400s",
+ start,
+ end-1,
+ PyString_AS_STRING(reasonObj)
+ );
+ }
+ result = PyString_FromString(buffer);
+
+error:
+ Py_XDECREF(reasonObj);
+ Py_XDECREF(objectObj);
+ return result;
+}
+
+static PyMethodDef UnicodeTranslateError_methods[] = {
+ {"__init__", UnicodeTranslateError__init__, METH_VARARGS},
+ {"__str__", UnicodeTranslateError__str__, METH_O},
+ {NULL, NULL}
+};
+
+
+PyObject * PyUnicodeTranslateError_Create(
+ const Py_UNICODE *object, int length,
+ int start, int end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#iis",
+ object, length, start, end, reason);
+}
+
+
/* Exception doc strings */
@@ -865,6 +1453,12 @@ PyDoc_STRVAR(ValueError__doc__,
PyDoc_STRVAR(UnicodeError__doc__, "Unicode related error.");
+PyDoc_STRVAR(UnicodeEncodeError__doc__, "Unicode encoding error.");
+
+PyDoc_STRVAR(UnicodeDecodeError__doc__, "Unicode decoding error.");
+
+PyDoc_STRVAR(UnicodeTranslateError__doc__, "Unicode translation error.");
+
PyDoc_STRVAR(SystemError__doc__,
"Internal error in the Python interpreter.\n\
\n\
@@ -949,6 +1543,9 @@ PyObject *PyExc_SystemError;
PyObject *PyExc_SystemExit;
PyObject *PyExc_UnboundLocalError;
PyObject *PyExc_UnicodeError;
+PyObject *PyExc_UnicodeEncodeError;
+PyObject *PyExc_UnicodeDecodeError;
+PyObject *PyExc_UnicodeTranslateError;
PyObject *PyExc_TypeError;
PyObject *PyExc_ValueError;
PyObject *PyExc_ZeroDivisionError;
@@ -1035,6 +1632,12 @@ static struct {
FloatingPointError__doc__},
{"ValueError", &PyExc_ValueError, 0, ValueError__doc__},
{"UnicodeError", &PyExc_UnicodeError, &PyExc_ValueError, UnicodeError__doc__},
+ {"UnicodeEncodeError", &PyExc_UnicodeEncodeError, &PyExc_UnicodeError,
+ UnicodeEncodeError__doc__, UnicodeEncodeError_methods},
+ {"UnicodeDecodeError", &PyExc_UnicodeDecodeError, &PyExc_UnicodeError,
+ UnicodeDecodeError__doc__, UnicodeDecodeError_methods},
+ {"UnicodeTranslateError", &PyExc_UnicodeTranslateError, &PyExc_UnicodeError,
+ UnicodeTranslateError__doc__, UnicodeTranslateError_methods},
{"ReferenceError", &PyExc_ReferenceError, 0, ReferenceError__doc__},
{"SystemError", &PyExc_SystemError, 0, SystemError__doc__},
{"MemoryError", &PyExc_MemoryError, 0, MemoryError__doc__},