blob: e900243448fdd8e34c0b337f4cacecae7891df02 [file] [log] [blame]
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001/*
2 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
3 *
4 * Thanks go to Tim Peters and Michael Hudson for debugging.
5 */
6
Thomas Wouters477c8d52006-05-27 19:21:47 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
9#include "structmember.h"
10#include "osdefs.h"
11
12#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +000013
14/* NOTE: If the exception class hierarchy changes, don't forget to update
15 * Lib/test/exception_hierarchy.txt
16 */
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018/*
19 * BaseException
20 */
21static PyObject *
22BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyBaseExceptionObject *self;
25
26 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
Guido van Rossumd8faa362007-04-27 19:54:29 +000027 if (!self)
28 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000029 /* the dict is created on the fly in PyObject_GenericSetAttr */
Guido van Rossumebe3e162007-05-17 18:20:34 +000030 self->dict = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000031
32 self->args = PyTuple_New(0);
33 if (!self->args) {
34 Py_DECREF(self);
35 return NULL;
36 }
37
Thomas Wouters477c8d52006-05-27 19:21:47 +000038 return (PyObject *)self;
39}
40
41static int
42BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
43{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000044 if (!_PyArg_NoKeywords(Py_Type(self)->tp_name, kwds))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000045 return -1;
46
Thomas Wouters477c8d52006-05-27 19:21:47 +000047 Py_DECREF(self->args);
48 self->args = args;
49 Py_INCREF(self->args);
50
Thomas Wouters477c8d52006-05-27 19:21:47 +000051 return 0;
52}
53
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000054static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000055BaseException_clear(PyBaseExceptionObject *self)
56{
57 Py_CLEAR(self->dict);
58 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000059 return 0;
60}
61
62static void
63BaseException_dealloc(PyBaseExceptionObject *self)
64{
Thomas Wouters89f507f2006-12-13 04:49:30 +000065 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000066 BaseException_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000067 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000068}
69
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000070static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000071BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
72{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000073 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000074 Py_VISIT(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000075 return 0;
76}
77
78static PyObject *
79BaseException_str(PyBaseExceptionObject *self)
80{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000081 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000082 case 0:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000083 return PyUnicode_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 case 1:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000085 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +000086 default:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000087 return PyObject_Unicode(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000088 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000089}
90
91static PyObject *
92BaseException_repr(PyBaseExceptionObject *self)
93{
Thomas Wouters477c8d52006-05-27 19:21:47 +000094 char *name;
95 char *dot;
96
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000097 name = (char *)Py_Type(self)->tp_name;
Thomas Wouters477c8d52006-05-27 19:21:47 +000098 dot = strrchr(name, '.');
99 if (dot != NULL) name = dot+1;
100
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000101 return PyUnicode_FromFormat("%s%R", name, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000102}
103
104/* Pickling support */
105static PyObject *
106BaseException_reduce(PyBaseExceptionObject *self)
107{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000108 if (self->args && self->dict)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000109 return PyTuple_Pack(3, Py_Type(self), self->args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000110 else
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000111 return PyTuple_Pack(2, Py_Type(self), self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112}
113
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000114/*
115 * Needed for backward compatibility, since exceptions used to store
116 * all their attributes in the __dict__. Code is taken from cPickle's
117 * load_build function.
118 */
119static PyObject *
120BaseException_setstate(PyObject *self, PyObject *state)
121{
122 PyObject *d_key, *d_value;
123 Py_ssize_t i = 0;
124
125 if (state != Py_None) {
126 if (!PyDict_Check(state)) {
127 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
128 return NULL;
129 }
130 while (PyDict_Next(state, &i, &d_key, &d_value)) {
131 if (PyObject_SetAttr(self, d_key, d_value) < 0)
132 return NULL;
133 }
134 }
135 Py_RETURN_NONE;
136}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000137
Thomas Wouters477c8d52006-05-27 19:21:47 +0000138
139static PyMethodDef BaseException_methods[] = {
140 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000141 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000142 {NULL, NULL, 0, NULL},
143};
144
145
Thomas Wouters477c8d52006-05-27 19:21:47 +0000146static PyObject *
147BaseException_get_dict(PyBaseExceptionObject *self)
148{
149 if (self->dict == NULL) {
150 self->dict = PyDict_New();
151 if (!self->dict)
152 return NULL;
153 }
154 Py_INCREF(self->dict);
155 return self->dict;
156}
157
158static int
159BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
160{
161 if (val == NULL) {
162 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
163 return -1;
164 }
165 if (!PyDict_Check(val)) {
166 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
167 return -1;
168 }
169 Py_CLEAR(self->dict);
170 Py_INCREF(val);
171 self->dict = val;
172 return 0;
173}
174
175static PyObject *
176BaseException_get_args(PyBaseExceptionObject *self)
177{
178 if (self->args == NULL) {
179 Py_INCREF(Py_None);
180 return Py_None;
181 }
182 Py_INCREF(self->args);
183 return self->args;
184}
185
186static int
187BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
188{
189 PyObject *seq;
190 if (val == NULL) {
191 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
192 return -1;
193 }
194 seq = PySequence_Tuple(val);
195 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000196 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000197 self->args = seq;
198 return 0;
199}
200
Guido van Rossum360e4b82007-05-14 22:51:27 +0000201
Thomas Wouters477c8d52006-05-27 19:21:47 +0000202static PyGetSetDef BaseException_getset[] = {
203 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
204 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
205 {NULL},
206};
207
208
209static PyTypeObject _PyExc_BaseException = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000210 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +0000211 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000212 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
213 0, /*tp_itemsize*/
214 (destructor)BaseException_dealloc, /*tp_dealloc*/
215 0, /*tp_print*/
216 0, /*tp_getattr*/
217 0, /*tp_setattr*/
218 0, /* tp_compare; */
219 (reprfunc)BaseException_repr, /*tp_repr*/
220 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000221 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222 0, /*tp_as_mapping*/
223 0, /*tp_hash */
224 0, /*tp_call*/
225 (reprfunc)BaseException_str, /*tp_str*/
226 PyObject_GenericGetAttr, /*tp_getattro*/
227 PyObject_GenericSetAttr, /*tp_setattro*/
228 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000229 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
230 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000231 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
232 (traverseproc)BaseException_traverse, /* tp_traverse */
233 (inquiry)BaseException_clear, /* tp_clear */
234 0, /* tp_richcompare */
235 0, /* tp_weaklistoffset */
236 0, /* tp_iter */
237 0, /* tp_iternext */
238 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000239 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000240 BaseException_getset, /* tp_getset */
241 0, /* tp_base */
242 0, /* tp_dict */
243 0, /* tp_descr_get */
244 0, /* tp_descr_set */
245 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
246 (initproc)BaseException_init, /* tp_init */
247 0, /* tp_alloc */
248 BaseException_new, /* tp_new */
249};
250/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
251from the previous implmentation and also allowing Python objects to be used
252in the API */
253PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
254
255/* note these macros omit the last semicolon so the macro invocation may
256 * include it and not look strange.
257 */
258#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
259static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000260 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000261 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000262 sizeof(PyBaseExceptionObject), \
263 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
264 0, 0, 0, 0, 0, 0, 0, \
265 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
266 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
267 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
268 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
269 (initproc)BaseException_init, 0, BaseException_new,\
270}; \
271PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
272
273#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
274static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000275 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000276 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000278 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000279 0, 0, 0, 0, 0, \
280 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000281 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
282 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000283 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000285}; \
286PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
287
288#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
289static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000290 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000291 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000292 sizeof(Py ## EXCSTORE ## Object), 0, \
293 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
294 (reprfunc)EXCSTR, 0, 0, 0, \
295 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
296 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
297 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
298 EXCMEMBERS, 0, &_ ## EXCBASE, \
299 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000300 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000301}; \
302PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
303
304
305/*
306 * Exception extends BaseException
307 */
308SimpleExtendsException(PyExc_BaseException, Exception,
309 "Common base class for all non-exit exceptions.");
310
311
312/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000313 * TypeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000314 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000315SimpleExtendsException(PyExc_Exception, TypeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316 "Inappropriate argument type.");
317
318
319/*
320 * StopIteration extends Exception
321 */
322SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000323 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324
325
326/*
327 * GeneratorExit extends Exception
328 */
329SimpleExtendsException(PyExc_Exception, GeneratorExit,
330 "Request that a generator exit.");
331
332
333/*
334 * SystemExit extends BaseException
335 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000336
337static int
338SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
339{
340 Py_ssize_t size = PyTuple_GET_SIZE(args);
341
342 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
343 return -1;
344
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000345 if (size == 0)
346 return 0;
347 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000348 if (size == 1)
349 self->code = PyTuple_GET_ITEM(args, 0);
350 else if (size > 1)
351 self->code = args;
352 Py_INCREF(self->code);
353 return 0;
354}
355
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000356static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000357SystemExit_clear(PySystemExitObject *self)
358{
359 Py_CLEAR(self->code);
360 return BaseException_clear((PyBaseExceptionObject *)self);
361}
362
363static void
364SystemExit_dealloc(PySystemExitObject *self)
365{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000366 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367 SystemExit_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000368 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369}
370
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000371static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000372SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
373{
374 Py_VISIT(self->code);
375 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
376}
377
378static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000379 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
380 PyDoc_STR("exception code")},
381 {NULL} /* Sentinel */
382};
383
384ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
385 SystemExit_dealloc, 0, SystemExit_members, 0,
386 "Request to exit from the interpreter.");
387
388/*
389 * KeyboardInterrupt extends BaseException
390 */
391SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
392 "Program interrupted by user.");
393
394
395/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000396 * ImportError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000397 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000398SimpleExtendsException(PyExc_Exception, ImportError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399 "Import can't find module, or can't find name in module.");
400
401
402/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000403 * EnvironmentError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404 */
405
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406/* Where a function has a single filename, such as open() or some
407 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
408 * called, giving a third argument which is the filename. But, so
409 * that old code using in-place unpacking doesn't break, e.g.:
410 *
411 * except IOError, (errno, strerror):
412 *
413 * we hack args so that it only contains two items. This also
414 * means we need our own __str__() which prints out the filename
415 * when it was supplied.
416 */
417static int
418EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
419 PyObject *kwds)
420{
421 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
422 PyObject *subslice = NULL;
423
424 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
425 return -1;
426
Thomas Wouters89f507f2006-12-13 04:49:30 +0000427 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000428 return 0;
429 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000430
431 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432 &myerrno, &strerror, &filename)) {
433 return -1;
434 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000435 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000436 self->myerrno = myerrno;
437 Py_INCREF(self->myerrno);
438
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000439 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440 self->strerror = strerror;
441 Py_INCREF(self->strerror);
442
443 /* self->filename will remain Py_None otherwise */
444 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000445 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446 self->filename = filename;
447 Py_INCREF(self->filename);
448
449 subslice = PyTuple_GetSlice(args, 0, 2);
450 if (!subslice)
451 return -1;
452
453 Py_DECREF(self->args); /* replacing args */
454 self->args = subslice;
455 }
456 return 0;
457}
458
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000459static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460EnvironmentError_clear(PyEnvironmentErrorObject *self)
461{
462 Py_CLEAR(self->myerrno);
463 Py_CLEAR(self->strerror);
464 Py_CLEAR(self->filename);
465 return BaseException_clear((PyBaseExceptionObject *)self);
466}
467
468static void
469EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
470{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472 EnvironmentError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000473 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474}
475
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000476static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000477EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
478 void *arg)
479{
480 Py_VISIT(self->myerrno);
481 Py_VISIT(self->strerror);
482 Py_VISIT(self->filename);
483 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
484}
485
486static PyObject *
487EnvironmentError_str(PyEnvironmentErrorObject *self)
488{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000489 if (self->filename)
490 return PyUnicode_FromFormat("[Errno %S] %S: %R",
491 self->myerrno ? self->myerrno: Py_None,
492 self->strerror ? self->strerror: Py_None,
493 self->filename);
494 else if (self->myerrno && self->strerror)
495 return PyUnicode_FromFormat("[Errno %S] %S",
496 self->myerrno ? self->myerrno: Py_None,
497 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000499 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500}
501
502static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000503 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
504 PyDoc_STR("exception errno")},
505 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
506 PyDoc_STR("exception strerror")},
507 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
508 PyDoc_STR("exception filename")},
509 {NULL} /* Sentinel */
510};
511
512
513static PyObject *
514EnvironmentError_reduce(PyEnvironmentErrorObject *self)
515{
516 PyObject *args = self->args;
517 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000518
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519 /* self->args is only the first two real arguments if there was a
520 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000521 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522 args = PyTuple_New(3);
523 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524
525 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 Py_INCREF(tmp);
527 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000528
529 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000530 Py_INCREF(tmp);
531 PyTuple_SET_ITEM(args, 1, tmp);
532
533 Py_INCREF(self->filename);
534 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000535 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000536 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000537
538 if (self->dict)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000539 res = PyTuple_Pack(3, Py_Type(self), args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000540 else
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000541 res = PyTuple_Pack(2, Py_Type(self), args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000542 Py_DECREF(args);
543 return res;
544}
545
546
547static PyMethodDef EnvironmentError_methods[] = {
548 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
549 {NULL}
550};
551
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000552ComplexExtendsException(PyExc_Exception, EnvironmentError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000553 EnvironmentError, EnvironmentError_dealloc,
554 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000555 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000556 "Base class for I/O related errors.");
557
558
559/*
560 * IOError extends EnvironmentError
561 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000562MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000563 EnvironmentError, "I/O operation failed.");
564
565
566/*
567 * OSError extends EnvironmentError
568 */
569MiddlingExtendsException(PyExc_EnvironmentError, OSError,
570 EnvironmentError, "OS system call failed.");
571
572
573/*
574 * WindowsError extends OSError
575 */
576#ifdef MS_WINDOWS
577#include "errmap.h"
578
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000579static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000580WindowsError_clear(PyWindowsErrorObject *self)
581{
582 Py_CLEAR(self->myerrno);
583 Py_CLEAR(self->strerror);
584 Py_CLEAR(self->filename);
585 Py_CLEAR(self->winerror);
586 return BaseException_clear((PyBaseExceptionObject *)self);
587}
588
589static void
590WindowsError_dealloc(PyWindowsErrorObject *self)
591{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000592 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000593 WindowsError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000594 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000595}
596
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000597static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
599{
600 Py_VISIT(self->myerrno);
601 Py_VISIT(self->strerror);
602 Py_VISIT(self->filename);
603 Py_VISIT(self->winerror);
604 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
605}
606
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607static int
608WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
609{
610 PyObject *o_errcode = NULL;
611 long errcode;
612 long posix_errno;
613
614 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
615 == -1)
616 return -1;
617
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000618 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000620
621 /* Set errno to the POSIX errno, and winerror to the Win32
622 error code. */
623 errcode = PyInt_AsLong(self->myerrno);
624 if (errcode == -1 && PyErr_Occurred())
625 return -1;
626 posix_errno = winerror_to_errno(errcode);
627
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000628 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000629 self->winerror = self->myerrno;
630
631 o_errcode = PyInt_FromLong(posix_errno);
632 if (!o_errcode)
633 return -1;
634
635 self->myerrno = o_errcode;
636
637 return 0;
638}
639
640
641static PyObject *
642WindowsError_str(PyWindowsErrorObject *self)
643{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000644 if (self->filename)
645 return PyUnicode_FromFormat("[Error %S] %S: %R",
646 self->winerror ? self->winerror: Py_None,
647 self->strerror ? self->strerror: Py_None,
648 self->filename);
649 else if (self->winerror && self->strerror)
650 return PyUnicode_FromFormat("[Error %S] %S",
651 self->winerror ? self->winerror: Py_None,
652 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000654 return EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000655}
656
657static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000658 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
659 PyDoc_STR("POSIX exception code")},
660 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
661 PyDoc_STR("exception strerror")},
662 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
663 PyDoc_STR("exception filename")},
664 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
665 PyDoc_STR("Win32 exception code")},
666 {NULL} /* Sentinel */
667};
668
669ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
670 WindowsError_dealloc, 0, WindowsError_members,
671 WindowsError_str, "MS-Windows OS system call failed.");
672
673#endif /* MS_WINDOWS */
674
675
676/*
677 * VMSError extends OSError (I think)
678 */
679#ifdef __VMS
680MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
681 "OpenVMS OS system call failed.");
682#endif
683
684
685/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 * EOFError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000688SimpleExtendsException(PyExc_Exception, EOFError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689 "Read beyond end of file.");
690
691
692/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693 * RuntimeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000695SimpleExtendsException(PyExc_Exception, RuntimeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000696 "Unspecified run-time error.");
697
698
699/*
700 * NotImplementedError extends RuntimeError
701 */
702SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
703 "Method or function hasn't been implemented yet.");
704
705/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000706 * NameError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000708SimpleExtendsException(PyExc_Exception, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709 "Name not found globally.");
710
711/*
712 * UnboundLocalError extends NameError
713 */
714SimpleExtendsException(PyExc_NameError, UnboundLocalError,
715 "Local name referenced but not bound to a value.");
716
717/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000718 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000720SimpleExtendsException(PyExc_Exception, AttributeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000721 "Attribute not found.");
722
723
724/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000725 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727
728static int
729SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
730{
731 PyObject *info = NULL;
732 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
733
734 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
735 return -1;
736
737 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000738 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739 self->msg = PyTuple_GET_ITEM(args, 0);
740 Py_INCREF(self->msg);
741 }
742 if (lenargs == 2) {
743 info = PyTuple_GET_ITEM(args, 1);
744 info = PySequence_Tuple(info);
745 if (!info) return -1;
746
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000747 if (PyTuple_GET_SIZE(info) != 4) {
748 /* not a very good error message, but it's what Python 2.4 gives */
749 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
750 Py_DECREF(info);
751 return -1;
752 }
753
754 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755 self->filename = PyTuple_GET_ITEM(info, 0);
756 Py_INCREF(self->filename);
757
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000758 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759 self->lineno = PyTuple_GET_ITEM(info, 1);
760 Py_INCREF(self->lineno);
761
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000762 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763 self->offset = PyTuple_GET_ITEM(info, 2);
764 Py_INCREF(self->offset);
765
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000766 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000767 self->text = PyTuple_GET_ITEM(info, 3);
768 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000769
770 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771 }
772 return 0;
773}
774
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000775static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776SyntaxError_clear(PySyntaxErrorObject *self)
777{
778 Py_CLEAR(self->msg);
779 Py_CLEAR(self->filename);
780 Py_CLEAR(self->lineno);
781 Py_CLEAR(self->offset);
782 Py_CLEAR(self->text);
783 Py_CLEAR(self->print_file_and_line);
784 return BaseException_clear((PyBaseExceptionObject *)self);
785}
786
787static void
788SyntaxError_dealloc(PySyntaxErrorObject *self)
789{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000790 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791 SyntaxError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000792 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793}
794
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000795static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000796SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
797{
798 Py_VISIT(self->msg);
799 Py_VISIT(self->filename);
800 Py_VISIT(self->lineno);
801 Py_VISIT(self->offset);
802 Py_VISIT(self->text);
803 Py_VISIT(self->print_file_and_line);
804 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
805}
806
807/* This is called "my_basename" instead of just "basename" to avoid name
808 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
809 defined, and Python does define that. */
810static char *
811my_basename(char *name)
812{
813 char *cp = name;
814 char *result = name;
815
816 if (name == NULL)
817 return "???";
818 while (*cp != '\0') {
819 if (*cp == SEP)
820 result = cp + 1;
821 ++cp;
822 }
823 return result;
824}
825
826
827static PyObject *
828SyntaxError_str(PySyntaxErrorObject *self)
829{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000830 int have_lineno = 0;
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000831 char *filename = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832
833 /* XXX -- do all the additional formatting with filename and
834 lineno here */
835
Neal Norwitzed2b7392007-08-26 04:51:10 +0000836 if (self->filename && PyUnicode_Check(self->filename)) {
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000837 filename = PyUnicode_AsString(self->filename);
838 }
Guido van Rossumddefaf32007-01-14 03:31:43 +0000839 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000840
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000841 if (!filename && !have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000842 return PyObject_Unicode(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000843
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000844 if (filename && have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000845 return PyUnicode_FromFormat("%S (%s, line %ld)",
846 self->msg ? self->msg : Py_None,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000847 my_basename(filename),
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000848 PyInt_AsLong(self->lineno));
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000849 else if (filename)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000850 return PyUnicode_FromFormat("%S (%s)",
851 self->msg ? self->msg : Py_None,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000852 my_basename(filename));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000853 else /* only have_lineno */
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000854 return PyUnicode_FromFormat("%S (line %ld)",
855 self->msg ? self->msg : Py_None,
856 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000857}
858
859static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
861 PyDoc_STR("exception msg")},
862 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
863 PyDoc_STR("exception filename")},
864 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
865 PyDoc_STR("exception lineno")},
866 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
867 PyDoc_STR("exception offset")},
868 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
869 PyDoc_STR("exception text")},
870 {"print_file_and_line", T_OBJECT,
871 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
872 PyDoc_STR("exception print_file_and_line")},
873 {NULL} /* Sentinel */
874};
875
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000876ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000877 SyntaxError_dealloc, 0, SyntaxError_members,
878 SyntaxError_str, "Invalid syntax.");
879
880
881/*
882 * IndentationError extends SyntaxError
883 */
884MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
885 "Improper indentation.");
886
887
888/*
889 * TabError extends IndentationError
890 */
891MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
892 "Improper mixture of spaces and tabs.");
893
894
895/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000896 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000897 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000898SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000899 "Base class for lookup errors.");
900
901
902/*
903 * IndexError extends LookupError
904 */
905SimpleExtendsException(PyExc_LookupError, IndexError,
906 "Sequence index out of range.");
907
908
909/*
910 * KeyError extends LookupError
911 */
912static PyObject *
913KeyError_str(PyBaseExceptionObject *self)
914{
915 /* If args is a tuple of exactly one item, apply repr to args[0].
916 This is done so that e.g. the exception raised by {}[''] prints
917 KeyError: ''
918 rather than the confusing
919 KeyError
920 alone. The downside is that if KeyError is raised with an explanatory
921 string, that string will be displayed in quotes. Too bad.
922 If args is anything else, use the default BaseException__str__().
923 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000924 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000925 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926 }
927 return BaseException_str(self);
928}
929
930ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
931 0, 0, 0, KeyError_str, "Mapping key not found.");
932
933
934/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000935 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000936 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000937SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000938 "Inappropriate argument value (of correct type).");
939
940/*
941 * UnicodeError extends ValueError
942 */
943
944SimpleExtendsException(PyExc_ValueError, UnicodeError,
945 "Unicode related error.");
946
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +0000948get_bytes(PyObject *attr, const char *name)
949{
950 if (!attr) {
951 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
952 return NULL;
953 }
954
955 if (!PyBytes_Check(attr)) {
956 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
957 return NULL;
958 }
959 Py_INCREF(attr);
960 return attr;
961}
962
963static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964get_unicode(PyObject *attr, const char *name)
965{
966 if (!attr) {
967 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
968 return NULL;
969 }
970
971 if (!PyUnicode_Check(attr)) {
972 PyErr_Format(PyExc_TypeError,
973 "%.200s attribute must be unicode", name);
974 return NULL;
975 }
976 Py_INCREF(attr);
977 return attr;
978}
979
Walter Dörwaldd2034312007-05-18 16:29:38 +0000980static int
981set_unicodefromstring(PyObject **attr, const char *value)
982{
983 PyObject *obj = PyUnicode_FromString(value);
984 if (!obj)
985 return -1;
986 Py_CLEAR(*attr);
987 *attr = obj;
988 return 0;
989}
990
Thomas Wouters477c8d52006-05-27 19:21:47 +0000991PyObject *
992PyUnicodeEncodeError_GetEncoding(PyObject *exc)
993{
Walter Dörwaldd2034312007-05-18 16:29:38 +0000994 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000995}
996
997PyObject *
998PyUnicodeDecodeError_GetEncoding(PyObject *exc)
999{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001000 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001}
1002
1003PyObject *
1004PyUnicodeEncodeError_GetObject(PyObject *exc)
1005{
1006 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1007}
1008
1009PyObject *
1010PyUnicodeDecodeError_GetObject(PyObject *exc)
1011{
Walter Dörwald612344f2007-05-04 19:28:21 +00001012 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001013}
1014
1015PyObject *
1016PyUnicodeTranslateError_GetObject(PyObject *exc)
1017{
1018 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1019}
1020
1021int
1022PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1023{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001024 Py_ssize_t size;
1025 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1026 "object");
1027 if (!obj)
1028 return -1;
1029 *start = ((PyUnicodeErrorObject *)exc)->start;
1030 size = PyUnicode_GET_SIZE(obj);
1031 if (*start<0)
1032 *start = 0; /*XXX check for values <0*/
1033 if (*start>=size)
1034 *start = size-1;
1035 Py_DECREF(obj);
1036 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001037}
1038
1039
1040int
1041PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1042{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001043 Py_ssize_t size;
1044 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1045 if (!obj)
1046 return -1;
1047 size = PyBytes_GET_SIZE(obj);
1048 *start = ((PyUnicodeErrorObject *)exc)->start;
1049 if (*start<0)
1050 *start = 0;
1051 if (*start>=size)
1052 *start = size-1;
1053 Py_DECREF(obj);
1054 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001055}
1056
1057
1058int
1059PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1060{
1061 return PyUnicodeEncodeError_GetStart(exc, start);
1062}
1063
1064
1065int
1066PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1067{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001068 ((PyUnicodeErrorObject *)exc)->start = start;
1069 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001070}
1071
1072
1073int
1074PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1075{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001076 ((PyUnicodeErrorObject *)exc)->start = start;
1077 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001078}
1079
1080
1081int
1082PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1083{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001084 ((PyUnicodeErrorObject *)exc)->start = start;
1085 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086}
1087
1088
1089int
1090PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1091{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001092 Py_ssize_t size;
1093 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1094 "object");
1095 if (!obj)
1096 return -1;
1097 *end = ((PyUnicodeErrorObject *)exc)->end;
1098 size = PyUnicode_GET_SIZE(obj);
1099 if (*end<1)
1100 *end = 1;
1101 if (*end>size)
1102 *end = size;
1103 Py_DECREF(obj);
1104 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001105}
1106
1107
1108int
1109PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1110{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001111 Py_ssize_t size;
1112 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1113 if (!obj)
1114 return -1;
1115 size = PyBytes_GET_SIZE(obj);
1116 *end = ((PyUnicodeErrorObject *)exc)->end;
1117 if (*end<1)
1118 *end = 1;
1119 if (*end>size)
1120 *end = size;
1121 Py_DECREF(obj);
1122 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001123}
1124
1125
1126int
1127PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1128{
1129 return PyUnicodeEncodeError_GetEnd(exc, start);
1130}
1131
1132
1133int
1134PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1135{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001136 ((PyUnicodeErrorObject *)exc)->end = end;
1137 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138}
1139
1140
1141int
1142PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1143{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001144 ((PyUnicodeErrorObject *)exc)->end = end;
1145 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001146}
1147
1148
1149int
1150PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1151{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001152 ((PyUnicodeErrorObject *)exc)->end = end;
1153 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001154}
1155
1156PyObject *
1157PyUnicodeEncodeError_GetReason(PyObject *exc)
1158{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001159 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001160}
1161
1162
1163PyObject *
1164PyUnicodeDecodeError_GetReason(PyObject *exc)
1165{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001166 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001167}
1168
1169
1170PyObject *
1171PyUnicodeTranslateError_GetReason(PyObject *exc)
1172{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001173 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174}
1175
1176
1177int
1178PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1179{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001180 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1181 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182}
1183
1184
1185int
1186PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1187{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001188 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1189 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001190}
1191
1192
1193int
1194PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1195{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001196 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1197 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001198}
1199
1200
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201static int
1202UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1203 PyTypeObject *objecttype)
1204{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001205 Py_CLEAR(self->encoding);
1206 Py_CLEAR(self->object);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001207 Py_CLEAR(self->reason);
1208
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001209 if (!PyArg_ParseTuple(args, "O!O!nnO!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001210 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211 objecttype, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001212 &self->start,
1213 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001214 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001215 self->encoding = self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001216 return -1;
1217 }
1218
1219 Py_INCREF(self->encoding);
1220 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001221 Py_INCREF(self->reason);
1222
1223 return 0;
1224}
1225
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001226static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001227UnicodeError_clear(PyUnicodeErrorObject *self)
1228{
1229 Py_CLEAR(self->encoding);
1230 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001231 Py_CLEAR(self->reason);
1232 return BaseException_clear((PyBaseExceptionObject *)self);
1233}
1234
1235static void
1236UnicodeError_dealloc(PyUnicodeErrorObject *self)
1237{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001238 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001239 UnicodeError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001240 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001241}
1242
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001243static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001244UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1245{
1246 Py_VISIT(self->encoding);
1247 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001248 Py_VISIT(self->reason);
1249 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1250}
1251
1252static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1254 PyDoc_STR("exception encoding")},
1255 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1256 PyDoc_STR("exception object")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001257 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001259 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260 PyDoc_STR("exception end")},
1261 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1262 PyDoc_STR("exception reason")},
1263 {NULL} /* Sentinel */
1264};
1265
1266
1267/*
1268 * UnicodeEncodeError extends UnicodeError
1269 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001270
1271static int
1272UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1273{
1274 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1275 return -1;
1276 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1277 kwds, &PyUnicode_Type);
1278}
1279
1280static PyObject *
1281UnicodeEncodeError_str(PyObject *self)
1282{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001283 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001284
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001285 if (uself->end==uself->start+1) {
1286 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001287 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001288 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001289 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001290 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001291 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001292 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001293 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001294 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001295 fmt,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001296 ((PyUnicodeErrorObject *)self)->encoding,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001297 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001298 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001299 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001300 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001301 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001302 return PyUnicode_FromFormat(
1303 "'%U' codec can't encode characters in position %zd-%zd: %U",
1304 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001305 uself->start,
1306 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001307 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001308 );
1309}
1310
1311static PyTypeObject _PyExc_UnicodeEncodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001312 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001313 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001314 sizeof(PyUnicodeErrorObject), 0,
1315 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1316 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1317 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001318 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1319 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001321 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322};
1323PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1324
1325PyObject *
1326PyUnicodeEncodeError_Create(
1327 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1328 Py_ssize_t start, Py_ssize_t end, const char *reason)
1329{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001330 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001331 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332}
1333
1334
1335/*
1336 * UnicodeDecodeError extends UnicodeError
1337 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001338
1339static int
1340UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1341{
1342 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1343 return -1;
1344 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001345 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346}
1347
1348static PyObject *
1349UnicodeDecodeError_str(PyObject *self)
1350{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001351 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001353 if (uself->end==uself->start+1) {
1354 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001355 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001356 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001357 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001358 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001359 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001360 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001361 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001363 return PyUnicode_FromFormat(
1364 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1365 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001366 uself->start,
1367 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001368 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369 );
1370}
1371
1372static PyTypeObject _PyExc_UnicodeDecodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001373 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001374 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375 sizeof(PyUnicodeErrorObject), 0,
1376 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1377 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1378 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001379 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1380 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001381 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001382 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001383};
1384PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1385
1386PyObject *
1387PyUnicodeDecodeError_Create(
1388 const char *encoding, const char *object, Py_ssize_t length,
1389 Py_ssize_t start, Py_ssize_t end, const char *reason)
1390{
1391 assert(length < INT_MAX);
1392 assert(start < INT_MAX);
1393 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001394 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001395 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001396}
1397
1398
1399/*
1400 * UnicodeTranslateError extends UnicodeError
1401 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402
1403static int
1404UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1405 PyObject *kwds)
1406{
1407 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1408 return -1;
1409
1410 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411 Py_CLEAR(self->reason);
1412
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001413 if (!PyArg_ParseTuple(args, "O!nnO!",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414 &PyUnicode_Type, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001415 &self->start,
1416 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001417 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001418 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419 return -1;
1420 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001421
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423 Py_INCREF(self->reason);
1424
1425 return 0;
1426}
1427
1428
1429static PyObject *
1430UnicodeTranslateError_str(PyObject *self)
1431{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001432 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001433
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001434 if (uself->end==uself->start+1) {
1435 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001436 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001437 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001438 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001439 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001440 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001441 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001442 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001443 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001444 fmt,
1445 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001446 uself->start,
1447 uself->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001448 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001450 return PyUnicode_FromFormat(
1451 "can't translate characters in position %zd-%zd: %U",
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001452 uself->start,
1453 uself->end-1,
1454 uself->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455 );
1456}
1457
1458static PyTypeObject _PyExc_UnicodeTranslateError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001459 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001460 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001461 sizeof(PyUnicodeErrorObject), 0,
1462 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1463 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1464 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001465 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001466 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1467 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001468 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469};
1470PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1471
1472PyObject *
1473PyUnicodeTranslateError_Create(
1474 const Py_UNICODE *object, Py_ssize_t length,
1475 Py_ssize_t start, Py_ssize_t end, const char *reason)
1476{
1477 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001478 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001480
1481
1482/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001483 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001484 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001485SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001486 "Assertion failed.");
1487
1488
1489/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001490 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001491 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001492SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001493 "Base class for arithmetic errors.");
1494
1495
1496/*
1497 * FloatingPointError extends ArithmeticError
1498 */
1499SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1500 "Floating point operation failed.");
1501
1502
1503/*
1504 * OverflowError extends ArithmeticError
1505 */
1506SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1507 "Result too large to be represented.");
1508
1509
1510/*
1511 * ZeroDivisionError extends ArithmeticError
1512 */
1513SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1514 "Second argument to a division or modulo operation was zero.");
1515
1516
1517/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001518 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001519 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001520SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 "Internal error in the Python interpreter.\n"
1522 "\n"
1523 "Please report this to the Python maintainer, along with the traceback,\n"
1524 "the Python version, and the hardware/OS platform and version.");
1525
1526
1527/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001528 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001530SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531 "Weak ref proxy used after referent went away.");
1532
1533
1534/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001535 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001537SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001538
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001539/*
1540 * BufferError extends Exception
1541 */
1542SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
1543
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544
1545/* Warning category docstrings */
1546
1547/*
1548 * Warning extends Exception
1549 */
1550SimpleExtendsException(PyExc_Exception, Warning,
1551 "Base class for warning categories.");
1552
1553
1554/*
1555 * UserWarning extends Warning
1556 */
1557SimpleExtendsException(PyExc_Warning, UserWarning,
1558 "Base class for warnings generated by user code.");
1559
1560
1561/*
1562 * DeprecationWarning extends Warning
1563 */
1564SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1565 "Base class for warnings about deprecated features.");
1566
1567
1568/*
1569 * PendingDeprecationWarning extends Warning
1570 */
1571SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1572 "Base class for warnings about features which will be deprecated\n"
1573 "in the future.");
1574
1575
1576/*
1577 * SyntaxWarning extends Warning
1578 */
1579SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1580 "Base class for warnings about dubious syntax.");
1581
1582
1583/*
1584 * RuntimeWarning extends Warning
1585 */
1586SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1587 "Base class for warnings about dubious runtime behavior.");
1588
1589
1590/*
1591 * FutureWarning extends Warning
1592 */
1593SimpleExtendsException(PyExc_Warning, FutureWarning,
1594 "Base class for warnings about constructs that will change semantically\n"
1595 "in the future.");
1596
1597
1598/*
1599 * ImportWarning extends Warning
1600 */
1601SimpleExtendsException(PyExc_Warning, ImportWarning,
1602 "Base class for warnings about probable mistakes in module imports");
1603
1604
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001605/*
1606 * UnicodeWarning extends Warning
1607 */
1608SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1609 "Base class for warnings about Unicode related problems, mostly\n"
1610 "related to conversion problems.");
1611
1612
Thomas Wouters477c8d52006-05-27 19:21:47 +00001613/* Pre-computed MemoryError instance. Best to create this as early as
1614 * possible and not wait until a MemoryError is actually raised!
1615 */
1616PyObject *PyExc_MemoryErrorInst=NULL;
1617
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1619 Py_FatalError("exceptions bootstrapping error.");
1620
1621#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001622 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1623 Py_FatalError("Module dictionary insertion problem.");
1624
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001625#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1626/* crt variable checking in VisualStudio .NET 2005 */
1627#include <crtdbg.h>
1628
1629static int prevCrtReportMode;
1630static _invalid_parameter_handler prevCrtHandler;
1631
1632/* Invalid parameter handler. Sets a ValueError exception */
1633static void
1634InvalidParameterHandler(
1635 const wchar_t * expression,
1636 const wchar_t * function,
1637 const wchar_t * file,
1638 unsigned int line,
1639 uintptr_t pReserved)
1640{
1641 /* Do nothing, allow execution to continue. Usually this
1642 * means that the CRT will set errno to EINVAL
1643 */
1644}
1645#endif
1646
1647
Thomas Wouters477c8d52006-05-27 19:21:47 +00001648PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001649_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001650{
Neal Norwitz2633c692007-02-26 22:22:47 +00001651 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001652
1653 PRE_INIT(BaseException)
1654 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655 PRE_INIT(TypeError)
1656 PRE_INIT(StopIteration)
1657 PRE_INIT(GeneratorExit)
1658 PRE_INIT(SystemExit)
1659 PRE_INIT(KeyboardInterrupt)
1660 PRE_INIT(ImportError)
1661 PRE_INIT(EnvironmentError)
1662 PRE_INIT(IOError)
1663 PRE_INIT(OSError)
1664#ifdef MS_WINDOWS
1665 PRE_INIT(WindowsError)
1666#endif
1667#ifdef __VMS
1668 PRE_INIT(VMSError)
1669#endif
1670 PRE_INIT(EOFError)
1671 PRE_INIT(RuntimeError)
1672 PRE_INIT(NotImplementedError)
1673 PRE_INIT(NameError)
1674 PRE_INIT(UnboundLocalError)
1675 PRE_INIT(AttributeError)
1676 PRE_INIT(SyntaxError)
1677 PRE_INIT(IndentationError)
1678 PRE_INIT(TabError)
1679 PRE_INIT(LookupError)
1680 PRE_INIT(IndexError)
1681 PRE_INIT(KeyError)
1682 PRE_INIT(ValueError)
1683 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001684 PRE_INIT(UnicodeEncodeError)
1685 PRE_INIT(UnicodeDecodeError)
1686 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001687 PRE_INIT(AssertionError)
1688 PRE_INIT(ArithmeticError)
1689 PRE_INIT(FloatingPointError)
1690 PRE_INIT(OverflowError)
1691 PRE_INIT(ZeroDivisionError)
1692 PRE_INIT(SystemError)
1693 PRE_INIT(ReferenceError)
Neal Norwitzfaa54a32007-08-19 04:23:20 +00001694 PRE_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695 PRE_INIT(MemoryError)
1696 PRE_INIT(Warning)
1697 PRE_INIT(UserWarning)
1698 PRE_INIT(DeprecationWarning)
1699 PRE_INIT(PendingDeprecationWarning)
1700 PRE_INIT(SyntaxWarning)
1701 PRE_INIT(RuntimeWarning)
1702 PRE_INIT(FutureWarning)
1703 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001704 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705
Thomas Wouters477c8d52006-05-27 19:21:47 +00001706 bltinmod = PyImport_ImportModule("__builtin__");
1707 if (bltinmod == NULL)
1708 Py_FatalError("exceptions bootstrapping error.");
1709 bdict = PyModule_GetDict(bltinmod);
1710 if (bdict == NULL)
1711 Py_FatalError("exceptions bootstrapping error.");
1712
1713 POST_INIT(BaseException)
1714 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 POST_INIT(TypeError)
1716 POST_INIT(StopIteration)
1717 POST_INIT(GeneratorExit)
1718 POST_INIT(SystemExit)
1719 POST_INIT(KeyboardInterrupt)
1720 POST_INIT(ImportError)
1721 POST_INIT(EnvironmentError)
1722 POST_INIT(IOError)
1723 POST_INIT(OSError)
1724#ifdef MS_WINDOWS
1725 POST_INIT(WindowsError)
1726#endif
1727#ifdef __VMS
1728 POST_INIT(VMSError)
1729#endif
1730 POST_INIT(EOFError)
1731 POST_INIT(RuntimeError)
1732 POST_INIT(NotImplementedError)
1733 POST_INIT(NameError)
1734 POST_INIT(UnboundLocalError)
1735 POST_INIT(AttributeError)
1736 POST_INIT(SyntaxError)
1737 POST_INIT(IndentationError)
1738 POST_INIT(TabError)
1739 POST_INIT(LookupError)
1740 POST_INIT(IndexError)
1741 POST_INIT(KeyError)
1742 POST_INIT(ValueError)
1743 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001744 POST_INIT(UnicodeEncodeError)
1745 POST_INIT(UnicodeDecodeError)
1746 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001747 POST_INIT(AssertionError)
1748 POST_INIT(ArithmeticError)
1749 POST_INIT(FloatingPointError)
1750 POST_INIT(OverflowError)
1751 POST_INIT(ZeroDivisionError)
1752 POST_INIT(SystemError)
1753 POST_INIT(ReferenceError)
Neal Norwitzfaa54a32007-08-19 04:23:20 +00001754 POST_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755 POST_INIT(MemoryError)
1756 POST_INIT(Warning)
1757 POST_INIT(UserWarning)
1758 POST_INIT(DeprecationWarning)
1759 POST_INIT(PendingDeprecationWarning)
1760 POST_INIT(SyntaxWarning)
1761 POST_INIT(RuntimeWarning)
1762 POST_INIT(FutureWarning)
1763 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001764 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001765
1766 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1767 if (!PyExc_MemoryErrorInst)
1768 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1769
1770 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001771
1772#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1773 /* Set CRT argument error handler */
1774 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1775 /* turn off assertions in debug mode */
1776 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1777#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778}
1779
1780void
1781_PyExc_Fini(void)
1782{
1783 Py_XDECREF(PyExc_MemoryErrorInst);
1784 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001785#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1786 /* reset CRT error handling */
1787 _set_invalid_parameter_handler(prevCrtHandler);
1788 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1789#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001790}