/* * New exceptions.c written in Iceland by Richard Jones and Georg Brandl. * * Thanks go to Tim Peters and Michael Hudson for debugging. */ #define PY_SSIZE_T_CLEAN#include <Python.h>#include "structmember.h"#include "osdefs.h" #define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);#define EXC_MODULE_NAME "exceptions." /* NOTE: If the exception class hierarchy changes, don't forget to update * Lib/test/exception_hierarchy.txt */ PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\\n\Exceptions found here are defined both in the exceptions module and the\n\built-in namespace. It is recommended that user-defined exceptions\n\inherit from Exception. See the documentation for the exception\n\inheritance hierarchy.\n\"); /* * BaseException */static PyObject *BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds){ PyBaseExceptionObject *self; self = (PyBaseExceptionObject *)type->tp_alloc(type, 0); /* the dict is created on the fly in PyObject_GenericSetAttr */ self->message = self->dict = NULL; self->args = PyTuple_New(0); if (!self->args) { Py_DECREF(self); return NULL; } self->message = PyString_FromString(""); if (!self->message) { Py_DECREF(self); return NULL; } return (PyObject *)self;} static intBaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds){ if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds)) return -1; Py_DECREF(self->args); self->args = args; Py_INCREF(self->args); if (PyTuple_GET_SIZE(self->args) == 1) { Py_CLEAR(self->message); self->message = PyTuple_GET_ITEM(self->args, 0); Py_INCREF(self->message); } return 0;} static intBaseException_clear(PyBaseExceptionObject *self){ Py_CLEAR(self->dict); Py_CLEAR(self->args); Py_CLEAR(self->message); return 0;} static voidBaseException_dealloc(PyBaseExceptionObject *self){ _PyObject_GC_UNTRACK(self); BaseException_clear(self); self->ob_type->tp_free((PyObject *)self);} static intBaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg){ Py_VISIT(self->dict); Py_VISIT(self->args); Py_VISIT(self->message); return 0;} static PyObject *BaseException_str(PyBaseExceptionObject *self){ PyObject *out; switch (PyTuple_GET_SIZE(self->args)) { case 0: out = PyString_FromString(""); break; case 1: out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0)); break; default: out = PyObject_Str(self->args); break; } return out;} static PyObject *BaseException_repr(PyBaseExceptionObject *self){ PyObject *repr_suffix; PyObject *repr; char *name; char *dot; repr_suffix = PyObject_Repr(self->args); if (!repr_suffix) return NULL; name = (char *)self->ob_type->tp_name; dot = strrchr(name, '.'); if (dot != NULL) name = dot+1; repr = PyString_FromString(name); if (!repr) { Py_DECREF(repr_suffix); return NULL; } PyString_ConcatAndDel(&repr, repr_suffix); return repr;} /* Pickling support */static PyObject *BaseException_reduce(PyBaseExceptionObject *self){ if (self->args && self->dict) return PyTuple_Pack(3, self->ob_type, self->args, self->dict); else return PyTuple_Pack(2, self->ob_type, self->args);} /* * Needed for backward compatibility, since exceptions used to store * all their attributes in the __dict__. Code is taken from cPickle's * load_build function. */static PyObject *BaseException_setstate(PyObject *self, PyObject *state){ PyObject *d_key, *d_value; Py_ssize_t i = 0; if (state != Py_None) { if (!PyDict_Check(state)) { PyErr_SetString(PyExc_TypeError, "state is not a dictionary"); return NULL; } while (PyDict_Next(state, &i, &d_key, &d_value)) { if (PyObject_SetAttr(self, d_key, d_value) < 0) return NULL; } } Py_RETURN_NONE;} static PyMethodDef BaseException_methods[] = { {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, {NULL, NULL, 0, NULL},}; static PyObject *BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index){ return PySequence_GetItem(self->args, index);} static PyObject *BaseException_getslice(PyBaseExceptionObject *self, Py_ssize_t start, Py_ssize_t stop){ return PySequence_GetSlice(self->args, start, stop);} static PySequenceMethods BaseException_as_sequence = { 0, /* sq_length; */ 0, /* sq_concat; */ 0, /* sq_repeat; */ (ssizeargfunc)BaseException_getitem, /* sq_item; */ (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */ 0, /* sq_ass_item; */ 0, /* sq_ass_slice; */ 0, /* sq_contains; */ 0, /* sq_inplace_concat; */ 0 /* sq_inplace_repeat; */}; static PyMemberDef BaseException_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0, PyDoc_STR("exception message")}, {NULL} /* Sentinel */}; static PyObject *BaseException_get_dict(PyBaseExceptionObject *self){ if (self->dict == NULL) { self->dict = PyDict_New(); if (!self->dict) return NULL; } Py_INCREF(self->dict); return self->dict;} static intBaseException_set_dict(PyBaseExceptionObject *self, PyObject *val){ if (val == NULL) { PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted"); return -1; } if (!PyDict_Check(val)) { PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary"); return -1; } Py_CLEAR(self->dict); Py_INCREF(val); self->dict = val; return 0;} static PyObject *BaseException_get_args(PyBaseExceptionObject *self){ if (self->args == NULL) { Py_INCREF(Py_None); return Py_None; } Py_INCREF(self->args); return self->args;} static intBaseException_set_args(PyBaseExceptionObject *self, PyObject *val){ PyObject *seq; if (val == NULL) { PyErr_SetString(PyExc_TypeError, "args may not be deleted"); return -1; } seq = PySequence_Tuple(val); if (!seq) return -1; Py_CLEAR(self->args); self->args = seq; return 0;} static PyGetSetDef BaseException_getset[] = { {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict}, {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, {NULL},}; static PyTypeObject _PyExc_BaseException = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ EXC_MODULE_NAME "BaseException", /*tp_name*/ sizeof(PyBaseExceptionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)BaseException_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /* tp_compare; */ (reprfunc)BaseException_repr, /*tp_repr*/ 0, /*tp_as_number*/ &BaseException_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)BaseException_str, /*tp_str*/ PyObject_GenericGetAttr, /*tp_getattro*/ PyObject_GenericSetAttr, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ PyDoc_STR("Common base class for all exceptions"), /* tp_doc */ (traverseproc)BaseException_traverse, /* tp_traverse */ (inquiry)BaseException_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ BaseException_methods, /* tp_methods */ BaseException_members, /* tp_members */ BaseException_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */ (initproc)BaseException_init, /* tp_init */ 0, /* tp_alloc */ BaseException_new, /* tp_new */};/* the CPython API expects exceptions to be (PyObject *) - both a hold-overfrom the previous implmentation and also allowing Python objects to be usedin the API */PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException; /* note these macros omit the last semicolon so the macro invocation may * include it and not look strange. */#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(PyBaseExceptionObject), \ 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \ (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \ (initproc)BaseException_init, 0, BaseException_new,\}; \PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(Py ## EXCSTORE ## Object), \ 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ (initproc)EXCSTORE ## _init, 0, BaseException_new,\}; \PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(Py ## EXCSTORE ## Object), 0, \ (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ (reprfunc)EXCSTR, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \ EXCMEMBERS, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ (initproc)EXCSTORE ## _init, 0, BaseException_new,\}; \PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME /* * Exception extends BaseException */SimpleExtendsException(PyExc_BaseException, Exception, "Common base class for all non-exit exceptions."); /* * StandardError extends Exception */SimpleExtendsException(PyExc_Exception, StandardError, "Base class for all standard Python exceptions that do not represent\n" "interpreter exiting."); /* * TypeError extends StandardError */SimpleExtendsException(PyExc_StandardError, TypeError, "Inappropriate argument type."); /* * StopIteration extends Exception */SimpleExtendsException(PyExc_Exception, StopIteration, "Signal the end from iterator.next()."); /* * GeneratorExit extends Exception */SimpleExtendsException(PyExc_Exception, GeneratorExit, "Request that a generator exit."); /* * SystemExit extends BaseException */ static intSystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds){ Py_ssize_t size = PyTuple_GET_SIZE(args); if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; if (size == 0) return 0; Py_CLEAR(self->code); if (size == 1) self->code = PyTuple_GET_ITEM(args, 0); else if (size > 1) self->code = args; Py_INCREF(self->code); return 0;} static intSystemExit_clear(PySystemExitObject *self){ Py_CLEAR(self->code); return BaseException_clear((PyBaseExceptionObject *)self);} static voidSystemExit_dealloc(PySystemExitObject *self){ _PyObject_GC_UNTRACK(self); SystemExit_clear(self); self->ob_type->tp_free((PyObject *)self);} static intSystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg){ Py_VISIT(self->code); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);} static PyMemberDef SystemExit_members[] = { {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0, PyDoc_STR("exception message")}, {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0, PyDoc_STR("exception code")}, {NULL} /* Sentinel */}; ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit, SystemExit_dealloc, 0, SystemExit_members, 0, "Request to exit from the interpreter."); /* * KeyboardInterrupt extends BaseException */SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, "Program interrupted by user."); /* * ImportError extends StandardError */SimpleExtendsException(PyExc_StandardError, ImportError, "Import can't find module, or can't find name in module."); /* * EnvironmentError extends StandardError */ /* Where a function has a single filename, such as open() or some * of the os module functions, PyErr_SetFromErrnoWithFilename() is * called, giving a third argument which is the filename. But, so * that old code using in-place unpacking doesn't break, e.g.: * * except IOError, (errno, strerror): * * we hack args so that it only contains two items. This also * means we need our own __str__() which prints out the filenameLines 1–500 of 2147. Load more
/* * New exceptions.c written in Iceland by Richard Jones and Georg Brandl. * * Thanks go to Tim Peters and Michael Hudson for debugging. */ #define PY_SSIZE_T_CLEAN #include <Python.h> #include "structmember.h" #include "osdefs.h" #define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None); #define EXC_MODULE_NAME "exceptions." /* NOTE: If the exception class hierarchy changes, don't forget to update * Lib/test/exception_hierarchy.txt */ PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\ \n\ Exceptions found here are defined both in the exceptions module and the\n\ built-in namespace. It is recommended that user-defined exceptions\n\ inherit from Exception. See the documentation for the exception\n\ inheritance hierarchy.\n\ "); /* * BaseException */ static PyObject * BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; self = (PyBaseExceptionObject *)type->tp_alloc(type, 0); /* the dict is created on the fly in PyObject_GenericSetAttr */ self->message = self->dict = NULL; self->args = PyTuple_New(0); if (!self->args) { Py_DECREF(self); return NULL; } self->message = PyString_FromString(""); if (!self->message) { Py_DECREF(self); return NULL; } return (PyObject *)self; } static int BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) { if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds)) return -1; Py_DECREF(self->args); self->args = args; Py_INCREF(self->args); if (PyTuple_GET_SIZE(self->args) == 1) { Py_CLEAR(self->message); self->message = PyTuple_GET_ITEM(self->args, 0); Py_INCREF(self->message); } return 0; } static int BaseException_clear(PyBaseExceptionObject *self) { Py_CLEAR(self->dict); Py_CLEAR(self->args); Py_CLEAR(self->message); return 0; } static void BaseException_dealloc(PyBaseExceptionObject *self) { _PyObject_GC_UNTRACK(self); BaseException_clear(self); self->ob_type->tp_free((PyObject *)self); } static int BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg) { Py_VISIT(self->dict); Py_VISIT(self->args); Py_VISIT(self->message); return 0; } static PyObject * BaseException_str(PyBaseExceptionObject *self) { PyObject *out; switch (PyTuple_GET_SIZE(self->args)) { case 0: out = PyString_FromString(""); break; case 1: out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0)); break; default: out = PyObject_Str(self->args); break; } return out; } static PyObject * BaseException_repr(PyBaseExceptionObject *self) { PyObject *repr_suffix; PyObject *repr; char *name; char *dot; repr_suffix = PyObject_Repr(self->args); if (!repr_suffix) return NULL; name = (char *)self->ob_type->tp_name; dot = strrchr(name, '.'); if (dot != NULL) name = dot+1; repr = PyString_FromString(name); if (!repr) { Py_DECREF(repr_suffix); return NULL; } PyString_ConcatAndDel(&repr, repr_suffix); return repr; } /* Pickling support */ static PyObject * BaseException_reduce(PyBaseExceptionObject *self) { if (self->args && self->dict) return PyTuple_Pack(3, self->ob_type, self->args, self->dict); else return PyTuple_Pack(2, self->ob_type, self->args); } /* * Needed for backward compatibility, since exceptions used to store * all their attributes in the __dict__. Code is taken from cPickle's * load_build function. */ static PyObject * BaseException_setstate(PyObject *self, PyObject *state) { PyObject *d_key, *d_value; Py_ssize_t i = 0; if (state != Py_None) { if (!PyDict_Check(state)) { PyErr_SetString(PyExc_TypeError, "state is not a dictionary"); return NULL; } while (PyDict_Next(state, &i, &d_key, &d_value)) { if (PyObject_SetAttr(self, d_key, d_value) < 0) return NULL; } } Py_RETURN_NONE; } static PyMethodDef BaseException_methods[] = { {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, {NULL, NULL, 0, NULL}, }; static PyObject * BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index) { return PySequence_GetItem(self->args, index); } static PyObject * BaseException_getslice(PyBaseExceptionObject *self, Py_ssize_t start, Py_ssize_t stop) { return PySequence_GetSlice(self->args, start, stop); } static PySequenceMethods BaseException_as_sequence = { 0, /* sq_length; */ 0, /* sq_concat; */ 0, /* sq_repeat; */ (ssizeargfunc)BaseException_getitem, /* sq_item; */ (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */ 0, /* sq_ass_item; */ 0, /* sq_ass_slice; */ 0, /* sq_contains; */ 0, /* sq_inplace_concat; */ 0 /* sq_inplace_repeat; */ }; static PyMemberDef BaseException_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0, PyDoc_STR("exception message")}, {NULL} /* Sentinel */ }; static PyObject * BaseException_get_dict(PyBaseExceptionObject *self) { if (self->dict == NULL) { self->dict = PyDict_New(); if (!self->dict) return NULL; } Py_INCREF(self->dict); return self->dict; } static int BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val) { if (val == NULL) { PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted"); return -1; } if (!PyDict_Check(val)) { PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary"); return -1; } Py_CLEAR(self->dict); Py_INCREF(val); self->dict = val; return 0; } static PyObject * BaseException_get_args(PyBaseExceptionObject *self) { if (self->args == NULL) { Py_INCREF(Py_None); return Py_None; } Py_INCREF(self->args); return self->args; } static int BaseException_set_args(PyBaseExceptionObject *self, PyObject *val) { PyObject *seq; if (val == NULL) { PyErr_SetString(PyExc_TypeError, "args may not be deleted"); return -1; } seq = PySequence_Tuple(val); if (!seq) return -1; Py_CLEAR(self->args); self->args = seq; return 0; } static PyGetSetDef BaseException_getset[] = { {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict}, {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, {NULL}, }; static PyTypeObject _PyExc_BaseException = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ EXC_MODULE_NAME "BaseException", /*tp_name*/ sizeof(PyBaseExceptionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)BaseException_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /* tp_compare; */ (reprfunc)BaseException_repr, /*tp_repr*/ 0, /*tp_as_number*/ &BaseException_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ (reprfunc)BaseException_str, /*tp_str*/ PyObject_GenericGetAttr, /*tp_getattro*/ PyObject_GenericSetAttr, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ PyDoc_STR("Common base class for all exceptions"), /* tp_doc */ (traverseproc)BaseException_traverse, /* tp_traverse */ (inquiry)BaseException_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ BaseException_methods, /* tp_methods */ BaseException_members, /* tp_members */ BaseException_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */ (initproc)BaseException_init, /* tp_init */ 0, /* tp_alloc */ BaseException_new, /* tp_new */ }; /* the CPython API expects exceptions to be (PyObject *) - both a hold-over from the previous implmentation and also allowing Python objects to be used in the API */ PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException; /* note these macros omit the last semicolon so the macro invocation may * include it and not look strange. */ #define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \ static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(PyBaseExceptionObject), \ 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \ (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \ (initproc)BaseException_init, 0, BaseException_new,\ }; \ PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \ static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(Py ## EXCSTORE ## Object), \ 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ (initproc)EXCSTORE ## _init, 0, BaseException_new,\ }; \ PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \ static PyTypeObject _PyExc_ ## EXCNAME = { \ PyObject_HEAD_INIT(NULL) \ 0, \ EXC_MODULE_NAME # EXCNAME, \ sizeof(Py ## EXCSTORE ## Object), 0, \ (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ (reprfunc)EXCSTR, 0, 0, 0, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \ EXCMEMBERS, 0, &_ ## EXCBASE, \ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \ (initproc)EXCSTORE ## _init, 0, BaseException_new,\ }; \ PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME /* * Exception extends BaseException */ SimpleExtendsException(PyExc_BaseException, Exception, "Common base class for all non-exit exceptions."); /* * StandardError extends Exception */ SimpleExtendsException(PyExc_Exception, StandardError, "Base class for all standard Python exceptions that do not represent\n" "interpreter exiting."); /* * TypeError extends StandardError */ SimpleExtendsException(PyExc_StandardError, TypeError, "Inappropriate argument type."); /* * StopIteration extends Exception */ SimpleExtendsException(PyExc_Exception, StopIteration, "Signal the end from iterator.next()."); /* * GeneratorExit extends Exception */ SimpleExtendsException(PyExc_Exception, GeneratorExit, "Request that a generator exit."); /* * SystemExit extends BaseException */ static int SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) { Py_ssize_t size = PyTuple_GET_SIZE(args); if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; if (size == 0) return 0; Py_CLEAR(self->code); if (size == 1) self->code = PyTuple_GET_ITEM(args, 0); else if (size > 1) self->code = args; Py_INCREF(self->code); return 0; } static int SystemExit_clear(PySystemExitObject *self) { Py_CLEAR(self->code); return BaseException_clear((PyBaseExceptionObject *)self); } static void SystemExit_dealloc(PySystemExitObject *self) { _PyObject_GC_UNTRACK(self); SystemExit_clear(self); self->ob_type->tp_free((PyObject *)self); } static int SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg) { Py_VISIT(self->code); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } static PyMemberDef SystemExit_members[] = { {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0, PyDoc_STR("exception message")}, {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0, PyDoc_STR("exception code")}, {NULL} /* Sentinel */ }; ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit, SystemExit_dealloc, 0, SystemExit_members, 0, "Request to exit from the interpreter."); /* * KeyboardInterrupt extends BaseException */ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, "Program interrupted by user."); /* * ImportError extends StandardError */ SimpleExtendsException(PyExc_StandardError, ImportError, "Import can't find module, or can't find name in module."); /* * EnvironmentError extends StandardError */ /* Where a function has a single filename, such as open() or some * of the os module functions, PyErr_SetFromErrnoWithFilename() is * called, giving a third argument which is the filename. But, so * that old code using in-place unpacking doesn't break, e.g.: * * except IOError, (errno, strerror): * * we hack args so that it only contains two items. This also * means we need our own __str__() which prints out the filename