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