diff options
| author | Collin Winter <collinw@gmail.com> | 2007-08-31 00:04:24 +0000 | 
|---|---|---|
| committer | Collin Winter <collinw@gmail.com> | 2007-08-31 00:04:24 +0000 | 
| commit | 828f04ac3f0dd3b68b4dbf42a79ebb846d1de568 (patch) | |
| tree | 21e25d3d969ce636c32539e4d4b5255dc4c85702 /Objects/exceptions.c | |
| parent | 150b7d7d02eca6970d792f3e6887f957a36b6ca2 (diff) | |
| download | cpython-git-828f04ac3f0dd3b68b4dbf42a79ebb846d1de568.tar.gz | |
Issue #1066: implement PEP 3109, 2/3 of PEP 3134.
Diffstat (limited to 'Objects/exceptions.c')
| -rw-r--r-- | Objects/exceptions.c | 98 | 
1 files changed, 97 insertions, 1 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index e900243448..cbc41e8ba2 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -28,6 +28,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)          return NULL;      /* the dict is created on the fly in PyObject_GenericSetAttr */      self->dict = NULL; +    self->traceback = NULL;      self->args = PyTuple_New(0);      if (!self->args) { @@ -56,6 +57,7 @@ BaseException_clear(PyBaseExceptionObject *self)  {      Py_CLEAR(self->dict);      Py_CLEAR(self->args); +    Py_CLEAR(self->traceback);      return 0;  } @@ -72,6 +74,7 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)  {      Py_VISIT(self->dict);      Py_VISIT(self->args); +    Py_VISIT(self->traceback);      return 0;  } @@ -135,10 +138,20 @@ BaseException_setstate(PyObject *self, PyObject *state)      Py_RETURN_NONE;  } +static PyObject * +BaseException_with_traceback(PyObject *self, PyObject *tb) { +    if (PyException_SetTraceback(self, tb)) +        return NULL; + +    Py_INCREF(self); +    return self; +} +  static PyMethodDef BaseException_methods[] = {     {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },     {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, +   {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O },     {NULL, NULL, 0, NULL},  }; @@ -198,14 +211,97 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)      return 0;  } +static PyObject * +BaseException_get_tb(PyBaseExceptionObject *self) +{ +    if (self->traceback == NULL) { +        Py_INCREF(Py_None); +        return Py_None; +    } +    Py_INCREF(self->traceback); +    return self->traceback; +} + +static int +BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb) +{ +    if (tb == NULL) { +        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); +        return -1; +    } +    else if (!(tb == Py_None || PyTraceBack_Check(tb))) { +        PyErr_SetString(PyExc_TypeError, +                        "__traceback__ must be a traceback or None"); +        return -1; +    } + +    Py_XINCREF(tb); +    Py_XDECREF(self->traceback); +    self->traceback = tb; +    return 0; +} +  static PyGetSetDef BaseException_getset[] = {      {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},      {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, +    {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},      {NULL},  }; +PyObject * +PyException_GetTraceback(PyObject *self) { +    PyBaseExceptionObject *base_self = (PyBaseExceptionObject *)self; +    Py_XINCREF(base_self->traceback); +    return base_self->traceback; +} + + +int +PyException_SetTraceback(PyObject *self, PyObject *tb) { +    return BaseException_set_tb((PyBaseExceptionObject *)self, tb); +} + +PyObject * +PyException_GetCause(PyObject *self) { +    PyObject *cause = ((PyBaseExceptionObject *)self)->cause; +    Py_XINCREF(cause); +    return cause; +} + +/* Steals a reference to cause */ +void +PyException_SetCause(PyObject *self, PyObject *cause) { +    PyObject *old_cause = ((PyBaseExceptionObject *)self)->cause; +    ((PyBaseExceptionObject *)self)->cause = cause; +    Py_XDECREF(old_cause); +} + +PyObject * +PyException_GetContext(PyObject *self) { +    PyObject *context = ((PyBaseExceptionObject *)self)->context; +    Py_XINCREF(context); +    return context; +} + +/* Steals a reference to context */ +void +PyException_SetContext(PyObject *self, PyObject *context) { +    PyObject *old_context = ((PyBaseExceptionObject *)self)->context; +    ((PyBaseExceptionObject *)self)->context = context; +    Py_XDECREF(old_context); +} + + +static PyMemberDef BaseException_members[] = { +    {"__context__", T_OBJECT, offsetof(PyBaseExceptionObject, context), 0, +        PyDoc_STR("exception context")}, +    {"__cause__", T_OBJECT, offsetof(PyBaseExceptionObject, cause), 0, +        PyDoc_STR("exception cause")}, +    {NULL}  /* Sentinel */ +}; +  static PyTypeObject _PyExc_BaseException = {      PyVarObject_HEAD_INIT(NULL, 0)      "BaseException", /*tp_name*/ @@ -236,7 +332,7 @@ static PyTypeObject _PyExc_BaseException = {      0,                          /* tp_iter */      0,                          /* tp_iternext */      BaseException_methods,      /* tp_methods */ -    0,                          /* tp_members */ +    BaseException_members,      /* tp_members */      BaseException_getset,       /* tp_getset */      0,                          /* tp_base */      0,                          /* tp_dict */  | 
