blob: e50a77c33f749e304532c5710ba513a582f1ba29 [file] [log] [blame]
Richard Jones7b9558d2006-05-27 12:29:24 +00001#define PY_SSIZE_T_CLEAN
2#include <Python.h>
3#include "structmember.h"
4#include "osdefs.h"
5
6#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
7#define EXC_MODULE_NAME "exceptions."
8
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00009/* NOTE: If the exception class hierarchy changes, don't forget to update
10 * Lib/test/exception_hierarchy.txt
11 */
12
13PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
14\n\
15Exceptions found here are defined both in the exceptions module and the\n\
16built-in namespace. It is recommended that user-defined exceptions\n\
17inherit from Exception. See the documentation for the exception\n\
18inheritance hierarchy.\n\
19");
20
Richard Jones7b9558d2006-05-27 12:29:24 +000021/*
22 * BaseException
23 */
24static PyObject *
25BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
26{
27 PyBaseExceptionObject *self;
28
29 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
30 /* the dict is created on the fly in PyObject_GenericSetAttr */
31 self->message = self->dict = NULL;
32
33 self->args = PyTuple_New(0);
34 if (!self->args) {
35 Py_DECREF(self);
36 return NULL;
37 }
38
Michael W. Hudson22a80e72006-05-28 15:51:40 +000039 self->message = PyString_FromString("");
Richard Jones7b9558d2006-05-27 12:29:24 +000040 if (!self->message) {
41 Py_DECREF(self);
42 return NULL;
43 }
44
45 return (PyObject *)self;
46}
47
48static int
49BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
50{
51 Py_DECREF(self->args);
52 self->args = args;
53 Py_INCREF(self->args);
54
55 if (PyTuple_GET_SIZE(self->args) == 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +000056 Py_CLEAR(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000057 self->message = PyTuple_GET_ITEM(self->args, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +000058 Py_INCREF(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000059 }
60 return 0;
61}
62
Michael W. Hudson96495ee2006-05-28 17:40:29 +000063static int
Richard Jones7b9558d2006-05-27 12:29:24 +000064BaseException_clear(PyBaseExceptionObject *self)
65{
66 Py_CLEAR(self->dict);
67 Py_CLEAR(self->args);
68 Py_CLEAR(self->message);
69 return 0;
70}
71
72static void
73BaseException_dealloc(PyBaseExceptionObject *self)
74{
75 BaseException_clear(self);
76 self->ob_type->tp_free((PyObject *)self);
77}
78
Michael W. Hudson96495ee2006-05-28 17:40:29 +000079static int
Richard Jones7b9558d2006-05-27 12:29:24 +000080BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
81{
Michael W. Hudson22a80e72006-05-28 15:51:40 +000082 Py_VISIT(self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +000083 Py_VISIT(self->args);
84 Py_VISIT(self->message);
85 return 0;
86}
87
88static PyObject *
89BaseException_str(PyBaseExceptionObject *self)
90{
91 PyObject *out;
92
Michael W. Hudson22a80e72006-05-28 15:51:40 +000093 switch (PyTuple_GET_SIZE(self->args)) {
Richard Jones7b9558d2006-05-27 12:29:24 +000094 case 0:
95 out = PyString_FromString("");
96 break;
97 case 1:
Michael W. Hudson22a80e72006-05-28 15:51:40 +000098 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +000099 break;
Richard Jones7b9558d2006-05-27 12:29:24 +0000100 default:
101 out = PyObject_Str(self->args);
102 break;
103 }
104
105 return out;
106}
107
108static PyObject *
109BaseException_repr(PyBaseExceptionObject *self)
110{
Richard Jones7b9558d2006-05-27 12:29:24 +0000111 PyObject *repr_suffix;
112 PyObject *repr;
113 char *name;
114 char *dot;
115
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000116 repr_suffix = PyObject_Repr(self->args);
117 if (!repr_suffix)
Richard Jones7b9558d2006-05-27 12:29:24 +0000118 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000119
120 name = (char *)self->ob_type->tp_name;
121 dot = strrchr(name, '.');
122 if (dot != NULL) name = dot+1;
123
124 repr = PyString_FromString(name);
125 if (!repr) {
126 Py_DECREF(repr_suffix);
127 return NULL;
128 }
129
130 PyString_ConcatAndDel(&repr, repr_suffix);
131 return repr;
132}
133
134/* Pickling support */
135static PyObject *
136BaseException_reduce(PyBaseExceptionObject *self)
137{
138 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
139}
140
141
142#ifdef Py_USING_UNICODE
143/* while this method generates fairly uninspired output, it a least
144 * guarantees that we can display exceptions that have unicode attributes
145 */
146static PyObject *
147BaseException_unicode(PyBaseExceptionObject *self)
148{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000149 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000150 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000151 if (PyTuple_GET_SIZE(self->args) == 1)
152 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000153 return PyObject_Unicode(self->args);
154}
155#endif /* Py_USING_UNICODE */
156
157static PyMethodDef BaseException_methods[] = {
158 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
159#ifdef Py_USING_UNICODE
160 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
161#endif
162 {NULL, NULL, 0, NULL},
163};
164
165
166
167static PyObject *
168BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
169{
170 return PySequence_GetItem(self->args, index);
171}
172
173static PySequenceMethods BaseException_as_sequence = {
174 0, /* sq_length; */
175 0, /* sq_concat; */
176 0, /* sq_repeat; */
177 (ssizeargfunc)BaseException_getitem, /* sq_item; */
178 0, /* sq_slice; */
179 0, /* sq_ass_item; */
180 0, /* sq_ass_slice; */
181 0, /* sq_contains; */
182 0, /* sq_inplace_concat; */
183 0 /* sq_inplace_repeat; */
184};
185
186static PyMemberDef BaseException_members[] = {
187 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
188 PyDoc_STR("exception message")},
189 {NULL} /* Sentinel */
190};
191
192
193static PyObject *
194BaseException_get_dict(PyBaseExceptionObject *self)
195{
196 if (self->dict == NULL) {
197 self->dict = PyDict_New();
198 if (!self->dict)
199 return NULL;
200 }
201 Py_INCREF(self->dict);
202 return self->dict;
203}
204
205static int
206BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
207{
208 if (val == NULL) {
209 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
210 return -1;
211 }
212 if (!PyDict_Check(val)) {
213 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
214 return -1;
215 }
216 Py_CLEAR(self->dict);
217 Py_INCREF(val);
218 self->dict = val;
219 return 0;
220}
221
222static PyObject *
223BaseException_get_args(PyBaseExceptionObject *self)
224{
225 if (self->args == NULL) {
226 Py_INCREF(Py_None);
227 return Py_None;
228 }
229 Py_INCREF(self->args);
230 return self->args;
231}
232
233static int
234BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
235{
236 PyObject *seq;
237 if (val == NULL) {
238 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
239 return -1;
240 }
241 seq = PySequence_Tuple(val);
242 if (!seq) return -1;
243 self->args = seq;
244 return 0;
245}
246
247static PyGetSetDef BaseException_getset[] = {
248 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
249 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
250 {NULL},
251};
252
253
254static PyTypeObject _PyExc_BaseException = {
255 PyObject_HEAD_INIT(NULL)
256 0, /*ob_size*/
257 EXC_MODULE_NAME "BaseException", /*tp_name*/
258 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
259 0, /*tp_itemsize*/
260 (destructor)BaseException_dealloc, /*tp_dealloc*/
261 0, /*tp_print*/
262 0, /*tp_getattr*/
263 0, /*tp_setattr*/
264 0, /* tp_compare; */
265 (reprfunc)BaseException_repr, /*tp_repr*/
266 0, /*tp_as_number*/
267 &BaseException_as_sequence, /*tp_as_sequence*/
268 0, /*tp_as_mapping*/
269 0, /*tp_hash */
270 0, /*tp_call*/
271 (reprfunc)BaseException_str, /*tp_str*/
272 PyObject_GenericGetAttr, /*tp_getattro*/
273 PyObject_GenericSetAttr, /*tp_setattro*/
274 0, /*tp_as_buffer*/
275 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
276 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
277 (traverseproc)BaseException_traverse, /* tp_traverse */
278 (inquiry)BaseException_clear, /* tp_clear */
279 0, /* tp_richcompare */
280 0, /* tp_weaklistoffset */
281 0, /* tp_iter */
282 0, /* tp_iternext */
283 BaseException_methods, /* tp_methods */
284 BaseException_members, /* tp_members */
285 BaseException_getset, /* tp_getset */
286 0, /* tp_base */
287 0, /* tp_dict */
288 0, /* tp_descr_get */
289 0, /* tp_descr_set */
290 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
291 (initproc)BaseException_init, /* tp_init */
292 0, /* tp_alloc */
293 BaseException_new, /* tp_new */
294};
295/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
296from the previous implmentation and also allowing Python objects to be used
297in the API */
298PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
299
Richard Jones2d555b32006-05-27 16:15:11 +0000300/* note these macros omit the last semicolon so the macro invocation may
301 * include it and not look strange.
302 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000303#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
304static PyTypeObject _PyExc_ ## EXCNAME = { \
305 PyObject_HEAD_INIT(NULL) \
306 0, \
307 EXC_MODULE_NAME # EXCNAME, \
308 sizeof(PyBaseExceptionObject), \
309 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
310 0, 0, 0, 0, 0, 0, 0, \
311 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
312 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
313 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
314 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
315 (initproc)BaseException_init, 0, BaseException_new,\
316}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000317PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000318
319#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
320static PyTypeObject _PyExc_ ## EXCNAME = { \
321 PyObject_HEAD_INIT(NULL) \
322 0, \
323 EXC_MODULE_NAME # EXCNAME, \
324 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000325 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000326 0, 0, 0, 0, 0, \
327 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000328 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
329 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000330 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000331 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000332}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000333PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000334
335#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
336static PyTypeObject _PyExc_ ## EXCNAME = { \
337 PyObject_HEAD_INIT(NULL) \
338 0, \
339 EXC_MODULE_NAME # EXCNAME, \
340 sizeof(Py ## EXCSTORE ## Object), 0, \
341 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
342 (reprfunc)EXCSTR, 0, 0, 0, \
343 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
344 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
345 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
346 EXCMEMBERS, 0, &_ ## EXCBASE, \
347 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000348 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000349}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000350PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000351
352
353/*
354 * Exception extends BaseException
355 */
356SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000357 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000358
359
360/*
361 * StandardError extends Exception
362 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000363SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000364 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000365 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000366
367
368/*
369 * TypeError extends StandardError
370 */
371SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000372 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000373
374
375/*
376 * StopIteration extends Exception
377 */
378SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000379 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000380
381
382/*
383 * GeneratorExit extends Exception
384 */
385SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000386 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000387
388
389/*
390 * SystemExit extends BaseException
391 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000392
393static int
394SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
395{
396 Py_ssize_t size = PyTuple_GET_SIZE(args);
397
398 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
399 return -1;
400
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000401 if (size == 0)
402 return 0;
403 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000404 if (size == 1)
405 self->code = PyTuple_GET_ITEM(args, 0);
406 else if (size > 1)
407 self->code = args;
408 Py_INCREF(self->code);
409 return 0;
410}
411
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000412static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000413SystemExit_clear(PySystemExitObject *self)
414{
415 Py_CLEAR(self->code);
416 return BaseException_clear((PyBaseExceptionObject *)self);
417}
418
419static void
420SystemExit_dealloc(PySystemExitObject *self)
421{
422 SystemExit_clear(self);
423 self->ob_type->tp_free((PyObject *)self);
424}
425
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000426static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000427SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
428{
429 Py_VISIT(self->code);
430 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
431}
432
433static PyMemberDef SystemExit_members[] = {
434 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
435 PyDoc_STR("exception message")},
436 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
437 PyDoc_STR("exception code")},
438 {NULL} /* Sentinel */
439};
440
441ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
442 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000443 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000444
445/*
446 * KeyboardInterrupt extends BaseException
447 */
448SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000449 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000450
451
452/*
453 * ImportError extends StandardError
454 */
455SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000456 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000457
458
459/*
460 * EnvironmentError extends StandardError
461 */
462
Richard Jones7b9558d2006-05-27 12:29:24 +0000463/* Where a function has a single filename, such as open() or some
464 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
465 * called, giving a third argument which is the filename. But, so
466 * that old code using in-place unpacking doesn't break, e.g.:
467 *
468 * except IOError, (errno, strerror):
469 *
470 * we hack args so that it only contains two items. This also
471 * means we need our own __str__() which prints out the filename
472 * when it was supplied.
473 */
474static int
475EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
476 PyObject *kwds)
477{
478 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
479 PyObject *subslice = NULL;
480
481 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
482 return -1;
483
484 if (PyTuple_GET_SIZE(args) <= 1) {
485 return 0;
486 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000487
488 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000489 &myerrno, &strerror, &filename)) {
490 return -1;
491 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000492 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000493 self->myerrno = myerrno;
494 Py_INCREF(self->myerrno);
495
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000496 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000497 self->strerror = strerror;
498 Py_INCREF(self->strerror);
499
500 /* self->filename will remain Py_None otherwise */
501 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000502 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000503 self->filename = filename;
504 Py_INCREF(self->filename);
505
506 subslice = PyTuple_GetSlice(args, 0, 2);
507 if (!subslice)
508 return -1;
509
510 Py_DECREF(self->args); /* replacing args */
511 self->args = subslice;
512 }
513 return 0;
514}
515
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000516static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000517EnvironmentError_clear(PyEnvironmentErrorObject *self)
518{
519 Py_CLEAR(self->myerrno);
520 Py_CLEAR(self->strerror);
521 Py_CLEAR(self->filename);
522 return BaseException_clear((PyBaseExceptionObject *)self);
523}
524
525static void
526EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
527{
528 EnvironmentError_clear(self);
529 self->ob_type->tp_free((PyObject *)self);
530}
531
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000532static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000533EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
534 void *arg)
535{
536 Py_VISIT(self->myerrno);
537 Py_VISIT(self->strerror);
538 Py_VISIT(self->filename);
539 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
540}
541
542static PyObject *
543EnvironmentError_str(PyEnvironmentErrorObject *self)
544{
545 PyObject *rtnval = NULL;
546
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000547 if (self->filename) {
548 PyObject *fmt;
549 PyObject *repr;
550 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000551
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000552 fmt = PyString_FromString("[Errno %s] %s: %s");
553 if (!fmt)
554 return NULL;
555
556 repr = PyObject_Repr(self->filename);
557 if (!repr) {
558 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000559 return NULL;
560 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000561 tuple = PyTuple_New(3);
562 if (!tuple) {
563 Py_DECREF(repr);
564 Py_DECREF(fmt);
565 return NULL;
566 }
567
568 if (self->myerrno) {
569 Py_INCREF(self->myerrno);
570 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
571 }
572 else {
573 Py_INCREF(Py_None);
574 PyTuple_SET_ITEM(tuple, 0, Py_None);
575 }
576 if (self->strerror) {
577 Py_INCREF(self->strerror);
578 PyTuple_SET_ITEM(tuple, 1, self->strerror);
579 }
580 else {
581 Py_INCREF(Py_None);
582 PyTuple_SET_ITEM(tuple, 1, Py_None);
583 }
584
Richard Jones7b9558d2006-05-27 12:29:24 +0000585 Py_INCREF(repr);
586 PyTuple_SET_ITEM(tuple, 2, repr);
587
588 rtnval = PyString_Format(fmt, tuple);
589
590 Py_DECREF(fmt);
591 Py_DECREF(tuple);
592 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000593 else if (self->myerrno && self->strerror) {
594 PyObject *fmt;
595 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000596
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000597 fmt = PyString_FromString("[Errno %s] %s");
598 if (!fmt)
599 return NULL;
600
601 tuple = PyTuple_New(2);
602 if (!tuple) {
603 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000604 return NULL;
605 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000606
607 if (self->myerrno) {
608 Py_INCREF(self->myerrno);
609 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
610 }
611 else {
612 Py_INCREF(Py_None);
613 PyTuple_SET_ITEM(tuple, 0, Py_None);
614 }
615 if (self->strerror) {
616 Py_INCREF(self->strerror);
617 PyTuple_SET_ITEM(tuple, 1, self->strerror);
618 }
619 else {
620 Py_INCREF(Py_None);
621 PyTuple_SET_ITEM(tuple, 1, Py_None);
622 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000623
624 rtnval = PyString_Format(fmt, tuple);
625
626 Py_DECREF(fmt);
627 Py_DECREF(tuple);
628 }
629 else
630 rtnval = BaseException_str((PyBaseExceptionObject *)self);
631
632 return rtnval;
633}
634
635static PyMemberDef EnvironmentError_members[] = {
636 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
637 PyDoc_STR("exception message")},
638 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000639 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000640 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000641 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000642 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000643 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000644 {NULL} /* Sentinel */
645};
646
647
648static PyObject *
649EnvironmentError_reduce(PyEnvironmentErrorObject *self)
650{
651 PyObject *args = self->args;
652 PyObject *res = NULL, *tmp;
653 /* self->args is only the first two real arguments if there was a
654 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000655 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000656 args = PyTuple_New(3);
657 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000658
659 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000660 Py_INCREF(tmp);
661 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000662
663 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000664 Py_INCREF(tmp);
665 PyTuple_SET_ITEM(args, 1, tmp);
666
667 Py_INCREF(self->filename);
668 PyTuple_SET_ITEM(args, 2, self->filename);
669 } else {
670 Py_INCREF(args);
671 }
672 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +0000673 Py_DECREF(args);
674 return res;
675}
676
677
678static PyMethodDef EnvironmentError_methods[] = {
679 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
680 {NULL}
681};
682
683ComplexExtendsException(PyExc_StandardError, EnvironmentError,
684 EnvironmentError, EnvironmentError_dealloc,
685 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000686 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000687 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000688
689
690/*
691 * IOError extends EnvironmentError
692 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000693MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000694 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000695
696
697/*
698 * OSError extends EnvironmentError
699 */
700MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000701 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000702
703
704/*
705 * WindowsError extends OSError
706 */
707#ifdef MS_WINDOWS
708#include "errmap.h"
709
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000710static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000711WindowsError_clear(PyWindowsErrorObject *self)
712{
713 Py_CLEAR(self->myerrno);
714 Py_CLEAR(self->strerror);
715 Py_CLEAR(self->filename);
716 Py_CLEAR(self->winerror);
717 return BaseException_clear((PyBaseExceptionObject *)self);
718}
719
720static void
721WindowsError_dealloc(PyWindowsErrorObject *self)
722{
723 WindowsError_clear(self);
724 self->ob_type->tp_free((PyObject *)self);
725}
726
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000727static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000728WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
729{
730 Py_VISIT(self->myerrno);
731 Py_VISIT(self->strerror);
732 Py_VISIT(self->filename);
733 Py_VISIT(self->winerror);
734 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
735}
736
Richard Jones7b9558d2006-05-27 12:29:24 +0000737static int
738WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
739{
740 PyObject *o_errcode = NULL;
741 long errcode;
742 long posix_errno;
743
744 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
745 == -1)
746 return -1;
747
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000748 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000749 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000750
751 /* Set errno to the POSIX errno, and winerror to the Win32
752 error code. */
753 errcode = PyInt_AsLong(self->myerrno);
754 if (errcode == -1 && PyErr_Occurred())
755 return -1;
756 posix_errno = winerror_to_errno(errcode);
757
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000758 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000759 self->winerror = self->myerrno;
760
761 o_errcode = PyInt_FromLong(posix_errno);
762 if (!o_errcode)
763 return -1;
764
765 self->myerrno = o_errcode;
766
767 return 0;
768}
769
770
771static PyObject *
772WindowsError_str(PyWindowsErrorObject *self)
773{
Richard Jones7b9558d2006-05-27 12:29:24 +0000774 PyObject *rtnval = NULL;
775
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000776 if (self->filename) {
777 PyObject *fmt;
778 PyObject *repr;
779 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000780
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000781 fmt = PyString_FromString("[Error %s] %s: %s");
782 if (!fmt)
783 return NULL;
784
785 repr = PyObject_Repr(self->filename);
786 if (!repr) {
787 Py_DECREF(fmt);
788 return NULL;
789 }
790 tuple = PyTuple_New(3);
791 if (!tuple) {
792 Py_DECREF(repr);
793 Py_DECREF(fmt);
794 return NULL;
795 }
796
797 if (self->myerrno) {
798 Py_INCREF(self->myerrno);
799 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
800 }
801 else {
802 Py_INCREF(Py_None);
803 PyTuple_SET_ITEM(tuple, 0, Py_None);
804 }
805 if (self->strerror) {
806 Py_INCREF(self->strerror);
807 PyTuple_SET_ITEM(tuple, 1, self->strerror);
808 }
809 else {
810 Py_INCREF(Py_None);
811 PyTuple_SET_ITEM(tuple, 1, Py_None);
812 }
813
814 Py_INCREF(repr);
815 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000816
817 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000818
819 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000820 Py_DECREF(tuple);
821 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000822 else if (self->myerrno && self->strerror) {
823 PyObject *fmt;
824 PyObject *tuple;
825
Richard Jones7b9558d2006-05-27 12:29:24 +0000826 fmt = PyString_FromString("[Error %s] %s");
827 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000828 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000829
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000830 tuple = PyTuple_New(2);
831 if (!tuple) {
832 Py_DECREF(fmt);
833 return NULL;
834 }
835
836 if (self->myerrno) {
837 Py_INCREF(self->myerrno);
838 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
839 }
840 else {
841 Py_INCREF(Py_None);
842 PyTuple_SET_ITEM(tuple, 0, Py_None);
843 }
844 if (self->strerror) {
845 Py_INCREF(self->strerror);
846 PyTuple_SET_ITEM(tuple, 1, self->strerror);
847 }
848 else {
849 Py_INCREF(Py_None);
850 PyTuple_SET_ITEM(tuple, 1, Py_None);
851 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000852
853 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000854
855 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000856 Py_DECREF(tuple);
857 }
858 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000859 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000860
Richard Jones7b9558d2006-05-27 12:29:24 +0000861 return rtnval;
862}
863
864static PyMemberDef WindowsError_members[] = {
865 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
866 PyDoc_STR("exception message")},
867 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000868 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000869 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000870 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000871 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000872 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000873 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000874 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000875 {NULL} /* Sentinel */
876};
877
Richard Jones2d555b32006-05-27 16:15:11 +0000878ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
879 WindowsError_dealloc, 0, WindowsError_members,
880 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000881
882#endif /* MS_WINDOWS */
883
884
885/*
886 * VMSError extends OSError (I think)
887 */
888#ifdef __VMS
889MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000890 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000891#endif
892
893
894/*
895 * EOFError extends StandardError
896 */
897SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000898 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000899
900
901/*
902 * RuntimeError extends StandardError
903 */
904SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000905 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000906
907
908/*
909 * NotImplementedError extends RuntimeError
910 */
911SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000912 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000913
914/*
915 * NameError extends StandardError
916 */
917SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000918 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000919
920/*
921 * UnboundLocalError extends NameError
922 */
923SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000924 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000925
926/*
927 * AttributeError extends StandardError
928 */
929SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000930 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000931
932
933/*
934 * SyntaxError extends StandardError
935 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000936
937static int
938SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
939{
940 PyObject *info = NULL;
941 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
942
943 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
944 return -1;
945
946 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000947 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000948 self->msg = PyTuple_GET_ITEM(args, 0);
949 Py_INCREF(self->msg);
950 }
951 if (lenargs == 2) {
952 info = PyTuple_GET_ITEM(args, 1);
953 info = PySequence_Tuple(info);
954 if (!info) return -1;
955
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000956 if (PyTuple_GET_SIZE(info) != 4) {
957 /* not a very good error message, but it's what Python 2.4 gives */
958 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
959 Py_DECREF(info);
960 return -1;
961 }
962
963 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +0000964 self->filename = PyTuple_GET_ITEM(info, 0);
965 Py_INCREF(self->filename);
966
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000967 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +0000968 self->lineno = PyTuple_GET_ITEM(info, 1);
969 Py_INCREF(self->lineno);
970
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000971 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +0000972 self->offset = PyTuple_GET_ITEM(info, 2);
973 Py_INCREF(self->offset);
974
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000975 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +0000976 self->text = PyTuple_GET_ITEM(info, 3);
977 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000978
979 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +0000980 }
981 return 0;
982}
983
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000984static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000985SyntaxError_clear(PySyntaxErrorObject *self)
986{
987 Py_CLEAR(self->msg);
988 Py_CLEAR(self->filename);
989 Py_CLEAR(self->lineno);
990 Py_CLEAR(self->offset);
991 Py_CLEAR(self->text);
992 Py_CLEAR(self->print_file_and_line);
993 return BaseException_clear((PyBaseExceptionObject *)self);
994}
995
996static void
997SyntaxError_dealloc(PySyntaxErrorObject *self)
998{
999 SyntaxError_clear(self);
1000 self->ob_type->tp_free((PyObject *)self);
1001}
1002
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001003static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001004SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1005{
1006 Py_VISIT(self->msg);
1007 Py_VISIT(self->filename);
1008 Py_VISIT(self->lineno);
1009 Py_VISIT(self->offset);
1010 Py_VISIT(self->text);
1011 Py_VISIT(self->print_file_and_line);
1012 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1013}
1014
1015/* This is called "my_basename" instead of just "basename" to avoid name
1016 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1017 defined, and Python does define that. */
1018static char *
1019my_basename(char *name)
1020{
1021 char *cp = name;
1022 char *result = name;
1023
1024 if (name == NULL)
1025 return "???";
1026 while (*cp != '\0') {
1027 if (*cp == SEP)
1028 result = cp + 1;
1029 ++cp;
1030 }
1031 return result;
1032}
1033
1034
1035static PyObject *
1036SyntaxError_str(PySyntaxErrorObject *self)
1037{
1038 PyObject *str;
1039 PyObject *result;
1040
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001041 if (self->msg)
1042 str = PyObject_Str(self->msg);
1043 else
1044 str = PyObject_Str(Py_None);
Richard Jones7b9558d2006-05-27 12:29:24 +00001045 result = str;
1046
1047 /* XXX -- do all the additional formatting with filename and
1048 lineno here */
1049
1050 if (str != NULL && PyString_Check(str)) {
1051 int have_filename = 0;
1052 int have_lineno = 0;
1053 char *buffer = NULL;
1054
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001055 have_filename = (self->filename != NULL) &&
Richard Jones7b9558d2006-05-27 12:29:24 +00001056 PyString_Check(self->filename);
1057 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
1058
1059 if (have_filename || have_lineno) {
1060 Py_ssize_t bufsize = PyString_GET_SIZE(str) + 64;
1061 if (have_filename)
1062 bufsize += PyString_GET_SIZE(self->filename);
1063
1064 buffer = (char *)PyMem_MALLOC(bufsize);
1065 if (buffer != NULL) {
1066 if (have_filename && have_lineno)
1067 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1068 PyString_AS_STRING(str),
1069 my_basename(PyString_AS_STRING(self->filename)),
1070 PyInt_AsLong(self->lineno));
1071 else if (have_filename)
1072 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1073 PyString_AS_STRING(str),
1074 my_basename(PyString_AS_STRING(self->filename)));
1075 else if (have_lineno)
1076 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1077 PyString_AS_STRING(str),
1078 PyInt_AsLong(self->lineno));
1079
1080 result = PyString_FromString(buffer);
1081 PyMem_FREE(buffer);
1082
1083 if (result == NULL)
1084 result = str;
1085 else
1086 Py_DECREF(str);
1087 }
1088 }
1089 }
1090 return result;
1091}
1092
1093static PyMemberDef SyntaxError_members[] = {
1094 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1095 PyDoc_STR("exception message")},
1096 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1097 PyDoc_STR("exception msg")},
1098 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1099 PyDoc_STR("exception filename")},
1100 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1101 PyDoc_STR("exception lineno")},
1102 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1103 PyDoc_STR("exception offset")},
1104 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1105 PyDoc_STR("exception text")},
1106 {"print_file_and_line", T_OBJECT,
1107 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1108 PyDoc_STR("exception print_file_and_line")},
1109 {NULL} /* Sentinel */
1110};
1111
1112ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1113 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001114 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001115
1116
1117/*
1118 * IndentationError extends SyntaxError
1119 */
1120MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001121 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001122
1123
1124/*
1125 * TabError extends IndentationError
1126 */
1127MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001128 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001129
1130
1131/*
1132 * LookupError extends StandardError
1133 */
1134SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001135 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001136
1137
1138/*
1139 * IndexError extends LookupError
1140 */
1141SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001142 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001143
1144
1145/*
1146 * KeyError extends LookupError
1147 */
1148static PyObject *
1149KeyError_str(PyBaseExceptionObject *self)
1150{
1151 /* If args is a tuple of exactly one item, apply repr to args[0].
1152 This is done so that e.g. the exception raised by {}[''] prints
1153 KeyError: ''
1154 rather than the confusing
1155 KeyError
1156 alone. The downside is that if KeyError is raised with an explanatory
1157 string, that string will be displayed in quotes. Too bad.
1158 If args is anything else, use the default BaseException__str__().
1159 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001160 if (PyTuple_GET_SIZE(self->args) == 1) {
1161 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001162 }
1163 return BaseException_str(self);
1164}
1165
1166ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001167 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001168
1169
1170/*
1171 * ValueError extends StandardError
1172 */
1173SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001174 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001175
1176/*
1177 * UnicodeError extends ValueError
1178 */
1179
1180SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001181 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001182
1183#ifdef Py_USING_UNICODE
1184static int
1185get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1186{
1187 if (!attr) {
1188 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1189 return -1;
1190 }
1191
1192 if (PyInt_Check(attr)) {
1193 *value = PyInt_AS_LONG(attr);
1194 } else if (PyLong_Check(attr)) {
1195 *value = _PyLong_AsSsize_t(attr);
1196 if (*value == -1 && PyErr_Occurred())
1197 return -1;
1198 } else {
1199 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1200 return -1;
1201 }
1202 return 0;
1203}
1204
1205static int
1206set_ssize_t(PyObject **attr, Py_ssize_t value)
1207{
1208 PyObject *obj = PyInt_FromSsize_t(value);
1209 if (!obj)
1210 return -1;
1211 Py_XDECREF(*attr);
1212 *attr = obj;
1213 return 0;
1214}
1215
1216static PyObject *
1217get_string(PyObject *attr, const char *name)
1218{
1219 if (!attr) {
1220 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1221 return NULL;
1222 }
1223
1224 if (!PyString_Check(attr)) {
1225 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1226 return NULL;
1227 }
1228 Py_INCREF(attr);
1229 return attr;
1230}
1231
1232
1233static int
1234set_string(PyObject **attr, const char *value)
1235{
1236 PyObject *obj = PyString_FromString(value);
1237 if (!obj)
1238 return -1;
1239 Py_XDECREF(*attr);
1240 *attr = obj;
1241 return 0;
1242}
1243
1244
1245static PyObject *
1246get_unicode(PyObject *attr, const char *name)
1247{
1248 if (!attr) {
1249 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1250 return NULL;
1251 }
1252
1253 if (!PyUnicode_Check(attr)) {
1254 PyErr_Format(PyExc_TypeError,
1255 "%.200s attribute must be unicode", name);
1256 return NULL;
1257 }
1258 Py_INCREF(attr);
1259 return attr;
1260}
1261
1262PyObject *
1263PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1264{
1265 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1266}
1267
1268PyObject *
1269PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1270{
1271 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1272}
1273
1274PyObject *
1275PyUnicodeEncodeError_GetObject(PyObject *exc)
1276{
1277 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1278}
1279
1280PyObject *
1281PyUnicodeDecodeError_GetObject(PyObject *exc)
1282{
1283 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1284}
1285
1286PyObject *
1287PyUnicodeTranslateError_GetObject(PyObject *exc)
1288{
1289 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1290}
1291
1292int
1293PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1294{
1295 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1296 Py_ssize_t size;
1297 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1298 "object");
1299 if (!obj) return -1;
1300 size = PyUnicode_GET_SIZE(obj);
1301 if (*start<0)
1302 *start = 0; /*XXX check for values <0*/
1303 if (*start>=size)
1304 *start = size-1;
1305 return 0;
1306 }
1307 return -1;
1308}
1309
1310
1311int
1312PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1313{
1314 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1315 Py_ssize_t size;
1316 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1317 "object");
1318 if (!obj) return -1;
1319 size = PyString_GET_SIZE(obj);
1320 if (*start<0)
1321 *start = 0;
1322 if (*start>=size)
1323 *start = size-1;
1324 return 0;
1325 }
1326 return -1;
1327}
1328
1329
1330int
1331PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1332{
1333 return PyUnicodeEncodeError_GetStart(exc, start);
1334}
1335
1336
1337int
1338PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1339{
1340 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1341}
1342
1343
1344int
1345PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1346{
1347 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1348}
1349
1350
1351int
1352PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1353{
1354 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1355}
1356
1357
1358int
1359PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1360{
1361 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1362 Py_ssize_t size;
1363 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1364 "object");
1365 if (!obj) return -1;
1366 size = PyUnicode_GET_SIZE(obj);
1367 if (*end<1)
1368 *end = 1;
1369 if (*end>size)
1370 *end = size;
1371 return 0;
1372 }
1373 return -1;
1374}
1375
1376
1377int
1378PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1379{
1380 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1381 Py_ssize_t size;
1382 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1383 "object");
1384 if (!obj) return -1;
1385 size = PyString_GET_SIZE(obj);
1386 if (*end<1)
1387 *end = 1;
1388 if (*end>size)
1389 *end = size;
1390 return 0;
1391 }
1392 return -1;
1393}
1394
1395
1396int
1397PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1398{
1399 return PyUnicodeEncodeError_GetEnd(exc, start);
1400}
1401
1402
1403int
1404PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1405{
1406 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1407}
1408
1409
1410int
1411PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1412{
1413 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1414}
1415
1416
1417int
1418PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1419{
1420 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1421}
1422
1423PyObject *
1424PyUnicodeEncodeError_GetReason(PyObject *exc)
1425{
1426 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1427}
1428
1429
1430PyObject *
1431PyUnicodeDecodeError_GetReason(PyObject *exc)
1432{
1433 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1434}
1435
1436
1437PyObject *
1438PyUnicodeTranslateError_GetReason(PyObject *exc)
1439{
1440 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1441}
1442
1443
1444int
1445PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1446{
1447 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1448}
1449
1450
1451int
1452PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1453{
1454 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1455}
1456
1457
1458int
1459PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1460{
1461 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1462}
1463
1464
Richard Jones7b9558d2006-05-27 12:29:24 +00001465static int
1466UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1467 PyTypeObject *objecttype)
1468{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001469 Py_CLEAR(self->encoding);
1470 Py_CLEAR(self->object);
1471 Py_CLEAR(self->start);
1472 Py_CLEAR(self->end);
1473 Py_CLEAR(self->reason);
1474
Richard Jones7b9558d2006-05-27 12:29:24 +00001475 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1476 &PyString_Type, &self->encoding,
1477 objecttype, &self->object,
1478 &PyInt_Type, &self->start,
1479 &PyInt_Type, &self->end,
1480 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001481 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001482 self->reason = NULL;
1483 return -1;
1484 }
1485
1486 Py_INCREF(self->encoding);
1487 Py_INCREF(self->object);
1488 Py_INCREF(self->start);
1489 Py_INCREF(self->end);
1490 Py_INCREF(self->reason);
1491
1492 return 0;
1493}
1494
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001495static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001496UnicodeError_clear(PyUnicodeErrorObject *self)
1497{
1498 Py_CLEAR(self->encoding);
1499 Py_CLEAR(self->object);
1500 Py_CLEAR(self->start);
1501 Py_CLEAR(self->end);
1502 Py_CLEAR(self->reason);
1503 return BaseException_clear((PyBaseExceptionObject *)self);
1504}
1505
1506static void
1507UnicodeError_dealloc(PyUnicodeErrorObject *self)
1508{
1509 UnicodeError_clear(self);
1510 self->ob_type->tp_free((PyObject *)self);
1511}
1512
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001513static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001514UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1515{
1516 Py_VISIT(self->encoding);
1517 Py_VISIT(self->object);
1518 Py_VISIT(self->start);
1519 Py_VISIT(self->end);
1520 Py_VISIT(self->reason);
1521 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1522}
1523
1524static PyMemberDef UnicodeError_members[] = {
1525 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1526 PyDoc_STR("exception message")},
1527 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1528 PyDoc_STR("exception encoding")},
1529 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1530 PyDoc_STR("exception object")},
1531 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1532 PyDoc_STR("exception start")},
1533 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1534 PyDoc_STR("exception end")},
1535 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1536 PyDoc_STR("exception reason")},
1537 {NULL} /* Sentinel */
1538};
1539
1540
1541/*
1542 * UnicodeEncodeError extends UnicodeError
1543 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001544
1545static int
1546UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1547{
1548 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1549 return -1;
1550 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1551 kwds, &PyUnicode_Type);
1552}
1553
1554static PyObject *
1555UnicodeEncodeError_str(PyObject *self)
1556{
1557 Py_ssize_t start;
1558 Py_ssize_t end;
1559
1560 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001561 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001562
1563 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001564 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001565
1566 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001567 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1568 char badchar_str[20];
1569 if (badchar <= 0xff)
1570 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1571 else if (badchar <= 0xffff)
1572 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1573 else
1574 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1575 return PyString_FromFormat(
1576 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1577 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1578 badchar_str,
1579 start,
1580 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1581 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001582 }
1583 return PyString_FromFormat(
1584 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1585 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1586 start,
1587 (end-1),
1588 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1589 );
1590}
1591
1592static PyTypeObject _PyExc_UnicodeEncodeError = {
1593 PyObject_HEAD_INIT(NULL)
1594 0,
1595 "UnicodeEncodeError",
1596 sizeof(PyUnicodeErrorObject), 0,
1597 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1598 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1599 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1600 PyDoc_STR("Unicode encoding error."), (traverseproc)BaseException_traverse,
1601 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1602 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001603 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001604};
1605PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1606
1607PyObject *
1608PyUnicodeEncodeError_Create(
1609 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1610 Py_ssize_t start, Py_ssize_t end, const char *reason)
1611{
1612 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001613 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001614}
1615
1616
1617/*
1618 * UnicodeDecodeError extends UnicodeError
1619 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001620
1621static int
1622UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1623{
1624 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1625 return -1;
1626 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1627 kwds, &PyString_Type);
1628}
1629
1630static PyObject *
1631UnicodeDecodeError_str(PyObject *self)
1632{
1633 Py_ssize_t start;
1634 Py_ssize_t end;
1635
1636 if (PyUnicodeDecodeError_GetStart(self, &start))
1637 return NULL;
1638
1639 if (PyUnicodeDecodeError_GetEnd(self, &end))
1640 return NULL;
1641
1642 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001643 /* FromFormat does not support %02x, so format that separately */
1644 char byte[4];
1645 PyOS_snprintf(byte, sizeof(byte), "%02x",
1646 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1647 return PyString_FromFormat(
1648 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1649 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1650 byte,
1651 start,
1652 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1653 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001654 }
1655 return PyString_FromFormat(
1656 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1657 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1658 start,
1659 (end-1),
1660 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1661 );
1662}
1663
1664static PyTypeObject _PyExc_UnicodeDecodeError = {
1665 PyObject_HEAD_INIT(NULL)
1666 0,
1667 EXC_MODULE_NAME "UnicodeDecodeError",
1668 sizeof(PyUnicodeErrorObject), 0,
1669 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1670 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1671 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1672 PyDoc_STR("Unicode decoding error."), (traverseproc)BaseException_traverse,
1673 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1674 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001675 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001676};
1677PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1678
1679PyObject *
1680PyUnicodeDecodeError_Create(
1681 const char *encoding, const char *object, Py_ssize_t length,
1682 Py_ssize_t start, Py_ssize_t end, const char *reason)
1683{
1684 assert(length < INT_MAX);
1685 assert(start < INT_MAX);
1686 assert(end < INT_MAX);
1687 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001688 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001689}
1690
1691
1692/*
1693 * UnicodeTranslateError extends UnicodeError
1694 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001695
1696static int
1697UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1698 PyObject *kwds)
1699{
1700 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1701 return -1;
1702
1703 Py_CLEAR(self->object);
1704 Py_CLEAR(self->start);
1705 Py_CLEAR(self->end);
1706 Py_CLEAR(self->reason);
1707
1708 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1709 &PyUnicode_Type, &self->object,
1710 &PyInt_Type, &self->start,
1711 &PyInt_Type, &self->end,
1712 &PyString_Type, &self->reason)) {
1713 self->object = self->start = self->end = self->reason = NULL;
1714 return -1;
1715 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001716
Richard Jones7b9558d2006-05-27 12:29:24 +00001717 Py_INCREF(self->object);
1718 Py_INCREF(self->start);
1719 Py_INCREF(self->end);
1720 Py_INCREF(self->reason);
1721
1722 return 0;
1723}
1724
1725
1726static PyObject *
1727UnicodeTranslateError_str(PyObject *self)
1728{
1729 Py_ssize_t start;
1730 Py_ssize_t end;
1731
1732 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001733 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001734
1735 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001736 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001737
1738 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001739 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1740 char badchar_str[20];
1741 if (badchar <= 0xff)
1742 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1743 else if (badchar <= 0xffff)
1744 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1745 else
1746 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1747 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001748 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001749 badchar_str,
1750 start,
1751 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1752 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001753 }
1754 return PyString_FromFormat(
1755 "can't translate characters in position %zd-%zd: %.400s",
1756 start,
1757 (end-1),
1758 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1759 );
1760}
1761
1762static PyTypeObject _PyExc_UnicodeTranslateError = {
1763 PyObject_HEAD_INIT(NULL)
1764 0,
1765 EXC_MODULE_NAME "UnicodeTranslateError",
1766 sizeof(PyUnicodeErrorObject), 0,
1767 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1768 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1769 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1770 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1771 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1772 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001773 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001774};
1775PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1776
1777PyObject *
1778PyUnicodeTranslateError_Create(
1779 const Py_UNICODE *object, Py_ssize_t length,
1780 Py_ssize_t start, Py_ssize_t end, const char *reason)
1781{
1782 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001783 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001784}
1785#endif
1786
1787
1788/*
1789 * AssertionError extends StandardError
1790 */
1791SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001792 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001793
1794
1795/*
1796 * ArithmeticError extends StandardError
1797 */
1798SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001799 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001800
1801
1802/*
1803 * FloatingPointError extends ArithmeticError
1804 */
1805SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001806 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001807
1808
1809/*
1810 * OverflowError extends ArithmeticError
1811 */
1812SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001813 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001814
1815
1816/*
1817 * ZeroDivisionError extends ArithmeticError
1818 */
1819SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001820 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001821
1822
1823/*
1824 * SystemError extends StandardError
1825 */
1826SimpleExtendsException(PyExc_StandardError, SystemError,
1827 "Internal error in the Python interpreter.\n"
1828 "\n"
1829 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001830 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001831
1832
1833/*
1834 * ReferenceError extends StandardError
1835 */
1836SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001837 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001838
1839
1840/*
1841 * MemoryError extends StandardError
1842 */
Richard Jones2d555b32006-05-27 16:15:11 +00001843SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001844
1845
1846/* Warning category docstrings */
1847
1848/*
1849 * Warning extends Exception
1850 */
1851SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001852 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001853
1854
1855/*
1856 * UserWarning extends Warning
1857 */
1858SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001859 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001860
1861
1862/*
1863 * DeprecationWarning extends Warning
1864 */
1865SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001866 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001867
1868
1869/*
1870 * PendingDeprecationWarning extends Warning
1871 */
1872SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1873 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001874 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001875
1876
1877/*
1878 * SyntaxWarning extends Warning
1879 */
1880SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001881 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001882
1883
1884/*
1885 * RuntimeWarning extends Warning
1886 */
1887SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001888 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001889
1890
1891/*
1892 * FutureWarning extends Warning
1893 */
1894SimpleExtendsException(PyExc_Warning, FutureWarning,
1895 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001896 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001897
1898
1899/*
1900 * ImportWarning extends Warning
1901 */
1902SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001903 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001904
1905
1906/* Pre-computed MemoryError instance. Best to create this as early as
1907 * possible and not wait until a MemoryError is actually raised!
1908 */
1909PyObject *PyExc_MemoryErrorInst=NULL;
1910
1911/* module global functions */
1912static PyMethodDef functions[] = {
1913 /* Sentinel */
1914 {NULL, NULL}
1915};
1916
1917#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1918 Py_FatalError("exceptions bootstrapping error.");
1919
1920#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1921 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1922 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1923 Py_FatalError("Module dictionary insertion problem.");
1924
1925PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001926_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001927{
1928 PyObject *m, *bltinmod, *bdict;
1929
1930 PRE_INIT(BaseException)
1931 PRE_INIT(Exception)
1932 PRE_INIT(StandardError)
1933 PRE_INIT(TypeError)
1934 PRE_INIT(StopIteration)
1935 PRE_INIT(GeneratorExit)
1936 PRE_INIT(SystemExit)
1937 PRE_INIT(KeyboardInterrupt)
1938 PRE_INIT(ImportError)
1939 PRE_INIT(EnvironmentError)
1940 PRE_INIT(IOError)
1941 PRE_INIT(OSError)
1942#ifdef MS_WINDOWS
1943 PRE_INIT(WindowsError)
1944#endif
1945#ifdef __VMS
1946 PRE_INIT(VMSError)
1947#endif
1948 PRE_INIT(EOFError)
1949 PRE_INIT(RuntimeError)
1950 PRE_INIT(NotImplementedError)
1951 PRE_INIT(NameError)
1952 PRE_INIT(UnboundLocalError)
1953 PRE_INIT(AttributeError)
1954 PRE_INIT(SyntaxError)
1955 PRE_INIT(IndentationError)
1956 PRE_INIT(TabError)
1957 PRE_INIT(LookupError)
1958 PRE_INIT(IndexError)
1959 PRE_INIT(KeyError)
1960 PRE_INIT(ValueError)
1961 PRE_INIT(UnicodeError)
1962#ifdef Py_USING_UNICODE
1963 PRE_INIT(UnicodeEncodeError)
1964 PRE_INIT(UnicodeDecodeError)
1965 PRE_INIT(UnicodeTranslateError)
1966#endif
1967 PRE_INIT(AssertionError)
1968 PRE_INIT(ArithmeticError)
1969 PRE_INIT(FloatingPointError)
1970 PRE_INIT(OverflowError)
1971 PRE_INIT(ZeroDivisionError)
1972 PRE_INIT(SystemError)
1973 PRE_INIT(ReferenceError)
1974 PRE_INIT(MemoryError)
1975 PRE_INIT(Warning)
1976 PRE_INIT(UserWarning)
1977 PRE_INIT(DeprecationWarning)
1978 PRE_INIT(PendingDeprecationWarning)
1979 PRE_INIT(SyntaxWarning)
1980 PRE_INIT(RuntimeWarning)
1981 PRE_INIT(FutureWarning)
1982 PRE_INIT(ImportWarning)
1983
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00001984 m = Py_InitModule4("exceptions", functions, exceptions_doc,
1985 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00001986 if (m == NULL) return;
1987
1988 bltinmod = PyImport_ImportModule("__builtin__");
1989 if (bltinmod == NULL)
1990 Py_FatalError("exceptions bootstrapping error.");
1991 bdict = PyModule_GetDict(bltinmod);
1992 if (bdict == NULL)
1993 Py_FatalError("exceptions bootstrapping error.");
1994
1995 POST_INIT(BaseException)
1996 POST_INIT(Exception)
1997 POST_INIT(StandardError)
1998 POST_INIT(TypeError)
1999 POST_INIT(StopIteration)
2000 POST_INIT(GeneratorExit)
2001 POST_INIT(SystemExit)
2002 POST_INIT(KeyboardInterrupt)
2003 POST_INIT(ImportError)
2004 POST_INIT(EnvironmentError)
2005 POST_INIT(IOError)
2006 POST_INIT(OSError)
2007#ifdef MS_WINDOWS
2008 POST_INIT(WindowsError)
2009#endif
2010#ifdef __VMS
2011 POST_INIT(VMSError)
2012#endif
2013 POST_INIT(EOFError)
2014 POST_INIT(RuntimeError)
2015 POST_INIT(NotImplementedError)
2016 POST_INIT(NameError)
2017 POST_INIT(UnboundLocalError)
2018 POST_INIT(AttributeError)
2019 POST_INIT(SyntaxError)
2020 POST_INIT(IndentationError)
2021 POST_INIT(TabError)
2022 POST_INIT(LookupError)
2023 POST_INIT(IndexError)
2024 POST_INIT(KeyError)
2025 POST_INIT(ValueError)
2026 POST_INIT(UnicodeError)
2027#ifdef Py_USING_UNICODE
2028 POST_INIT(UnicodeEncodeError)
2029 POST_INIT(UnicodeDecodeError)
2030 POST_INIT(UnicodeTranslateError)
2031#endif
2032 POST_INIT(AssertionError)
2033 POST_INIT(ArithmeticError)
2034 POST_INIT(FloatingPointError)
2035 POST_INIT(OverflowError)
2036 POST_INIT(ZeroDivisionError)
2037 POST_INIT(SystemError)
2038 POST_INIT(ReferenceError)
2039 POST_INIT(MemoryError)
2040 POST_INIT(Warning)
2041 POST_INIT(UserWarning)
2042 POST_INIT(DeprecationWarning)
2043 POST_INIT(PendingDeprecationWarning)
2044 POST_INIT(SyntaxWarning)
2045 POST_INIT(RuntimeWarning)
2046 POST_INIT(FutureWarning)
2047 POST_INIT(ImportWarning)
2048
2049 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2050 if (!PyExc_MemoryErrorInst)
2051 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2052
2053 Py_DECREF(bltinmod);
2054}
2055
2056void
2057_PyExc_Fini(void)
2058{
2059 Py_XDECREF(PyExc_MemoryErrorInst);
2060 PyExc_MemoryErrorInst = NULL;
2061}