blob: 28fb0c14e88bcc56aaba9adee6d3097c8cbbdb66 [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
Georg Brandl861089f2006-05-30 07:34:45 +000035 if (!_PyArg_NoKeywords("BaseException", kwds))
36 return NULL;
37
Richard Jones7b9558d2006-05-27 12:29:24 +000038 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
39 /* the dict is created on the fly in PyObject_GenericSetAttr */
40 self->message = self->dict = NULL;
41
42 self->args = PyTuple_New(0);
43 if (!self->args) {
44 Py_DECREF(self);
45 return NULL;
46 }
47
Michael W. Hudson22a80e72006-05-28 15:51:40 +000048 self->message = PyString_FromString("");
Richard Jones7b9558d2006-05-27 12:29:24 +000049 if (!self->message) {
50 Py_DECREF(self);
51 return NULL;
52 }
53
54 return (PyObject *)self;
55}
56
57static int
58BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
59{
60 Py_DECREF(self->args);
61 self->args = args;
62 Py_INCREF(self->args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +000065 Py_CLEAR(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000066 self->message = PyTuple_GET_ITEM(self->args, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +000067 Py_INCREF(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000068 }
69 return 0;
70}
71
Michael W. Hudson96495ee2006-05-28 17:40:29 +000072static int
Richard Jones7b9558d2006-05-27 12:29:24 +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{
84 BaseException_clear(self);
85 self->ob_type->tp_free((PyObject *)self);
86}
87
Michael W. Hudson96495ee2006-05-28 17:40:29 +000088static int
Richard Jones7b9558d2006-05-27 12:29:24 +000089BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
90{
Michael W. Hudson22a80e72006-05-28 15:51:40 +000091 Py_VISIT(self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +000092 Py_VISIT(self->args);
93 Py_VISIT(self->message);
94 return 0;
95}
96
97static PyObject *
98BaseException_str(PyBaseExceptionObject *self)
99{
100 PyObject *out;
101
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000102 switch (PyTuple_GET_SIZE(self->args)) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000103 case 0:
104 out = PyString_FromString("");
105 break;
106 case 1:
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000107 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000108 break;
Richard Jones7b9558d2006-05-27 12:29:24 +0000109 default:
110 out = PyObject_Str(self->args);
111 break;
112 }
113
114 return out;
115}
116
117static PyObject *
118BaseException_repr(PyBaseExceptionObject *self)
119{
Richard Jones7b9558d2006-05-27 12:29:24 +0000120 PyObject *repr_suffix;
121 PyObject *repr;
122 char *name;
123 char *dot;
124
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000125 repr_suffix = PyObject_Repr(self->args);
126 if (!repr_suffix)
Richard Jones7b9558d2006-05-27 12:29:24 +0000127 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000128
129 name = (char *)self->ob_type->tp_name;
130 dot = strrchr(name, '.');
131 if (dot != NULL) name = dot+1;
132
133 repr = PyString_FromString(name);
134 if (!repr) {
135 Py_DECREF(repr_suffix);
136 return NULL;
137 }
138
139 PyString_ConcatAndDel(&repr, repr_suffix);
140 return repr;
141}
142
143/* Pickling support */
144static PyObject *
145BaseException_reduce(PyBaseExceptionObject *self)
146{
Georg Brandlddba4732006-05-30 07:04:55 +0000147 if (self->args && self->dict)
148 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000149 else
Georg Brandlddba4732006-05-30 07:04:55 +0000150 return PyTuple_Pack(2, self->ob_type, self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000151}
152
153
154#ifdef Py_USING_UNICODE
155/* while this method generates fairly uninspired output, it a least
156 * guarantees that we can display exceptions that have unicode attributes
157 */
158static PyObject *
159BaseException_unicode(PyBaseExceptionObject *self)
160{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000161 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000162 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000163 if (PyTuple_GET_SIZE(self->args) == 1)
164 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000165 return PyObject_Unicode(self->args);
166}
167#endif /* Py_USING_UNICODE */
168
169static PyMethodDef BaseException_methods[] = {
170 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
171#ifdef Py_USING_UNICODE
172 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
173#endif
174 {NULL, NULL, 0, NULL},
175};
176
177
178
179static PyObject *
180BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
181{
182 return PySequence_GetItem(self->args, index);
183}
184
185static PySequenceMethods BaseException_as_sequence = {
186 0, /* sq_length; */
187 0, /* sq_concat; */
188 0, /* sq_repeat; */
189 (ssizeargfunc)BaseException_getitem, /* sq_item; */
190 0, /* sq_slice; */
191 0, /* sq_ass_item; */
192 0, /* sq_ass_slice; */
193 0, /* sq_contains; */
194 0, /* sq_inplace_concat; */
195 0 /* sq_inplace_repeat; */
196};
197
198static PyMemberDef BaseException_members[] = {
199 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
200 PyDoc_STR("exception message")},
201 {NULL} /* Sentinel */
202};
203
204
205static PyObject *
206BaseException_get_dict(PyBaseExceptionObject *self)
207{
208 if (self->dict == NULL) {
209 self->dict = PyDict_New();
210 if (!self->dict)
211 return NULL;
212 }
213 Py_INCREF(self->dict);
214 return self->dict;
215}
216
217static int
218BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
219{
220 if (val == NULL) {
221 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
222 return -1;
223 }
224 if (!PyDict_Check(val)) {
225 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
226 return -1;
227 }
228 Py_CLEAR(self->dict);
229 Py_INCREF(val);
230 self->dict = val;
231 return 0;
232}
233
234static PyObject *
235BaseException_get_args(PyBaseExceptionObject *self)
236{
237 if (self->args == NULL) {
238 Py_INCREF(Py_None);
239 return Py_None;
240 }
241 Py_INCREF(self->args);
242 return self->args;
243}
244
245static int
246BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
247{
248 PyObject *seq;
249 if (val == NULL) {
250 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
251 return -1;
252 }
253 seq = PySequence_Tuple(val);
254 if (!seq) return -1;
Georg Brandlc7c51142006-05-29 09:46:51 +0000255 Py_CLEAR(self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000256 self->args = seq;
257 return 0;
258}
259
260static PyGetSetDef BaseException_getset[] = {
261 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
262 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
263 {NULL},
264};
265
266
267static PyTypeObject _PyExc_BaseException = {
268 PyObject_HEAD_INIT(NULL)
269 0, /*ob_size*/
270 EXC_MODULE_NAME "BaseException", /*tp_name*/
271 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
272 0, /*tp_itemsize*/
273 (destructor)BaseException_dealloc, /*tp_dealloc*/
274 0, /*tp_print*/
275 0, /*tp_getattr*/
276 0, /*tp_setattr*/
277 0, /* tp_compare; */
278 (reprfunc)BaseException_repr, /*tp_repr*/
279 0, /*tp_as_number*/
280 &BaseException_as_sequence, /*tp_as_sequence*/
281 0, /*tp_as_mapping*/
282 0, /*tp_hash */
283 0, /*tp_call*/
284 (reprfunc)BaseException_str, /*tp_str*/
285 PyObject_GenericGetAttr, /*tp_getattro*/
286 PyObject_GenericSetAttr, /*tp_setattro*/
287 0, /*tp_as_buffer*/
288 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
289 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
290 (traverseproc)BaseException_traverse, /* tp_traverse */
291 (inquiry)BaseException_clear, /* tp_clear */
292 0, /* tp_richcompare */
293 0, /* tp_weaklistoffset */
294 0, /* tp_iter */
295 0, /* tp_iternext */
296 BaseException_methods, /* tp_methods */
297 BaseException_members, /* tp_members */
298 BaseException_getset, /* tp_getset */
299 0, /* tp_base */
300 0, /* tp_dict */
301 0, /* tp_descr_get */
302 0, /* tp_descr_set */
303 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
304 (initproc)BaseException_init, /* tp_init */
305 0, /* tp_alloc */
306 BaseException_new, /* tp_new */
307};
308/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
309from the previous implmentation and also allowing Python objects to be used
310in the API */
311PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
312
Richard Jones2d555b32006-05-27 16:15:11 +0000313/* note these macros omit the last semicolon so the macro invocation may
314 * include it and not look strange.
315 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000316#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
317static PyTypeObject _PyExc_ ## EXCNAME = { \
318 PyObject_HEAD_INIT(NULL) \
319 0, \
320 EXC_MODULE_NAME # EXCNAME, \
321 sizeof(PyBaseExceptionObject), \
322 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
323 0, 0, 0, 0, 0, 0, 0, \
324 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
325 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
326 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
327 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
328 (initproc)BaseException_init, 0, BaseException_new,\
329}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000330PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000331
332#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
333static PyTypeObject _PyExc_ ## EXCNAME = { \
334 PyObject_HEAD_INIT(NULL) \
335 0, \
336 EXC_MODULE_NAME # EXCNAME, \
337 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000338 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000339 0, 0, 0, 0, 0, \
340 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000341 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
342 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000343 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000344 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000345}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000346PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000347
348#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
349static PyTypeObject _PyExc_ ## EXCNAME = { \
350 PyObject_HEAD_INIT(NULL) \
351 0, \
352 EXC_MODULE_NAME # EXCNAME, \
353 sizeof(Py ## EXCSTORE ## Object), 0, \
354 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
355 (reprfunc)EXCSTR, 0, 0, 0, \
356 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
357 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
358 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
359 EXCMEMBERS, 0, &_ ## EXCBASE, \
360 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000361 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000362}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000363PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000364
365
366/*
367 * Exception extends BaseException
368 */
369SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000370 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000371
372
373/*
374 * StandardError extends Exception
375 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000376SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000377 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000378 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000379
380
381/*
382 * TypeError extends StandardError
383 */
384SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000385 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000386
387
388/*
389 * StopIteration extends Exception
390 */
391SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000392 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000393
394
395/*
396 * GeneratorExit extends Exception
397 */
398SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000399 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000400
401
402/*
403 * SystemExit extends BaseException
404 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000405
406static int
407SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
408{
409 Py_ssize_t size = PyTuple_GET_SIZE(args);
410
411 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
412 return -1;
413
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000414 if (size == 0)
415 return 0;
416 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000417 if (size == 1)
418 self->code = PyTuple_GET_ITEM(args, 0);
419 else if (size > 1)
420 self->code = args;
421 Py_INCREF(self->code);
422 return 0;
423}
424
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000425static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000426SystemExit_clear(PySystemExitObject *self)
427{
428 Py_CLEAR(self->code);
429 return BaseException_clear((PyBaseExceptionObject *)self);
430}
431
432static void
433SystemExit_dealloc(PySystemExitObject *self)
434{
435 SystemExit_clear(self);
436 self->ob_type->tp_free((PyObject *)self);
437}
438
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000439static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000440SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
441{
442 Py_VISIT(self->code);
443 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
444}
445
446static PyMemberDef SystemExit_members[] = {
447 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
448 PyDoc_STR("exception message")},
449 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
450 PyDoc_STR("exception code")},
451 {NULL} /* Sentinel */
452};
453
454ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
455 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000456 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000457
458/*
459 * KeyboardInterrupt extends BaseException
460 */
461SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000462 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000463
464
465/*
466 * ImportError extends StandardError
467 */
468SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000469 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000470
471
472/*
473 * EnvironmentError extends StandardError
474 */
475
Richard Jones7b9558d2006-05-27 12:29:24 +0000476/* Where a function has a single filename, such as open() or some
477 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
478 * called, giving a third argument which is the filename. But, so
479 * that old code using in-place unpacking doesn't break, e.g.:
480 *
481 * except IOError, (errno, strerror):
482 *
483 * we hack args so that it only contains two items. This also
484 * means we need our own __str__() which prints out the filename
485 * when it was supplied.
486 */
487static int
488EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
489 PyObject *kwds)
490{
491 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
492 PyObject *subslice = NULL;
493
494 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
495 return -1;
496
497 if (PyTuple_GET_SIZE(args) <= 1) {
498 return 0;
499 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000500
501 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000502 &myerrno, &strerror, &filename)) {
503 return -1;
504 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000505 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000506 self->myerrno = myerrno;
507 Py_INCREF(self->myerrno);
508
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000509 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000510 self->strerror = strerror;
511 Py_INCREF(self->strerror);
512
513 /* self->filename will remain Py_None otherwise */
514 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000515 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000516 self->filename = filename;
517 Py_INCREF(self->filename);
518
519 subslice = PyTuple_GetSlice(args, 0, 2);
520 if (!subslice)
521 return -1;
522
523 Py_DECREF(self->args); /* replacing args */
524 self->args = subslice;
525 }
526 return 0;
527}
528
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000529static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000530EnvironmentError_clear(PyEnvironmentErrorObject *self)
531{
532 Py_CLEAR(self->myerrno);
533 Py_CLEAR(self->strerror);
534 Py_CLEAR(self->filename);
535 return BaseException_clear((PyBaseExceptionObject *)self);
536}
537
538static void
539EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
540{
541 EnvironmentError_clear(self);
542 self->ob_type->tp_free((PyObject *)self);
543}
544
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000545static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000546EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
547 void *arg)
548{
549 Py_VISIT(self->myerrno);
550 Py_VISIT(self->strerror);
551 Py_VISIT(self->filename);
552 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
553}
554
555static PyObject *
556EnvironmentError_str(PyEnvironmentErrorObject *self)
557{
558 PyObject *rtnval = NULL;
559
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000560 if (self->filename) {
561 PyObject *fmt;
562 PyObject *repr;
563 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000564
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000565 fmt = PyString_FromString("[Errno %s] %s: %s");
566 if (!fmt)
567 return NULL;
568
569 repr = PyObject_Repr(self->filename);
570 if (!repr) {
571 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000572 return NULL;
573 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000574 tuple = PyTuple_New(3);
575 if (!tuple) {
576 Py_DECREF(repr);
577 Py_DECREF(fmt);
578 return NULL;
579 }
580
581 if (self->myerrno) {
582 Py_INCREF(self->myerrno);
583 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
584 }
585 else {
586 Py_INCREF(Py_None);
587 PyTuple_SET_ITEM(tuple, 0, Py_None);
588 }
589 if (self->strerror) {
590 Py_INCREF(self->strerror);
591 PyTuple_SET_ITEM(tuple, 1, self->strerror);
592 }
593 else {
594 Py_INCREF(Py_None);
595 PyTuple_SET_ITEM(tuple, 1, Py_None);
596 }
597
Richard Jones7b9558d2006-05-27 12:29:24 +0000598 Py_INCREF(repr);
599 PyTuple_SET_ITEM(tuple, 2, repr);
600
601 rtnval = PyString_Format(fmt, tuple);
602
603 Py_DECREF(fmt);
604 Py_DECREF(tuple);
605 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000606 else if (self->myerrno && self->strerror) {
607 PyObject *fmt;
608 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000609
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000610 fmt = PyString_FromString("[Errno %s] %s");
611 if (!fmt)
612 return NULL;
613
614 tuple = PyTuple_New(2);
615 if (!tuple) {
616 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000617 return NULL;
618 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000619
620 if (self->myerrno) {
621 Py_INCREF(self->myerrno);
622 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
623 }
624 else {
625 Py_INCREF(Py_None);
626 PyTuple_SET_ITEM(tuple, 0, Py_None);
627 }
628 if (self->strerror) {
629 Py_INCREF(self->strerror);
630 PyTuple_SET_ITEM(tuple, 1, self->strerror);
631 }
632 else {
633 Py_INCREF(Py_None);
634 PyTuple_SET_ITEM(tuple, 1, Py_None);
635 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000636
637 rtnval = PyString_Format(fmt, tuple);
638
639 Py_DECREF(fmt);
640 Py_DECREF(tuple);
641 }
642 else
643 rtnval = BaseException_str((PyBaseExceptionObject *)self);
644
645 return rtnval;
646}
647
648static PyMemberDef EnvironmentError_members[] = {
649 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
650 PyDoc_STR("exception message")},
651 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000652 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000653 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000654 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000655 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000656 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000657 {NULL} /* Sentinel */
658};
659
660
661static PyObject *
662EnvironmentError_reduce(PyEnvironmentErrorObject *self)
663{
664 PyObject *args = self->args;
665 PyObject *res = NULL, *tmp;
Georg Brandl05f97bf2006-05-30 07:13:29 +0000666
Richard Jones7b9558d2006-05-27 12:29:24 +0000667 /* self->args is only the first two real arguments if there was a
668 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000669 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000670 args = PyTuple_New(3);
671 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000672
673 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000674 Py_INCREF(tmp);
675 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000676
677 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000678 Py_INCREF(tmp);
679 PyTuple_SET_ITEM(args, 1, tmp);
680
681 Py_INCREF(self->filename);
682 PyTuple_SET_ITEM(args, 2, self->filename);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000683 } else
Richard Jones7b9558d2006-05-27 12:29:24 +0000684 Py_INCREF(args);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000685
686 if (self->dict)
687 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
688 else
689 res = PyTuple_Pack(2, self->ob_type, args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000690 Py_DECREF(args);
691 return res;
692}
693
694
695static PyMethodDef EnvironmentError_methods[] = {
696 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
697 {NULL}
698};
699
700ComplexExtendsException(PyExc_StandardError, EnvironmentError,
701 EnvironmentError, EnvironmentError_dealloc,
702 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000703 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000704 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000705
706
707/*
708 * IOError extends EnvironmentError
709 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000710MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000711 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000712
713
714/*
715 * OSError extends EnvironmentError
716 */
717MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000718 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000719
720
721/*
722 * WindowsError extends OSError
723 */
724#ifdef MS_WINDOWS
725#include "errmap.h"
726
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000727static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000728WindowsError_clear(PyWindowsErrorObject *self)
729{
730 Py_CLEAR(self->myerrno);
731 Py_CLEAR(self->strerror);
732 Py_CLEAR(self->filename);
733 Py_CLEAR(self->winerror);
734 return BaseException_clear((PyBaseExceptionObject *)self);
735}
736
737static void
738WindowsError_dealloc(PyWindowsErrorObject *self)
739{
740 WindowsError_clear(self);
741 self->ob_type->tp_free((PyObject *)self);
742}
743
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000744static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000745WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
746{
747 Py_VISIT(self->myerrno);
748 Py_VISIT(self->strerror);
749 Py_VISIT(self->filename);
750 Py_VISIT(self->winerror);
751 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
752}
753
Richard Jones7b9558d2006-05-27 12:29:24 +0000754static int
755WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
756{
757 PyObject *o_errcode = NULL;
758 long errcode;
759 long posix_errno;
760
761 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
762 == -1)
763 return -1;
764
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000765 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000766 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000767
768 /* Set errno to the POSIX errno, and winerror to the Win32
769 error code. */
770 errcode = PyInt_AsLong(self->myerrno);
771 if (errcode == -1 && PyErr_Occurred())
772 return -1;
773 posix_errno = winerror_to_errno(errcode);
774
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000775 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000776 self->winerror = self->myerrno;
777
778 o_errcode = PyInt_FromLong(posix_errno);
779 if (!o_errcode)
780 return -1;
781
782 self->myerrno = o_errcode;
783
784 return 0;
785}
786
787
788static PyObject *
789WindowsError_str(PyWindowsErrorObject *self)
790{
Richard Jones7b9558d2006-05-27 12:29:24 +0000791 PyObject *rtnval = NULL;
792
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000793 if (self->filename) {
794 PyObject *fmt;
795 PyObject *repr;
796 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000797
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000798 fmt = PyString_FromString("[Error %s] %s: %s");
799 if (!fmt)
800 return NULL;
801
802 repr = PyObject_Repr(self->filename);
803 if (!repr) {
804 Py_DECREF(fmt);
805 return NULL;
806 }
807 tuple = PyTuple_New(3);
808 if (!tuple) {
809 Py_DECREF(repr);
810 Py_DECREF(fmt);
811 return NULL;
812 }
813
814 if (self->myerrno) {
815 Py_INCREF(self->myerrno);
816 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
817 }
818 else {
819 Py_INCREF(Py_None);
820 PyTuple_SET_ITEM(tuple, 0, Py_None);
821 }
822 if (self->strerror) {
823 Py_INCREF(self->strerror);
824 PyTuple_SET_ITEM(tuple, 1, self->strerror);
825 }
826 else {
827 Py_INCREF(Py_None);
828 PyTuple_SET_ITEM(tuple, 1, Py_None);
829 }
830
831 Py_INCREF(repr);
832 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000833
834 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000835
836 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000837 Py_DECREF(tuple);
838 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000839 else if (self->myerrno && self->strerror) {
840 PyObject *fmt;
841 PyObject *tuple;
842
Richard Jones7b9558d2006-05-27 12:29:24 +0000843 fmt = PyString_FromString("[Error %s] %s");
844 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000845 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000846
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000847 tuple = PyTuple_New(2);
848 if (!tuple) {
849 Py_DECREF(fmt);
850 return NULL;
851 }
852
853 if (self->myerrno) {
854 Py_INCREF(self->myerrno);
855 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
856 }
857 else {
858 Py_INCREF(Py_None);
859 PyTuple_SET_ITEM(tuple, 0, Py_None);
860 }
861 if (self->strerror) {
862 Py_INCREF(self->strerror);
863 PyTuple_SET_ITEM(tuple, 1, self->strerror);
864 }
865 else {
866 Py_INCREF(Py_None);
867 PyTuple_SET_ITEM(tuple, 1, Py_None);
868 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000869
870 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000871
872 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000873 Py_DECREF(tuple);
874 }
875 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000876 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000877
Richard Jones7b9558d2006-05-27 12:29:24 +0000878 return rtnval;
879}
880
881static PyMemberDef WindowsError_members[] = {
882 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
883 PyDoc_STR("exception message")},
884 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000885 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000886 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000887 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000888 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000889 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000890 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000891 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000892 {NULL} /* Sentinel */
893};
894
Richard Jones2d555b32006-05-27 16:15:11 +0000895ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
896 WindowsError_dealloc, 0, WindowsError_members,
897 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000898
899#endif /* MS_WINDOWS */
900
901
902/*
903 * VMSError extends OSError (I think)
904 */
905#ifdef __VMS
906MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000907 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000908#endif
909
910
911/*
912 * EOFError extends StandardError
913 */
914SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000915 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000916
917
918/*
919 * RuntimeError extends StandardError
920 */
921SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000922 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000923
924
925/*
926 * NotImplementedError extends RuntimeError
927 */
928SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000929 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000930
931/*
932 * NameError extends StandardError
933 */
934SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000935 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000936
937/*
938 * UnboundLocalError extends NameError
939 */
940SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000941 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000942
943/*
944 * AttributeError extends StandardError
945 */
946SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000947 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000948
949
950/*
951 * SyntaxError extends StandardError
952 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000953
954static int
955SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
956{
957 PyObject *info = NULL;
958 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
959
960 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
961 return -1;
962
963 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000964 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000965 self->msg = PyTuple_GET_ITEM(args, 0);
966 Py_INCREF(self->msg);
967 }
968 if (lenargs == 2) {
969 info = PyTuple_GET_ITEM(args, 1);
970 info = PySequence_Tuple(info);
971 if (!info) return -1;
972
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000973 if (PyTuple_GET_SIZE(info) != 4) {
974 /* not a very good error message, but it's what Python 2.4 gives */
975 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
976 Py_DECREF(info);
977 return -1;
978 }
979
980 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +0000981 self->filename = PyTuple_GET_ITEM(info, 0);
982 Py_INCREF(self->filename);
983
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000984 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +0000985 self->lineno = PyTuple_GET_ITEM(info, 1);
986 Py_INCREF(self->lineno);
987
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000988 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +0000989 self->offset = PyTuple_GET_ITEM(info, 2);
990 Py_INCREF(self->offset);
991
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000992 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +0000993 self->text = PyTuple_GET_ITEM(info, 3);
994 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000995
996 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +0000997 }
998 return 0;
999}
1000
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001001static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001002SyntaxError_clear(PySyntaxErrorObject *self)
1003{
1004 Py_CLEAR(self->msg);
1005 Py_CLEAR(self->filename);
1006 Py_CLEAR(self->lineno);
1007 Py_CLEAR(self->offset);
1008 Py_CLEAR(self->text);
1009 Py_CLEAR(self->print_file_and_line);
1010 return BaseException_clear((PyBaseExceptionObject *)self);
1011}
1012
1013static void
1014SyntaxError_dealloc(PySyntaxErrorObject *self)
1015{
1016 SyntaxError_clear(self);
1017 self->ob_type->tp_free((PyObject *)self);
1018}
1019
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001020static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001021SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1022{
1023 Py_VISIT(self->msg);
1024 Py_VISIT(self->filename);
1025 Py_VISIT(self->lineno);
1026 Py_VISIT(self->offset);
1027 Py_VISIT(self->text);
1028 Py_VISIT(self->print_file_and_line);
1029 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1030}
1031
1032/* This is called "my_basename" instead of just "basename" to avoid name
1033 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1034 defined, and Python does define that. */
1035static char *
1036my_basename(char *name)
1037{
1038 char *cp = name;
1039 char *result = name;
1040
1041 if (name == NULL)
1042 return "???";
1043 while (*cp != '\0') {
1044 if (*cp == SEP)
1045 result = cp + 1;
1046 ++cp;
1047 }
1048 return result;
1049}
1050
1051
1052static PyObject *
1053SyntaxError_str(PySyntaxErrorObject *self)
1054{
1055 PyObject *str;
1056 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001057 int have_filename = 0;
1058 int have_lineno = 0;
1059 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001060 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001061
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001062 if (self->msg)
1063 str = PyObject_Str(self->msg);
1064 else
1065 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001066 if (!str) return NULL;
1067 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1068 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001069
1070 /* XXX -- do all the additional formatting with filename and
1071 lineno here */
1072
Georg Brandl43ab1002006-05-28 20:57:09 +00001073 have_filename = (self->filename != NULL) &&
1074 PyString_Check(self->filename);
1075 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001076
Georg Brandl43ab1002006-05-28 20:57:09 +00001077 if (!have_filename && !have_lineno)
1078 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001079
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001080 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001081 if (have_filename)
1082 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001083
Georg Brandl43ab1002006-05-28 20:57:09 +00001084 buffer = PyMem_MALLOC(bufsize);
1085 if (buffer == NULL)
1086 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001087
Georg Brandl43ab1002006-05-28 20:57:09 +00001088 if (have_filename && have_lineno)
1089 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1090 PyString_AS_STRING(str),
1091 my_basename(PyString_AS_STRING(self->filename)),
1092 PyInt_AsLong(self->lineno));
1093 else if (have_filename)
1094 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1095 PyString_AS_STRING(str),
1096 my_basename(PyString_AS_STRING(self->filename)));
1097 else /* only have_lineno */
1098 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1099 PyString_AS_STRING(str),
1100 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001101
Georg Brandl43ab1002006-05-28 20:57:09 +00001102 result = PyString_FromString(buffer);
1103 PyMem_FREE(buffer);
1104
1105 if (result == NULL)
1106 result = str;
1107 else
1108 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001109 return result;
1110}
1111
1112static PyMemberDef SyntaxError_members[] = {
1113 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1114 PyDoc_STR("exception message")},
1115 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1116 PyDoc_STR("exception msg")},
1117 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1118 PyDoc_STR("exception filename")},
1119 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1120 PyDoc_STR("exception lineno")},
1121 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1122 PyDoc_STR("exception offset")},
1123 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1124 PyDoc_STR("exception text")},
1125 {"print_file_and_line", T_OBJECT,
1126 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1127 PyDoc_STR("exception print_file_and_line")},
1128 {NULL} /* Sentinel */
1129};
1130
1131ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1132 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001133 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001134
1135
1136/*
1137 * IndentationError extends SyntaxError
1138 */
1139MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001140 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001141
1142
1143/*
1144 * TabError extends IndentationError
1145 */
1146MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001147 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001148
1149
1150/*
1151 * LookupError extends StandardError
1152 */
1153SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001154 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001155
1156
1157/*
1158 * IndexError extends LookupError
1159 */
1160SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001161 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001162
1163
1164/*
1165 * KeyError extends LookupError
1166 */
1167static PyObject *
1168KeyError_str(PyBaseExceptionObject *self)
1169{
1170 /* If args is a tuple of exactly one item, apply repr to args[0].
1171 This is done so that e.g. the exception raised by {}[''] prints
1172 KeyError: ''
1173 rather than the confusing
1174 KeyError
1175 alone. The downside is that if KeyError is raised with an explanatory
1176 string, that string will be displayed in quotes. Too bad.
1177 If args is anything else, use the default BaseException__str__().
1178 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001179 if (PyTuple_GET_SIZE(self->args) == 1) {
1180 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001181 }
1182 return BaseException_str(self);
1183}
1184
1185ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001186 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001187
1188
1189/*
1190 * ValueError extends StandardError
1191 */
1192SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001193 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001194
1195/*
1196 * UnicodeError extends ValueError
1197 */
1198
1199SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001200 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001201
1202#ifdef Py_USING_UNICODE
1203static int
1204get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1205{
1206 if (!attr) {
1207 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1208 return -1;
1209 }
1210
1211 if (PyInt_Check(attr)) {
1212 *value = PyInt_AS_LONG(attr);
1213 } else if (PyLong_Check(attr)) {
1214 *value = _PyLong_AsSsize_t(attr);
1215 if (*value == -1 && PyErr_Occurred())
1216 return -1;
1217 } else {
1218 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1219 return -1;
1220 }
1221 return 0;
1222}
1223
1224static int
1225set_ssize_t(PyObject **attr, Py_ssize_t value)
1226{
1227 PyObject *obj = PyInt_FromSsize_t(value);
1228 if (!obj)
1229 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001230 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001231 *attr = obj;
1232 return 0;
1233}
1234
1235static PyObject *
1236get_string(PyObject *attr, const char *name)
1237{
1238 if (!attr) {
1239 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1240 return NULL;
1241 }
1242
1243 if (!PyString_Check(attr)) {
1244 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1245 return NULL;
1246 }
1247 Py_INCREF(attr);
1248 return attr;
1249}
1250
1251
1252static int
1253set_string(PyObject **attr, const char *value)
1254{
1255 PyObject *obj = PyString_FromString(value);
1256 if (!obj)
1257 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001258 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001259 *attr = obj;
1260 return 0;
1261}
1262
1263
1264static PyObject *
1265get_unicode(PyObject *attr, const char *name)
1266{
1267 if (!attr) {
1268 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1269 return NULL;
1270 }
1271
1272 if (!PyUnicode_Check(attr)) {
1273 PyErr_Format(PyExc_TypeError,
1274 "%.200s attribute must be unicode", name);
1275 return NULL;
1276 }
1277 Py_INCREF(attr);
1278 return attr;
1279}
1280
1281PyObject *
1282PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1283{
1284 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1285}
1286
1287PyObject *
1288PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1289{
1290 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1291}
1292
1293PyObject *
1294PyUnicodeEncodeError_GetObject(PyObject *exc)
1295{
1296 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1297}
1298
1299PyObject *
1300PyUnicodeDecodeError_GetObject(PyObject *exc)
1301{
1302 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1303}
1304
1305PyObject *
1306PyUnicodeTranslateError_GetObject(PyObject *exc)
1307{
1308 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1309}
1310
1311int
1312PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1313{
1314 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1315 Py_ssize_t size;
1316 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1317 "object");
1318 if (!obj) return -1;
1319 size = PyUnicode_GET_SIZE(obj);
1320 if (*start<0)
1321 *start = 0; /*XXX check for values <0*/
1322 if (*start>=size)
1323 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001324 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001325 return 0;
1326 }
1327 return -1;
1328}
1329
1330
1331int
1332PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1333{
1334 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1335 Py_ssize_t size;
1336 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1337 "object");
1338 if (!obj) return -1;
1339 size = PyString_GET_SIZE(obj);
1340 if (*start<0)
1341 *start = 0;
1342 if (*start>=size)
1343 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001344 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001345 return 0;
1346 }
1347 return -1;
1348}
1349
1350
1351int
1352PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1353{
1354 return PyUnicodeEncodeError_GetStart(exc, start);
1355}
1356
1357
1358int
1359PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1360{
1361 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1362}
1363
1364
1365int
1366PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1367{
1368 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1369}
1370
1371
1372int
1373PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1374{
1375 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1376}
1377
1378
1379int
1380PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1381{
1382 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1383 Py_ssize_t size;
1384 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1385 "object");
1386 if (!obj) return -1;
1387 size = PyUnicode_GET_SIZE(obj);
1388 if (*end<1)
1389 *end = 1;
1390 if (*end>size)
1391 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001392 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001393 return 0;
1394 }
1395 return -1;
1396}
1397
1398
1399int
1400PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1401{
1402 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1403 Py_ssize_t size;
1404 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1405 "object");
1406 if (!obj) return -1;
1407 size = PyString_GET_SIZE(obj);
1408 if (*end<1)
1409 *end = 1;
1410 if (*end>size)
1411 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001412 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001413 return 0;
1414 }
1415 return -1;
1416}
1417
1418
1419int
1420PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1421{
1422 return PyUnicodeEncodeError_GetEnd(exc, start);
1423}
1424
1425
1426int
1427PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1428{
1429 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1430}
1431
1432
1433int
1434PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1435{
1436 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1437}
1438
1439
1440int
1441PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1442{
1443 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1444}
1445
1446PyObject *
1447PyUnicodeEncodeError_GetReason(PyObject *exc)
1448{
1449 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1450}
1451
1452
1453PyObject *
1454PyUnicodeDecodeError_GetReason(PyObject *exc)
1455{
1456 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1457}
1458
1459
1460PyObject *
1461PyUnicodeTranslateError_GetReason(PyObject *exc)
1462{
1463 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1464}
1465
1466
1467int
1468PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1469{
1470 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1471}
1472
1473
1474int
1475PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1476{
1477 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1478}
1479
1480
1481int
1482PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1483{
1484 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1485}
1486
1487
Richard Jones7b9558d2006-05-27 12:29:24 +00001488static int
1489UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1490 PyTypeObject *objecttype)
1491{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001492 Py_CLEAR(self->encoding);
1493 Py_CLEAR(self->object);
1494 Py_CLEAR(self->start);
1495 Py_CLEAR(self->end);
1496 Py_CLEAR(self->reason);
1497
Richard Jones7b9558d2006-05-27 12:29:24 +00001498 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1499 &PyString_Type, &self->encoding,
1500 objecttype, &self->object,
1501 &PyInt_Type, &self->start,
1502 &PyInt_Type, &self->end,
1503 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001504 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001505 self->reason = NULL;
1506 return -1;
1507 }
1508
1509 Py_INCREF(self->encoding);
1510 Py_INCREF(self->object);
1511 Py_INCREF(self->start);
1512 Py_INCREF(self->end);
1513 Py_INCREF(self->reason);
1514
1515 return 0;
1516}
1517
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001518static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001519UnicodeError_clear(PyUnicodeErrorObject *self)
1520{
1521 Py_CLEAR(self->encoding);
1522 Py_CLEAR(self->object);
1523 Py_CLEAR(self->start);
1524 Py_CLEAR(self->end);
1525 Py_CLEAR(self->reason);
1526 return BaseException_clear((PyBaseExceptionObject *)self);
1527}
1528
1529static void
1530UnicodeError_dealloc(PyUnicodeErrorObject *self)
1531{
1532 UnicodeError_clear(self);
1533 self->ob_type->tp_free((PyObject *)self);
1534}
1535
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001536static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001537UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1538{
1539 Py_VISIT(self->encoding);
1540 Py_VISIT(self->object);
1541 Py_VISIT(self->start);
1542 Py_VISIT(self->end);
1543 Py_VISIT(self->reason);
1544 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1545}
1546
1547static PyMemberDef UnicodeError_members[] = {
1548 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1549 PyDoc_STR("exception message")},
1550 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1551 PyDoc_STR("exception encoding")},
1552 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1553 PyDoc_STR("exception object")},
1554 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1555 PyDoc_STR("exception start")},
1556 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1557 PyDoc_STR("exception end")},
1558 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1559 PyDoc_STR("exception reason")},
1560 {NULL} /* Sentinel */
1561};
1562
1563
1564/*
1565 * UnicodeEncodeError extends UnicodeError
1566 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001567
1568static int
1569UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1570{
1571 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1572 return -1;
1573 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1574 kwds, &PyUnicode_Type);
1575}
1576
1577static PyObject *
1578UnicodeEncodeError_str(PyObject *self)
1579{
1580 Py_ssize_t start;
1581 Py_ssize_t end;
1582
1583 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001584 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001585
1586 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001587 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001588
1589 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001590 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1591 char badchar_str[20];
1592 if (badchar <= 0xff)
1593 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1594 else if (badchar <= 0xffff)
1595 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1596 else
1597 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1598 return PyString_FromFormat(
1599 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1600 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1601 badchar_str,
1602 start,
1603 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1604 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001605 }
1606 return PyString_FromFormat(
1607 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1608 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1609 start,
1610 (end-1),
1611 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1612 );
1613}
1614
1615static PyTypeObject _PyExc_UnicodeEncodeError = {
1616 PyObject_HEAD_INIT(NULL)
1617 0,
1618 "UnicodeEncodeError",
1619 sizeof(PyUnicodeErrorObject), 0,
1620 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1621 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1622 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001623 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1624 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001625 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001626 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001627};
1628PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1629
1630PyObject *
1631PyUnicodeEncodeError_Create(
1632 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1633 Py_ssize_t start, Py_ssize_t end, const char *reason)
1634{
1635 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001636 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001637}
1638
1639
1640/*
1641 * UnicodeDecodeError extends UnicodeError
1642 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001643
1644static int
1645UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1646{
1647 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1648 return -1;
1649 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1650 kwds, &PyString_Type);
1651}
1652
1653static PyObject *
1654UnicodeDecodeError_str(PyObject *self)
1655{
Georg Brandl43ab1002006-05-28 20:57:09 +00001656 Py_ssize_t start = 0;
1657 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001658
1659 if (PyUnicodeDecodeError_GetStart(self, &start))
1660 return NULL;
1661
1662 if (PyUnicodeDecodeError_GetEnd(self, &end))
1663 return NULL;
1664
1665 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001666 /* FromFormat does not support %02x, so format that separately */
1667 char byte[4];
1668 PyOS_snprintf(byte, sizeof(byte), "%02x",
1669 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1670 return PyString_FromFormat(
1671 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1672 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1673 byte,
1674 start,
1675 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1676 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001677 }
1678 return PyString_FromFormat(
1679 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1680 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1681 start,
1682 (end-1),
1683 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1684 );
1685}
1686
1687static PyTypeObject _PyExc_UnicodeDecodeError = {
1688 PyObject_HEAD_INIT(NULL)
1689 0,
1690 EXC_MODULE_NAME "UnicodeDecodeError",
1691 sizeof(PyUnicodeErrorObject), 0,
1692 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1693 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1694 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001695 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1696 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001697 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001698 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001699};
1700PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1701
1702PyObject *
1703PyUnicodeDecodeError_Create(
1704 const char *encoding, const char *object, Py_ssize_t length,
1705 Py_ssize_t start, Py_ssize_t end, const char *reason)
1706{
1707 assert(length < INT_MAX);
1708 assert(start < INT_MAX);
1709 assert(end < INT_MAX);
1710 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001711 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001712}
1713
1714
1715/*
1716 * UnicodeTranslateError extends UnicodeError
1717 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001718
1719static int
1720UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1721 PyObject *kwds)
1722{
1723 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1724 return -1;
1725
1726 Py_CLEAR(self->object);
1727 Py_CLEAR(self->start);
1728 Py_CLEAR(self->end);
1729 Py_CLEAR(self->reason);
1730
1731 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1732 &PyUnicode_Type, &self->object,
1733 &PyInt_Type, &self->start,
1734 &PyInt_Type, &self->end,
1735 &PyString_Type, &self->reason)) {
1736 self->object = self->start = self->end = self->reason = NULL;
1737 return -1;
1738 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001739
Richard Jones7b9558d2006-05-27 12:29:24 +00001740 Py_INCREF(self->object);
1741 Py_INCREF(self->start);
1742 Py_INCREF(self->end);
1743 Py_INCREF(self->reason);
1744
1745 return 0;
1746}
1747
1748
1749static PyObject *
1750UnicodeTranslateError_str(PyObject *self)
1751{
1752 Py_ssize_t start;
1753 Py_ssize_t end;
1754
1755 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001756 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001757
1758 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001759 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001760
1761 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001762 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1763 char badchar_str[20];
1764 if (badchar <= 0xff)
1765 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1766 else if (badchar <= 0xffff)
1767 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1768 else
1769 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1770 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001771 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001772 badchar_str,
1773 start,
1774 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1775 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001776 }
1777 return PyString_FromFormat(
1778 "can't translate characters in position %zd-%zd: %.400s",
1779 start,
1780 (end-1),
1781 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1782 );
1783}
1784
1785static PyTypeObject _PyExc_UnicodeTranslateError = {
1786 PyObject_HEAD_INIT(NULL)
1787 0,
1788 EXC_MODULE_NAME "UnicodeTranslateError",
1789 sizeof(PyUnicodeErrorObject), 0,
1790 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1791 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1792 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1793 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1794 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1795 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001796 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001797};
1798PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1799
1800PyObject *
1801PyUnicodeTranslateError_Create(
1802 const Py_UNICODE *object, Py_ssize_t length,
1803 Py_ssize_t start, Py_ssize_t end, const char *reason)
1804{
1805 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001806 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001807}
1808#endif
1809
1810
1811/*
1812 * AssertionError extends StandardError
1813 */
1814SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001815 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001816
1817
1818/*
1819 * ArithmeticError extends StandardError
1820 */
1821SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001822 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001823
1824
1825/*
1826 * FloatingPointError extends ArithmeticError
1827 */
1828SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001829 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001830
1831
1832/*
1833 * OverflowError extends ArithmeticError
1834 */
1835SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001836 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001837
1838
1839/*
1840 * ZeroDivisionError extends ArithmeticError
1841 */
1842SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001843 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001844
1845
1846/*
1847 * SystemError extends StandardError
1848 */
1849SimpleExtendsException(PyExc_StandardError, SystemError,
1850 "Internal error in the Python interpreter.\n"
1851 "\n"
1852 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001853 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001854
1855
1856/*
1857 * ReferenceError extends StandardError
1858 */
1859SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001860 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001861
1862
1863/*
1864 * MemoryError extends StandardError
1865 */
Richard Jones2d555b32006-05-27 16:15:11 +00001866SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001867
1868
1869/* Warning category docstrings */
1870
1871/*
1872 * Warning extends Exception
1873 */
1874SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001875 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001876
1877
1878/*
1879 * UserWarning extends Warning
1880 */
1881SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001882 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001883
1884
1885/*
1886 * DeprecationWarning extends Warning
1887 */
1888SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001889 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001890
1891
1892/*
1893 * PendingDeprecationWarning extends Warning
1894 */
1895SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1896 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001897 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001898
1899
1900/*
1901 * SyntaxWarning extends Warning
1902 */
1903SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001904 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001905
1906
1907/*
1908 * RuntimeWarning extends Warning
1909 */
1910SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001911 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001912
1913
1914/*
1915 * FutureWarning extends Warning
1916 */
1917SimpleExtendsException(PyExc_Warning, FutureWarning,
1918 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001919 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001920
1921
1922/*
1923 * ImportWarning extends Warning
1924 */
1925SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001926 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001927
1928
1929/* Pre-computed MemoryError instance. Best to create this as early as
1930 * possible and not wait until a MemoryError is actually raised!
1931 */
1932PyObject *PyExc_MemoryErrorInst=NULL;
1933
1934/* module global functions */
1935static PyMethodDef functions[] = {
1936 /* Sentinel */
1937 {NULL, NULL}
1938};
1939
1940#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1941 Py_FatalError("exceptions bootstrapping error.");
1942
1943#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1944 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1945 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1946 Py_FatalError("Module dictionary insertion problem.");
1947
1948PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001949_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001950{
1951 PyObject *m, *bltinmod, *bdict;
1952
1953 PRE_INIT(BaseException)
1954 PRE_INIT(Exception)
1955 PRE_INIT(StandardError)
1956 PRE_INIT(TypeError)
1957 PRE_INIT(StopIteration)
1958 PRE_INIT(GeneratorExit)
1959 PRE_INIT(SystemExit)
1960 PRE_INIT(KeyboardInterrupt)
1961 PRE_INIT(ImportError)
1962 PRE_INIT(EnvironmentError)
1963 PRE_INIT(IOError)
1964 PRE_INIT(OSError)
1965#ifdef MS_WINDOWS
1966 PRE_INIT(WindowsError)
1967#endif
1968#ifdef __VMS
1969 PRE_INIT(VMSError)
1970#endif
1971 PRE_INIT(EOFError)
1972 PRE_INIT(RuntimeError)
1973 PRE_INIT(NotImplementedError)
1974 PRE_INIT(NameError)
1975 PRE_INIT(UnboundLocalError)
1976 PRE_INIT(AttributeError)
1977 PRE_INIT(SyntaxError)
1978 PRE_INIT(IndentationError)
1979 PRE_INIT(TabError)
1980 PRE_INIT(LookupError)
1981 PRE_INIT(IndexError)
1982 PRE_INIT(KeyError)
1983 PRE_INIT(ValueError)
1984 PRE_INIT(UnicodeError)
1985#ifdef Py_USING_UNICODE
1986 PRE_INIT(UnicodeEncodeError)
1987 PRE_INIT(UnicodeDecodeError)
1988 PRE_INIT(UnicodeTranslateError)
1989#endif
1990 PRE_INIT(AssertionError)
1991 PRE_INIT(ArithmeticError)
1992 PRE_INIT(FloatingPointError)
1993 PRE_INIT(OverflowError)
1994 PRE_INIT(ZeroDivisionError)
1995 PRE_INIT(SystemError)
1996 PRE_INIT(ReferenceError)
1997 PRE_INIT(MemoryError)
1998 PRE_INIT(Warning)
1999 PRE_INIT(UserWarning)
2000 PRE_INIT(DeprecationWarning)
2001 PRE_INIT(PendingDeprecationWarning)
2002 PRE_INIT(SyntaxWarning)
2003 PRE_INIT(RuntimeWarning)
2004 PRE_INIT(FutureWarning)
2005 PRE_INIT(ImportWarning)
2006
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00002007 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2008 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00002009 if (m == NULL) return;
2010
2011 bltinmod = PyImport_ImportModule("__builtin__");
2012 if (bltinmod == NULL)
2013 Py_FatalError("exceptions bootstrapping error.");
2014 bdict = PyModule_GetDict(bltinmod);
2015 if (bdict == NULL)
2016 Py_FatalError("exceptions bootstrapping error.");
2017
2018 POST_INIT(BaseException)
2019 POST_INIT(Exception)
2020 POST_INIT(StandardError)
2021 POST_INIT(TypeError)
2022 POST_INIT(StopIteration)
2023 POST_INIT(GeneratorExit)
2024 POST_INIT(SystemExit)
2025 POST_INIT(KeyboardInterrupt)
2026 POST_INIT(ImportError)
2027 POST_INIT(EnvironmentError)
2028 POST_INIT(IOError)
2029 POST_INIT(OSError)
2030#ifdef MS_WINDOWS
2031 POST_INIT(WindowsError)
2032#endif
2033#ifdef __VMS
2034 POST_INIT(VMSError)
2035#endif
2036 POST_INIT(EOFError)
2037 POST_INIT(RuntimeError)
2038 POST_INIT(NotImplementedError)
2039 POST_INIT(NameError)
2040 POST_INIT(UnboundLocalError)
2041 POST_INIT(AttributeError)
2042 POST_INIT(SyntaxError)
2043 POST_INIT(IndentationError)
2044 POST_INIT(TabError)
2045 POST_INIT(LookupError)
2046 POST_INIT(IndexError)
2047 POST_INIT(KeyError)
2048 POST_INIT(ValueError)
2049 POST_INIT(UnicodeError)
2050#ifdef Py_USING_UNICODE
2051 POST_INIT(UnicodeEncodeError)
2052 POST_INIT(UnicodeDecodeError)
2053 POST_INIT(UnicodeTranslateError)
2054#endif
2055 POST_INIT(AssertionError)
2056 POST_INIT(ArithmeticError)
2057 POST_INIT(FloatingPointError)
2058 POST_INIT(OverflowError)
2059 POST_INIT(ZeroDivisionError)
2060 POST_INIT(SystemError)
2061 POST_INIT(ReferenceError)
2062 POST_INIT(MemoryError)
2063 POST_INIT(Warning)
2064 POST_INIT(UserWarning)
2065 POST_INIT(DeprecationWarning)
2066 POST_INIT(PendingDeprecationWarning)
2067 POST_INIT(SyntaxWarning)
2068 POST_INIT(RuntimeWarning)
2069 POST_INIT(FutureWarning)
2070 POST_INIT(ImportWarning)
2071
2072 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2073 if (!PyExc_MemoryErrorInst)
2074 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2075
2076 Py_DECREF(bltinmod);
2077}
2078
2079void
2080_PyExc_Fini(void)
2081{
2082 Py_XDECREF(PyExc_MemoryErrorInst);
2083 PyExc_MemoryErrorInst = NULL;
2084}