blob: 38e523a802c096a7554e6dcd8f5bf05d44c597d0 [file] [log] [blame]
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001/*
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
Thomas Wouters477c8d52006-05-27 19:21:47 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
Victor Stinner331a6a52019-05-27 16:39:22 +02009#include "pycore_initconfig.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +010010#include "pycore_object.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020011#include "structmember.h" // PyMemberDef
Victor Stinner361dcdc2020-04-15 03:24:57 +020012#include "osdefs.h" // SEP
Thomas Wouters477c8d52006-05-27 19:21:47 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020015/* Compatibility aliases */
16PyObject *PyExc_EnvironmentError = NULL;
17PyObject *PyExc_IOError = NULL;
18#ifdef MS_WINDOWS
19PyObject *PyExc_WindowsError = NULL;
20#endif
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020021
Victor Stinner281cce12020-06-23 22:55:46 +020022
23static struct _Py_exc_state*
24get_exc_state(void)
25{
26 PyInterpreterState *interp = _PyInterpreterState_GET();
27 return &interp->exc_state;
28}
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020029
30
Thomas Wouters477c8d52006-05-27 19:21:47 +000031/* NOTE: If the exception class hierarchy changes, don't forget to update
32 * Lib/test/exception_hierarchy.txt
33 */
34
Thomas Wouters477c8d52006-05-27 19:21:47 +000035/*
36 * BaseException
37 */
38static PyObject *
39BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
40{
41 PyBaseExceptionObject *self;
42
43 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
Guido van Rossumd8faa362007-04-27 19:54:29 +000044 if (!self)
45 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000046 /* the dict is created on the fly in PyObject_GenericSetAttr */
Guido van Rossumebe3e162007-05-17 18:20:34 +000047 self->dict = NULL;
Collin Winter1966f1c2007-09-01 20:26:44 +000048 self->traceback = self->cause = self->context = NULL;
Benjamin Petersond5a1c442012-05-14 22:09:31 -070049 self->suppress_context = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +000050
Richard Oudkerk5562d9d2012-07-28 17:45:28 +010051 if (args) {
52 self->args = args;
53 Py_INCREF(args);
54 return (PyObject *)self;
55 }
56
Thomas Wouters477c8d52006-05-27 19:21:47 +000057 self->args = PyTuple_New(0);
58 if (!self->args) {
59 Py_DECREF(self);
60 return NULL;
61 }
62
Thomas Wouters477c8d52006-05-27 19:21:47 +000063 return (PyObject *)self;
64}
65
66static int
67BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
68{
Christian Heimes90aa7642007-12-19 02:45:37 +000069 if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000070 return -1;
71
Serhiy Storchaka576f1322016-01-05 21:27:54 +020072 Py_INCREF(args);
Serhiy Storchakaec397562016-04-06 09:50:03 +030073 Py_XSETREF(self->args, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000074
Thomas Wouters477c8d52006-05-27 19:21:47 +000075 return 0;
76}
77
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000078static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000079BaseException_clear(PyBaseExceptionObject *self)
80{
81 Py_CLEAR(self->dict);
82 Py_CLEAR(self->args);
Collin Winter828f04a2007-08-31 00:04:24 +000083 Py_CLEAR(self->traceback);
Collin Winter1966f1c2007-09-01 20:26:44 +000084 Py_CLEAR(self->cause);
85 Py_CLEAR(self->context);
Thomas Wouters477c8d52006-05-27 19:21:47 +000086 return 0;
87}
88
89static void
90BaseException_dealloc(PyBaseExceptionObject *self)
91{
Thomas Wouters89f507f2006-12-13 04:49:30 +000092 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000093 BaseException_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +000094 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000095}
96
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000097static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000098BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
99{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000100 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000101 Py_VISIT(self->args);
Collin Winter828f04a2007-08-31 00:04:24 +0000102 Py_VISIT(self->traceback);
Collin Winter1966f1c2007-09-01 20:26:44 +0000103 Py_VISIT(self->cause);
104 Py_VISIT(self->context);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000105 return 0;
106}
107
108static PyObject *
109BaseException_str(PyBaseExceptionObject *self)
110{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000111 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112 case 0:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000113 return PyUnicode_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 case 1:
Thomas Heller519a0422007-11-15 20:48:54 +0000115 return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000116 default:
Thomas Heller519a0422007-11-15 20:48:54 +0000117 return PyObject_Str(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000118 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000119}
120
121static PyObject *
122BaseException_repr(PyBaseExceptionObject *self)
123{
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +0300124 const char *name = _PyType_Name(Py_TYPE(self));
Serhiy Storchakaf8a4c032017-11-15 17:53:28 +0200125 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);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000130}
131
132/* Pickling support */
133static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530134BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000135{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000136 if (self->args && self->dict)
Christian Heimes90aa7642007-12-19 02:45:37 +0000137 return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000138 else
Christian Heimes90aa7642007-12-19 02:45:37 +0000139 return PyTuple_Pack(2, Py_TYPE(self), self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000140}
141
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000142/*
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 */
147static PyObject *
148BaseException_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}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000165
Collin Winter828f04a2007-08-31 00:04:24 +0000166static PyObject *
167BaseException_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
Georg Brandl76941002008-05-05 21:38:47 +0000175PyDoc_STRVAR(with_traceback_doc,
176"Exception.with_traceback(tb) --\n\
177 set self.__traceback__ to tb and return self.");
178
Thomas Wouters477c8d52006-05-27 19:21:47 +0000179
180static PyMethodDef BaseException_methods[] = {
181 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000182 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Georg Brandl76941002008-05-05 21:38:47 +0000183 {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
184 with_traceback_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000185 {NULL, NULL, 0, NULL},
186};
187
Thomas Wouters477c8d52006-05-27 19:21:47 +0000188static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200189BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000190{
191 if (self->args == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200192 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000193 }
194 Py_INCREF(self->args);
195 return self->args;
196}
197
198static int
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200199BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000200{
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);
Benjamin Peterson90b13582012-02-03 19:22:31 -0500207 if (!seq)
208 return -1;
Serhiy Storchaka48842712016-04-06 09:45:48 +0300209 Py_XSETREF(self->args, seq);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000210 return 0;
211}
212
Collin Winter828f04a2007-08-31 00:04:24 +0000213static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200214BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
Collin Winter828f04a2007-08-31 00:04:24 +0000215{
216 if (self->traceback == NULL) {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200217 Py_RETURN_NONE;
Collin Winter828f04a2007-08-31 00:04:24 +0000218 }
219 Py_INCREF(self->traceback);
220 return self->traceback;
221}
222
223static int
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200224BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
Collin Winter828f04a2007-08-31 00:04:24 +0000225{
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
Serhiy Storchaka37665722016-08-20 21:22:03 +0300236 Py_INCREF(tb);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300237 Py_XSETREF(self->traceback, tb);
Collin Winter828f04a2007-08-31 00:04:24 +0000238 return 0;
239}
240
Georg Brandlab6f2f62009-03-31 04:16:10 +0000241static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200242BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
243{
Georg Brandlab6f2f62009-03-31 04:16:10 +0000244 PyObject *res = PyException_GetContext(self);
Benjamin Peterson90b13582012-02-03 19:22:31 -0500245 if (res)
246 return res; /* new reference already returned above */
Georg Brandlab6f2f62009-03-31 04:16:10 +0000247 Py_RETURN_NONE;
248}
249
250static int
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200251BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
252{
Georg Brandlab6f2f62009-03-31 04:16:10 +0000253 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 }
Georg Brandlab6f2f62009-03-31 04:16:10 +0000266 PyException_SetContext(self, arg);
267 return 0;
268}
269
270static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200271BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
272{
Georg Brandlab6f2f62009-03-31 04:16:10 +0000273 PyObject *res = PyException_GetCause(self);
Benjamin Peterson90b13582012-02-03 19:22:31 -0500274 if (res)
275 return res; /* new reference already returned above */
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700276 Py_RETURN_NONE;
Georg Brandlab6f2f62009-03-31 04:16:10 +0000277}
278
279static int
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200280BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
281{
Georg Brandlab6f2f62009-03-31 04:16:10 +0000282 if (arg == NULL) {
283 PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
284 return -1;
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700285 } 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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 }
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700295 PyException_SetCause(self, arg);
296 return 0;
Georg Brandlab6f2f62009-03-31 04:16:10 +0000297}
298
Guido van Rossum360e4b82007-05-14 22:51:27 +0000299
Thomas Wouters477c8d52006-05-27 19:21:47 +0000300static PyGetSetDef BaseException_getset[] = {
Benjamin Peterson23d7f122012-02-19 20:02:57 -0500301 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000302 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
Collin Winter828f04a2007-08-31 00:04:24 +0000303 {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +0200304 {"__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")},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000308 {NULL},
309};
310
311
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200312static inline PyBaseExceptionObject*
313_PyBaseExceptionObject_cast(PyObject *exc)
314{
315 assert(PyExceptionInstance_Check(exc));
316 return (PyBaseExceptionObject *)exc;
317}
318
319
Collin Winter828f04a2007-08-31 00:04:24 +0000320PyObject *
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200321PyException_GetTraceback(PyObject *self)
322{
323 PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
Collin Winter828f04a2007-08-31 00:04:24 +0000324 Py_XINCREF(base_self->traceback);
325 return base_self->traceback;
326}
327
328
329int
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200330PyException_SetTraceback(PyObject *self, PyObject *tb)
331{
332 return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
Collin Winter828f04a2007-08-31 00:04:24 +0000333}
334
335PyObject *
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200336PyException_GetCause(PyObject *self)
337{
338 PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
Collin Winter828f04a2007-08-31 00:04:24 +0000339 Py_XINCREF(cause);
340 return cause;
341}
342
343/* Steals a reference to cause */
344void
Serhiy Storchaka576f1322016-01-05 21:27:54 +0200345PyException_SetCause(PyObject *self, PyObject *cause)
346{
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200347 PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
348 base_self->suppress_context = 1;
349 Py_XSETREF(base_self->cause, cause);
Collin Winter828f04a2007-08-31 00:04:24 +0000350}
351
352PyObject *
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200353PyException_GetContext(PyObject *self)
354{
355 PyObject *context = _PyBaseExceptionObject_cast(self)->context;
Collin Winter828f04a2007-08-31 00:04:24 +0000356 Py_XINCREF(context);
357 return context;
358}
359
360/* Steals a reference to context */
361void
Serhiy Storchaka576f1322016-01-05 21:27:54 +0200362PyException_SetContext(PyObject *self, PyObject *context)
363{
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200364 Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
Collin Winter828f04a2007-08-31 00:04:24 +0000365}
366
Serhiy Storchakaceeef102018-06-15 11:09:43 +0300367const char *
Christian Tismerea62ce72018-06-09 20:32:25 +0200368PyExceptionClass_Name(PyObject *ob)
369{
Victor Stinnerb0be6b32020-05-05 17:07:41 +0200370 assert(PyExceptionClass_Check(ob));
Serhiy Storchakaceeef102018-06-15 11:09:43 +0300371 return ((PyTypeObject*)ob)->tp_name;
Christian Tismerea62ce72018-06-09 20:32:25 +0200372}
Collin Winter828f04a2007-08-31 00:04:24 +0000373
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700374static struct PyMemberDef BaseException_members[] = {
375 {"__suppress_context__", T_BOOL,
Antoine Pitrou32bc80c2012-05-16 12:51:55 +0200376 offsetof(PyBaseExceptionObject, suppress_context)},
377 {NULL}
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700378};
379
380
Thomas Wouters477c8d52006-05-27 19:21:47 +0000381static PyTypeObject _PyExc_BaseException = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000382 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +0000383 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000384 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
385 0, /*tp_itemsize*/
386 (destructor)BaseException_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200387 0, /*tp_vectorcall_offset*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388 0, /*tp_getattr*/
389 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200390 0, /*tp_as_async*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000391 (reprfunc)BaseException_repr, /*tp_repr*/
392 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000393 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000394 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*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000401 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000403 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 */
Benjamin Petersond5a1c442012-05-14 22:09:31 -0700411 BaseException_members, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000412 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
Min ho Kimc4cacc82019-07-31 08:16:13 +1000423from the previous implementation and also allowing Python objects to be used
Thomas Wouters477c8d52006-05-27 19:21:47 +0000424in the API */
425PyObject *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) \
431static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000432 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000433 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434 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}; \
443PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
444
445#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
446static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000447 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000448 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000450 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000451 0, 0, 0, 0, 0, \
452 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000453 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
454 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000455 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200456 (initproc)EXCSTORE ## _init, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457}; \
458PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
459
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200460#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
461 EXCMETHODS, EXCMEMBERS, EXCGETSET, \
462 EXCSTR, EXCDOC) \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000463static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000464 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000465 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000466 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, \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200472 EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000473 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200474 (initproc)EXCSTORE ## _init, 0, EXCNEW,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000475}; \
476PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
477
478
479/*
480 * Exception extends BaseException
481 */
482SimpleExtendsException(PyExc_BaseException, Exception,
483 "Common base class for all non-exit exceptions.");
484
485
486/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000487 * TypeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000489SimpleExtendsException(PyExc_Exception, TypeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000490 "Inappropriate argument type.");
491
492
493/*
Yury Selivanov75445082015-05-11 22:57:16 -0400494 * StopAsyncIteration extends Exception
495 */
496SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
497 "Signal the end from iterator.__anext__().");
498
499
500/*
Thomas Wouters477c8d52006-05-27 19:21:47 +0000501 * StopIteration extends Exception
502 */
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000503
504static PyMemberDef StopIteration_members[] = {
505 {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
506 PyDoc_STR("generator return value")},
507 {NULL} /* Sentinel */
508};
509
510static int
511StopIteration_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
528static int
529StopIteration_clear(PyStopIterationObject *self)
530{
531 Py_CLEAR(self->value);
532 return BaseException_clear((PyBaseExceptionObject *)self);
533}
534
535static void
536StopIteration_dealloc(PyStopIterationObject *self)
537{
538 _PyObject_GC_UNTRACK(self);
539 StopIteration_clear(self);
540 Py_TYPE(self)->tp_free((PyObject *)self);
541}
542
543static int
544StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
545{
546 Py_VISIT(self->value);
547 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
548}
549
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000550ComplexExtendsException(
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);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000561
562
563/*
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000564 * GeneratorExit extends BaseException
Thomas Wouters477c8d52006-05-27 19:21:47 +0000565 */
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000566SimpleExtendsException(PyExc_BaseException, GeneratorExit,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000567 "Request that a generator exit.");
568
569
570/*
571 * SystemExit extends BaseException
572 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000573
574static int
575SystemExit_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
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000582 if (size == 0)
583 return 0;
Serhiy Storchaka191321d2015-12-27 15:41:34 +0200584 if (size == 1) {
585 Py_INCREF(PyTuple_GET_ITEM(args, 0));
Serhiy Storchaka48842712016-04-06 09:45:48 +0300586 Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
Serhiy Storchaka191321d2015-12-27 15:41:34 +0200587 }
588 else { /* size > 1 */
589 Py_INCREF(args);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300590 Py_XSETREF(self->code, args);
Serhiy Storchaka191321d2015-12-27 15:41:34 +0200591 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000592 return 0;
593}
594
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000595static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000596SystemExit_clear(PySystemExitObject *self)
597{
598 Py_CLEAR(self->code);
599 return BaseException_clear((PyBaseExceptionObject *)self);
600}
601
602static void
603SystemExit_dealloc(PySystemExitObject *self)
604{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000605 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000606 SystemExit_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000607 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608}
609
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000610static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
612{
613 Py_VISIT(self->code);
614 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
615}
616
617static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000618 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
619 PyDoc_STR("exception code")},
620 {NULL} /* Sentinel */
621};
622
623ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200624 0, 0, SystemExit_members, 0, 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625 "Request to exit from the interpreter.");
626
627/*
628 * KeyboardInterrupt extends BaseException
629 */
630SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
631 "Program interrupted by user.");
632
633
634/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000635 * ImportError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000636 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637
Brett Cannon79ec55e2012-04-12 20:24:54 -0400638static int
639ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
640{
Serhiy Storchaka47dee112016-09-27 20:45:35 +0300641 static char *kwlist[] = {"name", "path", 0};
642 PyObject *empty_tuple;
Brett Cannon79ec55e2012-04-12 20:24:54 -0400643 PyObject *msg = NULL;
644 PyObject *name = NULL;
645 PyObject *path = NULL;
646
Serhiy Storchaka47dee112016-09-27 20:45:35 +0300647 if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1)
Brett Cannon79ec55e2012-04-12 20:24:54 -0400648 return -1;
649
Serhiy Storchaka47dee112016-09-27 20:45:35 +0300650 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
Serhiy Storchakae9e44482016-09-28 07:53:32 +0300660 Py_XINCREF(name);
661 Py_XSETREF(self->name, name);
662
663 Py_XINCREF(path);
664 Py_XSETREF(self->path, path);
665
Serhiy Storchaka47dee112016-09-27 20:45:35 +0300666 if (PyTuple_GET_SIZE(args) == 1) {
667 msg = PyTuple_GET_ITEM(args, 0);
668 Py_INCREF(msg);
Serhiy Storchaka47dee112016-09-27 20:45:35 +0300669 }
Serhiy Storchakae9e44482016-09-28 07:53:32 +0300670 Py_XSETREF(self->msg, msg);
Brett Cannon79ec55e2012-04-12 20:24:54 -0400671
672 return 0;
673}
674
675static int
676ImportError_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
684static void
685ImportError_dealloc(PyImportErrorObject *self)
686{
687 _PyObject_GC_UNTRACK(self);
688 ImportError_clear(self);
689 Py_TYPE(self)->tp_free((PyObject *)self);
690}
691
692static int
693ImportError_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
701static PyObject *
702ImportError_str(PyImportErrorObject *self)
703{
Brett Cannon07c6e712012-08-24 13:05:09 -0400704 if (self->msg && PyUnicode_CheckExact(self->msg)) {
Brett Cannon79ec55e2012-04-12 20:24:54 -0400705 Py_INCREF(self->msg);
706 return self->msg;
707 }
708 else {
709 return BaseException_str((PyBaseExceptionObject *)self);
710 }
711}
712
Serhiy Storchakab7853962017-04-08 09:55:07 +0300713static PyObject *
714ImportError_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 */
743static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530744ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored))
Serhiy Storchakab7853962017-04-08 09:55:07 +0300745{
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
Brett Cannon79ec55e2012-04-12 20:24:54 -0400760static 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
770static PyMethodDef ImportError_methods[] = {
Serhiy Storchakab7853962017-04-08 09:55:07 +0300771 {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
Brett Cannon79ec55e2012-04-12 20:24:54 -0400772 {NULL}
773};
774
775ComplexExtendsException(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.");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000781
782/*
Eric Snowc9432652016-09-07 15:42:32 -0700783 * ModuleNotFoundError extends ImportError
784 */
785
786MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
787 "Module not found.");
788
789/*
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200790 * OSError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791 */
792
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200793#ifdef MS_WINDOWS
794#include "errmap.h"
795#endif
796
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797/* 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 *
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200802 * except OSError, (errno, strerror):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 *
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.
Larry Hastingsb0827312014-02-09 22:05:19 -0800807 *
808 * (If a function has two filenames, such as rename(), symlink(),
Larry Hastings8f9f0f12014-02-10 03:43:57 -0800809 * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
810 * which allows passing in a second filename.)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000811 */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200812
Antoine Pitroue0e27352011-12-15 14:31:28 +0100813/* This function doesn't cleanup on error, the caller should */
814static int
815oserror_parse_args(PyObject **p_args,
816 PyObject **myerrno, PyObject **strerror,
Larry Hastingsb0827312014-02-09 22:05:19 -0800817 PyObject **filename, PyObject **filename2
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200818#ifdef MS_WINDOWS
Antoine Pitroue0e27352011-12-15 14:31:28 +0100819 , PyObject **winerror
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200820#endif
Antoine Pitroue0e27352011-12-15 14:31:28 +0100821 )
822{
823 Py_ssize_t nargs;
824 PyObject *args = *p_args;
Larry Hastingsb0827312014-02-09 22:05:19 -0800825#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 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000833
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200834 nargs = PyTuple_GET_SIZE(args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835
Larry Hastingsb0827312014-02-09 22:05:19 -0800836 if (nargs >= 2 && nargs <= 5) {
837 if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
838 myerrno, strerror,
839 filename, winerror, filename2))
Antoine Pitroue0e27352011-12-15 14:31:28 +0100840 return -1;
Larry Hastingsb0827312014-02-09 22:05:19 -0800841#ifdef MS_WINDOWS
Antoine Pitroue0e27352011-12-15 14:31:28 +0100842 if (*winerror && PyLong_Check(*winerror)) {
843 long errcode, winerrcode;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200844 PyObject *newargs;
845 Py_ssize_t i;
846
Antoine Pitroue0e27352011-12-15 14:31:28 +0100847 winerrcode = PyLong_AsLong(*winerror);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200848 if (winerrcode == -1 && PyErr_Occurred())
Antoine Pitroue0e27352011-12-15 14:31:28 +0100849 return -1;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200850 /* 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;
Antoine Pitroue0e27352011-12-15 14:31:28 +0100858 *myerrno = PyLong_FromLong(errcode);
859 if (!*myerrno)
860 return -1;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200861 newargs = PyTuple_New(nargs);
862 if (!newargs)
Antoine Pitroue0e27352011-12-15 14:31:28 +0100863 return -1;
864 PyTuple_SET_ITEM(newargs, 0, *myerrno);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200865 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);
Antoine Pitroue0e27352011-12-15 14:31:28 +0100871 args = *p_args = newargs;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200872 }
Larry Hastingsb0827312014-02-09 22:05:19 -0800873#endif /* MS_WINDOWS */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200874 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000875
Antoine Pitroue0e27352011-12-15 14:31:28 +0100876 return 0;
877}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000878
Antoine Pitroue0e27352011-12-15 14:31:28 +0100879static int
880oserror_init(PyOSErrorObject *self, PyObject **p_args,
881 PyObject *myerrno, PyObject *strerror,
Larry Hastingsb0827312014-02-09 22:05:19 -0800882 PyObject *filename, PyObject *filename2
Antoine Pitroue0e27352011-12-15 14:31:28 +0100883#ifdef MS_WINDOWS
884 , PyObject *winerror
885#endif
886 )
887{
888 PyObject *args = *p_args;
889 Py_ssize_t nargs = PyTuple_GET_SIZE(args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000890
891 /* self->filename will remain Py_None otherwise */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200892 if (filename && filename != Py_None) {
Andy Lesterdffe4c02020-03-04 07:15:20 -0600893 if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200894 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())
Antoine Pitroue0e27352011-12-15 14:31:28 +0100900 return -1;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200901 }
902 else {
903 Py_INCREF(filename);
904 self->filename = filename;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905
Larry Hastingsb0827312014-02-09 22:05:19 -0800906 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) */
Antoine Pitroue0e27352011-12-15 14:31:28 +0100914 PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200915 if (!subslice)
Antoine Pitroue0e27352011-12-15 14:31:28 +0100916 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000917
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200918 Py_DECREF(args); /* replacing args */
Antoine Pitroue0e27352011-12-15 14:31:28 +0100919 *p_args = args = subslice;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200920 }
921 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200923 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
Antoine Pitroue0e27352011-12-15 14:31:28 +0100934 /* Steals the reference to args */
Serhiy Storchaka48842712016-04-06 09:45:48 +0300935 Py_XSETREF(self->args, args);
Victor Stinner46ef3192013-11-14 22:31:41 +0100936 *p_args = args = NULL;
Antoine Pitroue0e27352011-12-15 14:31:28 +0100937
938 return 0;
939}
940
941static PyObject *
942OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
943static int
944OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds);
945
946static int
947oserror_use_init(PyTypeObject *type)
948{
Martin Panter7462b6492015-11-02 03:37:02 +0000949 /* When __init__ is defined in an OSError subclass, we want any
Antoine Pitroue0e27352011-12-15 14:31:28 +0100950 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
Martin Pantere26da7c2016-06-02 10:07:09 +0000954 But when __new__ is overridden as well, it should call our __new__
Antoine Pitroue0e27352011-12-15 14:31:28 +0100955 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
967static PyObject *
968OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
969{
970 PyOSErrorObject *self = NULL;
Larry Hastingsb0827312014-02-09 22:05:19 -0800971 PyObject *myerrno = NULL, *strerror = NULL;
972 PyObject *filename = NULL, *filename2 = NULL;
Antoine Pitroue0e27352011-12-15 14:31:28 +0100973#ifdef MS_WINDOWS
974 PyObject *winerror = NULL;
975#endif
976
Victor Stinner46ef3192013-11-14 22:31:41 +0100977 Py_INCREF(args);
978
Antoine Pitroue0e27352011-12-15 14:31:28 +0100979 if (!oserror_use_init(type)) {
980 if (!_PyArg_NoKeywords(type->tp_name, kwds))
Victor Stinner46ef3192013-11-14 22:31:41 +0100981 goto error;
Antoine Pitroue0e27352011-12-15 14:31:28 +0100982
Larry Hastingsb0827312014-02-09 22:05:19 -0800983 if (oserror_parse_args(&args, &myerrno, &strerror,
984 &filename, &filename2
Antoine Pitroue0e27352011-12-15 14:31:28 +0100985#ifdef MS_WINDOWS
986 , &winerror
987#endif
988 ))
989 goto error;
990
Victor Stinner281cce12020-06-23 22:55:46 +0200991 struct _Py_exc_state *state = get_exc_state();
Antoine Pitroue0e27352011-12-15 14:31:28 +0100992 if (myerrno && PyLong_Check(myerrno) &&
Victor Stinner281cce12020-06-23 22:55:46 +0200993 state->errnomap && (PyObject *) type == PyExc_OSError) {
Antoine Pitroue0e27352011-12-15 14:31:28 +0100994 PyObject *newtype;
Victor Stinner281cce12020-06-23 22:55:46 +0200995 newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
Antoine Pitroue0e27352011-12-15 14:31:28 +0100996 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)) {
Larry Hastingsb0827312014-02-09 22:05:19 -08001014 if (oserror_init(self, &args, myerrno, strerror, filename, filename2
Antoine Pitroue0e27352011-12-15 14:31:28 +01001015#ifdef MS_WINDOWS
1016 , winerror
1017#endif
1018 ))
1019 goto error;
1020 }
Antoine Pitrouf87289b2012-06-30 23:37:47 +02001021 else {
1022 self->args = PyTuple_New(0);
1023 if (self->args == NULL)
1024 goto error;
1025 }
Antoine Pitroue0e27352011-12-15 14:31:28 +01001026
Victor Stinner46ef3192013-11-14 22:31:41 +01001027 Py_XDECREF(args);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001028 return (PyObject *) self;
1029
1030error:
1031 Py_XDECREF(args);
1032 Py_XDECREF(self);
1033 return NULL;
1034}
1035
1036static int
Antoine Pitroue0e27352011-12-15 14:31:28 +01001037OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds)
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001038{
Larry Hastingsb0827312014-02-09 22:05:19 -08001039 PyObject *myerrno = NULL, *strerror = NULL;
1040 PyObject *filename = NULL, *filename2 = NULL;
Antoine Pitroue0e27352011-12-15 14:31:28 +01001041#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);
Larry Hastingsb0827312014-02-09 22:05:19 -08001053 if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
Antoine Pitroue0e27352011-12-15 14:31:28 +01001054#ifdef MS_WINDOWS
1055 , &winerror
1056#endif
1057 ))
1058 goto error;
1059
Larry Hastingsb0827312014-02-09 22:05:19 -08001060 if (oserror_init(self, &args, myerrno, strerror, filename, filename2
Antoine Pitroue0e27352011-12-15 14:31:28 +01001061#ifdef MS_WINDOWS
1062 , winerror
1063#endif
1064 ))
1065 goto error;
1066
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067 return 0;
Antoine Pitroue0e27352011-12-15 14:31:28 +01001068
1069error:
Serhiy Storchaka37665722016-08-20 21:22:03 +03001070 Py_DECREF(args);
Antoine Pitroue0e27352011-12-15 14:31:28 +01001071 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001072}
1073
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001074static int
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001075OSError_clear(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001076{
1077 Py_CLEAR(self->myerrno);
1078 Py_CLEAR(self->strerror);
1079 Py_CLEAR(self->filename);
Larry Hastingsb0827312014-02-09 22:05:19 -08001080 Py_CLEAR(self->filename2);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001081#ifdef MS_WINDOWS
1082 Py_CLEAR(self->winerror);
1083#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001084 return BaseException_clear((PyBaseExceptionObject *)self);
1085}
1086
1087static void
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001088OSError_dealloc(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001090 _PyObject_GC_UNTRACK(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001091 OSError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001092 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001093}
1094
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001095static int
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001096OSError_traverse(PyOSErrorObject *self, visitproc visit,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097 void *arg)
1098{
1099 Py_VISIT(self->myerrno);
1100 Py_VISIT(self->strerror);
1101 Py_VISIT(self->filename);
Larry Hastingsb0827312014-02-09 22:05:19 -08001102 Py_VISIT(self->filename2);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001103#ifdef MS_WINDOWS
1104 Py_VISIT(self->winerror);
1105#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001106 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1107}
1108
1109static PyObject *
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001110OSError_str(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001111{
Larry Hastingsb0827312014-02-09 22:05:19 -08001112#define OR_NONE(x) ((x)?(x):Py_None)
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001113#ifdef MS_WINDOWS
1114 /* If available, winerror has the priority over myerrno */
Larry Hastingsb0827312014-02-09 22:05:19 -08001115 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 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001129 if (self->winerror && self->strerror)
Richard Oudkerk30147712012-08-28 19:33:26 +01001130 return PyUnicode_FromFormat("[WinError %S] %S",
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001131 self->winerror ? self->winerror: Py_None,
1132 self->strerror ? self->strerror: Py_None);
1133#endif
Larry Hastingsb0827312014-02-09 22:05:19 -08001134 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 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001148 if (self->myerrno && self->strerror)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001149 return PyUnicode_FromFormat("[Errno %S] %S",
Serhiy Storchaka37665722016-08-20 21:22:03 +03001150 self->myerrno, self->strerror);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001151 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001152}
1153
Thomas Wouters477c8d52006-05-27 19:21:47 +00001154static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301155OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156{
1157 PyObject *args = self->args;
1158 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001159
Thomas Wouters477c8d52006-05-27 19:21:47 +00001160 /* self->args is only the first two real arguments if there was a
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001161 * file name given to OSError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001162 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Larry Hastingsb0827312014-02-09 22:05:19 -08001163 Py_ssize_t size = self->filename2 ? 5 : 3;
1164 args = PyTuple_New(size);
Benjamin Peterson90b13582012-02-03 19:22:31 -05001165 if (!args)
1166 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001167
1168 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169 Py_INCREF(tmp);
1170 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001171
1172 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001173 Py_INCREF(tmp);
1174 PyTuple_SET_ITEM(args, 1, tmp);
1175
1176 Py_INCREF(self->filename);
1177 PyTuple_SET_ITEM(args, 2, self->filename);
Larry Hastingsb0827312014-02-09 22:05:19 -08001178
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 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001192 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001194
1195 if (self->dict)
Christian Heimes90aa7642007-12-19 02:45:37 +00001196 res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001197 else
Christian Heimes90aa7642007-12-19 02:45:37 +00001198 res = PyTuple_Pack(2, Py_TYPE(self), args);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001199 Py_DECREF(args);
1200 return res;
1201}
1202
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001203static PyObject *
1204OSError_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}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001212
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001213static int
1214OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
1215{
Serhiy Storchakae2af34f2018-12-17 16:43:14 +02001216 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 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001224 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
1232static 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")},
Larry Hastingsb0827312014-02-09 22:05:19 -08001239 {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
1240 PyDoc_STR("second exception filename")},
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001241#ifdef MS_WINDOWS
1242 {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
1243 PyDoc_STR("Win32 exception code")},
1244#endif
1245 {NULL} /* Sentinel */
1246};
1247
1248static PyMethodDef OSError_methods[] = {
1249 {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250 {NULL}
1251};
1252
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001253static PyGetSetDef OSError_getset[] = {
1254 {"characters_written", (getter) OSError_written_get,
1255 (setter) OSError_written_set, NULL},
1256 {NULL}
1257};
1258
1259
1260ComplexExtendsException(PyExc_Exception, OSError,
1261 OSError, OSError_new,
1262 OSError_methods, OSError_members, OSError_getset,
1263 OSError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001264 "Base class for I/O related errors.");
1265
1266
1267/*
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001268 * Various OSError subclasses
Thomas Wouters477c8d52006-05-27 19:21:47 +00001269 */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001270MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
1271 "I/O operation would block.");
1272MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
1273 "Connection error.");
1274MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
1275 "Child process error.");
1276MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
1277 "Broken pipe.");
1278MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
1279 "Connection aborted.");
1280MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
1281 "Connection refused.");
1282MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
1283 "Connection reset.");
1284MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
1285 "File already exists.");
1286MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
1287 "File not found.");
1288MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
1289 "Operation doesn't work on directories.");
1290MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
1291 "Operation only works on directories.");
1292MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
1293 "Interrupted by signal.");
1294MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
1295 "Not enough permissions.");
1296MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
1297 "Process not found.");
1298MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
1299 "Timeout expired.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001300
1301/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001302 * EOFError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001303 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001304SimpleExtendsException(PyExc_Exception, EOFError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001305 "Read beyond end of file.");
1306
1307
1308/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001309 * RuntimeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001310 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001311SimpleExtendsException(PyExc_Exception, RuntimeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001312 "Unspecified run-time error.");
1313
Yury Selivanovf488fb42015-07-03 01:04:23 -04001314/*
1315 * RecursionError extends RuntimeError
1316 */
1317SimpleExtendsException(PyExc_RuntimeError, RecursionError,
1318 "Recursion limit exceeded.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001319
1320/*
1321 * NotImplementedError extends RuntimeError
1322 */
1323SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
1324 "Method or function hasn't been implemented yet.");
1325
1326/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001327 * NameError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328 */
Pablo Galindo5bf8bf22021-04-14 15:10:33 +01001329
1330static int
1331NameError_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
1357static int
1358NameError_clear(PyNameErrorObject *self)
1359{
1360 Py_CLEAR(self->name);
1361 return BaseException_clear((PyBaseExceptionObject *)self);
1362}
1363
1364static void
1365NameError_dealloc(PyNameErrorObject *self)
1366{
1367 _PyObject_GC_UNTRACK(self);
1368 NameError_clear(self);
1369 Py_TYPE(self)->tp_free((PyObject *)self);
1370}
1371
1372static int
1373NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg)
1374{
1375 Py_VISIT(self->name);
1376 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1377}
1378
1379static PyMemberDef NameError_members[] = {
1380 {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
1381 {NULL} /* Sentinel */
1382};
1383
1384static PyMethodDef NameError_methods[] = {
1385 {NULL} /* Sentinel */
1386};
1387
1388ComplexExtendsException(PyExc_Exception, NameError,
1389 NameError, 0,
1390 NameError_methods, NameError_members,
1391 0, BaseException_str, "Name not found globally.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392
1393/*
1394 * UnboundLocalError extends NameError
1395 */
Pablo Galindo3b82cae2021-04-16 16:38:55 +01001396
1397MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398 "Local name referenced but not bound to a value.");
1399
1400/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001401 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403
Pablo Galindo37494b42021-04-14 02:36:07 +01001404static int
1405AttributeError_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
1435static int
1436AttributeError_clear(PyAttributeErrorObject *self)
1437{
1438 Py_CLEAR(self->obj);
1439 Py_CLEAR(self->name);
1440 return BaseException_clear((PyBaseExceptionObject *)self);
1441}
1442
1443static void
1444AttributeError_dealloc(PyAttributeErrorObject *self)
1445{
1446 _PyObject_GC_UNTRACK(self);
1447 AttributeError_clear(self);
1448 Py_TYPE(self)->tp_free((PyObject *)self);
1449}
1450
1451static int
1452AttributeError_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
1459static 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
1465static PyMethodDef AttributeError_methods[] = {
1466 {NULL} /* Sentinel */
1467};
1468
1469ComplexExtendsException(PyExc_Exception, AttributeError,
1470 AttributeError, 0,
1471 AttributeError_methods, AttributeError_members,
1472 0, BaseException_str, "Attribute not found.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001473
1474/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001475 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001476 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477
1478static int
1479SyntaxError_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) {
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001488 Py_INCREF(PyTuple_GET_ITEM(args, 0));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001489 Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490 }
1491 if (lenargs == 2) {
1492 info = PyTuple_GET_ITEM(args, 1);
1493 info = PySequence_Tuple(info);
Pablo Galindoa77aac42021-04-23 14:27:05 +01001494 if (!info) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001495 return -1;
1496 }
1497
Pablo Galindoa77aac42021-04-23 14:27:05 +01001498 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 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001507
Pablo Galindoa77aac42021-04-23 14:27:05 +01001508 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);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001514 Py_DECREF(info);
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10001515
Pablo Galindoa77aac42021-04-23 14:27:05 +01001516 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 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520 }
1521 return 0;
1522}
1523
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001524static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001525SyntaxError_clear(PySyntaxErrorObject *self)
1526{
1527 Py_CLEAR(self->msg);
1528 Py_CLEAR(self->filename);
1529 Py_CLEAR(self->lineno);
1530 Py_CLEAR(self->offset);
Pablo Galindoa77aac42021-04-23 14:27:05 +01001531 Py_CLEAR(self->end_lineno);
1532 Py_CLEAR(self->end_offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533 Py_CLEAR(self->text);
1534 Py_CLEAR(self->print_file_and_line);
1535 return BaseException_clear((PyBaseExceptionObject *)self);
1536}
1537
1538static void
1539SyntaxError_dealloc(PySyntaxErrorObject *self)
1540{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001541 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 SyntaxError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001543 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544}
1545
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001546static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547SyntaxError_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);
Pablo Galindoa77aac42021-04-23 14:27:05 +01001553 Py_VISIT(self->end_lineno);
1554 Py_VISIT(self->end_offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555 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. */
Victor Stinner6237daf2010-04-28 17:26:19 +00001563static PyObject*
1564my_basename(PyObject *name)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565{
Victor Stinner6237daf2010-04-28 17:26:19 +00001566 Py_ssize_t i, size, offset;
Victor Stinner31392e72011-10-05 20:14:23 +02001567 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +03001568 const void *data;
Victor Stinner31392e72011-10-05 20:14:23 +02001569
1570 if (PyUnicode_READY(name))
1571 return NULL;
1572 kind = PyUnicode_KIND(name);
1573 data = PyUnicode_DATA(name);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001574 size = PyUnicode_GET_LENGTH(name);
Victor Stinner6237daf2010-04-28 17:26:19 +00001575 offset = 0;
1576 for(i=0; i < size; i++) {
Victor Stinner361dcdc2020-04-15 03:24:57 +02001577 if (PyUnicode_READ(kind, data, i) == SEP) {
Victor Stinner6237daf2010-04-28 17:26:19 +00001578 offset = i + 1;
Victor Stinner361dcdc2020-04-15 03:24:57 +02001579 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001580 }
Victor Stinner361dcdc2020-04-15 03:24:57 +02001581 if (offset != 0) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001582 return PyUnicode_Substring(name, offset, size);
Victor Stinner361dcdc2020-04-15 03:24:57 +02001583 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001584 else {
Victor Stinner6237daf2010-04-28 17:26:19 +00001585 Py_INCREF(name);
1586 return name;
1587 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001588}
1589
1590
1591static PyObject *
1592SyntaxError_str(PySyntaxErrorObject *self)
1593{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001594 int have_lineno = 0;
Victor Stinner6237daf2010-04-28 17:26:19 +00001595 PyObject *filename;
1596 PyObject *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001597 /* 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;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601
1602 /* XXX -- do all the additional formatting with filename and
1603 lineno here */
1604
Neal Norwitzed2b7392007-08-26 04:51:10 +00001605 if (self->filename && PyUnicode_Check(self->filename)) {
Victor Stinner6237daf2010-04-28 17:26:19 +00001606 filename = my_basename(self->filename);
1607 if (filename == NULL)
1608 return NULL;
1609 } else {
1610 filename = NULL;
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001611 }
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001612 have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001613
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001614 if (!filename && !have_lineno)
Thomas Heller519a0422007-11-15 20:48:54 +00001615 return PyObject_Str(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001617 if (filename && have_lineno)
Victor Stinner6237daf2010-04-28 17:26:19 +00001618 result = PyUnicode_FromFormat("%S (%U, line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001619 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001620 filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001622 else if (filename)
Victor Stinner6237daf2010-04-28 17:26:19 +00001623 result = PyUnicode_FromFormat("%S (%U)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001624 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001625 filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001626 else /* only have_lineno */
Victor Stinner6237daf2010-04-28 17:26:19 +00001627 result = PyUnicode_FromFormat("%S (line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001628 self->msg ? self->msg : Py_None,
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001629 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Victor Stinner6237daf2010-04-28 17:26:19 +00001630 Py_XDECREF(filename);
1631 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001632}
1633
1634static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635 {"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")},
Pablo Galindoa77aac42021-04-23 14:27:05 +01001645 {"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")},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 {"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
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001655ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001656 0, 0, SyntaxError_members, 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 SyntaxError_str, "Invalid syntax.");
1658
1659
1660/*
1661 * IndentationError extends SyntaxError
1662 */
1663MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1664 "Improper indentation.");
1665
1666
1667/*
1668 * TabError extends IndentationError
1669 */
1670MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1671 "Improper mixture of spaces and tabs.");
1672
1673
1674/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001675 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001676 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001677SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 "Base class for lookup errors.");
1679
1680
1681/*
1682 * IndexError extends LookupError
1683 */
1684SimpleExtendsException(PyExc_LookupError, IndexError,
1685 "Sequence index out of range.");
1686
1687
1688/*
1689 * KeyError extends LookupError
1690 */
1691static PyObject *
1692KeyError_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 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001703 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001704 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705 }
1706 return BaseException_str(self);
1707}
1708
1709ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001710 0, 0, 0, 0, KeyError_str, "Mapping key not found.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001711
1712
1713/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001714 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001716SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717 "Inappropriate argument value (of correct type).");
1718
1719/*
1720 * UnicodeError extends ValueError
1721 */
1722
1723SimpleExtendsException(PyExc_ValueError, UnicodeError,
1724 "Unicode related error.");
1725
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001727get_string(PyObject *attr, const char *name)
Walter Dörwald612344f2007-05-04 19:28:21 +00001728{
1729 if (!attr) {
1730 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1731 return NULL;
1732 }
1733
Christian Heimes72b710a2008-05-26 13:28:38 +00001734 if (!PyBytes_Check(attr)) {
Walter Dörwald612344f2007-05-04 19:28:21 +00001735 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1736 return NULL;
1737 }
1738 Py_INCREF(attr);
1739 return attr;
1740}
1741
1742static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001743get_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
Walter Dörwaldd2034312007-05-18 16:29:38 +00001759static int
1760set_unicodefromstring(PyObject **attr, const char *value)
1761{
1762 PyObject *obj = PyUnicode_FromString(value);
1763 if (!obj)
1764 return -1;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001765 Py_XSETREF(*attr, obj);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001766 return 0;
1767}
1768
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769PyObject *
1770PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1771{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001772 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001773}
1774
1775PyObject *
1776PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1777{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001778 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779}
1780
1781PyObject *
1782PyUnicodeEncodeError_GetObject(PyObject *exc)
1783{
1784 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1785}
1786
1787PyObject *
1788PyUnicodeDecodeError_GetObject(PyObject *exc)
1789{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001790 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001791}
1792
1793PyObject *
1794PyUnicodeTranslateError_GetObject(PyObject *exc)
1795{
1796 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1797}
1798
1799int
1800PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1801{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001802 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;
Victor Stinner9e30aa52011-11-21 02:49:52 +01001808 size = PyUnicode_GET_LENGTH(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001809 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;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001815}
1816
1817
1818int
1819PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1820{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001821 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001822 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001823 if (!obj)
1824 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001825 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001826 *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;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001833}
1834
1835
1836int
1837PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1838{
1839 return PyUnicodeEncodeError_GetStart(exc, start);
1840}
1841
1842
1843int
1844PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1845{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001846 ((PyUnicodeErrorObject *)exc)->start = start;
1847 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001848}
1849
1850
1851int
1852PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1853{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001854 ((PyUnicodeErrorObject *)exc)->start = start;
1855 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001856}
1857
1858
1859int
1860PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1861{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001862 ((PyUnicodeErrorObject *)exc)->start = start;
1863 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001864}
1865
1866
1867int
1868PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1869{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001870 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;
Victor Stinner9e30aa52011-11-21 02:49:52 +01001876 size = PyUnicode_GET_LENGTH(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001877 if (*end<1)
1878 *end = 1;
1879 if (*end>size)
1880 *end = size;
1881 Py_DECREF(obj);
1882 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883}
1884
1885
1886int
1887PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1888{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001889 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001890 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001891 if (!obj)
1892 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001893 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001894 *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;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001901}
1902
1903
1904int
Max Bernsteine6a0e802019-04-02 01:16:22 -07001905PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001906{
Max Bernsteine6a0e802019-04-02 01:16:22 -07001907 return PyUnicodeEncodeError_GetEnd(exc, end);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001908}
1909
1910
1911int
1912PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1913{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001914 ((PyUnicodeErrorObject *)exc)->end = end;
1915 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001916}
1917
1918
1919int
1920PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1921{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001922 ((PyUnicodeErrorObject *)exc)->end = end;
1923 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001924}
1925
1926
1927int
1928PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1929{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001930 ((PyUnicodeErrorObject *)exc)->end = end;
1931 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001932}
1933
1934PyObject *
1935PyUnicodeEncodeError_GetReason(PyObject *exc)
1936{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001937 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001938}
1939
1940
1941PyObject *
1942PyUnicodeDecodeError_GetReason(PyObject *exc)
1943{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001944 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001945}
1946
1947
1948PyObject *
1949PyUnicodeTranslateError_GetReason(PyObject *exc)
1950{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001951 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001952}
1953
1954
1955int
1956PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1957{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001958 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1959 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001960}
1961
1962
1963int
1964PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1965{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001966 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1967 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001968}
1969
1970
1971int
1972PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1973{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001974 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1975 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001976}
1977
1978
Thomas Wouters477c8d52006-05-27 19:21:47 +00001979static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001980UnicodeError_clear(PyUnicodeErrorObject *self)
1981{
1982 Py_CLEAR(self->encoding);
1983 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984 Py_CLEAR(self->reason);
1985 return BaseException_clear((PyBaseExceptionObject *)self);
1986}
1987
1988static void
1989UnicodeError_dealloc(PyUnicodeErrorObject *self)
1990{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001991 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992 UnicodeError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001993 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994}
1995
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001996static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1998{
1999 Py_VISIT(self->encoding);
2000 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002001 Py_VISIT(self->reason);
2002 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2003}
2004
2005static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002006 {"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")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002010 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002011 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002012 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002013 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 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023
2024static int
2025UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2026{
Guido van Rossum98297ee2007-11-06 21:34:58 +00002027 PyUnicodeErrorObject *err;
2028
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2030 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00002031
2032 err = (PyUnicodeErrorObject *)self;
2033
2034 Py_CLEAR(err->encoding);
2035 Py_CLEAR(err->object);
2036 Py_CLEAR(err->reason);
2037
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03002038 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;
Martin v. Löwisb09af032011-11-04 11:16:41 +01002042 return -1;
2043 }
2044
Guido van Rossum98297ee2007-11-06 21:34:58 +00002045 Py_INCREF(err->encoding);
2046 Py_INCREF(err->object);
2047 Py_INCREF(err->reason);
2048
2049 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002050}
2051
2052static PyObject *
2053UnicodeEncodeError_str(PyObject *self)
2054{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002055 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00002056 PyObject *result = NULL;
2057 PyObject *reason_str = NULL;
2058 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002059
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002060 if (!uself->object)
2061 /* Not properly initialized. */
2062 return PyUnicode_FromString("");
2063
Eric Smith0facd772010-02-24 15:42:29 +00002064 /* Get reason and encoding as strings, which they might not be if
Martin Pantereb995702016-07-28 01:11:04 +00002065 they've been modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002066 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
Victor Stinnerda1ddf32011-11-20 22:50:23 +01002073 if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2074 Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
Walter Dörwald787b03b2007-06-05 13:29:29 +00002075 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002076 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002077 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002078 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002079 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002080 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00002081 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Eric Smith0facd772010-02-24 15:42:29 +00002082 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002083 fmt,
Eric Smith0facd772010-02-24 15:42:29 +00002084 encoding_str,
Victor Stinnerda1ddf32011-11-20 22:50:23 +01002085 (int)badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002086 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002087 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002088 }
Eric Smith0facd772010-02-24 15:42:29 +00002089 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 }
2097done:
2098 Py_XDECREF(reason_str);
2099 Py_XDECREF(encoding_str);
2100 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101}
2102
2103static PyTypeObject _PyExc_UnicodeEncodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002104 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002105 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002106 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,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002110 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
2111 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002112 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002113 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002114};
2115PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
2116
2117PyObject *
2118PyUnicodeEncodeError_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{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00002122 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002123 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002124}
2125
2126
2127/*
2128 * UnicodeDecodeError extends UnicodeError
2129 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002130
2131static int
2132UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2133{
Guido van Rossum98297ee2007-11-06 21:34:58 +00002134 PyUnicodeErrorObject *ude;
Guido van Rossum98297ee2007-11-06 21:34:58 +00002135
Thomas Wouters477c8d52006-05-27 19:21:47 +00002136 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2137 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00002138
2139 ude = (PyUnicodeErrorObject *)self;
2140
2141 Py_CLEAR(ude->encoding);
2142 Py_CLEAR(ude->object);
2143 Py_CLEAR(ude->reason);
2144
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03002145 if (!PyArg_ParseTuple(args, "UOnnU",
2146 &ude->encoding, &ude->object,
2147 &ude->start, &ude->end, &ude->reason)) {
Guido van Rossum98297ee2007-11-06 21:34:58 +00002148 ude->encoding = ude->object = ude->reason = NULL;
2149 return -1;
2150 }
2151
Guido van Rossum98297ee2007-11-06 21:34:58 +00002152 Py_INCREF(ude->encoding);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002153 Py_INCREF(ude->object);
Guido van Rossum98297ee2007-11-06 21:34:58 +00002154 Py_INCREF(ude->reason);
2155
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002156 if (!PyBytes_Check(ude->object)) {
2157 Py_buffer view;
2158 if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
2159 goto error;
Serhiy Storchaka48842712016-04-06 09:45:48 +03002160 Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002161 PyBuffer_Release(&view);
2162 if (!ude->object)
2163 goto error;
2164 }
Guido van Rossum98297ee2007-11-06 21:34:58 +00002165 return 0;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002166
2167error:
2168 Py_CLEAR(ude->encoding);
2169 Py_CLEAR(ude->object);
2170 Py_CLEAR(ude->reason);
2171 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002172}
2173
2174static PyObject *
2175UnicodeDecodeError_str(PyObject *self)
2176{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002177 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00002178 PyObject *result = NULL;
2179 PyObject *reason_str = NULL;
2180 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002181
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002182 if (!uself->object)
2183 /* Not properly initialized. */
2184 return PyUnicode_FromString("");
2185
Eric Smith0facd772010-02-24 15:42:29 +00002186 /* Get reason and encoding as strings, which they might not be if
Martin Pantereb995702016-07-28 01:11:04 +00002187 they've been modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002188 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) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002196 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Eric Smith0facd772010-02-24 15:42:29 +00002197 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002198 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Eric Smith0facd772010-02-24 15:42:29 +00002199 encoding_str,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002200 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002201 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002202 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002203 }
Eric Smith0facd772010-02-24 15:42:29 +00002204 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 }
2213done:
2214 Py_XDECREF(reason_str);
2215 Py_XDECREF(encoding_str);
2216 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002217}
2218
2219static PyTypeObject _PyExc_UnicodeDecodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002220 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002221 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002222 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,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002226 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
2227 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002228 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002229 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002230};
2231PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
2232
2233PyObject *
2234PyUnicodeDecodeError_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{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00002238 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002239 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002240}
2241
2242
2243/*
2244 * UnicodeTranslateError extends UnicodeError
2245 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002246
2247static int
2248UnicodeTranslateError_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);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002255 Py_CLEAR(self->reason);
2256
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03002257 if (!PyArg_ParseTuple(args, "UnnU",
2258 &self->object,
2259 &self->start, &self->end, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002260 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002261 return -1;
2262 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002263
Thomas Wouters477c8d52006-05-27 19:21:47 +00002264 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002265 Py_INCREF(self->reason);
2266
2267 return 0;
2268}
2269
2270
2271static PyObject *
2272UnicodeTranslateError_str(PyObject *self)
2273{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002274 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00002275 PyObject *result = NULL;
2276 PyObject *reason_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002277
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002278 if (!uself->object)
2279 /* Not properly initialized. */
2280 return PyUnicode_FromString("");
2281
Eric Smith0facd772010-02-24 15:42:29 +00002282 /* Get reason as a string, which it might not be if it's been
Martin Pantereb995702016-07-28 01:11:04 +00002283 modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002284 reason_str = PyObject_Str(uself->reason);
2285 if (reason_str == NULL)
2286 goto done;
2287
Victor Stinner53b33e72011-11-21 01:17:27 +01002288 if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2289 Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
Walter Dörwald787b03b2007-06-05 13:29:29 +00002290 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002291 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002292 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002293 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002294 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002295 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00002296 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Benjamin Petersonc5f4e1e2010-02-25 01:22:28 +00002297 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002298 fmt,
Victor Stinner53b33e72011-11-21 01:17:27 +01002299 (int)badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002300 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002301 reason_str
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002302 );
Eric Smith0facd772010-02-24 15:42:29 +00002303 } 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 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00002310 }
Eric Smith0facd772010-02-24 15:42:29 +00002311done:
2312 Py_XDECREF(reason_str);
2313 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002314}
2315
2316static PyTypeObject _PyExc_UnicodeTranslateError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002317 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002318 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002319 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,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002323 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002324 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2325 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002326 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002327};
2328PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
2329
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002330/* Deprecated. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002331PyObject *
2332PyUnicodeTranslateError_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",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002337 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002338}
Thomas Wouters477c8d52006-05-27 19:21:47 +00002339
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002340PyObject *
2341_PyUnicodeTranslateError_Create(
2342 PyObject *object,
2343 Py_ssize_t start, Py_ssize_t end, const char *reason)
2344{
Victor Stinner69598d4c2014-04-04 20:59:44 +02002345 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002346 object, start, end, reason);
2347}
Thomas Wouters477c8d52006-05-27 19:21:47 +00002348
2349/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002350 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002351 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002352SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002353 "Assertion failed.");
2354
2355
2356/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002357 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002358 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002359SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002360 "Base class for arithmetic errors.");
2361
2362
2363/*
2364 * FloatingPointError extends ArithmeticError
2365 */
2366SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
2367 "Floating point operation failed.");
2368
2369
2370/*
2371 * OverflowError extends ArithmeticError
2372 */
2373SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
2374 "Result too large to be represented.");
2375
2376
2377/*
2378 * ZeroDivisionError extends ArithmeticError
2379 */
2380SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
2381 "Second argument to a division or modulo operation was zero.");
2382
2383
2384/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002385 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002386 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002387SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002388 "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/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002395 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002396 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002397SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002398 "Weak ref proxy used after referent went away.");
2399
2400
2401/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002402 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002403 */
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002404
2405#define MEMERRORS_SAVE 16
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002406
2407static PyObject *
2408MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2409{
2410 PyBaseExceptionObject *self;
2411
Pablo Galindo9b648a92020-09-01 19:39:46 +01002412 /* 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) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002415 return BaseException_new(type, args, kwds);
Pablo Galindo9b648a92020-09-01 19:39:46 +01002416 }
Victor Stinner281cce12020-06-23 22:55:46 +02002417
2418 struct _Py_exc_state *state = get_exc_state();
2419 if (state->memerrors_freelist == NULL) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002420 return BaseException_new(type, args, kwds);
Victor Stinner281cce12020-06-23 22:55:46 +02002421 }
2422
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002423 /* Fetch object from freelist and revive it */
Victor Stinner281cce12020-06-23 22:55:46 +02002424 self = state->memerrors_freelist;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002425 self->args = PyTuple_New(0);
2426 /* This shouldn't happen since the empty tuple is persistent */
Victor Stinner281cce12020-06-23 22:55:46 +02002427 if (self->args == NULL) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002428 return NULL;
Victor Stinner281cce12020-06-23 22:55:46 +02002429 }
2430
2431 state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
2432 state->memerrors_numfree--;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002433 self->dict = NULL;
2434 _Py_NewReference((PyObject *)self);
2435 _PyObject_GC_TRACK(self);
2436 return (PyObject *)self;
2437}
2438
2439static void
2440MemoryError_dealloc(PyBaseExceptionObject *self)
2441{
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002442 BaseException_clear(self);
Victor Stinner281cce12020-06-23 22:55:46 +02002443
Pablo Galindo9b648a92020-09-01 19:39:46 +01002444 /* 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)) {
Victor Stinnerbbeb2232020-09-23 23:25:40 +02002447 Py_TYPE(self)->tp_free((PyObject *)self);
2448 return;
Pablo Galindo9b648a92020-09-01 19:39:46 +01002449 }
2450
2451 _PyObject_GC_UNTRACK(self);
2452
Victor Stinner281cce12020-06-23 22:55:46 +02002453 struct _Py_exc_state *state = get_exc_state();
2454 if (state->memerrors_numfree >= MEMERRORS_SAVE) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002455 Py_TYPE(self)->tp_free((PyObject *)self);
Victor Stinner281cce12020-06-23 22:55:46 +02002456 }
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002457 else {
Victor Stinner281cce12020-06-23 22:55:46 +02002458 self->dict = (PyObject *) state->memerrors_freelist;
2459 state->memerrors_freelist = self;
2460 state->memerrors_numfree++;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002461 }
2462}
2463
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002464static int
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002465preallocate_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);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002474 if (!errors[i]) {
2475 return -1;
2476 }
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002477 }
2478 for (i = 0; i < MEMERRORS_SAVE; i++) {
2479 Py_DECREF(errors[i]);
2480 }
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002481 return 0;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002482}
2483
2484static void
Victor Stinner281cce12020-06-23 22:55:46 +02002485free_preallocated_memerrors(struct _Py_exc_state *state)
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002486{
Victor Stinner281cce12020-06-23 22:55:46 +02002487 while (state->memerrors_freelist != NULL) {
2488 PyObject *self = (PyObject *) state->memerrors_freelist;
2489 state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002490 Py_TYPE(self)->tp_free((PyObject *)self);
2491 }
2492}
2493
2494
2495static 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};
2507PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
2508
Thomas Wouters477c8d52006-05-27 19:21:47 +00002509
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002510/*
2511 * BufferError extends Exception
2512 */
2513SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
2514
Thomas Wouters477c8d52006-05-27 19:21:47 +00002515
2516/* Warning category docstrings */
2517
2518/*
2519 * Warning extends Exception
2520 */
2521SimpleExtendsException(PyExc_Exception, Warning,
2522 "Base class for warning categories.");
2523
2524
2525/*
2526 * UserWarning extends Warning
2527 */
2528SimpleExtendsException(PyExc_Warning, UserWarning,
2529 "Base class for warnings generated by user code.");
2530
2531
2532/*
2533 * DeprecationWarning extends Warning
2534 */
2535SimpleExtendsException(PyExc_Warning, DeprecationWarning,
2536 "Base class for warnings about deprecated features.");
2537
2538
2539/*
2540 * PendingDeprecationWarning extends Warning
2541 */
2542SimpleExtendsException(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 */
2550SimpleExtendsException(PyExc_Warning, SyntaxWarning,
2551 "Base class for warnings about dubious syntax.");
2552
2553
2554/*
2555 * RuntimeWarning extends Warning
2556 */
2557SimpleExtendsException(PyExc_Warning, RuntimeWarning,
2558 "Base class for warnings about dubious runtime behavior.");
2559
2560
2561/*
2562 * FutureWarning extends Warning
2563 */
2564SimpleExtendsException(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 */
2572SimpleExtendsException(PyExc_Warning, ImportWarning,
2573 "Base class for warnings about probable mistakes in module imports");
2574
2575
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002576/*
2577 * UnicodeWarning extends Warning
2578 */
2579SimpleExtendsException(PyExc_Warning, UnicodeWarning,
2580 "Base class for warnings about Unicode related problems, mostly\n"
2581 "related to conversion problems.");
2582
Georg Brandl08be72d2010-10-24 15:11:22 +00002583
Guido van Rossum98297ee2007-11-06 21:34:58 +00002584/*
2585 * BytesWarning extends Warning
2586 */
2587SimpleExtendsException(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
Georg Brandl08be72d2010-10-24 15:11:22 +00002592/*
Inada Naoki48274832021-03-29 12:28:14 +09002593 * EncodingWarning extends Warning
2594 */
2595SimpleExtendsException(PyExc_Warning, EncodingWarning,
2596 "Base class for warnings about encodings.");
2597
2598
2599/*
Georg Brandl08be72d2010-10-24 15:11:22 +00002600 * ResourceWarning extends Warning
2601 */
2602SimpleExtendsException(PyExc_Warning, ResourceWarning,
2603 "Base class for warnings about resource usage.");
2604
2605
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002606
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002607#ifdef MS_WINDOWS
Antoine Pitrou7faf7052013-03-31 22:48:04 +02002608#include <winsock2.h>
Brian Curtin401f9f32012-05-13 11:19:23 -05002609/* 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
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002637#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 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002662
Victor Stinner331a6a52019-05-27 16:39:22 +02002663PyStatus
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002664_PyExc_Init(PyInterpreterState *interp)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002665{
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002666 struct _Py_exc_state *state = &interp->exc_state;
Victor Stinner281cce12020-06-23 22:55:46 +02002667
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002668#define PRE_INIT(TYPE) \
2669 if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
2670 if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002671 return _PyStatus_ERR("exceptions bootstrapping error."); \
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002672 } \
2673 Py_INCREF(PyExc_ ## TYPE); \
2674 }
2675
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002676#define ADD_ERRNO(TYPE, CODE) \
2677 do { \
2678 PyObject *_code = PyLong_FromLong(CODE); \
2679 assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
Serhiy Storchakaed1007c2020-11-21 19:17:46 +02002680 if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
2681 Py_XDECREF(_code); \
Victor Stinner331a6a52019-05-27 16:39:22 +02002682 return _PyStatus_ERR("errmap insertion problem."); \
Serhiy Storchakaed1007c2020-11-21 19:17:46 +02002683 } \
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002684 Py_DECREF(_code); \
2685 } while (0)
2686
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002687 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);
Inada Naoki48274832021-03-29 12:28:14 +09002727 PRE_INIT(EncodingWarning);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002728 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);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002737
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002738 /* OSError subclasses */
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002739 PRE_INIT(ConnectionError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002740
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002741 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);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002755
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002756 if (preallocate_memerrors() < 0) {
Victor Stinner281cce12020-06-23 22:55:46 +02002757 return _PyStatus_NO_MEMORY();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002758 }
2759
2760 /* Add exceptions to errnomap */
Victor Stinner281cce12020-06-23 22:55:46 +02002761 assert(state->errnomap == NULL);
2762 state->errnomap = PyDict_New();
2763 if (!state->errnomap) {
2764 return _PyStatus_NO_MEMORY();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002765 }
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
Victor Stinner331a6a52019-05-27 16:39:22 +02002789 return _PyStatus_OK();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002790
2791#undef PRE_INIT
2792#undef ADD_ERRNO
2793}
2794
2795
2796/* Add exception types to the builtins module */
Victor Stinner331a6a52019-05-27 16:39:22 +02002797PyStatus
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002798_PyBuiltins_AddExceptions(PyObject *bltinmod)
2799{
2800#define POST_INIT(TYPE) \
2801 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002802 return _PyStatus_ERR("Module dictionary insertion problem."); \
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002803 }
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)) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002811 return _PyStatus_ERR("Module dictionary insertion problem."); \
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002812 } \
2813 } while (0)
2814
2815 PyObject *bdict;
2816
Thomas Wouters477c8d52006-05-27 19:21:47 +00002817 bdict = PyModule_GetDict(bltinmod);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002818 if (bdict == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002819 return _PyStatus_ERR("exceptions bootstrapping error.");
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002820 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002821
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002822 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);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002835#ifdef MS_WINDOWS
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002836 INIT_ALIAS(WindowsError, OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002837#endif
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002838 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);
Inada Naoki48274832021-03-29 12:28:14 +09002867 POST_INIT(EncodingWarning);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002868 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);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002877
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002878 /* OSError subclasses */
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002879 POST_INIT(ConnectionError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002880
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002881 POST_INIT(BlockingIOError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002882 POST_INIT(BrokenPipeError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002883 POST_INIT(ChildProcessError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002884 POST_INIT(ConnectionAbortedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002885 POST_INIT(ConnectionRefusedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002886 POST_INIT(ConnectionResetError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002887 POST_INIT(FileExistsError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002888 POST_INIT(FileNotFoundError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002889 POST_INIT(IsADirectoryError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002890 POST_INIT(NotADirectoryError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002891 POST_INIT(InterruptedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002892 POST_INIT(PermissionError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002893 POST_INIT(ProcessLookupError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002894 POST_INIT(TimeoutError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002895
Victor Stinner331a6a52019-05-27 16:39:22 +02002896 return _PyStatus_OK();
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002897
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002898#undef POST_INIT
2899#undef INIT_ALIAS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002900}
2901
2902void
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002903_PyExc_Fini(PyInterpreterState *interp)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002904{
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002905 struct _Py_exc_state *state = &interp->exc_state;
Victor Stinner281cce12020-06-23 22:55:46 +02002906 free_preallocated_memerrors(state);
2907 Py_CLEAR(state->errnomap);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002908}
Nick Coghlan8b097b42013-11-13 23:49:21 +10002909
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 */
2938PyObject *
2939_PyErr_TrySetFromCause(const char *format, ...)
2940{
2941 PyObject* msg_prefix;
2942 PyObject *exc, *val, *tb;
2943 PyTypeObject *caught_type;
Christian Heimes6a3db252013-11-14 01:47:14 +01002944 PyObject **dictptr;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002945 PyObject *instance_args;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002946 Py_ssize_t num_args, caught_type_size, base_exc_size;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002947 PyObject *new_exc, *new_val, *new_tb;
2948 va_list vargs;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002949 int same_basic_size;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002950
Nick Coghlan8b097b42013-11-13 23:49:21 +10002951 PyErr_Fetch(&exc, &val, &tb);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002952 caught_type = (PyTypeObject *)exc;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002953 /* 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) &&
Victor Stinner12174a52014-08-15 23:17:38 +02002961 (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002962 )
2963 );
Benjamin Peterson079c9982013-11-13 23:25:01 -05002964 if (caught_type->tp_init != (initproc)BaseException_init ||
Nick Coghlan8b097b42013-11-13 23:49:21 +10002965 caught_type->tp_new != BaseException_new ||
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002966 !same_basic_size ||
Benjamin Peterson079c9982013-11-13 23:25:01 -05002967 caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002968 /* 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);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002978 instance_args = ((PyBaseExceptionObject *)val)->args;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002979 num_args = PyTuple_GET_SIZE(instance_args);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002980 if (num_args > 1 ||
Nick Coghlan8b097b42013-11-13 23:49:21 +10002981 (num_args == 1 &&
Benjamin Peterson079c9982013-11-13 23:25:01 -05002982 !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002983 /* 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 */
Christian Heimes6a3db252013-11-14 01:47:14 +01002990 dictptr = _PyObject_GetDictPtr(val);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002991 if (dictptr != NULL && *dictptr != NULL &&
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002992 PyDict_GET_SIZE(*dictptr) > 0) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002993 /* 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 */
Nick Coghlan77b286b2014-01-27 00:53:38 +10003011 /* Ensure the traceback is set correctly on the existing exception */
3012 if (tb != NULL) {
3013 PyException_SetTraceback(val, tb);
3014 Py_DECREF(tb);
3015 }
Benjamin Petersone109ee82013-11-13 23:49:49 -05003016
Christian Heimes507eabd2013-11-14 01:39:35 +01003017#ifdef HAVE_STDARG_PROTOTYPES
3018 va_start(vargs, format);
3019#else
3020 va_start(vargs);
3021#endif
Nick Coghlan8b097b42013-11-13 23:49:21 +10003022 msg_prefix = PyUnicode_FromFormatV(format, vargs);
Christian Heimes507eabd2013-11-14 01:39:35 +01003023 va_end(vargs);
Benjamin Petersone109ee82013-11-13 23:49:49 -05003024 if (msg_prefix == NULL) {
Nick Coghlan4b9b9362013-11-16 00:34:13 +10003025 Py_DECREF(exc);
Benjamin Petersone109ee82013-11-13 23:49:49 -05003026 Py_DECREF(val);
Nick Coghlan8b097b42013-11-13 23:49:21 +10003027 return NULL;
Benjamin Petersone109ee82013-11-13 23:49:49 -05003028 }
Nick Coghlan8b097b42013-11-13 23:49:21 +10003029
3030 PyErr_Format(exc, "%U (%s: %S)",
3031 msg_prefix, Py_TYPE(val)->tp_name, val);
Nick Coghlan4b9b9362013-11-16 00:34:13 +10003032 Py_DECREF(exc);
Benjamin Petersone109ee82013-11-13 23:49:49 -05003033 Py_DECREF(msg_prefix);
Nick Coghlan8b097b42013-11-13 23:49:21 +10003034 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}