• 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 "pycore_initconfig.h"
10 #include "pycore_object.h"
11 #include "structmember.h"         // PyMemberDef
12 #include "osdefs.h"               // SEP
13 
14 
15 /* Compatibility aliases */
16 PyObject *PyExc_EnvironmentError = NULL;
17 PyObject *PyExc_IOError = NULL;
18 #ifdef MS_WINDOWS
19 PyObject *PyExc_WindowsError = NULL;
20 #endif
21 
22 
23 static struct _Py_exc_state*
get_exc_state(void)24 get_exc_state(void)
25 {
26     PyInterpreterState *interp = _PyInterpreterState_GET();
27     return &interp->exc_state;
28 }
29 
30 
31 /* NOTE: If the exception class hierarchy changes, don't forget to update
32  * Lib/test/exception_hierarchy.txt
33  */
34 
35 /*
36  *    BaseException
37  */
38 static PyObject *
BaseException_new(PyTypeObject * type,PyObject * args,PyObject * kwds)39 BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
40 {
41     PyBaseExceptionObject *self;
42 
43     self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
44     if (!self)
45         return NULL;
46     /* the dict is created on the fly in PyObject_GenericSetAttr */
47     self->dict = NULL;
48     self->traceback = self->cause = self->context = NULL;
49     self->suppress_context = 0;
50 
51     if (args) {
52         self->args = args;
53         Py_INCREF(args);
54         return (PyObject *)self;
55     }
56 
57     self->args = PyTuple_New(0);
58     if (!self->args) {
59         Py_DECREF(self);
60         return NULL;
61     }
62 
63     return (PyObject *)self;
64 }
65 
66 static int
BaseException_init(PyBaseExceptionObject * self,PyObject * args,PyObject * kwds)67 BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
68 {
69     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
70         return -1;
71 
72     Py_INCREF(args);
73     Py_XSETREF(self->args, args);
74 
75     return 0;
76 }
77 
78 static int
BaseException_clear(PyBaseExceptionObject * self)79 BaseException_clear(PyBaseExceptionObject *self)
80 {
81     Py_CLEAR(self->dict);
82     Py_CLEAR(self->args);
83     Py_CLEAR(self->traceback);
84     Py_CLEAR(self->cause);
85     Py_CLEAR(self->context);
86     return 0;
87 }
88 
89 static void
BaseException_dealloc(PyBaseExceptionObject * self)90 BaseException_dealloc(PyBaseExceptionObject *self)
91 {
92     _PyObject_GC_UNTRACK(self);
93     BaseException_clear(self);
94     Py_TYPE(self)->tp_free((PyObject *)self);
95 }
96 
97 static int
BaseException_traverse(PyBaseExceptionObject * self,visitproc visit,void * arg)98 BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
99 {
100     Py_VISIT(self->dict);
101     Py_VISIT(self->args);
102     Py_VISIT(self->traceback);
103     Py_VISIT(self->cause);
104     Py_VISIT(self->context);
105     return 0;
106 }
107 
108 static PyObject *
BaseException_str(PyBaseExceptionObject * self)109 BaseException_str(PyBaseExceptionObject *self)
110 {
111     switch (PyTuple_GET_SIZE(self->args)) {
112     case 0:
113         return PyUnicode_FromString("");
114     case 1:
115         return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
116     default:
117         return PyObject_Str(self->args);
118     }
119 }
120 
121 static PyObject *
BaseException_repr(PyBaseExceptionObject * self)122 BaseException_repr(PyBaseExceptionObject *self)
123 {
124     const char *name = _PyType_Name(Py_TYPE(self));
125     if (PyTuple_GET_SIZE(self->args) == 1)
126         return PyUnicode_FromFormat("%s(%R)", name,
127                                     PyTuple_GET_ITEM(self->args, 0));
128     else
129         return PyUnicode_FromFormat("%s%R", name, self->args);
130 }
131 
132 /* Pickling support */
133 static PyObject *
BaseException_reduce(PyBaseExceptionObject * self,PyObject * Py_UNUSED (ignored))134 BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
135 {
136     if (self->args && self->dict)
137         return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
138     else
139         return PyTuple_Pack(2, Py_TYPE(self), self->args);
140 }
141 
142 /*
143  * Needed for backward compatibility, since exceptions used to store
144  * all their attributes in the __dict__. Code is taken from cPickle's
145  * load_build function.
146  */
147 static PyObject *
BaseException_setstate(PyObject * self,PyObject * state)148 BaseException_setstate(PyObject *self, PyObject *state)
149 {
150     PyObject *d_key, *d_value;
151     Py_ssize_t i = 0;
152 
153     if (state != Py_None) {
154         if (!PyDict_Check(state)) {
155             PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
156             return NULL;
157         }
158         while (PyDict_Next(state, &i, &d_key, &d_value)) {
159             if (PyObject_SetAttr(self, d_key, d_value) < 0)
160                 return NULL;
161         }
162     }
163     Py_RETURN_NONE;
164 }
165 
166 static PyObject *
BaseException_with_traceback(PyObject * self,PyObject * tb)167 BaseException_with_traceback(PyObject *self, PyObject *tb) {
168     if (PyException_SetTraceback(self, tb))
169         return NULL;
170 
171     Py_INCREF(self);
172     return self;
173 }
174 
175 PyDoc_STRVAR(with_traceback_doc,
176 "Exception.with_traceback(tb) --\n\
177     set self.__traceback__ to tb and return self.");
178 
179 
180 static PyMethodDef BaseException_methods[] = {
181    {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
182    {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
183    {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
184     with_traceback_doc},
185    {NULL, NULL, 0, NULL},
186 };
187 
188 static PyObject *
BaseException_get_args(PyBaseExceptionObject * self,void * Py_UNUSED (ignored))189 BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
190 {
191     if (self->args == NULL) {
192         Py_RETURN_NONE;
193     }
194     Py_INCREF(self->args);
195     return self->args;
196 }
197 
198 static int
BaseException_set_args(PyBaseExceptionObject * self,PyObject * val,void * Py_UNUSED (ignored))199 BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
200 {
201     PyObject *seq;
202     if (val == NULL) {
203         PyErr_SetString(PyExc_TypeError, "args may not be deleted");
204         return -1;
205     }
206     seq = PySequence_Tuple(val);
207     if (!seq)
208         return -1;
209     Py_XSETREF(self->args, seq);
210     return 0;
211 }
212 
213 static PyObject *
BaseException_get_tb(PyBaseExceptionObject * self,void * Py_UNUSED (ignored))214 BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
215 {
216     if (self->traceback == NULL) {
217         Py_RETURN_NONE;
218     }
219     Py_INCREF(self->traceback);
220     return self->traceback;
221 }
222 
223 static int
BaseException_set_tb(PyBaseExceptionObject * self,PyObject * tb,void * Py_UNUSED (ignored))224 BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
225 {
226     if (tb == NULL) {
227         PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
228         return -1;
229     }
230     else if (!(tb == Py_None || PyTraceBack_Check(tb))) {
231         PyErr_SetString(PyExc_TypeError,
232                         "__traceback__ must be a traceback or None");
233         return -1;
234     }
235 
236     Py_INCREF(tb);
237     Py_XSETREF(self->traceback, tb);
238     return 0;
239 }
240 
241 static PyObject *
BaseException_get_context(PyObject * self,void * Py_UNUSED (ignored))242 BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
243 {
244     PyObject *res = PyException_GetContext(self);
245     if (res)
246         return res;  /* new reference already returned above */
247     Py_RETURN_NONE;
248 }
249 
250 static int
BaseException_set_context(PyObject * self,PyObject * arg,void * Py_UNUSED (ignored))251 BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
252 {
253     if (arg == NULL) {
254         PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
255         return -1;
256     } else if (arg == Py_None) {
257         arg = NULL;
258     } else if (!PyExceptionInstance_Check(arg)) {
259         PyErr_SetString(PyExc_TypeError, "exception context must be None "
260                         "or derive from BaseException");
261         return -1;
262     } else {
263         /* PyException_SetContext steals this reference */
264         Py_INCREF(arg);
265     }
266     PyException_SetContext(self, arg);
267     return 0;
268 }
269 
270 static PyObject *
BaseException_get_cause(PyObject * self,void * Py_UNUSED (ignored))271 BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
272 {
273     PyObject *res = PyException_GetCause(self);
274     if (res)
275         return res;  /* new reference already returned above */
276     Py_RETURN_NONE;
277 }
278 
279 static int
BaseException_set_cause(PyObject * self,PyObject * arg,void * Py_UNUSED (ignored))280 BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
281 {
282     if (arg == NULL) {
283         PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
284         return -1;
285     } else if (arg == Py_None) {
286         arg = NULL;
287     } else if (!PyExceptionInstance_Check(arg)) {
288         PyErr_SetString(PyExc_TypeError, "exception cause must be None "
289                         "or derive from BaseException");
290         return -1;
291     } else {
292         /* PyException_SetCause steals this reference */
293         Py_INCREF(arg);
294     }
295     PyException_SetCause(self, arg);
296     return 0;
297 }
298 
299 
300 static PyGetSetDef BaseException_getset[] = {
301     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
302     {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
303     {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
304     {"__context__", BaseException_get_context,
305      BaseException_set_context, PyDoc_STR("exception context")},
306     {"__cause__", BaseException_get_cause,
307      BaseException_set_cause, PyDoc_STR("exception cause")},
308     {NULL},
309 };
310 
311 
312 static inline PyBaseExceptionObject*
_PyBaseExceptionObject_cast(PyObject * exc)313 _PyBaseExceptionObject_cast(PyObject *exc)
314 {
315     assert(PyExceptionInstance_Check(exc));
316     return (PyBaseExceptionObject *)exc;
317 }
318 
319 
320 PyObject *
PyException_GetTraceback(PyObject * self)321 PyException_GetTraceback(PyObject *self)
322 {
323     PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
324     Py_XINCREF(base_self->traceback);
325     return base_self->traceback;
326 }
327 
328 
329 int
PyException_SetTraceback(PyObject * self,PyObject * tb)330 PyException_SetTraceback(PyObject *self, PyObject *tb)
331 {
332     return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
333 }
334 
335 PyObject *
PyException_GetCause(PyObject * self)336 PyException_GetCause(PyObject *self)
337 {
338     PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
339     Py_XINCREF(cause);
340     return cause;
341 }
342 
343 /* Steals a reference to cause */
344 void
PyException_SetCause(PyObject * self,PyObject * cause)345 PyException_SetCause(PyObject *self, PyObject *cause)
346 {
347     PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
348     base_self->suppress_context = 1;
349     Py_XSETREF(base_self->cause, cause);
350 }
351 
352 PyObject *
PyException_GetContext(PyObject * self)353 PyException_GetContext(PyObject *self)
354 {
355     PyObject *context = _PyBaseExceptionObject_cast(self)->context;
356     Py_XINCREF(context);
357     return context;
358 }
359 
360 /* Steals a reference to context */
361 void
PyException_SetContext(PyObject * self,PyObject * context)362 PyException_SetContext(PyObject *self, PyObject *context)
363 {
364     Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
365 }
366 
367 const char *
PyExceptionClass_Name(PyObject * ob)368 PyExceptionClass_Name(PyObject *ob)
369 {
370     assert(PyExceptionClass_Check(ob));
371     return ((PyTypeObject*)ob)->tp_name;
372 }
373 
374 static struct PyMemberDef BaseException_members[] = {
375     {"__suppress_context__", T_BOOL,
376      offsetof(PyBaseExceptionObject, suppress_context)},
377     {NULL}
378 };
379 
380 
381 static PyTypeObject _PyExc_BaseException = {
382     PyVarObject_HEAD_INIT(NULL, 0)
383     "BaseException", /*tp_name*/
384     sizeof(PyBaseExceptionObject), /*tp_basicsize*/
385     0,                          /*tp_itemsize*/
386     (destructor)BaseException_dealloc, /*tp_dealloc*/
387     0,                          /*tp_vectorcall_offset*/
388     0,                          /*tp_getattr*/
389     0,                          /*tp_setattr*/
390     0,                          /*tp_as_async*/
391     (reprfunc)BaseException_repr, /*tp_repr*/
392     0,                          /*tp_as_number*/
393     0,                          /*tp_as_sequence*/
394     0,                          /*tp_as_mapping*/
395     0,                          /*tp_hash */
396     0,                          /*tp_call*/
397     (reprfunc)BaseException_str,  /*tp_str*/
398     PyObject_GenericGetAttr,    /*tp_getattro*/
399     PyObject_GenericSetAttr,    /*tp_setattro*/
400     0,                          /*tp_as_buffer*/
401     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
402         Py_TPFLAGS_BASE_EXC_SUBCLASS,  /*tp_flags*/
403     PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
404     (traverseproc)BaseException_traverse, /* tp_traverse */
405     (inquiry)BaseException_clear, /* tp_clear */
406     0,                          /* tp_richcompare */
407     0,                          /* tp_weaklistoffset */
408     0,                          /* tp_iter */
409     0,                          /* tp_iternext */
410     BaseException_methods,      /* tp_methods */
411     BaseException_members,      /* tp_members */
412     BaseException_getset,       /* tp_getset */
413     0,                          /* tp_base */
414     0,                          /* tp_dict */
415     0,                          /* tp_descr_get */
416     0,                          /* tp_descr_set */
417     offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
418     (initproc)BaseException_init, /* tp_init */
419     0,                          /* tp_alloc */
420     BaseException_new,          /* tp_new */
421 };
422 /* the CPython API expects exceptions to be (PyObject *) - both a hold-over
423 from the previous implementation and also allowing Python objects to be used
424 in the API */
425 PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
426 
427 /* note these macros omit the last semicolon so the macro invocation may
428  * include it and not look strange.
429  */
430 #define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
431 static PyTypeObject _PyExc_ ## EXCNAME = { \
432     PyVarObject_HEAD_INIT(NULL, 0) \
433     # EXCNAME, \
434     sizeof(PyBaseExceptionObject), \
435     0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
436     0, 0, 0, 0, 0, 0, 0, \
437     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
438     PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
439     (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
440     0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
441     (initproc)BaseException_init, 0, BaseException_new,\
442 }; \
443 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
444 
445 #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
446 static PyTypeObject _PyExc_ ## EXCNAME = { \
447     PyVarObject_HEAD_INIT(NULL, 0) \
448     # EXCNAME, \
449     sizeof(Py ## EXCSTORE ## Object), \
450     0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
451     0, 0, 0, 0, 0, \
452     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
453     PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
454     (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
455     0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
456     (initproc)EXCSTORE ## _init, 0, 0, \
457 }; \
458 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
459 
460 #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
461                                 EXCMETHODS, EXCMEMBERS, EXCGETSET, \
462                                 EXCSTR, EXCDOC) \
463 static PyTypeObject _PyExc_ ## EXCNAME = { \
464     PyVarObject_HEAD_INIT(NULL, 0) \
465     # EXCNAME, \
466     sizeof(Py ## EXCSTORE ## Object), 0, \
467     (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
468     (reprfunc)EXCSTR, 0, 0, 0, \
469     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
470     PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
471     (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
472     EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
473     0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
474     (initproc)EXCSTORE ## _init, 0, EXCNEW,\
475 }; \
476 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
477 
478 
479 /*
480  *    Exception extends BaseException
481  */
482 SimpleExtendsException(PyExc_BaseException, Exception,
483                        "Common base class for all non-exit exceptions.");
484 
485 
486 /*
487  *    TypeError extends Exception
488  */
489 SimpleExtendsException(PyExc_Exception, TypeError,
490                        "Inappropriate argument type.");
491 
492 
493 /*
494  *    StopAsyncIteration extends Exception
495  */
496 SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
497                        "Signal the end from iterator.__anext__().");
498 
499 
500 /*
501  *    StopIteration extends Exception
502  */
503 
504 static PyMemberDef StopIteration_members[] = {
505     {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
506         PyDoc_STR("generator return value")},
507     {NULL}  /* Sentinel */
508 };
509 
510 static int
StopIteration_init(PyStopIterationObject * self,PyObject * args,PyObject * kwds)511 StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds)
512 {
513     Py_ssize_t size = PyTuple_GET_SIZE(args);
514     PyObject *value;
515 
516     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
517         return -1;
518     Py_CLEAR(self->value);
519     if (size > 0)
520         value = PyTuple_GET_ITEM(args, 0);
521     else
522         value = Py_None;
523     Py_INCREF(value);
524     self->value = value;
525     return 0;
526 }
527 
528 static int
StopIteration_clear(PyStopIterationObject * self)529 StopIteration_clear(PyStopIterationObject *self)
530 {
531     Py_CLEAR(self->value);
532     return BaseException_clear((PyBaseExceptionObject *)self);
533 }
534 
535 static void
StopIteration_dealloc(PyStopIterationObject * self)536 StopIteration_dealloc(PyStopIterationObject *self)
537 {
538     _PyObject_GC_UNTRACK(self);
539     StopIteration_clear(self);
540     Py_TYPE(self)->tp_free((PyObject *)self);
541 }
542 
543 static int
StopIteration_traverse(PyStopIterationObject * self,visitproc visit,void * arg)544 StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
545 {
546     Py_VISIT(self->value);
547     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
548 }
549 
550 ComplexExtendsException(
551     PyExc_Exception,       /* base */
552     StopIteration,         /* name */
553     StopIteration,         /* prefix for *_init, etc */
554     0,                     /* new */
555     0,                     /* methods */
556     StopIteration_members, /* members */
557     0,                     /* getset */
558     0,                     /* str */
559     "Signal the end from iterator.__next__()."
560 );
561 
562 
563 /*
564  *    GeneratorExit extends BaseException
565  */
566 SimpleExtendsException(PyExc_BaseException, GeneratorExit,
567                        "Request that a generator exit.");
568 
569 
570 /*
571  *    SystemExit extends BaseException
572  */
573 
574 static int
SystemExit_init(PySystemExitObject * self,PyObject * args,PyObject * kwds)575 SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
576 {
577     Py_ssize_t size = PyTuple_GET_SIZE(args);
578 
579     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
580         return -1;
581 
582     if (size == 0)
583         return 0;
584     if (size == 1) {
585         Py_INCREF(PyTuple_GET_ITEM(args, 0));
586         Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
587     }
588     else { /* size > 1 */
589         Py_INCREF(args);
590         Py_XSETREF(self->code, args);
591     }
592     return 0;
593 }
594 
595 static int
SystemExit_clear(PySystemExitObject * self)596 SystemExit_clear(PySystemExitObject *self)
597 {
598     Py_CLEAR(self->code);
599     return BaseException_clear((PyBaseExceptionObject *)self);
600 }
601 
602 static void
SystemExit_dealloc(PySystemExitObject * self)603 SystemExit_dealloc(PySystemExitObject *self)
604 {
605     _PyObject_GC_UNTRACK(self);
606     SystemExit_clear(self);
607     Py_TYPE(self)->tp_free((PyObject *)self);
608 }
609 
610 static int
SystemExit_traverse(PySystemExitObject * self,visitproc visit,void * arg)611 SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
612 {
613     Py_VISIT(self->code);
614     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
615 }
616 
617 static PyMemberDef SystemExit_members[] = {
618     {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
619         PyDoc_STR("exception code")},
620     {NULL}  /* Sentinel */
621 };
622 
623 ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
624                         0, 0, SystemExit_members, 0, 0,
625                         "Request to exit from the interpreter.");
626 
627 /*
628  *    KeyboardInterrupt extends BaseException
629  */
630 SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
631                        "Program interrupted by user.");
632 
633 
634 /*
635  *    ImportError extends Exception
636  */
637 
638 static int
ImportError_init(PyImportErrorObject * self,PyObject * args,PyObject * kwds)639 ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
640 {
641     static char *kwlist[] = {"name", "path", 0};
642     PyObject *empty_tuple;
643     PyObject *msg = NULL;
644     PyObject *name = NULL;
645     PyObject *path = NULL;
646 
647     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1)
648         return -1;
649 
650     empty_tuple = PyTuple_New(0);
651     if (!empty_tuple)
652         return -1;
653     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist,
654                                      &name, &path)) {
655         Py_DECREF(empty_tuple);
656         return -1;
657     }
658     Py_DECREF(empty_tuple);
659 
660     Py_XINCREF(name);
661     Py_XSETREF(self->name, name);
662 
663     Py_XINCREF(path);
664     Py_XSETREF(self->path, path);
665 
666     if (PyTuple_GET_SIZE(args) == 1) {
667         msg = PyTuple_GET_ITEM(args, 0);
668         Py_INCREF(msg);
669     }
670     Py_XSETREF(self->msg, msg);
671 
672     return 0;
673 }
674 
675 static int
ImportError_clear(PyImportErrorObject * self)676 ImportError_clear(PyImportErrorObject *self)
677 {
678     Py_CLEAR(self->msg);
679     Py_CLEAR(self->name);
680     Py_CLEAR(self->path);
681     return BaseException_clear((PyBaseExceptionObject *)self);
682 }
683 
684 static void
ImportError_dealloc(PyImportErrorObject * self)685 ImportError_dealloc(PyImportErrorObject *self)
686 {
687     _PyObject_GC_UNTRACK(self);
688     ImportError_clear(self);
689     Py_TYPE(self)->tp_free((PyObject *)self);
690 }
691 
692 static int
ImportError_traverse(PyImportErrorObject * self,visitproc visit,void * arg)693 ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg)
694 {
695     Py_VISIT(self->msg);
696     Py_VISIT(self->name);
697     Py_VISIT(self->path);
698     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
699 }
700 
701 static PyObject *
ImportError_str(PyImportErrorObject * self)702 ImportError_str(PyImportErrorObject *self)
703 {
704     if (self->msg && PyUnicode_CheckExact(self->msg)) {
705         Py_INCREF(self->msg);
706         return self->msg;
707     }
708     else {
709         return BaseException_str((PyBaseExceptionObject *)self);
710     }
711 }
712 
713 static PyObject *
ImportError_getstate(PyImportErrorObject * self)714 ImportError_getstate(PyImportErrorObject *self)
715 {
716     PyObject *dict = ((PyBaseExceptionObject *)self)->dict;
717     if (self->name || self->path) {
718         _Py_IDENTIFIER(name);
719         _Py_IDENTIFIER(path);
720         dict = dict ? PyDict_Copy(dict) : PyDict_New();
721         if (dict == NULL)
722             return NULL;
723         if (self->name && _PyDict_SetItemId(dict, &PyId_name, self->name) < 0) {
724             Py_DECREF(dict);
725             return NULL;
726         }
727         if (self->path && _PyDict_SetItemId(dict, &PyId_path, self->path) < 0) {
728             Py_DECREF(dict);
729             return NULL;
730         }
731         return dict;
732     }
733     else if (dict) {
734         Py_INCREF(dict);
735         return dict;
736     }
737     else {
738         Py_RETURN_NONE;
739     }
740 }
741 
742 /* Pickling support */
743 static PyObject *
ImportError_reduce(PyImportErrorObject * self,PyObject * Py_UNUSED (ignored))744 ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored))
745 {
746     PyObject *res;
747     PyObject *args;
748     PyObject *state = ImportError_getstate(self);
749     if (state == NULL)
750         return NULL;
751     args = ((PyBaseExceptionObject *)self)->args;
752     if (state == Py_None)
753         res = PyTuple_Pack(2, Py_TYPE(self), args);
754     else
755         res = PyTuple_Pack(3, Py_TYPE(self), args, state);
756     Py_DECREF(state);
757     return res;
758 }
759 
760 static PyMemberDef ImportError_members[] = {
761     {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
762         PyDoc_STR("exception message")},
763     {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0,
764         PyDoc_STR("module name")},
765     {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0,
766         PyDoc_STR("module path")},
767     {NULL}  /* Sentinel */
768 };
769 
770 static PyMethodDef ImportError_methods[] = {
771     {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
772     {NULL}
773 };
774 
775 ComplexExtendsException(PyExc_Exception, ImportError,
776                         ImportError, 0 /* new */,
777                         ImportError_methods, ImportError_members,
778                         0 /* getset */, ImportError_str,
779                         "Import can't find module, or can't find name in "
780                         "module.");
781 
782 /*
783  *    ModuleNotFoundError extends ImportError
784  */
785 
786 MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
787                          "Module not found.");
788 
789 /*
790  *    OSError extends Exception
791  */
792 
793 #ifdef MS_WINDOWS
794 #include "errmap.h"
795 #endif
796 
797 /* Where a function has a single filename, such as open() or some
798  * of the os module functions, PyErr_SetFromErrnoWithFilename() is
799  * called, giving a third argument which is the filename.  But, so
800  * that old code using in-place unpacking doesn't break, e.g.:
801  *
802  * except OSError, (errno, strerror):
803  *
804  * we hack args so that it only contains two items.  This also
805  * means we need our own __str__() which prints out the filename
806  * when it was supplied.
807  *
808  * (If a function has two filenames, such as rename(), symlink(),
809  * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
810  * which allows passing in a second filename.)
811  */
812 
813 /* This function doesn't cleanup on error, the caller should */
814 static int
oserror_parse_args(PyObject ** p_args,PyObject ** myerrno,PyObject ** strerror,PyObject ** filename,PyObject ** filename2,PyObject ** winerror)815 oserror_parse_args(PyObject **p_args,
816                    PyObject **myerrno, PyObject **strerror,
817                    PyObject **filename, PyObject **filename2
818 #ifdef MS_WINDOWS
819                    , PyObject **winerror
820 #endif
821                   )
822 {
823     Py_ssize_t nargs;
824     PyObject *args = *p_args;
825 #ifndef MS_WINDOWS
826     /*
827      * ignored on non-Windows platforms,
828      * but parsed so OSError has a consistent signature
829      */
830     PyObject *_winerror = NULL;
831     PyObject **winerror = &_winerror;
832 #endif /* MS_WINDOWS */
833 
834     nargs = PyTuple_GET_SIZE(args);
835 
836     if (nargs >= 2 && nargs <= 5) {
837         if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
838                                myerrno, strerror,
839                                filename, winerror, filename2))
840             return -1;
841 #ifdef MS_WINDOWS
842         if (*winerror && PyLong_Check(*winerror)) {
843             long errcode, winerrcode;
844             PyObject *newargs;
845             Py_ssize_t i;
846 
847             winerrcode = PyLong_AsLong(*winerror);
848             if (winerrcode == -1 && PyErr_Occurred())
849                 return -1;
850             /* Set errno to the corresponding POSIX errno (overriding
851                first argument).  Windows Socket error codes (>= 10000)
852                have the same value as their POSIX counterparts.
853             */
854             if (winerrcode < 10000)
855                 errcode = winerror_to_errno(winerrcode);
856             else
857                 errcode = winerrcode;
858             *myerrno = PyLong_FromLong(errcode);
859             if (!*myerrno)
860                 return -1;
861             newargs = PyTuple_New(nargs);
862             if (!newargs)
863                 return -1;
864             PyTuple_SET_ITEM(newargs, 0, *myerrno);
865             for (i = 1; i < nargs; i++) {
866                 PyObject *val = PyTuple_GET_ITEM(args, i);
867                 Py_INCREF(val);
868                 PyTuple_SET_ITEM(newargs, i, val);
869             }
870             Py_DECREF(args);
871             args = *p_args = newargs;
872         }
873 #endif /* MS_WINDOWS */
874     }
875 
876     return 0;
877 }
878 
879 static int
oserror_init(PyOSErrorObject * self,PyObject ** p_args,PyObject * myerrno,PyObject * strerror,PyObject * filename,PyObject * filename2,PyObject * winerror)880 oserror_init(PyOSErrorObject *self, PyObject **p_args,
881              PyObject *myerrno, PyObject *strerror,
882              PyObject *filename, PyObject *filename2
883 #ifdef MS_WINDOWS
884              , PyObject *winerror
885 #endif
886              )
887 {
888     PyObject *args = *p_args;
889     Py_ssize_t nargs = PyTuple_GET_SIZE(args);
890 
891     /* self->filename will remain Py_None otherwise */
892     if (filename && filename != Py_None) {
893         if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
894             PyNumber_Check(filename)) {
895             /* BlockingIOError's 3rd argument can be the number of
896              * characters written.
897              */
898             self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
899             if (self->written == -1 && PyErr_Occurred())
900                 return -1;
901         }
902         else {
903             Py_INCREF(filename);
904             self->filename = filename;
905 
906             if (filename2 && filename2 != Py_None) {
907                 Py_INCREF(filename2);
908                 self->filename2 = filename2;
909             }
910 
911             if (nargs >= 2 && nargs <= 5) {
912                 /* filename, filename2, and winerror are removed from the args tuple
913                    (for compatibility purposes, see test_exceptions.py) */
914                 PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
915                 if (!subslice)
916                     return -1;
917 
918                 Py_DECREF(args);  /* replacing args */
919                 *p_args = args = subslice;
920             }
921         }
922     }
923     Py_XINCREF(myerrno);
924     self->myerrno = myerrno;
925 
926     Py_XINCREF(strerror);
927     self->strerror = strerror;
928 
929 #ifdef MS_WINDOWS
930     Py_XINCREF(winerror);
931     self->winerror = winerror;
932 #endif
933 
934     /* Steals the reference to args */
935     Py_XSETREF(self->args, args);
936     *p_args = args = NULL;
937 
938     return 0;
939 }
940 
941 static PyObject *
942 OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
943 static int
944 OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds);
945 
946 static int
oserror_use_init(PyTypeObject * type)947 oserror_use_init(PyTypeObject *type)
948 {
949     /* When __init__ is defined in an OSError subclass, we want any
950        extraneous argument to __new__ to be ignored.  The only reasonable
951        solution, given __new__ takes a variable number of arguments,
952        is to defer arg parsing and initialization to __init__.
953 
954        But when __new__ is overridden as well, it should call our __new__
955        with the right arguments.
956 
957        (see http://bugs.python.org/issue12555#msg148829 )
958     */
959     if (type->tp_init != (initproc) OSError_init &&
960         type->tp_new == (newfunc) OSError_new) {
961         assert((PyObject *) type != PyExc_OSError);
962         return 1;
963     }
964     return 0;
965 }
966 
967 static PyObject *
OSError_new(PyTypeObject * type,PyObject * args,PyObject * kwds)968 OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
969 {
970     PyOSErrorObject *self = NULL;
971     PyObject *myerrno = NULL, *strerror = NULL;
972     PyObject *filename = NULL, *filename2 = NULL;
973 #ifdef MS_WINDOWS
974     PyObject *winerror = NULL;
975 #endif
976 
977     Py_INCREF(args);
978 
979     if (!oserror_use_init(type)) {
980         if (!_PyArg_NoKeywords(type->tp_name, kwds))
981             goto error;
982 
983         if (oserror_parse_args(&args, &myerrno, &strerror,
984                                &filename, &filename2
985 #ifdef MS_WINDOWS
986                                , &winerror
987 #endif
988             ))
989             goto error;
990 
991         struct _Py_exc_state *state = get_exc_state();
992         if (myerrno && PyLong_Check(myerrno) &&
993             state->errnomap && (PyObject *) type == PyExc_OSError) {
994             PyObject *newtype;
995             newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
996             if (newtype) {
997                 assert(PyType_Check(newtype));
998                 type = (PyTypeObject *) newtype;
999             }
1000             else if (PyErr_Occurred())
1001                 goto error;
1002         }
1003     }
1004 
1005     self = (PyOSErrorObject *) type->tp_alloc(type, 0);
1006     if (!self)
1007         goto error;
1008 
1009     self->dict = NULL;
1010     self->traceback = self->cause = self->context = NULL;
1011     self->written = -1;
1012 
1013     if (!oserror_use_init(type)) {
1014         if (oserror_init(self, &args, myerrno, strerror, filename, filename2
1015 #ifdef MS_WINDOWS
1016                          , winerror
1017 #endif
1018             ))
1019             goto error;
1020     }
1021     else {
1022         self->args = PyTuple_New(0);
1023         if (self->args == NULL)
1024             goto error;
1025     }
1026 
1027     Py_XDECREF(args);
1028     return (PyObject *) self;
1029 
1030 error:
1031     Py_XDECREF(args);
1032     Py_XDECREF(self);
1033     return NULL;
1034 }
1035 
1036 static int
OSError_init(PyOSErrorObject * self,PyObject * args,PyObject * kwds)1037 OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds)
1038 {
1039     PyObject *myerrno = NULL, *strerror = NULL;
1040     PyObject *filename = NULL, *filename2 = NULL;
1041 #ifdef MS_WINDOWS
1042     PyObject *winerror = NULL;
1043 #endif
1044 
1045     if (!oserror_use_init(Py_TYPE(self)))
1046         /* Everything already done in OSError_new */
1047         return 0;
1048 
1049     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
1050         return -1;
1051 
1052     Py_INCREF(args);
1053     if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
1054 #ifdef MS_WINDOWS
1055                            , &winerror
1056 #endif
1057         ))
1058         goto error;
1059 
1060     if (oserror_init(self, &args, myerrno, strerror, filename, filename2
1061 #ifdef MS_WINDOWS
1062                      , winerror
1063 #endif
1064         ))
1065         goto error;
1066 
1067     return 0;
1068 
1069 error:
1070     Py_DECREF(args);
1071     return -1;
1072 }
1073 
1074 static int
OSError_clear(PyOSErrorObject * self)1075 OSError_clear(PyOSErrorObject *self)
1076 {
1077     Py_CLEAR(self->myerrno);
1078     Py_CLEAR(self->strerror);
1079     Py_CLEAR(self->filename);
1080     Py_CLEAR(self->filename2);
1081 #ifdef MS_WINDOWS
1082     Py_CLEAR(self->winerror);
1083 #endif
1084     return BaseException_clear((PyBaseExceptionObject *)self);
1085 }
1086 
1087 static void
OSError_dealloc(PyOSErrorObject * self)1088 OSError_dealloc(PyOSErrorObject *self)
1089 {
1090     _PyObject_GC_UNTRACK(self);
1091     OSError_clear(self);
1092     Py_TYPE(self)->tp_free((PyObject *)self);
1093 }
1094 
1095 static int
OSError_traverse(PyOSErrorObject * self,visitproc visit,void * arg)1096 OSError_traverse(PyOSErrorObject *self, visitproc visit,
1097         void *arg)
1098 {
1099     Py_VISIT(self->myerrno);
1100     Py_VISIT(self->strerror);
1101     Py_VISIT(self->filename);
1102     Py_VISIT(self->filename2);
1103 #ifdef MS_WINDOWS
1104     Py_VISIT(self->winerror);
1105 #endif
1106     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1107 }
1108 
1109 static PyObject *
OSError_str(PyOSErrorObject * self)1110 OSError_str(PyOSErrorObject *self)
1111 {
1112 #define OR_NONE(x) ((x)?(x):Py_None)
1113 #ifdef MS_WINDOWS
1114     /* If available, winerror has the priority over myerrno */
1115     if (self->winerror && self->filename) {
1116         if (self->filename2) {
1117             return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
1118                                         OR_NONE(self->winerror),
1119                                         OR_NONE(self->strerror),
1120                                         self->filename,
1121                                         self->filename2);
1122         } else {
1123             return PyUnicode_FromFormat("[WinError %S] %S: %R",
1124                                         OR_NONE(self->winerror),
1125                                         OR_NONE(self->strerror),
1126                                         self->filename);
1127         }
1128     }
1129     if (self->winerror && self->strerror)
1130         return PyUnicode_FromFormat("[WinError %S] %S",
1131                                     self->winerror ? self->winerror: Py_None,
1132                                     self->strerror ? self->strerror: Py_None);
1133 #endif
1134     if (self->filename) {
1135         if (self->filename2) {
1136             return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
1137                                         OR_NONE(self->myerrno),
1138                                         OR_NONE(self->strerror),
1139                                         self->filename,
1140                                         self->filename2);
1141         } else {
1142             return PyUnicode_FromFormat("[Errno %S] %S: %R",
1143                                         OR_NONE(self->myerrno),
1144                                         OR_NONE(self->strerror),
1145                                         self->filename);
1146         }
1147     }
1148     if (self->myerrno && self->strerror)
1149         return PyUnicode_FromFormat("[Errno %S] %S",
1150                                     self->myerrno, self->strerror);
1151     return BaseException_str((PyBaseExceptionObject *)self);
1152 }
1153 
1154 static PyObject *
OSError_reduce(PyOSErrorObject * self,PyObject * Py_UNUSED (ignored))1155 OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored))
1156 {
1157     PyObject *args = self->args;
1158     PyObject *res = NULL, *tmp;
1159 
1160     /* self->args is only the first two real arguments if there was a
1161      * file name given to OSError. */
1162     if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
1163         Py_ssize_t size = self->filename2 ? 5 : 3;
1164         args = PyTuple_New(size);
1165         if (!args)
1166             return NULL;
1167 
1168         tmp = PyTuple_GET_ITEM(self->args, 0);
1169         Py_INCREF(tmp);
1170         PyTuple_SET_ITEM(args, 0, tmp);
1171 
1172         tmp = PyTuple_GET_ITEM(self->args, 1);
1173         Py_INCREF(tmp);
1174         PyTuple_SET_ITEM(args, 1, tmp);
1175 
1176         Py_INCREF(self->filename);
1177         PyTuple_SET_ITEM(args, 2, self->filename);
1178 
1179         if (self->filename2) {
1180             /*
1181              * This tuple is essentially used as OSError(*args).
1182              * So, to recreate filename2, we need to pass in
1183              * winerror as well.
1184              */
1185             Py_INCREF(Py_None);
1186             PyTuple_SET_ITEM(args, 3, Py_None);
1187 
1188             /* filename2 */
1189             Py_INCREF(self->filename2);
1190             PyTuple_SET_ITEM(args, 4, self->filename2);
1191         }
1192     } else
1193         Py_INCREF(args);
1194 
1195     if (self->dict)
1196         res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
1197     else
1198         res = PyTuple_Pack(2, Py_TYPE(self), args);
1199     Py_DECREF(args);
1200     return res;
1201 }
1202 
1203 static PyObject *
OSError_written_get(PyOSErrorObject * self,void * context)1204 OSError_written_get(PyOSErrorObject *self, void *context)
1205 {
1206     if (self->written == -1) {
1207         PyErr_SetString(PyExc_AttributeError, "characters_written");
1208         return NULL;
1209     }
1210     return PyLong_FromSsize_t(self->written);
1211 }
1212 
1213 static int
OSError_written_set(PyOSErrorObject * self,PyObject * arg,void * context)1214 OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
1215 {
1216     if (arg == NULL) {
1217         if (self->written == -1) {
1218             PyErr_SetString(PyExc_AttributeError, "characters_written");
1219             return -1;
1220         }
1221         self->written = -1;
1222         return 0;
1223     }
1224     Py_ssize_t n;
1225     n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1226     if (n == -1 && PyErr_Occurred())
1227         return -1;
1228     self->written = n;
1229     return 0;
1230 }
1231 
1232 static PyMemberDef OSError_members[] = {
1233     {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
1234         PyDoc_STR("POSIX exception code")},
1235     {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
1236         PyDoc_STR("exception strerror")},
1237     {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
1238         PyDoc_STR("exception filename")},
1239     {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
1240         PyDoc_STR("second exception filename")},
1241 #ifdef MS_WINDOWS
1242     {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
1243         PyDoc_STR("Win32 exception code")},
1244 #endif
1245     {NULL}  /* Sentinel */
1246 };
1247 
1248 static PyMethodDef OSError_methods[] = {
1249     {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
1250     {NULL}
1251 };
1252 
1253 static PyGetSetDef OSError_getset[] = {
1254     {"characters_written", (getter) OSError_written_get,
1255                            (setter) OSError_written_set, NULL},
1256     {NULL}
1257 };
1258 
1259 
1260 ComplexExtendsException(PyExc_Exception, OSError,
1261                         OSError, OSError_new,
1262                         OSError_methods, OSError_members, OSError_getset,
1263                         OSError_str,
1264                         "Base class for I/O related errors.");
1265 
1266 
1267 /*
1268  *    Various OSError subclasses
1269  */
1270 MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
1271                          "I/O operation would block.");
1272 MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
1273                          "Connection error.");
1274 MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
1275                          "Child process error.");
1276 MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
1277                          "Broken pipe.");
1278 MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
1279                          "Connection aborted.");
1280 MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
1281                          "Connection refused.");
1282 MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
1283                          "Connection reset.");
1284 MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
1285                          "File already exists.");
1286 MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
1287                          "File not found.");
1288 MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
1289                          "Operation doesn't work on directories.");
1290 MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
1291                          "Operation only works on directories.");
1292 MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
1293                          "Interrupted by signal.");
1294 MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
1295                          "Not enough permissions.");
1296 MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
1297                          "Process not found.");
1298 MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
1299                          "Timeout expired.");
1300 
1301 /*
1302  *    EOFError extends Exception
1303  */
1304 SimpleExtendsException(PyExc_Exception, EOFError,
1305                        "Read beyond end of file.");
1306 
1307 
1308 /*
1309  *    RuntimeError extends Exception
1310  */
1311 SimpleExtendsException(PyExc_Exception, RuntimeError,
1312                        "Unspecified run-time error.");
1313 
1314 /*
1315  *    RecursionError extends RuntimeError
1316  */
1317 SimpleExtendsException(PyExc_RuntimeError, RecursionError,
1318                        "Recursion limit exceeded.");
1319 
1320 /*
1321  *    NotImplementedError extends RuntimeError
1322  */
1323 SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
1324                        "Method or function hasn't been implemented yet.");
1325 
1326 /*
1327  *    NameError extends Exception
1328  */
1329 
1330 static int
NameError_init(PyNameErrorObject * self,PyObject * args,PyObject * kwds)1331 NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds)
1332 {
1333     static char *kwlist[] = {"name", NULL};
1334     PyObject *name = NULL;
1335 
1336     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
1337         return -1;
1338     }
1339 
1340     PyObject *empty_tuple = PyTuple_New(0);
1341     if (!empty_tuple) {
1342         return -1;
1343     }
1344     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
1345                                      &name)) {
1346         Py_DECREF(empty_tuple);
1347         return -1;
1348     }
1349     Py_DECREF(empty_tuple);
1350 
1351     Py_XINCREF(name);
1352     Py_XSETREF(self->name, name);
1353 
1354     return 0;
1355 }
1356 
1357 static int
NameError_clear(PyNameErrorObject * self)1358 NameError_clear(PyNameErrorObject *self)
1359 {
1360     Py_CLEAR(self->name);
1361     return BaseException_clear((PyBaseExceptionObject *)self);
1362 }
1363 
1364 static void
NameError_dealloc(PyNameErrorObject * self)1365 NameError_dealloc(PyNameErrorObject *self)
1366 {
1367     _PyObject_GC_UNTRACK(self);
1368     NameError_clear(self);
1369     Py_TYPE(self)->tp_free((PyObject *)self);
1370 }
1371 
1372 static int
NameError_traverse(PyNameErrorObject * self,visitproc visit,void * arg)1373 NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg)
1374 {
1375     Py_VISIT(self->name);
1376     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1377 }
1378 
1379 static PyMemberDef NameError_members[] = {
1380         {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
1381         {NULL}  /* Sentinel */
1382 };
1383 
1384 static PyMethodDef NameError_methods[] = {
1385         {NULL}  /* Sentinel */
1386 };
1387 
1388 ComplexExtendsException(PyExc_Exception, NameError,
1389                         NameError, 0,
1390                         NameError_methods, NameError_members,
1391                         0, BaseException_str, "Name not found globally.");
1392 
1393 /*
1394  *    UnboundLocalError extends NameError
1395  */
1396 
1397 MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
1398                        "Local name referenced but not bound to a value.");
1399 
1400 /*
1401  *    AttributeError extends Exception
1402  */
1403 
1404 static int
AttributeError_init(PyAttributeErrorObject * self,PyObject * args,PyObject * kwds)1405 AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds)
1406 {
1407     static char *kwlist[] = {"name", "obj", NULL};
1408     PyObject *name = NULL;
1409     PyObject *obj = NULL;
1410 
1411     if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
1412         return -1;
1413     }
1414 
1415     PyObject *empty_tuple = PyTuple_New(0);
1416     if (!empty_tuple) {
1417         return -1;
1418     }
1419     if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
1420                                      &name, &obj)) {
1421         Py_DECREF(empty_tuple);
1422         return -1;
1423     }
1424     Py_DECREF(empty_tuple);
1425 
1426     Py_XINCREF(name);
1427     Py_XSETREF(self->name, name);
1428 
1429     Py_XINCREF(obj);
1430     Py_XSETREF(self->obj, obj);
1431 
1432     return 0;
1433 }
1434 
1435 static int
AttributeError_clear(PyAttributeErrorObject * self)1436 AttributeError_clear(PyAttributeErrorObject *self)
1437 {
1438     Py_CLEAR(self->obj);
1439     Py_CLEAR(self->name);
1440     return BaseException_clear((PyBaseExceptionObject *)self);
1441 }
1442 
1443 static void
AttributeError_dealloc(PyAttributeErrorObject * self)1444 AttributeError_dealloc(PyAttributeErrorObject *self)
1445 {
1446     _PyObject_GC_UNTRACK(self);
1447     AttributeError_clear(self);
1448     Py_TYPE(self)->tp_free((PyObject *)self);
1449 }
1450 
1451 static int
AttributeError_traverse(PyAttributeErrorObject * self,visitproc visit,void * arg)1452 AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg)
1453 {
1454     Py_VISIT(self->obj);
1455     Py_VISIT(self->name);
1456     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1457 }
1458 
1459 static PyMemberDef AttributeError_members[] = {
1460     {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
1461     {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
1462     {NULL}  /* Sentinel */
1463 };
1464 
1465 static PyMethodDef AttributeError_methods[] = {
1466     {NULL}  /* Sentinel */
1467 };
1468 
1469 ComplexExtendsException(PyExc_Exception, AttributeError,
1470                         AttributeError, 0,
1471                         AttributeError_methods, AttributeError_members,
1472                         0, BaseException_str, "Attribute not found.");
1473 
1474 /*
1475  *    SyntaxError extends Exception
1476  */
1477 
1478 static int
SyntaxError_init(PySyntaxErrorObject * self,PyObject * args,PyObject * kwds)1479 SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
1480 {
1481     PyObject *info = NULL;
1482     Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
1483 
1484     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1485         return -1;
1486 
1487     if (lenargs >= 1) {
1488         Py_INCREF(PyTuple_GET_ITEM(args, 0));
1489         Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
1490     }
1491     if (lenargs == 2) {
1492         info = PyTuple_GET_ITEM(args, 1);
1493         info = PySequence_Tuple(info);
1494         if (!info) {
1495             return -1;
1496         }
1497 
1498         self->end_lineno = NULL;
1499         self->end_offset = NULL;
1500         if (!PyArg_ParseTuple(info, "OOOO|OO",
1501                               &self->filename, &self->lineno,
1502                               &self->offset, &self->text,
1503                               &self->end_lineno, &self->end_offset)) {
1504             Py_DECREF(info);
1505             return -1;
1506         }
1507 
1508         Py_INCREF(self->filename);
1509         Py_INCREF(self->lineno);
1510         Py_INCREF(self->offset);
1511         Py_INCREF(self->text);
1512         Py_XINCREF(self->end_lineno);
1513         Py_XINCREF(self->end_offset);
1514         Py_DECREF(info);
1515 
1516         if (self->end_lineno != NULL && self->end_offset == NULL) {
1517             PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
1518             return -1;
1519         }
1520     }
1521     return 0;
1522 }
1523 
1524 static int
SyntaxError_clear(PySyntaxErrorObject * self)1525 SyntaxError_clear(PySyntaxErrorObject *self)
1526 {
1527     Py_CLEAR(self->msg);
1528     Py_CLEAR(self->filename);
1529     Py_CLEAR(self->lineno);
1530     Py_CLEAR(self->offset);
1531     Py_CLEAR(self->end_lineno);
1532     Py_CLEAR(self->end_offset);
1533     Py_CLEAR(self->text);
1534     Py_CLEAR(self->print_file_and_line);
1535     return BaseException_clear((PyBaseExceptionObject *)self);
1536 }
1537 
1538 static void
SyntaxError_dealloc(PySyntaxErrorObject * self)1539 SyntaxError_dealloc(PySyntaxErrorObject *self)
1540 {
1541     _PyObject_GC_UNTRACK(self);
1542     SyntaxError_clear(self);
1543     Py_TYPE(self)->tp_free((PyObject *)self);
1544 }
1545 
1546 static int
SyntaxError_traverse(PySyntaxErrorObject * self,visitproc visit,void * arg)1547 SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1548 {
1549     Py_VISIT(self->msg);
1550     Py_VISIT(self->filename);
1551     Py_VISIT(self->lineno);
1552     Py_VISIT(self->offset);
1553     Py_VISIT(self->end_lineno);
1554     Py_VISIT(self->end_offset);
1555     Py_VISIT(self->text);
1556     Py_VISIT(self->print_file_and_line);
1557     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1558 }
1559 
1560 /* This is called "my_basename" instead of just "basename" to avoid name
1561    conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1562    defined, and Python does define that. */
1563 static PyObject*
my_basename(PyObject * name)1564 my_basename(PyObject *name)
1565 {
1566     Py_ssize_t i, size, offset;
1567     int kind;
1568     const void *data;
1569 
1570     if (PyUnicode_READY(name))
1571         return NULL;
1572     kind = PyUnicode_KIND(name);
1573     data = PyUnicode_DATA(name);
1574     size = PyUnicode_GET_LENGTH(name);
1575     offset = 0;
1576     for(i=0; i < size; i++) {
1577         if (PyUnicode_READ(kind, data, i) == SEP) {
1578             offset = i + 1;
1579         }
1580     }
1581     if (offset != 0) {
1582         return PyUnicode_Substring(name, offset, size);
1583     }
1584     else {
1585         Py_INCREF(name);
1586         return name;
1587     }
1588 }
1589 
1590 
1591 static PyObject *
SyntaxError_str(PySyntaxErrorObject * self)1592 SyntaxError_str(PySyntaxErrorObject *self)
1593 {
1594     int have_lineno = 0;
1595     PyObject *filename;
1596     PyObject *result;
1597     /* Below, we always ignore overflow errors, just printing -1.
1598        Still, we cannot allow an OverflowError to be raised, so
1599        we need to call PyLong_AsLongAndOverflow. */
1600     int overflow;
1601 
1602     /* XXX -- do all the additional formatting with filename and
1603        lineno here */
1604 
1605     if (self->filename && PyUnicode_Check(self->filename)) {
1606         filename = my_basename(self->filename);
1607         if (filename == NULL)
1608             return NULL;
1609     } else {
1610         filename = NULL;
1611     }
1612     have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
1613 
1614     if (!filename && !have_lineno)
1615         return PyObject_Str(self->msg ? self->msg : Py_None);
1616 
1617     if (filename && have_lineno)
1618         result = PyUnicode_FromFormat("%S (%U, line %ld)",
1619                    self->msg ? self->msg : Py_None,
1620                    filename,
1621                    PyLong_AsLongAndOverflow(self->lineno, &overflow));
1622     else if (filename)
1623         result = PyUnicode_FromFormat("%S (%U)",
1624                    self->msg ? self->msg : Py_None,
1625                    filename);
1626     else /* only have_lineno */
1627         result = PyUnicode_FromFormat("%S (line %ld)",
1628                    self->msg ? self->msg : Py_None,
1629                    PyLong_AsLongAndOverflow(self->lineno, &overflow));
1630     Py_XDECREF(filename);
1631     return result;
1632 }
1633 
1634 static PyMemberDef SyntaxError_members[] = {
1635     {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1636         PyDoc_STR("exception msg")},
1637     {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1638         PyDoc_STR("exception filename")},
1639     {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1640         PyDoc_STR("exception lineno")},
1641     {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1642         PyDoc_STR("exception offset")},
1643     {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1644         PyDoc_STR("exception text")},
1645     {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
1646                    PyDoc_STR("exception end lineno")},
1647     {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
1648                    PyDoc_STR("exception end offset")},
1649     {"print_file_and_line", T_OBJECT,
1650         offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1651         PyDoc_STR("exception print_file_and_line")},
1652     {NULL}  /* Sentinel */
1653 };
1654 
1655 ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
1656                         0, 0, SyntaxError_members, 0,
1657                         SyntaxError_str, "Invalid syntax.");
1658 
1659 
1660 /*
1661  *    IndentationError extends SyntaxError
1662  */
1663 MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1664                          "Improper indentation.");
1665 
1666 
1667 /*
1668  *    TabError extends IndentationError
1669  */
1670 MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1671                          "Improper mixture of spaces and tabs.");
1672 
1673 
1674 /*
1675  *    LookupError extends Exception
1676  */
1677 SimpleExtendsException(PyExc_Exception, LookupError,
1678                        "Base class for lookup errors.");
1679 
1680 
1681 /*
1682  *    IndexError extends LookupError
1683  */
1684 SimpleExtendsException(PyExc_LookupError, IndexError,
1685                        "Sequence index out of range.");
1686 
1687 
1688 /*
1689  *    KeyError extends LookupError
1690  */
1691 static PyObject *
KeyError_str(PyBaseExceptionObject * self)1692 KeyError_str(PyBaseExceptionObject *self)
1693 {
1694     /* If args is a tuple of exactly one item, apply repr to args[0].
1695        This is done so that e.g. the exception raised by {}[''] prints
1696          KeyError: ''
1697        rather than the confusing
1698          KeyError
1699        alone.  The downside is that if KeyError is raised with an explanatory
1700        string, that string will be displayed in quotes.  Too bad.
1701        If args is anything else, use the default BaseException__str__().
1702     */
1703     if (PyTuple_GET_SIZE(self->args) == 1) {
1704         return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
1705     }
1706     return BaseException_str(self);
1707 }
1708 
1709 ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1710                         0, 0, 0, 0, KeyError_str, "Mapping key not found.");
1711 
1712 
1713 /*
1714  *    ValueError extends Exception
1715  */
1716 SimpleExtendsException(PyExc_Exception, ValueError,
1717                        "Inappropriate argument value (of correct type).");
1718 
1719 /*
1720  *    UnicodeError extends ValueError
1721  */
1722 
1723 SimpleExtendsException(PyExc_ValueError, UnicodeError,
1724                        "Unicode related error.");
1725 
1726 static PyObject *
get_string(PyObject * attr,const char * name)1727 get_string(PyObject *attr, const char *name)
1728 {
1729     if (!attr) {
1730         PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1731         return NULL;
1732     }
1733 
1734     if (!PyBytes_Check(attr)) {
1735         PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1736         return NULL;
1737     }
1738     Py_INCREF(attr);
1739     return attr;
1740 }
1741 
1742 static PyObject *
get_unicode(PyObject * attr,const char * name)1743 get_unicode(PyObject *attr, const char *name)
1744 {
1745     if (!attr) {
1746         PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1747         return NULL;
1748     }
1749 
1750     if (!PyUnicode_Check(attr)) {
1751         PyErr_Format(PyExc_TypeError,
1752                      "%.200s attribute must be unicode", name);
1753         return NULL;
1754     }
1755     Py_INCREF(attr);
1756     return attr;
1757 }
1758 
1759 static int
set_unicodefromstring(PyObject ** attr,const char * value)1760 set_unicodefromstring(PyObject **attr, const char *value)
1761 {
1762     PyObject *obj = PyUnicode_FromString(value);
1763     if (!obj)
1764         return -1;
1765     Py_XSETREF(*attr, obj);
1766     return 0;
1767 }
1768 
1769 PyObject *
PyUnicodeEncodeError_GetEncoding(PyObject * exc)1770 PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1771 {
1772     return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1773 }
1774 
1775 PyObject *
PyUnicodeDecodeError_GetEncoding(PyObject * exc)1776 PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1777 {
1778     return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1779 }
1780 
1781 PyObject *
PyUnicodeEncodeError_GetObject(PyObject * exc)1782 PyUnicodeEncodeError_GetObject(PyObject *exc)
1783 {
1784     return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1785 }
1786 
1787 PyObject *
PyUnicodeDecodeError_GetObject(PyObject * exc)1788 PyUnicodeDecodeError_GetObject(PyObject *exc)
1789 {
1790     return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1791 }
1792 
1793 PyObject *
PyUnicodeTranslateError_GetObject(PyObject * exc)1794 PyUnicodeTranslateError_GetObject(PyObject *exc)
1795 {
1796     return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1797 }
1798 
1799 int
PyUnicodeEncodeError_GetStart(PyObject * exc,Py_ssize_t * start)1800 PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1801 {
1802     Py_ssize_t size;
1803     PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1804                                 "object");
1805     if (!obj)
1806         return -1;
1807     *start = ((PyUnicodeErrorObject *)exc)->start;
1808     size = PyUnicode_GET_LENGTH(obj);
1809     if (*start<0)
1810         *start = 0; /*XXX check for values <0*/
1811     if (*start>=size)
1812         *start = size-1;
1813     Py_DECREF(obj);
1814     return 0;
1815 }
1816 
1817 
1818 int
PyUnicodeDecodeError_GetStart(PyObject * exc,Py_ssize_t * start)1819 PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1820 {
1821     Py_ssize_t size;
1822     PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1823     if (!obj)
1824         return -1;
1825     size = PyBytes_GET_SIZE(obj);
1826     *start = ((PyUnicodeErrorObject *)exc)->start;
1827     if (*start<0)
1828         *start = 0;
1829     if (*start>=size)
1830         *start = size-1;
1831     Py_DECREF(obj);
1832     return 0;
1833 }
1834 
1835 
1836 int
PyUnicodeTranslateError_GetStart(PyObject * exc,Py_ssize_t * start)1837 PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1838 {
1839     return PyUnicodeEncodeError_GetStart(exc, start);
1840 }
1841 
1842 
1843 int
PyUnicodeEncodeError_SetStart(PyObject * exc,Py_ssize_t start)1844 PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1845 {
1846     ((PyUnicodeErrorObject *)exc)->start = start;
1847     return 0;
1848 }
1849 
1850 
1851 int
PyUnicodeDecodeError_SetStart(PyObject * exc,Py_ssize_t start)1852 PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1853 {
1854     ((PyUnicodeErrorObject *)exc)->start = start;
1855     return 0;
1856 }
1857 
1858 
1859 int
PyUnicodeTranslateError_SetStart(PyObject * exc,Py_ssize_t start)1860 PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1861 {
1862     ((PyUnicodeErrorObject *)exc)->start = start;
1863     return 0;
1864 }
1865 
1866 
1867 int
PyUnicodeEncodeError_GetEnd(PyObject * exc,Py_ssize_t * end)1868 PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1869 {
1870     Py_ssize_t size;
1871     PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1872                                 "object");
1873     if (!obj)
1874         return -1;
1875     *end = ((PyUnicodeErrorObject *)exc)->end;
1876     size = PyUnicode_GET_LENGTH(obj);
1877     if (*end<1)
1878         *end = 1;
1879     if (*end>size)
1880         *end = size;
1881     Py_DECREF(obj);
1882     return 0;
1883 }
1884 
1885 
1886 int
PyUnicodeDecodeError_GetEnd(PyObject * exc,Py_ssize_t * end)1887 PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1888 {
1889     Py_ssize_t size;
1890     PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1891     if (!obj)
1892         return -1;
1893     size = PyBytes_GET_SIZE(obj);
1894     *end = ((PyUnicodeErrorObject *)exc)->end;
1895     if (*end<1)
1896         *end = 1;
1897     if (*end>size)
1898         *end = size;
1899     Py_DECREF(obj);
1900     return 0;
1901 }
1902 
1903 
1904 int
PyUnicodeTranslateError_GetEnd(PyObject * exc,Py_ssize_t * end)1905 PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
1906 {
1907     return PyUnicodeEncodeError_GetEnd(exc, end);
1908 }
1909 
1910 
1911 int
PyUnicodeEncodeError_SetEnd(PyObject * exc,Py_ssize_t end)1912 PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1913 {
1914     ((PyUnicodeErrorObject *)exc)->end = end;
1915     return 0;
1916 }
1917 
1918 
1919 int
PyUnicodeDecodeError_SetEnd(PyObject * exc,Py_ssize_t end)1920 PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1921 {
1922     ((PyUnicodeErrorObject *)exc)->end = end;
1923     return 0;
1924 }
1925 
1926 
1927 int
PyUnicodeTranslateError_SetEnd(PyObject * exc,Py_ssize_t end)1928 PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1929 {
1930     ((PyUnicodeErrorObject *)exc)->end = end;
1931     return 0;
1932 }
1933 
1934 PyObject *
PyUnicodeEncodeError_GetReason(PyObject * exc)1935 PyUnicodeEncodeError_GetReason(PyObject *exc)
1936 {
1937     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
1938 }
1939 
1940 
1941 PyObject *
PyUnicodeDecodeError_GetReason(PyObject * exc)1942 PyUnicodeDecodeError_GetReason(PyObject *exc)
1943 {
1944     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
1945 }
1946 
1947 
1948 PyObject *
PyUnicodeTranslateError_GetReason(PyObject * exc)1949 PyUnicodeTranslateError_GetReason(PyObject *exc)
1950 {
1951     return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
1952 }
1953 
1954 
1955 int
PyUnicodeEncodeError_SetReason(PyObject * exc,const char * reason)1956 PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1957 {
1958     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1959                                  reason);
1960 }
1961 
1962 
1963 int
PyUnicodeDecodeError_SetReason(PyObject * exc,const char * reason)1964 PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1965 {
1966     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1967                                  reason);
1968 }
1969 
1970 
1971 int
PyUnicodeTranslateError_SetReason(PyObject * exc,const char * reason)1972 PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1973 {
1974     return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1975                                  reason);
1976 }
1977 
1978 
1979 static int
UnicodeError_clear(PyUnicodeErrorObject * self)1980 UnicodeError_clear(PyUnicodeErrorObject *self)
1981 {
1982     Py_CLEAR(self->encoding);
1983     Py_CLEAR(self->object);
1984     Py_CLEAR(self->reason);
1985     return BaseException_clear((PyBaseExceptionObject *)self);
1986 }
1987 
1988 static void
UnicodeError_dealloc(PyUnicodeErrorObject * self)1989 UnicodeError_dealloc(PyUnicodeErrorObject *self)
1990 {
1991     _PyObject_GC_UNTRACK(self);
1992     UnicodeError_clear(self);
1993     Py_TYPE(self)->tp_free((PyObject *)self);
1994 }
1995 
1996 static int
UnicodeError_traverse(PyUnicodeErrorObject * self,visitproc visit,void * arg)1997 UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1998 {
1999     Py_VISIT(self->encoding);
2000     Py_VISIT(self->object);
2001     Py_VISIT(self->reason);
2002     return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2003 }
2004 
2005 static PyMemberDef UnicodeError_members[] = {
2006     {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
2007         PyDoc_STR("exception encoding")},
2008     {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
2009         PyDoc_STR("exception object")},
2010     {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
2011         PyDoc_STR("exception start")},
2012     {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
2013         PyDoc_STR("exception end")},
2014     {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
2015         PyDoc_STR("exception reason")},
2016     {NULL}  /* Sentinel */
2017 };
2018 
2019 
2020 /*
2021  *    UnicodeEncodeError extends UnicodeError
2022  */
2023 
2024 static int
UnicodeEncodeError_init(PyObject * self,PyObject * args,PyObject * kwds)2025 UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2026 {
2027     PyUnicodeErrorObject *err;
2028 
2029     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2030         return -1;
2031 
2032     err = (PyUnicodeErrorObject *)self;
2033 
2034     Py_CLEAR(err->encoding);
2035     Py_CLEAR(err->object);
2036     Py_CLEAR(err->reason);
2037 
2038     if (!PyArg_ParseTuple(args, "UUnnU",
2039                           &err->encoding, &err->object,
2040                           &err->start, &err->end, &err->reason)) {
2041         err->encoding = err->object = err->reason = NULL;
2042         return -1;
2043     }
2044 
2045     Py_INCREF(err->encoding);
2046     Py_INCREF(err->object);
2047     Py_INCREF(err->reason);
2048 
2049     return 0;
2050 }
2051 
2052 static PyObject *
UnicodeEncodeError_str(PyObject * self)2053 UnicodeEncodeError_str(PyObject *self)
2054 {
2055     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2056     PyObject *result = NULL;
2057     PyObject *reason_str = NULL;
2058     PyObject *encoding_str = NULL;
2059 
2060     if (!uself->object)
2061         /* Not properly initialized. */
2062         return PyUnicode_FromString("");
2063 
2064     /* Get reason and encoding as strings, which they might not be if
2065        they've been modified after we were constructed. */
2066     reason_str = PyObject_Str(uself->reason);
2067     if (reason_str == NULL)
2068         goto done;
2069     encoding_str = PyObject_Str(uself->encoding);
2070     if (encoding_str == NULL)
2071         goto done;
2072 
2073     if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2074         Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
2075         const char *fmt;
2076         if (badchar <= 0xff)
2077             fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
2078         else if (badchar <= 0xffff)
2079             fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
2080         else
2081             fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
2082         result = PyUnicode_FromFormat(
2083             fmt,
2084             encoding_str,
2085             (int)badchar,
2086             uself->start,
2087             reason_str);
2088     }
2089     else {
2090         result = PyUnicode_FromFormat(
2091             "'%U' codec can't encode characters in position %zd-%zd: %U",
2092             encoding_str,
2093             uself->start,
2094             uself->end-1,
2095             reason_str);
2096     }
2097 done:
2098     Py_XDECREF(reason_str);
2099     Py_XDECREF(encoding_str);
2100     return result;
2101 }
2102 
2103 static PyTypeObject _PyExc_UnicodeEncodeError = {
2104     PyVarObject_HEAD_INIT(NULL, 0)
2105     "UnicodeEncodeError",
2106     sizeof(PyUnicodeErrorObject), 0,
2107     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2108     (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
2109     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2110     PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
2111     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2112     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
2113     (initproc)UnicodeEncodeError_init, 0, BaseException_new,
2114 };
2115 PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
2116 
2117 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)2118 PyUnicodeEncodeError_Create(
2119     const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
2120     Py_ssize_t start, Py_ssize_t end, const char *reason)
2121 {
2122     return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
2123                                  encoding, object, length, start, end, reason);
2124 }
2125 
2126 
2127 /*
2128  *    UnicodeDecodeError extends UnicodeError
2129  */
2130 
2131 static int
UnicodeDecodeError_init(PyObject * self,PyObject * args,PyObject * kwds)2132 UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2133 {
2134     PyUnicodeErrorObject *ude;
2135 
2136     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2137         return -1;
2138 
2139     ude = (PyUnicodeErrorObject *)self;
2140 
2141     Py_CLEAR(ude->encoding);
2142     Py_CLEAR(ude->object);
2143     Py_CLEAR(ude->reason);
2144 
2145     if (!PyArg_ParseTuple(args, "UOnnU",
2146                           &ude->encoding, &ude->object,
2147                           &ude->start, &ude->end, &ude->reason)) {
2148              ude->encoding = ude->object = ude->reason = NULL;
2149              return -1;
2150     }
2151 
2152     Py_INCREF(ude->encoding);
2153     Py_INCREF(ude->object);
2154     Py_INCREF(ude->reason);
2155 
2156     if (!PyBytes_Check(ude->object)) {
2157         Py_buffer view;
2158         if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
2159             goto error;
2160         Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
2161         PyBuffer_Release(&view);
2162         if (!ude->object)
2163             goto error;
2164     }
2165     return 0;
2166 
2167 error:
2168     Py_CLEAR(ude->encoding);
2169     Py_CLEAR(ude->object);
2170     Py_CLEAR(ude->reason);
2171     return -1;
2172 }
2173 
2174 static PyObject *
UnicodeDecodeError_str(PyObject * self)2175 UnicodeDecodeError_str(PyObject *self)
2176 {
2177     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2178     PyObject *result = NULL;
2179     PyObject *reason_str = NULL;
2180     PyObject *encoding_str = NULL;
2181 
2182     if (!uself->object)
2183         /* Not properly initialized. */
2184         return PyUnicode_FromString("");
2185 
2186     /* Get reason and encoding as strings, which they might not be if
2187        they've been modified after we were constructed. */
2188     reason_str = PyObject_Str(uself->reason);
2189     if (reason_str == NULL)
2190         goto done;
2191     encoding_str = PyObject_Str(uself->encoding);
2192     if (encoding_str == NULL)
2193         goto done;
2194 
2195     if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) {
2196         int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
2197         result = PyUnicode_FromFormat(
2198             "'%U' codec can't decode byte 0x%02x in position %zd: %U",
2199             encoding_str,
2200             byte,
2201             uself->start,
2202             reason_str);
2203     }
2204     else {
2205         result = PyUnicode_FromFormat(
2206             "'%U' codec can't decode bytes in position %zd-%zd: %U",
2207             encoding_str,
2208             uself->start,
2209             uself->end-1,
2210             reason_str
2211             );
2212     }
2213 done:
2214     Py_XDECREF(reason_str);
2215     Py_XDECREF(encoding_str);
2216     return result;
2217 }
2218 
2219 static PyTypeObject _PyExc_UnicodeDecodeError = {
2220     PyVarObject_HEAD_INIT(NULL, 0)
2221     "UnicodeDecodeError",
2222     sizeof(PyUnicodeErrorObject), 0,
2223     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2224     (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
2225     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2226     PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
2227     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2228     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
2229     (initproc)UnicodeDecodeError_init, 0, BaseException_new,
2230 };
2231 PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
2232 
2233 PyObject *
PyUnicodeDecodeError_Create(const char * encoding,const char * object,Py_ssize_t length,Py_ssize_t start,Py_ssize_t end,const char * reason)2234 PyUnicodeDecodeError_Create(
2235     const char *encoding, const char *object, Py_ssize_t length,
2236     Py_ssize_t start, Py_ssize_t end, const char *reason)
2237 {
2238     return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
2239                                  encoding, object, length, start, end, reason);
2240 }
2241 
2242 
2243 /*
2244  *    UnicodeTranslateError extends UnicodeError
2245  */
2246 
2247 static int
UnicodeTranslateError_init(PyUnicodeErrorObject * self,PyObject * args,PyObject * kwds)2248 UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
2249                            PyObject *kwds)
2250 {
2251     if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2252         return -1;
2253 
2254     Py_CLEAR(self->object);
2255     Py_CLEAR(self->reason);
2256 
2257     if (!PyArg_ParseTuple(args, "UnnU",
2258                           &self->object,
2259                           &self->start, &self->end, &self->reason)) {
2260         self->object = self->reason = NULL;
2261         return -1;
2262     }
2263 
2264     Py_INCREF(self->object);
2265     Py_INCREF(self->reason);
2266 
2267     return 0;
2268 }
2269 
2270 
2271 static PyObject *
UnicodeTranslateError_str(PyObject * self)2272 UnicodeTranslateError_str(PyObject *self)
2273 {
2274     PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2275     PyObject *result = NULL;
2276     PyObject *reason_str = NULL;
2277 
2278     if (!uself->object)
2279         /* Not properly initialized. */
2280         return PyUnicode_FromString("");
2281 
2282     /* Get reason as a string, which it might not be if it's been
2283        modified after we were constructed. */
2284     reason_str = PyObject_Str(uself->reason);
2285     if (reason_str == NULL)
2286         goto done;
2287 
2288     if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2289         Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
2290         const char *fmt;
2291         if (badchar <= 0xff)
2292             fmt = "can't translate character '\\x%02x' in position %zd: %U";
2293         else if (badchar <= 0xffff)
2294             fmt = "can't translate character '\\u%04x' in position %zd: %U";
2295         else
2296             fmt = "can't translate character '\\U%08x' in position %zd: %U";
2297         result = PyUnicode_FromFormat(
2298             fmt,
2299             (int)badchar,
2300             uself->start,
2301             reason_str
2302         );
2303     } else {
2304         result = PyUnicode_FromFormat(
2305             "can't translate characters in position %zd-%zd: %U",
2306             uself->start,
2307             uself->end-1,
2308             reason_str
2309             );
2310     }
2311 done:
2312     Py_XDECREF(reason_str);
2313     return result;
2314 }
2315 
2316 static PyTypeObject _PyExc_UnicodeTranslateError = {
2317     PyVarObject_HEAD_INIT(NULL, 0)
2318     "UnicodeTranslateError",
2319     sizeof(PyUnicodeErrorObject), 0,
2320     (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2321     (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
2322     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2323     PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
2324     (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2325     0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
2326     (initproc)UnicodeTranslateError_init, 0, BaseException_new,
2327 };
2328 PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
2329 
2330 /* Deprecated. */
2331 PyObject *
PyUnicodeTranslateError_Create(const Py_UNICODE * object,Py_ssize_t length,Py_ssize_t start,Py_ssize_t end,const char * reason)2332 PyUnicodeTranslateError_Create(
2333     const Py_UNICODE *object, Py_ssize_t length,
2334     Py_ssize_t start, Py_ssize_t end, const char *reason)
2335 {
2336     return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
2337                                  object, length, start, end, reason);
2338 }
2339 
2340 PyObject *
_PyUnicodeTranslateError_Create(PyObject * object,Py_ssize_t start,Py_ssize_t end,const char * reason)2341 _PyUnicodeTranslateError_Create(
2342     PyObject *object,
2343     Py_ssize_t start, Py_ssize_t end, const char *reason)
2344 {
2345     return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
2346                                  object, start, end, reason);
2347 }
2348 
2349 /*
2350  *    AssertionError extends Exception
2351  */
2352 SimpleExtendsException(PyExc_Exception, AssertionError,
2353                        "Assertion failed.");
2354 
2355 
2356 /*
2357  *    ArithmeticError extends Exception
2358  */
2359 SimpleExtendsException(PyExc_Exception, ArithmeticError,
2360                        "Base class for arithmetic errors.");
2361 
2362 
2363 /*
2364  *    FloatingPointError extends ArithmeticError
2365  */
2366 SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
2367                        "Floating point operation failed.");
2368 
2369 
2370 /*
2371  *    OverflowError extends ArithmeticError
2372  */
2373 SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
2374                        "Result too large to be represented.");
2375 
2376 
2377 /*
2378  *    ZeroDivisionError extends ArithmeticError
2379  */
2380 SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
2381           "Second argument to a division or modulo operation was zero.");
2382 
2383 
2384 /*
2385  *    SystemError extends Exception
2386  */
2387 SimpleExtendsException(PyExc_Exception, SystemError,
2388     "Internal error in the Python interpreter.\n"
2389     "\n"
2390     "Please report this to the Python maintainer, along with the traceback,\n"
2391     "the Python version, and the hardware/OS platform and version.");
2392 
2393 
2394 /*
2395  *    ReferenceError extends Exception
2396  */
2397 SimpleExtendsException(PyExc_Exception, ReferenceError,
2398                        "Weak ref proxy used after referent went away.");
2399 
2400 
2401 /*
2402  *    MemoryError extends Exception
2403  */
2404 
2405 #define MEMERRORS_SAVE 16
2406 
2407 static PyObject *
MemoryError_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2408 MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2409 {
2410     PyBaseExceptionObject *self;
2411 
2412     /* If this is a subclass of MemoryError, don't use the freelist
2413      * and just return a fresh object */
2414     if (type != (PyTypeObject *) PyExc_MemoryError) {
2415         return BaseException_new(type, args, kwds);
2416     }
2417 
2418     struct _Py_exc_state *state = get_exc_state();
2419     if (state->memerrors_freelist == NULL) {
2420         return BaseException_new(type, args, kwds);
2421     }
2422 
2423     /* Fetch object from freelist and revive it */
2424     self = state->memerrors_freelist;
2425     self->args = PyTuple_New(0);
2426     /* This shouldn't happen since the empty tuple is persistent */
2427     if (self->args == NULL) {
2428         return NULL;
2429     }
2430 
2431     state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
2432     state->memerrors_numfree--;
2433     self->dict = NULL;
2434     _Py_NewReference((PyObject *)self);
2435     _PyObject_GC_TRACK(self);
2436     return (PyObject *)self;
2437 }
2438 
2439 static void
MemoryError_dealloc(PyBaseExceptionObject * self)2440 MemoryError_dealloc(PyBaseExceptionObject *self)
2441 {
2442     BaseException_clear(self);
2443 
2444     /* If this is a subclass of MemoryError, we don't need to
2445      * do anything in the free-list*/
2446     if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
2447         Py_TYPE(self)->tp_free((PyObject *)self);
2448         return;
2449     }
2450 
2451     _PyObject_GC_UNTRACK(self);
2452 
2453     struct _Py_exc_state *state = get_exc_state();
2454     if (state->memerrors_numfree >= MEMERRORS_SAVE) {
2455         Py_TYPE(self)->tp_free((PyObject *)self);
2456     }
2457     else {
2458         self->dict = (PyObject *) state->memerrors_freelist;
2459         state->memerrors_freelist = self;
2460         state->memerrors_numfree++;
2461     }
2462 }
2463 
2464 static int
preallocate_memerrors(void)2465 preallocate_memerrors(void)
2466 {
2467     /* We create enough MemoryErrors and then decref them, which will fill
2468        up the freelist. */
2469     int i;
2470     PyObject *errors[MEMERRORS_SAVE];
2471     for (i = 0; i < MEMERRORS_SAVE; i++) {
2472         errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
2473                                     NULL, NULL);
2474         if (!errors[i]) {
2475             return -1;
2476         }
2477     }
2478     for (i = 0; i < MEMERRORS_SAVE; i++) {
2479         Py_DECREF(errors[i]);
2480     }
2481     return 0;
2482 }
2483 
2484 static void
free_preallocated_memerrors(struct _Py_exc_state * state)2485 free_preallocated_memerrors(struct _Py_exc_state *state)
2486 {
2487     while (state->memerrors_freelist != NULL) {
2488         PyObject *self = (PyObject *) state->memerrors_freelist;
2489         state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
2490         Py_TYPE(self)->tp_free((PyObject *)self);
2491     }
2492 }
2493 
2494 
2495 static PyTypeObject _PyExc_MemoryError = {
2496     PyVarObject_HEAD_INIT(NULL, 0)
2497     "MemoryError",
2498     sizeof(PyBaseExceptionObject),
2499     0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
2500     0, 0, 0, 0, 0, 0, 0,
2501     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2502     PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
2503     (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
2504     0, 0, 0, offsetof(PyBaseExceptionObject, dict),
2505     (initproc)BaseException_init, 0, MemoryError_new
2506 };
2507 PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
2508 
2509 
2510 /*
2511  *    BufferError extends Exception
2512  */
2513 SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
2514 
2515 
2516 /* Warning category docstrings */
2517 
2518 /*
2519  *    Warning extends Exception
2520  */
2521 SimpleExtendsException(PyExc_Exception, Warning,
2522                        "Base class for warning categories.");
2523 
2524 
2525 /*
2526  *    UserWarning extends Warning
2527  */
2528 SimpleExtendsException(PyExc_Warning, UserWarning,
2529                        "Base class for warnings generated by user code.");
2530 
2531 
2532 /*
2533  *    DeprecationWarning extends Warning
2534  */
2535 SimpleExtendsException(PyExc_Warning, DeprecationWarning,
2536                        "Base class for warnings about deprecated features.");
2537 
2538 
2539 /*
2540  *    PendingDeprecationWarning extends Warning
2541  */
2542 SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
2543     "Base class for warnings about features which will be deprecated\n"
2544     "in the future.");
2545 
2546 
2547 /*
2548  *    SyntaxWarning extends Warning
2549  */
2550 SimpleExtendsException(PyExc_Warning, SyntaxWarning,
2551                        "Base class for warnings about dubious syntax.");
2552 
2553 
2554 /*
2555  *    RuntimeWarning extends Warning
2556  */
2557 SimpleExtendsException(PyExc_Warning, RuntimeWarning,
2558                  "Base class for warnings about dubious runtime behavior.");
2559 
2560 
2561 /*
2562  *    FutureWarning extends Warning
2563  */
2564 SimpleExtendsException(PyExc_Warning, FutureWarning,
2565     "Base class for warnings about constructs that will change semantically\n"
2566     "in the future.");
2567 
2568 
2569 /*
2570  *    ImportWarning extends Warning
2571  */
2572 SimpleExtendsException(PyExc_Warning, ImportWarning,
2573           "Base class for warnings about probable mistakes in module imports");
2574 
2575 
2576 /*
2577  *    UnicodeWarning extends Warning
2578  */
2579 SimpleExtendsException(PyExc_Warning, UnicodeWarning,
2580     "Base class for warnings about Unicode related problems, mostly\n"
2581     "related to conversion problems.");
2582 
2583 
2584 /*
2585  *    BytesWarning extends Warning
2586  */
2587 SimpleExtendsException(PyExc_Warning, BytesWarning,
2588     "Base class for warnings about bytes and buffer related problems, mostly\n"
2589     "related to conversion from str or comparing to str.");
2590 
2591 
2592 /*
2593  *    EncodingWarning extends Warning
2594  */
2595 SimpleExtendsException(PyExc_Warning, EncodingWarning,
2596     "Base class for warnings about encodings.");
2597 
2598 
2599 /*
2600  *    ResourceWarning extends Warning
2601  */
2602 SimpleExtendsException(PyExc_Warning, ResourceWarning,
2603     "Base class for warnings about resource usage.");
2604 
2605 
2606 
2607 #ifdef MS_WINDOWS
2608 #include <winsock2.h>
2609 /* The following constants were added to errno.h in VS2010 but have
2610    preferred WSA equivalents. */
2611 #undef EADDRINUSE
2612 #undef EADDRNOTAVAIL
2613 #undef EAFNOSUPPORT
2614 #undef EALREADY
2615 #undef ECONNABORTED
2616 #undef ECONNREFUSED
2617 #undef ECONNRESET
2618 #undef EDESTADDRREQ
2619 #undef EHOSTUNREACH
2620 #undef EINPROGRESS
2621 #undef EISCONN
2622 #undef ELOOP
2623 #undef EMSGSIZE
2624 #undef ENETDOWN
2625 #undef ENETRESET
2626 #undef ENETUNREACH
2627 #undef ENOBUFS
2628 #undef ENOPROTOOPT
2629 #undef ENOTCONN
2630 #undef ENOTSOCK
2631 #undef EOPNOTSUPP
2632 #undef EPROTONOSUPPORT
2633 #undef EPROTOTYPE
2634 #undef ETIMEDOUT
2635 #undef EWOULDBLOCK
2636 
2637 #if defined(WSAEALREADY) && !defined(EALREADY)
2638 #define EALREADY WSAEALREADY
2639 #endif
2640 #if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
2641 #define ECONNABORTED WSAECONNABORTED
2642 #endif
2643 #if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
2644 #define ECONNREFUSED WSAECONNREFUSED
2645 #endif
2646 #if defined(WSAECONNRESET) && !defined(ECONNRESET)
2647 #define ECONNRESET WSAECONNRESET
2648 #endif
2649 #if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
2650 #define EINPROGRESS WSAEINPROGRESS
2651 #endif
2652 #if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
2653 #define ESHUTDOWN WSAESHUTDOWN
2654 #endif
2655 #if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
2656 #define ETIMEDOUT WSAETIMEDOUT
2657 #endif
2658 #if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
2659 #define EWOULDBLOCK WSAEWOULDBLOCK
2660 #endif
2661 #endif /* MS_WINDOWS */
2662 
2663 PyStatus
_PyExc_Init(PyInterpreterState * interp)2664 _PyExc_Init(PyInterpreterState *interp)
2665 {
2666     struct _Py_exc_state *state = &interp->exc_state;
2667 
2668 #define PRE_INIT(TYPE) \
2669     if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
2670         if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
2671             return _PyStatus_ERR("exceptions bootstrapping error."); \
2672         } \
2673         Py_INCREF(PyExc_ ## TYPE); \
2674     }
2675 
2676 #define ADD_ERRNO(TYPE, CODE) \
2677     do { \
2678         PyObject *_code = PyLong_FromLong(CODE); \
2679         assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
2680         if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
2681             Py_XDECREF(_code); \
2682             return _PyStatus_ERR("errmap insertion problem."); \
2683         } \
2684         Py_DECREF(_code); \
2685     } while (0)
2686 
2687     PRE_INIT(BaseException);
2688     PRE_INIT(Exception);
2689     PRE_INIT(TypeError);
2690     PRE_INIT(StopAsyncIteration);
2691     PRE_INIT(StopIteration);
2692     PRE_INIT(GeneratorExit);
2693     PRE_INIT(SystemExit);
2694     PRE_INIT(KeyboardInterrupt);
2695     PRE_INIT(ImportError);
2696     PRE_INIT(ModuleNotFoundError);
2697     PRE_INIT(OSError);
2698     PRE_INIT(EOFError);
2699     PRE_INIT(RuntimeError);
2700     PRE_INIT(RecursionError);
2701     PRE_INIT(NotImplementedError);
2702     PRE_INIT(NameError);
2703     PRE_INIT(UnboundLocalError);
2704     PRE_INIT(AttributeError);
2705     PRE_INIT(SyntaxError);
2706     PRE_INIT(IndentationError);
2707     PRE_INIT(TabError);
2708     PRE_INIT(LookupError);
2709     PRE_INIT(IndexError);
2710     PRE_INIT(KeyError);
2711     PRE_INIT(ValueError);
2712     PRE_INIT(UnicodeError);
2713     PRE_INIT(UnicodeEncodeError);
2714     PRE_INIT(UnicodeDecodeError);
2715     PRE_INIT(UnicodeTranslateError);
2716     PRE_INIT(AssertionError);
2717     PRE_INIT(ArithmeticError);
2718     PRE_INIT(FloatingPointError);
2719     PRE_INIT(OverflowError);
2720     PRE_INIT(ZeroDivisionError);
2721     PRE_INIT(SystemError);
2722     PRE_INIT(ReferenceError);
2723     PRE_INIT(MemoryError);
2724     PRE_INIT(BufferError);
2725     PRE_INIT(Warning);
2726     PRE_INIT(UserWarning);
2727     PRE_INIT(EncodingWarning);
2728     PRE_INIT(DeprecationWarning);
2729     PRE_INIT(PendingDeprecationWarning);
2730     PRE_INIT(SyntaxWarning);
2731     PRE_INIT(RuntimeWarning);
2732     PRE_INIT(FutureWarning);
2733     PRE_INIT(ImportWarning);
2734     PRE_INIT(UnicodeWarning);
2735     PRE_INIT(BytesWarning);
2736     PRE_INIT(ResourceWarning);
2737 
2738     /* OSError subclasses */
2739     PRE_INIT(ConnectionError);
2740 
2741     PRE_INIT(BlockingIOError);
2742     PRE_INIT(BrokenPipeError);
2743     PRE_INIT(ChildProcessError);
2744     PRE_INIT(ConnectionAbortedError);
2745     PRE_INIT(ConnectionRefusedError);
2746     PRE_INIT(ConnectionResetError);
2747     PRE_INIT(FileExistsError);
2748     PRE_INIT(FileNotFoundError);
2749     PRE_INIT(IsADirectoryError);
2750     PRE_INIT(NotADirectoryError);
2751     PRE_INIT(InterruptedError);
2752     PRE_INIT(PermissionError);
2753     PRE_INIT(ProcessLookupError);
2754     PRE_INIT(TimeoutError);
2755 
2756     if (preallocate_memerrors() < 0) {
2757         return _PyStatus_NO_MEMORY();
2758     }
2759 
2760     /* Add exceptions to errnomap */
2761     assert(state->errnomap == NULL);
2762     state->errnomap = PyDict_New();
2763     if (!state->errnomap) {
2764         return _PyStatus_NO_MEMORY();
2765     }
2766 
2767     ADD_ERRNO(BlockingIOError, EAGAIN);
2768     ADD_ERRNO(BlockingIOError, EALREADY);
2769     ADD_ERRNO(BlockingIOError, EINPROGRESS);
2770     ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
2771     ADD_ERRNO(BrokenPipeError, EPIPE);
2772 #ifdef ESHUTDOWN
2773     ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
2774 #endif
2775     ADD_ERRNO(ChildProcessError, ECHILD);
2776     ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
2777     ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
2778     ADD_ERRNO(ConnectionResetError, ECONNRESET);
2779     ADD_ERRNO(FileExistsError, EEXIST);
2780     ADD_ERRNO(FileNotFoundError, ENOENT);
2781     ADD_ERRNO(IsADirectoryError, EISDIR);
2782     ADD_ERRNO(NotADirectoryError, ENOTDIR);
2783     ADD_ERRNO(InterruptedError, EINTR);
2784     ADD_ERRNO(PermissionError, EACCES);
2785     ADD_ERRNO(PermissionError, EPERM);
2786     ADD_ERRNO(ProcessLookupError, ESRCH);
2787     ADD_ERRNO(TimeoutError, ETIMEDOUT);
2788 
2789     return _PyStatus_OK();
2790 
2791 #undef PRE_INIT
2792 #undef ADD_ERRNO
2793 }
2794 
2795 
2796 /* Add exception types to the builtins module */
2797 PyStatus
_PyBuiltins_AddExceptions(PyObject * bltinmod)2798 _PyBuiltins_AddExceptions(PyObject *bltinmod)
2799 {
2800 #define POST_INIT(TYPE) \
2801     if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \
2802         return _PyStatus_ERR("Module dictionary insertion problem."); \
2803     }
2804 
2805 #define INIT_ALIAS(NAME, TYPE) \
2806     do { \
2807         Py_INCREF(PyExc_ ## TYPE); \
2808         Py_XDECREF(PyExc_ ## NAME); \
2809         PyExc_ ## NAME = PyExc_ ## TYPE; \
2810         if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \
2811             return _PyStatus_ERR("Module dictionary insertion problem."); \
2812         } \
2813     } while (0)
2814 
2815     PyObject *bdict;
2816 
2817     bdict = PyModule_GetDict(bltinmod);
2818     if (bdict == NULL) {
2819         return _PyStatus_ERR("exceptions bootstrapping error.");
2820     }
2821 
2822     POST_INIT(BaseException);
2823     POST_INIT(Exception);
2824     POST_INIT(TypeError);
2825     POST_INIT(StopAsyncIteration);
2826     POST_INIT(StopIteration);
2827     POST_INIT(GeneratorExit);
2828     POST_INIT(SystemExit);
2829     POST_INIT(KeyboardInterrupt);
2830     POST_INIT(ImportError);
2831     POST_INIT(ModuleNotFoundError);
2832     POST_INIT(OSError);
2833     INIT_ALIAS(EnvironmentError, OSError);
2834     INIT_ALIAS(IOError, OSError);
2835 #ifdef MS_WINDOWS
2836     INIT_ALIAS(WindowsError, OSError);
2837 #endif
2838     POST_INIT(EOFError);
2839     POST_INIT(RuntimeError);
2840     POST_INIT(RecursionError);
2841     POST_INIT(NotImplementedError);
2842     POST_INIT(NameError);
2843     POST_INIT(UnboundLocalError);
2844     POST_INIT(AttributeError);
2845     POST_INIT(SyntaxError);
2846     POST_INIT(IndentationError);
2847     POST_INIT(TabError);
2848     POST_INIT(LookupError);
2849     POST_INIT(IndexError);
2850     POST_INIT(KeyError);
2851     POST_INIT(ValueError);
2852     POST_INIT(UnicodeError);
2853     POST_INIT(UnicodeEncodeError);
2854     POST_INIT(UnicodeDecodeError);
2855     POST_INIT(UnicodeTranslateError);
2856     POST_INIT(AssertionError);
2857     POST_INIT(ArithmeticError);
2858     POST_INIT(FloatingPointError);
2859     POST_INIT(OverflowError);
2860     POST_INIT(ZeroDivisionError);
2861     POST_INIT(SystemError);
2862     POST_INIT(ReferenceError);
2863     POST_INIT(MemoryError);
2864     POST_INIT(BufferError);
2865     POST_INIT(Warning);
2866     POST_INIT(UserWarning);
2867     POST_INIT(EncodingWarning);
2868     POST_INIT(DeprecationWarning);
2869     POST_INIT(PendingDeprecationWarning);
2870     POST_INIT(SyntaxWarning);
2871     POST_INIT(RuntimeWarning);
2872     POST_INIT(FutureWarning);
2873     POST_INIT(ImportWarning);
2874     POST_INIT(UnicodeWarning);
2875     POST_INIT(BytesWarning);
2876     POST_INIT(ResourceWarning);
2877 
2878     /* OSError subclasses */
2879     POST_INIT(ConnectionError);
2880 
2881     POST_INIT(BlockingIOError);
2882     POST_INIT(BrokenPipeError);
2883     POST_INIT(ChildProcessError);
2884     POST_INIT(ConnectionAbortedError);
2885     POST_INIT(ConnectionRefusedError);
2886     POST_INIT(ConnectionResetError);
2887     POST_INIT(FileExistsError);
2888     POST_INIT(FileNotFoundError);
2889     POST_INIT(IsADirectoryError);
2890     POST_INIT(NotADirectoryError);
2891     POST_INIT(InterruptedError);
2892     POST_INIT(PermissionError);
2893     POST_INIT(ProcessLookupError);
2894     POST_INIT(TimeoutError);
2895 
2896     return _PyStatus_OK();
2897 
2898 #undef POST_INIT
2899 #undef INIT_ALIAS
2900 }
2901 
2902 void
_PyExc_Fini(PyInterpreterState * interp)2903 _PyExc_Fini(PyInterpreterState *interp)
2904 {
2905     struct _Py_exc_state *state = &interp->exc_state;
2906     free_preallocated_memerrors(state);
2907     Py_CLEAR(state->errnomap);
2908 }
2909 
2910 /* Helper to do the equivalent of "raise X from Y" in C, but always using
2911  * the current exception rather than passing one in.
2912  *
2913  * We currently limit this to *only* exceptions that use the BaseException
2914  * tp_init and tp_new methods, since we can be reasonably sure we can wrap
2915  * those correctly without losing data and without losing backwards
2916  * compatibility.
2917  *
2918  * We also aim to rule out *all* exceptions that might be storing additional
2919  * state, whether by having a size difference relative to BaseException,
2920  * additional arguments passed in during construction or by having a
2921  * non-empty instance dict.
2922  *
2923  * We need to be very careful with what we wrap, since changing types to
2924  * a broader exception type would be backwards incompatible for
2925  * existing codecs, and with different init or new method implementations
2926  * may either not support instantiation with PyErr_Format or lose
2927  * information when instantiated that way.
2928  *
2929  * XXX (ncoghlan): This could be made more comprehensive by exploiting the
2930  * fact that exceptions are expected to support pickling. If more builtin
2931  * exceptions (e.g. AttributeError) start to be converted to rich
2932  * exceptions with additional attributes, that's probably a better approach
2933  * to pursue over adding special cases for particular stateful subclasses.
2934  *
2935  * Returns a borrowed reference to the new exception (if any), NULL if the
2936  * existing exception was left in place.
2937  */
2938 PyObject *
_PyErr_TrySetFromCause(const char * format,...)2939 _PyErr_TrySetFromCause(const char *format, ...)
2940 {
2941     PyObject* msg_prefix;
2942     PyObject *exc, *val, *tb;
2943     PyTypeObject *caught_type;
2944     PyObject **dictptr;
2945     PyObject *instance_args;
2946     Py_ssize_t num_args, caught_type_size, base_exc_size;
2947     PyObject *new_exc, *new_val, *new_tb;
2948     va_list vargs;
2949     int same_basic_size;
2950 
2951     PyErr_Fetch(&exc, &val, &tb);
2952     caught_type = (PyTypeObject *)exc;
2953     /* Ensure type info indicates no extra state is stored at the C level
2954      * and that the type can be reinstantiated using PyErr_Format
2955      */
2956     caught_type_size = caught_type->tp_basicsize;
2957     base_exc_size = _PyExc_BaseException.tp_basicsize;
2958     same_basic_size = (
2959         caught_type_size == base_exc_size ||
2960         (PyType_SUPPORTS_WEAKREFS(caught_type) &&
2961             (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
2962         )
2963     );
2964     if (caught_type->tp_init != (initproc)BaseException_init ||
2965         caught_type->tp_new != BaseException_new ||
2966         !same_basic_size ||
2967         caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
2968         /* We can't be sure we can wrap this safely, since it may contain
2969          * more state than just the exception type. Accordingly, we just
2970          * leave it alone.
2971          */
2972         PyErr_Restore(exc, val, tb);
2973         return NULL;
2974     }
2975 
2976     /* Check the args are empty or contain a single string */
2977     PyErr_NormalizeException(&exc, &val, &tb);
2978     instance_args = ((PyBaseExceptionObject *)val)->args;
2979     num_args = PyTuple_GET_SIZE(instance_args);
2980     if (num_args > 1 ||
2981         (num_args == 1 &&
2982          !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
2983         /* More than 1 arg, or the one arg we do have isn't a string
2984          */
2985         PyErr_Restore(exc, val, tb);
2986         return NULL;
2987     }
2988 
2989     /* Ensure the instance dict is also empty */
2990     dictptr = _PyObject_GetDictPtr(val);
2991     if (dictptr != NULL && *dictptr != NULL &&
2992         PyDict_GET_SIZE(*dictptr) > 0) {
2993         /* While we could potentially copy a non-empty instance dictionary
2994          * to the replacement exception, for now we take the more
2995          * conservative path of leaving exceptions with attributes set
2996          * alone.
2997          */
2998         PyErr_Restore(exc, val, tb);
2999         return NULL;
3000     }
3001 
3002     /* For exceptions that we can wrap safely, we chain the original
3003      * exception to a new one of the exact same type with an
3004      * error message that mentions the additional details and the
3005      * original exception.
3006      *
3007      * It would be nice to wrap OSError and various other exception
3008      * types as well, but that's quite a bit trickier due to the extra
3009      * state potentially stored on OSError instances.
3010      */
3011     /* Ensure the traceback is set correctly on the existing exception */
3012     if (tb != NULL) {
3013         PyException_SetTraceback(val, tb);
3014         Py_DECREF(tb);
3015     }
3016 
3017 #ifdef HAVE_STDARG_PROTOTYPES
3018     va_start(vargs, format);
3019 #else
3020     va_start(vargs);
3021 #endif
3022     msg_prefix = PyUnicode_FromFormatV(format, vargs);
3023     va_end(vargs);
3024     if (msg_prefix == NULL) {
3025         Py_DECREF(exc);
3026         Py_DECREF(val);
3027         return NULL;
3028     }
3029 
3030     PyErr_Format(exc, "%U (%s: %S)",
3031                  msg_prefix, Py_TYPE(val)->tp_name, val);
3032     Py_DECREF(exc);
3033     Py_DECREF(msg_prefix);
3034     PyErr_Fetch(&new_exc, &new_val, &new_tb);
3035     PyErr_NormalizeException(&new_exc, &new_val, &new_tb);
3036     PyException_SetCause(new_val, val);
3037     PyErr_Restore(new_exc, new_val, new_tb);
3038     return new_val;
3039 }
3040