blob: cea41f8953a8f8b43bdcf0d2537b4f4a405eced8 [file] [log] [blame]
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001/*
2 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
3 *
4 * Thanks go to Tim Peters and Michael Hudson for debugging.
5 */
6
Thomas Wouters477c8d52006-05-27 19:21:47 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
9#include "structmember.h"
10#include "osdefs.h"
11
12#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +000013
14/* NOTE: If the exception class hierarchy changes, don't forget to update
15 * Lib/test/exception_hierarchy.txt
16 */
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018/*
19 * BaseException
20 */
21static PyObject *
22BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyBaseExceptionObject *self;
25
26 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
27 /* the dict is created on the fly in PyObject_GenericSetAttr */
28 self->message = self->dict = NULL;
29
30 self->args = PyTuple_New(0);
31 if (!self->args) {
32 Py_DECREF(self);
33 return NULL;
34 }
35
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000036 self->message = PyString_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000037 if (!self->message) {
38 Py_DECREF(self);
39 return NULL;
40 }
41
42 return (PyObject *)self;
43}
44
45static int
46BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
47{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000048 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
49 return -1;
50
Thomas Wouters477c8d52006-05-27 19:21:47 +000051 Py_DECREF(self->args);
52 self->args = args;
53 Py_INCREF(self->args);
54
55 if (PyTuple_GET_SIZE(self->args) == 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000056 Py_CLEAR(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000057 self->message = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000058 Py_INCREF(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000059 }
60 return 0;
61}
62
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000063static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000064BaseException_clear(PyBaseExceptionObject *self)
65{
66 Py_CLEAR(self->dict);
67 Py_CLEAR(self->args);
68 Py_CLEAR(self->message);
69 return 0;
70}
71
72static void
73BaseException_dealloc(PyBaseExceptionObject *self)
74{
Thomas Wouters89f507f2006-12-13 04:49:30 +000075 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000076 BaseException_clear(self);
77 self->ob_type->tp_free((PyObject *)self);
78}
79
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000080static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000081BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
82{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000083 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 Py_VISIT(self->args);
85 Py_VISIT(self->message);
86 return 0;
87}
88
89static PyObject *
90BaseException_str(PyBaseExceptionObject *self)
91{
92 PyObject *out;
93
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000094 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000095 case 0:
96 out = PyString_FromString("");
97 break;
98 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000099 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000100 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000101 default:
102 out = PyObject_Str(self->args);
103 break;
104 }
105
106 return out;
107}
108
109static PyObject *
110BaseException_repr(PyBaseExceptionObject *self)
111{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112 PyObject *repr_suffix;
113 PyObject *repr;
114 char *name;
115 char *dot;
116
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000117 repr_suffix = PyObject_Repr(self->args);
118 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000119 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000120
121 name = (char *)self->ob_type->tp_name;
122 dot = strrchr(name, '.');
123 if (dot != NULL) name = dot+1;
124
125 repr = PyString_FromString(name);
126 if (!repr) {
127 Py_DECREF(repr_suffix);
128 return NULL;
129 }
130
131 PyString_ConcatAndDel(&repr, repr_suffix);
132 return repr;
133}
134
135/* Pickling support */
136static PyObject *
137BaseException_reduce(PyBaseExceptionObject *self)
138{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000139 if (self->args && self->dict)
140 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
141 else
142 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000143}
144
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000145/*
146 * Needed for backward compatibility, since exceptions used to store
147 * all their attributes in the __dict__. Code is taken from cPickle's
148 * load_build function.
149 */
150static PyObject *
151BaseException_setstate(PyObject *self, PyObject *state)
152{
153 PyObject *d_key, *d_value;
154 Py_ssize_t i = 0;
155
156 if (state != Py_None) {
157 if (!PyDict_Check(state)) {
158 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
159 return NULL;
160 }
161 while (PyDict_Next(state, &i, &d_key, &d_value)) {
162 if (PyObject_SetAttr(self, d_key, d_value) < 0)
163 return NULL;
164 }
165 }
166 Py_RETURN_NONE;
167}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000168
Thomas Wouters477c8d52006-05-27 19:21:47 +0000169
170static PyMethodDef BaseException_methods[] = {
171 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000172 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000173 {NULL, NULL, 0, NULL},
174};
175
176
177
178static PyObject *
179BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
180{
181 return PySequence_GetItem(self->args, index);
182}
183
Thomas Wouters89f507f2006-12-13 04:49:30 +0000184static PyObject *
185BaseException_getslice(PyBaseExceptionObject *self,
186 Py_ssize_t start, Py_ssize_t stop)
187{
188 return PySequence_GetSlice(self->args, start, stop);
189}
190
Thomas Wouters477c8d52006-05-27 19:21:47 +0000191static PySequenceMethods BaseException_as_sequence = {
192 0, /* sq_length; */
193 0, /* sq_concat; */
194 0, /* sq_repeat; */
195 (ssizeargfunc)BaseException_getitem, /* sq_item; */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000196 (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000197 0, /* sq_ass_item; */
198 0, /* sq_ass_slice; */
199 0, /* sq_contains; */
200 0, /* sq_inplace_concat; */
201 0 /* sq_inplace_repeat; */
202};
203
204static PyMemberDef BaseException_members[] = {
205 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
206 PyDoc_STR("exception message")},
207 {NULL} /* Sentinel */
208};
209
210
211static PyObject *
212BaseException_get_dict(PyBaseExceptionObject *self)
213{
214 if (self->dict == NULL) {
215 self->dict = PyDict_New();
216 if (!self->dict)
217 return NULL;
218 }
219 Py_INCREF(self->dict);
220 return self->dict;
221}
222
223static int
224BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
225{
226 if (val == NULL) {
227 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
228 return -1;
229 }
230 if (!PyDict_Check(val)) {
231 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
232 return -1;
233 }
234 Py_CLEAR(self->dict);
235 Py_INCREF(val);
236 self->dict = val;
237 return 0;
238}
239
240static PyObject *
241BaseException_get_args(PyBaseExceptionObject *self)
242{
243 if (self->args == NULL) {
244 Py_INCREF(Py_None);
245 return Py_None;
246 }
247 Py_INCREF(self->args);
248 return self->args;
249}
250
251static int
252BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
253{
254 PyObject *seq;
255 if (val == NULL) {
256 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
257 return -1;
258 }
259 seq = PySequence_Tuple(val);
260 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000261 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000262 self->args = seq;
263 return 0;
264}
265
266static PyGetSetDef BaseException_getset[] = {
267 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
268 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
269 {NULL},
270};
271
272
273static PyTypeObject _PyExc_BaseException = {
274 PyObject_HEAD_INIT(NULL)
275 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000276 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
278 0, /*tp_itemsize*/
279 (destructor)BaseException_dealloc, /*tp_dealloc*/
280 0, /*tp_print*/
281 0, /*tp_getattr*/
282 0, /*tp_setattr*/
283 0, /* tp_compare; */
284 (reprfunc)BaseException_repr, /*tp_repr*/
285 0, /*tp_as_number*/
286 &BaseException_as_sequence, /*tp_as_sequence*/
287 0, /*tp_as_mapping*/
288 0, /*tp_hash */
289 0, /*tp_call*/
290 (reprfunc)BaseException_str, /*tp_str*/
291 PyObject_GenericGetAttr, /*tp_getattro*/
292 PyObject_GenericSetAttr, /*tp_setattro*/
293 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000294 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
295 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000296 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
297 (traverseproc)BaseException_traverse, /* tp_traverse */
298 (inquiry)BaseException_clear, /* tp_clear */
299 0, /* tp_richcompare */
300 0, /* tp_weaklistoffset */
301 0, /* tp_iter */
302 0, /* tp_iternext */
303 BaseException_methods, /* tp_methods */
304 BaseException_members, /* tp_members */
305 BaseException_getset, /* tp_getset */
306 0, /* tp_base */
307 0, /* tp_dict */
308 0, /* tp_descr_get */
309 0, /* tp_descr_set */
310 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
311 (initproc)BaseException_init, /* tp_init */
312 0, /* tp_alloc */
313 BaseException_new, /* tp_new */
314};
315/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
316from the previous implmentation and also allowing Python objects to be used
317in the API */
318PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
319
320/* note these macros omit the last semicolon so the macro invocation may
321 * include it and not look strange.
322 */
323#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
324static PyTypeObject _PyExc_ ## EXCNAME = { \
325 PyObject_HEAD_INIT(NULL) \
326 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000327 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328 sizeof(PyBaseExceptionObject), \
329 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
330 0, 0, 0, 0, 0, 0, 0, \
331 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
332 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
333 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
334 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
335 (initproc)BaseException_init, 0, BaseException_new,\
336}; \
337PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
338
339#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
340static PyTypeObject _PyExc_ ## EXCNAME = { \
341 PyObject_HEAD_INIT(NULL) \
342 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000343 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000345 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000346 0, 0, 0, 0, 0, \
347 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000348 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
349 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000350 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000351 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000352}; \
353PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
354
355#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
356static PyTypeObject _PyExc_ ## EXCNAME = { \
357 PyObject_HEAD_INIT(NULL) \
358 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000359 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000360 sizeof(Py ## EXCSTORE ## Object), 0, \
361 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
362 (reprfunc)EXCSTR, 0, 0, 0, \
363 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
364 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
365 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
366 EXCMEMBERS, 0, &_ ## EXCBASE, \
367 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000368 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369}; \
370PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
371
372
373/*
374 * Exception extends BaseException
375 */
376SimpleExtendsException(PyExc_BaseException, Exception,
377 "Common base class for all non-exit exceptions.");
378
379
380/*
381 * StandardError extends Exception
382 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000383SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000384 "Base class for all standard Python exceptions that do not represent\n"
385 "interpreter exiting.");
386
387
388/*
389 * TypeError extends StandardError
390 */
391SimpleExtendsException(PyExc_StandardError, TypeError,
392 "Inappropriate argument type.");
393
394
395/*
396 * StopIteration extends Exception
397 */
398SimpleExtendsException(PyExc_Exception, StopIteration,
399 "Signal the end from iterator.next().");
400
401
402/*
403 * GeneratorExit extends Exception
404 */
405SimpleExtendsException(PyExc_Exception, GeneratorExit,
406 "Request that a generator exit.");
407
408
409/*
410 * SystemExit extends BaseException
411 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000412
413static int
414SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
415{
416 Py_ssize_t size = PyTuple_GET_SIZE(args);
417
418 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
419 return -1;
420
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000421 if (size == 0)
422 return 0;
423 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000424 if (size == 1)
425 self->code = PyTuple_GET_ITEM(args, 0);
426 else if (size > 1)
427 self->code = args;
428 Py_INCREF(self->code);
429 return 0;
430}
431
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000432static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000433SystemExit_clear(PySystemExitObject *self)
434{
435 Py_CLEAR(self->code);
436 return BaseException_clear((PyBaseExceptionObject *)self);
437}
438
439static void
440SystemExit_dealloc(PySystemExitObject *self)
441{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000442 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443 SystemExit_clear(self);
444 self->ob_type->tp_free((PyObject *)self);
445}
446
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000447static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000448SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
449{
450 Py_VISIT(self->code);
451 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
452}
453
454static PyMemberDef SystemExit_members[] = {
455 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
456 PyDoc_STR("exception message")},
457 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
458 PyDoc_STR("exception code")},
459 {NULL} /* Sentinel */
460};
461
462ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
463 SystemExit_dealloc, 0, SystemExit_members, 0,
464 "Request to exit from the interpreter.");
465
466/*
467 * KeyboardInterrupt extends BaseException
468 */
469SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
470 "Program interrupted by user.");
471
472
473/*
474 * ImportError extends StandardError
475 */
476SimpleExtendsException(PyExc_StandardError, ImportError,
477 "Import can't find module, or can't find name in module.");
478
479
480/*
481 * EnvironmentError extends StandardError
482 */
483
Thomas Wouters477c8d52006-05-27 19:21:47 +0000484/* Where a function has a single filename, such as open() or some
485 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
486 * called, giving a third argument which is the filename. But, so
487 * that old code using in-place unpacking doesn't break, e.g.:
488 *
489 * except IOError, (errno, strerror):
490 *
491 * we hack args so that it only contains two items. This also
492 * means we need our own __str__() which prints out the filename
493 * when it was supplied.
494 */
495static int
496EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
497 PyObject *kwds)
498{
499 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
500 PyObject *subslice = NULL;
501
502 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
503 return -1;
504
Thomas Wouters89f507f2006-12-13 04:49:30 +0000505 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000506 return 0;
507 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000508
509 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510 &myerrno, &strerror, &filename)) {
511 return -1;
512 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000513 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000514 self->myerrno = myerrno;
515 Py_INCREF(self->myerrno);
516
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000517 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518 self->strerror = strerror;
519 Py_INCREF(self->strerror);
520
521 /* self->filename will remain Py_None otherwise */
522 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000523 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000524 self->filename = filename;
525 Py_INCREF(self->filename);
526
527 subslice = PyTuple_GetSlice(args, 0, 2);
528 if (!subslice)
529 return -1;
530
531 Py_DECREF(self->args); /* replacing args */
532 self->args = subslice;
533 }
534 return 0;
535}
536
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000537static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000538EnvironmentError_clear(PyEnvironmentErrorObject *self)
539{
540 Py_CLEAR(self->myerrno);
541 Py_CLEAR(self->strerror);
542 Py_CLEAR(self->filename);
543 return BaseException_clear((PyBaseExceptionObject *)self);
544}
545
546static void
547EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
548{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000549 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000550 EnvironmentError_clear(self);
551 self->ob_type->tp_free((PyObject *)self);
552}
553
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000554static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000555EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
556 void *arg)
557{
558 Py_VISIT(self->myerrno);
559 Py_VISIT(self->strerror);
560 Py_VISIT(self->filename);
561 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
562}
563
564static PyObject *
565EnvironmentError_str(PyEnvironmentErrorObject *self)
566{
567 PyObject *rtnval = NULL;
568
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000569 if (self->filename) {
570 PyObject *fmt;
571 PyObject *repr;
572 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000573
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000574 fmt = PyString_FromString("[Errno %s] %s: %s");
575 if (!fmt)
576 return NULL;
577
578 repr = PyObject_Repr(self->filename);
579 if (!repr) {
580 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000581 return NULL;
582 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000583 tuple = PyTuple_New(3);
584 if (!tuple) {
585 Py_DECREF(repr);
586 Py_DECREF(fmt);
587 return NULL;
588 }
589
590 if (self->myerrno) {
591 Py_INCREF(self->myerrno);
592 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
593 }
594 else {
595 Py_INCREF(Py_None);
596 PyTuple_SET_ITEM(tuple, 0, Py_None);
597 }
598 if (self->strerror) {
599 Py_INCREF(self->strerror);
600 PyTuple_SET_ITEM(tuple, 1, self->strerror);
601 }
602 else {
603 Py_INCREF(Py_None);
604 PyTuple_SET_ITEM(tuple, 1, Py_None);
605 }
606
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607 PyTuple_SET_ITEM(tuple, 2, repr);
608
609 rtnval = PyString_Format(fmt, tuple);
610
611 Py_DECREF(fmt);
612 Py_DECREF(tuple);
613 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000614 else if (self->myerrno && self->strerror) {
615 PyObject *fmt;
616 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000618 fmt = PyString_FromString("[Errno %s] %s");
619 if (!fmt)
620 return NULL;
621
622 tuple = PyTuple_New(2);
623 if (!tuple) {
624 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625 return NULL;
626 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000627
628 if (self->myerrno) {
629 Py_INCREF(self->myerrno);
630 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
631 }
632 else {
633 Py_INCREF(Py_None);
634 PyTuple_SET_ITEM(tuple, 0, Py_None);
635 }
636 if (self->strerror) {
637 Py_INCREF(self->strerror);
638 PyTuple_SET_ITEM(tuple, 1, self->strerror);
639 }
640 else {
641 Py_INCREF(Py_None);
642 PyTuple_SET_ITEM(tuple, 1, Py_None);
643 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000644
645 rtnval = PyString_Format(fmt, tuple);
646
647 Py_DECREF(fmt);
648 Py_DECREF(tuple);
649 }
650 else
651 rtnval = BaseException_str((PyBaseExceptionObject *)self);
652
653 return rtnval;
654}
655
656static PyMemberDef EnvironmentError_members[] = {
657 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
658 PyDoc_STR("exception message")},
659 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
660 PyDoc_STR("exception errno")},
661 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
662 PyDoc_STR("exception strerror")},
663 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
664 PyDoc_STR("exception filename")},
665 {NULL} /* Sentinel */
666};
667
668
669static PyObject *
670EnvironmentError_reduce(PyEnvironmentErrorObject *self)
671{
672 PyObject *args = self->args;
673 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000674
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675 /* self->args is only the first two real arguments if there was a
676 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000677 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678 args = PyTuple_New(3);
679 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000680
681 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000682 Py_INCREF(tmp);
683 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000684
685 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686 Py_INCREF(tmp);
687 PyTuple_SET_ITEM(args, 1, tmp);
688
689 Py_INCREF(self->filename);
690 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000691 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000693
694 if (self->dict)
695 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
696 else
697 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000698 Py_DECREF(args);
699 return res;
700}
701
702
703static PyMethodDef EnvironmentError_methods[] = {
704 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
705 {NULL}
706};
707
708ComplexExtendsException(PyExc_StandardError, EnvironmentError,
709 EnvironmentError, EnvironmentError_dealloc,
710 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000711 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000712 "Base class for I/O related errors.");
713
714
715/*
716 * IOError extends EnvironmentError
717 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000718MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719 EnvironmentError, "I/O operation failed.");
720
721
722/*
723 * OSError extends EnvironmentError
724 */
725MiddlingExtendsException(PyExc_EnvironmentError, OSError,
726 EnvironmentError, "OS system call failed.");
727
728
729/*
730 * WindowsError extends OSError
731 */
732#ifdef MS_WINDOWS
733#include "errmap.h"
734
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000735static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736WindowsError_clear(PyWindowsErrorObject *self)
737{
738 Py_CLEAR(self->myerrno);
739 Py_CLEAR(self->strerror);
740 Py_CLEAR(self->filename);
741 Py_CLEAR(self->winerror);
742 return BaseException_clear((PyBaseExceptionObject *)self);
743}
744
745static void
746WindowsError_dealloc(PyWindowsErrorObject *self)
747{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000748 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749 WindowsError_clear(self);
750 self->ob_type->tp_free((PyObject *)self);
751}
752
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000753static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000754WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
755{
756 Py_VISIT(self->myerrno);
757 Py_VISIT(self->strerror);
758 Py_VISIT(self->filename);
759 Py_VISIT(self->winerror);
760 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
761}
762
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763static int
764WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
765{
766 PyObject *o_errcode = NULL;
767 long errcode;
768 long posix_errno;
769
770 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
771 == -1)
772 return -1;
773
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000774 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000775 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776
777 /* Set errno to the POSIX errno, and winerror to the Win32
778 error code. */
779 errcode = PyInt_AsLong(self->myerrno);
780 if (errcode == -1 && PyErr_Occurred())
781 return -1;
782 posix_errno = winerror_to_errno(errcode);
783
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000784 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785 self->winerror = self->myerrno;
786
787 o_errcode = PyInt_FromLong(posix_errno);
788 if (!o_errcode)
789 return -1;
790
791 self->myerrno = o_errcode;
792
793 return 0;
794}
795
796
797static PyObject *
798WindowsError_str(PyWindowsErrorObject *self)
799{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000800 PyObject *rtnval = NULL;
801
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000802 if (self->filename) {
803 PyObject *fmt;
804 PyObject *repr;
805 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000806
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000807 fmt = PyString_FromString("[Error %s] %s: %s");
808 if (!fmt)
809 return NULL;
810
811 repr = PyObject_Repr(self->filename);
812 if (!repr) {
813 Py_DECREF(fmt);
814 return NULL;
815 }
816 tuple = PyTuple_New(3);
817 if (!tuple) {
818 Py_DECREF(repr);
819 Py_DECREF(fmt);
820 return NULL;
821 }
822
Thomas Wouters89f507f2006-12-13 04:49:30 +0000823 if (self->winerror) {
824 Py_INCREF(self->winerror);
825 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000826 }
827 else {
828 Py_INCREF(Py_None);
829 PyTuple_SET_ITEM(tuple, 0, Py_None);
830 }
831 if (self->strerror) {
832 Py_INCREF(self->strerror);
833 PyTuple_SET_ITEM(tuple, 1, self->strerror);
834 }
835 else {
836 Py_INCREF(Py_None);
837 PyTuple_SET_ITEM(tuple, 1, Py_None);
838 }
839
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000840 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000841
842 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000843
844 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845 Py_DECREF(tuple);
846 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000847 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000848 PyObject *fmt;
849 PyObject *tuple;
850
Thomas Wouters477c8d52006-05-27 19:21:47 +0000851 fmt = PyString_FromString("[Error %s] %s");
852 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000853 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000855 tuple = PyTuple_New(2);
856 if (!tuple) {
857 Py_DECREF(fmt);
858 return NULL;
859 }
860
Thomas Wouters89f507f2006-12-13 04:49:30 +0000861 if (self->winerror) {
862 Py_INCREF(self->winerror);
863 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000864 }
865 else {
866 Py_INCREF(Py_None);
867 PyTuple_SET_ITEM(tuple, 0, Py_None);
868 }
869 if (self->strerror) {
870 Py_INCREF(self->strerror);
871 PyTuple_SET_ITEM(tuple, 1, self->strerror);
872 }
873 else {
874 Py_INCREF(Py_None);
875 PyTuple_SET_ITEM(tuple, 1, Py_None);
876 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000877
878 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000879
880 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000881 Py_DECREF(tuple);
882 }
883 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000884 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000885
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886 return rtnval;
887}
888
889static PyMemberDef WindowsError_members[] = {
890 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
891 PyDoc_STR("exception message")},
892 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
893 PyDoc_STR("POSIX exception code")},
894 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
895 PyDoc_STR("exception strerror")},
896 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
897 PyDoc_STR("exception filename")},
898 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
899 PyDoc_STR("Win32 exception code")},
900 {NULL} /* Sentinel */
901};
902
903ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
904 WindowsError_dealloc, 0, WindowsError_members,
905 WindowsError_str, "MS-Windows OS system call failed.");
906
907#endif /* MS_WINDOWS */
908
909
910/*
911 * VMSError extends OSError (I think)
912 */
913#ifdef __VMS
914MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
915 "OpenVMS OS system call failed.");
916#endif
917
918
919/*
920 * EOFError extends StandardError
921 */
922SimpleExtendsException(PyExc_StandardError, EOFError,
923 "Read beyond end of file.");
924
925
926/*
927 * RuntimeError extends StandardError
928 */
929SimpleExtendsException(PyExc_StandardError, RuntimeError,
930 "Unspecified run-time error.");
931
932
933/*
934 * NotImplementedError extends RuntimeError
935 */
936SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
937 "Method or function hasn't been implemented yet.");
938
939/*
940 * NameError extends StandardError
941 */
942SimpleExtendsException(PyExc_StandardError, NameError,
943 "Name not found globally.");
944
945/*
946 * UnboundLocalError extends NameError
947 */
948SimpleExtendsException(PyExc_NameError, UnboundLocalError,
949 "Local name referenced but not bound to a value.");
950
951/*
952 * AttributeError extends StandardError
953 */
954SimpleExtendsException(PyExc_StandardError, AttributeError,
955 "Attribute not found.");
956
957
958/*
959 * SyntaxError extends StandardError
960 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000961
962static int
963SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
964{
965 PyObject *info = NULL;
966 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
967
968 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
969 return -1;
970
971 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000972 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000973 self->msg = PyTuple_GET_ITEM(args, 0);
974 Py_INCREF(self->msg);
975 }
976 if (lenargs == 2) {
977 info = PyTuple_GET_ITEM(args, 1);
978 info = PySequence_Tuple(info);
979 if (!info) return -1;
980
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000981 if (PyTuple_GET_SIZE(info) != 4) {
982 /* not a very good error message, but it's what Python 2.4 gives */
983 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
984 Py_DECREF(info);
985 return -1;
986 }
987
988 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000989 self->filename = PyTuple_GET_ITEM(info, 0);
990 Py_INCREF(self->filename);
991
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000992 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000993 self->lineno = PyTuple_GET_ITEM(info, 1);
994 Py_INCREF(self->lineno);
995
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000996 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997 self->offset = PyTuple_GET_ITEM(info, 2);
998 Py_INCREF(self->offset);
999
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001000 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001 self->text = PyTuple_GET_ITEM(info, 3);
1002 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001003
1004 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005 }
1006 return 0;
1007}
1008
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001009static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001010SyntaxError_clear(PySyntaxErrorObject *self)
1011{
1012 Py_CLEAR(self->msg);
1013 Py_CLEAR(self->filename);
1014 Py_CLEAR(self->lineno);
1015 Py_CLEAR(self->offset);
1016 Py_CLEAR(self->text);
1017 Py_CLEAR(self->print_file_and_line);
1018 return BaseException_clear((PyBaseExceptionObject *)self);
1019}
1020
1021static void
1022SyntaxError_dealloc(PySyntaxErrorObject *self)
1023{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001024 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025 SyntaxError_clear(self);
1026 self->ob_type->tp_free((PyObject *)self);
1027}
1028
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001029static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001030SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1031{
1032 Py_VISIT(self->msg);
1033 Py_VISIT(self->filename);
1034 Py_VISIT(self->lineno);
1035 Py_VISIT(self->offset);
1036 Py_VISIT(self->text);
1037 Py_VISIT(self->print_file_and_line);
1038 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1039}
1040
1041/* This is called "my_basename" instead of just "basename" to avoid name
1042 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1043 defined, and Python does define that. */
1044static char *
1045my_basename(char *name)
1046{
1047 char *cp = name;
1048 char *result = name;
1049
1050 if (name == NULL)
1051 return "???";
1052 while (*cp != '\0') {
1053 if (*cp == SEP)
1054 result = cp + 1;
1055 ++cp;
1056 }
1057 return result;
1058}
1059
1060
1061static PyObject *
1062SyntaxError_str(PySyntaxErrorObject *self)
1063{
1064 PyObject *str;
1065 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001066 int have_filename = 0;
1067 int have_lineno = 0;
1068 char *buffer = NULL;
1069 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001070
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001071 if (self->msg)
1072 str = PyObject_Str(self->msg);
1073 else
1074 str = PyObject_Str(Py_None);
1075 if (!str) return NULL;
1076 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1077 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001078
1079 /* XXX -- do all the additional formatting with filename and
1080 lineno here */
1081
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001082 have_filename = (self->filename != NULL) &&
1083 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001084 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001085
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001086 if (!have_filename && !have_lineno)
1087 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001088
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001089 bufsize = PyString_GET_SIZE(str) + 64;
1090 if (have_filename)
1091 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001092
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001093 buffer = PyMem_MALLOC(bufsize);
1094 if (buffer == NULL)
1095 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001096
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097 if (have_filename && have_lineno)
1098 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1099 PyString_AS_STRING(str),
1100 my_basename(PyString_AS_STRING(self->filename)),
1101 PyInt_AsLong(self->lineno));
1102 else if (have_filename)
1103 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1104 PyString_AS_STRING(str),
1105 my_basename(PyString_AS_STRING(self->filename)));
1106 else /* only have_lineno */
1107 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1108 PyString_AS_STRING(str),
1109 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001111 result = PyString_FromString(buffer);
1112 PyMem_FREE(buffer);
1113
1114 if (result == NULL)
1115 result = str;
1116 else
1117 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001118 return result;
1119}
1120
1121static PyMemberDef SyntaxError_members[] = {
1122 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1123 PyDoc_STR("exception message")},
1124 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1125 PyDoc_STR("exception msg")},
1126 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1127 PyDoc_STR("exception filename")},
1128 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1129 PyDoc_STR("exception lineno")},
1130 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1131 PyDoc_STR("exception offset")},
1132 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1133 PyDoc_STR("exception text")},
1134 {"print_file_and_line", T_OBJECT,
1135 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1136 PyDoc_STR("exception print_file_and_line")},
1137 {NULL} /* Sentinel */
1138};
1139
1140ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1141 SyntaxError_dealloc, 0, SyntaxError_members,
1142 SyntaxError_str, "Invalid syntax.");
1143
1144
1145/*
1146 * IndentationError extends SyntaxError
1147 */
1148MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1149 "Improper indentation.");
1150
1151
1152/*
1153 * TabError extends IndentationError
1154 */
1155MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1156 "Improper mixture of spaces and tabs.");
1157
1158
1159/*
1160 * LookupError extends StandardError
1161 */
1162SimpleExtendsException(PyExc_StandardError, LookupError,
1163 "Base class for lookup errors.");
1164
1165
1166/*
1167 * IndexError extends LookupError
1168 */
1169SimpleExtendsException(PyExc_LookupError, IndexError,
1170 "Sequence index out of range.");
1171
1172
1173/*
1174 * KeyError extends LookupError
1175 */
1176static PyObject *
1177KeyError_str(PyBaseExceptionObject *self)
1178{
1179 /* If args is a tuple of exactly one item, apply repr to args[0].
1180 This is done so that e.g. the exception raised by {}[''] prints
1181 KeyError: ''
1182 rather than the confusing
1183 KeyError
1184 alone. The downside is that if KeyError is raised with an explanatory
1185 string, that string will be displayed in quotes. Too bad.
1186 If args is anything else, use the default BaseException__str__().
1187 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001188 if (PyTuple_GET_SIZE(self->args) == 1) {
1189 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001190 }
1191 return BaseException_str(self);
1192}
1193
1194ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1195 0, 0, 0, KeyError_str, "Mapping key not found.");
1196
1197
1198/*
1199 * ValueError extends StandardError
1200 */
1201SimpleExtendsException(PyExc_StandardError, ValueError,
1202 "Inappropriate argument value (of correct type).");
1203
1204/*
1205 * UnicodeError extends ValueError
1206 */
1207
1208SimpleExtendsException(PyExc_ValueError, UnicodeError,
1209 "Unicode related error.");
1210
1211#ifdef Py_USING_UNICODE
1212static int
1213get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1214{
1215 if (!attr) {
1216 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1217 return -1;
1218 }
1219
Guido van Rossumddefaf32007-01-14 03:31:43 +00001220 if (PyLong_Check(attr)) {
1221 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001222 if (*value == -1 && PyErr_Occurred())
1223 return -1;
1224 } else {
1225 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1226 return -1;
1227 }
1228 return 0;
1229}
1230
1231static int
1232set_ssize_t(PyObject **attr, Py_ssize_t value)
1233{
1234 PyObject *obj = PyInt_FromSsize_t(value);
1235 if (!obj)
1236 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001237 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001238 *attr = obj;
1239 return 0;
1240}
1241
1242static PyObject *
1243get_string(PyObject *attr, const char *name)
1244{
1245 if (!attr) {
1246 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1247 return NULL;
1248 }
1249
1250 if (!PyString_Check(attr)) {
1251 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1252 return NULL;
1253 }
1254 Py_INCREF(attr);
1255 return attr;
1256}
1257
1258
1259static int
1260set_string(PyObject **attr, const char *value)
1261{
1262 PyObject *obj = PyString_FromString(value);
1263 if (!obj)
1264 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001265 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001266 *attr = obj;
1267 return 0;
1268}
1269
1270
1271static PyObject *
1272get_unicode(PyObject *attr, const char *name)
1273{
1274 if (!attr) {
1275 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1276 return NULL;
1277 }
1278
1279 if (!PyUnicode_Check(attr)) {
1280 PyErr_Format(PyExc_TypeError,
1281 "%.200s attribute must be unicode", name);
1282 return NULL;
1283 }
1284 Py_INCREF(attr);
1285 return attr;
1286}
1287
1288PyObject *
1289PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1290{
1291 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1292}
1293
1294PyObject *
1295PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1296{
1297 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1298}
1299
1300PyObject *
1301PyUnicodeEncodeError_GetObject(PyObject *exc)
1302{
1303 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1304}
1305
1306PyObject *
1307PyUnicodeDecodeError_GetObject(PyObject *exc)
1308{
1309 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1310}
1311
1312PyObject *
1313PyUnicodeTranslateError_GetObject(PyObject *exc)
1314{
1315 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1316}
1317
1318int
1319PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1320{
1321 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1322 Py_ssize_t size;
1323 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1324 "object");
1325 if (!obj) return -1;
1326 size = PyUnicode_GET_SIZE(obj);
1327 if (*start<0)
1328 *start = 0; /*XXX check for values <0*/
1329 if (*start>=size)
1330 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001331 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332 return 0;
1333 }
1334 return -1;
1335}
1336
1337
1338int
1339PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1340{
1341 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1342 Py_ssize_t size;
1343 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1344 "object");
1345 if (!obj) return -1;
1346 size = PyString_GET_SIZE(obj);
1347 if (*start<0)
1348 *start = 0;
1349 if (*start>=size)
1350 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001351 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352 return 0;
1353 }
1354 return -1;
1355}
1356
1357
1358int
1359PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1360{
1361 return PyUnicodeEncodeError_GetStart(exc, start);
1362}
1363
1364
1365int
1366PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1367{
1368 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1369}
1370
1371
1372int
1373PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1374{
1375 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1376}
1377
1378
1379int
1380PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1381{
1382 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1383}
1384
1385
1386int
1387PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1388{
1389 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1390 Py_ssize_t size;
1391 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1392 "object");
1393 if (!obj) return -1;
1394 size = PyUnicode_GET_SIZE(obj);
1395 if (*end<1)
1396 *end = 1;
1397 if (*end>size)
1398 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001399 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400 return 0;
1401 }
1402 return -1;
1403}
1404
1405
1406int
1407PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1408{
1409 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1410 Py_ssize_t size;
1411 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1412 "object");
1413 if (!obj) return -1;
1414 size = PyString_GET_SIZE(obj);
1415 if (*end<1)
1416 *end = 1;
1417 if (*end>size)
1418 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001419 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001420 return 0;
1421 }
1422 return -1;
1423}
1424
1425
1426int
1427PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1428{
1429 return PyUnicodeEncodeError_GetEnd(exc, start);
1430}
1431
1432
1433int
1434PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1435{
1436 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1437}
1438
1439
1440int
1441PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1442{
1443 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1444}
1445
1446
1447int
1448PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1449{
1450 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1451}
1452
1453PyObject *
1454PyUnicodeEncodeError_GetReason(PyObject *exc)
1455{
1456 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1457}
1458
1459
1460PyObject *
1461PyUnicodeDecodeError_GetReason(PyObject *exc)
1462{
1463 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1464}
1465
1466
1467PyObject *
1468PyUnicodeTranslateError_GetReason(PyObject *exc)
1469{
1470 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1471}
1472
1473
1474int
1475PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1476{
1477 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1478}
1479
1480
1481int
1482PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1483{
1484 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1485}
1486
1487
1488int
1489PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1490{
1491 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1492}
1493
1494
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495static int
1496UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1497 PyTypeObject *objecttype)
1498{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001499 Py_CLEAR(self->encoding);
1500 Py_CLEAR(self->object);
1501 Py_CLEAR(self->start);
1502 Py_CLEAR(self->end);
1503 Py_CLEAR(self->reason);
1504
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1506 &PyString_Type, &self->encoding,
1507 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001508 &PyLong_Type, &self->start,
1509 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001511 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512 self->reason = NULL;
1513 return -1;
1514 }
1515
1516 Py_INCREF(self->encoding);
1517 Py_INCREF(self->object);
1518 Py_INCREF(self->start);
1519 Py_INCREF(self->end);
1520 Py_INCREF(self->reason);
1521
1522 return 0;
1523}
1524
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001525static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526UnicodeError_clear(PyUnicodeErrorObject *self)
1527{
1528 Py_CLEAR(self->encoding);
1529 Py_CLEAR(self->object);
1530 Py_CLEAR(self->start);
1531 Py_CLEAR(self->end);
1532 Py_CLEAR(self->reason);
1533 return BaseException_clear((PyBaseExceptionObject *)self);
1534}
1535
1536static void
1537UnicodeError_dealloc(PyUnicodeErrorObject *self)
1538{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001539 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540 UnicodeError_clear(self);
1541 self->ob_type->tp_free((PyObject *)self);
1542}
1543
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001544static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1546{
1547 Py_VISIT(self->encoding);
1548 Py_VISIT(self->object);
1549 Py_VISIT(self->start);
1550 Py_VISIT(self->end);
1551 Py_VISIT(self->reason);
1552 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1553}
1554
1555static PyMemberDef UnicodeError_members[] = {
1556 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1557 PyDoc_STR("exception message")},
1558 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1559 PyDoc_STR("exception encoding")},
1560 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1561 PyDoc_STR("exception object")},
1562 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1563 PyDoc_STR("exception start")},
1564 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1565 PyDoc_STR("exception end")},
1566 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1567 PyDoc_STR("exception reason")},
1568 {NULL} /* Sentinel */
1569};
1570
1571
1572/*
1573 * UnicodeEncodeError extends UnicodeError
1574 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001575
1576static int
1577UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1578{
1579 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1580 return -1;
1581 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1582 kwds, &PyUnicode_Type);
1583}
1584
1585static PyObject *
1586UnicodeEncodeError_str(PyObject *self)
1587{
1588 Py_ssize_t start;
1589 Py_ssize_t end;
1590
1591 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001592 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001593
1594 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001595 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001596
1597 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001598 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1599 char badchar_str[20];
1600 if (badchar <= 0xff)
1601 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1602 else if (badchar <= 0xffff)
1603 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1604 else
1605 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1606 return PyString_FromFormat(
1607 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1608 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1609 badchar_str,
1610 start,
1611 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1612 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001613 }
1614 return PyString_FromFormat(
1615 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1616 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1617 start,
1618 (end-1),
1619 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1620 );
1621}
1622
1623static PyTypeObject _PyExc_UnicodeEncodeError = {
1624 PyObject_HEAD_INIT(NULL)
1625 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001626 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627 sizeof(PyUnicodeErrorObject), 0,
1628 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1629 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1630 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001631 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1632 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001634 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635};
1636PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1637
1638PyObject *
1639PyUnicodeEncodeError_Create(
1640 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1641 Py_ssize_t start, Py_ssize_t end, const char *reason)
1642{
1643 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001644 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645}
1646
1647
1648/*
1649 * UnicodeDecodeError extends UnicodeError
1650 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651
1652static int
1653UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1654{
1655 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1656 return -1;
1657 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1658 kwds, &PyString_Type);
1659}
1660
1661static PyObject *
1662UnicodeDecodeError_str(PyObject *self)
1663{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001664 Py_ssize_t start = 0;
1665 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001666
1667 if (PyUnicodeDecodeError_GetStart(self, &start))
1668 return NULL;
1669
1670 if (PyUnicodeDecodeError_GetEnd(self, &end))
1671 return NULL;
1672
1673 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001674 /* FromFormat does not support %02x, so format that separately */
1675 char byte[4];
1676 PyOS_snprintf(byte, sizeof(byte), "%02x",
1677 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1678 return PyString_FromFormat(
1679 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1680 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1681 byte,
1682 start,
1683 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1684 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685 }
1686 return PyString_FromFormat(
1687 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1688 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1689 start,
1690 (end-1),
1691 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1692 );
1693}
1694
1695static PyTypeObject _PyExc_UnicodeDecodeError = {
1696 PyObject_HEAD_INIT(NULL)
1697 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001698 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001699 sizeof(PyUnicodeErrorObject), 0,
1700 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1701 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1702 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001703 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1704 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001706 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707};
1708PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1709
1710PyObject *
1711PyUnicodeDecodeError_Create(
1712 const char *encoding, const char *object, Py_ssize_t length,
1713 Py_ssize_t start, Py_ssize_t end, const char *reason)
1714{
1715 assert(length < INT_MAX);
1716 assert(start < INT_MAX);
1717 assert(end < INT_MAX);
1718 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001719 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720}
1721
1722
1723/*
1724 * UnicodeTranslateError extends UnicodeError
1725 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726
1727static int
1728UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1729 PyObject *kwds)
1730{
1731 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1732 return -1;
1733
1734 Py_CLEAR(self->object);
1735 Py_CLEAR(self->start);
1736 Py_CLEAR(self->end);
1737 Py_CLEAR(self->reason);
1738
1739 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1740 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001741 &PyLong_Type, &self->start,
1742 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001743 &PyString_Type, &self->reason)) {
1744 self->object = self->start = self->end = self->reason = NULL;
1745 return -1;
1746 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001747
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748 Py_INCREF(self->object);
1749 Py_INCREF(self->start);
1750 Py_INCREF(self->end);
1751 Py_INCREF(self->reason);
1752
1753 return 0;
1754}
1755
1756
1757static PyObject *
1758UnicodeTranslateError_str(PyObject *self)
1759{
1760 Py_ssize_t start;
1761 Py_ssize_t end;
1762
1763 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001764 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001765
1766 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001767 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001768
1769 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001770 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1771 char badchar_str[20];
1772 if (badchar <= 0xff)
1773 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1774 else if (badchar <= 0xffff)
1775 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1776 else
1777 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1778 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001780 badchar_str,
1781 start,
1782 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1783 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001784 }
1785 return PyString_FromFormat(
1786 "can't translate characters in position %zd-%zd: %.400s",
1787 start,
1788 (end-1),
1789 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1790 );
1791}
1792
1793static PyTypeObject _PyExc_UnicodeTranslateError = {
1794 PyObject_HEAD_INIT(NULL)
1795 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001796 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001797 sizeof(PyUnicodeErrorObject), 0,
1798 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1799 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1800 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001801 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001802 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1803 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001804 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001805};
1806PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1807
1808PyObject *
1809PyUnicodeTranslateError_Create(
1810 const Py_UNICODE *object, Py_ssize_t length,
1811 Py_ssize_t start, Py_ssize_t end, const char *reason)
1812{
1813 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001814 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001815}
1816#endif
1817
1818
1819/*
1820 * AssertionError extends StandardError
1821 */
1822SimpleExtendsException(PyExc_StandardError, AssertionError,
1823 "Assertion failed.");
1824
1825
1826/*
1827 * ArithmeticError extends StandardError
1828 */
1829SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1830 "Base class for arithmetic errors.");
1831
1832
1833/*
1834 * FloatingPointError extends ArithmeticError
1835 */
1836SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1837 "Floating point operation failed.");
1838
1839
1840/*
1841 * OverflowError extends ArithmeticError
1842 */
1843SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1844 "Result too large to be represented.");
1845
1846
1847/*
1848 * ZeroDivisionError extends ArithmeticError
1849 */
1850SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1851 "Second argument to a division or modulo operation was zero.");
1852
1853
1854/*
1855 * SystemError extends StandardError
1856 */
1857SimpleExtendsException(PyExc_StandardError, SystemError,
1858 "Internal error in the Python interpreter.\n"
1859 "\n"
1860 "Please report this to the Python maintainer, along with the traceback,\n"
1861 "the Python version, and the hardware/OS platform and version.");
1862
1863
1864/*
1865 * ReferenceError extends StandardError
1866 */
1867SimpleExtendsException(PyExc_StandardError, ReferenceError,
1868 "Weak ref proxy used after referent went away.");
1869
1870
1871/*
1872 * MemoryError extends StandardError
1873 */
1874SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1875
1876
1877/* Warning category docstrings */
1878
1879/*
1880 * Warning extends Exception
1881 */
1882SimpleExtendsException(PyExc_Exception, Warning,
1883 "Base class for warning categories.");
1884
1885
1886/*
1887 * UserWarning extends Warning
1888 */
1889SimpleExtendsException(PyExc_Warning, UserWarning,
1890 "Base class for warnings generated by user code.");
1891
1892
1893/*
1894 * DeprecationWarning extends Warning
1895 */
1896SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1897 "Base class for warnings about deprecated features.");
1898
1899
1900/*
1901 * PendingDeprecationWarning extends Warning
1902 */
1903SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1904 "Base class for warnings about features which will be deprecated\n"
1905 "in the future.");
1906
1907
1908/*
1909 * SyntaxWarning extends Warning
1910 */
1911SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1912 "Base class for warnings about dubious syntax.");
1913
1914
1915/*
1916 * RuntimeWarning extends Warning
1917 */
1918SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1919 "Base class for warnings about dubious runtime behavior.");
1920
1921
1922/*
1923 * FutureWarning extends Warning
1924 */
1925SimpleExtendsException(PyExc_Warning, FutureWarning,
1926 "Base class for warnings about constructs that will change semantically\n"
1927 "in the future.");
1928
1929
1930/*
1931 * ImportWarning extends Warning
1932 */
1933SimpleExtendsException(PyExc_Warning, ImportWarning,
1934 "Base class for warnings about probable mistakes in module imports");
1935
1936
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001937/*
1938 * UnicodeWarning extends Warning
1939 */
1940SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1941 "Base class for warnings about Unicode related problems, mostly\n"
1942 "related to conversion problems.");
1943
1944
Thomas Wouters477c8d52006-05-27 19:21:47 +00001945/* Pre-computed MemoryError instance. Best to create this as early as
1946 * possible and not wait until a MemoryError is actually raised!
1947 */
1948PyObject *PyExc_MemoryErrorInst=NULL;
1949
Thomas Wouters477c8d52006-05-27 19:21:47 +00001950#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1951 Py_FatalError("exceptions bootstrapping error.");
1952
1953#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001954 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1955 Py_FatalError("Module dictionary insertion problem.");
1956
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001957#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1958/* crt variable checking in VisualStudio .NET 2005 */
1959#include <crtdbg.h>
1960
1961static int prevCrtReportMode;
1962static _invalid_parameter_handler prevCrtHandler;
1963
1964/* Invalid parameter handler. Sets a ValueError exception */
1965static void
1966InvalidParameterHandler(
1967 const wchar_t * expression,
1968 const wchar_t * function,
1969 const wchar_t * file,
1970 unsigned int line,
1971 uintptr_t pReserved)
1972{
1973 /* Do nothing, allow execution to continue. Usually this
1974 * means that the CRT will set errno to EINVAL
1975 */
1976}
1977#endif
1978
1979
Thomas Wouters477c8d52006-05-27 19:21:47 +00001980PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001981_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001982{
Neal Norwitz2633c692007-02-26 22:22:47 +00001983 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984
1985 PRE_INIT(BaseException)
1986 PRE_INIT(Exception)
1987 PRE_INIT(StandardError)
1988 PRE_INIT(TypeError)
1989 PRE_INIT(StopIteration)
1990 PRE_INIT(GeneratorExit)
1991 PRE_INIT(SystemExit)
1992 PRE_INIT(KeyboardInterrupt)
1993 PRE_INIT(ImportError)
1994 PRE_INIT(EnvironmentError)
1995 PRE_INIT(IOError)
1996 PRE_INIT(OSError)
1997#ifdef MS_WINDOWS
1998 PRE_INIT(WindowsError)
1999#endif
2000#ifdef __VMS
2001 PRE_INIT(VMSError)
2002#endif
2003 PRE_INIT(EOFError)
2004 PRE_INIT(RuntimeError)
2005 PRE_INIT(NotImplementedError)
2006 PRE_INIT(NameError)
2007 PRE_INIT(UnboundLocalError)
2008 PRE_INIT(AttributeError)
2009 PRE_INIT(SyntaxError)
2010 PRE_INIT(IndentationError)
2011 PRE_INIT(TabError)
2012 PRE_INIT(LookupError)
2013 PRE_INIT(IndexError)
2014 PRE_INIT(KeyError)
2015 PRE_INIT(ValueError)
2016 PRE_INIT(UnicodeError)
2017#ifdef Py_USING_UNICODE
2018 PRE_INIT(UnicodeEncodeError)
2019 PRE_INIT(UnicodeDecodeError)
2020 PRE_INIT(UnicodeTranslateError)
2021#endif
2022 PRE_INIT(AssertionError)
2023 PRE_INIT(ArithmeticError)
2024 PRE_INIT(FloatingPointError)
2025 PRE_INIT(OverflowError)
2026 PRE_INIT(ZeroDivisionError)
2027 PRE_INIT(SystemError)
2028 PRE_INIT(ReferenceError)
2029 PRE_INIT(MemoryError)
2030 PRE_INIT(Warning)
2031 PRE_INIT(UserWarning)
2032 PRE_INIT(DeprecationWarning)
2033 PRE_INIT(PendingDeprecationWarning)
2034 PRE_INIT(SyntaxWarning)
2035 PRE_INIT(RuntimeWarning)
2036 PRE_INIT(FutureWarning)
2037 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002038 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002039
Thomas Wouters477c8d52006-05-27 19:21:47 +00002040 bltinmod = PyImport_ImportModule("__builtin__");
2041 if (bltinmod == NULL)
2042 Py_FatalError("exceptions bootstrapping error.");
2043 bdict = PyModule_GetDict(bltinmod);
2044 if (bdict == NULL)
2045 Py_FatalError("exceptions bootstrapping error.");
2046
2047 POST_INIT(BaseException)
2048 POST_INIT(Exception)
2049 POST_INIT(StandardError)
2050 POST_INIT(TypeError)
2051 POST_INIT(StopIteration)
2052 POST_INIT(GeneratorExit)
2053 POST_INIT(SystemExit)
2054 POST_INIT(KeyboardInterrupt)
2055 POST_INIT(ImportError)
2056 POST_INIT(EnvironmentError)
2057 POST_INIT(IOError)
2058 POST_INIT(OSError)
2059#ifdef MS_WINDOWS
2060 POST_INIT(WindowsError)
2061#endif
2062#ifdef __VMS
2063 POST_INIT(VMSError)
2064#endif
2065 POST_INIT(EOFError)
2066 POST_INIT(RuntimeError)
2067 POST_INIT(NotImplementedError)
2068 POST_INIT(NameError)
2069 POST_INIT(UnboundLocalError)
2070 POST_INIT(AttributeError)
2071 POST_INIT(SyntaxError)
2072 POST_INIT(IndentationError)
2073 POST_INIT(TabError)
2074 POST_INIT(LookupError)
2075 POST_INIT(IndexError)
2076 POST_INIT(KeyError)
2077 POST_INIT(ValueError)
2078 POST_INIT(UnicodeError)
2079#ifdef Py_USING_UNICODE
2080 POST_INIT(UnicodeEncodeError)
2081 POST_INIT(UnicodeDecodeError)
2082 POST_INIT(UnicodeTranslateError)
2083#endif
2084 POST_INIT(AssertionError)
2085 POST_INIT(ArithmeticError)
2086 POST_INIT(FloatingPointError)
2087 POST_INIT(OverflowError)
2088 POST_INIT(ZeroDivisionError)
2089 POST_INIT(SystemError)
2090 POST_INIT(ReferenceError)
2091 POST_INIT(MemoryError)
2092 POST_INIT(Warning)
2093 POST_INIT(UserWarning)
2094 POST_INIT(DeprecationWarning)
2095 POST_INIT(PendingDeprecationWarning)
2096 POST_INIT(SyntaxWarning)
2097 POST_INIT(RuntimeWarning)
2098 POST_INIT(FutureWarning)
2099 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002100 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101
2102 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2103 if (!PyExc_MemoryErrorInst)
2104 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2105
2106 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002107
2108#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2109 /* Set CRT argument error handler */
2110 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2111 /* turn off assertions in debug mode */
2112 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2113#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002114}
2115
2116void
2117_PyExc_Fini(void)
2118{
2119 Py_XDECREF(PyExc_MemoryErrorInst);
2120 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002121#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2122 /* reset CRT error handling */
2123 _set_invalid_parameter_handler(prevCrtHandler);
2124 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2125#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002126}