• 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