blob: 2ac45fbdae6f0cf08e994c09502ad9a6fcb6ee2f [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{
144 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
145}
146
147
148#ifdef Py_USING_UNICODE
149/* while this method generates fairly uninspired output, it a least
150 * guarantees that we can display exceptions that have unicode attributes
151 */
152static PyObject *
153BaseException_unicode(PyBaseExceptionObject *self)
154{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000155 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000156 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000157 if (PyTuple_GET_SIZE(self->args) == 1)
158 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000159 return PyObject_Unicode(self->args);
160}
161#endif /* Py_USING_UNICODE */
162
163static PyMethodDef BaseException_methods[] = {
164 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
165#ifdef Py_USING_UNICODE
166 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
167#endif
168 {NULL, NULL, 0, NULL},
169};
170
171
172
173static PyObject *
174BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
175{
176 return PySequence_GetItem(self->args, index);
177}
178
179static PySequenceMethods BaseException_as_sequence = {
180 0, /* sq_length; */
181 0, /* sq_concat; */
182 0, /* sq_repeat; */
183 (ssizeargfunc)BaseException_getitem, /* sq_item; */
184 0, /* sq_slice; */
185 0, /* sq_ass_item; */
186 0, /* sq_ass_slice; */
187 0, /* sq_contains; */
188 0, /* sq_inplace_concat; */
189 0 /* sq_inplace_repeat; */
190};
191
192static PyMemberDef BaseException_members[] = {
193 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
194 PyDoc_STR("exception message")},
195 {NULL} /* Sentinel */
196};
197
198
199static PyObject *
200BaseException_get_dict(PyBaseExceptionObject *self)
201{
202 if (self->dict == NULL) {
203 self->dict = PyDict_New();
204 if (!self->dict)
205 return NULL;
206 }
207 Py_INCREF(self->dict);
208 return self->dict;
209}
210
211static int
212BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
213{
214 if (val == NULL) {
215 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
216 return -1;
217 }
218 if (!PyDict_Check(val)) {
219 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
220 return -1;
221 }
222 Py_CLEAR(self->dict);
223 Py_INCREF(val);
224 self->dict = val;
225 return 0;
226}
227
228static PyObject *
229BaseException_get_args(PyBaseExceptionObject *self)
230{
231 if (self->args == NULL) {
232 Py_INCREF(Py_None);
233 return Py_None;
234 }
235 Py_INCREF(self->args);
236 return self->args;
237}
238
239static int
240BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
241{
242 PyObject *seq;
243 if (val == NULL) {
244 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
245 return -1;
246 }
247 seq = PySequence_Tuple(val);
248 if (!seq) return -1;
249 self->args = seq;
250 return 0;
251}
252
253static PyGetSetDef BaseException_getset[] = {
254 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
255 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
256 {NULL},
257};
258
259
260static PyTypeObject _PyExc_BaseException = {
261 PyObject_HEAD_INIT(NULL)
262 0, /*ob_size*/
263 EXC_MODULE_NAME "BaseException", /*tp_name*/
264 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
265 0, /*tp_itemsize*/
266 (destructor)BaseException_dealloc, /*tp_dealloc*/
267 0, /*tp_print*/
268 0, /*tp_getattr*/
269 0, /*tp_setattr*/
270 0, /* tp_compare; */
271 (reprfunc)BaseException_repr, /*tp_repr*/
272 0, /*tp_as_number*/
273 &BaseException_as_sequence, /*tp_as_sequence*/
274 0, /*tp_as_mapping*/
275 0, /*tp_hash */
276 0, /*tp_call*/
277 (reprfunc)BaseException_str, /*tp_str*/
278 PyObject_GenericGetAttr, /*tp_getattro*/
279 PyObject_GenericSetAttr, /*tp_setattro*/
280 0, /*tp_as_buffer*/
281 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
282 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
283 (traverseproc)BaseException_traverse, /* tp_traverse */
284 (inquiry)BaseException_clear, /* tp_clear */
285 0, /* tp_richcompare */
286 0, /* tp_weaklistoffset */
287 0, /* tp_iter */
288 0, /* tp_iternext */
289 BaseException_methods, /* tp_methods */
290 BaseException_members, /* tp_members */
291 BaseException_getset, /* tp_getset */
292 0, /* tp_base */
293 0, /* tp_dict */
294 0, /* tp_descr_get */
295 0, /* tp_descr_set */
296 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
297 (initproc)BaseException_init, /* tp_init */
298 0, /* tp_alloc */
299 BaseException_new, /* tp_new */
300};
301/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
302from the previous implmentation and also allowing Python objects to be used
303in the API */
304PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
305
Richard Jones2d555b32006-05-27 16:15:11 +0000306/* note these macros omit the last semicolon so the macro invocation may
307 * include it and not look strange.
308 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000309#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
310static PyTypeObject _PyExc_ ## EXCNAME = { \
311 PyObject_HEAD_INIT(NULL) \
312 0, \
313 EXC_MODULE_NAME # EXCNAME, \
314 sizeof(PyBaseExceptionObject), \
315 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
316 0, 0, 0, 0, 0, 0, 0, \
317 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
318 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
319 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
320 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
321 (initproc)BaseException_init, 0, BaseException_new,\
322}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000323PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000324
325#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
326static PyTypeObject _PyExc_ ## EXCNAME = { \
327 PyObject_HEAD_INIT(NULL) \
328 0, \
329 EXC_MODULE_NAME # EXCNAME, \
330 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000331 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000332 0, 0, 0, 0, 0, \
333 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000334 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
335 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000336 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000337 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000338}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000339PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000340
341#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
342static PyTypeObject _PyExc_ ## EXCNAME = { \
343 PyObject_HEAD_INIT(NULL) \
344 0, \
345 EXC_MODULE_NAME # EXCNAME, \
346 sizeof(Py ## EXCSTORE ## Object), 0, \
347 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
348 (reprfunc)EXCSTR, 0, 0, 0, \
349 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
350 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
351 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
352 EXCMEMBERS, 0, &_ ## EXCBASE, \
353 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000354 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000355}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000356PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000357
358
359/*
360 * Exception extends BaseException
361 */
362SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000363 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000364
365
366/*
367 * StandardError extends Exception
368 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000369SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000370 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000371 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000372
373
374/*
375 * TypeError extends StandardError
376 */
377SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000378 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000379
380
381/*
382 * StopIteration extends Exception
383 */
384SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000385 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000386
387
388/*
389 * GeneratorExit extends Exception
390 */
391SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000392 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000393
394
395/*
396 * SystemExit extends BaseException
397 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000398
399static int
400SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
401{
402 Py_ssize_t size = PyTuple_GET_SIZE(args);
403
404 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
405 return -1;
406
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000407 if (size == 0)
408 return 0;
409 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000410 if (size == 1)
411 self->code = PyTuple_GET_ITEM(args, 0);
412 else if (size > 1)
413 self->code = args;
414 Py_INCREF(self->code);
415 return 0;
416}
417
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000418static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000419SystemExit_clear(PySystemExitObject *self)
420{
421 Py_CLEAR(self->code);
422 return BaseException_clear((PyBaseExceptionObject *)self);
423}
424
425static void
426SystemExit_dealloc(PySystemExitObject *self)
427{
428 SystemExit_clear(self);
429 self->ob_type->tp_free((PyObject *)self);
430}
431
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000432static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000433SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
434{
435 Py_VISIT(self->code);
436 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
437}
438
439static PyMemberDef SystemExit_members[] = {
440 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
441 PyDoc_STR("exception message")},
442 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
443 PyDoc_STR("exception code")},
444 {NULL} /* Sentinel */
445};
446
447ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
448 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000449 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000450
451/*
452 * KeyboardInterrupt extends BaseException
453 */
454SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000455 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000456
457
458/*
459 * ImportError extends StandardError
460 */
461SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000462 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000463
464
465/*
466 * EnvironmentError extends StandardError
467 */
468
Richard Jones7b9558d2006-05-27 12:29:24 +0000469/* Where a function has a single filename, such as open() or some
470 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
471 * called, giving a third argument which is the filename. But, so
472 * that old code using in-place unpacking doesn't break, e.g.:
473 *
474 * except IOError, (errno, strerror):
475 *
476 * we hack args so that it only contains two items. This also
477 * means we need our own __str__() which prints out the filename
478 * when it was supplied.
479 */
480static int
481EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
482 PyObject *kwds)
483{
484 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
485 PyObject *subslice = NULL;
486
487 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
488 return -1;
489
490 if (PyTuple_GET_SIZE(args) <= 1) {
491 return 0;
492 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000493
494 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000495 &myerrno, &strerror, &filename)) {
496 return -1;
497 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000498 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000499 self->myerrno = myerrno;
500 Py_INCREF(self->myerrno);
501
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000502 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000503 self->strerror = strerror;
504 Py_INCREF(self->strerror);
505
506 /* self->filename will remain Py_None otherwise */
507 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000508 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000509 self->filename = filename;
510 Py_INCREF(self->filename);
511
512 subslice = PyTuple_GetSlice(args, 0, 2);
513 if (!subslice)
514 return -1;
515
516 Py_DECREF(self->args); /* replacing args */
517 self->args = subslice;
518 }
519 return 0;
520}
521
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000522static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000523EnvironmentError_clear(PyEnvironmentErrorObject *self)
524{
525 Py_CLEAR(self->myerrno);
526 Py_CLEAR(self->strerror);
527 Py_CLEAR(self->filename);
528 return BaseException_clear((PyBaseExceptionObject *)self);
529}
530
531static void
532EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
533{
534 EnvironmentError_clear(self);
535 self->ob_type->tp_free((PyObject *)self);
536}
537
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000538static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000539EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
540 void *arg)
541{
542 Py_VISIT(self->myerrno);
543 Py_VISIT(self->strerror);
544 Py_VISIT(self->filename);
545 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
546}
547
548static PyObject *
549EnvironmentError_str(PyEnvironmentErrorObject *self)
550{
551 PyObject *rtnval = NULL;
552
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000553 if (self->filename) {
554 PyObject *fmt;
555 PyObject *repr;
556 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000557
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000558 fmt = PyString_FromString("[Errno %s] %s: %s");
559 if (!fmt)
560 return NULL;
561
562 repr = PyObject_Repr(self->filename);
563 if (!repr) {
564 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000565 return NULL;
566 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000567 tuple = PyTuple_New(3);
568 if (!tuple) {
569 Py_DECREF(repr);
570 Py_DECREF(fmt);
571 return NULL;
572 }
573
574 if (self->myerrno) {
575 Py_INCREF(self->myerrno);
576 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
577 }
578 else {
579 Py_INCREF(Py_None);
580 PyTuple_SET_ITEM(tuple, 0, Py_None);
581 }
582 if (self->strerror) {
583 Py_INCREF(self->strerror);
584 PyTuple_SET_ITEM(tuple, 1, self->strerror);
585 }
586 else {
587 Py_INCREF(Py_None);
588 PyTuple_SET_ITEM(tuple, 1, Py_None);
589 }
590
Richard Jones7b9558d2006-05-27 12:29:24 +0000591 Py_INCREF(repr);
592 PyTuple_SET_ITEM(tuple, 2, repr);
593
594 rtnval = PyString_Format(fmt, tuple);
595
596 Py_DECREF(fmt);
597 Py_DECREF(tuple);
598 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000599 else if (self->myerrno && self->strerror) {
600 PyObject *fmt;
601 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000602
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000603 fmt = PyString_FromString("[Errno %s] %s");
604 if (!fmt)
605 return NULL;
606
607 tuple = PyTuple_New(2);
608 if (!tuple) {
609 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000610 return NULL;
611 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000612
613 if (self->myerrno) {
614 Py_INCREF(self->myerrno);
615 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
616 }
617 else {
618 Py_INCREF(Py_None);
619 PyTuple_SET_ITEM(tuple, 0, Py_None);
620 }
621 if (self->strerror) {
622 Py_INCREF(self->strerror);
623 PyTuple_SET_ITEM(tuple, 1, self->strerror);
624 }
625 else {
626 Py_INCREF(Py_None);
627 PyTuple_SET_ITEM(tuple, 1, Py_None);
628 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000629
630 rtnval = PyString_Format(fmt, tuple);
631
632 Py_DECREF(fmt);
633 Py_DECREF(tuple);
634 }
635 else
636 rtnval = BaseException_str((PyBaseExceptionObject *)self);
637
638 return rtnval;
639}
640
641static PyMemberDef EnvironmentError_members[] = {
642 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
643 PyDoc_STR("exception message")},
644 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000645 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000646 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000647 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000648 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000649 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000650 {NULL} /* Sentinel */
651};
652
653
654static PyObject *
655EnvironmentError_reduce(PyEnvironmentErrorObject *self)
656{
657 PyObject *args = self->args;
658 PyObject *res = NULL, *tmp;
659 /* self->args is only the first two real arguments if there was a
660 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000661 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000662 args = PyTuple_New(3);
663 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000664
665 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000666 Py_INCREF(tmp);
667 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000668
669 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000670 Py_INCREF(tmp);
671 PyTuple_SET_ITEM(args, 1, tmp);
672
673 Py_INCREF(self->filename);
674 PyTuple_SET_ITEM(args, 2, self->filename);
675 } else {
676 Py_INCREF(args);
677 }
678 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +0000679 Py_DECREF(args);
680 return res;
681}
682
683
684static PyMethodDef EnvironmentError_methods[] = {
685 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
686 {NULL}
687};
688
689ComplexExtendsException(PyExc_StandardError, EnvironmentError,
690 EnvironmentError, EnvironmentError_dealloc,
691 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000692 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000693 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000694
695
696/*
697 * IOError extends EnvironmentError
698 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000699MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000700 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000701
702
703/*
704 * OSError extends EnvironmentError
705 */
706MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000707 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000708
709
710/*
711 * WindowsError extends OSError
712 */
713#ifdef MS_WINDOWS
714#include "errmap.h"
715
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000716static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000717WindowsError_clear(PyWindowsErrorObject *self)
718{
719 Py_CLEAR(self->myerrno);
720 Py_CLEAR(self->strerror);
721 Py_CLEAR(self->filename);
722 Py_CLEAR(self->winerror);
723 return BaseException_clear((PyBaseExceptionObject *)self);
724}
725
726static void
727WindowsError_dealloc(PyWindowsErrorObject *self)
728{
729 WindowsError_clear(self);
730 self->ob_type->tp_free((PyObject *)self);
731}
732
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000733static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000734WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
735{
736 Py_VISIT(self->myerrno);
737 Py_VISIT(self->strerror);
738 Py_VISIT(self->filename);
739 Py_VISIT(self->winerror);
740 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
741}
742
Richard Jones7b9558d2006-05-27 12:29:24 +0000743static int
744WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
745{
746 PyObject *o_errcode = NULL;
747 long errcode;
748 long posix_errno;
749
750 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
751 == -1)
752 return -1;
753
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000754 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000755 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000756
757 /* Set errno to the POSIX errno, and winerror to the Win32
758 error code. */
759 errcode = PyInt_AsLong(self->myerrno);
760 if (errcode == -1 && PyErr_Occurred())
761 return -1;
762 posix_errno = winerror_to_errno(errcode);
763
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000764 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000765 self->winerror = self->myerrno;
766
767 o_errcode = PyInt_FromLong(posix_errno);
768 if (!o_errcode)
769 return -1;
770
771 self->myerrno = o_errcode;
772
773 return 0;
774}
775
776
777static PyObject *
778WindowsError_str(PyWindowsErrorObject *self)
779{
Richard Jones7b9558d2006-05-27 12:29:24 +0000780 PyObject *rtnval = NULL;
781
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000782 if (self->filename) {
783 PyObject *fmt;
784 PyObject *repr;
785 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000786
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000787 fmt = PyString_FromString("[Error %s] %s: %s");
788 if (!fmt)
789 return NULL;
790
791 repr = PyObject_Repr(self->filename);
792 if (!repr) {
793 Py_DECREF(fmt);
794 return NULL;
795 }
796 tuple = PyTuple_New(3);
797 if (!tuple) {
798 Py_DECREF(repr);
799 Py_DECREF(fmt);
800 return NULL;
801 }
802
803 if (self->myerrno) {
804 Py_INCREF(self->myerrno);
805 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
806 }
807 else {
808 Py_INCREF(Py_None);
809 PyTuple_SET_ITEM(tuple, 0, Py_None);
810 }
811 if (self->strerror) {
812 Py_INCREF(self->strerror);
813 PyTuple_SET_ITEM(tuple, 1, self->strerror);
814 }
815 else {
816 Py_INCREF(Py_None);
817 PyTuple_SET_ITEM(tuple, 1, Py_None);
818 }
819
820 Py_INCREF(repr);
821 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000822
823 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000824
825 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000826 Py_DECREF(tuple);
827 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000828 else if (self->myerrno && self->strerror) {
829 PyObject *fmt;
830 PyObject *tuple;
831
Richard Jones7b9558d2006-05-27 12:29:24 +0000832 fmt = PyString_FromString("[Error %s] %s");
833 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000834 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000835
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000836 tuple = PyTuple_New(2);
837 if (!tuple) {
838 Py_DECREF(fmt);
839 return NULL;
840 }
841
842 if (self->myerrno) {
843 Py_INCREF(self->myerrno);
844 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
845 }
846 else {
847 Py_INCREF(Py_None);
848 PyTuple_SET_ITEM(tuple, 0, Py_None);
849 }
850 if (self->strerror) {
851 Py_INCREF(self->strerror);
852 PyTuple_SET_ITEM(tuple, 1, self->strerror);
853 }
854 else {
855 Py_INCREF(Py_None);
856 PyTuple_SET_ITEM(tuple, 1, Py_None);
857 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000858
859 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000860
861 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000862 Py_DECREF(tuple);
863 }
864 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000865 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000866
Richard Jones7b9558d2006-05-27 12:29:24 +0000867 return rtnval;
868}
869
870static PyMemberDef WindowsError_members[] = {
871 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
872 PyDoc_STR("exception message")},
873 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000874 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000875 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000876 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000877 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000878 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000879 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000880 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000881 {NULL} /* Sentinel */
882};
883
Richard Jones2d555b32006-05-27 16:15:11 +0000884ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
885 WindowsError_dealloc, 0, WindowsError_members,
886 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000887
888#endif /* MS_WINDOWS */
889
890
891/*
892 * VMSError extends OSError (I think)
893 */
894#ifdef __VMS
895MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000896 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000897#endif
898
899
900/*
901 * EOFError extends StandardError
902 */
903SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000904 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000905
906
907/*
908 * RuntimeError extends StandardError
909 */
910SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000911 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000912
913
914/*
915 * NotImplementedError extends RuntimeError
916 */
917SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000918 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000919
920/*
921 * NameError extends StandardError
922 */
923SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000924 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000925
926/*
927 * UnboundLocalError extends NameError
928 */
929SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000930 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000931
932/*
933 * AttributeError extends StandardError
934 */
935SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000936 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000937
938
939/*
940 * SyntaxError extends StandardError
941 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000942
943static int
944SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
945{
946 PyObject *info = NULL;
947 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
948
949 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
950 return -1;
951
952 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000953 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000954 self->msg = PyTuple_GET_ITEM(args, 0);
955 Py_INCREF(self->msg);
956 }
957 if (lenargs == 2) {
958 info = PyTuple_GET_ITEM(args, 1);
959 info = PySequence_Tuple(info);
960 if (!info) return -1;
961
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000962 if (PyTuple_GET_SIZE(info) != 4) {
963 /* not a very good error message, but it's what Python 2.4 gives */
964 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
965 Py_DECREF(info);
966 return -1;
967 }
968
969 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +0000970 self->filename = PyTuple_GET_ITEM(info, 0);
971 Py_INCREF(self->filename);
972
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000973 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +0000974 self->lineno = PyTuple_GET_ITEM(info, 1);
975 Py_INCREF(self->lineno);
976
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000977 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +0000978 self->offset = PyTuple_GET_ITEM(info, 2);
979 Py_INCREF(self->offset);
980
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000981 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +0000982 self->text = PyTuple_GET_ITEM(info, 3);
983 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000984
985 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +0000986 }
987 return 0;
988}
989
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000990static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000991SyntaxError_clear(PySyntaxErrorObject *self)
992{
993 Py_CLEAR(self->msg);
994 Py_CLEAR(self->filename);
995 Py_CLEAR(self->lineno);
996 Py_CLEAR(self->offset);
997 Py_CLEAR(self->text);
998 Py_CLEAR(self->print_file_and_line);
999 return BaseException_clear((PyBaseExceptionObject *)self);
1000}
1001
1002static void
1003SyntaxError_dealloc(PySyntaxErrorObject *self)
1004{
1005 SyntaxError_clear(self);
1006 self->ob_type->tp_free((PyObject *)self);
1007}
1008
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001009static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001010SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1011{
1012 Py_VISIT(self->msg);
1013 Py_VISIT(self->filename);
1014 Py_VISIT(self->lineno);
1015 Py_VISIT(self->offset);
1016 Py_VISIT(self->text);
1017 Py_VISIT(self->print_file_and_line);
1018 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1019}
1020
1021/* This is called "my_basename" instead of just "basename" to avoid name
1022 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1023 defined, and Python does define that. */
1024static char *
1025my_basename(char *name)
1026{
1027 char *cp = name;
1028 char *result = name;
1029
1030 if (name == NULL)
1031 return "???";
1032 while (*cp != '\0') {
1033 if (*cp == SEP)
1034 result = cp + 1;
1035 ++cp;
1036 }
1037 return result;
1038}
1039
1040
1041static PyObject *
1042SyntaxError_str(PySyntaxErrorObject *self)
1043{
1044 PyObject *str;
1045 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001046 int have_filename = 0;
1047 int have_lineno = 0;
1048 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001049 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001050
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001051 if (self->msg)
1052 str = PyObject_Str(self->msg);
1053 else
1054 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001055 if (!str) return NULL;
1056 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1057 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001058
1059 /* XXX -- do all the additional formatting with filename and
1060 lineno here */
1061
Georg Brandl43ab1002006-05-28 20:57:09 +00001062 have_filename = (self->filename != NULL) &&
1063 PyString_Check(self->filename);
1064 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001065
Georg Brandl43ab1002006-05-28 20:57:09 +00001066 if (!have_filename && !have_lineno)
1067 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001068
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001069 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001070 if (have_filename)
1071 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001072
Georg Brandl43ab1002006-05-28 20:57:09 +00001073 buffer = PyMem_MALLOC(bufsize);
1074 if (buffer == NULL)
1075 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001076
Georg Brandl43ab1002006-05-28 20:57:09 +00001077 if (have_filename && have_lineno)
1078 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1079 PyString_AS_STRING(str),
1080 my_basename(PyString_AS_STRING(self->filename)),
1081 PyInt_AsLong(self->lineno));
1082 else if (have_filename)
1083 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1084 PyString_AS_STRING(str),
1085 my_basename(PyString_AS_STRING(self->filename)));
1086 else /* only have_lineno */
1087 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1088 PyString_AS_STRING(str),
1089 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001090
Georg Brandl43ab1002006-05-28 20:57:09 +00001091 result = PyString_FromString(buffer);
1092 PyMem_FREE(buffer);
1093
1094 if (result == NULL)
1095 result = str;
1096 else
1097 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001098 return result;
1099}
1100
1101static PyMemberDef SyntaxError_members[] = {
1102 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1103 PyDoc_STR("exception message")},
1104 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1105 PyDoc_STR("exception msg")},
1106 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1107 PyDoc_STR("exception filename")},
1108 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1109 PyDoc_STR("exception lineno")},
1110 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1111 PyDoc_STR("exception offset")},
1112 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1113 PyDoc_STR("exception text")},
1114 {"print_file_and_line", T_OBJECT,
1115 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1116 PyDoc_STR("exception print_file_and_line")},
1117 {NULL} /* Sentinel */
1118};
1119
1120ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1121 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001122 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001123
1124
1125/*
1126 * IndentationError extends SyntaxError
1127 */
1128MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001129 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001130
1131
1132/*
1133 * TabError extends IndentationError
1134 */
1135MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001136 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001137
1138
1139/*
1140 * LookupError extends StandardError
1141 */
1142SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001143 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001144
1145
1146/*
1147 * IndexError extends LookupError
1148 */
1149SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001150 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001151
1152
1153/*
1154 * KeyError extends LookupError
1155 */
1156static PyObject *
1157KeyError_str(PyBaseExceptionObject *self)
1158{
1159 /* If args is a tuple of exactly one item, apply repr to args[0].
1160 This is done so that e.g. the exception raised by {}[''] prints
1161 KeyError: ''
1162 rather than the confusing
1163 KeyError
1164 alone. The downside is that if KeyError is raised with an explanatory
1165 string, that string will be displayed in quotes. Too bad.
1166 If args is anything else, use the default BaseException__str__().
1167 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001168 if (PyTuple_GET_SIZE(self->args) == 1) {
1169 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001170 }
1171 return BaseException_str(self);
1172}
1173
1174ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001175 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001176
1177
1178/*
1179 * ValueError extends StandardError
1180 */
1181SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001182 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001183
1184/*
1185 * UnicodeError extends ValueError
1186 */
1187
1188SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001189 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001190
1191#ifdef Py_USING_UNICODE
1192static int
1193get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1194{
1195 if (!attr) {
1196 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1197 return -1;
1198 }
1199
1200 if (PyInt_Check(attr)) {
1201 *value = PyInt_AS_LONG(attr);
1202 } else if (PyLong_Check(attr)) {
1203 *value = _PyLong_AsSsize_t(attr);
1204 if (*value == -1 && PyErr_Occurred())
1205 return -1;
1206 } else {
1207 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1208 return -1;
1209 }
1210 return 0;
1211}
1212
1213static int
1214set_ssize_t(PyObject **attr, Py_ssize_t value)
1215{
1216 PyObject *obj = PyInt_FromSsize_t(value);
1217 if (!obj)
1218 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001219 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001220 *attr = obj;
1221 return 0;
1222}
1223
1224static PyObject *
1225get_string(PyObject *attr, const char *name)
1226{
1227 if (!attr) {
1228 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1229 return NULL;
1230 }
1231
1232 if (!PyString_Check(attr)) {
1233 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1234 return NULL;
1235 }
1236 Py_INCREF(attr);
1237 return attr;
1238}
1239
1240
1241static int
1242set_string(PyObject **attr, const char *value)
1243{
1244 PyObject *obj = PyString_FromString(value);
1245 if (!obj)
1246 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001247 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001248 *attr = obj;
1249 return 0;
1250}
1251
1252
1253static PyObject *
1254get_unicode(PyObject *attr, const char *name)
1255{
1256 if (!attr) {
1257 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1258 return NULL;
1259 }
1260
1261 if (!PyUnicode_Check(attr)) {
1262 PyErr_Format(PyExc_TypeError,
1263 "%.200s attribute must be unicode", name);
1264 return NULL;
1265 }
1266 Py_INCREF(attr);
1267 return attr;
1268}
1269
1270PyObject *
1271PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1272{
1273 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1274}
1275
1276PyObject *
1277PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1278{
1279 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1280}
1281
1282PyObject *
1283PyUnicodeEncodeError_GetObject(PyObject *exc)
1284{
1285 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1286}
1287
1288PyObject *
1289PyUnicodeDecodeError_GetObject(PyObject *exc)
1290{
1291 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1292}
1293
1294PyObject *
1295PyUnicodeTranslateError_GetObject(PyObject *exc)
1296{
1297 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1298}
1299
1300int
1301PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1302{
1303 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1304 Py_ssize_t size;
1305 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1306 "object");
1307 if (!obj) return -1;
1308 size = PyUnicode_GET_SIZE(obj);
1309 if (*start<0)
1310 *start = 0; /*XXX check for values <0*/
1311 if (*start>=size)
1312 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001313 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001314 return 0;
1315 }
1316 return -1;
1317}
1318
1319
1320int
1321PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1322{
1323 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1324 Py_ssize_t size;
1325 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1326 "object");
1327 if (!obj) return -1;
1328 size = PyString_GET_SIZE(obj);
1329 if (*start<0)
1330 *start = 0;
1331 if (*start>=size)
1332 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001333 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001334 return 0;
1335 }
1336 return -1;
1337}
1338
1339
1340int
1341PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1342{
1343 return PyUnicodeEncodeError_GetStart(exc, start);
1344}
1345
1346
1347int
1348PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1349{
1350 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1351}
1352
1353
1354int
1355PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1356{
1357 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1358}
1359
1360
1361int
1362PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1363{
1364 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1365}
1366
1367
1368int
1369PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1370{
1371 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1372 Py_ssize_t size;
1373 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1374 "object");
1375 if (!obj) return -1;
1376 size = PyUnicode_GET_SIZE(obj);
1377 if (*end<1)
1378 *end = 1;
1379 if (*end>size)
1380 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001381 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001382 return 0;
1383 }
1384 return -1;
1385}
1386
1387
1388int
1389PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1390{
1391 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1392 Py_ssize_t size;
1393 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1394 "object");
1395 if (!obj) return -1;
1396 size = PyString_GET_SIZE(obj);
1397 if (*end<1)
1398 *end = 1;
1399 if (*end>size)
1400 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001401 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001402 return 0;
1403 }
1404 return -1;
1405}
1406
1407
1408int
1409PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1410{
1411 return PyUnicodeEncodeError_GetEnd(exc, start);
1412}
1413
1414
1415int
1416PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1417{
1418 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1419}
1420
1421
1422int
1423PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1424{
1425 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1426}
1427
1428
1429int
1430PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1431{
1432 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1433}
1434
1435PyObject *
1436PyUnicodeEncodeError_GetReason(PyObject *exc)
1437{
1438 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1439}
1440
1441
1442PyObject *
1443PyUnicodeDecodeError_GetReason(PyObject *exc)
1444{
1445 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1446}
1447
1448
1449PyObject *
1450PyUnicodeTranslateError_GetReason(PyObject *exc)
1451{
1452 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1453}
1454
1455
1456int
1457PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1458{
1459 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1460}
1461
1462
1463int
1464PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1465{
1466 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1467}
1468
1469
1470int
1471PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1472{
1473 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1474}
1475
1476
Richard Jones7b9558d2006-05-27 12:29:24 +00001477static int
1478UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1479 PyTypeObject *objecttype)
1480{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001481 Py_CLEAR(self->encoding);
1482 Py_CLEAR(self->object);
1483 Py_CLEAR(self->start);
1484 Py_CLEAR(self->end);
1485 Py_CLEAR(self->reason);
1486
Richard Jones7b9558d2006-05-27 12:29:24 +00001487 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1488 &PyString_Type, &self->encoding,
1489 objecttype, &self->object,
1490 &PyInt_Type, &self->start,
1491 &PyInt_Type, &self->end,
1492 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001493 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001494 self->reason = NULL;
1495 return -1;
1496 }
1497
1498 Py_INCREF(self->encoding);
1499 Py_INCREF(self->object);
1500 Py_INCREF(self->start);
1501 Py_INCREF(self->end);
1502 Py_INCREF(self->reason);
1503
1504 return 0;
1505}
1506
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001507static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001508UnicodeError_clear(PyUnicodeErrorObject *self)
1509{
1510 Py_CLEAR(self->encoding);
1511 Py_CLEAR(self->object);
1512 Py_CLEAR(self->start);
1513 Py_CLEAR(self->end);
1514 Py_CLEAR(self->reason);
1515 return BaseException_clear((PyBaseExceptionObject *)self);
1516}
1517
1518static void
1519UnicodeError_dealloc(PyUnicodeErrorObject *self)
1520{
1521 UnicodeError_clear(self);
1522 self->ob_type->tp_free((PyObject *)self);
1523}
1524
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001525static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001526UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1527{
1528 Py_VISIT(self->encoding);
1529 Py_VISIT(self->object);
1530 Py_VISIT(self->start);
1531 Py_VISIT(self->end);
1532 Py_VISIT(self->reason);
1533 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1534}
1535
1536static PyMemberDef UnicodeError_members[] = {
1537 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1538 PyDoc_STR("exception message")},
1539 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1540 PyDoc_STR("exception encoding")},
1541 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1542 PyDoc_STR("exception object")},
1543 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1544 PyDoc_STR("exception start")},
1545 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1546 PyDoc_STR("exception end")},
1547 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1548 PyDoc_STR("exception reason")},
1549 {NULL} /* Sentinel */
1550};
1551
1552
1553/*
1554 * UnicodeEncodeError extends UnicodeError
1555 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001556
1557static int
1558UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1559{
1560 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1561 return -1;
1562 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1563 kwds, &PyUnicode_Type);
1564}
1565
1566static PyObject *
1567UnicodeEncodeError_str(PyObject *self)
1568{
1569 Py_ssize_t start;
1570 Py_ssize_t end;
1571
1572 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001573 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001574
1575 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001576 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001577
1578 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001579 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1580 char badchar_str[20];
1581 if (badchar <= 0xff)
1582 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1583 else if (badchar <= 0xffff)
1584 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1585 else
1586 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1587 return PyString_FromFormat(
1588 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1589 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1590 badchar_str,
1591 start,
1592 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1593 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001594 }
1595 return PyString_FromFormat(
1596 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1597 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1598 start,
1599 (end-1),
1600 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1601 );
1602}
1603
1604static PyTypeObject _PyExc_UnicodeEncodeError = {
1605 PyObject_HEAD_INIT(NULL)
1606 0,
1607 "UnicodeEncodeError",
1608 sizeof(PyUnicodeErrorObject), 0,
1609 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1610 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1611 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001612 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1613 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001614 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001615 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001616};
1617PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1618
1619PyObject *
1620PyUnicodeEncodeError_Create(
1621 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1622 Py_ssize_t start, Py_ssize_t end, const char *reason)
1623{
1624 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001625 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001626}
1627
1628
1629/*
1630 * UnicodeDecodeError extends UnicodeError
1631 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001632
1633static int
1634UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1635{
1636 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1637 return -1;
1638 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1639 kwds, &PyString_Type);
1640}
1641
1642static PyObject *
1643UnicodeDecodeError_str(PyObject *self)
1644{
Georg Brandl43ab1002006-05-28 20:57:09 +00001645 Py_ssize_t start = 0;
1646 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001647
1648 if (PyUnicodeDecodeError_GetStart(self, &start))
1649 return NULL;
1650
1651 if (PyUnicodeDecodeError_GetEnd(self, &end))
1652 return NULL;
1653
1654 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001655 /* FromFormat does not support %02x, so format that separately */
1656 char byte[4];
1657 PyOS_snprintf(byte, sizeof(byte), "%02x",
1658 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1659 return PyString_FromFormat(
1660 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1661 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1662 byte,
1663 start,
1664 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1665 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001666 }
1667 return PyString_FromFormat(
1668 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1669 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1670 start,
1671 (end-1),
1672 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1673 );
1674}
1675
1676static PyTypeObject _PyExc_UnicodeDecodeError = {
1677 PyObject_HEAD_INIT(NULL)
1678 0,
1679 EXC_MODULE_NAME "UnicodeDecodeError",
1680 sizeof(PyUnicodeErrorObject), 0,
1681 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1682 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1683 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001684 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1685 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001686 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001687 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001688};
1689PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1690
1691PyObject *
1692PyUnicodeDecodeError_Create(
1693 const char *encoding, const char *object, Py_ssize_t length,
1694 Py_ssize_t start, Py_ssize_t end, const char *reason)
1695{
1696 assert(length < INT_MAX);
1697 assert(start < INT_MAX);
1698 assert(end < INT_MAX);
1699 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001700 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001701}
1702
1703
1704/*
1705 * UnicodeTranslateError extends UnicodeError
1706 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001707
1708static int
1709UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1710 PyObject *kwds)
1711{
1712 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1713 return -1;
1714
1715 Py_CLEAR(self->object);
1716 Py_CLEAR(self->start);
1717 Py_CLEAR(self->end);
1718 Py_CLEAR(self->reason);
1719
1720 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1721 &PyUnicode_Type, &self->object,
1722 &PyInt_Type, &self->start,
1723 &PyInt_Type, &self->end,
1724 &PyString_Type, &self->reason)) {
1725 self->object = self->start = self->end = self->reason = NULL;
1726 return -1;
1727 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001728
Richard Jones7b9558d2006-05-27 12:29:24 +00001729 Py_INCREF(self->object);
1730 Py_INCREF(self->start);
1731 Py_INCREF(self->end);
1732 Py_INCREF(self->reason);
1733
1734 return 0;
1735}
1736
1737
1738static PyObject *
1739UnicodeTranslateError_str(PyObject *self)
1740{
1741 Py_ssize_t start;
1742 Py_ssize_t end;
1743
1744 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001745 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001746
1747 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001748 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001749
1750 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001751 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1752 char badchar_str[20];
1753 if (badchar <= 0xff)
1754 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1755 else if (badchar <= 0xffff)
1756 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1757 else
1758 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1759 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001760 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001761 badchar_str,
1762 start,
1763 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1764 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001765 }
1766 return PyString_FromFormat(
1767 "can't translate characters in position %zd-%zd: %.400s",
1768 start,
1769 (end-1),
1770 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1771 );
1772}
1773
1774static PyTypeObject _PyExc_UnicodeTranslateError = {
1775 PyObject_HEAD_INIT(NULL)
1776 0,
1777 EXC_MODULE_NAME "UnicodeTranslateError",
1778 sizeof(PyUnicodeErrorObject), 0,
1779 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1780 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1781 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1782 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1783 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1784 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001785 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001786};
1787PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1788
1789PyObject *
1790PyUnicodeTranslateError_Create(
1791 const Py_UNICODE *object, Py_ssize_t length,
1792 Py_ssize_t start, Py_ssize_t end, const char *reason)
1793{
1794 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001795 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001796}
1797#endif
1798
1799
1800/*
1801 * AssertionError extends StandardError
1802 */
1803SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001804 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001805
1806
1807/*
1808 * ArithmeticError extends StandardError
1809 */
1810SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001811 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001812
1813
1814/*
1815 * FloatingPointError extends ArithmeticError
1816 */
1817SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001818 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001819
1820
1821/*
1822 * OverflowError extends ArithmeticError
1823 */
1824SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001825 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001826
1827
1828/*
1829 * ZeroDivisionError extends ArithmeticError
1830 */
1831SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001832 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001833
1834
1835/*
1836 * SystemError extends StandardError
1837 */
1838SimpleExtendsException(PyExc_StandardError, SystemError,
1839 "Internal error in the Python interpreter.\n"
1840 "\n"
1841 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001842 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001843
1844
1845/*
1846 * ReferenceError extends StandardError
1847 */
1848SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001849 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001850
1851
1852/*
1853 * MemoryError extends StandardError
1854 */
Richard Jones2d555b32006-05-27 16:15:11 +00001855SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001856
1857
1858/* Warning category docstrings */
1859
1860/*
1861 * Warning extends Exception
1862 */
1863SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001864 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001865
1866
1867/*
1868 * UserWarning extends Warning
1869 */
1870SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001871 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001872
1873
1874/*
1875 * DeprecationWarning extends Warning
1876 */
1877SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001878 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001879
1880
1881/*
1882 * PendingDeprecationWarning extends Warning
1883 */
1884SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1885 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001886 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001887
1888
1889/*
1890 * SyntaxWarning extends Warning
1891 */
1892SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001893 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001894
1895
1896/*
1897 * RuntimeWarning extends Warning
1898 */
1899SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001900 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001901
1902
1903/*
1904 * FutureWarning extends Warning
1905 */
1906SimpleExtendsException(PyExc_Warning, FutureWarning,
1907 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001908 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001909
1910
1911/*
1912 * ImportWarning extends Warning
1913 */
1914SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001915 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001916
1917
1918/* Pre-computed MemoryError instance. Best to create this as early as
1919 * possible and not wait until a MemoryError is actually raised!
1920 */
1921PyObject *PyExc_MemoryErrorInst=NULL;
1922
1923/* module global functions */
1924static PyMethodDef functions[] = {
1925 /* Sentinel */
1926 {NULL, NULL}
1927};
1928
1929#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1930 Py_FatalError("exceptions bootstrapping error.");
1931
1932#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1933 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1934 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1935 Py_FatalError("Module dictionary insertion problem.");
1936
1937PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001938_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001939{
1940 PyObject *m, *bltinmod, *bdict;
1941
1942 PRE_INIT(BaseException)
1943 PRE_INIT(Exception)
1944 PRE_INIT(StandardError)
1945 PRE_INIT(TypeError)
1946 PRE_INIT(StopIteration)
1947 PRE_INIT(GeneratorExit)
1948 PRE_INIT(SystemExit)
1949 PRE_INIT(KeyboardInterrupt)
1950 PRE_INIT(ImportError)
1951 PRE_INIT(EnvironmentError)
1952 PRE_INIT(IOError)
1953 PRE_INIT(OSError)
1954#ifdef MS_WINDOWS
1955 PRE_INIT(WindowsError)
1956#endif
1957#ifdef __VMS
1958 PRE_INIT(VMSError)
1959#endif
1960 PRE_INIT(EOFError)
1961 PRE_INIT(RuntimeError)
1962 PRE_INIT(NotImplementedError)
1963 PRE_INIT(NameError)
1964 PRE_INIT(UnboundLocalError)
1965 PRE_INIT(AttributeError)
1966 PRE_INIT(SyntaxError)
1967 PRE_INIT(IndentationError)
1968 PRE_INIT(TabError)
1969 PRE_INIT(LookupError)
1970 PRE_INIT(IndexError)
1971 PRE_INIT(KeyError)
1972 PRE_INIT(ValueError)
1973 PRE_INIT(UnicodeError)
1974#ifdef Py_USING_UNICODE
1975 PRE_INIT(UnicodeEncodeError)
1976 PRE_INIT(UnicodeDecodeError)
1977 PRE_INIT(UnicodeTranslateError)
1978#endif
1979 PRE_INIT(AssertionError)
1980 PRE_INIT(ArithmeticError)
1981 PRE_INIT(FloatingPointError)
1982 PRE_INIT(OverflowError)
1983 PRE_INIT(ZeroDivisionError)
1984 PRE_INIT(SystemError)
1985 PRE_INIT(ReferenceError)
1986 PRE_INIT(MemoryError)
1987 PRE_INIT(Warning)
1988 PRE_INIT(UserWarning)
1989 PRE_INIT(DeprecationWarning)
1990 PRE_INIT(PendingDeprecationWarning)
1991 PRE_INIT(SyntaxWarning)
1992 PRE_INIT(RuntimeWarning)
1993 PRE_INIT(FutureWarning)
1994 PRE_INIT(ImportWarning)
1995
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00001996 m = Py_InitModule4("exceptions", functions, exceptions_doc,
1997 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00001998 if (m == NULL) return;
1999
2000 bltinmod = PyImport_ImportModule("__builtin__");
2001 if (bltinmod == NULL)
2002 Py_FatalError("exceptions bootstrapping error.");
2003 bdict = PyModule_GetDict(bltinmod);
2004 if (bdict == NULL)
2005 Py_FatalError("exceptions bootstrapping error.");
2006
2007 POST_INIT(BaseException)
2008 POST_INIT(Exception)
2009 POST_INIT(StandardError)
2010 POST_INIT(TypeError)
2011 POST_INIT(StopIteration)
2012 POST_INIT(GeneratorExit)
2013 POST_INIT(SystemExit)
2014 POST_INIT(KeyboardInterrupt)
2015 POST_INIT(ImportError)
2016 POST_INIT(EnvironmentError)
2017 POST_INIT(IOError)
2018 POST_INIT(OSError)
2019#ifdef MS_WINDOWS
2020 POST_INIT(WindowsError)
2021#endif
2022#ifdef __VMS
2023 POST_INIT(VMSError)
2024#endif
2025 POST_INIT(EOFError)
2026 POST_INIT(RuntimeError)
2027 POST_INIT(NotImplementedError)
2028 POST_INIT(NameError)
2029 POST_INIT(UnboundLocalError)
2030 POST_INIT(AttributeError)
2031 POST_INIT(SyntaxError)
2032 POST_INIT(IndentationError)
2033 POST_INIT(TabError)
2034 POST_INIT(LookupError)
2035 POST_INIT(IndexError)
2036 POST_INIT(KeyError)
2037 POST_INIT(ValueError)
2038 POST_INIT(UnicodeError)
2039#ifdef Py_USING_UNICODE
2040 POST_INIT(UnicodeEncodeError)
2041 POST_INIT(UnicodeDecodeError)
2042 POST_INIT(UnicodeTranslateError)
2043#endif
2044 POST_INIT(AssertionError)
2045 POST_INIT(ArithmeticError)
2046 POST_INIT(FloatingPointError)
2047 POST_INIT(OverflowError)
2048 POST_INIT(ZeroDivisionError)
2049 POST_INIT(SystemError)
2050 POST_INIT(ReferenceError)
2051 POST_INIT(MemoryError)
2052 POST_INIT(Warning)
2053 POST_INIT(UserWarning)
2054 POST_INIT(DeprecationWarning)
2055 POST_INIT(PendingDeprecationWarning)
2056 POST_INIT(SyntaxWarning)
2057 POST_INIT(RuntimeWarning)
2058 POST_INIT(FutureWarning)
2059 POST_INIT(ImportWarning)
2060
2061 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2062 if (!PyExc_MemoryErrorInst)
2063 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2064
2065 Py_DECREF(bltinmod);
2066}
2067
2068void
2069_PyExc_Fini(void)
2070{
2071 Py_XDECREF(PyExc_MemoryErrorInst);
2072 PyExc_MemoryErrorInst = NULL;
2073}