blob: 0cd819c5a1559396d9aa43ce64615d22578fffbc [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);
13#define EXC_MODULE_NAME "exceptions."
14
15/* NOTE: If the exception class hierarchy changes, don't forget to update
16 * Lib/test/exception_hierarchy.txt
17 */
18
19PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
20\n\
21Exceptions found here are defined both in the exceptions module and the\n\
22built-in namespace. It is recommended that user-defined exceptions\n\
23inherit from Exception. See the documentation for the exception\n\
24inheritance hierarchy.\n\
25");
26
27/*
28 * BaseException
29 */
30static PyObject *
31BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
32{
33 PyBaseExceptionObject *self;
34
35 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
36 /* the dict is created on the fly in PyObject_GenericSetAttr */
37 self->message = self->dict = NULL;
38
39 self->args = PyTuple_New(0);
40 if (!self->args) {
41 Py_DECREF(self);
42 return NULL;
43 }
44
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000045 self->message = PyString_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000046 if (!self->message) {
47 Py_DECREF(self);
48 return NULL;
49 }
50
51 return (PyObject *)self;
52}
53
54static int
55BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
56{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000057 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
58 return -1;
59
Thomas Wouters477c8d52006-05-27 19:21:47 +000060 Py_DECREF(self->args);
61 self->args = args;
62 Py_INCREF(self->args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000065 Py_CLEAR(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000066 self->message = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000067 Py_INCREF(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000068 }
69 return 0;
70}
71
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000072static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000073BaseException_clear(PyBaseExceptionObject *self)
74{
75 Py_CLEAR(self->dict);
76 Py_CLEAR(self->args);
77 Py_CLEAR(self->message);
78 return 0;
79}
80
81static void
82BaseException_dealloc(PyBaseExceptionObject *self)
83{
Thomas Wouters89f507f2006-12-13 04:49:30 +000084 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000085 BaseException_clear(self);
86 self->ob_type->tp_free((PyObject *)self);
87}
88
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000089static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000090BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
91{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000092 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000093 Py_VISIT(self->args);
94 Py_VISIT(self->message);
95 return 0;
96}
97
98static PyObject *
99BaseException_str(PyBaseExceptionObject *self)
100{
101 PyObject *out;
102
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000103 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000104 case 0:
105 out = PyString_FromString("");
106 break;
107 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000108 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110 default:
111 out = PyObject_Str(self->args);
112 break;
113 }
114
115 return out;
116}
117
118static PyObject *
119BaseException_repr(PyBaseExceptionObject *self)
120{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000121 PyObject *repr_suffix;
122 PyObject *repr;
123 char *name;
124 char *dot;
125
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000126 repr_suffix = PyObject_Repr(self->args);
127 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000128 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000129
130 name = (char *)self->ob_type->tp_name;
131 dot = strrchr(name, '.');
132 if (dot != NULL) name = dot+1;
133
134 repr = PyString_FromString(name);
135 if (!repr) {
136 Py_DECREF(repr_suffix);
137 return NULL;
138 }
139
140 PyString_ConcatAndDel(&repr, repr_suffix);
141 return repr;
142}
143
144/* Pickling support */
145static PyObject *
146BaseException_reduce(PyBaseExceptionObject *self)
147{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000148 if (self->args && self->dict)
149 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
150 else
151 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000152}
153
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000154/*
155 * Needed for backward compatibility, since exceptions used to store
156 * all their attributes in the __dict__. Code is taken from cPickle's
157 * load_build function.
158 */
159static PyObject *
160BaseException_setstate(PyObject *self, PyObject *state)
161{
162 PyObject *d_key, *d_value;
163 Py_ssize_t i = 0;
164
165 if (state != Py_None) {
166 if (!PyDict_Check(state)) {
167 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
168 return NULL;
169 }
170 while (PyDict_Next(state, &i, &d_key, &d_value)) {
171 if (PyObject_SetAttr(self, d_key, d_value) < 0)
172 return NULL;
173 }
174 }
175 Py_RETURN_NONE;
176}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000177
Thomas Wouters477c8d52006-05-27 19:21:47 +0000178
179static PyMethodDef BaseException_methods[] = {
180 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000181 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000182 {NULL, NULL, 0, NULL},
183};
184
185
186
187static PyObject *
188BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
189{
190 return PySequence_GetItem(self->args, index);
191}
192
Thomas Wouters89f507f2006-12-13 04:49:30 +0000193static PyObject *
194BaseException_getslice(PyBaseExceptionObject *self,
195 Py_ssize_t start, Py_ssize_t stop)
196{
197 return PySequence_GetSlice(self->args, start, stop);
198}
199
Thomas Wouters477c8d52006-05-27 19:21:47 +0000200static PySequenceMethods BaseException_as_sequence = {
201 0, /* sq_length; */
202 0, /* sq_concat; */
203 0, /* sq_repeat; */
204 (ssizeargfunc)BaseException_getitem, /* sq_item; */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000205 (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000206 0, /* sq_ass_item; */
207 0, /* sq_ass_slice; */
208 0, /* sq_contains; */
209 0, /* sq_inplace_concat; */
210 0 /* sq_inplace_repeat; */
211};
212
213static PyMemberDef BaseException_members[] = {
214 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
215 PyDoc_STR("exception message")},
216 {NULL} /* Sentinel */
217};
218
219
220static PyObject *
221BaseException_get_dict(PyBaseExceptionObject *self)
222{
223 if (self->dict == NULL) {
224 self->dict = PyDict_New();
225 if (!self->dict)
226 return NULL;
227 }
228 Py_INCREF(self->dict);
229 return self->dict;
230}
231
232static int
233BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
234{
235 if (val == NULL) {
236 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
237 return -1;
238 }
239 if (!PyDict_Check(val)) {
240 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
241 return -1;
242 }
243 Py_CLEAR(self->dict);
244 Py_INCREF(val);
245 self->dict = val;
246 return 0;
247}
248
249static PyObject *
250BaseException_get_args(PyBaseExceptionObject *self)
251{
252 if (self->args == NULL) {
253 Py_INCREF(Py_None);
254 return Py_None;
255 }
256 Py_INCREF(self->args);
257 return self->args;
258}
259
260static int
261BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
262{
263 PyObject *seq;
264 if (val == NULL) {
265 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
266 return -1;
267 }
268 seq = PySequence_Tuple(val);
269 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000270 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000271 self->args = seq;
272 return 0;
273}
274
275static PyGetSetDef BaseException_getset[] = {
276 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
277 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
278 {NULL},
279};
280
281
282static PyTypeObject _PyExc_BaseException = {
283 PyObject_HEAD_INIT(NULL)
284 0, /*ob_size*/
285 EXC_MODULE_NAME "BaseException", /*tp_name*/
286 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
287 0, /*tp_itemsize*/
288 (destructor)BaseException_dealloc, /*tp_dealloc*/
289 0, /*tp_print*/
290 0, /*tp_getattr*/
291 0, /*tp_setattr*/
292 0, /* tp_compare; */
293 (reprfunc)BaseException_repr, /*tp_repr*/
294 0, /*tp_as_number*/
295 &BaseException_as_sequence, /*tp_as_sequence*/
296 0, /*tp_as_mapping*/
297 0, /*tp_hash */
298 0, /*tp_call*/
299 (reprfunc)BaseException_str, /*tp_str*/
300 PyObject_GenericGetAttr, /*tp_getattro*/
301 PyObject_GenericSetAttr, /*tp_setattro*/
302 0, /*tp_as_buffer*/
303 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
304 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
305 (traverseproc)BaseException_traverse, /* tp_traverse */
306 (inquiry)BaseException_clear, /* tp_clear */
307 0, /* tp_richcompare */
308 0, /* tp_weaklistoffset */
309 0, /* tp_iter */
310 0, /* tp_iternext */
311 BaseException_methods, /* tp_methods */
312 BaseException_members, /* tp_members */
313 BaseException_getset, /* tp_getset */
314 0, /* tp_base */
315 0, /* tp_dict */
316 0, /* tp_descr_get */
317 0, /* tp_descr_set */
318 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
319 (initproc)BaseException_init, /* tp_init */
320 0, /* tp_alloc */
321 BaseException_new, /* tp_new */
322};
323/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
324from the previous implmentation and also allowing Python objects to be used
325in the API */
326PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
327
328/* note these macros omit the last semicolon so the macro invocation may
329 * include it and not look strange.
330 */
331#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
332static PyTypeObject _PyExc_ ## EXCNAME = { \
333 PyObject_HEAD_INIT(NULL) \
334 0, \
335 EXC_MODULE_NAME # EXCNAME, \
336 sizeof(PyBaseExceptionObject), \
337 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
338 0, 0, 0, 0, 0, 0, 0, \
339 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
340 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
341 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
342 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
343 (initproc)BaseException_init, 0, BaseException_new,\
344}; \
345PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
346
347#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
348static PyTypeObject _PyExc_ ## EXCNAME = { \
349 PyObject_HEAD_INIT(NULL) \
350 0, \
351 EXC_MODULE_NAME # EXCNAME, \
352 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000353 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000354 0, 0, 0, 0, 0, \
355 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000356 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
357 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000358 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000359 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000360}; \
361PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
362
363#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
364static PyTypeObject _PyExc_ ## EXCNAME = { \
365 PyObject_HEAD_INIT(NULL) \
366 0, \
367 EXC_MODULE_NAME # EXCNAME, \
368 sizeof(Py ## EXCSTORE ## Object), 0, \
369 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
370 (reprfunc)EXCSTR, 0, 0, 0, \
371 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
372 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
373 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
374 EXCMEMBERS, 0, &_ ## EXCBASE, \
375 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000376 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000377}; \
378PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
379
380
381/*
382 * Exception extends BaseException
383 */
384SimpleExtendsException(PyExc_BaseException, Exception,
385 "Common base class for all non-exit exceptions.");
386
387
388/*
389 * StandardError extends Exception
390 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000391SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000392 "Base class for all standard Python exceptions that do not represent\n"
393 "interpreter exiting.");
394
395
396/*
397 * TypeError extends StandardError
398 */
399SimpleExtendsException(PyExc_StandardError, TypeError,
400 "Inappropriate argument type.");
401
402
403/*
404 * StopIteration extends Exception
405 */
406SimpleExtendsException(PyExc_Exception, StopIteration,
407 "Signal the end from iterator.next().");
408
409
410/*
411 * GeneratorExit extends Exception
412 */
413SimpleExtendsException(PyExc_Exception, GeneratorExit,
414 "Request that a generator exit.");
415
416
417/*
418 * SystemExit extends BaseException
419 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000420
421static int
422SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
423{
424 Py_ssize_t size = PyTuple_GET_SIZE(args);
425
426 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
427 return -1;
428
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000429 if (size == 0)
430 return 0;
431 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432 if (size == 1)
433 self->code = PyTuple_GET_ITEM(args, 0);
434 else if (size > 1)
435 self->code = args;
436 Py_INCREF(self->code);
437 return 0;
438}
439
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000440static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000441SystemExit_clear(PySystemExitObject *self)
442{
443 Py_CLEAR(self->code);
444 return BaseException_clear((PyBaseExceptionObject *)self);
445}
446
447static void
448SystemExit_dealloc(PySystemExitObject *self)
449{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000450 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000451 SystemExit_clear(self);
452 self->ob_type->tp_free((PyObject *)self);
453}
454
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000455static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000456SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
457{
458 Py_VISIT(self->code);
459 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
460}
461
462static PyMemberDef SystemExit_members[] = {
463 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
464 PyDoc_STR("exception message")},
465 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
466 PyDoc_STR("exception code")},
467 {NULL} /* Sentinel */
468};
469
470ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
471 SystemExit_dealloc, 0, SystemExit_members, 0,
472 "Request to exit from the interpreter.");
473
474/*
475 * KeyboardInterrupt extends BaseException
476 */
477SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
478 "Program interrupted by user.");
479
480
481/*
482 * ImportError extends StandardError
483 */
484SimpleExtendsException(PyExc_StandardError, ImportError,
485 "Import can't find module, or can't find name in module.");
486
487
488/*
489 * EnvironmentError extends StandardError
490 */
491
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492/* Where a function has a single filename, such as open() or some
493 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
494 * called, giving a third argument which is the filename. But, so
495 * that old code using in-place unpacking doesn't break, e.g.:
496 *
497 * except IOError, (errno, strerror):
498 *
499 * we hack args so that it only contains two items. This also
500 * means we need our own __str__() which prints out the filename
501 * when it was supplied.
502 */
503static int
504EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
505 PyObject *kwds)
506{
507 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
508 PyObject *subslice = NULL;
509
510 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
511 return -1;
512
Thomas Wouters89f507f2006-12-13 04:49:30 +0000513 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000514 return 0;
515 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000516
517 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518 &myerrno, &strerror, &filename)) {
519 return -1;
520 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000521 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522 self->myerrno = myerrno;
523 Py_INCREF(self->myerrno);
524
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000525 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 self->strerror = strerror;
527 Py_INCREF(self->strerror);
528
529 /* self->filename will remain Py_None otherwise */
530 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000531 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000532 self->filename = filename;
533 Py_INCREF(self->filename);
534
535 subslice = PyTuple_GetSlice(args, 0, 2);
536 if (!subslice)
537 return -1;
538
539 Py_DECREF(self->args); /* replacing args */
540 self->args = subslice;
541 }
542 return 0;
543}
544
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000545static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000546EnvironmentError_clear(PyEnvironmentErrorObject *self)
547{
548 Py_CLEAR(self->myerrno);
549 Py_CLEAR(self->strerror);
550 Py_CLEAR(self->filename);
551 return BaseException_clear((PyBaseExceptionObject *)self);
552}
553
554static void
555EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
556{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000557 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000558 EnvironmentError_clear(self);
559 self->ob_type->tp_free((PyObject *)self);
560}
561
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000562static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000563EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
564 void *arg)
565{
566 Py_VISIT(self->myerrno);
567 Py_VISIT(self->strerror);
568 Py_VISIT(self->filename);
569 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
570}
571
572static PyObject *
573EnvironmentError_str(PyEnvironmentErrorObject *self)
574{
575 PyObject *rtnval = NULL;
576
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000577 if (self->filename) {
578 PyObject *fmt;
579 PyObject *repr;
580 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000581
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000582 fmt = PyString_FromString("[Errno %s] %s: %s");
583 if (!fmt)
584 return NULL;
585
586 repr = PyObject_Repr(self->filename);
587 if (!repr) {
588 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000589 return NULL;
590 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000591 tuple = PyTuple_New(3);
592 if (!tuple) {
593 Py_DECREF(repr);
594 Py_DECREF(fmt);
595 return NULL;
596 }
597
598 if (self->myerrno) {
599 Py_INCREF(self->myerrno);
600 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
601 }
602 else {
603 Py_INCREF(Py_None);
604 PyTuple_SET_ITEM(tuple, 0, Py_None);
605 }
606 if (self->strerror) {
607 Py_INCREF(self->strerror);
608 PyTuple_SET_ITEM(tuple, 1, self->strerror);
609 }
610 else {
611 Py_INCREF(Py_None);
612 PyTuple_SET_ITEM(tuple, 1, Py_None);
613 }
614
Thomas Wouters477c8d52006-05-27 19:21:47 +0000615 PyTuple_SET_ITEM(tuple, 2, repr);
616
617 rtnval = PyString_Format(fmt, tuple);
618
619 Py_DECREF(fmt);
620 Py_DECREF(tuple);
621 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000622 else if (self->myerrno && self->strerror) {
623 PyObject *fmt;
624 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000626 fmt = PyString_FromString("[Errno %s] %s");
627 if (!fmt)
628 return NULL;
629
630 tuple = PyTuple_New(2);
631 if (!tuple) {
632 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633 return NULL;
634 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000635
636 if (self->myerrno) {
637 Py_INCREF(self->myerrno);
638 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
639 }
640 else {
641 Py_INCREF(Py_None);
642 PyTuple_SET_ITEM(tuple, 0, Py_None);
643 }
644 if (self->strerror) {
645 Py_INCREF(self->strerror);
646 PyTuple_SET_ITEM(tuple, 1, self->strerror);
647 }
648 else {
649 Py_INCREF(Py_None);
650 PyTuple_SET_ITEM(tuple, 1, Py_None);
651 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000652
653 rtnval = PyString_Format(fmt, tuple);
654
655 Py_DECREF(fmt);
656 Py_DECREF(tuple);
657 }
658 else
659 rtnval = BaseException_str((PyBaseExceptionObject *)self);
660
661 return rtnval;
662}
663
664static PyMemberDef EnvironmentError_members[] = {
665 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
666 PyDoc_STR("exception message")},
667 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
668 PyDoc_STR("exception errno")},
669 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
670 PyDoc_STR("exception strerror")},
671 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
672 PyDoc_STR("exception filename")},
673 {NULL} /* Sentinel */
674};
675
676
677static PyObject *
678EnvironmentError_reduce(PyEnvironmentErrorObject *self)
679{
680 PyObject *args = self->args;
681 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000682
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683 /* self->args is only the first two real arguments if there was a
684 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000685 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686 args = PyTuple_New(3);
687 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000688
689 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000690 Py_INCREF(tmp);
691 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000692
693 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694 Py_INCREF(tmp);
695 PyTuple_SET_ITEM(args, 1, tmp);
696
697 Py_INCREF(self->filename);
698 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000699 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000701
702 if (self->dict)
703 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
704 else
705 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000706 Py_DECREF(args);
707 return res;
708}
709
710
711static PyMethodDef EnvironmentError_methods[] = {
712 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
713 {NULL}
714};
715
716ComplexExtendsException(PyExc_StandardError, EnvironmentError,
717 EnvironmentError, EnvironmentError_dealloc,
718 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000719 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000720 "Base class for I/O related errors.");
721
722
723/*
724 * IOError extends EnvironmentError
725 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000726MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727 EnvironmentError, "I/O operation failed.");
728
729
730/*
731 * OSError extends EnvironmentError
732 */
733MiddlingExtendsException(PyExc_EnvironmentError, OSError,
734 EnvironmentError, "OS system call failed.");
735
736
737/*
738 * WindowsError extends OSError
739 */
740#ifdef MS_WINDOWS
741#include "errmap.h"
742
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000743static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744WindowsError_clear(PyWindowsErrorObject *self)
745{
746 Py_CLEAR(self->myerrno);
747 Py_CLEAR(self->strerror);
748 Py_CLEAR(self->filename);
749 Py_CLEAR(self->winerror);
750 return BaseException_clear((PyBaseExceptionObject *)self);
751}
752
753static void
754WindowsError_dealloc(PyWindowsErrorObject *self)
755{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000756 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000757 WindowsError_clear(self);
758 self->ob_type->tp_free((PyObject *)self);
759}
760
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000761static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000762WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
763{
764 Py_VISIT(self->myerrno);
765 Py_VISIT(self->strerror);
766 Py_VISIT(self->filename);
767 Py_VISIT(self->winerror);
768 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
769}
770
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771static int
772WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
773{
774 PyObject *o_errcode = NULL;
775 long errcode;
776 long posix_errno;
777
778 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
779 == -1)
780 return -1;
781
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000782 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000783 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784
785 /* Set errno to the POSIX errno, and winerror to the Win32
786 error code. */
787 errcode = PyInt_AsLong(self->myerrno);
788 if (errcode == -1 && PyErr_Occurred())
789 return -1;
790 posix_errno = winerror_to_errno(errcode);
791
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000792 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793 self->winerror = self->myerrno;
794
795 o_errcode = PyInt_FromLong(posix_errno);
796 if (!o_errcode)
797 return -1;
798
799 self->myerrno = o_errcode;
800
801 return 0;
802}
803
804
805static PyObject *
806WindowsError_str(PyWindowsErrorObject *self)
807{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808 PyObject *rtnval = NULL;
809
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000810 if (self->filename) {
811 PyObject *fmt;
812 PyObject *repr;
813 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000814
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000815 fmt = PyString_FromString("[Error %s] %s: %s");
816 if (!fmt)
817 return NULL;
818
819 repr = PyObject_Repr(self->filename);
820 if (!repr) {
821 Py_DECREF(fmt);
822 return NULL;
823 }
824 tuple = PyTuple_New(3);
825 if (!tuple) {
826 Py_DECREF(repr);
827 Py_DECREF(fmt);
828 return NULL;
829 }
830
Thomas Wouters89f507f2006-12-13 04:49:30 +0000831 if (self->winerror) {
832 Py_INCREF(self->winerror);
833 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000834 }
835 else {
836 Py_INCREF(Py_None);
837 PyTuple_SET_ITEM(tuple, 0, Py_None);
838 }
839 if (self->strerror) {
840 Py_INCREF(self->strerror);
841 PyTuple_SET_ITEM(tuple, 1, self->strerror);
842 }
843 else {
844 Py_INCREF(Py_None);
845 PyTuple_SET_ITEM(tuple, 1, Py_None);
846 }
847
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000848 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000849
850 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000851
852 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000853 Py_DECREF(tuple);
854 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000855 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000856 PyObject *fmt;
857 PyObject *tuple;
858
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859 fmt = PyString_FromString("[Error %s] %s");
860 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000861 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000863 tuple = PyTuple_New(2);
864 if (!tuple) {
865 Py_DECREF(fmt);
866 return NULL;
867 }
868
Thomas Wouters89f507f2006-12-13 04:49:30 +0000869 if (self->winerror) {
870 Py_INCREF(self->winerror);
871 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000872 }
873 else {
874 Py_INCREF(Py_None);
875 PyTuple_SET_ITEM(tuple, 0, Py_None);
876 }
877 if (self->strerror) {
878 Py_INCREF(self->strerror);
879 PyTuple_SET_ITEM(tuple, 1, self->strerror);
880 }
881 else {
882 Py_INCREF(Py_None);
883 PyTuple_SET_ITEM(tuple, 1, Py_None);
884 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000885
886 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000887
888 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889 Py_DECREF(tuple);
890 }
891 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000892 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000893
Thomas Wouters477c8d52006-05-27 19:21:47 +0000894 return rtnval;
895}
896
897static PyMemberDef WindowsError_members[] = {
898 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
899 PyDoc_STR("exception message")},
900 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
901 PyDoc_STR("POSIX exception code")},
902 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
903 PyDoc_STR("exception strerror")},
904 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
905 PyDoc_STR("exception filename")},
906 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
907 PyDoc_STR("Win32 exception code")},
908 {NULL} /* Sentinel */
909};
910
911ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
912 WindowsError_dealloc, 0, WindowsError_members,
913 WindowsError_str, "MS-Windows OS system call failed.");
914
915#endif /* MS_WINDOWS */
916
917
918/*
919 * VMSError extends OSError (I think)
920 */
921#ifdef __VMS
922MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
923 "OpenVMS OS system call failed.");
924#endif
925
926
927/*
928 * EOFError extends StandardError
929 */
930SimpleExtendsException(PyExc_StandardError, EOFError,
931 "Read beyond end of file.");
932
933
934/*
935 * RuntimeError extends StandardError
936 */
937SimpleExtendsException(PyExc_StandardError, RuntimeError,
938 "Unspecified run-time error.");
939
940
941/*
942 * NotImplementedError extends RuntimeError
943 */
944SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
945 "Method or function hasn't been implemented yet.");
946
947/*
948 * NameError extends StandardError
949 */
950SimpleExtendsException(PyExc_StandardError, NameError,
951 "Name not found globally.");
952
953/*
954 * UnboundLocalError extends NameError
955 */
956SimpleExtendsException(PyExc_NameError, UnboundLocalError,
957 "Local name referenced but not bound to a value.");
958
959/*
960 * AttributeError extends StandardError
961 */
962SimpleExtendsException(PyExc_StandardError, AttributeError,
963 "Attribute not found.");
964
965
966/*
967 * SyntaxError extends StandardError
968 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000969
970static int
971SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
972{
973 PyObject *info = NULL;
974 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
975
976 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
977 return -1;
978
979 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000980 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981 self->msg = PyTuple_GET_ITEM(args, 0);
982 Py_INCREF(self->msg);
983 }
984 if (lenargs == 2) {
985 info = PyTuple_GET_ITEM(args, 1);
986 info = PySequence_Tuple(info);
987 if (!info) return -1;
988
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000989 if (PyTuple_GET_SIZE(info) != 4) {
990 /* not a very good error message, but it's what Python 2.4 gives */
991 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
992 Py_DECREF(info);
993 return -1;
994 }
995
996 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997 self->filename = PyTuple_GET_ITEM(info, 0);
998 Py_INCREF(self->filename);
999
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001000 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001 self->lineno = PyTuple_GET_ITEM(info, 1);
1002 Py_INCREF(self->lineno);
1003
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001004 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005 self->offset = PyTuple_GET_ITEM(info, 2);
1006 Py_INCREF(self->offset);
1007
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001008 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001009 self->text = PyTuple_GET_ITEM(info, 3);
1010 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001011
1012 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001013 }
1014 return 0;
1015}
1016
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001017static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001018SyntaxError_clear(PySyntaxErrorObject *self)
1019{
1020 Py_CLEAR(self->msg);
1021 Py_CLEAR(self->filename);
1022 Py_CLEAR(self->lineno);
1023 Py_CLEAR(self->offset);
1024 Py_CLEAR(self->text);
1025 Py_CLEAR(self->print_file_and_line);
1026 return BaseException_clear((PyBaseExceptionObject *)self);
1027}
1028
1029static void
1030SyntaxError_dealloc(PySyntaxErrorObject *self)
1031{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001032 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001033 SyntaxError_clear(self);
1034 self->ob_type->tp_free((PyObject *)self);
1035}
1036
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001037static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1039{
1040 Py_VISIT(self->msg);
1041 Py_VISIT(self->filename);
1042 Py_VISIT(self->lineno);
1043 Py_VISIT(self->offset);
1044 Py_VISIT(self->text);
1045 Py_VISIT(self->print_file_and_line);
1046 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1047}
1048
1049/* This is called "my_basename" instead of just "basename" to avoid name
1050 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1051 defined, and Python does define that. */
1052static char *
1053my_basename(char *name)
1054{
1055 char *cp = name;
1056 char *result = name;
1057
1058 if (name == NULL)
1059 return "???";
1060 while (*cp != '\0') {
1061 if (*cp == SEP)
1062 result = cp + 1;
1063 ++cp;
1064 }
1065 return result;
1066}
1067
1068
1069static PyObject *
1070SyntaxError_str(PySyntaxErrorObject *self)
1071{
1072 PyObject *str;
1073 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001074 int have_filename = 0;
1075 int have_lineno = 0;
1076 char *buffer = NULL;
1077 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001078
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001079 if (self->msg)
1080 str = PyObject_Str(self->msg);
1081 else
1082 str = PyObject_Str(Py_None);
1083 if (!str) return NULL;
1084 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1085 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086
1087 /* XXX -- do all the additional formatting with filename and
1088 lineno here */
1089
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001090 have_filename = (self->filename != NULL) &&
1091 PyString_Check(self->filename);
1092 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001093
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001094 if (!have_filename && !have_lineno)
1095 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001096
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097 bufsize = PyString_GET_SIZE(str) + 64;
1098 if (have_filename)
1099 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001100
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001101 buffer = PyMem_MALLOC(bufsize);
1102 if (buffer == NULL)
1103 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001104
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001105 if (have_filename && have_lineno)
1106 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1107 PyString_AS_STRING(str),
1108 my_basename(PyString_AS_STRING(self->filename)),
1109 PyInt_AsLong(self->lineno));
1110 else if (have_filename)
1111 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1112 PyString_AS_STRING(str),
1113 my_basename(PyString_AS_STRING(self->filename)));
1114 else /* only have_lineno */
1115 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1116 PyString_AS_STRING(str),
1117 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001118
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001119 result = PyString_FromString(buffer);
1120 PyMem_FREE(buffer);
1121
1122 if (result == NULL)
1123 result = str;
1124 else
1125 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126 return result;
1127}
1128
1129static PyMemberDef SyntaxError_members[] = {
1130 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1131 PyDoc_STR("exception message")},
1132 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1133 PyDoc_STR("exception msg")},
1134 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1135 PyDoc_STR("exception filename")},
1136 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1137 PyDoc_STR("exception lineno")},
1138 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1139 PyDoc_STR("exception offset")},
1140 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1141 PyDoc_STR("exception text")},
1142 {"print_file_and_line", T_OBJECT,
1143 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1144 PyDoc_STR("exception print_file_and_line")},
1145 {NULL} /* Sentinel */
1146};
1147
1148ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1149 SyntaxError_dealloc, 0, SyntaxError_members,
1150 SyntaxError_str, "Invalid syntax.");
1151
1152
1153/*
1154 * IndentationError extends SyntaxError
1155 */
1156MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1157 "Improper indentation.");
1158
1159
1160/*
1161 * TabError extends IndentationError
1162 */
1163MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1164 "Improper mixture of spaces and tabs.");
1165
1166
1167/*
1168 * LookupError extends StandardError
1169 */
1170SimpleExtendsException(PyExc_StandardError, LookupError,
1171 "Base class for lookup errors.");
1172
1173
1174/*
1175 * IndexError extends LookupError
1176 */
1177SimpleExtendsException(PyExc_LookupError, IndexError,
1178 "Sequence index out of range.");
1179
1180
1181/*
1182 * KeyError extends LookupError
1183 */
1184static PyObject *
1185KeyError_str(PyBaseExceptionObject *self)
1186{
1187 /* If args is a tuple of exactly one item, apply repr to args[0].
1188 This is done so that e.g. the exception raised by {}[''] prints
1189 KeyError: ''
1190 rather than the confusing
1191 KeyError
1192 alone. The downside is that if KeyError is raised with an explanatory
1193 string, that string will be displayed in quotes. Too bad.
1194 If args is anything else, use the default BaseException__str__().
1195 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001196 if (PyTuple_GET_SIZE(self->args) == 1) {
1197 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001198 }
1199 return BaseException_str(self);
1200}
1201
1202ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1203 0, 0, 0, KeyError_str, "Mapping key not found.");
1204
1205
1206/*
1207 * ValueError extends StandardError
1208 */
1209SimpleExtendsException(PyExc_StandardError, ValueError,
1210 "Inappropriate argument value (of correct type).");
1211
1212/*
1213 * UnicodeError extends ValueError
1214 */
1215
1216SimpleExtendsException(PyExc_ValueError, UnicodeError,
1217 "Unicode related error.");
1218
1219#ifdef Py_USING_UNICODE
1220static int
1221get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1222{
1223 if (!attr) {
1224 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1225 return -1;
1226 }
1227
1228 if (PyInt_Check(attr)) {
1229 *value = PyInt_AS_LONG(attr);
1230 } else if (PyLong_Check(attr)) {
1231 *value = _PyLong_AsSsize_t(attr);
1232 if (*value == -1 && PyErr_Occurred())
1233 return -1;
1234 } else {
1235 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1236 return -1;
1237 }
1238 return 0;
1239}
1240
1241static int
1242set_ssize_t(PyObject **attr, Py_ssize_t value)
1243{
1244 PyObject *obj = PyInt_FromSsize_t(value);
1245 if (!obj)
1246 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001247 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001248 *attr = obj;
1249 return 0;
1250}
1251
1252static PyObject *
1253get_string(PyObject *attr, const char *name)
1254{
1255 if (!attr) {
1256 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1257 return NULL;
1258 }
1259
1260 if (!PyString_Check(attr)) {
1261 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1262 return NULL;
1263 }
1264 Py_INCREF(attr);
1265 return attr;
1266}
1267
1268
1269static int
1270set_string(PyObject **attr, const char *value)
1271{
1272 PyObject *obj = PyString_FromString(value);
1273 if (!obj)
1274 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001275 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001276 *attr = obj;
1277 return 0;
1278}
1279
1280
1281static PyObject *
1282get_unicode(PyObject *attr, const char *name)
1283{
1284 if (!attr) {
1285 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1286 return NULL;
1287 }
1288
1289 if (!PyUnicode_Check(attr)) {
1290 PyErr_Format(PyExc_TypeError,
1291 "%.200s attribute must be unicode", name);
1292 return NULL;
1293 }
1294 Py_INCREF(attr);
1295 return attr;
1296}
1297
1298PyObject *
1299PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1300{
1301 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1302}
1303
1304PyObject *
1305PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1306{
1307 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1308}
1309
1310PyObject *
1311PyUnicodeEncodeError_GetObject(PyObject *exc)
1312{
1313 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1314}
1315
1316PyObject *
1317PyUnicodeDecodeError_GetObject(PyObject *exc)
1318{
1319 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1320}
1321
1322PyObject *
1323PyUnicodeTranslateError_GetObject(PyObject *exc)
1324{
1325 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1326}
1327
1328int
1329PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1330{
1331 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1332 Py_ssize_t size;
1333 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1334 "object");
1335 if (!obj) return -1;
1336 size = PyUnicode_GET_SIZE(obj);
1337 if (*start<0)
1338 *start = 0; /*XXX check for values <0*/
1339 if (*start>=size)
1340 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001341 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001342 return 0;
1343 }
1344 return -1;
1345}
1346
1347
1348int
1349PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1350{
1351 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1352 Py_ssize_t size;
1353 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1354 "object");
1355 if (!obj) return -1;
1356 size = PyString_GET_SIZE(obj);
1357 if (*start<0)
1358 *start = 0;
1359 if (*start>=size)
1360 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001361 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362 return 0;
1363 }
1364 return -1;
1365}
1366
1367
1368int
1369PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1370{
1371 return PyUnicodeEncodeError_GetStart(exc, start);
1372}
1373
1374
1375int
1376PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1377{
1378 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1379}
1380
1381
1382int
1383PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1384{
1385 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1386}
1387
1388
1389int
1390PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1391{
1392 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1393}
1394
1395
1396int
1397PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1398{
1399 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1400 Py_ssize_t size;
1401 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1402 "object");
1403 if (!obj) return -1;
1404 size = PyUnicode_GET_SIZE(obj);
1405 if (*end<1)
1406 *end = 1;
1407 if (*end>size)
1408 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001409 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001410 return 0;
1411 }
1412 return -1;
1413}
1414
1415
1416int
1417PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1418{
1419 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1420 Py_ssize_t size;
1421 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1422 "object");
1423 if (!obj) return -1;
1424 size = PyString_GET_SIZE(obj);
1425 if (*end<1)
1426 *end = 1;
1427 if (*end>size)
1428 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001429 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430 return 0;
1431 }
1432 return -1;
1433}
1434
1435
1436int
1437PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1438{
1439 return PyUnicodeEncodeError_GetEnd(exc, start);
1440}
1441
1442
1443int
1444PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1445{
1446 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1447}
1448
1449
1450int
1451PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1452{
1453 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1454}
1455
1456
1457int
1458PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1459{
1460 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1461}
1462
1463PyObject *
1464PyUnicodeEncodeError_GetReason(PyObject *exc)
1465{
1466 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1467}
1468
1469
1470PyObject *
1471PyUnicodeDecodeError_GetReason(PyObject *exc)
1472{
1473 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1474}
1475
1476
1477PyObject *
1478PyUnicodeTranslateError_GetReason(PyObject *exc)
1479{
1480 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1481}
1482
1483
1484int
1485PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1486{
1487 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1488}
1489
1490
1491int
1492PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1493{
1494 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1495}
1496
1497
1498int
1499PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1500{
1501 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1502}
1503
1504
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505static int
1506UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1507 PyTypeObject *objecttype)
1508{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001509 Py_CLEAR(self->encoding);
1510 Py_CLEAR(self->object);
1511 Py_CLEAR(self->start);
1512 Py_CLEAR(self->end);
1513 Py_CLEAR(self->reason);
1514
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1516 &PyString_Type, &self->encoding,
1517 objecttype, &self->object,
1518 &PyInt_Type, &self->start,
1519 &PyInt_Type, &self->end,
1520 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001521 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001522 self->reason = NULL;
1523 return -1;
1524 }
1525
1526 Py_INCREF(self->encoding);
1527 Py_INCREF(self->object);
1528 Py_INCREF(self->start);
1529 Py_INCREF(self->end);
1530 Py_INCREF(self->reason);
1531
1532 return 0;
1533}
1534
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001535static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536UnicodeError_clear(PyUnicodeErrorObject *self)
1537{
1538 Py_CLEAR(self->encoding);
1539 Py_CLEAR(self->object);
1540 Py_CLEAR(self->start);
1541 Py_CLEAR(self->end);
1542 Py_CLEAR(self->reason);
1543 return BaseException_clear((PyBaseExceptionObject *)self);
1544}
1545
1546static void
1547UnicodeError_dealloc(PyUnicodeErrorObject *self)
1548{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001549 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 UnicodeError_clear(self);
1551 self->ob_type->tp_free((PyObject *)self);
1552}
1553
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001554static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1556{
1557 Py_VISIT(self->encoding);
1558 Py_VISIT(self->object);
1559 Py_VISIT(self->start);
1560 Py_VISIT(self->end);
1561 Py_VISIT(self->reason);
1562 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1563}
1564
1565static PyMemberDef UnicodeError_members[] = {
1566 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1567 PyDoc_STR("exception message")},
1568 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1569 PyDoc_STR("exception encoding")},
1570 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1571 PyDoc_STR("exception object")},
1572 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1573 PyDoc_STR("exception start")},
1574 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1575 PyDoc_STR("exception end")},
1576 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1577 PyDoc_STR("exception reason")},
1578 {NULL} /* Sentinel */
1579};
1580
1581
1582/*
1583 * UnicodeEncodeError extends UnicodeError
1584 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001585
1586static int
1587UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1588{
1589 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1590 return -1;
1591 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1592 kwds, &PyUnicode_Type);
1593}
1594
1595static PyObject *
1596UnicodeEncodeError_str(PyObject *self)
1597{
1598 Py_ssize_t start;
1599 Py_ssize_t end;
1600
1601 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001602 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001603
1604 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001605 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606
1607 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001608 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1609 char badchar_str[20];
1610 if (badchar <= 0xff)
1611 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1612 else if (badchar <= 0xffff)
1613 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1614 else
1615 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1616 return PyString_FromFormat(
1617 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1618 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1619 badchar_str,
1620 start,
1621 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1622 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001623 }
1624 return PyString_FromFormat(
1625 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1626 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1627 start,
1628 (end-1),
1629 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1630 );
1631}
1632
1633static PyTypeObject _PyExc_UnicodeEncodeError = {
1634 PyObject_HEAD_INIT(NULL)
1635 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001636 EXC_MODULE_NAME "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001637 sizeof(PyUnicodeErrorObject), 0,
1638 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1639 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1640 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001641 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1642 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001643 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001644 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645};
1646PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1647
1648PyObject *
1649PyUnicodeEncodeError_Create(
1650 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1651 Py_ssize_t start, Py_ssize_t end, const char *reason)
1652{
1653 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001654 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655}
1656
1657
1658/*
1659 * UnicodeDecodeError extends UnicodeError
1660 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001661
1662static int
1663UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1664{
1665 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1666 return -1;
1667 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1668 kwds, &PyString_Type);
1669}
1670
1671static PyObject *
1672UnicodeDecodeError_str(PyObject *self)
1673{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001674 Py_ssize_t start = 0;
1675 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001676
1677 if (PyUnicodeDecodeError_GetStart(self, &start))
1678 return NULL;
1679
1680 if (PyUnicodeDecodeError_GetEnd(self, &end))
1681 return NULL;
1682
1683 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001684 /* FromFormat does not support %02x, so format that separately */
1685 char byte[4];
1686 PyOS_snprintf(byte, sizeof(byte), "%02x",
1687 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1688 return PyString_FromFormat(
1689 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1690 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1691 byte,
1692 start,
1693 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1694 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695 }
1696 return PyString_FromFormat(
1697 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1698 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1699 start,
1700 (end-1),
1701 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1702 );
1703}
1704
1705static PyTypeObject _PyExc_UnicodeDecodeError = {
1706 PyObject_HEAD_INIT(NULL)
1707 0,
1708 EXC_MODULE_NAME "UnicodeDecodeError",
1709 sizeof(PyUnicodeErrorObject), 0,
1710 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1711 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1712 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001713 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1714 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001716 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717};
1718PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1719
1720PyObject *
1721PyUnicodeDecodeError_Create(
1722 const char *encoding, const char *object, Py_ssize_t length,
1723 Py_ssize_t start, Py_ssize_t end, const char *reason)
1724{
1725 assert(length < INT_MAX);
1726 assert(start < INT_MAX);
1727 assert(end < INT_MAX);
1728 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001729 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730}
1731
1732
1733/*
1734 * UnicodeTranslateError extends UnicodeError
1735 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736
1737static int
1738UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1739 PyObject *kwds)
1740{
1741 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1742 return -1;
1743
1744 Py_CLEAR(self->object);
1745 Py_CLEAR(self->start);
1746 Py_CLEAR(self->end);
1747 Py_CLEAR(self->reason);
1748
1749 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1750 &PyUnicode_Type, &self->object,
1751 &PyInt_Type, &self->start,
1752 &PyInt_Type, &self->end,
1753 &PyString_Type, &self->reason)) {
1754 self->object = self->start = self->end = self->reason = NULL;
1755 return -1;
1756 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001757
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758 Py_INCREF(self->object);
1759 Py_INCREF(self->start);
1760 Py_INCREF(self->end);
1761 Py_INCREF(self->reason);
1762
1763 return 0;
1764}
1765
1766
1767static PyObject *
1768UnicodeTranslateError_str(PyObject *self)
1769{
1770 Py_ssize_t start;
1771 Py_ssize_t end;
1772
1773 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001774 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775
1776 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001777 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778
1779 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001780 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1781 char badchar_str[20];
1782 if (badchar <= 0xff)
1783 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1784 else if (badchar <= 0xffff)
1785 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1786 else
1787 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1788 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001790 badchar_str,
1791 start,
1792 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1793 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794 }
1795 return PyString_FromFormat(
1796 "can't translate characters in position %zd-%zd: %.400s",
1797 start,
1798 (end-1),
1799 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1800 );
1801}
1802
1803static PyTypeObject _PyExc_UnicodeTranslateError = {
1804 PyObject_HEAD_INIT(NULL)
1805 0,
1806 EXC_MODULE_NAME "UnicodeTranslateError",
1807 sizeof(PyUnicodeErrorObject), 0,
1808 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1809 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1810 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001811 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001812 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1813 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001814 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001815};
1816PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1817
1818PyObject *
1819PyUnicodeTranslateError_Create(
1820 const Py_UNICODE *object, Py_ssize_t length,
1821 Py_ssize_t start, Py_ssize_t end, const char *reason)
1822{
1823 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001824 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001825}
1826#endif
1827
1828
1829/*
1830 * AssertionError extends StandardError
1831 */
1832SimpleExtendsException(PyExc_StandardError, AssertionError,
1833 "Assertion failed.");
1834
1835
1836/*
1837 * ArithmeticError extends StandardError
1838 */
1839SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1840 "Base class for arithmetic errors.");
1841
1842
1843/*
1844 * FloatingPointError extends ArithmeticError
1845 */
1846SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1847 "Floating point operation failed.");
1848
1849
1850/*
1851 * OverflowError extends ArithmeticError
1852 */
1853SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1854 "Result too large to be represented.");
1855
1856
1857/*
1858 * ZeroDivisionError extends ArithmeticError
1859 */
1860SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1861 "Second argument to a division or modulo operation was zero.");
1862
1863
1864/*
1865 * SystemError extends StandardError
1866 */
1867SimpleExtendsException(PyExc_StandardError, SystemError,
1868 "Internal error in the Python interpreter.\n"
1869 "\n"
1870 "Please report this to the Python maintainer, along with the traceback,\n"
1871 "the Python version, and the hardware/OS platform and version.");
1872
1873
1874/*
1875 * ReferenceError extends StandardError
1876 */
1877SimpleExtendsException(PyExc_StandardError, ReferenceError,
1878 "Weak ref proxy used after referent went away.");
1879
1880
1881/*
1882 * MemoryError extends StandardError
1883 */
1884SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1885
1886
1887/* Warning category docstrings */
1888
1889/*
1890 * Warning extends Exception
1891 */
1892SimpleExtendsException(PyExc_Exception, Warning,
1893 "Base class for warning categories.");
1894
1895
1896/*
1897 * UserWarning extends Warning
1898 */
1899SimpleExtendsException(PyExc_Warning, UserWarning,
1900 "Base class for warnings generated by user code.");
1901
1902
1903/*
1904 * DeprecationWarning extends Warning
1905 */
1906SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1907 "Base class for warnings about deprecated features.");
1908
1909
1910/*
1911 * PendingDeprecationWarning extends Warning
1912 */
1913SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1914 "Base class for warnings about features which will be deprecated\n"
1915 "in the future.");
1916
1917
1918/*
1919 * SyntaxWarning extends Warning
1920 */
1921SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1922 "Base class for warnings about dubious syntax.");
1923
1924
1925/*
1926 * RuntimeWarning extends Warning
1927 */
1928SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1929 "Base class for warnings about dubious runtime behavior.");
1930
1931
1932/*
1933 * FutureWarning extends Warning
1934 */
1935SimpleExtendsException(PyExc_Warning, FutureWarning,
1936 "Base class for warnings about constructs that will change semantically\n"
1937 "in the future.");
1938
1939
1940/*
1941 * ImportWarning extends Warning
1942 */
1943SimpleExtendsException(PyExc_Warning, ImportWarning,
1944 "Base class for warnings about probable mistakes in module imports");
1945
1946
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001947/*
1948 * UnicodeWarning extends Warning
1949 */
1950SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1951 "Base class for warnings about Unicode related problems, mostly\n"
1952 "related to conversion problems.");
1953
1954
Thomas Wouters477c8d52006-05-27 19:21:47 +00001955/* Pre-computed MemoryError instance. Best to create this as early as
1956 * possible and not wait until a MemoryError is actually raised!
1957 */
1958PyObject *PyExc_MemoryErrorInst=NULL;
1959
1960/* module global functions */
1961static PyMethodDef functions[] = {
1962 /* Sentinel */
1963 {NULL, NULL}
1964};
1965
1966#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1967 Py_FatalError("exceptions bootstrapping error.");
1968
1969#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1970 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1971 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1972 Py_FatalError("Module dictionary insertion problem.");
1973
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001974#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1975/* crt variable checking in VisualStudio .NET 2005 */
1976#include <crtdbg.h>
1977
1978static int prevCrtReportMode;
1979static _invalid_parameter_handler prevCrtHandler;
1980
1981/* Invalid parameter handler. Sets a ValueError exception */
1982static void
1983InvalidParameterHandler(
1984 const wchar_t * expression,
1985 const wchar_t * function,
1986 const wchar_t * file,
1987 unsigned int line,
1988 uintptr_t pReserved)
1989{
1990 /* Do nothing, allow execution to continue. Usually this
1991 * means that the CRT will set errno to EINVAL
1992 */
1993}
1994#endif
1995
1996
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001998_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999{
2000 PyObject *m, *bltinmod, *bdict;
2001
2002 PRE_INIT(BaseException)
2003 PRE_INIT(Exception)
2004 PRE_INIT(StandardError)
2005 PRE_INIT(TypeError)
2006 PRE_INIT(StopIteration)
2007 PRE_INIT(GeneratorExit)
2008 PRE_INIT(SystemExit)
2009 PRE_INIT(KeyboardInterrupt)
2010 PRE_INIT(ImportError)
2011 PRE_INIT(EnvironmentError)
2012 PRE_INIT(IOError)
2013 PRE_INIT(OSError)
2014#ifdef MS_WINDOWS
2015 PRE_INIT(WindowsError)
2016#endif
2017#ifdef __VMS
2018 PRE_INIT(VMSError)
2019#endif
2020 PRE_INIT(EOFError)
2021 PRE_INIT(RuntimeError)
2022 PRE_INIT(NotImplementedError)
2023 PRE_INIT(NameError)
2024 PRE_INIT(UnboundLocalError)
2025 PRE_INIT(AttributeError)
2026 PRE_INIT(SyntaxError)
2027 PRE_INIT(IndentationError)
2028 PRE_INIT(TabError)
2029 PRE_INIT(LookupError)
2030 PRE_INIT(IndexError)
2031 PRE_INIT(KeyError)
2032 PRE_INIT(ValueError)
2033 PRE_INIT(UnicodeError)
2034#ifdef Py_USING_UNICODE
2035 PRE_INIT(UnicodeEncodeError)
2036 PRE_INIT(UnicodeDecodeError)
2037 PRE_INIT(UnicodeTranslateError)
2038#endif
2039 PRE_INIT(AssertionError)
2040 PRE_INIT(ArithmeticError)
2041 PRE_INIT(FloatingPointError)
2042 PRE_INIT(OverflowError)
2043 PRE_INIT(ZeroDivisionError)
2044 PRE_INIT(SystemError)
2045 PRE_INIT(ReferenceError)
2046 PRE_INIT(MemoryError)
2047 PRE_INIT(Warning)
2048 PRE_INIT(UserWarning)
2049 PRE_INIT(DeprecationWarning)
2050 PRE_INIT(PendingDeprecationWarning)
2051 PRE_INIT(SyntaxWarning)
2052 PRE_INIT(RuntimeWarning)
2053 PRE_INIT(FutureWarning)
2054 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002055 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002056
2057 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2058 (PyObject *)NULL, PYTHON_API_VERSION);
2059 if (m == NULL) return;
2060
2061 bltinmod = PyImport_ImportModule("__builtin__");
2062 if (bltinmod == NULL)
2063 Py_FatalError("exceptions bootstrapping error.");
2064 bdict = PyModule_GetDict(bltinmod);
2065 if (bdict == NULL)
2066 Py_FatalError("exceptions bootstrapping error.");
2067
2068 POST_INIT(BaseException)
2069 POST_INIT(Exception)
2070 POST_INIT(StandardError)
2071 POST_INIT(TypeError)
2072 POST_INIT(StopIteration)
2073 POST_INIT(GeneratorExit)
2074 POST_INIT(SystemExit)
2075 POST_INIT(KeyboardInterrupt)
2076 POST_INIT(ImportError)
2077 POST_INIT(EnvironmentError)
2078 POST_INIT(IOError)
2079 POST_INIT(OSError)
2080#ifdef MS_WINDOWS
2081 POST_INIT(WindowsError)
2082#endif
2083#ifdef __VMS
2084 POST_INIT(VMSError)
2085#endif
2086 POST_INIT(EOFError)
2087 POST_INIT(RuntimeError)
2088 POST_INIT(NotImplementedError)
2089 POST_INIT(NameError)
2090 POST_INIT(UnboundLocalError)
2091 POST_INIT(AttributeError)
2092 POST_INIT(SyntaxError)
2093 POST_INIT(IndentationError)
2094 POST_INIT(TabError)
2095 POST_INIT(LookupError)
2096 POST_INIT(IndexError)
2097 POST_INIT(KeyError)
2098 POST_INIT(ValueError)
2099 POST_INIT(UnicodeError)
2100#ifdef Py_USING_UNICODE
2101 POST_INIT(UnicodeEncodeError)
2102 POST_INIT(UnicodeDecodeError)
2103 POST_INIT(UnicodeTranslateError)
2104#endif
2105 POST_INIT(AssertionError)
2106 POST_INIT(ArithmeticError)
2107 POST_INIT(FloatingPointError)
2108 POST_INIT(OverflowError)
2109 POST_INIT(ZeroDivisionError)
2110 POST_INIT(SystemError)
2111 POST_INIT(ReferenceError)
2112 POST_INIT(MemoryError)
2113 POST_INIT(Warning)
2114 POST_INIT(UserWarning)
2115 POST_INIT(DeprecationWarning)
2116 POST_INIT(PendingDeprecationWarning)
2117 POST_INIT(SyntaxWarning)
2118 POST_INIT(RuntimeWarning)
2119 POST_INIT(FutureWarning)
2120 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002121 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002122
2123 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2124 if (!PyExc_MemoryErrorInst)
2125 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2126
2127 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002128
2129#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2130 /* Set CRT argument error handler */
2131 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2132 /* turn off assertions in debug mode */
2133 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2134#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002135}
2136
2137void
2138_PyExc_Fini(void)
2139{
2140 Py_XDECREF(PyExc_MemoryErrorInst);
2141 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002142#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2143 /* reset CRT error handling */
2144 _set_invalid_parameter_handler(prevCrtHandler);
2145 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2146#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002147}