blob: 16ba5e56c269111802e2f27a33fd63d24d7c097f [file] [log] [blame]
Georg Brandl43ab1002006-05-28 20:57:09 +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
Richard Jones7b9558d2006-05-27 12:29:24 +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
Richard Jonesc5b2a2e2006-05-27 16:07:28 +000015/* 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
Richard Jones7b9558d2006-05-27 12:29:24 +000027/*
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
Michael W. Hudson22a80e72006-05-28 15:51:40 +000045 self->message = PyString_FromString("");
Richard Jones7b9558d2006-05-27 12:29:24 +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{
57 Py_DECREF(self->args);
58 self->args = args;
59 Py_INCREF(self->args);
60
61 if (PyTuple_GET_SIZE(self->args) == 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +000062 Py_CLEAR(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000063 self->message = PyTuple_GET_ITEM(self->args, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +000064 Py_INCREF(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000065 }
66 return 0;
67}
68
Michael W. Hudson96495ee2006-05-28 17:40:29 +000069static int
Richard Jones7b9558d2006-05-27 12:29:24 +000070BaseException_clear(PyBaseExceptionObject *self)
71{
72 Py_CLEAR(self->dict);
73 Py_CLEAR(self->args);
74 Py_CLEAR(self->message);
75 return 0;
76}
77
78static void
79BaseException_dealloc(PyBaseExceptionObject *self)
80{
81 BaseException_clear(self);
82 self->ob_type->tp_free((PyObject *)self);
83}
84
Michael W. Hudson96495ee2006-05-28 17:40:29 +000085static int
Richard Jones7b9558d2006-05-27 12:29:24 +000086BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
87{
Michael W. Hudson22a80e72006-05-28 15:51:40 +000088 Py_VISIT(self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +000089 Py_VISIT(self->args);
90 Py_VISIT(self->message);
91 return 0;
92}
93
94static PyObject *
95BaseException_str(PyBaseExceptionObject *self)
96{
97 PyObject *out;
98
Michael W. Hudson22a80e72006-05-28 15:51:40 +000099 switch (PyTuple_GET_SIZE(self->args)) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000100 case 0:
101 out = PyString_FromString("");
102 break;
103 case 1:
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000104 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000105 break;
Richard Jones7b9558d2006-05-27 12:29:24 +0000106 default:
107 out = PyObject_Str(self->args);
108 break;
109 }
110
111 return out;
112}
113
114static PyObject *
115BaseException_repr(PyBaseExceptionObject *self)
116{
Richard Jones7b9558d2006-05-27 12:29:24 +0000117 PyObject *repr_suffix;
118 PyObject *repr;
119 char *name;
120 char *dot;
121
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000122 repr_suffix = PyObject_Repr(self->args);
123 if (!repr_suffix)
Richard Jones7b9558d2006-05-27 12:29:24 +0000124 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000125
126 name = (char *)self->ob_type->tp_name;
127 dot = strrchr(name, '.');
128 if (dot != NULL) name = dot+1;
129
130 repr = PyString_FromString(name);
131 if (!repr) {
132 Py_DECREF(repr_suffix);
133 return NULL;
134 }
135
136 PyString_ConcatAndDel(&repr, repr_suffix);
137 return repr;
138}
139
140/* Pickling support */
141static PyObject *
142BaseException_reduce(PyBaseExceptionObject *self)
143{
Georg Brandlddba4732006-05-30 07:04:55 +0000144 if (self->args && self->dict)
145 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000146 else
Georg Brandlddba4732006-05-30 07:04:55 +0000147 return PyTuple_Pack(2, self->ob_type, self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000148}
149
150
151#ifdef Py_USING_UNICODE
152/* while this method generates fairly uninspired output, it a least
153 * guarantees that we can display exceptions that have unicode attributes
154 */
155static PyObject *
156BaseException_unicode(PyBaseExceptionObject *self)
157{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000158 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000159 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000160 if (PyTuple_GET_SIZE(self->args) == 1)
161 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000162 return PyObject_Unicode(self->args);
163}
164#endif /* Py_USING_UNICODE */
165
166static PyMethodDef BaseException_methods[] = {
167 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
168#ifdef Py_USING_UNICODE
169 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
170#endif
171 {NULL, NULL, 0, NULL},
172};
173
174
175
176static PyObject *
177BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
178{
179 return PySequence_GetItem(self->args, index);
180}
181
182static PySequenceMethods BaseException_as_sequence = {
183 0, /* sq_length; */
184 0, /* sq_concat; */
185 0, /* sq_repeat; */
186 (ssizeargfunc)BaseException_getitem, /* sq_item; */
187 0, /* sq_slice; */
188 0, /* sq_ass_item; */
189 0, /* sq_ass_slice; */
190 0, /* sq_contains; */
191 0, /* sq_inplace_concat; */
192 0 /* sq_inplace_repeat; */
193};
194
195static PyMemberDef BaseException_members[] = {
196 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
197 PyDoc_STR("exception message")},
198 {NULL} /* Sentinel */
199};
200
201
202static PyObject *
203BaseException_get_dict(PyBaseExceptionObject *self)
204{
205 if (self->dict == NULL) {
206 self->dict = PyDict_New();
207 if (!self->dict)
208 return NULL;
209 }
210 Py_INCREF(self->dict);
211 return self->dict;
212}
213
214static int
215BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
216{
217 if (val == NULL) {
218 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
219 return -1;
220 }
221 if (!PyDict_Check(val)) {
222 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
223 return -1;
224 }
225 Py_CLEAR(self->dict);
226 Py_INCREF(val);
227 self->dict = val;
228 return 0;
229}
230
231static PyObject *
232BaseException_get_args(PyBaseExceptionObject *self)
233{
234 if (self->args == NULL) {
235 Py_INCREF(Py_None);
236 return Py_None;
237 }
238 Py_INCREF(self->args);
239 return self->args;
240}
241
242static int
243BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
244{
245 PyObject *seq;
246 if (val == NULL) {
247 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
248 return -1;
249 }
250 seq = PySequence_Tuple(val);
251 if (!seq) return -1;
Georg Brandlc7c51142006-05-29 09:46:51 +0000252 Py_CLEAR(self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000253 self->args = seq;
254 return 0;
255}
256
257static PyGetSetDef BaseException_getset[] = {
258 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
259 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
260 {NULL},
261};
262
263
264static PyTypeObject _PyExc_BaseException = {
265 PyObject_HEAD_INIT(NULL)
266 0, /*ob_size*/
267 EXC_MODULE_NAME "BaseException", /*tp_name*/
268 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
269 0, /*tp_itemsize*/
270 (destructor)BaseException_dealloc, /*tp_dealloc*/
271 0, /*tp_print*/
272 0, /*tp_getattr*/
273 0, /*tp_setattr*/
274 0, /* tp_compare; */
275 (reprfunc)BaseException_repr, /*tp_repr*/
276 0, /*tp_as_number*/
277 &BaseException_as_sequence, /*tp_as_sequence*/
278 0, /*tp_as_mapping*/
279 0, /*tp_hash */
280 0, /*tp_call*/
281 (reprfunc)BaseException_str, /*tp_str*/
282 PyObject_GenericGetAttr, /*tp_getattro*/
283 PyObject_GenericSetAttr, /*tp_setattro*/
284 0, /*tp_as_buffer*/
285 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
286 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
287 (traverseproc)BaseException_traverse, /* tp_traverse */
288 (inquiry)BaseException_clear, /* tp_clear */
289 0, /* tp_richcompare */
290 0, /* tp_weaklistoffset */
291 0, /* tp_iter */
292 0, /* tp_iternext */
293 BaseException_methods, /* tp_methods */
294 BaseException_members, /* tp_members */
295 BaseException_getset, /* tp_getset */
296 0, /* tp_base */
297 0, /* tp_dict */
298 0, /* tp_descr_get */
299 0, /* tp_descr_set */
300 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
301 (initproc)BaseException_init, /* tp_init */
302 0, /* tp_alloc */
303 BaseException_new, /* tp_new */
304};
305/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
306from the previous implmentation and also allowing Python objects to be used
307in the API */
308PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
309
Richard Jones2d555b32006-05-27 16:15:11 +0000310/* note these macros omit the last semicolon so the macro invocation may
311 * include it and not look strange.
312 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000313#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
314static PyTypeObject _PyExc_ ## EXCNAME = { \
315 PyObject_HEAD_INIT(NULL) \
316 0, \
317 EXC_MODULE_NAME # EXCNAME, \
318 sizeof(PyBaseExceptionObject), \
319 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
320 0, 0, 0, 0, 0, 0, 0, \
321 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
322 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
323 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
324 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
325 (initproc)BaseException_init, 0, BaseException_new,\
326}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000327PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000328
329#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
330static PyTypeObject _PyExc_ ## EXCNAME = { \
331 PyObject_HEAD_INIT(NULL) \
332 0, \
333 EXC_MODULE_NAME # EXCNAME, \
334 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000335 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000336 0, 0, 0, 0, 0, \
337 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000338 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
339 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000340 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000341 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000342}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000343PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000344
345#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
346static PyTypeObject _PyExc_ ## EXCNAME = { \
347 PyObject_HEAD_INIT(NULL) \
348 0, \
349 EXC_MODULE_NAME # EXCNAME, \
350 sizeof(Py ## EXCSTORE ## Object), 0, \
351 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
352 (reprfunc)EXCSTR, 0, 0, 0, \
353 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
354 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
355 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
356 EXCMEMBERS, 0, &_ ## EXCBASE, \
357 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000358 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000359}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000360PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000361
362
363/*
364 * Exception extends BaseException
365 */
366SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000367 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000368
369
370/*
371 * StandardError extends Exception
372 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000373SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000374 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000375 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000376
377
378/*
379 * TypeError extends StandardError
380 */
381SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000382 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000383
384
385/*
386 * StopIteration extends Exception
387 */
388SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000389 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000390
391
392/*
393 * GeneratorExit extends Exception
394 */
395SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000396 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000397
398
399/*
400 * SystemExit extends BaseException
401 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000402
403static int
404SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
405{
406 Py_ssize_t size = PyTuple_GET_SIZE(args);
407
408 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
409 return -1;
410
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000411 if (size == 0)
412 return 0;
413 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000414 if (size == 1)
415 self->code = PyTuple_GET_ITEM(args, 0);
416 else if (size > 1)
417 self->code = args;
418 Py_INCREF(self->code);
419 return 0;
420}
421
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000422static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000423SystemExit_clear(PySystemExitObject *self)
424{
425 Py_CLEAR(self->code);
426 return BaseException_clear((PyBaseExceptionObject *)self);
427}
428
429static void
430SystemExit_dealloc(PySystemExitObject *self)
431{
432 SystemExit_clear(self);
433 self->ob_type->tp_free((PyObject *)self);
434}
435
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000436static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000437SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
438{
439 Py_VISIT(self->code);
440 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
441}
442
443static PyMemberDef SystemExit_members[] = {
444 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
445 PyDoc_STR("exception message")},
446 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
447 PyDoc_STR("exception code")},
448 {NULL} /* Sentinel */
449};
450
451ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
452 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000453 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000454
455/*
456 * KeyboardInterrupt extends BaseException
457 */
458SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000459 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000460
461
462/*
463 * ImportError extends StandardError
464 */
465SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000466 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000467
468
469/*
470 * EnvironmentError extends StandardError
471 */
472
Richard Jones7b9558d2006-05-27 12:29:24 +0000473/* Where a function has a single filename, such as open() or some
474 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
475 * called, giving a third argument which is the filename. But, so
476 * that old code using in-place unpacking doesn't break, e.g.:
477 *
478 * except IOError, (errno, strerror):
479 *
480 * we hack args so that it only contains two items. This also
481 * means we need our own __str__() which prints out the filename
482 * when it was supplied.
483 */
484static int
485EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
486 PyObject *kwds)
487{
488 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
489 PyObject *subslice = NULL;
490
491 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
492 return -1;
493
494 if (PyTuple_GET_SIZE(args) <= 1) {
495 return 0;
496 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000497
498 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000499 &myerrno, &strerror, &filename)) {
500 return -1;
501 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000502 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000503 self->myerrno = myerrno;
504 Py_INCREF(self->myerrno);
505
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000506 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000507 self->strerror = strerror;
508 Py_INCREF(self->strerror);
509
510 /* self->filename will remain Py_None otherwise */
511 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000512 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000513 self->filename = filename;
514 Py_INCREF(self->filename);
515
516 subslice = PyTuple_GetSlice(args, 0, 2);
517 if (!subslice)
518 return -1;
519
520 Py_DECREF(self->args); /* replacing args */
521 self->args = subslice;
522 }
523 return 0;
524}
525
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000526static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000527EnvironmentError_clear(PyEnvironmentErrorObject *self)
528{
529 Py_CLEAR(self->myerrno);
530 Py_CLEAR(self->strerror);
531 Py_CLEAR(self->filename);
532 return BaseException_clear((PyBaseExceptionObject *)self);
533}
534
535static void
536EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
537{
538 EnvironmentError_clear(self);
539 self->ob_type->tp_free((PyObject *)self);
540}
541
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000542static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000543EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
544 void *arg)
545{
546 Py_VISIT(self->myerrno);
547 Py_VISIT(self->strerror);
548 Py_VISIT(self->filename);
549 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
550}
551
552static PyObject *
553EnvironmentError_str(PyEnvironmentErrorObject *self)
554{
555 PyObject *rtnval = NULL;
556
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000557 if (self->filename) {
558 PyObject *fmt;
559 PyObject *repr;
560 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000561
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000562 fmt = PyString_FromString("[Errno %s] %s: %s");
563 if (!fmt)
564 return NULL;
565
566 repr = PyObject_Repr(self->filename);
567 if (!repr) {
568 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000569 return NULL;
570 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000571 tuple = PyTuple_New(3);
572 if (!tuple) {
573 Py_DECREF(repr);
574 Py_DECREF(fmt);
575 return NULL;
576 }
577
578 if (self->myerrno) {
579 Py_INCREF(self->myerrno);
580 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
581 }
582 else {
583 Py_INCREF(Py_None);
584 PyTuple_SET_ITEM(tuple, 0, Py_None);
585 }
586 if (self->strerror) {
587 Py_INCREF(self->strerror);
588 PyTuple_SET_ITEM(tuple, 1, self->strerror);
589 }
590 else {
591 Py_INCREF(Py_None);
592 PyTuple_SET_ITEM(tuple, 1, Py_None);
593 }
594
Richard Jones7b9558d2006-05-27 12:29:24 +0000595 Py_INCREF(repr);
596 PyTuple_SET_ITEM(tuple, 2, repr);
597
598 rtnval = PyString_Format(fmt, tuple);
599
600 Py_DECREF(fmt);
601 Py_DECREF(tuple);
602 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000603 else if (self->myerrno && self->strerror) {
604 PyObject *fmt;
605 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000606
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000607 fmt = PyString_FromString("[Errno %s] %s");
608 if (!fmt)
609 return NULL;
610
611 tuple = PyTuple_New(2);
612 if (!tuple) {
613 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000614 return NULL;
615 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000616
617 if (self->myerrno) {
618 Py_INCREF(self->myerrno);
619 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
620 }
621 else {
622 Py_INCREF(Py_None);
623 PyTuple_SET_ITEM(tuple, 0, Py_None);
624 }
625 if (self->strerror) {
626 Py_INCREF(self->strerror);
627 PyTuple_SET_ITEM(tuple, 1, self->strerror);
628 }
629 else {
630 Py_INCREF(Py_None);
631 PyTuple_SET_ITEM(tuple, 1, Py_None);
632 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000633
634 rtnval = PyString_Format(fmt, tuple);
635
636 Py_DECREF(fmt);
637 Py_DECREF(tuple);
638 }
639 else
640 rtnval = BaseException_str((PyBaseExceptionObject *)self);
641
642 return rtnval;
643}
644
645static PyMemberDef EnvironmentError_members[] = {
646 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
647 PyDoc_STR("exception message")},
648 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000649 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000650 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000651 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000652 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000653 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000654 {NULL} /* Sentinel */
655};
656
657
658static PyObject *
659EnvironmentError_reduce(PyEnvironmentErrorObject *self)
660{
661 PyObject *args = self->args;
662 PyObject *res = NULL, *tmp;
Georg Brandl05f97bf2006-05-30 07:13:29 +0000663
Richard Jones7b9558d2006-05-27 12:29:24 +0000664 /* self->args is only the first two real arguments if there was a
665 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000666 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000667 args = PyTuple_New(3);
668 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000669
670 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000671 Py_INCREF(tmp);
672 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000673
674 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000675 Py_INCREF(tmp);
676 PyTuple_SET_ITEM(args, 1, tmp);
677
678 Py_INCREF(self->filename);
679 PyTuple_SET_ITEM(args, 2, self->filename);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000680 } else
Richard Jones7b9558d2006-05-27 12:29:24 +0000681 Py_INCREF(args);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000682
683 if (self->dict)
684 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
685 else
686 res = PyTuple_Pack(2, self->ob_type, args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000687 Py_DECREF(args);
688 return res;
689}
690
691
692static PyMethodDef EnvironmentError_methods[] = {
693 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
694 {NULL}
695};
696
697ComplexExtendsException(PyExc_StandardError, EnvironmentError,
698 EnvironmentError, EnvironmentError_dealloc,
699 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000700 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000701 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000702
703
704/*
705 * IOError extends EnvironmentError
706 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000707MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000708 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000709
710
711/*
712 * OSError extends EnvironmentError
713 */
714MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000715 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000716
717
718/*
719 * WindowsError extends OSError
720 */
721#ifdef MS_WINDOWS
722#include "errmap.h"
723
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000724static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000725WindowsError_clear(PyWindowsErrorObject *self)
726{
727 Py_CLEAR(self->myerrno);
728 Py_CLEAR(self->strerror);
729 Py_CLEAR(self->filename);
730 Py_CLEAR(self->winerror);
731 return BaseException_clear((PyBaseExceptionObject *)self);
732}
733
734static void
735WindowsError_dealloc(PyWindowsErrorObject *self)
736{
737 WindowsError_clear(self);
738 self->ob_type->tp_free((PyObject *)self);
739}
740
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000741static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000742WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
743{
744 Py_VISIT(self->myerrno);
745 Py_VISIT(self->strerror);
746 Py_VISIT(self->filename);
747 Py_VISIT(self->winerror);
748 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
749}
750
Richard Jones7b9558d2006-05-27 12:29:24 +0000751static int
752WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
753{
754 PyObject *o_errcode = NULL;
755 long errcode;
756 long posix_errno;
757
758 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
759 == -1)
760 return -1;
761
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000762 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000763 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000764
765 /* Set errno to the POSIX errno, and winerror to the Win32
766 error code. */
767 errcode = PyInt_AsLong(self->myerrno);
768 if (errcode == -1 && PyErr_Occurred())
769 return -1;
770 posix_errno = winerror_to_errno(errcode);
771
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000772 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000773 self->winerror = self->myerrno;
774
775 o_errcode = PyInt_FromLong(posix_errno);
776 if (!o_errcode)
777 return -1;
778
779 self->myerrno = o_errcode;
780
781 return 0;
782}
783
784
785static PyObject *
786WindowsError_str(PyWindowsErrorObject *self)
787{
Richard Jones7b9558d2006-05-27 12:29:24 +0000788 PyObject *rtnval = NULL;
789
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000790 if (self->filename) {
791 PyObject *fmt;
792 PyObject *repr;
793 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000794
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000795 fmt = PyString_FromString("[Error %s] %s: %s");
796 if (!fmt)
797 return NULL;
798
799 repr = PyObject_Repr(self->filename);
800 if (!repr) {
801 Py_DECREF(fmt);
802 return NULL;
803 }
804 tuple = PyTuple_New(3);
805 if (!tuple) {
806 Py_DECREF(repr);
807 Py_DECREF(fmt);
808 return NULL;
809 }
810
811 if (self->myerrno) {
812 Py_INCREF(self->myerrno);
813 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
814 }
815 else {
816 Py_INCREF(Py_None);
817 PyTuple_SET_ITEM(tuple, 0, Py_None);
818 }
819 if (self->strerror) {
820 Py_INCREF(self->strerror);
821 PyTuple_SET_ITEM(tuple, 1, self->strerror);
822 }
823 else {
824 Py_INCREF(Py_None);
825 PyTuple_SET_ITEM(tuple, 1, Py_None);
826 }
827
828 Py_INCREF(repr);
829 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000830
831 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000832
833 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000834 Py_DECREF(tuple);
835 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000836 else if (self->myerrno && self->strerror) {
837 PyObject *fmt;
838 PyObject *tuple;
839
Richard Jones7b9558d2006-05-27 12:29:24 +0000840 fmt = PyString_FromString("[Error %s] %s");
841 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000842 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000843
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000844 tuple = PyTuple_New(2);
845 if (!tuple) {
846 Py_DECREF(fmt);
847 return NULL;
848 }
849
850 if (self->myerrno) {
851 Py_INCREF(self->myerrno);
852 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
853 }
854 else {
855 Py_INCREF(Py_None);
856 PyTuple_SET_ITEM(tuple, 0, Py_None);
857 }
858 if (self->strerror) {
859 Py_INCREF(self->strerror);
860 PyTuple_SET_ITEM(tuple, 1, self->strerror);
861 }
862 else {
863 Py_INCREF(Py_None);
864 PyTuple_SET_ITEM(tuple, 1, Py_None);
865 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000866
867 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000868
869 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000870 Py_DECREF(tuple);
871 }
872 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000873 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000874
Richard Jones7b9558d2006-05-27 12:29:24 +0000875 return rtnval;
876}
877
878static PyMemberDef WindowsError_members[] = {
879 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
880 PyDoc_STR("exception message")},
881 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000882 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000883 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000884 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000885 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000886 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000887 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000888 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000889 {NULL} /* Sentinel */
890};
891
Richard Jones2d555b32006-05-27 16:15:11 +0000892ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
893 WindowsError_dealloc, 0, WindowsError_members,
894 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000895
896#endif /* MS_WINDOWS */
897
898
899/*
900 * VMSError extends OSError (I think)
901 */
902#ifdef __VMS
903MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000904 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000905#endif
906
907
908/*
909 * EOFError extends StandardError
910 */
911SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000912 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000913
914
915/*
916 * RuntimeError extends StandardError
917 */
918SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000919 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000920
921
922/*
923 * NotImplementedError extends RuntimeError
924 */
925SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000926 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000927
928/*
929 * NameError extends StandardError
930 */
931SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000932 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000933
934/*
935 * UnboundLocalError extends NameError
936 */
937SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000938 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000939
940/*
941 * AttributeError extends StandardError
942 */
943SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000944 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000945
946
947/*
948 * SyntaxError extends StandardError
949 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000950
951static int
952SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
953{
954 PyObject *info = NULL;
955 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
956
957 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
958 return -1;
959
960 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000961 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000962 self->msg = PyTuple_GET_ITEM(args, 0);
963 Py_INCREF(self->msg);
964 }
965 if (lenargs == 2) {
966 info = PyTuple_GET_ITEM(args, 1);
967 info = PySequence_Tuple(info);
968 if (!info) return -1;
969
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000970 if (PyTuple_GET_SIZE(info) != 4) {
971 /* not a very good error message, but it's what Python 2.4 gives */
972 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
973 Py_DECREF(info);
974 return -1;
975 }
976
977 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +0000978 self->filename = PyTuple_GET_ITEM(info, 0);
979 Py_INCREF(self->filename);
980
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000981 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +0000982 self->lineno = PyTuple_GET_ITEM(info, 1);
983 Py_INCREF(self->lineno);
984
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000985 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +0000986 self->offset = PyTuple_GET_ITEM(info, 2);
987 Py_INCREF(self->offset);
988
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000989 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +0000990 self->text = PyTuple_GET_ITEM(info, 3);
991 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000992
993 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +0000994 }
995 return 0;
996}
997
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000998static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000999SyntaxError_clear(PySyntaxErrorObject *self)
1000{
1001 Py_CLEAR(self->msg);
1002 Py_CLEAR(self->filename);
1003 Py_CLEAR(self->lineno);
1004 Py_CLEAR(self->offset);
1005 Py_CLEAR(self->text);
1006 Py_CLEAR(self->print_file_and_line);
1007 return BaseException_clear((PyBaseExceptionObject *)self);
1008}
1009
1010static void
1011SyntaxError_dealloc(PySyntaxErrorObject *self)
1012{
1013 SyntaxError_clear(self);
1014 self->ob_type->tp_free((PyObject *)self);
1015}
1016
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001017static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001018SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1019{
1020 Py_VISIT(self->msg);
1021 Py_VISIT(self->filename);
1022 Py_VISIT(self->lineno);
1023 Py_VISIT(self->offset);
1024 Py_VISIT(self->text);
1025 Py_VISIT(self->print_file_and_line);
1026 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1027}
1028
1029/* This is called "my_basename" instead of just "basename" to avoid name
1030 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1031 defined, and Python does define that. */
1032static char *
1033my_basename(char *name)
1034{
1035 char *cp = name;
1036 char *result = name;
1037
1038 if (name == NULL)
1039 return "???";
1040 while (*cp != '\0') {
1041 if (*cp == SEP)
1042 result = cp + 1;
1043 ++cp;
1044 }
1045 return result;
1046}
1047
1048
1049static PyObject *
1050SyntaxError_str(PySyntaxErrorObject *self)
1051{
1052 PyObject *str;
1053 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001054 int have_filename = 0;
1055 int have_lineno = 0;
1056 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001057 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001058
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001059 if (self->msg)
1060 str = PyObject_Str(self->msg);
1061 else
1062 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001063 if (!str) return NULL;
1064 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1065 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001066
1067 /* XXX -- do all the additional formatting with filename and
1068 lineno here */
1069
Georg Brandl43ab1002006-05-28 20:57:09 +00001070 have_filename = (self->filename != NULL) &&
1071 PyString_Check(self->filename);
1072 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001073
Georg Brandl43ab1002006-05-28 20:57:09 +00001074 if (!have_filename && !have_lineno)
1075 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001076
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001077 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001078 if (have_filename)
1079 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001080
Georg Brandl43ab1002006-05-28 20:57:09 +00001081 buffer = PyMem_MALLOC(bufsize);
1082 if (buffer == NULL)
1083 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001084
Georg Brandl43ab1002006-05-28 20:57:09 +00001085 if (have_filename && have_lineno)
1086 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1087 PyString_AS_STRING(str),
1088 my_basename(PyString_AS_STRING(self->filename)),
1089 PyInt_AsLong(self->lineno));
1090 else if (have_filename)
1091 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1092 PyString_AS_STRING(str),
1093 my_basename(PyString_AS_STRING(self->filename)));
1094 else /* only have_lineno */
1095 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1096 PyString_AS_STRING(str),
1097 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001098
Georg Brandl43ab1002006-05-28 20:57:09 +00001099 result = PyString_FromString(buffer);
1100 PyMem_FREE(buffer);
1101
1102 if (result == NULL)
1103 result = str;
1104 else
1105 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001106 return result;
1107}
1108
1109static PyMemberDef SyntaxError_members[] = {
1110 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1111 PyDoc_STR("exception message")},
1112 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1113 PyDoc_STR("exception msg")},
1114 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1115 PyDoc_STR("exception filename")},
1116 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1117 PyDoc_STR("exception lineno")},
1118 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1119 PyDoc_STR("exception offset")},
1120 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1121 PyDoc_STR("exception text")},
1122 {"print_file_and_line", T_OBJECT,
1123 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1124 PyDoc_STR("exception print_file_and_line")},
1125 {NULL} /* Sentinel */
1126};
1127
1128ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1129 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001130 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001131
1132
1133/*
1134 * IndentationError extends SyntaxError
1135 */
1136MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001137 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001138
1139
1140/*
1141 * TabError extends IndentationError
1142 */
1143MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001144 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001145
1146
1147/*
1148 * LookupError extends StandardError
1149 */
1150SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001151 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001152
1153
1154/*
1155 * IndexError extends LookupError
1156 */
1157SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001158 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001159
1160
1161/*
1162 * KeyError extends LookupError
1163 */
1164static PyObject *
1165KeyError_str(PyBaseExceptionObject *self)
1166{
1167 /* If args is a tuple of exactly one item, apply repr to args[0].
1168 This is done so that e.g. the exception raised by {}[''] prints
1169 KeyError: ''
1170 rather than the confusing
1171 KeyError
1172 alone. The downside is that if KeyError is raised with an explanatory
1173 string, that string will be displayed in quotes. Too bad.
1174 If args is anything else, use the default BaseException__str__().
1175 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001176 if (PyTuple_GET_SIZE(self->args) == 1) {
1177 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001178 }
1179 return BaseException_str(self);
1180}
1181
1182ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001183 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001184
1185
1186/*
1187 * ValueError extends StandardError
1188 */
1189SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001190 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001191
1192/*
1193 * UnicodeError extends ValueError
1194 */
1195
1196SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001197 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001198
1199#ifdef Py_USING_UNICODE
1200static int
1201get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1202{
1203 if (!attr) {
1204 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1205 return -1;
1206 }
1207
1208 if (PyInt_Check(attr)) {
1209 *value = PyInt_AS_LONG(attr);
1210 } else if (PyLong_Check(attr)) {
1211 *value = _PyLong_AsSsize_t(attr);
1212 if (*value == -1 && PyErr_Occurred())
1213 return -1;
1214 } else {
1215 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1216 return -1;
1217 }
1218 return 0;
1219}
1220
1221static int
1222set_ssize_t(PyObject **attr, Py_ssize_t value)
1223{
1224 PyObject *obj = PyInt_FromSsize_t(value);
1225 if (!obj)
1226 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001227 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001228 *attr = obj;
1229 return 0;
1230}
1231
1232static PyObject *
1233get_string(PyObject *attr, const char *name)
1234{
1235 if (!attr) {
1236 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1237 return NULL;
1238 }
1239
1240 if (!PyString_Check(attr)) {
1241 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1242 return NULL;
1243 }
1244 Py_INCREF(attr);
1245 return attr;
1246}
1247
1248
1249static int
1250set_string(PyObject **attr, const char *value)
1251{
1252 PyObject *obj = PyString_FromString(value);
1253 if (!obj)
1254 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001255 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001256 *attr = obj;
1257 return 0;
1258}
1259
1260
1261static PyObject *
1262get_unicode(PyObject *attr, const char *name)
1263{
1264 if (!attr) {
1265 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1266 return NULL;
1267 }
1268
1269 if (!PyUnicode_Check(attr)) {
1270 PyErr_Format(PyExc_TypeError,
1271 "%.200s attribute must be unicode", name);
1272 return NULL;
1273 }
1274 Py_INCREF(attr);
1275 return attr;
1276}
1277
1278PyObject *
1279PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1280{
1281 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1282}
1283
1284PyObject *
1285PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1286{
1287 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1288}
1289
1290PyObject *
1291PyUnicodeEncodeError_GetObject(PyObject *exc)
1292{
1293 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1294}
1295
1296PyObject *
1297PyUnicodeDecodeError_GetObject(PyObject *exc)
1298{
1299 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1300}
1301
1302PyObject *
1303PyUnicodeTranslateError_GetObject(PyObject *exc)
1304{
1305 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1306}
1307
1308int
1309PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1310{
1311 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1312 Py_ssize_t size;
1313 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1314 "object");
1315 if (!obj) return -1;
1316 size = PyUnicode_GET_SIZE(obj);
1317 if (*start<0)
1318 *start = 0; /*XXX check for values <0*/
1319 if (*start>=size)
1320 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001321 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001322 return 0;
1323 }
1324 return -1;
1325}
1326
1327
1328int
1329PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1330{
1331 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1332 Py_ssize_t size;
1333 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1334 "object");
1335 if (!obj) return -1;
1336 size = PyString_GET_SIZE(obj);
1337 if (*start<0)
1338 *start = 0;
1339 if (*start>=size)
1340 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001341 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001342 return 0;
1343 }
1344 return -1;
1345}
1346
1347
1348int
1349PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1350{
1351 return PyUnicodeEncodeError_GetStart(exc, start);
1352}
1353
1354
1355int
1356PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1357{
1358 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1359}
1360
1361
1362int
1363PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1364{
1365 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1366}
1367
1368
1369int
1370PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1371{
1372 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1373}
1374
1375
1376int
1377PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1378{
1379 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1380 Py_ssize_t size;
1381 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1382 "object");
1383 if (!obj) return -1;
1384 size = PyUnicode_GET_SIZE(obj);
1385 if (*end<1)
1386 *end = 1;
1387 if (*end>size)
1388 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001389 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001390 return 0;
1391 }
1392 return -1;
1393}
1394
1395
1396int
1397PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1398{
1399 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1400 Py_ssize_t size;
1401 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1402 "object");
1403 if (!obj) return -1;
1404 size = PyString_GET_SIZE(obj);
1405 if (*end<1)
1406 *end = 1;
1407 if (*end>size)
1408 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001409 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001410 return 0;
1411 }
1412 return -1;
1413}
1414
1415
1416int
1417PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1418{
1419 return PyUnicodeEncodeError_GetEnd(exc, start);
1420}
1421
1422
1423int
1424PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1425{
1426 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1427}
1428
1429
1430int
1431PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1432{
1433 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1434}
1435
1436
1437int
1438PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1439{
1440 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1441}
1442
1443PyObject *
1444PyUnicodeEncodeError_GetReason(PyObject *exc)
1445{
1446 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1447}
1448
1449
1450PyObject *
1451PyUnicodeDecodeError_GetReason(PyObject *exc)
1452{
1453 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1454}
1455
1456
1457PyObject *
1458PyUnicodeTranslateError_GetReason(PyObject *exc)
1459{
1460 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1461}
1462
1463
1464int
1465PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1466{
1467 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1468}
1469
1470
1471int
1472PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1473{
1474 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1475}
1476
1477
1478int
1479PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1480{
1481 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1482}
1483
1484
Richard Jones7b9558d2006-05-27 12:29:24 +00001485static int
1486UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1487 PyTypeObject *objecttype)
1488{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001489 Py_CLEAR(self->encoding);
1490 Py_CLEAR(self->object);
1491 Py_CLEAR(self->start);
1492 Py_CLEAR(self->end);
1493 Py_CLEAR(self->reason);
1494
Richard Jones7b9558d2006-05-27 12:29:24 +00001495 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1496 &PyString_Type, &self->encoding,
1497 objecttype, &self->object,
1498 &PyInt_Type, &self->start,
1499 &PyInt_Type, &self->end,
1500 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001501 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001502 self->reason = NULL;
1503 return -1;
1504 }
1505
1506 Py_INCREF(self->encoding);
1507 Py_INCREF(self->object);
1508 Py_INCREF(self->start);
1509 Py_INCREF(self->end);
1510 Py_INCREF(self->reason);
1511
1512 return 0;
1513}
1514
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001515static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001516UnicodeError_clear(PyUnicodeErrorObject *self)
1517{
1518 Py_CLEAR(self->encoding);
1519 Py_CLEAR(self->object);
1520 Py_CLEAR(self->start);
1521 Py_CLEAR(self->end);
1522 Py_CLEAR(self->reason);
1523 return BaseException_clear((PyBaseExceptionObject *)self);
1524}
1525
1526static void
1527UnicodeError_dealloc(PyUnicodeErrorObject *self)
1528{
1529 UnicodeError_clear(self);
1530 self->ob_type->tp_free((PyObject *)self);
1531}
1532
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001533static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001534UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1535{
1536 Py_VISIT(self->encoding);
1537 Py_VISIT(self->object);
1538 Py_VISIT(self->start);
1539 Py_VISIT(self->end);
1540 Py_VISIT(self->reason);
1541 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1542}
1543
1544static PyMemberDef UnicodeError_members[] = {
1545 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1546 PyDoc_STR("exception message")},
1547 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1548 PyDoc_STR("exception encoding")},
1549 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1550 PyDoc_STR("exception object")},
1551 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1552 PyDoc_STR("exception start")},
1553 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1554 PyDoc_STR("exception end")},
1555 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1556 PyDoc_STR("exception reason")},
1557 {NULL} /* Sentinel */
1558};
1559
1560
1561/*
1562 * UnicodeEncodeError extends UnicodeError
1563 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001564
1565static int
1566UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1567{
1568 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1569 return -1;
1570 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1571 kwds, &PyUnicode_Type);
1572}
1573
1574static PyObject *
1575UnicodeEncodeError_str(PyObject *self)
1576{
1577 Py_ssize_t start;
1578 Py_ssize_t end;
1579
1580 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001581 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001582
1583 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001584 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001585
1586 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001587 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1588 char badchar_str[20];
1589 if (badchar <= 0xff)
1590 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1591 else if (badchar <= 0xffff)
1592 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1593 else
1594 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1595 return PyString_FromFormat(
1596 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1597 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1598 badchar_str,
1599 start,
1600 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1601 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001602 }
1603 return PyString_FromFormat(
1604 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1605 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1606 start,
1607 (end-1),
1608 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1609 );
1610}
1611
1612static PyTypeObject _PyExc_UnicodeEncodeError = {
1613 PyObject_HEAD_INIT(NULL)
1614 0,
1615 "UnicodeEncodeError",
1616 sizeof(PyUnicodeErrorObject), 0,
1617 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1618 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1619 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001620 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1621 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001622 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001623 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001624};
1625PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1626
1627PyObject *
1628PyUnicodeEncodeError_Create(
1629 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1630 Py_ssize_t start, Py_ssize_t end, const char *reason)
1631{
1632 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001633 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001634}
1635
1636
1637/*
1638 * UnicodeDecodeError extends UnicodeError
1639 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001640
1641static int
1642UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1643{
1644 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1645 return -1;
1646 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1647 kwds, &PyString_Type);
1648}
1649
1650static PyObject *
1651UnicodeDecodeError_str(PyObject *self)
1652{
Georg Brandl43ab1002006-05-28 20:57:09 +00001653 Py_ssize_t start = 0;
1654 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001655
1656 if (PyUnicodeDecodeError_GetStart(self, &start))
1657 return NULL;
1658
1659 if (PyUnicodeDecodeError_GetEnd(self, &end))
1660 return NULL;
1661
1662 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001663 /* FromFormat does not support %02x, so format that separately */
1664 char byte[4];
1665 PyOS_snprintf(byte, sizeof(byte), "%02x",
1666 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1667 return PyString_FromFormat(
1668 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1669 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1670 byte,
1671 start,
1672 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1673 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001674 }
1675 return PyString_FromFormat(
1676 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1677 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1678 start,
1679 (end-1),
1680 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1681 );
1682}
1683
1684static PyTypeObject _PyExc_UnicodeDecodeError = {
1685 PyObject_HEAD_INIT(NULL)
1686 0,
1687 EXC_MODULE_NAME "UnicodeDecodeError",
1688 sizeof(PyUnicodeErrorObject), 0,
1689 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1690 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1691 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001692 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1693 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001694 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001695 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001696};
1697PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1698
1699PyObject *
1700PyUnicodeDecodeError_Create(
1701 const char *encoding, const char *object, Py_ssize_t length,
1702 Py_ssize_t start, Py_ssize_t end, const char *reason)
1703{
1704 assert(length < INT_MAX);
1705 assert(start < INT_MAX);
1706 assert(end < INT_MAX);
1707 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001708 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001709}
1710
1711
1712/*
1713 * UnicodeTranslateError extends UnicodeError
1714 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001715
1716static int
1717UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1718 PyObject *kwds)
1719{
1720 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1721 return -1;
1722
1723 Py_CLEAR(self->object);
1724 Py_CLEAR(self->start);
1725 Py_CLEAR(self->end);
1726 Py_CLEAR(self->reason);
1727
1728 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1729 &PyUnicode_Type, &self->object,
1730 &PyInt_Type, &self->start,
1731 &PyInt_Type, &self->end,
1732 &PyString_Type, &self->reason)) {
1733 self->object = self->start = self->end = self->reason = NULL;
1734 return -1;
1735 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001736
Richard Jones7b9558d2006-05-27 12:29:24 +00001737 Py_INCREF(self->object);
1738 Py_INCREF(self->start);
1739 Py_INCREF(self->end);
1740 Py_INCREF(self->reason);
1741
1742 return 0;
1743}
1744
1745
1746static PyObject *
1747UnicodeTranslateError_str(PyObject *self)
1748{
1749 Py_ssize_t start;
1750 Py_ssize_t end;
1751
1752 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001753 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001754
1755 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001756 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001757
1758 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001759 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1760 char badchar_str[20];
1761 if (badchar <= 0xff)
1762 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1763 else if (badchar <= 0xffff)
1764 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1765 else
1766 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1767 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001768 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001769 badchar_str,
1770 start,
1771 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1772 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001773 }
1774 return PyString_FromFormat(
1775 "can't translate characters in position %zd-%zd: %.400s",
1776 start,
1777 (end-1),
1778 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1779 );
1780}
1781
1782static PyTypeObject _PyExc_UnicodeTranslateError = {
1783 PyObject_HEAD_INIT(NULL)
1784 0,
1785 EXC_MODULE_NAME "UnicodeTranslateError",
1786 sizeof(PyUnicodeErrorObject), 0,
1787 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1788 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1789 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1790 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1791 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1792 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001793 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001794};
1795PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1796
1797PyObject *
1798PyUnicodeTranslateError_Create(
1799 const Py_UNICODE *object, Py_ssize_t length,
1800 Py_ssize_t start, Py_ssize_t end, const char *reason)
1801{
1802 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001803 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001804}
1805#endif
1806
1807
1808/*
1809 * AssertionError extends StandardError
1810 */
1811SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001812 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001813
1814
1815/*
1816 * ArithmeticError extends StandardError
1817 */
1818SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001819 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001820
1821
1822/*
1823 * FloatingPointError extends ArithmeticError
1824 */
1825SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001826 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001827
1828
1829/*
1830 * OverflowError extends ArithmeticError
1831 */
1832SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001833 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001834
1835
1836/*
1837 * ZeroDivisionError extends ArithmeticError
1838 */
1839SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001840 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001841
1842
1843/*
1844 * SystemError extends StandardError
1845 */
1846SimpleExtendsException(PyExc_StandardError, SystemError,
1847 "Internal error in the Python interpreter.\n"
1848 "\n"
1849 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001850 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001851
1852
1853/*
1854 * ReferenceError extends StandardError
1855 */
1856SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001857 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001858
1859
1860/*
1861 * MemoryError extends StandardError
1862 */
Richard Jones2d555b32006-05-27 16:15:11 +00001863SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001864
1865
1866/* Warning category docstrings */
1867
1868/*
1869 * Warning extends Exception
1870 */
1871SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001872 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001873
1874
1875/*
1876 * UserWarning extends Warning
1877 */
1878SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001879 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001880
1881
1882/*
1883 * DeprecationWarning extends Warning
1884 */
1885SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001886 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001887
1888
1889/*
1890 * PendingDeprecationWarning extends Warning
1891 */
1892SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1893 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001894 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001895
1896
1897/*
1898 * SyntaxWarning extends Warning
1899 */
1900SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001901 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001902
1903
1904/*
1905 * RuntimeWarning extends Warning
1906 */
1907SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001908 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001909
1910
1911/*
1912 * FutureWarning extends Warning
1913 */
1914SimpleExtendsException(PyExc_Warning, FutureWarning,
1915 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001916 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001917
1918
1919/*
1920 * ImportWarning extends Warning
1921 */
1922SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001923 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001924
1925
1926/* Pre-computed MemoryError instance. Best to create this as early as
1927 * possible and not wait until a MemoryError is actually raised!
1928 */
1929PyObject *PyExc_MemoryErrorInst=NULL;
1930
1931/* module global functions */
1932static PyMethodDef functions[] = {
1933 /* Sentinel */
1934 {NULL, NULL}
1935};
1936
1937#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1938 Py_FatalError("exceptions bootstrapping error.");
1939
1940#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1941 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1942 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1943 Py_FatalError("Module dictionary insertion problem.");
1944
1945PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001946_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001947{
1948 PyObject *m, *bltinmod, *bdict;
1949
1950 PRE_INIT(BaseException)
1951 PRE_INIT(Exception)
1952 PRE_INIT(StandardError)
1953 PRE_INIT(TypeError)
1954 PRE_INIT(StopIteration)
1955 PRE_INIT(GeneratorExit)
1956 PRE_INIT(SystemExit)
1957 PRE_INIT(KeyboardInterrupt)
1958 PRE_INIT(ImportError)
1959 PRE_INIT(EnvironmentError)
1960 PRE_INIT(IOError)
1961 PRE_INIT(OSError)
1962#ifdef MS_WINDOWS
1963 PRE_INIT(WindowsError)
1964#endif
1965#ifdef __VMS
1966 PRE_INIT(VMSError)
1967#endif
1968 PRE_INIT(EOFError)
1969 PRE_INIT(RuntimeError)
1970 PRE_INIT(NotImplementedError)
1971 PRE_INIT(NameError)
1972 PRE_INIT(UnboundLocalError)
1973 PRE_INIT(AttributeError)
1974 PRE_INIT(SyntaxError)
1975 PRE_INIT(IndentationError)
1976 PRE_INIT(TabError)
1977 PRE_INIT(LookupError)
1978 PRE_INIT(IndexError)
1979 PRE_INIT(KeyError)
1980 PRE_INIT(ValueError)
1981 PRE_INIT(UnicodeError)
1982#ifdef Py_USING_UNICODE
1983 PRE_INIT(UnicodeEncodeError)
1984 PRE_INIT(UnicodeDecodeError)
1985 PRE_INIT(UnicodeTranslateError)
1986#endif
1987 PRE_INIT(AssertionError)
1988 PRE_INIT(ArithmeticError)
1989 PRE_INIT(FloatingPointError)
1990 PRE_INIT(OverflowError)
1991 PRE_INIT(ZeroDivisionError)
1992 PRE_INIT(SystemError)
1993 PRE_INIT(ReferenceError)
1994 PRE_INIT(MemoryError)
1995 PRE_INIT(Warning)
1996 PRE_INIT(UserWarning)
1997 PRE_INIT(DeprecationWarning)
1998 PRE_INIT(PendingDeprecationWarning)
1999 PRE_INIT(SyntaxWarning)
2000 PRE_INIT(RuntimeWarning)
2001 PRE_INIT(FutureWarning)
2002 PRE_INIT(ImportWarning)
2003
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00002004 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2005 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00002006 if (m == NULL) return;
2007
2008 bltinmod = PyImport_ImportModule("__builtin__");
2009 if (bltinmod == NULL)
2010 Py_FatalError("exceptions bootstrapping error.");
2011 bdict = PyModule_GetDict(bltinmod);
2012 if (bdict == NULL)
2013 Py_FatalError("exceptions bootstrapping error.");
2014
2015 POST_INIT(BaseException)
2016 POST_INIT(Exception)
2017 POST_INIT(StandardError)
2018 POST_INIT(TypeError)
2019 POST_INIT(StopIteration)
2020 POST_INIT(GeneratorExit)
2021 POST_INIT(SystemExit)
2022 POST_INIT(KeyboardInterrupt)
2023 POST_INIT(ImportError)
2024 POST_INIT(EnvironmentError)
2025 POST_INIT(IOError)
2026 POST_INIT(OSError)
2027#ifdef MS_WINDOWS
2028 POST_INIT(WindowsError)
2029#endif
2030#ifdef __VMS
2031 POST_INIT(VMSError)
2032#endif
2033 POST_INIT(EOFError)
2034 POST_INIT(RuntimeError)
2035 POST_INIT(NotImplementedError)
2036 POST_INIT(NameError)
2037 POST_INIT(UnboundLocalError)
2038 POST_INIT(AttributeError)
2039 POST_INIT(SyntaxError)
2040 POST_INIT(IndentationError)
2041 POST_INIT(TabError)
2042 POST_INIT(LookupError)
2043 POST_INIT(IndexError)
2044 POST_INIT(KeyError)
2045 POST_INIT(ValueError)
2046 POST_INIT(UnicodeError)
2047#ifdef Py_USING_UNICODE
2048 POST_INIT(UnicodeEncodeError)
2049 POST_INIT(UnicodeDecodeError)
2050 POST_INIT(UnicodeTranslateError)
2051#endif
2052 POST_INIT(AssertionError)
2053 POST_INIT(ArithmeticError)
2054 POST_INIT(FloatingPointError)
2055 POST_INIT(OverflowError)
2056 POST_INIT(ZeroDivisionError)
2057 POST_INIT(SystemError)
2058 POST_INIT(ReferenceError)
2059 POST_INIT(MemoryError)
2060 POST_INIT(Warning)
2061 POST_INIT(UserWarning)
2062 POST_INIT(DeprecationWarning)
2063 POST_INIT(PendingDeprecationWarning)
2064 POST_INIT(SyntaxWarning)
2065 POST_INIT(RuntimeWarning)
2066 POST_INIT(FutureWarning)
2067 POST_INIT(ImportWarning)
2068
2069 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2070 if (!PyExc_MemoryErrorInst)
2071 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2072
2073 Py_DECREF(bltinmod);
2074}
2075
2076void
2077_PyExc_Fini(void)
2078{
2079 Py_XDECREF(PyExc_MemoryErrorInst);
2080 PyExc_MemoryErrorInst = NULL;
2081}