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