blob: 3b79307406114f88dd58c9efcc4d4aa39e152139 [file] [log] [blame]
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001/*
2 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
3 *
4 * Thanks go to Tim Peters and Michael Hudson for debugging.
5 */
6
Thomas Wouters477c8d52006-05-27 19:21:47 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
9#include "structmember.h"
10#include "osdefs.h"
11
12#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
13#define EXC_MODULE_NAME "exceptions."
14
15/* NOTE: If the exception class hierarchy changes, don't forget to update
16 * Lib/test/exception_hierarchy.txt
17 */
18
19PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
20\n\
21Exceptions found here are defined both in the exceptions module and the\n\
22built-in namespace. It is recommended that user-defined exceptions\n\
23inherit from Exception. See the documentation for the exception\n\
24inheritance hierarchy.\n\
25");
26
27/*
28 * BaseException
29 */
30static PyObject *
31BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
32{
33 PyBaseExceptionObject *self;
34
35 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
36 /* the dict is created on the fly in PyObject_GenericSetAttr */
37 self->message = self->dict = NULL;
38
39 self->args = PyTuple_New(0);
40 if (!self->args) {
41 Py_DECREF(self);
42 return NULL;
43 }
44
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000045 self->message = PyString_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000046 if (!self->message) {
47 Py_DECREF(self);
48 return NULL;
49 }
50
51 return (PyObject *)self;
52}
53
54static int
55BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
56{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000057 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
58 return -1;
59
Thomas Wouters477c8d52006-05-27 19:21:47 +000060 Py_DECREF(self->args);
61 self->args = args;
62 Py_INCREF(self->args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000065 Py_CLEAR(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000066 self->message = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000067 Py_INCREF(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000068 }
69 return 0;
70}
71
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000072static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000073BaseException_clear(PyBaseExceptionObject *self)
74{
75 Py_CLEAR(self->dict);
76 Py_CLEAR(self->args);
77 Py_CLEAR(self->message);
78 return 0;
79}
80
81static void
82BaseException_dealloc(PyBaseExceptionObject *self)
83{
84 BaseException_clear(self);
85 self->ob_type->tp_free((PyObject *)self);
86}
87
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000088static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000089BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
90{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000091 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000092 Py_VISIT(self->args);
93 Py_VISIT(self->message);
94 return 0;
95}
96
97static PyObject *
98BaseException_str(PyBaseExceptionObject *self)
99{
100 PyObject *out;
101
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000102 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000103 case 0:
104 out = PyString_FromString("");
105 break;
106 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000107 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000108 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109 default:
110 out = PyObject_Str(self->args);
111 break;
112 }
113
114 return out;
115}
116
117static PyObject *
118BaseException_repr(PyBaseExceptionObject *self)
119{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000120 PyObject *repr_suffix;
121 PyObject *repr;
122 char *name;
123 char *dot;
124
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000125 repr_suffix = PyObject_Repr(self->args);
126 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000127 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000128
129 name = (char *)self->ob_type->tp_name;
130 dot = strrchr(name, '.');
131 if (dot != NULL) name = dot+1;
132
133 repr = PyString_FromString(name);
134 if (!repr) {
135 Py_DECREF(repr_suffix);
136 return NULL;
137 }
138
139 PyString_ConcatAndDel(&repr, repr_suffix);
140 return repr;
141}
142
143/* Pickling support */
144static PyObject *
145BaseException_reduce(PyBaseExceptionObject *self)
146{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000147 if (self->args && self->dict)
148 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
149 else
150 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000151}
152
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000153/*
154 * Needed for backward compatibility, since exceptions used to store
155 * all their attributes in the __dict__. Code is taken from cPickle's
156 * load_build function.
157 */
158static PyObject *
159BaseException_setstate(PyObject *self, PyObject *state)
160{
161 PyObject *d_key, *d_value;
162 Py_ssize_t i = 0;
163
164 if (state != Py_None) {
165 if (!PyDict_Check(state)) {
166 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
167 return NULL;
168 }
169 while (PyDict_Next(state, &i, &d_key, &d_value)) {
170 if (PyObject_SetAttr(self, d_key, d_value) < 0)
171 return NULL;
172 }
173 }
174 Py_RETURN_NONE;
175}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000176
177#ifdef Py_USING_UNICODE
178/* while this method generates fairly uninspired output, it a least
179 * guarantees that we can display exceptions that have unicode attributes
180 */
181static PyObject *
182BaseException_unicode(PyBaseExceptionObject *self)
183{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000184 if (PyTuple_GET_SIZE(self->args) == 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000185 return PyUnicode_FromUnicode(NULL, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000186 if (PyTuple_GET_SIZE(self->args) == 1)
187 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000188 return PyObject_Unicode(self->args);
189}
190#endif /* Py_USING_UNICODE */
191
192static PyMethodDef BaseException_methods[] = {
193 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000194 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000195#ifdef Py_USING_UNICODE
196 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
197#endif
198 {NULL, NULL, 0, NULL},
199};
200
201
202
203static PyObject *
204BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
205{
206 return PySequence_GetItem(self->args, index);
207}
208
209static PySequenceMethods BaseException_as_sequence = {
210 0, /* sq_length; */
211 0, /* sq_concat; */
212 0, /* sq_repeat; */
213 (ssizeargfunc)BaseException_getitem, /* sq_item; */
214 0, /* sq_slice; */
215 0, /* sq_ass_item; */
216 0, /* sq_ass_slice; */
217 0, /* sq_contains; */
218 0, /* sq_inplace_concat; */
219 0 /* sq_inplace_repeat; */
220};
221
222static PyMemberDef BaseException_members[] = {
223 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
224 PyDoc_STR("exception message")},
225 {NULL} /* Sentinel */
226};
227
228
229static PyObject *
230BaseException_get_dict(PyBaseExceptionObject *self)
231{
232 if (self->dict == NULL) {
233 self->dict = PyDict_New();
234 if (!self->dict)
235 return NULL;
236 }
237 Py_INCREF(self->dict);
238 return self->dict;
239}
240
241static int
242BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
243{
244 if (val == NULL) {
245 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
246 return -1;
247 }
248 if (!PyDict_Check(val)) {
249 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
250 return -1;
251 }
252 Py_CLEAR(self->dict);
253 Py_INCREF(val);
254 self->dict = val;
255 return 0;
256}
257
258static PyObject *
259BaseException_get_args(PyBaseExceptionObject *self)
260{
261 if (self->args == NULL) {
262 Py_INCREF(Py_None);
263 return Py_None;
264 }
265 Py_INCREF(self->args);
266 return self->args;
267}
268
269static int
270BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
271{
272 PyObject *seq;
273 if (val == NULL) {
274 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
275 return -1;
276 }
277 seq = PySequence_Tuple(val);
278 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000279 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280 self->args = seq;
281 return 0;
282}
283
284static PyGetSetDef BaseException_getset[] = {
285 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
286 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
287 {NULL},
288};
289
290
291static PyTypeObject _PyExc_BaseException = {
292 PyObject_HEAD_INIT(NULL)
293 0, /*ob_size*/
294 EXC_MODULE_NAME "BaseException", /*tp_name*/
295 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
296 0, /*tp_itemsize*/
297 (destructor)BaseException_dealloc, /*tp_dealloc*/
298 0, /*tp_print*/
299 0, /*tp_getattr*/
300 0, /*tp_setattr*/
301 0, /* tp_compare; */
302 (reprfunc)BaseException_repr, /*tp_repr*/
303 0, /*tp_as_number*/
304 &BaseException_as_sequence, /*tp_as_sequence*/
305 0, /*tp_as_mapping*/
306 0, /*tp_hash */
307 0, /*tp_call*/
308 (reprfunc)BaseException_str, /*tp_str*/
309 PyObject_GenericGetAttr, /*tp_getattro*/
310 PyObject_GenericSetAttr, /*tp_setattro*/
311 0, /*tp_as_buffer*/
312 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
313 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
314 (traverseproc)BaseException_traverse, /* tp_traverse */
315 (inquiry)BaseException_clear, /* tp_clear */
316 0, /* tp_richcompare */
317 0, /* tp_weaklistoffset */
318 0, /* tp_iter */
319 0, /* tp_iternext */
320 BaseException_methods, /* tp_methods */
321 BaseException_members, /* tp_members */
322 BaseException_getset, /* tp_getset */
323 0, /* tp_base */
324 0, /* tp_dict */
325 0, /* tp_descr_get */
326 0, /* tp_descr_set */
327 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
328 (initproc)BaseException_init, /* tp_init */
329 0, /* tp_alloc */
330 BaseException_new, /* tp_new */
331};
332/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
333from the previous implmentation and also allowing Python objects to be used
334in the API */
335PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
336
337/* note these macros omit the last semicolon so the macro invocation may
338 * include it and not look strange.
339 */
340#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
341static PyTypeObject _PyExc_ ## EXCNAME = { \
342 PyObject_HEAD_INIT(NULL) \
343 0, \
344 EXC_MODULE_NAME # EXCNAME, \
345 sizeof(PyBaseExceptionObject), \
346 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
347 0, 0, 0, 0, 0, 0, 0, \
348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
349 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
350 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
351 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
352 (initproc)BaseException_init, 0, BaseException_new,\
353}; \
354PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
355
356#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
357static PyTypeObject _PyExc_ ## EXCNAME = { \
358 PyObject_HEAD_INIT(NULL) \
359 0, \
360 EXC_MODULE_NAME # EXCNAME, \
361 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000362 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000363 0, 0, 0, 0, 0, \
364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000365 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
366 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000368 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369}; \
370PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
371
372#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
373static PyTypeObject _PyExc_ ## EXCNAME = { \
374 PyObject_HEAD_INIT(NULL) \
375 0, \
376 EXC_MODULE_NAME # EXCNAME, \
377 sizeof(Py ## EXCSTORE ## Object), 0, \
378 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
379 (reprfunc)EXCSTR, 0, 0, 0, \
380 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
381 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
382 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
383 EXCMEMBERS, 0, &_ ## EXCBASE, \
384 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000385 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000386}; \
387PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
388
389
390/*
391 * Exception extends BaseException
392 */
393SimpleExtendsException(PyExc_BaseException, Exception,
394 "Common base class for all non-exit exceptions.");
395
396
397/*
398 * StandardError extends Exception
399 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000400SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000401 "Base class for all standard Python exceptions that do not represent\n"
402 "interpreter exiting.");
403
404
405/*
406 * TypeError extends StandardError
407 */
408SimpleExtendsException(PyExc_StandardError, TypeError,
409 "Inappropriate argument type.");
410
411
412/*
413 * StopIteration extends Exception
414 */
415SimpleExtendsException(PyExc_Exception, StopIteration,
416 "Signal the end from iterator.next().");
417
418
419/*
420 * GeneratorExit extends Exception
421 */
422SimpleExtendsException(PyExc_Exception, GeneratorExit,
423 "Request that a generator exit.");
424
425
426/*
427 * SystemExit extends BaseException
428 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000429
430static int
431SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
432{
433 Py_ssize_t size = PyTuple_GET_SIZE(args);
434
435 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
436 return -1;
437
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000438 if (size == 0)
439 return 0;
440 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000441 if (size == 1)
442 self->code = PyTuple_GET_ITEM(args, 0);
443 else if (size > 1)
444 self->code = args;
445 Py_INCREF(self->code);
446 return 0;
447}
448
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000449static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000450SystemExit_clear(PySystemExitObject *self)
451{
452 Py_CLEAR(self->code);
453 return BaseException_clear((PyBaseExceptionObject *)self);
454}
455
456static void
457SystemExit_dealloc(PySystemExitObject *self)
458{
459 SystemExit_clear(self);
460 self->ob_type->tp_free((PyObject *)self);
461}
462
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000463static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
465{
466 Py_VISIT(self->code);
467 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
468}
469
470static PyMemberDef SystemExit_members[] = {
471 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
472 PyDoc_STR("exception message")},
473 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
474 PyDoc_STR("exception code")},
475 {NULL} /* Sentinel */
476};
477
478ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
479 SystemExit_dealloc, 0, SystemExit_members, 0,
480 "Request to exit from the interpreter.");
481
482/*
483 * KeyboardInterrupt extends BaseException
484 */
485SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
486 "Program interrupted by user.");
487
488
489/*
490 * ImportError extends StandardError
491 */
492SimpleExtendsException(PyExc_StandardError, ImportError,
493 "Import can't find module, or can't find name in module.");
494
495
496/*
497 * EnvironmentError extends StandardError
498 */
499
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500/* Where a function has a single filename, such as open() or some
501 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
502 * called, giving a third argument which is the filename. But, so
503 * that old code using in-place unpacking doesn't break, e.g.:
504 *
505 * except IOError, (errno, strerror):
506 *
507 * we hack args so that it only contains two items. This also
508 * means we need our own __str__() which prints out the filename
509 * when it was supplied.
510 */
511static int
512EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
513 PyObject *kwds)
514{
515 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
516 PyObject *subslice = NULL;
517
518 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
519 return -1;
520
521 if (PyTuple_GET_SIZE(args) <= 1) {
522 return 0;
523 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524
525 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 &myerrno, &strerror, &filename)) {
527 return -1;
528 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000529 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000530 self->myerrno = myerrno;
531 Py_INCREF(self->myerrno);
532
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000533 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000534 self->strerror = strerror;
535 Py_INCREF(self->strerror);
536
537 /* self->filename will remain Py_None otherwise */
538 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000539 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000540 self->filename = filename;
541 Py_INCREF(self->filename);
542
543 subslice = PyTuple_GetSlice(args, 0, 2);
544 if (!subslice)
545 return -1;
546
547 Py_DECREF(self->args); /* replacing args */
548 self->args = subslice;
549 }
550 return 0;
551}
552
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000553static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000554EnvironmentError_clear(PyEnvironmentErrorObject *self)
555{
556 Py_CLEAR(self->myerrno);
557 Py_CLEAR(self->strerror);
558 Py_CLEAR(self->filename);
559 return BaseException_clear((PyBaseExceptionObject *)self);
560}
561
562static void
563EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
564{
565 EnvironmentError_clear(self);
566 self->ob_type->tp_free((PyObject *)self);
567}
568
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000569static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000570EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
571 void *arg)
572{
573 Py_VISIT(self->myerrno);
574 Py_VISIT(self->strerror);
575 Py_VISIT(self->filename);
576 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
577}
578
579static PyObject *
580EnvironmentError_str(PyEnvironmentErrorObject *self)
581{
582 PyObject *rtnval = NULL;
583
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000584 if (self->filename) {
585 PyObject *fmt;
586 PyObject *repr;
587 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000588
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000589 fmt = PyString_FromString("[Errno %s] %s: %s");
590 if (!fmt)
591 return NULL;
592
593 repr = PyObject_Repr(self->filename);
594 if (!repr) {
595 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000596 return NULL;
597 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000598 tuple = PyTuple_New(3);
599 if (!tuple) {
600 Py_DECREF(repr);
601 Py_DECREF(fmt);
602 return NULL;
603 }
604
605 if (self->myerrno) {
606 Py_INCREF(self->myerrno);
607 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
608 }
609 else {
610 Py_INCREF(Py_None);
611 PyTuple_SET_ITEM(tuple, 0, Py_None);
612 }
613 if (self->strerror) {
614 Py_INCREF(self->strerror);
615 PyTuple_SET_ITEM(tuple, 1, self->strerror);
616 }
617 else {
618 Py_INCREF(Py_None);
619 PyTuple_SET_ITEM(tuple, 1, Py_None);
620 }
621
Thomas Wouters477c8d52006-05-27 19:21:47 +0000622 PyTuple_SET_ITEM(tuple, 2, repr);
623
624 rtnval = PyString_Format(fmt, tuple);
625
626 Py_DECREF(fmt);
627 Py_DECREF(tuple);
628 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000629 else if (self->myerrno && self->strerror) {
630 PyObject *fmt;
631 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000632
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000633 fmt = PyString_FromString("[Errno %s] %s");
634 if (!fmt)
635 return NULL;
636
637 tuple = PyTuple_New(2);
638 if (!tuple) {
639 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000640 return NULL;
641 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000642
643 if (self->myerrno) {
644 Py_INCREF(self->myerrno);
645 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
646 }
647 else {
648 Py_INCREF(Py_None);
649 PyTuple_SET_ITEM(tuple, 0, Py_None);
650 }
651 if (self->strerror) {
652 Py_INCREF(self->strerror);
653 PyTuple_SET_ITEM(tuple, 1, self->strerror);
654 }
655 else {
656 Py_INCREF(Py_None);
657 PyTuple_SET_ITEM(tuple, 1, Py_None);
658 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659
660 rtnval = PyString_Format(fmt, tuple);
661
662 Py_DECREF(fmt);
663 Py_DECREF(tuple);
664 }
665 else
666 rtnval = BaseException_str((PyBaseExceptionObject *)self);
667
668 return rtnval;
669}
670
671static PyMemberDef EnvironmentError_members[] = {
672 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
673 PyDoc_STR("exception message")},
674 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
675 PyDoc_STR("exception errno")},
676 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
677 PyDoc_STR("exception strerror")},
678 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
679 PyDoc_STR("exception filename")},
680 {NULL} /* Sentinel */
681};
682
683
684static PyObject *
685EnvironmentError_reduce(PyEnvironmentErrorObject *self)
686{
687 PyObject *args = self->args;
688 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000689
Thomas Wouters477c8d52006-05-27 19:21:47 +0000690 /* self->args is only the first two real arguments if there was a
691 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000692 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693 args = PyTuple_New(3);
694 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000695
696 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697 Py_INCREF(tmp);
698 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000699
700 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000701 Py_INCREF(tmp);
702 PyTuple_SET_ITEM(args, 1, tmp);
703
704 Py_INCREF(self->filename);
705 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000706 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000708
709 if (self->dict)
710 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
711 else
712 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000713 Py_DECREF(args);
714 return res;
715}
716
717
718static PyMethodDef EnvironmentError_methods[] = {
719 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
720 {NULL}
721};
722
723ComplexExtendsException(PyExc_StandardError, EnvironmentError,
724 EnvironmentError, EnvironmentError_dealloc,
725 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000726 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727 "Base class for I/O related errors.");
728
729
730/*
731 * IOError extends EnvironmentError
732 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000733MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000734 EnvironmentError, "I/O operation failed.");
735
736
737/*
738 * OSError extends EnvironmentError
739 */
740MiddlingExtendsException(PyExc_EnvironmentError, OSError,
741 EnvironmentError, "OS system call failed.");
742
743
744/*
745 * WindowsError extends OSError
746 */
747#ifdef MS_WINDOWS
748#include "errmap.h"
749
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000750static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000751WindowsError_clear(PyWindowsErrorObject *self)
752{
753 Py_CLEAR(self->myerrno);
754 Py_CLEAR(self->strerror);
755 Py_CLEAR(self->filename);
756 Py_CLEAR(self->winerror);
757 return BaseException_clear((PyBaseExceptionObject *)self);
758}
759
760static void
761WindowsError_dealloc(PyWindowsErrorObject *self)
762{
763 WindowsError_clear(self);
764 self->ob_type->tp_free((PyObject *)self);
765}
766
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000767static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000768WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
769{
770 Py_VISIT(self->myerrno);
771 Py_VISIT(self->strerror);
772 Py_VISIT(self->filename);
773 Py_VISIT(self->winerror);
774 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
775}
776
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777static int
778WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
779{
780 PyObject *o_errcode = NULL;
781 long errcode;
782 long posix_errno;
783
784 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
785 == -1)
786 return -1;
787
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000788 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000789 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000790
791 /* Set errno to the POSIX errno, and winerror to the Win32
792 error code. */
793 errcode = PyInt_AsLong(self->myerrno);
794 if (errcode == -1 && PyErr_Occurred())
795 return -1;
796 posix_errno = winerror_to_errno(errcode);
797
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000798 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000799 self->winerror = self->myerrno;
800
801 o_errcode = PyInt_FromLong(posix_errno);
802 if (!o_errcode)
803 return -1;
804
805 self->myerrno = o_errcode;
806
807 return 0;
808}
809
810
811static PyObject *
812WindowsError_str(PyWindowsErrorObject *self)
813{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000814 PyObject *rtnval = NULL;
815
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 if (self->filename) {
817 PyObject *fmt;
818 PyObject *repr;
819 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000821 fmt = PyString_FromString("[Error %s] %s: %s");
822 if (!fmt)
823 return NULL;
824
825 repr = PyObject_Repr(self->filename);
826 if (!repr) {
827 Py_DECREF(fmt);
828 return NULL;
829 }
830 tuple = PyTuple_New(3);
831 if (!tuple) {
832 Py_DECREF(repr);
833 Py_DECREF(fmt);
834 return NULL;
835 }
836
837 if (self->myerrno) {
838 Py_INCREF(self->myerrno);
839 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
840 }
841 else {
842 Py_INCREF(Py_None);
843 PyTuple_SET_ITEM(tuple, 0, Py_None);
844 }
845 if (self->strerror) {
846 Py_INCREF(self->strerror);
847 PyTuple_SET_ITEM(tuple, 1, self->strerror);
848 }
849 else {
850 Py_INCREF(Py_None);
851 PyTuple_SET_ITEM(tuple, 1, Py_None);
852 }
853
854 Py_INCREF(repr);
855 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856
857 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000858
859 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860 Py_DECREF(tuple);
861 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000862 else if (self->myerrno && self->strerror) {
863 PyObject *fmt;
864 PyObject *tuple;
865
Thomas Wouters477c8d52006-05-27 19:21:47 +0000866 fmt = PyString_FromString("[Error %s] %s");
867 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000868 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000870 tuple = PyTuple_New(2);
871 if (!tuple) {
872 Py_DECREF(fmt);
873 return NULL;
874 }
875
876 if (self->myerrno) {
877 Py_INCREF(self->myerrno);
878 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
879 }
880 else {
881 Py_INCREF(Py_None);
882 PyTuple_SET_ITEM(tuple, 0, Py_None);
883 }
884 if (self->strerror) {
885 Py_INCREF(self->strerror);
886 PyTuple_SET_ITEM(tuple, 1, self->strerror);
887 }
888 else {
889 Py_INCREF(Py_None);
890 PyTuple_SET_ITEM(tuple, 1, Py_None);
891 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000892
893 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000894
895 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896 Py_DECREF(tuple);
897 }
898 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000899 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000900
Thomas Wouters477c8d52006-05-27 19:21:47 +0000901 return rtnval;
902}
903
904static PyMemberDef WindowsError_members[] = {
905 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
906 PyDoc_STR("exception message")},
907 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
908 PyDoc_STR("POSIX exception code")},
909 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
910 PyDoc_STR("exception strerror")},
911 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
912 PyDoc_STR("exception filename")},
913 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
914 PyDoc_STR("Win32 exception code")},
915 {NULL} /* Sentinel */
916};
917
918ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
919 WindowsError_dealloc, 0, WindowsError_members,
920 WindowsError_str, "MS-Windows OS system call failed.");
921
922#endif /* MS_WINDOWS */
923
924
925/*
926 * VMSError extends OSError (I think)
927 */
928#ifdef __VMS
929MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
930 "OpenVMS OS system call failed.");
931#endif
932
933
934/*
935 * EOFError extends StandardError
936 */
937SimpleExtendsException(PyExc_StandardError, EOFError,
938 "Read beyond end of file.");
939
940
941/*
942 * RuntimeError extends StandardError
943 */
944SimpleExtendsException(PyExc_StandardError, RuntimeError,
945 "Unspecified run-time error.");
946
947
948/*
949 * NotImplementedError extends RuntimeError
950 */
951SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
952 "Method or function hasn't been implemented yet.");
953
954/*
955 * NameError extends StandardError
956 */
957SimpleExtendsException(PyExc_StandardError, NameError,
958 "Name not found globally.");
959
960/*
961 * UnboundLocalError extends NameError
962 */
963SimpleExtendsException(PyExc_NameError, UnboundLocalError,
964 "Local name referenced but not bound to a value.");
965
966/*
967 * AttributeError extends StandardError
968 */
969SimpleExtendsException(PyExc_StandardError, AttributeError,
970 "Attribute not found.");
971
972
973/*
974 * SyntaxError extends StandardError
975 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000976
977static int
978SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
979{
980 PyObject *info = NULL;
981 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
982
983 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
984 return -1;
985
986 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000987 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000988 self->msg = PyTuple_GET_ITEM(args, 0);
989 Py_INCREF(self->msg);
990 }
991 if (lenargs == 2) {
992 info = PyTuple_GET_ITEM(args, 1);
993 info = PySequence_Tuple(info);
994 if (!info) return -1;
995
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000996 if (PyTuple_GET_SIZE(info) != 4) {
997 /* not a very good error message, but it's what Python 2.4 gives */
998 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
999 Py_DECREF(info);
1000 return -1;
1001 }
1002
1003 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001004 self->filename = PyTuple_GET_ITEM(info, 0);
1005 Py_INCREF(self->filename);
1006
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001007 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008 self->lineno = PyTuple_GET_ITEM(info, 1);
1009 Py_INCREF(self->lineno);
1010
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001011 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001012 self->offset = PyTuple_GET_ITEM(info, 2);
1013 Py_INCREF(self->offset);
1014
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001015 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001016 self->text = PyTuple_GET_ITEM(info, 3);
1017 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018
1019 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001020 }
1021 return 0;
1022}
1023
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001024static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025SyntaxError_clear(PySyntaxErrorObject *self)
1026{
1027 Py_CLEAR(self->msg);
1028 Py_CLEAR(self->filename);
1029 Py_CLEAR(self->lineno);
1030 Py_CLEAR(self->offset);
1031 Py_CLEAR(self->text);
1032 Py_CLEAR(self->print_file_and_line);
1033 return BaseException_clear((PyBaseExceptionObject *)self);
1034}
1035
1036static void
1037SyntaxError_dealloc(PySyntaxErrorObject *self)
1038{
1039 SyntaxError_clear(self);
1040 self->ob_type->tp_free((PyObject *)self);
1041}
1042
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001043static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001044SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1045{
1046 Py_VISIT(self->msg);
1047 Py_VISIT(self->filename);
1048 Py_VISIT(self->lineno);
1049 Py_VISIT(self->offset);
1050 Py_VISIT(self->text);
1051 Py_VISIT(self->print_file_and_line);
1052 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1053}
1054
1055/* This is called "my_basename" instead of just "basename" to avoid name
1056 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1057 defined, and Python does define that. */
1058static char *
1059my_basename(char *name)
1060{
1061 char *cp = name;
1062 char *result = name;
1063
1064 if (name == NULL)
1065 return "???";
1066 while (*cp != '\0') {
1067 if (*cp == SEP)
1068 result = cp + 1;
1069 ++cp;
1070 }
1071 return result;
1072}
1073
1074
1075static PyObject *
1076SyntaxError_str(PySyntaxErrorObject *self)
1077{
1078 PyObject *str;
1079 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 int have_filename = 0;
1081 int have_lineno = 0;
1082 char *buffer = NULL;
1083 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001084
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001085 if (self->msg)
1086 str = PyObject_Str(self->msg);
1087 else
1088 str = PyObject_Str(Py_None);
1089 if (!str) return NULL;
1090 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1091 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001092
1093 /* XXX -- do all the additional formatting with filename and
1094 lineno here */
1095
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001096 have_filename = (self->filename != NULL) &&
1097 PyString_Check(self->filename);
1098 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001099
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001100 if (!have_filename && !have_lineno)
1101 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001102
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001103 bufsize = PyString_GET_SIZE(str) + 64;
1104 if (have_filename)
1105 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001106
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001107 buffer = PyMem_MALLOC(bufsize);
1108 if (buffer == NULL)
1109 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001111 if (have_filename && have_lineno)
1112 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1113 PyString_AS_STRING(str),
1114 my_basename(PyString_AS_STRING(self->filename)),
1115 PyInt_AsLong(self->lineno));
1116 else if (have_filename)
1117 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1118 PyString_AS_STRING(str),
1119 my_basename(PyString_AS_STRING(self->filename)));
1120 else /* only have_lineno */
1121 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1122 PyString_AS_STRING(str),
1123 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001124
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001125 result = PyString_FromString(buffer);
1126 PyMem_FREE(buffer);
1127
1128 if (result == NULL)
1129 result = str;
1130 else
1131 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001132 return result;
1133}
1134
1135static PyMemberDef SyntaxError_members[] = {
1136 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1137 PyDoc_STR("exception message")},
1138 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1139 PyDoc_STR("exception msg")},
1140 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1141 PyDoc_STR("exception filename")},
1142 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1143 PyDoc_STR("exception lineno")},
1144 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1145 PyDoc_STR("exception offset")},
1146 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1147 PyDoc_STR("exception text")},
1148 {"print_file_and_line", T_OBJECT,
1149 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1150 PyDoc_STR("exception print_file_and_line")},
1151 {NULL} /* Sentinel */
1152};
1153
1154ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1155 SyntaxError_dealloc, 0, SyntaxError_members,
1156 SyntaxError_str, "Invalid syntax.");
1157
1158
1159/*
1160 * IndentationError extends SyntaxError
1161 */
1162MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1163 "Improper indentation.");
1164
1165
1166/*
1167 * TabError extends IndentationError
1168 */
1169MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1170 "Improper mixture of spaces and tabs.");
1171
1172
1173/*
1174 * LookupError extends StandardError
1175 */
1176SimpleExtendsException(PyExc_StandardError, LookupError,
1177 "Base class for lookup errors.");
1178
1179
1180/*
1181 * IndexError extends LookupError
1182 */
1183SimpleExtendsException(PyExc_LookupError, IndexError,
1184 "Sequence index out of range.");
1185
1186
1187/*
1188 * KeyError extends LookupError
1189 */
1190static PyObject *
1191KeyError_str(PyBaseExceptionObject *self)
1192{
1193 /* If args is a tuple of exactly one item, apply repr to args[0].
1194 This is done so that e.g. the exception raised by {}[''] prints
1195 KeyError: ''
1196 rather than the confusing
1197 KeyError
1198 alone. The downside is that if KeyError is raised with an explanatory
1199 string, that string will be displayed in quotes. Too bad.
1200 If args is anything else, use the default BaseException__str__().
1201 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001202 if (PyTuple_GET_SIZE(self->args) == 1) {
1203 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204 }
1205 return BaseException_str(self);
1206}
1207
1208ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1209 0, 0, 0, KeyError_str, "Mapping key not found.");
1210
1211
1212/*
1213 * ValueError extends StandardError
1214 */
1215SimpleExtendsException(PyExc_StandardError, ValueError,
1216 "Inappropriate argument value (of correct type).");
1217
1218/*
1219 * UnicodeError extends ValueError
1220 */
1221
1222SimpleExtendsException(PyExc_ValueError, UnicodeError,
1223 "Unicode related error.");
1224
1225#ifdef Py_USING_UNICODE
1226static int
1227get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1228{
1229 if (!attr) {
1230 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1231 return -1;
1232 }
1233
1234 if (PyInt_Check(attr)) {
1235 *value = PyInt_AS_LONG(attr);
1236 } else if (PyLong_Check(attr)) {
1237 *value = _PyLong_AsSsize_t(attr);
1238 if (*value == -1 && PyErr_Occurred())
1239 return -1;
1240 } else {
1241 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1242 return -1;
1243 }
1244 return 0;
1245}
1246
1247static int
1248set_ssize_t(PyObject **attr, Py_ssize_t value)
1249{
1250 PyObject *obj = PyInt_FromSsize_t(value);
1251 if (!obj)
1252 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001253 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001254 *attr = obj;
1255 return 0;
1256}
1257
1258static PyObject *
1259get_string(PyObject *attr, const char *name)
1260{
1261 if (!attr) {
1262 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1263 return NULL;
1264 }
1265
1266 if (!PyString_Check(attr)) {
1267 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1268 return NULL;
1269 }
1270 Py_INCREF(attr);
1271 return attr;
1272}
1273
1274
1275static int
1276set_string(PyObject **attr, const char *value)
1277{
1278 PyObject *obj = PyString_FromString(value);
1279 if (!obj)
1280 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001281 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282 *attr = obj;
1283 return 0;
1284}
1285
1286
1287static PyObject *
1288get_unicode(PyObject *attr, const char *name)
1289{
1290 if (!attr) {
1291 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1292 return NULL;
1293 }
1294
1295 if (!PyUnicode_Check(attr)) {
1296 PyErr_Format(PyExc_TypeError,
1297 "%.200s attribute must be unicode", name);
1298 return NULL;
1299 }
1300 Py_INCREF(attr);
1301 return attr;
1302}
1303
1304PyObject *
1305PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1306{
1307 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1308}
1309
1310PyObject *
1311PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1312{
1313 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1314}
1315
1316PyObject *
1317PyUnicodeEncodeError_GetObject(PyObject *exc)
1318{
1319 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1320}
1321
1322PyObject *
1323PyUnicodeDecodeError_GetObject(PyObject *exc)
1324{
1325 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1326}
1327
1328PyObject *
1329PyUnicodeTranslateError_GetObject(PyObject *exc)
1330{
1331 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1332}
1333
1334int
1335PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1336{
1337 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1338 Py_ssize_t size;
1339 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1340 "object");
1341 if (!obj) return -1;
1342 size = PyUnicode_GET_SIZE(obj);
1343 if (*start<0)
1344 *start = 0; /*XXX check for values <0*/
1345 if (*start>=size)
1346 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348 return 0;
1349 }
1350 return -1;
1351}
1352
1353
1354int
1355PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1356{
1357 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1358 Py_ssize_t size;
1359 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1360 "object");
1361 if (!obj) return -1;
1362 size = PyString_GET_SIZE(obj);
1363 if (*start<0)
1364 *start = 0;
1365 if (*start>=size)
1366 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001367 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368 return 0;
1369 }
1370 return -1;
1371}
1372
1373
1374int
1375PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1376{
1377 return PyUnicodeEncodeError_GetStart(exc, start);
1378}
1379
1380
1381int
1382PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1383{
1384 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1385}
1386
1387
1388int
1389PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1390{
1391 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1392}
1393
1394
1395int
1396PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1397{
1398 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1399}
1400
1401
1402int
1403PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1404{
1405 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1406 Py_ssize_t size;
1407 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1408 "object");
1409 if (!obj) return -1;
1410 size = PyUnicode_GET_SIZE(obj);
1411 if (*end<1)
1412 *end = 1;
1413 if (*end>size)
1414 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001415 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416 return 0;
1417 }
1418 return -1;
1419}
1420
1421
1422int
1423PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1424{
1425 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1426 Py_ssize_t size;
1427 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1428 "object");
1429 if (!obj) return -1;
1430 size = PyString_GET_SIZE(obj);
1431 if (*end<1)
1432 *end = 1;
1433 if (*end>size)
1434 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001435 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436 return 0;
1437 }
1438 return -1;
1439}
1440
1441
1442int
1443PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1444{
1445 return PyUnicodeEncodeError_GetEnd(exc, start);
1446}
1447
1448
1449int
1450PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1451{
1452 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1453}
1454
1455
1456int
1457PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1458{
1459 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1460}
1461
1462
1463int
1464PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1465{
1466 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1467}
1468
1469PyObject *
1470PyUnicodeEncodeError_GetReason(PyObject *exc)
1471{
1472 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1473}
1474
1475
1476PyObject *
1477PyUnicodeDecodeError_GetReason(PyObject *exc)
1478{
1479 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1480}
1481
1482
1483PyObject *
1484PyUnicodeTranslateError_GetReason(PyObject *exc)
1485{
1486 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1487}
1488
1489
1490int
1491PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1492{
1493 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1494}
1495
1496
1497int
1498PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1499{
1500 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1501}
1502
1503
1504int
1505PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1506{
1507 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1508}
1509
1510
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511static int
1512UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1513 PyTypeObject *objecttype)
1514{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001515 Py_CLEAR(self->encoding);
1516 Py_CLEAR(self->object);
1517 Py_CLEAR(self->start);
1518 Py_CLEAR(self->end);
1519 Py_CLEAR(self->reason);
1520
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1522 &PyString_Type, &self->encoding,
1523 objecttype, &self->object,
1524 &PyInt_Type, &self->start,
1525 &PyInt_Type, &self->end,
1526 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001527 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001528 self->reason = NULL;
1529 return -1;
1530 }
1531
1532 Py_INCREF(self->encoding);
1533 Py_INCREF(self->object);
1534 Py_INCREF(self->start);
1535 Py_INCREF(self->end);
1536 Py_INCREF(self->reason);
1537
1538 return 0;
1539}
1540
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001541static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542UnicodeError_clear(PyUnicodeErrorObject *self)
1543{
1544 Py_CLEAR(self->encoding);
1545 Py_CLEAR(self->object);
1546 Py_CLEAR(self->start);
1547 Py_CLEAR(self->end);
1548 Py_CLEAR(self->reason);
1549 return BaseException_clear((PyBaseExceptionObject *)self);
1550}
1551
1552static void
1553UnicodeError_dealloc(PyUnicodeErrorObject *self)
1554{
1555 UnicodeError_clear(self);
1556 self->ob_type->tp_free((PyObject *)self);
1557}
1558
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001559static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1561{
1562 Py_VISIT(self->encoding);
1563 Py_VISIT(self->object);
1564 Py_VISIT(self->start);
1565 Py_VISIT(self->end);
1566 Py_VISIT(self->reason);
1567 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1568}
1569
1570static PyMemberDef UnicodeError_members[] = {
1571 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1572 PyDoc_STR("exception message")},
1573 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1574 PyDoc_STR("exception encoding")},
1575 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1576 PyDoc_STR("exception object")},
1577 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1578 PyDoc_STR("exception start")},
1579 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1580 PyDoc_STR("exception end")},
1581 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1582 PyDoc_STR("exception reason")},
1583 {NULL} /* Sentinel */
1584};
1585
1586
1587/*
1588 * UnicodeEncodeError extends UnicodeError
1589 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001590
1591static int
1592UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1593{
1594 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1595 return -1;
1596 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1597 kwds, &PyUnicode_Type);
1598}
1599
1600static PyObject *
1601UnicodeEncodeError_str(PyObject *self)
1602{
1603 Py_ssize_t start;
1604 Py_ssize_t end;
1605
1606 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001607 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001608
1609 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001610 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001611
1612 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001613 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1614 char badchar_str[20];
1615 if (badchar <= 0xff)
1616 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1617 else if (badchar <= 0xffff)
1618 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1619 else
1620 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1621 return PyString_FromFormat(
1622 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1623 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1624 badchar_str,
1625 start,
1626 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1627 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001628 }
1629 return PyString_FromFormat(
1630 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1631 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1632 start,
1633 (end-1),
1634 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1635 );
1636}
1637
1638static PyTypeObject _PyExc_UnicodeEncodeError = {
1639 PyObject_HEAD_INIT(NULL)
1640 0,
1641 "UnicodeEncodeError",
1642 sizeof(PyUnicodeErrorObject), 0,
1643 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1644 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1645 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001646 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1647 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001648 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001649 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001650};
1651PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1652
1653PyObject *
1654PyUnicodeEncodeError_Create(
1655 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1656 Py_ssize_t start, Py_ssize_t end, const char *reason)
1657{
1658 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001659 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660}
1661
1662
1663/*
1664 * UnicodeDecodeError extends UnicodeError
1665 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001666
1667static int
1668UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1669{
1670 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1671 return -1;
1672 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1673 kwds, &PyString_Type);
1674}
1675
1676static PyObject *
1677UnicodeDecodeError_str(PyObject *self)
1678{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001679 Py_ssize_t start = 0;
1680 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001681
1682 if (PyUnicodeDecodeError_GetStart(self, &start))
1683 return NULL;
1684
1685 if (PyUnicodeDecodeError_GetEnd(self, &end))
1686 return NULL;
1687
1688 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001689 /* FromFormat does not support %02x, so format that separately */
1690 char byte[4];
1691 PyOS_snprintf(byte, sizeof(byte), "%02x",
1692 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1693 return PyString_FromFormat(
1694 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1695 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1696 byte,
1697 start,
1698 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1699 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001700 }
1701 return PyString_FromFormat(
1702 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1703 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1704 start,
1705 (end-1),
1706 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1707 );
1708}
1709
1710static PyTypeObject _PyExc_UnicodeDecodeError = {
1711 PyObject_HEAD_INIT(NULL)
1712 0,
1713 EXC_MODULE_NAME "UnicodeDecodeError",
1714 sizeof(PyUnicodeErrorObject), 0,
1715 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1716 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1717 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001718 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1719 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001721 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001722};
1723PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1724
1725PyObject *
1726PyUnicodeDecodeError_Create(
1727 const char *encoding, const char *object, Py_ssize_t length,
1728 Py_ssize_t start, Py_ssize_t end, const char *reason)
1729{
1730 assert(length < INT_MAX);
1731 assert(start < INT_MAX);
1732 assert(end < INT_MAX);
1733 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001734 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001735}
1736
1737
1738/*
1739 * UnicodeTranslateError extends UnicodeError
1740 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741
1742static int
1743UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1744 PyObject *kwds)
1745{
1746 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1747 return -1;
1748
1749 Py_CLEAR(self->object);
1750 Py_CLEAR(self->start);
1751 Py_CLEAR(self->end);
1752 Py_CLEAR(self->reason);
1753
1754 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1755 &PyUnicode_Type, &self->object,
1756 &PyInt_Type, &self->start,
1757 &PyInt_Type, &self->end,
1758 &PyString_Type, &self->reason)) {
1759 self->object = self->start = self->end = self->reason = NULL;
1760 return -1;
1761 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001762
Thomas Wouters477c8d52006-05-27 19:21:47 +00001763 Py_INCREF(self->object);
1764 Py_INCREF(self->start);
1765 Py_INCREF(self->end);
1766 Py_INCREF(self->reason);
1767
1768 return 0;
1769}
1770
1771
1772static PyObject *
1773UnicodeTranslateError_str(PyObject *self)
1774{
1775 Py_ssize_t start;
1776 Py_ssize_t end;
1777
1778 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001779 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001780
1781 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001782 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001783
1784 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001785 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1786 char badchar_str[20];
1787 if (badchar <= 0xff)
1788 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1789 else if (badchar <= 0xffff)
1790 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1791 else
1792 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1793 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001795 badchar_str,
1796 start,
1797 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1798 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001799 }
1800 return PyString_FromFormat(
1801 "can't translate characters in position %zd-%zd: %.400s",
1802 start,
1803 (end-1),
1804 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1805 );
1806}
1807
1808static PyTypeObject _PyExc_UnicodeTranslateError = {
1809 PyObject_HEAD_INIT(NULL)
1810 0,
1811 EXC_MODULE_NAME "UnicodeTranslateError",
1812 sizeof(PyUnicodeErrorObject), 0,
1813 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1814 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1815 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1816 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1817 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1818 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001819 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001820};
1821PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1822
1823PyObject *
1824PyUnicodeTranslateError_Create(
1825 const Py_UNICODE *object, Py_ssize_t length,
1826 Py_ssize_t start, Py_ssize_t end, const char *reason)
1827{
1828 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001829 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001830}
1831#endif
1832
1833
1834/*
1835 * AssertionError extends StandardError
1836 */
1837SimpleExtendsException(PyExc_StandardError, AssertionError,
1838 "Assertion failed.");
1839
1840
1841/*
1842 * ArithmeticError extends StandardError
1843 */
1844SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1845 "Base class for arithmetic errors.");
1846
1847
1848/*
1849 * FloatingPointError extends ArithmeticError
1850 */
1851SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1852 "Floating point operation failed.");
1853
1854
1855/*
1856 * OverflowError extends ArithmeticError
1857 */
1858SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1859 "Result too large to be represented.");
1860
1861
1862/*
1863 * ZeroDivisionError extends ArithmeticError
1864 */
1865SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1866 "Second argument to a division or modulo operation was zero.");
1867
1868
1869/*
1870 * SystemError extends StandardError
1871 */
1872SimpleExtendsException(PyExc_StandardError, SystemError,
1873 "Internal error in the Python interpreter.\n"
1874 "\n"
1875 "Please report this to the Python maintainer, along with the traceback,\n"
1876 "the Python version, and the hardware/OS platform and version.");
1877
1878
1879/*
1880 * ReferenceError extends StandardError
1881 */
1882SimpleExtendsException(PyExc_StandardError, ReferenceError,
1883 "Weak ref proxy used after referent went away.");
1884
1885
1886/*
1887 * MemoryError extends StandardError
1888 */
1889SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1890
1891
1892/* Warning category docstrings */
1893
1894/*
1895 * Warning extends Exception
1896 */
1897SimpleExtendsException(PyExc_Exception, Warning,
1898 "Base class for warning categories.");
1899
1900
1901/*
1902 * UserWarning extends Warning
1903 */
1904SimpleExtendsException(PyExc_Warning, UserWarning,
1905 "Base class for warnings generated by user code.");
1906
1907
1908/*
1909 * DeprecationWarning extends Warning
1910 */
1911SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1912 "Base class for warnings about deprecated features.");
1913
1914
1915/*
1916 * PendingDeprecationWarning extends Warning
1917 */
1918SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1919 "Base class for warnings about features which will be deprecated\n"
1920 "in the future.");
1921
1922
1923/*
1924 * SyntaxWarning extends Warning
1925 */
1926SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1927 "Base class for warnings about dubious syntax.");
1928
1929
1930/*
1931 * RuntimeWarning extends Warning
1932 */
1933SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1934 "Base class for warnings about dubious runtime behavior.");
1935
1936
1937/*
1938 * FutureWarning extends Warning
1939 */
1940SimpleExtendsException(PyExc_Warning, FutureWarning,
1941 "Base class for warnings about constructs that will change semantically\n"
1942 "in the future.");
1943
1944
1945/*
1946 * ImportWarning extends Warning
1947 */
1948SimpleExtendsException(PyExc_Warning, ImportWarning,
1949 "Base class for warnings about probable mistakes in module imports");
1950
1951
1952/* Pre-computed MemoryError instance. Best to create this as early as
1953 * possible and not wait until a MemoryError is actually raised!
1954 */
1955PyObject *PyExc_MemoryErrorInst=NULL;
1956
1957/* module global functions */
1958static PyMethodDef functions[] = {
1959 /* Sentinel */
1960 {NULL, NULL}
1961};
1962
1963#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1964 Py_FatalError("exceptions bootstrapping error.");
1965
1966#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1967 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1968 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1969 Py_FatalError("Module dictionary insertion problem.");
1970
1971PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001972_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001973{
1974 PyObject *m, *bltinmod, *bdict;
1975
1976 PRE_INIT(BaseException)
1977 PRE_INIT(Exception)
1978 PRE_INIT(StandardError)
1979 PRE_INIT(TypeError)
1980 PRE_INIT(StopIteration)
1981 PRE_INIT(GeneratorExit)
1982 PRE_INIT(SystemExit)
1983 PRE_INIT(KeyboardInterrupt)
1984 PRE_INIT(ImportError)
1985 PRE_INIT(EnvironmentError)
1986 PRE_INIT(IOError)
1987 PRE_INIT(OSError)
1988#ifdef MS_WINDOWS
1989 PRE_INIT(WindowsError)
1990#endif
1991#ifdef __VMS
1992 PRE_INIT(VMSError)
1993#endif
1994 PRE_INIT(EOFError)
1995 PRE_INIT(RuntimeError)
1996 PRE_INIT(NotImplementedError)
1997 PRE_INIT(NameError)
1998 PRE_INIT(UnboundLocalError)
1999 PRE_INIT(AttributeError)
2000 PRE_INIT(SyntaxError)
2001 PRE_INIT(IndentationError)
2002 PRE_INIT(TabError)
2003 PRE_INIT(LookupError)
2004 PRE_INIT(IndexError)
2005 PRE_INIT(KeyError)
2006 PRE_INIT(ValueError)
2007 PRE_INIT(UnicodeError)
2008#ifdef Py_USING_UNICODE
2009 PRE_INIT(UnicodeEncodeError)
2010 PRE_INIT(UnicodeDecodeError)
2011 PRE_INIT(UnicodeTranslateError)
2012#endif
2013 PRE_INIT(AssertionError)
2014 PRE_INIT(ArithmeticError)
2015 PRE_INIT(FloatingPointError)
2016 PRE_INIT(OverflowError)
2017 PRE_INIT(ZeroDivisionError)
2018 PRE_INIT(SystemError)
2019 PRE_INIT(ReferenceError)
2020 PRE_INIT(MemoryError)
2021 PRE_INIT(Warning)
2022 PRE_INIT(UserWarning)
2023 PRE_INIT(DeprecationWarning)
2024 PRE_INIT(PendingDeprecationWarning)
2025 PRE_INIT(SyntaxWarning)
2026 PRE_INIT(RuntimeWarning)
2027 PRE_INIT(FutureWarning)
2028 PRE_INIT(ImportWarning)
2029
2030 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2031 (PyObject *)NULL, PYTHON_API_VERSION);
2032 if (m == NULL) return;
2033
2034 bltinmod = PyImport_ImportModule("__builtin__");
2035 if (bltinmod == NULL)
2036 Py_FatalError("exceptions bootstrapping error.");
2037 bdict = PyModule_GetDict(bltinmod);
2038 if (bdict == NULL)
2039 Py_FatalError("exceptions bootstrapping error.");
2040
2041 POST_INIT(BaseException)
2042 POST_INIT(Exception)
2043 POST_INIT(StandardError)
2044 POST_INIT(TypeError)
2045 POST_INIT(StopIteration)
2046 POST_INIT(GeneratorExit)
2047 POST_INIT(SystemExit)
2048 POST_INIT(KeyboardInterrupt)
2049 POST_INIT(ImportError)
2050 POST_INIT(EnvironmentError)
2051 POST_INIT(IOError)
2052 POST_INIT(OSError)
2053#ifdef MS_WINDOWS
2054 POST_INIT(WindowsError)
2055#endif
2056#ifdef __VMS
2057 POST_INIT(VMSError)
2058#endif
2059 POST_INIT(EOFError)
2060 POST_INIT(RuntimeError)
2061 POST_INIT(NotImplementedError)
2062 POST_INIT(NameError)
2063 POST_INIT(UnboundLocalError)
2064 POST_INIT(AttributeError)
2065 POST_INIT(SyntaxError)
2066 POST_INIT(IndentationError)
2067 POST_INIT(TabError)
2068 POST_INIT(LookupError)
2069 POST_INIT(IndexError)
2070 POST_INIT(KeyError)
2071 POST_INIT(ValueError)
2072 POST_INIT(UnicodeError)
2073#ifdef Py_USING_UNICODE
2074 POST_INIT(UnicodeEncodeError)
2075 POST_INIT(UnicodeDecodeError)
2076 POST_INIT(UnicodeTranslateError)
2077#endif
2078 POST_INIT(AssertionError)
2079 POST_INIT(ArithmeticError)
2080 POST_INIT(FloatingPointError)
2081 POST_INIT(OverflowError)
2082 POST_INIT(ZeroDivisionError)
2083 POST_INIT(SystemError)
2084 POST_INIT(ReferenceError)
2085 POST_INIT(MemoryError)
2086 POST_INIT(Warning)
2087 POST_INIT(UserWarning)
2088 POST_INIT(DeprecationWarning)
2089 POST_INIT(PendingDeprecationWarning)
2090 POST_INIT(SyntaxWarning)
2091 POST_INIT(RuntimeWarning)
2092 POST_INIT(FutureWarning)
2093 POST_INIT(ImportWarning)
2094
2095 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2096 if (!PyExc_MemoryErrorInst)
2097 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2098
2099 Py_DECREF(bltinmod);
2100}
2101
2102void
2103_PyExc_Fini(void)
2104{
2105 Py_XDECREF(PyExc_MemoryErrorInst);
2106 PyExc_MemoryErrorInst = NULL;
2107}