blob: 44c8fd65a5c3136a7b4ffa24f4892bf95c12989c [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;
Georg Brandlc7c51142006-05-29 09:46:51 +0000249 Py_CLEAR(self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000250 self->args = seq;
251 return 0;
252}
253
254static PyGetSetDef BaseException_getset[] = {
255 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
256 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
257 {NULL},
258};
259
260
261static PyTypeObject _PyExc_BaseException = {
262 PyObject_HEAD_INIT(NULL)
263 0, /*ob_size*/
264 EXC_MODULE_NAME "BaseException", /*tp_name*/
265 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
266 0, /*tp_itemsize*/
267 (destructor)BaseException_dealloc, /*tp_dealloc*/
268 0, /*tp_print*/
269 0, /*tp_getattr*/
270 0, /*tp_setattr*/
271 0, /* tp_compare; */
272 (reprfunc)BaseException_repr, /*tp_repr*/
273 0, /*tp_as_number*/
274 &BaseException_as_sequence, /*tp_as_sequence*/
275 0, /*tp_as_mapping*/
276 0, /*tp_hash */
277 0, /*tp_call*/
278 (reprfunc)BaseException_str, /*tp_str*/
279 PyObject_GenericGetAttr, /*tp_getattro*/
280 PyObject_GenericSetAttr, /*tp_setattro*/
281 0, /*tp_as_buffer*/
282 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
283 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
284 (traverseproc)BaseException_traverse, /* tp_traverse */
285 (inquiry)BaseException_clear, /* tp_clear */
286 0, /* tp_richcompare */
287 0, /* tp_weaklistoffset */
288 0, /* tp_iter */
289 0, /* tp_iternext */
290 BaseException_methods, /* tp_methods */
291 BaseException_members, /* tp_members */
292 BaseException_getset, /* tp_getset */
293 0, /* tp_base */
294 0, /* tp_dict */
295 0, /* tp_descr_get */
296 0, /* tp_descr_set */
297 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
298 (initproc)BaseException_init, /* tp_init */
299 0, /* tp_alloc */
300 BaseException_new, /* tp_new */
301};
302/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
303from the previous implmentation and also allowing Python objects to be used
304in the API */
305PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
306
Richard Jones2d555b32006-05-27 16:15:11 +0000307/* note these macros omit the last semicolon so the macro invocation may
308 * include it and not look strange.
309 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000310#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
311static PyTypeObject _PyExc_ ## EXCNAME = { \
312 PyObject_HEAD_INIT(NULL) \
313 0, \
314 EXC_MODULE_NAME # EXCNAME, \
315 sizeof(PyBaseExceptionObject), \
316 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
317 0, 0, 0, 0, 0, 0, 0, \
318 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
319 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
320 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
321 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
322 (initproc)BaseException_init, 0, BaseException_new,\
323}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000324PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000325
326#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
327static PyTypeObject _PyExc_ ## EXCNAME = { \
328 PyObject_HEAD_INIT(NULL) \
329 0, \
330 EXC_MODULE_NAME # EXCNAME, \
331 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000332 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000333 0, 0, 0, 0, 0, \
334 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000335 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
336 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000337 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000338 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000339}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000340PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000341
342#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
343static PyTypeObject _PyExc_ ## EXCNAME = { \
344 PyObject_HEAD_INIT(NULL) \
345 0, \
346 EXC_MODULE_NAME # EXCNAME, \
347 sizeof(Py ## EXCSTORE ## Object), 0, \
348 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
349 (reprfunc)EXCSTR, 0, 0, 0, \
350 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
351 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
352 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
353 EXCMEMBERS, 0, &_ ## EXCBASE, \
354 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000355 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000356}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000357PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000358
359
360/*
361 * Exception extends BaseException
362 */
363SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000364 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000365
366
367/*
368 * StandardError extends Exception
369 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000370SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000371 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000372 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000373
374
375/*
376 * TypeError extends StandardError
377 */
378SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000379 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000380
381
382/*
383 * StopIteration extends Exception
384 */
385SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000386 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000387
388
389/*
390 * GeneratorExit extends Exception
391 */
392SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000393 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000394
395
396/*
397 * SystemExit extends BaseException
398 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000399
400static int
401SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
402{
403 Py_ssize_t size = PyTuple_GET_SIZE(args);
404
405 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
406 return -1;
407
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000408 if (size == 0)
409 return 0;
410 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000411 if (size == 1)
412 self->code = PyTuple_GET_ITEM(args, 0);
413 else if (size > 1)
414 self->code = args;
415 Py_INCREF(self->code);
416 return 0;
417}
418
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000419static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000420SystemExit_clear(PySystemExitObject *self)
421{
422 Py_CLEAR(self->code);
423 return BaseException_clear((PyBaseExceptionObject *)self);
424}
425
426static void
427SystemExit_dealloc(PySystemExitObject *self)
428{
429 SystemExit_clear(self);
430 self->ob_type->tp_free((PyObject *)self);
431}
432
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000433static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000434SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
435{
436 Py_VISIT(self->code);
437 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
438}
439
440static PyMemberDef SystemExit_members[] = {
441 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
442 PyDoc_STR("exception message")},
443 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
444 PyDoc_STR("exception code")},
445 {NULL} /* Sentinel */
446};
447
448ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
449 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000450 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000451
452/*
453 * KeyboardInterrupt extends BaseException
454 */
455SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000456 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000457
458
459/*
460 * ImportError extends StandardError
461 */
462SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000463 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000464
465
466/*
467 * EnvironmentError extends StandardError
468 */
469
Richard Jones7b9558d2006-05-27 12:29:24 +0000470/* Where a function has a single filename, such as open() or some
471 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
472 * called, giving a third argument which is the filename. But, so
473 * that old code using in-place unpacking doesn't break, e.g.:
474 *
475 * except IOError, (errno, strerror):
476 *
477 * we hack args so that it only contains two items. This also
478 * means we need our own __str__() which prints out the filename
479 * when it was supplied.
480 */
481static int
482EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
483 PyObject *kwds)
484{
485 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
486 PyObject *subslice = NULL;
487
488 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
489 return -1;
490
491 if (PyTuple_GET_SIZE(args) <= 1) {
492 return 0;
493 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000494
495 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000496 &myerrno, &strerror, &filename)) {
497 return -1;
498 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000499 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000500 self->myerrno = myerrno;
501 Py_INCREF(self->myerrno);
502
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000503 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000504 self->strerror = strerror;
505 Py_INCREF(self->strerror);
506
507 /* self->filename will remain Py_None otherwise */
508 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000509 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000510 self->filename = filename;
511 Py_INCREF(self->filename);
512
513 subslice = PyTuple_GetSlice(args, 0, 2);
514 if (!subslice)
515 return -1;
516
517 Py_DECREF(self->args); /* replacing args */
518 self->args = subslice;
519 }
520 return 0;
521}
522
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000523static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000524EnvironmentError_clear(PyEnvironmentErrorObject *self)
525{
526 Py_CLEAR(self->myerrno);
527 Py_CLEAR(self->strerror);
528 Py_CLEAR(self->filename);
529 return BaseException_clear((PyBaseExceptionObject *)self);
530}
531
532static void
533EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
534{
535 EnvironmentError_clear(self);
536 self->ob_type->tp_free((PyObject *)self);
537}
538
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000539static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000540EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
541 void *arg)
542{
543 Py_VISIT(self->myerrno);
544 Py_VISIT(self->strerror);
545 Py_VISIT(self->filename);
546 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
547}
548
549static PyObject *
550EnvironmentError_str(PyEnvironmentErrorObject *self)
551{
552 PyObject *rtnval = NULL;
553
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000554 if (self->filename) {
555 PyObject *fmt;
556 PyObject *repr;
557 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000558
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000559 fmt = PyString_FromString("[Errno %s] %s: %s");
560 if (!fmt)
561 return NULL;
562
563 repr = PyObject_Repr(self->filename);
564 if (!repr) {
565 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000566 return NULL;
567 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000568 tuple = PyTuple_New(3);
569 if (!tuple) {
570 Py_DECREF(repr);
571 Py_DECREF(fmt);
572 return NULL;
573 }
574
575 if (self->myerrno) {
576 Py_INCREF(self->myerrno);
577 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
578 }
579 else {
580 Py_INCREF(Py_None);
581 PyTuple_SET_ITEM(tuple, 0, Py_None);
582 }
583 if (self->strerror) {
584 Py_INCREF(self->strerror);
585 PyTuple_SET_ITEM(tuple, 1, self->strerror);
586 }
587 else {
588 Py_INCREF(Py_None);
589 PyTuple_SET_ITEM(tuple, 1, Py_None);
590 }
591
Richard Jones7b9558d2006-05-27 12:29:24 +0000592 Py_INCREF(repr);
593 PyTuple_SET_ITEM(tuple, 2, repr);
594
595 rtnval = PyString_Format(fmt, tuple);
596
597 Py_DECREF(fmt);
598 Py_DECREF(tuple);
599 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000600 else if (self->myerrno && self->strerror) {
601 PyObject *fmt;
602 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000603
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000604 fmt = PyString_FromString("[Errno %s] %s");
605 if (!fmt)
606 return NULL;
607
608 tuple = PyTuple_New(2);
609 if (!tuple) {
610 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000611 return NULL;
612 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000613
614 if (self->myerrno) {
615 Py_INCREF(self->myerrno);
616 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
617 }
618 else {
619 Py_INCREF(Py_None);
620 PyTuple_SET_ITEM(tuple, 0, Py_None);
621 }
622 if (self->strerror) {
623 Py_INCREF(self->strerror);
624 PyTuple_SET_ITEM(tuple, 1, self->strerror);
625 }
626 else {
627 Py_INCREF(Py_None);
628 PyTuple_SET_ITEM(tuple, 1, Py_None);
629 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000630
631 rtnval = PyString_Format(fmt, tuple);
632
633 Py_DECREF(fmt);
634 Py_DECREF(tuple);
635 }
636 else
637 rtnval = BaseException_str((PyBaseExceptionObject *)self);
638
639 return rtnval;
640}
641
642static PyMemberDef EnvironmentError_members[] = {
643 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
644 PyDoc_STR("exception message")},
645 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000646 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000647 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000648 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000649 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000650 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000651 {NULL} /* Sentinel */
652};
653
654
655static PyObject *
656EnvironmentError_reduce(PyEnvironmentErrorObject *self)
657{
658 PyObject *args = self->args;
659 PyObject *res = NULL, *tmp;
660 /* self->args is only the first two real arguments if there was a
661 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000662 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000663 args = PyTuple_New(3);
664 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000665
666 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000667 Py_INCREF(tmp);
668 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000669
670 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000671 Py_INCREF(tmp);
672 PyTuple_SET_ITEM(args, 1, tmp);
673
674 Py_INCREF(self->filename);
675 PyTuple_SET_ITEM(args, 2, self->filename);
676 } else {
677 Py_INCREF(args);
678 }
679 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +0000680 Py_DECREF(args);
681 return res;
682}
683
684
685static PyMethodDef EnvironmentError_methods[] = {
686 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
687 {NULL}
688};
689
690ComplexExtendsException(PyExc_StandardError, EnvironmentError,
691 EnvironmentError, EnvironmentError_dealloc,
692 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000693 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000694 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000695
696
697/*
698 * IOError extends EnvironmentError
699 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000700MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000701 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000702
703
704/*
705 * OSError extends EnvironmentError
706 */
707MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000708 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000709
710
711/*
712 * WindowsError extends OSError
713 */
714#ifdef MS_WINDOWS
715#include "errmap.h"
716
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000717static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000718WindowsError_clear(PyWindowsErrorObject *self)
719{
720 Py_CLEAR(self->myerrno);
721 Py_CLEAR(self->strerror);
722 Py_CLEAR(self->filename);
723 Py_CLEAR(self->winerror);
724 return BaseException_clear((PyBaseExceptionObject *)self);
725}
726
727static void
728WindowsError_dealloc(PyWindowsErrorObject *self)
729{
730 WindowsError_clear(self);
731 self->ob_type->tp_free((PyObject *)self);
732}
733
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000734static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000735WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
736{
737 Py_VISIT(self->myerrno);
738 Py_VISIT(self->strerror);
739 Py_VISIT(self->filename);
740 Py_VISIT(self->winerror);
741 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
742}
743
Richard Jones7b9558d2006-05-27 12:29:24 +0000744static int
745WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
746{
747 PyObject *o_errcode = NULL;
748 long errcode;
749 long posix_errno;
750
751 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
752 == -1)
753 return -1;
754
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000755 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000756 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000757
758 /* Set errno to the POSIX errno, and winerror to the Win32
759 error code. */
760 errcode = PyInt_AsLong(self->myerrno);
761 if (errcode == -1 && PyErr_Occurred())
762 return -1;
763 posix_errno = winerror_to_errno(errcode);
764
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000765 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000766 self->winerror = self->myerrno;
767
768 o_errcode = PyInt_FromLong(posix_errno);
769 if (!o_errcode)
770 return -1;
771
772 self->myerrno = o_errcode;
773
774 return 0;
775}
776
777
778static PyObject *
779WindowsError_str(PyWindowsErrorObject *self)
780{
Richard Jones7b9558d2006-05-27 12:29:24 +0000781 PyObject *rtnval = NULL;
782
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000783 if (self->filename) {
784 PyObject *fmt;
785 PyObject *repr;
786 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000787
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000788 fmt = PyString_FromString("[Error %s] %s: %s");
789 if (!fmt)
790 return NULL;
791
792 repr = PyObject_Repr(self->filename);
793 if (!repr) {
794 Py_DECREF(fmt);
795 return NULL;
796 }
797 tuple = PyTuple_New(3);
798 if (!tuple) {
799 Py_DECREF(repr);
800 Py_DECREF(fmt);
801 return NULL;
802 }
803
804 if (self->myerrno) {
805 Py_INCREF(self->myerrno);
806 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
807 }
808 else {
809 Py_INCREF(Py_None);
810 PyTuple_SET_ITEM(tuple, 0, Py_None);
811 }
812 if (self->strerror) {
813 Py_INCREF(self->strerror);
814 PyTuple_SET_ITEM(tuple, 1, self->strerror);
815 }
816 else {
817 Py_INCREF(Py_None);
818 PyTuple_SET_ITEM(tuple, 1, Py_None);
819 }
820
821 Py_INCREF(repr);
822 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000823
824 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000825
826 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000827 Py_DECREF(tuple);
828 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000829 else if (self->myerrno && self->strerror) {
830 PyObject *fmt;
831 PyObject *tuple;
832
Richard Jones7b9558d2006-05-27 12:29:24 +0000833 fmt = PyString_FromString("[Error %s] %s");
834 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000835 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000836
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000837 tuple = PyTuple_New(2);
838 if (!tuple) {
839 Py_DECREF(fmt);
840 return NULL;
841 }
842
843 if (self->myerrno) {
844 Py_INCREF(self->myerrno);
845 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
846 }
847 else {
848 Py_INCREF(Py_None);
849 PyTuple_SET_ITEM(tuple, 0, Py_None);
850 }
851 if (self->strerror) {
852 Py_INCREF(self->strerror);
853 PyTuple_SET_ITEM(tuple, 1, self->strerror);
854 }
855 else {
856 Py_INCREF(Py_None);
857 PyTuple_SET_ITEM(tuple, 1, Py_None);
858 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000859
860 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000861
862 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000863 Py_DECREF(tuple);
864 }
865 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000866 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000867
Richard Jones7b9558d2006-05-27 12:29:24 +0000868 return rtnval;
869}
870
871static PyMemberDef WindowsError_members[] = {
872 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
873 PyDoc_STR("exception message")},
874 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000875 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000876 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000877 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000878 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000879 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000880 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000881 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000882 {NULL} /* Sentinel */
883};
884
Richard Jones2d555b32006-05-27 16:15:11 +0000885ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
886 WindowsError_dealloc, 0, WindowsError_members,
887 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000888
889#endif /* MS_WINDOWS */
890
891
892/*
893 * VMSError extends OSError (I think)
894 */
895#ifdef __VMS
896MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000897 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000898#endif
899
900
901/*
902 * EOFError extends StandardError
903 */
904SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000905 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000906
907
908/*
909 * RuntimeError extends StandardError
910 */
911SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000912 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000913
914
915/*
916 * NotImplementedError extends RuntimeError
917 */
918SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000919 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000920
921/*
922 * NameError extends StandardError
923 */
924SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000925 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000926
927/*
928 * UnboundLocalError extends NameError
929 */
930SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000931 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000932
933/*
934 * AttributeError extends StandardError
935 */
936SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000937 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000938
939
940/*
941 * SyntaxError extends StandardError
942 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000943
944static int
945SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
946{
947 PyObject *info = NULL;
948 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
949
950 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
951 return -1;
952
953 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000954 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000955 self->msg = PyTuple_GET_ITEM(args, 0);
956 Py_INCREF(self->msg);
957 }
958 if (lenargs == 2) {
959 info = PyTuple_GET_ITEM(args, 1);
960 info = PySequence_Tuple(info);
961 if (!info) return -1;
962
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000963 if (PyTuple_GET_SIZE(info) != 4) {
964 /* not a very good error message, but it's what Python 2.4 gives */
965 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
966 Py_DECREF(info);
967 return -1;
968 }
969
970 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +0000971 self->filename = PyTuple_GET_ITEM(info, 0);
972 Py_INCREF(self->filename);
973
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000974 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +0000975 self->lineno = PyTuple_GET_ITEM(info, 1);
976 Py_INCREF(self->lineno);
977
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000978 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +0000979 self->offset = PyTuple_GET_ITEM(info, 2);
980 Py_INCREF(self->offset);
981
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000982 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +0000983 self->text = PyTuple_GET_ITEM(info, 3);
984 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000985
986 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +0000987 }
988 return 0;
989}
990
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000991static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000992SyntaxError_clear(PySyntaxErrorObject *self)
993{
994 Py_CLEAR(self->msg);
995 Py_CLEAR(self->filename);
996 Py_CLEAR(self->lineno);
997 Py_CLEAR(self->offset);
998 Py_CLEAR(self->text);
999 Py_CLEAR(self->print_file_and_line);
1000 return BaseException_clear((PyBaseExceptionObject *)self);
1001}
1002
1003static void
1004SyntaxError_dealloc(PySyntaxErrorObject *self)
1005{
1006 SyntaxError_clear(self);
1007 self->ob_type->tp_free((PyObject *)self);
1008}
1009
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001010static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001011SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1012{
1013 Py_VISIT(self->msg);
1014 Py_VISIT(self->filename);
1015 Py_VISIT(self->lineno);
1016 Py_VISIT(self->offset);
1017 Py_VISIT(self->text);
1018 Py_VISIT(self->print_file_and_line);
1019 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1020}
1021
1022/* This is called "my_basename" instead of just "basename" to avoid name
1023 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1024 defined, and Python does define that. */
1025static char *
1026my_basename(char *name)
1027{
1028 char *cp = name;
1029 char *result = name;
1030
1031 if (name == NULL)
1032 return "???";
1033 while (*cp != '\0') {
1034 if (*cp == SEP)
1035 result = cp + 1;
1036 ++cp;
1037 }
1038 return result;
1039}
1040
1041
1042static PyObject *
1043SyntaxError_str(PySyntaxErrorObject *self)
1044{
1045 PyObject *str;
1046 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001047 int have_filename = 0;
1048 int have_lineno = 0;
1049 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001050 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001051
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001052 if (self->msg)
1053 str = PyObject_Str(self->msg);
1054 else
1055 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001056 if (!str) return NULL;
1057 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1058 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001059
1060 /* XXX -- do all the additional formatting with filename and
1061 lineno here */
1062
Georg Brandl43ab1002006-05-28 20:57:09 +00001063 have_filename = (self->filename != NULL) &&
1064 PyString_Check(self->filename);
1065 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001066
Georg Brandl43ab1002006-05-28 20:57:09 +00001067 if (!have_filename && !have_lineno)
1068 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001069
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001070 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001071 if (have_filename)
1072 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001073
Georg Brandl43ab1002006-05-28 20:57:09 +00001074 buffer = PyMem_MALLOC(bufsize);
1075 if (buffer == NULL)
1076 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001077
Georg Brandl43ab1002006-05-28 20:57:09 +00001078 if (have_filename && have_lineno)
1079 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1080 PyString_AS_STRING(str),
1081 my_basename(PyString_AS_STRING(self->filename)),
1082 PyInt_AsLong(self->lineno));
1083 else if (have_filename)
1084 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1085 PyString_AS_STRING(str),
1086 my_basename(PyString_AS_STRING(self->filename)));
1087 else /* only have_lineno */
1088 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1089 PyString_AS_STRING(str),
1090 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001091
Georg Brandl43ab1002006-05-28 20:57:09 +00001092 result = PyString_FromString(buffer);
1093 PyMem_FREE(buffer);
1094
1095 if (result == NULL)
1096 result = str;
1097 else
1098 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001099 return result;
1100}
1101
1102static PyMemberDef SyntaxError_members[] = {
1103 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1104 PyDoc_STR("exception message")},
1105 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1106 PyDoc_STR("exception msg")},
1107 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1108 PyDoc_STR("exception filename")},
1109 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1110 PyDoc_STR("exception lineno")},
1111 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1112 PyDoc_STR("exception offset")},
1113 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1114 PyDoc_STR("exception text")},
1115 {"print_file_and_line", T_OBJECT,
1116 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1117 PyDoc_STR("exception print_file_and_line")},
1118 {NULL} /* Sentinel */
1119};
1120
1121ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1122 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001123 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001124
1125
1126/*
1127 * IndentationError extends SyntaxError
1128 */
1129MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001130 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001131
1132
1133/*
1134 * TabError extends IndentationError
1135 */
1136MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001137 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001138
1139
1140/*
1141 * LookupError extends StandardError
1142 */
1143SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001144 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001145
1146
1147/*
1148 * IndexError extends LookupError
1149 */
1150SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001151 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001152
1153
1154/*
1155 * KeyError extends LookupError
1156 */
1157static PyObject *
1158KeyError_str(PyBaseExceptionObject *self)
1159{
1160 /* If args is a tuple of exactly one item, apply repr to args[0].
1161 This is done so that e.g. the exception raised by {}[''] prints
1162 KeyError: ''
1163 rather than the confusing
1164 KeyError
1165 alone. The downside is that if KeyError is raised with an explanatory
1166 string, that string will be displayed in quotes. Too bad.
1167 If args is anything else, use the default BaseException__str__().
1168 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001169 if (PyTuple_GET_SIZE(self->args) == 1) {
1170 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001171 }
1172 return BaseException_str(self);
1173}
1174
1175ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001176 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001177
1178
1179/*
1180 * ValueError extends StandardError
1181 */
1182SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001183 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001184
1185/*
1186 * UnicodeError extends ValueError
1187 */
1188
1189SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001190 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001191
1192#ifdef Py_USING_UNICODE
1193static int
1194get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1195{
1196 if (!attr) {
1197 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1198 return -1;
1199 }
1200
1201 if (PyInt_Check(attr)) {
1202 *value = PyInt_AS_LONG(attr);
1203 } else if (PyLong_Check(attr)) {
1204 *value = _PyLong_AsSsize_t(attr);
1205 if (*value == -1 && PyErr_Occurred())
1206 return -1;
1207 } else {
1208 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1209 return -1;
1210 }
1211 return 0;
1212}
1213
1214static int
1215set_ssize_t(PyObject **attr, Py_ssize_t value)
1216{
1217 PyObject *obj = PyInt_FromSsize_t(value);
1218 if (!obj)
1219 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001220 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001221 *attr = obj;
1222 return 0;
1223}
1224
1225static PyObject *
1226get_string(PyObject *attr, const char *name)
1227{
1228 if (!attr) {
1229 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1230 return NULL;
1231 }
1232
1233 if (!PyString_Check(attr)) {
1234 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1235 return NULL;
1236 }
1237 Py_INCREF(attr);
1238 return attr;
1239}
1240
1241
1242static int
1243set_string(PyObject **attr, const char *value)
1244{
1245 PyObject *obj = PyString_FromString(value);
1246 if (!obj)
1247 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001248 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001249 *attr = obj;
1250 return 0;
1251}
1252
1253
1254static PyObject *
1255get_unicode(PyObject *attr, const char *name)
1256{
1257 if (!attr) {
1258 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1259 return NULL;
1260 }
1261
1262 if (!PyUnicode_Check(attr)) {
1263 PyErr_Format(PyExc_TypeError,
1264 "%.200s attribute must be unicode", name);
1265 return NULL;
1266 }
1267 Py_INCREF(attr);
1268 return attr;
1269}
1270
1271PyObject *
1272PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1273{
1274 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1275}
1276
1277PyObject *
1278PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1279{
1280 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1281}
1282
1283PyObject *
1284PyUnicodeEncodeError_GetObject(PyObject *exc)
1285{
1286 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1287}
1288
1289PyObject *
1290PyUnicodeDecodeError_GetObject(PyObject *exc)
1291{
1292 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1293}
1294
1295PyObject *
1296PyUnicodeTranslateError_GetObject(PyObject *exc)
1297{
1298 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1299}
1300
1301int
1302PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1303{
1304 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1305 Py_ssize_t size;
1306 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1307 "object");
1308 if (!obj) return -1;
1309 size = PyUnicode_GET_SIZE(obj);
1310 if (*start<0)
1311 *start = 0; /*XXX check for values <0*/
1312 if (*start>=size)
1313 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001314 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001315 return 0;
1316 }
1317 return -1;
1318}
1319
1320
1321int
1322PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1323{
1324 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1325 Py_ssize_t size;
1326 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1327 "object");
1328 if (!obj) return -1;
1329 size = PyString_GET_SIZE(obj);
1330 if (*start<0)
1331 *start = 0;
1332 if (*start>=size)
1333 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001334 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001335 return 0;
1336 }
1337 return -1;
1338}
1339
1340
1341int
1342PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1343{
1344 return PyUnicodeEncodeError_GetStart(exc, start);
1345}
1346
1347
1348int
1349PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1350{
1351 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1352}
1353
1354
1355int
1356PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1357{
1358 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1359}
1360
1361
1362int
1363PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1364{
1365 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1366}
1367
1368
1369int
1370PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1371{
1372 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1373 Py_ssize_t size;
1374 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1375 "object");
1376 if (!obj) return -1;
1377 size = PyUnicode_GET_SIZE(obj);
1378 if (*end<1)
1379 *end = 1;
1380 if (*end>size)
1381 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001382 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001383 return 0;
1384 }
1385 return -1;
1386}
1387
1388
1389int
1390PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1391{
1392 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1393 Py_ssize_t size;
1394 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1395 "object");
1396 if (!obj) return -1;
1397 size = PyString_GET_SIZE(obj);
1398 if (*end<1)
1399 *end = 1;
1400 if (*end>size)
1401 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001402 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001403 return 0;
1404 }
1405 return -1;
1406}
1407
1408
1409int
1410PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1411{
1412 return PyUnicodeEncodeError_GetEnd(exc, start);
1413}
1414
1415
1416int
1417PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1418{
1419 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1420}
1421
1422
1423int
1424PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1425{
1426 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1427}
1428
1429
1430int
1431PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1432{
1433 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1434}
1435
1436PyObject *
1437PyUnicodeEncodeError_GetReason(PyObject *exc)
1438{
1439 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1440}
1441
1442
1443PyObject *
1444PyUnicodeDecodeError_GetReason(PyObject *exc)
1445{
1446 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1447}
1448
1449
1450PyObject *
1451PyUnicodeTranslateError_GetReason(PyObject *exc)
1452{
1453 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1454}
1455
1456
1457int
1458PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1459{
1460 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1461}
1462
1463
1464int
1465PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1466{
1467 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1468}
1469
1470
1471int
1472PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1473{
1474 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1475}
1476
1477
Richard Jones7b9558d2006-05-27 12:29:24 +00001478static int
1479UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1480 PyTypeObject *objecttype)
1481{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001482 Py_CLEAR(self->encoding);
1483 Py_CLEAR(self->object);
1484 Py_CLEAR(self->start);
1485 Py_CLEAR(self->end);
1486 Py_CLEAR(self->reason);
1487
Richard Jones7b9558d2006-05-27 12:29:24 +00001488 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1489 &PyString_Type, &self->encoding,
1490 objecttype, &self->object,
1491 &PyInt_Type, &self->start,
1492 &PyInt_Type, &self->end,
1493 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001494 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001495 self->reason = NULL;
1496 return -1;
1497 }
1498
1499 Py_INCREF(self->encoding);
1500 Py_INCREF(self->object);
1501 Py_INCREF(self->start);
1502 Py_INCREF(self->end);
1503 Py_INCREF(self->reason);
1504
1505 return 0;
1506}
1507
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001508static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001509UnicodeError_clear(PyUnicodeErrorObject *self)
1510{
1511 Py_CLEAR(self->encoding);
1512 Py_CLEAR(self->object);
1513 Py_CLEAR(self->start);
1514 Py_CLEAR(self->end);
1515 Py_CLEAR(self->reason);
1516 return BaseException_clear((PyBaseExceptionObject *)self);
1517}
1518
1519static void
1520UnicodeError_dealloc(PyUnicodeErrorObject *self)
1521{
1522 UnicodeError_clear(self);
1523 self->ob_type->tp_free((PyObject *)self);
1524}
1525
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001526static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001527UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1528{
1529 Py_VISIT(self->encoding);
1530 Py_VISIT(self->object);
1531 Py_VISIT(self->start);
1532 Py_VISIT(self->end);
1533 Py_VISIT(self->reason);
1534 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1535}
1536
1537static PyMemberDef UnicodeError_members[] = {
1538 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1539 PyDoc_STR("exception message")},
1540 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1541 PyDoc_STR("exception encoding")},
1542 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1543 PyDoc_STR("exception object")},
1544 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1545 PyDoc_STR("exception start")},
1546 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1547 PyDoc_STR("exception end")},
1548 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1549 PyDoc_STR("exception reason")},
1550 {NULL} /* Sentinel */
1551};
1552
1553
1554/*
1555 * UnicodeEncodeError extends UnicodeError
1556 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001557
1558static int
1559UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1560{
1561 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1562 return -1;
1563 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1564 kwds, &PyUnicode_Type);
1565}
1566
1567static PyObject *
1568UnicodeEncodeError_str(PyObject *self)
1569{
1570 Py_ssize_t start;
1571 Py_ssize_t end;
1572
1573 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001574 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001575
1576 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001577 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001578
1579 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001580 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1581 char badchar_str[20];
1582 if (badchar <= 0xff)
1583 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1584 else if (badchar <= 0xffff)
1585 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1586 else
1587 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1588 return PyString_FromFormat(
1589 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1590 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1591 badchar_str,
1592 start,
1593 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1594 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001595 }
1596 return PyString_FromFormat(
1597 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1598 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1599 start,
1600 (end-1),
1601 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1602 );
1603}
1604
1605static PyTypeObject _PyExc_UnicodeEncodeError = {
1606 PyObject_HEAD_INIT(NULL)
1607 0,
1608 "UnicodeEncodeError",
1609 sizeof(PyUnicodeErrorObject), 0,
1610 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1611 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1612 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001613 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1614 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001615 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001616 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001617};
1618PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1619
1620PyObject *
1621PyUnicodeEncodeError_Create(
1622 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1623 Py_ssize_t start, Py_ssize_t end, const char *reason)
1624{
1625 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001626 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001627}
1628
1629
1630/*
1631 * UnicodeDecodeError extends UnicodeError
1632 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001633
1634static int
1635UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1636{
1637 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1638 return -1;
1639 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1640 kwds, &PyString_Type);
1641}
1642
1643static PyObject *
1644UnicodeDecodeError_str(PyObject *self)
1645{
Georg Brandl43ab1002006-05-28 20:57:09 +00001646 Py_ssize_t start = 0;
1647 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001648
1649 if (PyUnicodeDecodeError_GetStart(self, &start))
1650 return NULL;
1651
1652 if (PyUnicodeDecodeError_GetEnd(self, &end))
1653 return NULL;
1654
1655 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001656 /* FromFormat does not support %02x, so format that separately */
1657 char byte[4];
1658 PyOS_snprintf(byte, sizeof(byte), "%02x",
1659 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1660 return PyString_FromFormat(
1661 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1662 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1663 byte,
1664 start,
1665 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1666 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001667 }
1668 return PyString_FromFormat(
1669 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1670 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1671 start,
1672 (end-1),
1673 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1674 );
1675}
1676
1677static PyTypeObject _PyExc_UnicodeDecodeError = {
1678 PyObject_HEAD_INIT(NULL)
1679 0,
1680 EXC_MODULE_NAME "UnicodeDecodeError",
1681 sizeof(PyUnicodeErrorObject), 0,
1682 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1683 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1684 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001685 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1686 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001687 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001688 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001689};
1690PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1691
1692PyObject *
1693PyUnicodeDecodeError_Create(
1694 const char *encoding, const char *object, Py_ssize_t length,
1695 Py_ssize_t start, Py_ssize_t end, const char *reason)
1696{
1697 assert(length < INT_MAX);
1698 assert(start < INT_MAX);
1699 assert(end < INT_MAX);
1700 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001701 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001702}
1703
1704
1705/*
1706 * UnicodeTranslateError extends UnicodeError
1707 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001708
1709static int
1710UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1711 PyObject *kwds)
1712{
1713 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1714 return -1;
1715
1716 Py_CLEAR(self->object);
1717 Py_CLEAR(self->start);
1718 Py_CLEAR(self->end);
1719 Py_CLEAR(self->reason);
1720
1721 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1722 &PyUnicode_Type, &self->object,
1723 &PyInt_Type, &self->start,
1724 &PyInt_Type, &self->end,
1725 &PyString_Type, &self->reason)) {
1726 self->object = self->start = self->end = self->reason = NULL;
1727 return -1;
1728 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001729
Richard Jones7b9558d2006-05-27 12:29:24 +00001730 Py_INCREF(self->object);
1731 Py_INCREF(self->start);
1732 Py_INCREF(self->end);
1733 Py_INCREF(self->reason);
1734
1735 return 0;
1736}
1737
1738
1739static PyObject *
1740UnicodeTranslateError_str(PyObject *self)
1741{
1742 Py_ssize_t start;
1743 Py_ssize_t end;
1744
1745 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001746 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001747
1748 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001749 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001750
1751 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001752 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1753 char badchar_str[20];
1754 if (badchar <= 0xff)
1755 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1756 else if (badchar <= 0xffff)
1757 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1758 else
1759 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1760 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001761 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001762 badchar_str,
1763 start,
1764 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1765 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001766 }
1767 return PyString_FromFormat(
1768 "can't translate characters in position %zd-%zd: %.400s",
1769 start,
1770 (end-1),
1771 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1772 );
1773}
1774
1775static PyTypeObject _PyExc_UnicodeTranslateError = {
1776 PyObject_HEAD_INIT(NULL)
1777 0,
1778 EXC_MODULE_NAME "UnicodeTranslateError",
1779 sizeof(PyUnicodeErrorObject), 0,
1780 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1781 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1782 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1783 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1784 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1785 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001786 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001787};
1788PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1789
1790PyObject *
1791PyUnicodeTranslateError_Create(
1792 const Py_UNICODE *object, Py_ssize_t length,
1793 Py_ssize_t start, Py_ssize_t end, const char *reason)
1794{
1795 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001796 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001797}
1798#endif
1799
1800
1801/*
1802 * AssertionError extends StandardError
1803 */
1804SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001805 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001806
1807
1808/*
1809 * ArithmeticError extends StandardError
1810 */
1811SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001812 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001813
1814
1815/*
1816 * FloatingPointError extends ArithmeticError
1817 */
1818SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001819 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001820
1821
1822/*
1823 * OverflowError extends ArithmeticError
1824 */
1825SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001826 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001827
1828
1829/*
1830 * ZeroDivisionError extends ArithmeticError
1831 */
1832SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001833 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001834
1835
1836/*
1837 * SystemError extends StandardError
1838 */
1839SimpleExtendsException(PyExc_StandardError, SystemError,
1840 "Internal error in the Python interpreter.\n"
1841 "\n"
1842 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001843 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001844
1845
1846/*
1847 * ReferenceError extends StandardError
1848 */
1849SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001850 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001851
1852
1853/*
1854 * MemoryError extends StandardError
1855 */
Richard Jones2d555b32006-05-27 16:15:11 +00001856SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001857
1858
1859/* Warning category docstrings */
1860
1861/*
1862 * Warning extends Exception
1863 */
1864SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001865 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001866
1867
1868/*
1869 * UserWarning extends Warning
1870 */
1871SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001872 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001873
1874
1875/*
1876 * DeprecationWarning extends Warning
1877 */
1878SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001879 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001880
1881
1882/*
1883 * PendingDeprecationWarning extends Warning
1884 */
1885SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1886 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001887 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001888
1889
1890/*
1891 * SyntaxWarning extends Warning
1892 */
1893SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001894 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001895
1896
1897/*
1898 * RuntimeWarning extends Warning
1899 */
1900SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001901 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001902
1903
1904/*
1905 * FutureWarning extends Warning
1906 */
1907SimpleExtendsException(PyExc_Warning, FutureWarning,
1908 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001909 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001910
1911
1912/*
1913 * ImportWarning extends Warning
1914 */
1915SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001916 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001917
1918
1919/* Pre-computed MemoryError instance. Best to create this as early as
1920 * possible and not wait until a MemoryError is actually raised!
1921 */
1922PyObject *PyExc_MemoryErrorInst=NULL;
1923
1924/* module global functions */
1925static PyMethodDef functions[] = {
1926 /* Sentinel */
1927 {NULL, NULL}
1928};
1929
1930#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1931 Py_FatalError("exceptions bootstrapping error.");
1932
1933#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1934 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1935 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1936 Py_FatalError("Module dictionary insertion problem.");
1937
1938PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001939_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001940{
1941 PyObject *m, *bltinmod, *bdict;
1942
1943 PRE_INIT(BaseException)
1944 PRE_INIT(Exception)
1945 PRE_INIT(StandardError)
1946 PRE_INIT(TypeError)
1947 PRE_INIT(StopIteration)
1948 PRE_INIT(GeneratorExit)
1949 PRE_INIT(SystemExit)
1950 PRE_INIT(KeyboardInterrupt)
1951 PRE_INIT(ImportError)
1952 PRE_INIT(EnvironmentError)
1953 PRE_INIT(IOError)
1954 PRE_INIT(OSError)
1955#ifdef MS_WINDOWS
1956 PRE_INIT(WindowsError)
1957#endif
1958#ifdef __VMS
1959 PRE_INIT(VMSError)
1960#endif
1961 PRE_INIT(EOFError)
1962 PRE_INIT(RuntimeError)
1963 PRE_INIT(NotImplementedError)
1964 PRE_INIT(NameError)
1965 PRE_INIT(UnboundLocalError)
1966 PRE_INIT(AttributeError)
1967 PRE_INIT(SyntaxError)
1968 PRE_INIT(IndentationError)
1969 PRE_INIT(TabError)
1970 PRE_INIT(LookupError)
1971 PRE_INIT(IndexError)
1972 PRE_INIT(KeyError)
1973 PRE_INIT(ValueError)
1974 PRE_INIT(UnicodeError)
1975#ifdef Py_USING_UNICODE
1976 PRE_INIT(UnicodeEncodeError)
1977 PRE_INIT(UnicodeDecodeError)
1978 PRE_INIT(UnicodeTranslateError)
1979#endif
1980 PRE_INIT(AssertionError)
1981 PRE_INIT(ArithmeticError)
1982 PRE_INIT(FloatingPointError)
1983 PRE_INIT(OverflowError)
1984 PRE_INIT(ZeroDivisionError)
1985 PRE_INIT(SystemError)
1986 PRE_INIT(ReferenceError)
1987 PRE_INIT(MemoryError)
1988 PRE_INIT(Warning)
1989 PRE_INIT(UserWarning)
1990 PRE_INIT(DeprecationWarning)
1991 PRE_INIT(PendingDeprecationWarning)
1992 PRE_INIT(SyntaxWarning)
1993 PRE_INIT(RuntimeWarning)
1994 PRE_INIT(FutureWarning)
1995 PRE_INIT(ImportWarning)
1996
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00001997 m = Py_InitModule4("exceptions", functions, exceptions_doc,
1998 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00001999 if (m == NULL) return;
2000
2001 bltinmod = PyImport_ImportModule("__builtin__");
2002 if (bltinmod == NULL)
2003 Py_FatalError("exceptions bootstrapping error.");
2004 bdict = PyModule_GetDict(bltinmod);
2005 if (bdict == NULL)
2006 Py_FatalError("exceptions bootstrapping error.");
2007
2008 POST_INIT(BaseException)
2009 POST_INIT(Exception)
2010 POST_INIT(StandardError)
2011 POST_INIT(TypeError)
2012 POST_INIT(StopIteration)
2013 POST_INIT(GeneratorExit)
2014 POST_INIT(SystemExit)
2015 POST_INIT(KeyboardInterrupt)
2016 POST_INIT(ImportError)
2017 POST_INIT(EnvironmentError)
2018 POST_INIT(IOError)
2019 POST_INIT(OSError)
2020#ifdef MS_WINDOWS
2021 POST_INIT(WindowsError)
2022#endif
2023#ifdef __VMS
2024 POST_INIT(VMSError)
2025#endif
2026 POST_INIT(EOFError)
2027 POST_INIT(RuntimeError)
2028 POST_INIT(NotImplementedError)
2029 POST_INIT(NameError)
2030 POST_INIT(UnboundLocalError)
2031 POST_INIT(AttributeError)
2032 POST_INIT(SyntaxError)
2033 POST_INIT(IndentationError)
2034 POST_INIT(TabError)
2035 POST_INIT(LookupError)
2036 POST_INIT(IndexError)
2037 POST_INIT(KeyError)
2038 POST_INIT(ValueError)
2039 POST_INIT(UnicodeError)
2040#ifdef Py_USING_UNICODE
2041 POST_INIT(UnicodeEncodeError)
2042 POST_INIT(UnicodeDecodeError)
2043 POST_INIT(UnicodeTranslateError)
2044#endif
2045 POST_INIT(AssertionError)
2046 POST_INIT(ArithmeticError)
2047 POST_INIT(FloatingPointError)
2048 POST_INIT(OverflowError)
2049 POST_INIT(ZeroDivisionError)
2050 POST_INIT(SystemError)
2051 POST_INIT(ReferenceError)
2052 POST_INIT(MemoryError)
2053 POST_INIT(Warning)
2054 POST_INIT(UserWarning)
2055 POST_INIT(DeprecationWarning)
2056 POST_INIT(PendingDeprecationWarning)
2057 POST_INIT(SyntaxWarning)
2058 POST_INIT(RuntimeWarning)
2059 POST_INIT(FutureWarning)
2060 POST_INIT(ImportWarning)
2061
2062 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2063 if (!PyExc_MemoryErrorInst)
2064 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2065
2066 Py_DECREF(bltinmod);
2067}
2068
2069void
2070_PyExc_Fini(void)
2071{
2072 Py_XDECREF(PyExc_MemoryErrorInst);
2073 PyExc_MemoryErrorInst = NULL;
2074}