summaryrefslogtreecommitdiffstats
path: root/Objects/exceptions.c
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2023-03-21 21:36:31 (GMT)
committerGitHub <noreply@github.com>2023-03-21 21:36:31 (GMT)
commit76350e85ebf96df588384f3d9bdc20d11045bef4 (patch)
treedfc8197d86f5cbb646d932d05e7612435887c5c7 /Objects/exceptions.c
parente6ecd3e6b437f3056e0a410a57c52e2639b56353 (diff)
downloadcpython-76350e85ebf96df588384f3d9bdc20d11045bef4.zip
cpython-76350e85ebf96df588384f3d9bdc20d11045bef4.tar.gz
cpython-76350e85ebf96df588384f3d9bdc20d11045bef4.tar.bz2
gh-102406: replace exception chaining by PEP-678 notes in codecs (#102407)
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r--Objects/exceptions.c110
1 files changed, 0 insertions, 110 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index d69f740..a355244 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -3764,113 +3764,3 @@ _PyException_AddNote(PyObject *exc, PyObject *note)
return res;
}
-/* Helper to do the equivalent of "raise X from Y" in C, but always using
- * the current exception rather than passing one in.
- *
- * We currently limit this to *only* exceptions that use the BaseException
- * tp_init and tp_new methods, since we can be reasonably sure we can wrap
- * those correctly without losing data and without losing backwards
- * compatibility.
- *
- * We also aim to rule out *all* exceptions that might be storing additional
- * state, whether by having a size difference relative to BaseException,
- * additional arguments passed in during construction or by having a
- * non-empty instance dict.
- *
- * We need to be very careful with what we wrap, since changing types to
- * a broader exception type would be backwards incompatible for
- * existing codecs, and with different init or new method implementations
- * may either not support instantiation with PyErr_Format or lose
- * information when instantiated that way.
- *
- * XXX (ncoghlan): This could be made more comprehensive by exploiting the
- * fact that exceptions are expected to support pickling. If more builtin
- * exceptions (e.g. AttributeError) start to be converted to rich
- * exceptions with additional attributes, that's probably a better approach
- * to pursue over adding special cases for particular stateful subclasses.
- *
- * Returns a borrowed reference to the new exception (if any), NULL if the
- * existing exception was left in place.
- */
-PyObject *
-_PyErr_TrySetFromCause(const char *format, ...)
-{
- PyObject* msg_prefix;
- PyObject *instance_args;
- Py_ssize_t num_args, caught_type_size, base_exc_size;
- va_list vargs;
- int same_basic_size;
-
- PyObject *exc = PyErr_GetRaisedException();
- PyTypeObject *caught_type = Py_TYPE(exc);
- /* Ensure type info indicates no extra state is stored at the C level
- * and that the type can be reinstantiated using PyErr_Format
- */
- caught_type_size = caught_type->tp_basicsize;
- base_exc_size = _PyExc_BaseException.tp_basicsize;
- same_basic_size = (
- caught_type_size == base_exc_size ||
- (_PyType_SUPPORTS_WEAKREFS(caught_type) &&
- (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
- )
- );
- if (caught_type->tp_init != (initproc)BaseException_init ||
- caught_type->tp_new != BaseException_new ||
- !same_basic_size ||
- caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
- /* We can't be sure we can wrap this safely, since it may contain
- * more state than just the exception type. Accordingly, we just
- * leave it alone.
- */
- PyErr_SetRaisedException(exc);
- return NULL;
- }
-
- /* Check the args are empty or contain a single string */
- instance_args = ((PyBaseExceptionObject *)exc)->args;
- num_args = PyTuple_GET_SIZE(instance_args);
- if (num_args > 1 ||
- (num_args == 1 &&
- !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
- /* More than 1 arg, or the one arg we do have isn't a string
- */
- PyErr_SetRaisedException(exc);
- return NULL;
- }
-
- /* Ensure the instance dict is also empty */
- if (!_PyObject_IsInstanceDictEmpty(exc)) {
- /* While we could potentially copy a non-empty instance dictionary
- * to the replacement exception, for now we take the more
- * conservative path of leaving exceptions with attributes set
- * alone.
- */
- PyErr_SetRaisedException(exc);
- return NULL;
- }
-
- /* For exceptions that we can wrap safely, we chain the original
- * exception to a new one of the exact same type with an
- * error message that mentions the additional details and the
- * original exception.
- *
- * It would be nice to wrap OSError and various other exception
- * types as well, but that's quite a bit trickier due to the extra
- * state potentially stored on OSError instances.
- */
- va_start(vargs, format);
- msg_prefix = PyUnicode_FromFormatV(format, vargs);
- va_end(vargs);
- if (msg_prefix == NULL) {
- Py_DECREF(exc);
- return NULL;
- }
-
- PyErr_Format((PyObject*)Py_TYPE(exc), "%U (%s: %S)",
- msg_prefix, Py_TYPE(exc)->tp_name, exc);
- Py_DECREF(msg_prefix);
- PyObject *new_exc = PyErr_GetRaisedException();
- PyException_SetCause(new_exc, exc);
- PyErr_SetRaisedException(new_exc);
- return new_exc;
-}