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