blob: c3ead698e81597f25e5d60dc242680a705a4aff1 [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
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000854 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000855
856 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000857
858 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859 Py_DECREF(tuple);
860 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000861 else if (self->myerrno && self->strerror) {
862 PyObject *fmt;
863 PyObject *tuple;
864
Thomas Wouters477c8d52006-05-27 19:21:47 +0000865 fmt = PyString_FromString("[Error %s] %s");
866 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000867 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000868
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000869 tuple = PyTuple_New(2);
870 if (!tuple) {
871 Py_DECREF(fmt);
872 return NULL;
873 }
874
875 if (self->myerrno) {
876 Py_INCREF(self->myerrno);
877 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
878 }
879 else {
880 Py_INCREF(Py_None);
881 PyTuple_SET_ITEM(tuple, 0, Py_None);
882 }
883 if (self->strerror) {
884 Py_INCREF(self->strerror);
885 PyTuple_SET_ITEM(tuple, 1, self->strerror);
886 }
887 else {
888 Py_INCREF(Py_None);
889 PyTuple_SET_ITEM(tuple, 1, Py_None);
890 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000891
892 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000893
894 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895 Py_DECREF(tuple);
896 }
897 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000898 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000899
Thomas Wouters477c8d52006-05-27 19:21:47 +0000900 return rtnval;
901}
902
903static PyMemberDef WindowsError_members[] = {
904 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
905 PyDoc_STR("exception message")},
906 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
907 PyDoc_STR("POSIX exception code")},
908 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
909 PyDoc_STR("exception strerror")},
910 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
911 PyDoc_STR("exception filename")},
912 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
913 PyDoc_STR("Win32 exception code")},
914 {NULL} /* Sentinel */
915};
916
917ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
918 WindowsError_dealloc, 0, WindowsError_members,
919 WindowsError_str, "MS-Windows OS system call failed.");
920
921#endif /* MS_WINDOWS */
922
923
924/*
925 * VMSError extends OSError (I think)
926 */
927#ifdef __VMS
928MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
929 "OpenVMS OS system call failed.");
930#endif
931
932
933/*
934 * EOFError extends StandardError
935 */
936SimpleExtendsException(PyExc_StandardError, EOFError,
937 "Read beyond end of file.");
938
939
940/*
941 * RuntimeError extends StandardError
942 */
943SimpleExtendsException(PyExc_StandardError, RuntimeError,
944 "Unspecified run-time error.");
945
946
947/*
948 * NotImplementedError extends RuntimeError
949 */
950SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
951 "Method or function hasn't been implemented yet.");
952
953/*
954 * NameError extends StandardError
955 */
956SimpleExtendsException(PyExc_StandardError, NameError,
957 "Name not found globally.");
958
959/*
960 * UnboundLocalError extends NameError
961 */
962SimpleExtendsException(PyExc_NameError, UnboundLocalError,
963 "Local name referenced but not bound to a value.");
964
965/*
966 * AttributeError extends StandardError
967 */
968SimpleExtendsException(PyExc_StandardError, AttributeError,
969 "Attribute not found.");
970
971
972/*
973 * SyntaxError extends StandardError
974 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000975
976static int
977SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
978{
979 PyObject *info = NULL;
980 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
981
982 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
983 return -1;
984
985 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000986 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000987 self->msg = PyTuple_GET_ITEM(args, 0);
988 Py_INCREF(self->msg);
989 }
990 if (lenargs == 2) {
991 info = PyTuple_GET_ITEM(args, 1);
992 info = PySequence_Tuple(info);
993 if (!info) return -1;
994
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000995 if (PyTuple_GET_SIZE(info) != 4) {
996 /* not a very good error message, but it's what Python 2.4 gives */
997 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
998 Py_DECREF(info);
999 return -1;
1000 }
1001
1002 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003 self->filename = PyTuple_GET_ITEM(info, 0);
1004 Py_INCREF(self->filename);
1005
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001006 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001007 self->lineno = PyTuple_GET_ITEM(info, 1);
1008 Py_INCREF(self->lineno);
1009
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001010 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001011 self->offset = PyTuple_GET_ITEM(info, 2);
1012 Py_INCREF(self->offset);
1013
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001014 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001015 self->text = PyTuple_GET_ITEM(info, 3);
1016 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001017
1018 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019 }
1020 return 0;
1021}
1022
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001023static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024SyntaxError_clear(PySyntaxErrorObject *self)
1025{
1026 Py_CLEAR(self->msg);
1027 Py_CLEAR(self->filename);
1028 Py_CLEAR(self->lineno);
1029 Py_CLEAR(self->offset);
1030 Py_CLEAR(self->text);
1031 Py_CLEAR(self->print_file_and_line);
1032 return BaseException_clear((PyBaseExceptionObject *)self);
1033}
1034
1035static void
1036SyntaxError_dealloc(PySyntaxErrorObject *self)
1037{
1038 SyntaxError_clear(self);
1039 self->ob_type->tp_free((PyObject *)self);
1040}
1041
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001042static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001043SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1044{
1045 Py_VISIT(self->msg);
1046 Py_VISIT(self->filename);
1047 Py_VISIT(self->lineno);
1048 Py_VISIT(self->offset);
1049 Py_VISIT(self->text);
1050 Py_VISIT(self->print_file_and_line);
1051 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1052}
1053
1054/* This is called "my_basename" instead of just "basename" to avoid name
1055 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1056 defined, and Python does define that. */
1057static char *
1058my_basename(char *name)
1059{
1060 char *cp = name;
1061 char *result = name;
1062
1063 if (name == NULL)
1064 return "???";
1065 while (*cp != '\0') {
1066 if (*cp == SEP)
1067 result = cp + 1;
1068 ++cp;
1069 }
1070 return result;
1071}
1072
1073
1074static PyObject *
1075SyntaxError_str(PySyntaxErrorObject *self)
1076{
1077 PyObject *str;
1078 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001079 int have_filename = 0;
1080 int have_lineno = 0;
1081 char *buffer = NULL;
1082 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001083
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001084 if (self->msg)
1085 str = PyObject_Str(self->msg);
1086 else
1087 str = PyObject_Str(Py_None);
1088 if (!str) return NULL;
1089 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1090 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001091
1092 /* XXX -- do all the additional formatting with filename and
1093 lineno here */
1094
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001095 have_filename = (self->filename != NULL) &&
1096 PyString_Check(self->filename);
1097 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001098
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001099 if (!have_filename && !have_lineno)
1100 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001101
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001102 bufsize = PyString_GET_SIZE(str) + 64;
1103 if (have_filename)
1104 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001105
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001106 buffer = PyMem_MALLOC(bufsize);
1107 if (buffer == NULL)
1108 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001109
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001110 if (have_filename && have_lineno)
1111 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1112 PyString_AS_STRING(str),
1113 my_basename(PyString_AS_STRING(self->filename)),
1114 PyInt_AsLong(self->lineno));
1115 else if (have_filename)
1116 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1117 PyString_AS_STRING(str),
1118 my_basename(PyString_AS_STRING(self->filename)));
1119 else /* only have_lineno */
1120 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1121 PyString_AS_STRING(str),
1122 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001123
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001124 result = PyString_FromString(buffer);
1125 PyMem_FREE(buffer);
1126
1127 if (result == NULL)
1128 result = str;
1129 else
1130 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001131 return result;
1132}
1133
1134static PyMemberDef SyntaxError_members[] = {
1135 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1136 PyDoc_STR("exception message")},
1137 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1138 PyDoc_STR("exception msg")},
1139 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1140 PyDoc_STR("exception filename")},
1141 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1142 PyDoc_STR("exception lineno")},
1143 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1144 PyDoc_STR("exception offset")},
1145 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1146 PyDoc_STR("exception text")},
1147 {"print_file_and_line", T_OBJECT,
1148 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1149 PyDoc_STR("exception print_file_and_line")},
1150 {NULL} /* Sentinel */
1151};
1152
1153ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1154 SyntaxError_dealloc, 0, SyntaxError_members,
1155 SyntaxError_str, "Invalid syntax.");
1156
1157
1158/*
1159 * IndentationError extends SyntaxError
1160 */
1161MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1162 "Improper indentation.");
1163
1164
1165/*
1166 * TabError extends IndentationError
1167 */
1168MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1169 "Improper mixture of spaces and tabs.");
1170
1171
1172/*
1173 * LookupError extends StandardError
1174 */
1175SimpleExtendsException(PyExc_StandardError, LookupError,
1176 "Base class for lookup errors.");
1177
1178
1179/*
1180 * IndexError extends LookupError
1181 */
1182SimpleExtendsException(PyExc_LookupError, IndexError,
1183 "Sequence index out of range.");
1184
1185
1186/*
1187 * KeyError extends LookupError
1188 */
1189static PyObject *
1190KeyError_str(PyBaseExceptionObject *self)
1191{
1192 /* If args is a tuple of exactly one item, apply repr to args[0].
1193 This is done so that e.g. the exception raised by {}[''] prints
1194 KeyError: ''
1195 rather than the confusing
1196 KeyError
1197 alone. The downside is that if KeyError is raised with an explanatory
1198 string, that string will be displayed in quotes. Too bad.
1199 If args is anything else, use the default BaseException__str__().
1200 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001201 if (PyTuple_GET_SIZE(self->args) == 1) {
1202 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001203 }
1204 return BaseException_str(self);
1205}
1206
1207ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1208 0, 0, 0, KeyError_str, "Mapping key not found.");
1209
1210
1211/*
1212 * ValueError extends StandardError
1213 */
1214SimpleExtendsException(PyExc_StandardError, ValueError,
1215 "Inappropriate argument value (of correct type).");
1216
1217/*
1218 * UnicodeError extends ValueError
1219 */
1220
1221SimpleExtendsException(PyExc_ValueError, UnicodeError,
1222 "Unicode related error.");
1223
1224#ifdef Py_USING_UNICODE
1225static int
1226get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1227{
1228 if (!attr) {
1229 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1230 return -1;
1231 }
1232
1233 if (PyInt_Check(attr)) {
1234 *value = PyInt_AS_LONG(attr);
1235 } else if (PyLong_Check(attr)) {
1236 *value = _PyLong_AsSsize_t(attr);
1237 if (*value == -1 && PyErr_Occurred())
1238 return -1;
1239 } else {
1240 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1241 return -1;
1242 }
1243 return 0;
1244}
1245
1246static int
1247set_ssize_t(PyObject **attr, Py_ssize_t value)
1248{
1249 PyObject *obj = PyInt_FromSsize_t(value);
1250 if (!obj)
1251 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001252 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253 *attr = obj;
1254 return 0;
1255}
1256
1257static PyObject *
1258get_string(PyObject *attr, const char *name)
1259{
1260 if (!attr) {
1261 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1262 return NULL;
1263 }
1264
1265 if (!PyString_Check(attr)) {
1266 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1267 return NULL;
1268 }
1269 Py_INCREF(attr);
1270 return attr;
1271}
1272
1273
1274static int
1275set_string(PyObject **attr, const char *value)
1276{
1277 PyObject *obj = PyString_FromString(value);
1278 if (!obj)
1279 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001280 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001281 *attr = obj;
1282 return 0;
1283}
1284
1285
1286static PyObject *
1287get_unicode(PyObject *attr, const char *name)
1288{
1289 if (!attr) {
1290 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1291 return NULL;
1292 }
1293
1294 if (!PyUnicode_Check(attr)) {
1295 PyErr_Format(PyExc_TypeError,
1296 "%.200s attribute must be unicode", name);
1297 return NULL;
1298 }
1299 Py_INCREF(attr);
1300 return attr;
1301}
1302
1303PyObject *
1304PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1305{
1306 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1307}
1308
1309PyObject *
1310PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1311{
1312 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1313}
1314
1315PyObject *
1316PyUnicodeEncodeError_GetObject(PyObject *exc)
1317{
1318 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1319}
1320
1321PyObject *
1322PyUnicodeDecodeError_GetObject(PyObject *exc)
1323{
1324 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1325}
1326
1327PyObject *
1328PyUnicodeTranslateError_GetObject(PyObject *exc)
1329{
1330 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1331}
1332
1333int
1334PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1335{
1336 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1337 Py_ssize_t size;
1338 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1339 "object");
1340 if (!obj) return -1;
1341 size = PyUnicode_GET_SIZE(obj);
1342 if (*start<0)
1343 *start = 0; /*XXX check for values <0*/
1344 if (*start>=size)
1345 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001346 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001347 return 0;
1348 }
1349 return -1;
1350}
1351
1352
1353int
1354PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1355{
1356 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1357 Py_ssize_t size;
1358 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1359 "object");
1360 if (!obj) return -1;
1361 size = PyString_GET_SIZE(obj);
1362 if (*start<0)
1363 *start = 0;
1364 if (*start>=size)
1365 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001366 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001367 return 0;
1368 }
1369 return -1;
1370}
1371
1372
1373int
1374PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1375{
1376 return PyUnicodeEncodeError_GetStart(exc, start);
1377}
1378
1379
1380int
1381PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1382{
1383 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1384}
1385
1386
1387int
1388PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1389{
1390 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1391}
1392
1393
1394int
1395PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1396{
1397 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1398}
1399
1400
1401int
1402PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1403{
1404 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1405 Py_ssize_t size;
1406 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1407 "object");
1408 if (!obj) return -1;
1409 size = PyUnicode_GET_SIZE(obj);
1410 if (*end<1)
1411 *end = 1;
1412 if (*end>size)
1413 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001414 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415 return 0;
1416 }
1417 return -1;
1418}
1419
1420
1421int
1422PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1423{
1424 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1425 Py_ssize_t size;
1426 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1427 "object");
1428 if (!obj) return -1;
1429 size = PyString_GET_SIZE(obj);
1430 if (*end<1)
1431 *end = 1;
1432 if (*end>size)
1433 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001434 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435 return 0;
1436 }
1437 return -1;
1438}
1439
1440
1441int
1442PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1443{
1444 return PyUnicodeEncodeError_GetEnd(exc, start);
1445}
1446
1447
1448int
1449PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1450{
1451 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1452}
1453
1454
1455int
1456PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1457{
1458 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1459}
1460
1461
1462int
1463PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1464{
1465 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1466}
1467
1468PyObject *
1469PyUnicodeEncodeError_GetReason(PyObject *exc)
1470{
1471 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1472}
1473
1474
1475PyObject *
1476PyUnicodeDecodeError_GetReason(PyObject *exc)
1477{
1478 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1479}
1480
1481
1482PyObject *
1483PyUnicodeTranslateError_GetReason(PyObject *exc)
1484{
1485 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1486}
1487
1488
1489int
1490PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1491{
1492 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1493}
1494
1495
1496int
1497PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1498{
1499 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1500}
1501
1502
1503int
1504PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1505{
1506 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1507}
1508
1509
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510static int
1511UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1512 PyTypeObject *objecttype)
1513{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001514 Py_CLEAR(self->encoding);
1515 Py_CLEAR(self->object);
1516 Py_CLEAR(self->start);
1517 Py_CLEAR(self->end);
1518 Py_CLEAR(self->reason);
1519
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1521 &PyString_Type, &self->encoding,
1522 objecttype, &self->object,
1523 &PyInt_Type, &self->start,
1524 &PyInt_Type, &self->end,
1525 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001526 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527 self->reason = NULL;
1528 return -1;
1529 }
1530
1531 Py_INCREF(self->encoding);
1532 Py_INCREF(self->object);
1533 Py_INCREF(self->start);
1534 Py_INCREF(self->end);
1535 Py_INCREF(self->reason);
1536
1537 return 0;
1538}
1539
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001540static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001541UnicodeError_clear(PyUnicodeErrorObject *self)
1542{
1543 Py_CLEAR(self->encoding);
1544 Py_CLEAR(self->object);
1545 Py_CLEAR(self->start);
1546 Py_CLEAR(self->end);
1547 Py_CLEAR(self->reason);
1548 return BaseException_clear((PyBaseExceptionObject *)self);
1549}
1550
1551static void
1552UnicodeError_dealloc(PyUnicodeErrorObject *self)
1553{
1554 UnicodeError_clear(self);
1555 self->ob_type->tp_free((PyObject *)self);
1556}
1557
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001558static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1560{
1561 Py_VISIT(self->encoding);
1562 Py_VISIT(self->object);
1563 Py_VISIT(self->start);
1564 Py_VISIT(self->end);
1565 Py_VISIT(self->reason);
1566 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1567}
1568
1569static PyMemberDef UnicodeError_members[] = {
1570 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1571 PyDoc_STR("exception message")},
1572 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1573 PyDoc_STR("exception encoding")},
1574 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1575 PyDoc_STR("exception object")},
1576 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1577 PyDoc_STR("exception start")},
1578 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1579 PyDoc_STR("exception end")},
1580 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1581 PyDoc_STR("exception reason")},
1582 {NULL} /* Sentinel */
1583};
1584
1585
1586/*
1587 * UnicodeEncodeError extends UnicodeError
1588 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001589
1590static int
1591UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1592{
1593 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1594 return -1;
1595 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1596 kwds, &PyUnicode_Type);
1597}
1598
1599static PyObject *
1600UnicodeEncodeError_str(PyObject *self)
1601{
1602 Py_ssize_t start;
1603 Py_ssize_t end;
1604
1605 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001606 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001607
1608 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001609 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610
1611 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001612 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1613 char badchar_str[20];
1614 if (badchar <= 0xff)
1615 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1616 else if (badchar <= 0xffff)
1617 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1618 else
1619 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1620 return PyString_FromFormat(
1621 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1622 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1623 badchar_str,
1624 start,
1625 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1626 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627 }
1628 return PyString_FromFormat(
1629 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1630 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1631 start,
1632 (end-1),
1633 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1634 );
1635}
1636
1637static PyTypeObject _PyExc_UnicodeEncodeError = {
1638 PyObject_HEAD_INIT(NULL)
1639 0,
1640 "UnicodeEncodeError",
1641 sizeof(PyUnicodeErrorObject), 0,
1642 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1643 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1644 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001645 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1646 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001647 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001648 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649};
1650PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1651
1652PyObject *
1653PyUnicodeEncodeError_Create(
1654 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1655 Py_ssize_t start, Py_ssize_t end, const char *reason)
1656{
1657 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001658 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659}
1660
1661
1662/*
1663 * UnicodeDecodeError extends UnicodeError
1664 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001665
1666static int
1667UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1668{
1669 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1670 return -1;
1671 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1672 kwds, &PyString_Type);
1673}
1674
1675static PyObject *
1676UnicodeDecodeError_str(PyObject *self)
1677{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001678 Py_ssize_t start = 0;
1679 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001680
1681 if (PyUnicodeDecodeError_GetStart(self, &start))
1682 return NULL;
1683
1684 if (PyUnicodeDecodeError_GetEnd(self, &end))
1685 return NULL;
1686
1687 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001688 /* FromFormat does not support %02x, so format that separately */
1689 char byte[4];
1690 PyOS_snprintf(byte, sizeof(byte), "%02x",
1691 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1692 return PyString_FromFormat(
1693 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1694 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1695 byte,
1696 start,
1697 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1698 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001699 }
1700 return PyString_FromFormat(
1701 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1702 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1703 start,
1704 (end-1),
1705 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1706 );
1707}
1708
1709static PyTypeObject _PyExc_UnicodeDecodeError = {
1710 PyObject_HEAD_INIT(NULL)
1711 0,
1712 EXC_MODULE_NAME "UnicodeDecodeError",
1713 sizeof(PyUnicodeErrorObject), 0,
1714 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1715 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1716 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001717 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1718 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001719 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001720 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721};
1722PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1723
1724PyObject *
1725PyUnicodeDecodeError_Create(
1726 const char *encoding, const char *object, Py_ssize_t length,
1727 Py_ssize_t start, Py_ssize_t end, const char *reason)
1728{
1729 assert(length < INT_MAX);
1730 assert(start < INT_MAX);
1731 assert(end < INT_MAX);
1732 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001733 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001734}
1735
1736
1737/*
1738 * UnicodeTranslateError extends UnicodeError
1739 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740
1741static int
1742UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1743 PyObject *kwds)
1744{
1745 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1746 return -1;
1747
1748 Py_CLEAR(self->object);
1749 Py_CLEAR(self->start);
1750 Py_CLEAR(self->end);
1751 Py_CLEAR(self->reason);
1752
1753 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1754 &PyUnicode_Type, &self->object,
1755 &PyInt_Type, &self->start,
1756 &PyInt_Type, &self->end,
1757 &PyString_Type, &self->reason)) {
1758 self->object = self->start = self->end = self->reason = NULL;
1759 return -1;
1760 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001761
Thomas Wouters477c8d52006-05-27 19:21:47 +00001762 Py_INCREF(self->object);
1763 Py_INCREF(self->start);
1764 Py_INCREF(self->end);
1765 Py_INCREF(self->reason);
1766
1767 return 0;
1768}
1769
1770
1771static PyObject *
1772UnicodeTranslateError_str(PyObject *self)
1773{
1774 Py_ssize_t start;
1775 Py_ssize_t end;
1776
1777 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001778 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779
1780 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001781 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001782
1783 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001784 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1785 char badchar_str[20];
1786 if (badchar <= 0xff)
1787 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1788 else if (badchar <= 0xffff)
1789 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1790 else
1791 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1792 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001793 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001794 badchar_str,
1795 start,
1796 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1797 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798 }
1799 return PyString_FromFormat(
1800 "can't translate characters in position %zd-%zd: %.400s",
1801 start,
1802 (end-1),
1803 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1804 );
1805}
1806
1807static PyTypeObject _PyExc_UnicodeTranslateError = {
1808 PyObject_HEAD_INIT(NULL)
1809 0,
1810 EXC_MODULE_NAME "UnicodeTranslateError",
1811 sizeof(PyUnicodeErrorObject), 0,
1812 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1813 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1814 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1815 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1816 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1817 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001818 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001819};
1820PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1821
1822PyObject *
1823PyUnicodeTranslateError_Create(
1824 const Py_UNICODE *object, Py_ssize_t length,
1825 Py_ssize_t start, Py_ssize_t end, const char *reason)
1826{
1827 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001828 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001829}
1830#endif
1831
1832
1833/*
1834 * AssertionError extends StandardError
1835 */
1836SimpleExtendsException(PyExc_StandardError, AssertionError,
1837 "Assertion failed.");
1838
1839
1840/*
1841 * ArithmeticError extends StandardError
1842 */
1843SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1844 "Base class for arithmetic errors.");
1845
1846
1847/*
1848 * FloatingPointError extends ArithmeticError
1849 */
1850SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1851 "Floating point operation failed.");
1852
1853
1854/*
1855 * OverflowError extends ArithmeticError
1856 */
1857SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1858 "Result too large to be represented.");
1859
1860
1861/*
1862 * ZeroDivisionError extends ArithmeticError
1863 */
1864SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1865 "Second argument to a division or modulo operation was zero.");
1866
1867
1868/*
1869 * SystemError extends StandardError
1870 */
1871SimpleExtendsException(PyExc_StandardError, SystemError,
1872 "Internal error in the Python interpreter.\n"
1873 "\n"
1874 "Please report this to the Python maintainer, along with the traceback,\n"
1875 "the Python version, and the hardware/OS platform and version.");
1876
1877
1878/*
1879 * ReferenceError extends StandardError
1880 */
1881SimpleExtendsException(PyExc_StandardError, ReferenceError,
1882 "Weak ref proxy used after referent went away.");
1883
1884
1885/*
1886 * MemoryError extends StandardError
1887 */
1888SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1889
1890
1891/* Warning category docstrings */
1892
1893/*
1894 * Warning extends Exception
1895 */
1896SimpleExtendsException(PyExc_Exception, Warning,
1897 "Base class for warning categories.");
1898
1899
1900/*
1901 * UserWarning extends Warning
1902 */
1903SimpleExtendsException(PyExc_Warning, UserWarning,
1904 "Base class for warnings generated by user code.");
1905
1906
1907/*
1908 * DeprecationWarning extends Warning
1909 */
1910SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1911 "Base class for warnings about deprecated features.");
1912
1913
1914/*
1915 * PendingDeprecationWarning extends Warning
1916 */
1917SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1918 "Base class for warnings about features which will be deprecated\n"
1919 "in the future.");
1920
1921
1922/*
1923 * SyntaxWarning extends Warning
1924 */
1925SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1926 "Base class for warnings about dubious syntax.");
1927
1928
1929/*
1930 * RuntimeWarning extends Warning
1931 */
1932SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1933 "Base class for warnings about dubious runtime behavior.");
1934
1935
1936/*
1937 * FutureWarning extends Warning
1938 */
1939SimpleExtendsException(PyExc_Warning, FutureWarning,
1940 "Base class for warnings about constructs that will change semantically\n"
1941 "in the future.");
1942
1943
1944/*
1945 * ImportWarning extends Warning
1946 */
1947SimpleExtendsException(PyExc_Warning, ImportWarning,
1948 "Base class for warnings about probable mistakes in module imports");
1949
1950
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001951/*
1952 * UnicodeWarning extends Warning
1953 */
1954SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1955 "Base class for warnings about Unicode related problems, mostly\n"
1956 "related to conversion problems.");
1957
1958
Thomas Wouters477c8d52006-05-27 19:21:47 +00001959/* Pre-computed MemoryError instance. Best to create this as early as
1960 * possible and not wait until a MemoryError is actually raised!
1961 */
1962PyObject *PyExc_MemoryErrorInst=NULL;
1963
1964/* module global functions */
1965static PyMethodDef functions[] = {
1966 /* Sentinel */
1967 {NULL, NULL}
1968};
1969
1970#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1971 Py_FatalError("exceptions bootstrapping error.");
1972
1973#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1974 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1975 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1976 Py_FatalError("Module dictionary insertion problem.");
1977
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001978#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1979/* crt variable checking in VisualStudio .NET 2005 */
1980#include <crtdbg.h>
1981
1982static int prevCrtReportMode;
1983static _invalid_parameter_handler prevCrtHandler;
1984
1985/* Invalid parameter handler. Sets a ValueError exception */
1986static void
1987InvalidParameterHandler(
1988 const wchar_t * expression,
1989 const wchar_t * function,
1990 const wchar_t * file,
1991 unsigned int line,
1992 uintptr_t pReserved)
1993{
1994 /* Do nothing, allow execution to continue. Usually this
1995 * means that the CRT will set errno to EINVAL
1996 */
1997}
1998#endif
1999
2000
Thomas Wouters477c8d52006-05-27 19:21:47 +00002001PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002002_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002003{
2004 PyObject *m, *bltinmod, *bdict;
2005
2006 PRE_INIT(BaseException)
2007 PRE_INIT(Exception)
2008 PRE_INIT(StandardError)
2009 PRE_INIT(TypeError)
2010 PRE_INIT(StopIteration)
2011 PRE_INIT(GeneratorExit)
2012 PRE_INIT(SystemExit)
2013 PRE_INIT(KeyboardInterrupt)
2014 PRE_INIT(ImportError)
2015 PRE_INIT(EnvironmentError)
2016 PRE_INIT(IOError)
2017 PRE_INIT(OSError)
2018#ifdef MS_WINDOWS
2019 PRE_INIT(WindowsError)
2020#endif
2021#ifdef __VMS
2022 PRE_INIT(VMSError)
2023#endif
2024 PRE_INIT(EOFError)
2025 PRE_INIT(RuntimeError)
2026 PRE_INIT(NotImplementedError)
2027 PRE_INIT(NameError)
2028 PRE_INIT(UnboundLocalError)
2029 PRE_INIT(AttributeError)
2030 PRE_INIT(SyntaxError)
2031 PRE_INIT(IndentationError)
2032 PRE_INIT(TabError)
2033 PRE_INIT(LookupError)
2034 PRE_INIT(IndexError)
2035 PRE_INIT(KeyError)
2036 PRE_INIT(ValueError)
2037 PRE_INIT(UnicodeError)
2038#ifdef Py_USING_UNICODE
2039 PRE_INIT(UnicodeEncodeError)
2040 PRE_INIT(UnicodeDecodeError)
2041 PRE_INIT(UnicodeTranslateError)
2042#endif
2043 PRE_INIT(AssertionError)
2044 PRE_INIT(ArithmeticError)
2045 PRE_INIT(FloatingPointError)
2046 PRE_INIT(OverflowError)
2047 PRE_INIT(ZeroDivisionError)
2048 PRE_INIT(SystemError)
2049 PRE_INIT(ReferenceError)
2050 PRE_INIT(MemoryError)
2051 PRE_INIT(Warning)
2052 PRE_INIT(UserWarning)
2053 PRE_INIT(DeprecationWarning)
2054 PRE_INIT(PendingDeprecationWarning)
2055 PRE_INIT(SyntaxWarning)
2056 PRE_INIT(RuntimeWarning)
2057 PRE_INIT(FutureWarning)
2058 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002059 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002060
2061 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2062 (PyObject *)NULL, PYTHON_API_VERSION);
2063 if (m == NULL) return;
2064
2065 bltinmod = PyImport_ImportModule("__builtin__");
2066 if (bltinmod == NULL)
2067 Py_FatalError("exceptions bootstrapping error.");
2068 bdict = PyModule_GetDict(bltinmod);
2069 if (bdict == NULL)
2070 Py_FatalError("exceptions bootstrapping error.");
2071
2072 POST_INIT(BaseException)
2073 POST_INIT(Exception)
2074 POST_INIT(StandardError)
2075 POST_INIT(TypeError)
2076 POST_INIT(StopIteration)
2077 POST_INIT(GeneratorExit)
2078 POST_INIT(SystemExit)
2079 POST_INIT(KeyboardInterrupt)
2080 POST_INIT(ImportError)
2081 POST_INIT(EnvironmentError)
2082 POST_INIT(IOError)
2083 POST_INIT(OSError)
2084#ifdef MS_WINDOWS
2085 POST_INIT(WindowsError)
2086#endif
2087#ifdef __VMS
2088 POST_INIT(VMSError)
2089#endif
2090 POST_INIT(EOFError)
2091 POST_INIT(RuntimeError)
2092 POST_INIT(NotImplementedError)
2093 POST_INIT(NameError)
2094 POST_INIT(UnboundLocalError)
2095 POST_INIT(AttributeError)
2096 POST_INIT(SyntaxError)
2097 POST_INIT(IndentationError)
2098 POST_INIT(TabError)
2099 POST_INIT(LookupError)
2100 POST_INIT(IndexError)
2101 POST_INIT(KeyError)
2102 POST_INIT(ValueError)
2103 POST_INIT(UnicodeError)
2104#ifdef Py_USING_UNICODE
2105 POST_INIT(UnicodeEncodeError)
2106 POST_INIT(UnicodeDecodeError)
2107 POST_INIT(UnicodeTranslateError)
2108#endif
2109 POST_INIT(AssertionError)
2110 POST_INIT(ArithmeticError)
2111 POST_INIT(FloatingPointError)
2112 POST_INIT(OverflowError)
2113 POST_INIT(ZeroDivisionError)
2114 POST_INIT(SystemError)
2115 POST_INIT(ReferenceError)
2116 POST_INIT(MemoryError)
2117 POST_INIT(Warning)
2118 POST_INIT(UserWarning)
2119 POST_INIT(DeprecationWarning)
2120 POST_INIT(PendingDeprecationWarning)
2121 POST_INIT(SyntaxWarning)
2122 POST_INIT(RuntimeWarning)
2123 POST_INIT(FutureWarning)
2124 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002125 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002126
2127 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2128 if (!PyExc_MemoryErrorInst)
2129 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2130
2131 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002132
2133#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2134 /* Set CRT argument error handler */
2135 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2136 /* turn off assertions in debug mode */
2137 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2138#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002139}
2140
2141void
2142_PyExc_Fini(void)
2143{
2144 Py_XDECREF(PyExc_MemoryErrorInst);
2145 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002146#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2147 /* reset CRT error handling */
2148 _set_invalid_parameter_handler(prevCrtHandler);
2149 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2150#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002151}