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