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