blob: 402bcecfde97677ba560b8a99fc292583e696fad [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*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000303 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
304 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000305 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
306 (traverseproc)BaseException_traverse, /* tp_traverse */
307 (inquiry)BaseException_clear, /* tp_clear */
308 0, /* tp_richcompare */
309 0, /* tp_weaklistoffset */
310 0, /* tp_iter */
311 0, /* tp_iternext */
312 BaseException_methods, /* tp_methods */
313 BaseException_members, /* tp_members */
314 BaseException_getset, /* tp_getset */
315 0, /* tp_base */
316 0, /* tp_dict */
317 0, /* tp_descr_get */
318 0, /* tp_descr_set */
319 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
320 (initproc)BaseException_init, /* tp_init */
321 0, /* tp_alloc */
322 BaseException_new, /* tp_new */
323};
324/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
325from the previous implmentation and also allowing Python objects to be used
326in the API */
327PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
328
329/* note these macros omit the last semicolon so the macro invocation may
330 * include it and not look strange.
331 */
332#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
333static PyTypeObject _PyExc_ ## EXCNAME = { \
334 PyObject_HEAD_INIT(NULL) \
335 0, \
336 EXC_MODULE_NAME # EXCNAME, \
337 sizeof(PyBaseExceptionObject), \
338 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
339 0, 0, 0, 0, 0, 0, 0, \
340 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
341 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
342 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
343 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
344 (initproc)BaseException_init, 0, BaseException_new,\
345}; \
346PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
347
348#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
349static PyTypeObject _PyExc_ ## EXCNAME = { \
350 PyObject_HEAD_INIT(NULL) \
351 0, \
352 EXC_MODULE_NAME # EXCNAME, \
353 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000354 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000355 0, 0, 0, 0, 0, \
356 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000357 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
358 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000359 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000360 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000361}; \
362PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
363
364#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
365static PyTypeObject _PyExc_ ## EXCNAME = { \
366 PyObject_HEAD_INIT(NULL) \
367 0, \
368 EXC_MODULE_NAME # EXCNAME, \
369 sizeof(Py ## EXCSTORE ## Object), 0, \
370 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
371 (reprfunc)EXCSTR, 0, 0, 0, \
372 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
373 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
374 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
375 EXCMEMBERS, 0, &_ ## EXCBASE, \
376 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000377 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000378}; \
379PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
380
381
382/*
383 * Exception extends BaseException
384 */
385SimpleExtendsException(PyExc_BaseException, Exception,
386 "Common base class for all non-exit exceptions.");
387
388
389/*
390 * StandardError extends Exception
391 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000392SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000393 "Base class for all standard Python exceptions that do not represent\n"
394 "interpreter exiting.");
395
396
397/*
398 * TypeError extends StandardError
399 */
400SimpleExtendsException(PyExc_StandardError, TypeError,
401 "Inappropriate argument type.");
402
403
404/*
405 * StopIteration extends Exception
406 */
407SimpleExtendsException(PyExc_Exception, StopIteration,
408 "Signal the end from iterator.next().");
409
410
411/*
412 * GeneratorExit extends Exception
413 */
414SimpleExtendsException(PyExc_Exception, GeneratorExit,
415 "Request that a generator exit.");
416
417
418/*
419 * SystemExit extends BaseException
420 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421
422static int
423SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
424{
425 Py_ssize_t size = PyTuple_GET_SIZE(args);
426
427 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
428 return -1;
429
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000430 if (size == 0)
431 return 0;
432 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000433 if (size == 1)
434 self->code = PyTuple_GET_ITEM(args, 0);
435 else if (size > 1)
436 self->code = args;
437 Py_INCREF(self->code);
438 return 0;
439}
440
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000441static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000442SystemExit_clear(PySystemExitObject *self)
443{
444 Py_CLEAR(self->code);
445 return BaseException_clear((PyBaseExceptionObject *)self);
446}
447
448static void
449SystemExit_dealloc(PySystemExitObject *self)
450{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000451 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000452 SystemExit_clear(self);
453 self->ob_type->tp_free((PyObject *)self);
454}
455
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000456static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
458{
459 Py_VISIT(self->code);
460 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
461}
462
463static PyMemberDef SystemExit_members[] = {
464 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
465 PyDoc_STR("exception message")},
466 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
467 PyDoc_STR("exception code")},
468 {NULL} /* Sentinel */
469};
470
471ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
472 SystemExit_dealloc, 0, SystemExit_members, 0,
473 "Request to exit from the interpreter.");
474
475/*
476 * KeyboardInterrupt extends BaseException
477 */
478SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
479 "Program interrupted by user.");
480
481
482/*
483 * ImportError extends StandardError
484 */
485SimpleExtendsException(PyExc_StandardError, ImportError,
486 "Import can't find module, or can't find name in module.");
487
488
489/*
490 * EnvironmentError extends StandardError
491 */
492
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493/* Where a function has a single filename, such as open() or some
494 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
495 * called, giving a third argument which is the filename. But, so
496 * that old code using in-place unpacking doesn't break, e.g.:
497 *
498 * except IOError, (errno, strerror):
499 *
500 * we hack args so that it only contains two items. This also
501 * means we need our own __str__() which prints out the filename
502 * when it was supplied.
503 */
504static int
505EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
506 PyObject *kwds)
507{
508 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
509 PyObject *subslice = NULL;
510
511 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
512 return -1;
513
Thomas Wouters89f507f2006-12-13 04:49:30 +0000514 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000515 return 0;
516 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000517
518 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519 &myerrno, &strerror, &filename)) {
520 return -1;
521 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000522 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000523 self->myerrno = myerrno;
524 Py_INCREF(self->myerrno);
525
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000526 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527 self->strerror = strerror;
528 Py_INCREF(self->strerror);
529
530 /* self->filename will remain Py_None otherwise */
531 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000532 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000533 self->filename = filename;
534 Py_INCREF(self->filename);
535
536 subslice = PyTuple_GetSlice(args, 0, 2);
537 if (!subslice)
538 return -1;
539
540 Py_DECREF(self->args); /* replacing args */
541 self->args = subslice;
542 }
543 return 0;
544}
545
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000546static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000547EnvironmentError_clear(PyEnvironmentErrorObject *self)
548{
549 Py_CLEAR(self->myerrno);
550 Py_CLEAR(self->strerror);
551 Py_CLEAR(self->filename);
552 return BaseException_clear((PyBaseExceptionObject *)self);
553}
554
555static void
556EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
557{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000558 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000559 EnvironmentError_clear(self);
560 self->ob_type->tp_free((PyObject *)self);
561}
562
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000563static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000564EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
565 void *arg)
566{
567 Py_VISIT(self->myerrno);
568 Py_VISIT(self->strerror);
569 Py_VISIT(self->filename);
570 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
571}
572
573static PyObject *
574EnvironmentError_str(PyEnvironmentErrorObject *self)
575{
576 PyObject *rtnval = NULL;
577
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000578 if (self->filename) {
579 PyObject *fmt;
580 PyObject *repr;
581 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000582
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000583 fmt = PyString_FromString("[Errno %s] %s: %s");
584 if (!fmt)
585 return NULL;
586
587 repr = PyObject_Repr(self->filename);
588 if (!repr) {
589 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000590 return NULL;
591 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000592 tuple = PyTuple_New(3);
593 if (!tuple) {
594 Py_DECREF(repr);
595 Py_DECREF(fmt);
596 return NULL;
597 }
598
599 if (self->myerrno) {
600 Py_INCREF(self->myerrno);
601 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
602 }
603 else {
604 Py_INCREF(Py_None);
605 PyTuple_SET_ITEM(tuple, 0, Py_None);
606 }
607 if (self->strerror) {
608 Py_INCREF(self->strerror);
609 PyTuple_SET_ITEM(tuple, 1, self->strerror);
610 }
611 else {
612 Py_INCREF(Py_None);
613 PyTuple_SET_ITEM(tuple, 1, Py_None);
614 }
615
Thomas Wouters477c8d52006-05-27 19:21:47 +0000616 PyTuple_SET_ITEM(tuple, 2, repr);
617
618 rtnval = PyString_Format(fmt, tuple);
619
620 Py_DECREF(fmt);
621 Py_DECREF(tuple);
622 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000623 else if (self->myerrno && self->strerror) {
624 PyObject *fmt;
625 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000626
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000627 fmt = PyString_FromString("[Errno %s] %s");
628 if (!fmt)
629 return NULL;
630
631 tuple = PyTuple_New(2);
632 if (!tuple) {
633 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000634 return NULL;
635 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000636
637 if (self->myerrno) {
638 Py_INCREF(self->myerrno);
639 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
640 }
641 else {
642 Py_INCREF(Py_None);
643 PyTuple_SET_ITEM(tuple, 0, Py_None);
644 }
645 if (self->strerror) {
646 Py_INCREF(self->strerror);
647 PyTuple_SET_ITEM(tuple, 1, self->strerror);
648 }
649 else {
650 Py_INCREF(Py_None);
651 PyTuple_SET_ITEM(tuple, 1, Py_None);
652 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653
654 rtnval = PyString_Format(fmt, tuple);
655
656 Py_DECREF(fmt);
657 Py_DECREF(tuple);
658 }
659 else
660 rtnval = BaseException_str((PyBaseExceptionObject *)self);
661
662 return rtnval;
663}
664
665static PyMemberDef EnvironmentError_members[] = {
666 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
667 PyDoc_STR("exception message")},
668 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
669 PyDoc_STR("exception errno")},
670 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
671 PyDoc_STR("exception strerror")},
672 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
673 PyDoc_STR("exception filename")},
674 {NULL} /* Sentinel */
675};
676
677
678static PyObject *
679EnvironmentError_reduce(PyEnvironmentErrorObject *self)
680{
681 PyObject *args = self->args;
682 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000683
Thomas Wouters477c8d52006-05-27 19:21:47 +0000684 /* self->args is only the first two real arguments if there was a
685 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000686 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 args = PyTuple_New(3);
688 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000689
690 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000691 Py_INCREF(tmp);
692 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000693
694 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695 Py_INCREF(tmp);
696 PyTuple_SET_ITEM(args, 1, tmp);
697
698 Py_INCREF(self->filename);
699 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000700 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000701 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000702
703 if (self->dict)
704 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
705 else
706 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 Py_DECREF(args);
708 return res;
709}
710
711
712static PyMethodDef EnvironmentError_methods[] = {
713 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
714 {NULL}
715};
716
717ComplexExtendsException(PyExc_StandardError, EnvironmentError,
718 EnvironmentError, EnvironmentError_dealloc,
719 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000720 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000721 "Base class for I/O related errors.");
722
723
724/*
725 * IOError extends EnvironmentError
726 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000727MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000728 EnvironmentError, "I/O operation failed.");
729
730
731/*
732 * OSError extends EnvironmentError
733 */
734MiddlingExtendsException(PyExc_EnvironmentError, OSError,
735 EnvironmentError, "OS system call failed.");
736
737
738/*
739 * WindowsError extends OSError
740 */
741#ifdef MS_WINDOWS
742#include "errmap.h"
743
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000744static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000745WindowsError_clear(PyWindowsErrorObject *self)
746{
747 Py_CLEAR(self->myerrno);
748 Py_CLEAR(self->strerror);
749 Py_CLEAR(self->filename);
750 Py_CLEAR(self->winerror);
751 return BaseException_clear((PyBaseExceptionObject *)self);
752}
753
754static void
755WindowsError_dealloc(PyWindowsErrorObject *self)
756{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000757 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758 WindowsError_clear(self);
759 self->ob_type->tp_free((PyObject *)self);
760}
761
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000762static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
764{
765 Py_VISIT(self->myerrno);
766 Py_VISIT(self->strerror);
767 Py_VISIT(self->filename);
768 Py_VISIT(self->winerror);
769 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
770}
771
Thomas Wouters477c8d52006-05-27 19:21:47 +0000772static int
773WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
774{
775 PyObject *o_errcode = NULL;
776 long errcode;
777 long posix_errno;
778
779 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
780 == -1)
781 return -1;
782
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000783 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785
786 /* Set errno to the POSIX errno, and winerror to the Win32
787 error code. */
788 errcode = PyInt_AsLong(self->myerrno);
789 if (errcode == -1 && PyErr_Occurred())
790 return -1;
791 posix_errno = winerror_to_errno(errcode);
792
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000793 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000794 self->winerror = self->myerrno;
795
796 o_errcode = PyInt_FromLong(posix_errno);
797 if (!o_errcode)
798 return -1;
799
800 self->myerrno = o_errcode;
801
802 return 0;
803}
804
805
806static PyObject *
807WindowsError_str(PyWindowsErrorObject *self)
808{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809 PyObject *rtnval = NULL;
810
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000811 if (self->filename) {
812 PyObject *fmt;
813 PyObject *repr;
814 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000815
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 fmt = PyString_FromString("[Error %s] %s: %s");
817 if (!fmt)
818 return NULL;
819
820 repr = PyObject_Repr(self->filename);
821 if (!repr) {
822 Py_DECREF(fmt);
823 return NULL;
824 }
825 tuple = PyTuple_New(3);
826 if (!tuple) {
827 Py_DECREF(repr);
828 Py_DECREF(fmt);
829 return NULL;
830 }
831
Thomas Wouters89f507f2006-12-13 04:49:30 +0000832 if (self->winerror) {
833 Py_INCREF(self->winerror);
834 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000835 }
836 else {
837 Py_INCREF(Py_None);
838 PyTuple_SET_ITEM(tuple, 0, Py_None);
839 }
840 if (self->strerror) {
841 Py_INCREF(self->strerror);
842 PyTuple_SET_ITEM(tuple, 1, self->strerror);
843 }
844 else {
845 Py_INCREF(Py_None);
846 PyTuple_SET_ITEM(tuple, 1, Py_None);
847 }
848
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000849 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850
851 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000852
853 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854 Py_DECREF(tuple);
855 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000856 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000857 PyObject *fmt;
858 PyObject *tuple;
859
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860 fmt = PyString_FromString("[Error %s] %s");
861 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000862 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000863
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000864 tuple = PyTuple_New(2);
865 if (!tuple) {
866 Py_DECREF(fmt);
867 return NULL;
868 }
869
Thomas Wouters89f507f2006-12-13 04:49:30 +0000870 if (self->winerror) {
871 Py_INCREF(self->winerror);
872 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000873 }
874 else {
875 Py_INCREF(Py_None);
876 PyTuple_SET_ITEM(tuple, 0, Py_None);
877 }
878 if (self->strerror) {
879 Py_INCREF(self->strerror);
880 PyTuple_SET_ITEM(tuple, 1, self->strerror);
881 }
882 else {
883 Py_INCREF(Py_None);
884 PyTuple_SET_ITEM(tuple, 1, Py_None);
885 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886
887 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000888
889 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000890 Py_DECREF(tuple);
891 }
892 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000893 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000894
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895 return rtnval;
896}
897
898static PyMemberDef WindowsError_members[] = {
899 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
900 PyDoc_STR("exception message")},
901 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
902 PyDoc_STR("POSIX exception code")},
903 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
904 PyDoc_STR("exception strerror")},
905 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
906 PyDoc_STR("exception filename")},
907 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
908 PyDoc_STR("Win32 exception code")},
909 {NULL} /* Sentinel */
910};
911
912ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
913 WindowsError_dealloc, 0, WindowsError_members,
914 WindowsError_str, "MS-Windows OS system call failed.");
915
916#endif /* MS_WINDOWS */
917
918
919/*
920 * VMSError extends OSError (I think)
921 */
922#ifdef __VMS
923MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
924 "OpenVMS OS system call failed.");
925#endif
926
927
928/*
929 * EOFError extends StandardError
930 */
931SimpleExtendsException(PyExc_StandardError, EOFError,
932 "Read beyond end of file.");
933
934
935/*
936 * RuntimeError extends StandardError
937 */
938SimpleExtendsException(PyExc_StandardError, RuntimeError,
939 "Unspecified run-time error.");
940
941
942/*
943 * NotImplementedError extends RuntimeError
944 */
945SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
946 "Method or function hasn't been implemented yet.");
947
948/*
949 * NameError extends StandardError
950 */
951SimpleExtendsException(PyExc_StandardError, NameError,
952 "Name not found globally.");
953
954/*
955 * UnboundLocalError extends NameError
956 */
957SimpleExtendsException(PyExc_NameError, UnboundLocalError,
958 "Local name referenced but not bound to a value.");
959
960/*
961 * AttributeError extends StandardError
962 */
963SimpleExtendsException(PyExc_StandardError, AttributeError,
964 "Attribute not found.");
965
966
967/*
968 * SyntaxError extends StandardError
969 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000970
971static int
972SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
973{
974 PyObject *info = NULL;
975 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
976
977 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
978 return -1;
979
980 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000981 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000982 self->msg = PyTuple_GET_ITEM(args, 0);
983 Py_INCREF(self->msg);
984 }
985 if (lenargs == 2) {
986 info = PyTuple_GET_ITEM(args, 1);
987 info = PySequence_Tuple(info);
988 if (!info) return -1;
989
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000990 if (PyTuple_GET_SIZE(info) != 4) {
991 /* not a very good error message, but it's what Python 2.4 gives */
992 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
993 Py_DECREF(info);
994 return -1;
995 }
996
997 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998 self->filename = PyTuple_GET_ITEM(info, 0);
999 Py_INCREF(self->filename);
1000
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001001 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002 self->lineno = PyTuple_GET_ITEM(info, 1);
1003 Py_INCREF(self->lineno);
1004
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001005 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006 self->offset = PyTuple_GET_ITEM(info, 2);
1007 Py_INCREF(self->offset);
1008
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001009 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001010 self->text = PyTuple_GET_ITEM(info, 3);
1011 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001012
1013 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001014 }
1015 return 0;
1016}
1017
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019SyntaxError_clear(PySyntaxErrorObject *self)
1020{
1021 Py_CLEAR(self->msg);
1022 Py_CLEAR(self->filename);
1023 Py_CLEAR(self->lineno);
1024 Py_CLEAR(self->offset);
1025 Py_CLEAR(self->text);
1026 Py_CLEAR(self->print_file_and_line);
1027 return BaseException_clear((PyBaseExceptionObject *)self);
1028}
1029
1030static void
1031SyntaxError_dealloc(PySyntaxErrorObject *self)
1032{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001033 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034 SyntaxError_clear(self);
1035 self->ob_type->tp_free((PyObject *)self);
1036}
1037
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001038static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001039SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1040{
1041 Py_VISIT(self->msg);
1042 Py_VISIT(self->filename);
1043 Py_VISIT(self->lineno);
1044 Py_VISIT(self->offset);
1045 Py_VISIT(self->text);
1046 Py_VISIT(self->print_file_and_line);
1047 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1048}
1049
1050/* This is called "my_basename" instead of just "basename" to avoid name
1051 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1052 defined, and Python does define that. */
1053static char *
1054my_basename(char *name)
1055{
1056 char *cp = name;
1057 char *result = name;
1058
1059 if (name == NULL)
1060 return "???";
1061 while (*cp != '\0') {
1062 if (*cp == SEP)
1063 result = cp + 1;
1064 ++cp;
1065 }
1066 return result;
1067}
1068
1069
1070static PyObject *
1071SyntaxError_str(PySyntaxErrorObject *self)
1072{
1073 PyObject *str;
1074 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001075 int have_filename = 0;
1076 int have_lineno = 0;
1077 char *buffer = NULL;
1078 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001079
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 if (self->msg)
1081 str = PyObject_Str(self->msg);
1082 else
1083 str = PyObject_Str(Py_None);
1084 if (!str) return NULL;
1085 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1086 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001087
1088 /* XXX -- do all the additional formatting with filename and
1089 lineno here */
1090
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001091 have_filename = (self->filename != NULL) &&
1092 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001093 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001094
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001095 if (!have_filename && !have_lineno)
1096 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001098 bufsize = PyString_GET_SIZE(str) + 64;
1099 if (have_filename)
1100 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001101
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001102 buffer = PyMem_MALLOC(bufsize);
1103 if (buffer == NULL)
1104 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001105
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001106 if (have_filename && have_lineno)
1107 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1108 PyString_AS_STRING(str),
1109 my_basename(PyString_AS_STRING(self->filename)),
1110 PyInt_AsLong(self->lineno));
1111 else if (have_filename)
1112 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1113 PyString_AS_STRING(str),
1114 my_basename(PyString_AS_STRING(self->filename)));
1115 else /* only have_lineno */
1116 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1117 PyString_AS_STRING(str),
1118 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001119
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001120 result = PyString_FromString(buffer);
1121 PyMem_FREE(buffer);
1122
1123 if (result == NULL)
1124 result = str;
1125 else
1126 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001127 return result;
1128}
1129
1130static PyMemberDef SyntaxError_members[] = {
1131 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1132 PyDoc_STR("exception message")},
1133 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1134 PyDoc_STR("exception msg")},
1135 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1136 PyDoc_STR("exception filename")},
1137 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1138 PyDoc_STR("exception lineno")},
1139 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1140 PyDoc_STR("exception offset")},
1141 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1142 PyDoc_STR("exception text")},
1143 {"print_file_and_line", T_OBJECT,
1144 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1145 PyDoc_STR("exception print_file_and_line")},
1146 {NULL} /* Sentinel */
1147};
1148
1149ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1150 SyntaxError_dealloc, 0, SyntaxError_members,
1151 SyntaxError_str, "Invalid syntax.");
1152
1153
1154/*
1155 * IndentationError extends SyntaxError
1156 */
1157MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1158 "Improper indentation.");
1159
1160
1161/*
1162 * TabError extends IndentationError
1163 */
1164MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1165 "Improper mixture of spaces and tabs.");
1166
1167
1168/*
1169 * LookupError extends StandardError
1170 */
1171SimpleExtendsException(PyExc_StandardError, LookupError,
1172 "Base class for lookup errors.");
1173
1174
1175/*
1176 * IndexError extends LookupError
1177 */
1178SimpleExtendsException(PyExc_LookupError, IndexError,
1179 "Sequence index out of range.");
1180
1181
1182/*
1183 * KeyError extends LookupError
1184 */
1185static PyObject *
1186KeyError_str(PyBaseExceptionObject *self)
1187{
1188 /* If args is a tuple of exactly one item, apply repr to args[0].
1189 This is done so that e.g. the exception raised by {}[''] prints
1190 KeyError: ''
1191 rather than the confusing
1192 KeyError
1193 alone. The downside is that if KeyError is raised with an explanatory
1194 string, that string will be displayed in quotes. Too bad.
1195 If args is anything else, use the default BaseException__str__().
1196 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001197 if (PyTuple_GET_SIZE(self->args) == 1) {
1198 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001199 }
1200 return BaseException_str(self);
1201}
1202
1203ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1204 0, 0, 0, KeyError_str, "Mapping key not found.");
1205
1206
1207/*
1208 * ValueError extends StandardError
1209 */
1210SimpleExtendsException(PyExc_StandardError, ValueError,
1211 "Inappropriate argument value (of correct type).");
1212
1213/*
1214 * UnicodeError extends ValueError
1215 */
1216
1217SimpleExtendsException(PyExc_ValueError, UnicodeError,
1218 "Unicode related error.");
1219
1220#ifdef Py_USING_UNICODE
1221static int
1222get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1223{
1224 if (!attr) {
1225 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1226 return -1;
1227 }
1228
Guido van Rossumddefaf32007-01-14 03:31:43 +00001229 if (PyLong_Check(attr)) {
1230 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001231 if (*value == -1 && PyErr_Occurred())
1232 return -1;
1233 } else {
1234 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1235 return -1;
1236 }
1237 return 0;
1238}
1239
1240static int
1241set_ssize_t(PyObject **attr, Py_ssize_t value)
1242{
1243 PyObject *obj = PyInt_FromSsize_t(value);
1244 if (!obj)
1245 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001246 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247 *attr = obj;
1248 return 0;
1249}
1250
1251static PyObject *
1252get_string(PyObject *attr, const char *name)
1253{
1254 if (!attr) {
1255 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1256 return NULL;
1257 }
1258
1259 if (!PyString_Check(attr)) {
1260 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1261 return NULL;
1262 }
1263 Py_INCREF(attr);
1264 return attr;
1265}
1266
1267
1268static int
1269set_string(PyObject **attr, const char *value)
1270{
1271 PyObject *obj = PyString_FromString(value);
1272 if (!obj)
1273 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001274 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275 *attr = obj;
1276 return 0;
1277}
1278
1279
1280static PyObject *
1281get_unicode(PyObject *attr, const char *name)
1282{
1283 if (!attr) {
1284 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1285 return NULL;
1286 }
1287
1288 if (!PyUnicode_Check(attr)) {
1289 PyErr_Format(PyExc_TypeError,
1290 "%.200s attribute must be unicode", name);
1291 return NULL;
1292 }
1293 Py_INCREF(attr);
1294 return attr;
1295}
1296
1297PyObject *
1298PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1299{
1300 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1301}
1302
1303PyObject *
1304PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1305{
1306 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1307}
1308
1309PyObject *
1310PyUnicodeEncodeError_GetObject(PyObject *exc)
1311{
1312 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1313}
1314
1315PyObject *
1316PyUnicodeDecodeError_GetObject(PyObject *exc)
1317{
1318 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1319}
1320
1321PyObject *
1322PyUnicodeTranslateError_GetObject(PyObject *exc)
1323{
1324 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1325}
1326
1327int
1328PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1329{
1330 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1331 Py_ssize_t size;
1332 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1333 "object");
1334 if (!obj) return -1;
1335 size = PyUnicode_GET_SIZE(obj);
1336 if (*start<0)
1337 *start = 0; /*XXX check for values <0*/
1338 if (*start>=size)
1339 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001340 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341 return 0;
1342 }
1343 return -1;
1344}
1345
1346
1347int
1348PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1349{
1350 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1351 Py_ssize_t size;
1352 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1353 "object");
1354 if (!obj) return -1;
1355 size = PyString_GET_SIZE(obj);
1356 if (*start<0)
1357 *start = 0;
1358 if (*start>=size)
1359 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001360 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001361 return 0;
1362 }
1363 return -1;
1364}
1365
1366
1367int
1368PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1369{
1370 return PyUnicodeEncodeError_GetStart(exc, start);
1371}
1372
1373
1374int
1375PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1376{
1377 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1378}
1379
1380
1381int
1382PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1383{
1384 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1385}
1386
1387
1388int
1389PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1390{
1391 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1392}
1393
1394
1395int
1396PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1397{
1398 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1399 Py_ssize_t size;
1400 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1401 "object");
1402 if (!obj) return -1;
1403 size = PyUnicode_GET_SIZE(obj);
1404 if (*end<1)
1405 *end = 1;
1406 if (*end>size)
1407 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001408 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409 return 0;
1410 }
1411 return -1;
1412}
1413
1414
1415int
1416PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1417{
1418 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1419 Py_ssize_t size;
1420 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1421 "object");
1422 if (!obj) return -1;
1423 size = PyString_GET_SIZE(obj);
1424 if (*end<1)
1425 *end = 1;
1426 if (*end>size)
1427 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001428 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429 return 0;
1430 }
1431 return -1;
1432}
1433
1434
1435int
1436PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1437{
1438 return PyUnicodeEncodeError_GetEnd(exc, start);
1439}
1440
1441
1442int
1443PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1444{
1445 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1446}
1447
1448
1449int
1450PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1451{
1452 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1453}
1454
1455
1456int
1457PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1458{
1459 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1460}
1461
1462PyObject *
1463PyUnicodeEncodeError_GetReason(PyObject *exc)
1464{
1465 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1466}
1467
1468
1469PyObject *
1470PyUnicodeDecodeError_GetReason(PyObject *exc)
1471{
1472 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1473}
1474
1475
1476PyObject *
1477PyUnicodeTranslateError_GetReason(PyObject *exc)
1478{
1479 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1480}
1481
1482
1483int
1484PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1485{
1486 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1487}
1488
1489
1490int
1491PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1492{
1493 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1494}
1495
1496
1497int
1498PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1499{
1500 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1501}
1502
1503
Thomas Wouters477c8d52006-05-27 19:21:47 +00001504static int
1505UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1506 PyTypeObject *objecttype)
1507{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001508 Py_CLEAR(self->encoding);
1509 Py_CLEAR(self->object);
1510 Py_CLEAR(self->start);
1511 Py_CLEAR(self->end);
1512 Py_CLEAR(self->reason);
1513
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1515 &PyString_Type, &self->encoding,
1516 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001517 &PyLong_Type, &self->start,
1518 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001519 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001520 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 self->reason = NULL;
1522 return -1;
1523 }
1524
1525 Py_INCREF(self->encoding);
1526 Py_INCREF(self->object);
1527 Py_INCREF(self->start);
1528 Py_INCREF(self->end);
1529 Py_INCREF(self->reason);
1530
1531 return 0;
1532}
1533
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001534static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535UnicodeError_clear(PyUnicodeErrorObject *self)
1536{
1537 Py_CLEAR(self->encoding);
1538 Py_CLEAR(self->object);
1539 Py_CLEAR(self->start);
1540 Py_CLEAR(self->end);
1541 Py_CLEAR(self->reason);
1542 return BaseException_clear((PyBaseExceptionObject *)self);
1543}
1544
1545static void
1546UnicodeError_dealloc(PyUnicodeErrorObject *self)
1547{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001548 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549 UnicodeError_clear(self);
1550 self->ob_type->tp_free((PyObject *)self);
1551}
1552
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001553static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1555{
1556 Py_VISIT(self->encoding);
1557 Py_VISIT(self->object);
1558 Py_VISIT(self->start);
1559 Py_VISIT(self->end);
1560 Py_VISIT(self->reason);
1561 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1562}
1563
1564static PyMemberDef UnicodeError_members[] = {
1565 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1566 PyDoc_STR("exception message")},
1567 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1568 PyDoc_STR("exception encoding")},
1569 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1570 PyDoc_STR("exception object")},
1571 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1572 PyDoc_STR("exception start")},
1573 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1574 PyDoc_STR("exception end")},
1575 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1576 PyDoc_STR("exception reason")},
1577 {NULL} /* Sentinel */
1578};
1579
1580
1581/*
1582 * UnicodeEncodeError extends UnicodeError
1583 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001584
1585static int
1586UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1587{
1588 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1589 return -1;
1590 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1591 kwds, &PyUnicode_Type);
1592}
1593
1594static PyObject *
1595UnicodeEncodeError_str(PyObject *self)
1596{
1597 Py_ssize_t start;
1598 Py_ssize_t end;
1599
1600 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001601 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001602
1603 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001604 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605
1606 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001607 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1608 char badchar_str[20];
1609 if (badchar <= 0xff)
1610 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1611 else if (badchar <= 0xffff)
1612 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1613 else
1614 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1615 return PyString_FromFormat(
1616 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1617 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1618 badchar_str,
1619 start,
1620 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1621 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001622 }
1623 return PyString_FromFormat(
1624 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1625 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1626 start,
1627 (end-1),
1628 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1629 );
1630}
1631
1632static PyTypeObject _PyExc_UnicodeEncodeError = {
1633 PyObject_HEAD_INIT(NULL)
1634 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001635 EXC_MODULE_NAME "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636 sizeof(PyUnicodeErrorObject), 0,
1637 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1638 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1639 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001640 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1641 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001642 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001643 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001644};
1645PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1646
1647PyObject *
1648PyUnicodeEncodeError_Create(
1649 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1650 Py_ssize_t start, Py_ssize_t end, const char *reason)
1651{
1652 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001653 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001654}
1655
1656
1657/*
1658 * UnicodeDecodeError extends UnicodeError
1659 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660
1661static int
1662UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1663{
1664 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1665 return -1;
1666 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1667 kwds, &PyString_Type);
1668}
1669
1670static PyObject *
1671UnicodeDecodeError_str(PyObject *self)
1672{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001673 Py_ssize_t start = 0;
1674 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675
1676 if (PyUnicodeDecodeError_GetStart(self, &start))
1677 return NULL;
1678
1679 if (PyUnicodeDecodeError_GetEnd(self, &end))
1680 return NULL;
1681
1682 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001683 /* FromFormat does not support %02x, so format that separately */
1684 char byte[4];
1685 PyOS_snprintf(byte, sizeof(byte), "%02x",
1686 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1687 return PyString_FromFormat(
1688 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1689 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1690 byte,
1691 start,
1692 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1693 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 }
1695 return PyString_FromFormat(
1696 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1697 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1698 start,
1699 (end-1),
1700 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1701 );
1702}
1703
1704static PyTypeObject _PyExc_UnicodeDecodeError = {
1705 PyObject_HEAD_INIT(NULL)
1706 0,
1707 EXC_MODULE_NAME "UnicodeDecodeError",
1708 sizeof(PyUnicodeErrorObject), 0,
1709 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1710 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1711 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001712 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1713 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001714 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001715 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001716};
1717PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1718
1719PyObject *
1720PyUnicodeDecodeError_Create(
1721 const char *encoding, const char *object, Py_ssize_t length,
1722 Py_ssize_t start, Py_ssize_t end, const char *reason)
1723{
1724 assert(length < INT_MAX);
1725 assert(start < INT_MAX);
1726 assert(end < INT_MAX);
1727 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001728 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729}
1730
1731
1732/*
1733 * UnicodeTranslateError extends UnicodeError
1734 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001735
1736static int
1737UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1738 PyObject *kwds)
1739{
1740 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1741 return -1;
1742
1743 Py_CLEAR(self->object);
1744 Py_CLEAR(self->start);
1745 Py_CLEAR(self->end);
1746 Py_CLEAR(self->reason);
1747
1748 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1749 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001750 &PyLong_Type, &self->start,
1751 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001752 &PyString_Type, &self->reason)) {
1753 self->object = self->start = self->end = self->reason = NULL;
1754 return -1;
1755 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001756
Thomas Wouters477c8d52006-05-27 19:21:47 +00001757 Py_INCREF(self->object);
1758 Py_INCREF(self->start);
1759 Py_INCREF(self->end);
1760 Py_INCREF(self->reason);
1761
1762 return 0;
1763}
1764
1765
1766static PyObject *
1767UnicodeTranslateError_str(PyObject *self)
1768{
1769 Py_ssize_t start;
1770 Py_ssize_t end;
1771
1772 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001773 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001774
1775 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001776 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001777
1778 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001779 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1780 char badchar_str[20];
1781 if (badchar <= 0xff)
1782 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1783 else if (badchar <= 0xffff)
1784 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1785 else
1786 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1787 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001788 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001789 badchar_str,
1790 start,
1791 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1792 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001793 }
1794 return PyString_FromFormat(
1795 "can't translate characters in position %zd-%zd: %.400s",
1796 start,
1797 (end-1),
1798 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1799 );
1800}
1801
1802static PyTypeObject _PyExc_UnicodeTranslateError = {
1803 PyObject_HEAD_INIT(NULL)
1804 0,
1805 EXC_MODULE_NAME "UnicodeTranslateError",
1806 sizeof(PyUnicodeErrorObject), 0,
1807 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1808 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1809 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001810 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1812 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001813 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001814};
1815PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1816
1817PyObject *
1818PyUnicodeTranslateError_Create(
1819 const Py_UNICODE *object, Py_ssize_t length,
1820 Py_ssize_t start, Py_ssize_t end, const char *reason)
1821{
1822 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001823 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824}
1825#endif
1826
1827
1828/*
1829 * AssertionError extends StandardError
1830 */
1831SimpleExtendsException(PyExc_StandardError, AssertionError,
1832 "Assertion failed.");
1833
1834
1835/*
1836 * ArithmeticError extends StandardError
1837 */
1838SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1839 "Base class for arithmetic errors.");
1840
1841
1842/*
1843 * FloatingPointError extends ArithmeticError
1844 */
1845SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1846 "Floating point operation failed.");
1847
1848
1849/*
1850 * OverflowError extends ArithmeticError
1851 */
1852SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1853 "Result too large to be represented.");
1854
1855
1856/*
1857 * ZeroDivisionError extends ArithmeticError
1858 */
1859SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1860 "Second argument to a division or modulo operation was zero.");
1861
1862
1863/*
1864 * SystemError extends StandardError
1865 */
1866SimpleExtendsException(PyExc_StandardError, SystemError,
1867 "Internal error in the Python interpreter.\n"
1868 "\n"
1869 "Please report this to the Python maintainer, along with the traceback,\n"
1870 "the Python version, and the hardware/OS platform and version.");
1871
1872
1873/*
1874 * ReferenceError extends StandardError
1875 */
1876SimpleExtendsException(PyExc_StandardError, ReferenceError,
1877 "Weak ref proxy used after referent went away.");
1878
1879
1880/*
1881 * MemoryError extends StandardError
1882 */
1883SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1884
1885
1886/* Warning category docstrings */
1887
1888/*
1889 * Warning extends Exception
1890 */
1891SimpleExtendsException(PyExc_Exception, Warning,
1892 "Base class for warning categories.");
1893
1894
1895/*
1896 * UserWarning extends Warning
1897 */
1898SimpleExtendsException(PyExc_Warning, UserWarning,
1899 "Base class for warnings generated by user code.");
1900
1901
1902/*
1903 * DeprecationWarning extends Warning
1904 */
1905SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1906 "Base class for warnings about deprecated features.");
1907
1908
1909/*
1910 * PendingDeprecationWarning extends Warning
1911 */
1912SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1913 "Base class for warnings about features which will be deprecated\n"
1914 "in the future.");
1915
1916
1917/*
1918 * SyntaxWarning extends Warning
1919 */
1920SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1921 "Base class for warnings about dubious syntax.");
1922
1923
1924/*
1925 * RuntimeWarning extends Warning
1926 */
1927SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1928 "Base class for warnings about dubious runtime behavior.");
1929
1930
1931/*
1932 * FutureWarning extends Warning
1933 */
1934SimpleExtendsException(PyExc_Warning, FutureWarning,
1935 "Base class for warnings about constructs that will change semantically\n"
1936 "in the future.");
1937
1938
1939/*
1940 * ImportWarning extends Warning
1941 */
1942SimpleExtendsException(PyExc_Warning, ImportWarning,
1943 "Base class for warnings about probable mistakes in module imports");
1944
1945
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001946/*
1947 * UnicodeWarning extends Warning
1948 */
1949SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1950 "Base class for warnings about Unicode related problems, mostly\n"
1951 "related to conversion problems.");
1952
1953
Thomas Wouters477c8d52006-05-27 19:21:47 +00001954/* Pre-computed MemoryError instance. Best to create this as early as
1955 * possible and not wait until a MemoryError is actually raised!
1956 */
1957PyObject *PyExc_MemoryErrorInst=NULL;
1958
1959/* module global functions */
1960static PyMethodDef functions[] = {
1961 /* Sentinel */
1962 {NULL, NULL}
1963};
1964
1965#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1966 Py_FatalError("exceptions bootstrapping error.");
1967
1968#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1969 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1970 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1971 Py_FatalError("Module dictionary insertion problem.");
1972
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001973#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1974/* crt variable checking in VisualStudio .NET 2005 */
1975#include <crtdbg.h>
1976
1977static int prevCrtReportMode;
1978static _invalid_parameter_handler prevCrtHandler;
1979
1980/* Invalid parameter handler. Sets a ValueError exception */
1981static void
1982InvalidParameterHandler(
1983 const wchar_t * expression,
1984 const wchar_t * function,
1985 const wchar_t * file,
1986 unsigned int line,
1987 uintptr_t pReserved)
1988{
1989 /* Do nothing, allow execution to continue. Usually this
1990 * means that the CRT will set errno to EINVAL
1991 */
1992}
1993#endif
1994
1995
Thomas Wouters477c8d52006-05-27 19:21:47 +00001996PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001997_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001998{
1999 PyObject *m, *bltinmod, *bdict;
2000
2001 PRE_INIT(BaseException)
2002 PRE_INIT(Exception)
2003 PRE_INIT(StandardError)
2004 PRE_INIT(TypeError)
2005 PRE_INIT(StopIteration)
2006 PRE_INIT(GeneratorExit)
2007 PRE_INIT(SystemExit)
2008 PRE_INIT(KeyboardInterrupt)
2009 PRE_INIT(ImportError)
2010 PRE_INIT(EnvironmentError)
2011 PRE_INIT(IOError)
2012 PRE_INIT(OSError)
2013#ifdef MS_WINDOWS
2014 PRE_INIT(WindowsError)
2015#endif
2016#ifdef __VMS
2017 PRE_INIT(VMSError)
2018#endif
2019 PRE_INIT(EOFError)
2020 PRE_INIT(RuntimeError)
2021 PRE_INIT(NotImplementedError)
2022 PRE_INIT(NameError)
2023 PRE_INIT(UnboundLocalError)
2024 PRE_INIT(AttributeError)
2025 PRE_INIT(SyntaxError)
2026 PRE_INIT(IndentationError)
2027 PRE_INIT(TabError)
2028 PRE_INIT(LookupError)
2029 PRE_INIT(IndexError)
2030 PRE_INIT(KeyError)
2031 PRE_INIT(ValueError)
2032 PRE_INIT(UnicodeError)
2033#ifdef Py_USING_UNICODE
2034 PRE_INIT(UnicodeEncodeError)
2035 PRE_INIT(UnicodeDecodeError)
2036 PRE_INIT(UnicodeTranslateError)
2037#endif
2038 PRE_INIT(AssertionError)
2039 PRE_INIT(ArithmeticError)
2040 PRE_INIT(FloatingPointError)
2041 PRE_INIT(OverflowError)
2042 PRE_INIT(ZeroDivisionError)
2043 PRE_INIT(SystemError)
2044 PRE_INIT(ReferenceError)
2045 PRE_INIT(MemoryError)
2046 PRE_INIT(Warning)
2047 PRE_INIT(UserWarning)
2048 PRE_INIT(DeprecationWarning)
2049 PRE_INIT(PendingDeprecationWarning)
2050 PRE_INIT(SyntaxWarning)
2051 PRE_INIT(RuntimeWarning)
2052 PRE_INIT(FutureWarning)
2053 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002054 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002055
2056 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2057 (PyObject *)NULL, PYTHON_API_VERSION);
2058 if (m == NULL) return;
2059
2060 bltinmod = PyImport_ImportModule("__builtin__");
2061 if (bltinmod == NULL)
2062 Py_FatalError("exceptions bootstrapping error.");
2063 bdict = PyModule_GetDict(bltinmod);
2064 if (bdict == NULL)
2065 Py_FatalError("exceptions bootstrapping error.");
2066
2067 POST_INIT(BaseException)
2068 POST_INIT(Exception)
2069 POST_INIT(StandardError)
2070 POST_INIT(TypeError)
2071 POST_INIT(StopIteration)
2072 POST_INIT(GeneratorExit)
2073 POST_INIT(SystemExit)
2074 POST_INIT(KeyboardInterrupt)
2075 POST_INIT(ImportError)
2076 POST_INIT(EnvironmentError)
2077 POST_INIT(IOError)
2078 POST_INIT(OSError)
2079#ifdef MS_WINDOWS
2080 POST_INIT(WindowsError)
2081#endif
2082#ifdef __VMS
2083 POST_INIT(VMSError)
2084#endif
2085 POST_INIT(EOFError)
2086 POST_INIT(RuntimeError)
2087 POST_INIT(NotImplementedError)
2088 POST_INIT(NameError)
2089 POST_INIT(UnboundLocalError)
2090 POST_INIT(AttributeError)
2091 POST_INIT(SyntaxError)
2092 POST_INIT(IndentationError)
2093 POST_INIT(TabError)
2094 POST_INIT(LookupError)
2095 POST_INIT(IndexError)
2096 POST_INIT(KeyError)
2097 POST_INIT(ValueError)
2098 POST_INIT(UnicodeError)
2099#ifdef Py_USING_UNICODE
2100 POST_INIT(UnicodeEncodeError)
2101 POST_INIT(UnicodeDecodeError)
2102 POST_INIT(UnicodeTranslateError)
2103#endif
2104 POST_INIT(AssertionError)
2105 POST_INIT(ArithmeticError)
2106 POST_INIT(FloatingPointError)
2107 POST_INIT(OverflowError)
2108 POST_INIT(ZeroDivisionError)
2109 POST_INIT(SystemError)
2110 POST_INIT(ReferenceError)
2111 POST_INIT(MemoryError)
2112 POST_INIT(Warning)
2113 POST_INIT(UserWarning)
2114 POST_INIT(DeprecationWarning)
2115 POST_INIT(PendingDeprecationWarning)
2116 POST_INIT(SyntaxWarning)
2117 POST_INIT(RuntimeWarning)
2118 POST_INIT(FutureWarning)
2119 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002120 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002121
2122 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2123 if (!PyExc_MemoryErrorInst)
2124 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2125
2126 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002127
2128#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2129 /* Set CRT argument error handler */
2130 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2131 /* turn off assertions in debug mode */
2132 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2133#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002134}
2135
2136void
2137_PyExc_Fini(void)
2138{
2139 Py_XDECREF(PyExc_MemoryErrorInst);
2140 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002141#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2142 /* reset CRT error handling */
2143 _set_invalid_parameter_handler(prevCrtHandler);
2144 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2145#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002146}