summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Aditya <kumaraditya@python.org>2025-01-13 14:38:33 (GMT)
committerGitHub <noreply@github.com>2025-01-13 14:38:33 (GMT)
commit75214f87f1ddd1d7b9a5b663a9c688b1bd41c098 (patch)
tree230d33954692c754f51b56b4ecdde0566d1f3dff
parentbf64a582f00a030fee11b7f89c6a02ea967990ca (diff)
downloadcpython-75214f87f1ddd1d7b9a5b663a9c688b1bd41c098.zip
cpython-75214f87f1ddd1d7b9a5b663a9c688b1bd41c098.tar.gz
cpython-75214f87f1ddd1d7b9a5b663a9c688b1bd41c098.tar.bz2
gh-128421: make getters and setters of `BaseException` thread safe (#128728)
-rw-r--r--Objects/clinic/exceptions.c.h311
-rw-r--r--Objects/exceptions.c298
2 files changed, 520 insertions, 89 deletions
diff --git a/Objects/clinic/exceptions.c.h b/Objects/clinic/exceptions.c.h
new file mode 100644
index 0000000..caa5b0c
--- /dev/null
+++ b/Objects/clinic/exceptions.c.h
@@ -0,0 +1,311 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
+#include "pycore_modsupport.h" // _PyArg_BadArgument()
+
+PyDoc_STRVAR(BaseException___reduce____doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define BASEEXCEPTION___REDUCE___METHODDEF \
+ {"__reduce__", (PyCFunction)BaseException___reduce__, METH_NOARGS, BaseException___reduce____doc__},
+
+static PyObject *
+BaseException___reduce___impl(PyBaseExceptionObject *self);
+
+static PyObject *
+BaseException___reduce__(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___reduce___impl(self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+PyDoc_STRVAR(BaseException___setstate____doc__,
+"__setstate__($self, state, /)\n"
+"--\n"
+"\n");
+
+#define BASEEXCEPTION___SETSTATE___METHODDEF \
+ {"__setstate__", (PyCFunction)BaseException___setstate__, METH_O, BaseException___setstate____doc__},
+
+static PyObject *
+BaseException___setstate___impl(PyBaseExceptionObject *self, PyObject *state);
+
+static PyObject *
+BaseException___setstate__(PyBaseExceptionObject *self, PyObject *state)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___setstate___impl(self, state);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+PyDoc_STRVAR(BaseException_with_traceback__doc__,
+"with_traceback($self, tb, /)\n"
+"--\n"
+"\n"
+"Set self.__traceback__ to tb and return self.");
+
+#define BASEEXCEPTION_WITH_TRACEBACK_METHODDEF \
+ {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O, BaseException_with_traceback__doc__},
+
+static PyObject *
+BaseException_with_traceback_impl(PyBaseExceptionObject *self, PyObject *tb);
+
+static PyObject *
+BaseException_with_traceback(PyBaseExceptionObject *self, PyObject *tb)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException_with_traceback_impl(self, tb);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+PyDoc_STRVAR(BaseException_add_note__doc__,
+"add_note($self, note, /)\n"
+"--\n"
+"\n"
+"Add a note to the exception");
+
+#define BASEEXCEPTION_ADD_NOTE_METHODDEF \
+ {"add_note", (PyCFunction)BaseException_add_note, METH_O, BaseException_add_note__doc__},
+
+static PyObject *
+BaseException_add_note_impl(PyBaseExceptionObject *self, PyObject *note);
+
+static PyObject *
+BaseException_add_note(PyBaseExceptionObject *self, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *note;
+
+ if (!PyUnicode_Check(arg)) {
+ _PyArg_BadArgument("add_note", "argument", "str", arg);
+ goto exit;
+ }
+ note = arg;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException_add_note_impl(self, note);
+ Py_END_CRITICAL_SECTION();
+
+exit:
+ return return_value;
+}
+
+#if !defined(BaseException_args_DOCSTR)
+# define BaseException_args_DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION_ARGS_GETSETDEF)
+# undef BASEEXCEPTION_ARGS_GETSETDEF
+# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, (setter)BaseException_args_set, BaseException_args_DOCSTR},
+#else
+# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, NULL, BaseException_args_DOCSTR},
+#endif
+
+static PyObject *
+BaseException_args_get_impl(PyBaseExceptionObject *self);
+
+static PyObject *
+BaseException_args_get(PyBaseExceptionObject *self, void *Py_UNUSED(context))
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException_args_get_impl(self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException_args_DOCSTR)
+# define BaseException_args_DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION_ARGS_GETSETDEF)
+# undef BASEEXCEPTION_ARGS_GETSETDEF
+# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, (setter)BaseException_args_set, BaseException_args_DOCSTR},
+#else
+# define BASEEXCEPTION_ARGS_GETSETDEF {"args", NULL, (setter)BaseException_args_set, NULL},
+#endif
+
+static int
+BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value);
+
+static int
+BaseException_args_set(PyBaseExceptionObject *self, PyObject *value, void *Py_UNUSED(context))
+{
+ int return_value;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException_args_set_impl(self, value);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___traceback___DOCSTR)
+# define BaseException___traceback___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___TRACEBACK___GETSETDEF)
+# undef BASEEXCEPTION___TRACEBACK___GETSETDEF
+# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, (setter)BaseException___traceback___set, BaseException___traceback___DOCSTR},
+#else
+# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, NULL, BaseException___traceback___DOCSTR},
+#endif
+
+static PyObject *
+BaseException___traceback___get_impl(PyBaseExceptionObject *self);
+
+static PyObject *
+BaseException___traceback___get(PyBaseExceptionObject *self, void *Py_UNUSED(context))
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___traceback___get_impl(self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___traceback___DOCSTR)
+# define BaseException___traceback___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___TRACEBACK___GETSETDEF)
+# undef BASEEXCEPTION___TRACEBACK___GETSETDEF
+# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, (setter)BaseException___traceback___set, BaseException___traceback___DOCSTR},
+#else
+# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", NULL, (setter)BaseException___traceback___set, NULL},
+#endif
+
+static int
+BaseException___traceback___set_impl(PyBaseExceptionObject *self,
+ PyObject *value);
+
+static int
+BaseException___traceback___set(PyBaseExceptionObject *self, PyObject *value, void *Py_UNUSED(context))
+{
+ int return_value;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___traceback___set_impl(self, value);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___context___DOCSTR)
+# define BaseException___context___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___CONTEXT___GETSETDEF)
+# undef BASEEXCEPTION___CONTEXT___GETSETDEF
+# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, (setter)BaseException___context___set, BaseException___context___DOCSTR},
+#else
+# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, NULL, BaseException___context___DOCSTR},
+#endif
+
+static PyObject *
+BaseException___context___get_impl(PyBaseExceptionObject *self);
+
+static PyObject *
+BaseException___context___get(PyBaseExceptionObject *self, void *Py_UNUSED(context))
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___context___get_impl(self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___context___DOCSTR)
+# define BaseException___context___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___CONTEXT___GETSETDEF)
+# undef BASEEXCEPTION___CONTEXT___GETSETDEF
+# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, (setter)BaseException___context___set, BaseException___context___DOCSTR},
+#else
+# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", NULL, (setter)BaseException___context___set, NULL},
+#endif
+
+static int
+BaseException___context___set_impl(PyBaseExceptionObject *self,
+ PyObject *value);
+
+static int
+BaseException___context___set(PyBaseExceptionObject *self, PyObject *value, void *Py_UNUSED(context))
+{
+ int return_value;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___context___set_impl(self, value);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___cause___DOCSTR)
+# define BaseException___cause___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___CAUSE___GETSETDEF)
+# undef BASEEXCEPTION___CAUSE___GETSETDEF
+# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, (setter)BaseException___cause___set, BaseException___cause___DOCSTR},
+#else
+# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, NULL, BaseException___cause___DOCSTR},
+#endif
+
+static PyObject *
+BaseException___cause___get_impl(PyBaseExceptionObject *self);
+
+static PyObject *
+BaseException___cause___get(PyBaseExceptionObject *self, void *Py_UNUSED(context))
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___cause___get_impl(self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+#if !defined(BaseException___cause___DOCSTR)
+# define BaseException___cause___DOCSTR NULL
+#endif
+#if defined(BASEEXCEPTION___CAUSE___GETSETDEF)
+# undef BASEEXCEPTION___CAUSE___GETSETDEF
+# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, (setter)BaseException___cause___set, BaseException___cause___DOCSTR},
+#else
+# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", NULL, (setter)BaseException___cause___set, NULL},
+#endif
+
+static int
+BaseException___cause___set_impl(PyBaseExceptionObject *self,
+ PyObject *value);
+
+static int
+BaseException___cause___set(PyBaseExceptionObject *self, PyObject *value, void *Py_UNUSED(context))
+{
+ int return_value;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = BaseException___cause___set_impl(self, value);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+/*[clinic end generated code: output=58afcfd60057fc39 input=a9049054013a1b77]*/
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 714f8c8..4df89edf 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -16,6 +16,13 @@
#include "osdefs.h" // SEP
+#include "clinic/exceptions.c.h"
+
+/*[clinic input]
+class BaseException "PyBaseExceptionObject *" "&PyExc_BaseException"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=90558eb0fbf8a3d0]*/
+
/* Compatibility aliases */
PyObject *PyExc_EnvironmentError = NULL; // borrowed ref
@@ -152,30 +159,50 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
static PyObject *
BaseException_str(PyBaseExceptionObject *self)
{
+ PyObject *res;
+ Py_BEGIN_CRITICAL_SECTION(self);
switch (PyTuple_GET_SIZE(self->args)) {
case 0:
- return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
+ res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
+ break;
case 1:
- return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
+ res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
+ break;
default:
- return PyObject_Str(self->args);
+ res = PyObject_Str(self->args);
+ break;
}
+ Py_END_CRITICAL_SECTION();
+ return res;
}
static PyObject *
BaseException_repr(PyBaseExceptionObject *self)
{
+ PyObject *res;
+ Py_BEGIN_CRITICAL_SECTION(self);
const char *name = _PyType_Name(Py_TYPE(self));
- if (PyTuple_GET_SIZE(self->args) == 1)
- return PyUnicode_FromFormat("%s(%R)", name,
+ if (PyTuple_GET_SIZE(self->args) == 1) {
+ res = PyUnicode_FromFormat("%s(%R)", name,
PyTuple_GET_ITEM(self->args, 0));
- else
- return PyUnicode_FromFormat("%s%R", name, self->args);
+ }
+ else {
+ res = PyUnicode_FromFormat("%s%R", name, self->args);
+ }
+ Py_END_CRITICAL_SECTION();
+ return res;
}
/* Pickling support */
+
+/*[clinic input]
+@critical_section
+BaseException.__reduce__
+[clinic start generated code]*/
+
static PyObject *
-BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
+BaseException___reduce___impl(PyBaseExceptionObject *self)
+/*[clinic end generated code: output=af87c1247ef98748 input=283be5a10d9c964f]*/
{
if (self->args && self->dict)
return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
@@ -188,8 +215,17 @@ BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
* all their attributes in the __dict__. Code is taken from cPickle's
* load_build function.
*/
+
+/*[clinic input]
+@critical_section
+BaseException.__setstate__
+ state: object
+ /
+[clinic start generated code]*/
+
static PyObject *
-BaseException_setstate(PyObject *self, PyObject *state)
+BaseException___setstate___impl(PyBaseExceptionObject *self, PyObject *state)
+/*[clinic end generated code: output=f3834889950453ab input=5524b61cfe9b9856]*/
{
PyObject *d_key, *d_value;
Py_ssize_t i = 0;
@@ -202,7 +238,7 @@ BaseException_setstate(PyObject *self, PyObject *state)
while (PyDict_Next(state, &i, &d_key, &d_value)) {
Py_INCREF(d_key);
Py_INCREF(d_value);
- int res = PyObject_SetAttr(self, d_key, d_value);
+ int res = PyObject_SetAttr((PyObject *)self, d_key, d_value);
Py_DECREF(d_value);
Py_DECREF(d_key);
if (res < 0) {
@@ -213,18 +249,26 @@ BaseException_setstate(PyObject *self, PyObject *state)
Py_RETURN_NONE;
}
+
+/*[clinic input]
+@critical_section
+BaseException.with_traceback
+ tb: object
+ /
+
+Set self.__traceback__ to tb and return self.
+[clinic start generated code]*/
+
static PyObject *
-BaseException_with_traceback(PyObject *self, PyObject *tb) {
- if (PyException_SetTraceback(self, tb))
+BaseException_with_traceback_impl(PyBaseExceptionObject *self, PyObject *tb)
+/*[clinic end generated code: output=81e92f2387927f10 input=b5fb64d834717e36]*/
+{
+ if (BaseException___traceback___set_impl(self, tb) < 0){
return NULL;
-
+ }
return Py_NewRef(self);
}
-PyDoc_STRVAR(with_traceback_doc,
-"Exception.with_traceback(tb) --\n\
- set self.__traceback__ to tb and return self.");
-
static inline PyBaseExceptionObject*
_PyBaseExceptionObject_cast(PyObject *exc)
{
@@ -232,18 +276,21 @@ _PyBaseExceptionObject_cast(PyObject *exc)
return (PyBaseExceptionObject *)exc;
}
+/*[clinic input]
+@critical_section
+BaseException.add_note
+ note: object(subclass_of="&PyUnicode_Type")
+ /
+
+Add a note to the exception
+[clinic start generated code]*/
+
static PyObject *
-BaseException_add_note(PyObject *self, PyObject *note)
+BaseException_add_note_impl(PyBaseExceptionObject *self, PyObject *note)
+/*[clinic end generated code: output=fb7cbcba611c187b input=e60a6b6e9596acaf]*/
{
- if (!PyUnicode_Check(note)) {
- PyErr_Format(PyExc_TypeError,
- "note must be a str, not '%s'",
- Py_TYPE(note)->tp_name);
- return NULL;
- }
-
PyObject *notes;
- if (PyObject_GetOptionalAttr(self, &_Py_ID(__notes__), &notes) < 0) {
+ if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
return NULL;
}
if (notes == NULL) {
@@ -251,7 +298,7 @@ BaseException_add_note(PyObject *self, PyObject *note)
if (notes == NULL) {
return NULL;
}
- if (PyObject_SetAttr(self, &_Py_ID(__notes__), notes) < 0) {
+ if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
Py_DECREF(notes);
return NULL;
}
@@ -269,22 +316,23 @@ BaseException_add_note(PyObject *self, PyObject *note)
Py_RETURN_NONE;
}
-PyDoc_STRVAR(add_note_doc,
-"Exception.add_note(note) --\n\
- add a note to the exception");
-
static PyMethodDef BaseException_methods[] = {
- {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
- {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
- {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
- with_traceback_doc},
- {"add_note", (PyCFunction)BaseException_add_note, METH_O,
- add_note_doc},
- {NULL, NULL, 0, NULL},
+ BASEEXCEPTION___REDUCE___METHODDEF
+ BASEEXCEPTION___SETSTATE___METHODDEF
+ BASEEXCEPTION_WITH_TRACEBACK_METHODDEF
+ BASEEXCEPTION_ADD_NOTE_METHODDEF
+ {NULL, NULL, 0, NULL},
};
+/*[clinic input]
+@critical_section
+@getter
+BaseException.args
+[clinic start generated code]*/
+
static PyObject *
-BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
+BaseException_args_get_impl(PyBaseExceptionObject *self)
+/*[clinic end generated code: output=e02e34e35cf4d677 input=64282386e4d7822d]*/
{
if (self->args == NULL) {
Py_RETURN_NONE;
@@ -292,23 +340,37 @@ BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
return Py_NewRef(self->args);
}
+/*[clinic input]
+@critical_section
+@setter
+BaseException.args
+[clinic start generated code]*/
+
static int
-BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
+BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value)
+/*[clinic end generated code: output=331137e11d8f9e80 input=2400047ea5970a84]*/
{
PyObject *seq;
- if (val == NULL) {
+ if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "args may not be deleted");
return -1;
}
- seq = PySequence_Tuple(val);
+ seq = PySequence_Tuple(value);
if (!seq)
return -1;
Py_XSETREF(self->args, seq);
return 0;
}
+/*[clinic input]
+@critical_section
+@getter
+BaseException.__traceback__
+[clinic start generated code]*/
+
static PyObject *
-BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
+BaseException___traceback___get_impl(PyBaseExceptionObject *self)
+/*[clinic end generated code: output=17cf874a52339398 input=a2277f0de62170cf]*/
{
if (self->traceback == NULL) {
Py_RETURN_NONE;
@@ -316,17 +378,26 @@ BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
return Py_NewRef(self->traceback);
}
+
+/*[clinic input]
+@critical_section
+@setter
+BaseException.__traceback__
+[clinic start generated code]*/
+
static int
-BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
+BaseException___traceback___set_impl(PyBaseExceptionObject *self,
+ PyObject *value)
+/*[clinic end generated code: output=a82c86d9f29f48f0 input=12676035676badad]*/
{
- if (tb == NULL) {
+ if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
return -1;
}
- if (PyTraceBack_Check(tb)) {
- Py_XSETREF(self->traceback, Py_NewRef(tb));
+ if (PyTraceBack_Check(value)) {
+ Py_XSETREF(self->traceback, Py_NewRef(value));
}
- else if (tb == Py_None) {
+ else if (value == Py_None) {
Py_CLEAR(self->traceback);
}
else {
@@ -337,73 +408,100 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(
return 0;
}
+/*[clinic input]
+@critical_section
+@getter
+BaseException.__context__
+[clinic start generated code]*/
+
static PyObject *
-BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
+BaseException___context___get_impl(PyBaseExceptionObject *self)
+/*[clinic end generated code: output=6ec5d296ce8d1c93 input=b2d22687937e66ab]*/
{
- PyObject *res = PyException_GetContext(self);
- if (res)
- return res; /* new reference already returned above */
- Py_RETURN_NONE;
+ if (self->context == NULL) {
+ Py_RETURN_NONE;
+ }
+ return Py_NewRef(self->context);
}
+/*[clinic input]
+@critical_section
+@setter
+BaseException.__context__
+[clinic start generated code]*/
+
static int
-BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
+BaseException___context___set_impl(PyBaseExceptionObject *self,
+ PyObject *value)
+/*[clinic end generated code: output=b4cb52dcca1da3bd input=c0971adf47fa1858]*/
{
- if (arg == NULL) {
+ if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
return -1;
- } else if (arg == Py_None) {
- arg = NULL;
- } else if (!PyExceptionInstance_Check(arg)) {
+ } else if (value == Py_None) {
+ value = NULL;
+ } else if (!PyExceptionInstance_Check(value)) {
PyErr_SetString(PyExc_TypeError, "exception context must be None "
"or derive from BaseException");
return -1;
} else {
- /* PyException_SetContext steals this reference */
- Py_INCREF(arg);
+ Py_INCREF(value);
}
- PyException_SetContext(self, arg);
+ Py_XSETREF(self->context, value);
return 0;
}
+/*[clinic input]
+@critical_section
+@getter
+BaseException.__cause__
+[clinic start generated code]*/
+
static PyObject *
-BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
+BaseException___cause___get_impl(PyBaseExceptionObject *self)
+/*[clinic end generated code: output=987f6c4d8a0bdbab input=40e0eac427b6e602]*/
{
- PyObject *res = PyException_GetCause(self);
- if (res)
- return res; /* new reference already returned above */
- Py_RETURN_NONE;
+ if (self->cause == NULL) {
+ Py_RETURN_NONE;
+ }
+ return Py_NewRef(self->cause);
}
+/*[clinic input]
+@critical_section
+@setter
+BaseException.__cause__
+[clinic start generated code]*/
+
static int
-BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
+BaseException___cause___set_impl(PyBaseExceptionObject *self,
+ PyObject *value)
+/*[clinic end generated code: output=6161315398aaf541 input=e1b403c0bde3f62a]*/
{
- if (arg == NULL) {
+ if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
return -1;
- } else if (arg == Py_None) {
- arg = NULL;
- } else if (!PyExceptionInstance_Check(arg)) {
+ } else if (value == Py_None) {
+ value = NULL;
+ } else if (!PyExceptionInstance_Check(value)) {
PyErr_SetString(PyExc_TypeError, "exception cause must be None "
"or derive from BaseException");
return -1;
} else {
/* PyException_SetCause steals this reference */
- Py_INCREF(arg);
+ Py_INCREF(value);
}
- PyException_SetCause(self, arg);
+ PyException_SetCause((PyObject *)self, value);
return 0;
}
static PyGetSetDef BaseException_getset[] = {
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
- {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
- {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
- {"__context__", BaseException_get_context,
- BaseException_set_context, PyDoc_STR("exception context")},
- {"__cause__", BaseException_get_cause,
- BaseException_set_cause, PyDoc_STR("exception cause")},
+ BASEEXCEPTION_ARGS_GETSETDEF
+ BASEEXCEPTION___TRACEBACK___GETSETDEF
+ BASEEXCEPTION___CONTEXT___GETSETDEF
+ BASEEXCEPTION___CAUSE___GETSETDEF
{NULL},
};
@@ -411,59 +509,81 @@ static PyGetSetDef BaseException_getset[] = {
PyObject *
PyException_GetTraceback(PyObject *self)
{
- PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
- return Py_XNewRef(base_self->traceback);
+ PyObject *traceback;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ traceback = Py_XNewRef(_PyBaseExceptionObject_cast(self)->traceback);
+ Py_END_CRITICAL_SECTION();
+ return traceback;
}
int
PyException_SetTraceback(PyObject *self, PyObject *tb)
{
- return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
+ int res;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ res = BaseException___traceback___set_impl(_PyBaseExceptionObject_cast(self), tb);
+ Py_END_CRITICAL_SECTION();
+ return res;
}
PyObject *
PyException_GetCause(PyObject *self)
{
- PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
- return Py_XNewRef(cause);
+ PyObject *cause;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ cause = Py_XNewRef(_PyBaseExceptionObject_cast(self)->cause);
+ Py_END_CRITICAL_SECTION();
+ return cause;
}
/* Steals a reference to cause */
void
PyException_SetCause(PyObject *self, PyObject *cause)
{
+ Py_BEGIN_CRITICAL_SECTION(self);
PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
base_self->suppress_context = 1;
Py_XSETREF(base_self->cause, cause);
+ Py_END_CRITICAL_SECTION();
}
PyObject *
PyException_GetContext(PyObject *self)
{
- PyObject *context = _PyBaseExceptionObject_cast(self)->context;
- return Py_XNewRef(context);
+ PyObject *context;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ context = Py_XNewRef(_PyBaseExceptionObject_cast(self)->context);
+ Py_END_CRITICAL_SECTION();
+ return context;
}
/* Steals a reference to context */
void
PyException_SetContext(PyObject *self, PyObject *context)
{
+ Py_BEGIN_CRITICAL_SECTION(self);
Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
+ Py_END_CRITICAL_SECTION();
}
PyObject *
PyException_GetArgs(PyObject *self)
{
- PyObject *args = _PyBaseExceptionObject_cast(self)->args;
- return Py_NewRef(args);
+ PyObject *args;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ args = Py_NewRef(_PyBaseExceptionObject_cast(self)->args);
+ Py_END_CRITICAL_SECTION();
+ return args;
}
void
PyException_SetArgs(PyObject *self, PyObject *args)
{
+ Py_BEGIN_CRITICAL_SECTION(self);
Py_INCREF(args);
Py_XSETREF(_PyBaseExceptionObject_cast(self)->args, args);
+ Py_END_CRITICAL_SECTION();
}
const char *
@@ -4136,7 +4256,7 @@ _PyException_AddNote(PyObject *exc, PyObject *note)
Py_TYPE(exc)->tp_name);
return -1;
}
- PyObject *r = BaseException_add_note(exc, note);
+ PyObject *r = BaseException_add_note(_PyBaseExceptionObject_cast(exc), note);
int res = r == NULL ? -1 : 0;
Py_XDECREF(r);
return res;