blob: 4bb415331161fad79c405f56b78ff09b7612b091 [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 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001329SimpleExtendsException(PyExc_Exception, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001330 "Name not found globally.");
1331
1332/*
1333 * UnboundLocalError extends NameError
1334 */
1335SimpleExtendsException(PyExc_NameError, UnboundLocalError,
1336 "Local name referenced but not bound to a value.");
1337
1338/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001339 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341
Pablo Galindo37494b42021-04-14 02:36:07 +01001342static int
1343AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds)
1344{
1345 static char *kwlist[] = {"name", "obj", NULL};
1346 PyObject *name = NULL;
1347 PyObject *obj = NULL;
1348
1349 if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
1350 return -1;
1351 }
1352
1353 PyObject *empty_tuple = PyTuple_New(0);
1354 if (!empty_tuple) {
1355 return -1;
1356 }
1357 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
1358 &name, &obj)) {
1359 Py_DECREF(empty_tuple);
1360 return -1;
1361 }
1362 Py_DECREF(empty_tuple);
1363
1364 Py_XINCREF(name);
1365 Py_XSETREF(self->name, name);
1366
1367 Py_XINCREF(obj);
1368 Py_XSETREF(self->obj, obj);
1369
1370 return 0;
1371}
1372
1373static int
1374AttributeError_clear(PyAttributeErrorObject *self)
1375{
1376 Py_CLEAR(self->obj);
1377 Py_CLEAR(self->name);
1378 return BaseException_clear((PyBaseExceptionObject *)self);
1379}
1380
1381static void
1382AttributeError_dealloc(PyAttributeErrorObject *self)
1383{
1384 _PyObject_GC_UNTRACK(self);
1385 AttributeError_clear(self);
1386 Py_TYPE(self)->tp_free((PyObject *)self);
1387}
1388
1389static int
1390AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg)
1391{
1392 Py_VISIT(self->obj);
1393 Py_VISIT(self->name);
1394 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1395}
1396
1397static PyMemberDef AttributeError_members[] = {
1398 {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
1399 {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
1400 {NULL} /* Sentinel */
1401};
1402
1403static PyMethodDef AttributeError_methods[] = {
1404 {NULL} /* Sentinel */
1405};
1406
1407ComplexExtendsException(PyExc_Exception, AttributeError,
1408 AttributeError, 0,
1409 AttributeError_methods, AttributeError_members,
1410 0, BaseException_str, "Attribute not found.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411
1412/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001413 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415
Raymond Hettinger7ea386e2016-08-25 21:11:50 -07001416/* Helper function to customize error message for some syntax errors */
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10001417static int _report_missing_parentheses(PySyntaxErrorObject *self);
1418
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419static int
1420SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
1421{
1422 PyObject *info = NULL;
1423 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
1424
1425 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1426 return -1;
1427
1428 if (lenargs >= 1) {
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001429 Py_INCREF(PyTuple_GET_ITEM(args, 0));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001430 Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431 }
1432 if (lenargs == 2) {
1433 info = PyTuple_GET_ITEM(args, 1);
1434 info = PySequence_Tuple(info);
Benjamin Peterson90b13582012-02-03 19:22:31 -05001435 if (!info)
1436 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001438 if (PyTuple_GET_SIZE(info) != 4) {
1439 /* not a very good error message, but it's what Python 2.4 gives */
1440 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
1441 Py_DECREF(info);
1442 return -1;
1443 }
1444
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001445 Py_INCREF(PyTuple_GET_ITEM(info, 0));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001446 Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001448 Py_INCREF(PyTuple_GET_ITEM(info, 1));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001449 Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001450
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001451 Py_INCREF(PyTuple_GET_ITEM(info, 2));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001452 Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001453
Serhiy Storchaka4a1e70f2015-12-27 12:36:18 +02001454 Py_INCREF(PyTuple_GET_ITEM(info, 3));
Serhiy Storchaka48842712016-04-06 09:45:48 +03001455 Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001456
1457 Py_DECREF(info);
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10001458
Martijn Pieters772d8092017-08-22 21:16:23 +01001459 /*
1460 * Issue #21669: Custom error for 'print' & 'exec' as statements
1461 *
1462 * Only applies to SyntaxError instances, not to subclasses such
1463 * as TabError or IndentationError (see issue #31161)
1464 */
Andy Lesterdffe4c02020-03-04 07:15:20 -06001465 if (Py_IS_TYPE(self, (PyTypeObject *)PyExc_SyntaxError) &&
Martijn Pieters772d8092017-08-22 21:16:23 +01001466 self->text && PyUnicode_Check(self->text) &&
1467 _report_missing_parentheses(self) < 0) {
1468 return -1;
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10001469 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470 }
1471 return 0;
1472}
1473
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001474static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475SyntaxError_clear(PySyntaxErrorObject *self)
1476{
1477 Py_CLEAR(self->msg);
1478 Py_CLEAR(self->filename);
1479 Py_CLEAR(self->lineno);
1480 Py_CLEAR(self->offset);
1481 Py_CLEAR(self->text);
1482 Py_CLEAR(self->print_file_and_line);
1483 return BaseException_clear((PyBaseExceptionObject *)self);
1484}
1485
1486static void
1487SyntaxError_dealloc(PySyntaxErrorObject *self)
1488{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001489 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490 SyntaxError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001491 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001492}
1493
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001494static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1496{
1497 Py_VISIT(self->msg);
1498 Py_VISIT(self->filename);
1499 Py_VISIT(self->lineno);
1500 Py_VISIT(self->offset);
1501 Py_VISIT(self->text);
1502 Py_VISIT(self->print_file_and_line);
1503 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1504}
1505
1506/* This is called "my_basename" instead of just "basename" to avoid name
1507 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1508 defined, and Python does define that. */
Victor Stinner6237daf2010-04-28 17:26:19 +00001509static PyObject*
1510my_basename(PyObject *name)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511{
Victor Stinner6237daf2010-04-28 17:26:19 +00001512 Py_ssize_t i, size, offset;
Victor Stinner31392e72011-10-05 20:14:23 +02001513 int kind;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +03001514 const void *data;
Victor Stinner31392e72011-10-05 20:14:23 +02001515
1516 if (PyUnicode_READY(name))
1517 return NULL;
1518 kind = PyUnicode_KIND(name);
1519 data = PyUnicode_DATA(name);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001520 size = PyUnicode_GET_LENGTH(name);
Victor Stinner6237daf2010-04-28 17:26:19 +00001521 offset = 0;
1522 for(i=0; i < size; i++) {
Victor Stinner361dcdc2020-04-15 03:24:57 +02001523 if (PyUnicode_READ(kind, data, i) == SEP) {
Victor Stinner6237daf2010-04-28 17:26:19 +00001524 offset = i + 1;
Victor Stinner361dcdc2020-04-15 03:24:57 +02001525 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526 }
Victor Stinner361dcdc2020-04-15 03:24:57 +02001527 if (offset != 0) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001528 return PyUnicode_Substring(name, offset, size);
Victor Stinner361dcdc2020-04-15 03:24:57 +02001529 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001530 else {
Victor Stinner6237daf2010-04-28 17:26:19 +00001531 Py_INCREF(name);
1532 return name;
1533 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001534}
1535
1536
1537static PyObject *
1538SyntaxError_str(PySyntaxErrorObject *self)
1539{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001540 int have_lineno = 0;
Victor Stinner6237daf2010-04-28 17:26:19 +00001541 PyObject *filename;
1542 PyObject *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001543 /* Below, we always ignore overflow errors, just printing -1.
1544 Still, we cannot allow an OverflowError to be raised, so
1545 we need to call PyLong_AsLongAndOverflow. */
1546 int overflow;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547
1548 /* XXX -- do all the additional formatting with filename and
1549 lineno here */
1550
Neal Norwitzed2b7392007-08-26 04:51:10 +00001551 if (self->filename && PyUnicode_Check(self->filename)) {
Victor Stinner6237daf2010-04-28 17:26:19 +00001552 filename = my_basename(self->filename);
1553 if (filename == NULL)
1554 return NULL;
1555 } else {
1556 filename = NULL;
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001557 }
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001558 have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001560 if (!filename && !have_lineno)
Thomas Heller519a0422007-11-15 20:48:54 +00001561 return PyObject_Str(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001562
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001563 if (filename && have_lineno)
Victor Stinner6237daf2010-04-28 17:26:19 +00001564 result = PyUnicode_FromFormat("%S (%U, line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001565 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001566 filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001568 else if (filename)
Victor Stinner6237daf2010-04-28 17:26:19 +00001569 result = PyUnicode_FromFormat("%S (%U)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001570 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001571 filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001572 else /* only have_lineno */
Victor Stinner6237daf2010-04-28 17:26:19 +00001573 result = PyUnicode_FromFormat("%S (line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001574 self->msg ? self->msg : Py_None,
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001575 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Victor Stinner6237daf2010-04-28 17:26:19 +00001576 Py_XDECREF(filename);
1577 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001578}
1579
1580static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001581 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1582 PyDoc_STR("exception msg")},
1583 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1584 PyDoc_STR("exception filename")},
1585 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1586 PyDoc_STR("exception lineno")},
1587 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1588 PyDoc_STR("exception offset")},
1589 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1590 PyDoc_STR("exception text")},
1591 {"print_file_and_line", T_OBJECT,
1592 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1593 PyDoc_STR("exception print_file_and_line")},
1594 {NULL} /* Sentinel */
1595};
1596
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001597ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001598 0, 0, SyntaxError_members, 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599 SyntaxError_str, "Invalid syntax.");
1600
1601
1602/*
1603 * IndentationError extends SyntaxError
1604 */
1605MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1606 "Improper indentation.");
1607
1608
1609/*
1610 * TabError extends IndentationError
1611 */
1612MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1613 "Improper mixture of spaces and tabs.");
1614
1615
1616/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001617 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001619SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001620 "Base class for lookup errors.");
1621
1622
1623/*
1624 * IndexError extends LookupError
1625 */
1626SimpleExtendsException(PyExc_LookupError, IndexError,
1627 "Sequence index out of range.");
1628
1629
1630/*
1631 * KeyError extends LookupError
1632 */
1633static PyObject *
1634KeyError_str(PyBaseExceptionObject *self)
1635{
1636 /* If args is a tuple of exactly one item, apply repr to args[0].
1637 This is done so that e.g. the exception raised by {}[''] prints
1638 KeyError: ''
1639 rather than the confusing
1640 KeyError
1641 alone. The downside is that if KeyError is raised with an explanatory
1642 string, that string will be displayed in quotes. Too bad.
1643 If args is anything else, use the default BaseException__str__().
1644 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001645 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001646 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001647 }
1648 return BaseException_str(self);
1649}
1650
1651ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001652 0, 0, 0, 0, KeyError_str, "Mapping key not found.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653
1654
1655/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001656 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001658SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659 "Inappropriate argument value (of correct type).");
1660
1661/*
1662 * UnicodeError extends ValueError
1663 */
1664
1665SimpleExtendsException(PyExc_ValueError, UnicodeError,
1666 "Unicode related error.");
1667
Thomas Wouters477c8d52006-05-27 19:21:47 +00001668static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001669get_string(PyObject *attr, const char *name)
Walter Dörwald612344f2007-05-04 19:28:21 +00001670{
1671 if (!attr) {
1672 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1673 return NULL;
1674 }
1675
Christian Heimes72b710a2008-05-26 13:28:38 +00001676 if (!PyBytes_Check(attr)) {
Walter Dörwald612344f2007-05-04 19:28:21 +00001677 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1678 return NULL;
1679 }
1680 Py_INCREF(attr);
1681 return attr;
1682}
1683
1684static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685get_unicode(PyObject *attr, const char *name)
1686{
1687 if (!attr) {
1688 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1689 return NULL;
1690 }
1691
1692 if (!PyUnicode_Check(attr)) {
1693 PyErr_Format(PyExc_TypeError,
1694 "%.200s attribute must be unicode", name);
1695 return NULL;
1696 }
1697 Py_INCREF(attr);
1698 return attr;
1699}
1700
Walter Dörwaldd2034312007-05-18 16:29:38 +00001701static int
1702set_unicodefromstring(PyObject **attr, const char *value)
1703{
1704 PyObject *obj = PyUnicode_FromString(value);
1705 if (!obj)
1706 return -1;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001707 Py_XSETREF(*attr, obj);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001708 return 0;
1709}
1710
Thomas Wouters477c8d52006-05-27 19:21:47 +00001711PyObject *
1712PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1713{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001714 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715}
1716
1717PyObject *
1718PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1719{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001720 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721}
1722
1723PyObject *
1724PyUnicodeEncodeError_GetObject(PyObject *exc)
1725{
1726 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1727}
1728
1729PyObject *
1730PyUnicodeDecodeError_GetObject(PyObject *exc)
1731{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001732 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001733}
1734
1735PyObject *
1736PyUnicodeTranslateError_GetObject(PyObject *exc)
1737{
1738 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1739}
1740
1741int
1742PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1743{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001744 Py_ssize_t size;
1745 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1746 "object");
1747 if (!obj)
1748 return -1;
1749 *start = ((PyUnicodeErrorObject *)exc)->start;
Victor Stinner9e30aa52011-11-21 02:49:52 +01001750 size = PyUnicode_GET_LENGTH(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001751 if (*start<0)
1752 *start = 0; /*XXX check for values <0*/
1753 if (*start>=size)
1754 *start = size-1;
1755 Py_DECREF(obj);
1756 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001757}
1758
1759
1760int
1761PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1762{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001763 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001764 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001765 if (!obj)
1766 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001767 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001768 *start = ((PyUnicodeErrorObject *)exc)->start;
1769 if (*start<0)
1770 *start = 0;
1771 if (*start>=size)
1772 *start = size-1;
1773 Py_DECREF(obj);
1774 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775}
1776
1777
1778int
1779PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1780{
1781 return PyUnicodeEncodeError_GetStart(exc, start);
1782}
1783
1784
1785int
1786PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1787{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001788 ((PyUnicodeErrorObject *)exc)->start = start;
1789 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001790}
1791
1792
1793int
1794PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1795{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001796 ((PyUnicodeErrorObject *)exc)->start = start;
1797 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798}
1799
1800
1801int
1802PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1803{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001804 ((PyUnicodeErrorObject *)exc)->start = start;
1805 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001806}
1807
1808
1809int
1810PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1811{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001812 Py_ssize_t size;
1813 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1814 "object");
1815 if (!obj)
1816 return -1;
1817 *end = ((PyUnicodeErrorObject *)exc)->end;
Victor Stinner9e30aa52011-11-21 02:49:52 +01001818 size = PyUnicode_GET_LENGTH(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001819 if (*end<1)
1820 *end = 1;
1821 if (*end>size)
1822 *end = size;
1823 Py_DECREF(obj);
1824 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001825}
1826
1827
1828int
1829PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1830{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001831 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001832 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001833 if (!obj)
1834 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001835 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001836 *end = ((PyUnicodeErrorObject *)exc)->end;
1837 if (*end<1)
1838 *end = 1;
1839 if (*end>size)
1840 *end = size;
1841 Py_DECREF(obj);
1842 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001843}
1844
1845
1846int
Max Bernsteine6a0e802019-04-02 01:16:22 -07001847PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001848{
Max Bernsteine6a0e802019-04-02 01:16:22 -07001849 return PyUnicodeEncodeError_GetEnd(exc, end);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001850}
1851
1852
1853int
1854PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1855{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001856 ((PyUnicodeErrorObject *)exc)->end = end;
1857 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001858}
1859
1860
1861int
1862PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1863{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001864 ((PyUnicodeErrorObject *)exc)->end = end;
1865 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001866}
1867
1868
1869int
1870PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1871{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001872 ((PyUnicodeErrorObject *)exc)->end = end;
1873 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001874}
1875
1876PyObject *
1877PyUnicodeEncodeError_GetReason(PyObject *exc)
1878{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001879 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001880}
1881
1882
1883PyObject *
1884PyUnicodeDecodeError_GetReason(PyObject *exc)
1885{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001886 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887}
1888
1889
1890PyObject *
1891PyUnicodeTranslateError_GetReason(PyObject *exc)
1892{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001893 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001894}
1895
1896
1897int
1898PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1899{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001900 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1901 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001902}
1903
1904
1905int
1906PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1907{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001908 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1909 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001910}
1911
1912
1913int
1914PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1915{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001916 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1917 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001918}
1919
1920
Thomas Wouters477c8d52006-05-27 19:21:47 +00001921static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001922UnicodeError_clear(PyUnicodeErrorObject *self)
1923{
1924 Py_CLEAR(self->encoding);
1925 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926 Py_CLEAR(self->reason);
1927 return BaseException_clear((PyBaseExceptionObject *)self);
1928}
1929
1930static void
1931UnicodeError_dealloc(PyUnicodeErrorObject *self)
1932{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001933 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001934 UnicodeError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001935 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001936}
1937
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001938static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001939UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1940{
1941 Py_VISIT(self->encoding);
1942 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001943 Py_VISIT(self->reason);
1944 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1945}
1946
1947static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001948 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1949 PyDoc_STR("exception encoding")},
1950 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1951 PyDoc_STR("exception object")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001952 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001953 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001954 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001955 PyDoc_STR("exception end")},
1956 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1957 PyDoc_STR("exception reason")},
1958 {NULL} /* Sentinel */
1959};
1960
1961
1962/*
1963 * UnicodeEncodeError extends UnicodeError
1964 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965
1966static int
1967UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1968{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001969 PyUnicodeErrorObject *err;
1970
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1972 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001973
1974 err = (PyUnicodeErrorObject *)self;
1975
1976 Py_CLEAR(err->encoding);
1977 Py_CLEAR(err->object);
1978 Py_CLEAR(err->reason);
1979
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03001980 if (!PyArg_ParseTuple(args, "UUnnU",
1981 &err->encoding, &err->object,
1982 &err->start, &err->end, &err->reason)) {
1983 err->encoding = err->object = err->reason = NULL;
Martin v. Löwisb09af032011-11-04 11:16:41 +01001984 return -1;
1985 }
1986
Guido van Rossum98297ee2007-11-06 21:34:58 +00001987 Py_INCREF(err->encoding);
1988 Py_INCREF(err->object);
1989 Py_INCREF(err->reason);
1990
1991 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992}
1993
1994static PyObject *
1995UnicodeEncodeError_str(PyObject *self)
1996{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001997 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00001998 PyObject *result = NULL;
1999 PyObject *reason_str = NULL;
2000 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002001
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002002 if (!uself->object)
2003 /* Not properly initialized. */
2004 return PyUnicode_FromString("");
2005
Eric Smith0facd772010-02-24 15:42:29 +00002006 /* Get reason and encoding as strings, which they might not be if
Martin Pantereb995702016-07-28 01:11:04 +00002007 they've been modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002008 reason_str = PyObject_Str(uself->reason);
2009 if (reason_str == NULL)
2010 goto done;
2011 encoding_str = PyObject_Str(uself->encoding);
2012 if (encoding_str == NULL)
2013 goto done;
2014
Victor Stinnerda1ddf32011-11-20 22:50:23 +01002015 if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2016 Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
Walter Dörwald787b03b2007-06-05 13:29:29 +00002017 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002018 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002019 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002020 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002021 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002022 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00002023 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Eric Smith0facd772010-02-24 15:42:29 +00002024 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002025 fmt,
Eric Smith0facd772010-02-24 15:42:29 +00002026 encoding_str,
Victor Stinnerda1ddf32011-11-20 22:50:23 +01002027 (int)badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002028 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002029 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002030 }
Eric Smith0facd772010-02-24 15:42:29 +00002031 else {
2032 result = PyUnicode_FromFormat(
2033 "'%U' codec can't encode characters in position %zd-%zd: %U",
2034 encoding_str,
2035 uself->start,
2036 uself->end-1,
2037 reason_str);
2038 }
2039done:
2040 Py_XDECREF(reason_str);
2041 Py_XDECREF(encoding_str);
2042 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002043}
2044
2045static PyTypeObject _PyExc_UnicodeEncodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002046 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002047 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002048 sizeof(PyUnicodeErrorObject), 0,
2049 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2050 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
2051 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002052 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
2053 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002054 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002055 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002056};
2057PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
2058
2059PyObject *
2060PyUnicodeEncodeError_Create(
2061 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
2062 Py_ssize_t start, Py_ssize_t end, const char *reason)
2063{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00002064 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002065 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002066}
2067
2068
2069/*
2070 * UnicodeDecodeError extends UnicodeError
2071 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002072
2073static int
2074UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2075{
Guido van Rossum98297ee2007-11-06 21:34:58 +00002076 PyUnicodeErrorObject *ude;
Guido van Rossum98297ee2007-11-06 21:34:58 +00002077
Thomas Wouters477c8d52006-05-27 19:21:47 +00002078 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2079 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00002080
2081 ude = (PyUnicodeErrorObject *)self;
2082
2083 Py_CLEAR(ude->encoding);
2084 Py_CLEAR(ude->object);
2085 Py_CLEAR(ude->reason);
2086
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03002087 if (!PyArg_ParseTuple(args, "UOnnU",
2088 &ude->encoding, &ude->object,
2089 &ude->start, &ude->end, &ude->reason)) {
Guido van Rossum98297ee2007-11-06 21:34:58 +00002090 ude->encoding = ude->object = ude->reason = NULL;
2091 return -1;
2092 }
2093
Guido van Rossum98297ee2007-11-06 21:34:58 +00002094 Py_INCREF(ude->encoding);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002095 Py_INCREF(ude->object);
Guido van Rossum98297ee2007-11-06 21:34:58 +00002096 Py_INCREF(ude->reason);
2097
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002098 if (!PyBytes_Check(ude->object)) {
2099 Py_buffer view;
2100 if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
2101 goto error;
Serhiy Storchaka48842712016-04-06 09:45:48 +03002102 Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002103 PyBuffer_Release(&view);
2104 if (!ude->object)
2105 goto error;
2106 }
Guido van Rossum98297ee2007-11-06 21:34:58 +00002107 return 0;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002108
2109error:
2110 Py_CLEAR(ude->encoding);
2111 Py_CLEAR(ude->object);
2112 Py_CLEAR(ude->reason);
2113 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002114}
2115
2116static PyObject *
2117UnicodeDecodeError_str(PyObject *self)
2118{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002119 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00002120 PyObject *result = NULL;
2121 PyObject *reason_str = NULL;
2122 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002123
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002124 if (!uself->object)
2125 /* Not properly initialized. */
2126 return PyUnicode_FromString("");
2127
Eric Smith0facd772010-02-24 15:42:29 +00002128 /* Get reason and encoding as strings, which they might not be if
Martin Pantereb995702016-07-28 01:11:04 +00002129 they've been modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002130 reason_str = PyObject_Str(uself->reason);
2131 if (reason_str == NULL)
2132 goto done;
2133 encoding_str = PyObject_Str(uself->encoding);
2134 if (encoding_str == NULL)
2135 goto done;
2136
2137 if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002138 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Eric Smith0facd772010-02-24 15:42:29 +00002139 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002140 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Eric Smith0facd772010-02-24 15:42:29 +00002141 encoding_str,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002142 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002143 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002144 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002145 }
Eric Smith0facd772010-02-24 15:42:29 +00002146 else {
2147 result = PyUnicode_FromFormat(
2148 "'%U' codec can't decode bytes in position %zd-%zd: %U",
2149 encoding_str,
2150 uself->start,
2151 uself->end-1,
2152 reason_str
2153 );
2154 }
2155done:
2156 Py_XDECREF(reason_str);
2157 Py_XDECREF(encoding_str);
2158 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002159}
2160
2161static PyTypeObject _PyExc_UnicodeDecodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002162 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002163 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002164 sizeof(PyUnicodeErrorObject), 0,
2165 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2166 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
2167 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002168 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
2169 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002170 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002171 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002172};
2173PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
2174
2175PyObject *
2176PyUnicodeDecodeError_Create(
2177 const char *encoding, const char *object, Py_ssize_t length,
2178 Py_ssize_t start, Py_ssize_t end, const char *reason)
2179{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00002180 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002181 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002182}
2183
2184
2185/*
2186 * UnicodeTranslateError extends UnicodeError
2187 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002188
2189static int
2190UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
2191 PyObject *kwds)
2192{
2193 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2194 return -1;
2195
2196 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002197 Py_CLEAR(self->reason);
2198
Serhiy Storchakaf8d7d412016-10-23 15:12:25 +03002199 if (!PyArg_ParseTuple(args, "UnnU",
2200 &self->object,
2201 &self->start, &self->end, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002202 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002203 return -1;
2204 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002205
Thomas Wouters477c8d52006-05-27 19:21:47 +00002206 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002207 Py_INCREF(self->reason);
2208
2209 return 0;
2210}
2211
2212
2213static PyObject *
2214UnicodeTranslateError_str(PyObject *self)
2215{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002216 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00002217 PyObject *result = NULL;
2218 PyObject *reason_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002219
Benjamin Peterson9b09ba12014-04-02 12:15:06 -04002220 if (!uself->object)
2221 /* Not properly initialized. */
2222 return PyUnicode_FromString("");
2223
Eric Smith0facd772010-02-24 15:42:29 +00002224 /* Get reason as a string, which it might not be if it's been
Martin Pantereb995702016-07-28 01:11:04 +00002225 modified after we were constructed. */
Eric Smith0facd772010-02-24 15:42:29 +00002226 reason_str = PyObject_Str(uself->reason);
2227 if (reason_str == NULL)
2228 goto done;
2229
Victor Stinner53b33e72011-11-21 01:17:27 +01002230 if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2231 Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
Walter Dörwald787b03b2007-06-05 13:29:29 +00002232 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002233 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002234 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002235 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00002236 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002237 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00002238 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Benjamin Petersonc5f4e1e2010-02-25 01:22:28 +00002239 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00002240 fmt,
Victor Stinner53b33e72011-11-21 01:17:27 +01002241 (int)badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00002242 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00002243 reason_str
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002244 );
Eric Smith0facd772010-02-24 15:42:29 +00002245 } else {
2246 result = PyUnicode_FromFormat(
2247 "can't translate characters in position %zd-%zd: %U",
2248 uself->start,
2249 uself->end-1,
2250 reason_str
2251 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00002252 }
Eric Smith0facd772010-02-24 15:42:29 +00002253done:
2254 Py_XDECREF(reason_str);
2255 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002256}
2257
2258static PyTypeObject _PyExc_UnicodeTranslateError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002259 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00002260 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00002261 sizeof(PyUnicodeErrorObject), 0,
2262 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2263 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
2264 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002265 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002266 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2267 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002268 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002269};
2270PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
2271
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002272/* Deprecated. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002273PyObject *
2274PyUnicodeTranslateError_Create(
2275 const Py_UNICODE *object, Py_ssize_t length,
2276 Py_ssize_t start, Py_ssize_t end, const char *reason)
2277{
2278 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002279 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002280}
Thomas Wouters477c8d52006-05-27 19:21:47 +00002281
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002282PyObject *
2283_PyUnicodeTranslateError_Create(
2284 PyObject *object,
2285 Py_ssize_t start, Py_ssize_t end, const char *reason)
2286{
Victor Stinner69598d42014-04-04 20:59:44 +02002287 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002288 object, start, end, reason);
2289}
Thomas Wouters477c8d52006-05-27 19:21:47 +00002290
2291/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002292 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002293 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002294SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002295 "Assertion failed.");
2296
2297
2298/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002299 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002300 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002301SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002302 "Base class for arithmetic errors.");
2303
2304
2305/*
2306 * FloatingPointError extends ArithmeticError
2307 */
2308SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
2309 "Floating point operation failed.");
2310
2311
2312/*
2313 * OverflowError extends ArithmeticError
2314 */
2315SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
2316 "Result too large to be represented.");
2317
2318
2319/*
2320 * ZeroDivisionError extends ArithmeticError
2321 */
2322SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
2323 "Second argument to a division or modulo operation was zero.");
2324
2325
2326/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002327 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002328 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002329SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002330 "Internal error in the Python interpreter.\n"
2331 "\n"
2332 "Please report this to the Python maintainer, along with the traceback,\n"
2333 "the Python version, and the hardware/OS platform and version.");
2334
2335
2336/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002337 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002338 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002339SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002340 "Weak ref proxy used after referent went away.");
2341
2342
2343/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00002344 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00002345 */
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002346
2347#define MEMERRORS_SAVE 16
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002348
2349static PyObject *
2350MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2351{
2352 PyBaseExceptionObject *self;
2353
Pablo Galindo9b648a92020-09-01 19:39:46 +01002354 /* If this is a subclass of MemoryError, don't use the freelist
2355 * and just return a fresh object */
2356 if (type != (PyTypeObject *) PyExc_MemoryError) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002357 return BaseException_new(type, args, kwds);
Pablo Galindo9b648a92020-09-01 19:39:46 +01002358 }
Victor Stinner281cce12020-06-23 22:55:46 +02002359
2360 struct _Py_exc_state *state = get_exc_state();
2361 if (state->memerrors_freelist == NULL) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002362 return BaseException_new(type, args, kwds);
Victor Stinner281cce12020-06-23 22:55:46 +02002363 }
2364
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002365 /* Fetch object from freelist and revive it */
Victor Stinner281cce12020-06-23 22:55:46 +02002366 self = state->memerrors_freelist;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002367 self->args = PyTuple_New(0);
2368 /* This shouldn't happen since the empty tuple is persistent */
Victor Stinner281cce12020-06-23 22:55:46 +02002369 if (self->args == NULL) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002370 return NULL;
Victor Stinner281cce12020-06-23 22:55:46 +02002371 }
2372
2373 state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
2374 state->memerrors_numfree--;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002375 self->dict = NULL;
2376 _Py_NewReference((PyObject *)self);
2377 _PyObject_GC_TRACK(self);
2378 return (PyObject *)self;
2379}
2380
2381static void
2382MemoryError_dealloc(PyBaseExceptionObject *self)
2383{
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002384 BaseException_clear(self);
Victor Stinner281cce12020-06-23 22:55:46 +02002385
Pablo Galindo9b648a92020-09-01 19:39:46 +01002386 /* If this is a subclass of MemoryError, we don't need to
2387 * do anything in the free-list*/
2388 if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
Victor Stinnerbbeb2232020-09-23 23:25:40 +02002389 Py_TYPE(self)->tp_free((PyObject *)self);
2390 return;
Pablo Galindo9b648a92020-09-01 19:39:46 +01002391 }
2392
2393 _PyObject_GC_UNTRACK(self);
2394
Victor Stinner281cce12020-06-23 22:55:46 +02002395 struct _Py_exc_state *state = get_exc_state();
2396 if (state->memerrors_numfree >= MEMERRORS_SAVE) {
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002397 Py_TYPE(self)->tp_free((PyObject *)self);
Victor Stinner281cce12020-06-23 22:55:46 +02002398 }
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002399 else {
Victor Stinner281cce12020-06-23 22:55:46 +02002400 self->dict = (PyObject *) state->memerrors_freelist;
2401 state->memerrors_freelist = self;
2402 state->memerrors_numfree++;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002403 }
2404}
2405
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002406static int
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002407preallocate_memerrors(void)
2408{
2409 /* We create enough MemoryErrors and then decref them, which will fill
2410 up the freelist. */
2411 int i;
2412 PyObject *errors[MEMERRORS_SAVE];
2413 for (i = 0; i < MEMERRORS_SAVE; i++) {
2414 errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
2415 NULL, NULL);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002416 if (!errors[i]) {
2417 return -1;
2418 }
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002419 }
2420 for (i = 0; i < MEMERRORS_SAVE; i++) {
2421 Py_DECREF(errors[i]);
2422 }
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002423 return 0;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002424}
2425
2426static void
Victor Stinner281cce12020-06-23 22:55:46 +02002427free_preallocated_memerrors(struct _Py_exc_state *state)
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002428{
Victor Stinner281cce12020-06-23 22:55:46 +02002429 while (state->memerrors_freelist != NULL) {
2430 PyObject *self = (PyObject *) state->memerrors_freelist;
2431 state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002432 Py_TYPE(self)->tp_free((PyObject *)self);
2433 }
2434}
2435
2436
2437static PyTypeObject _PyExc_MemoryError = {
2438 PyVarObject_HEAD_INIT(NULL, 0)
2439 "MemoryError",
2440 sizeof(PyBaseExceptionObject),
2441 0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
2442 0, 0, 0, 0, 0, 0, 0,
2443 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2444 PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
2445 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
2446 0, 0, 0, offsetof(PyBaseExceptionObject, dict),
2447 (initproc)BaseException_init, 0, MemoryError_new
2448};
2449PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
2450
Thomas Wouters477c8d52006-05-27 19:21:47 +00002451
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002452/*
2453 * BufferError extends Exception
2454 */
2455SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
2456
Thomas Wouters477c8d52006-05-27 19:21:47 +00002457
2458/* Warning category docstrings */
2459
2460/*
2461 * Warning extends Exception
2462 */
2463SimpleExtendsException(PyExc_Exception, Warning,
2464 "Base class for warning categories.");
2465
2466
2467/*
2468 * UserWarning extends Warning
2469 */
2470SimpleExtendsException(PyExc_Warning, UserWarning,
2471 "Base class for warnings generated by user code.");
2472
2473
2474/*
2475 * DeprecationWarning extends Warning
2476 */
2477SimpleExtendsException(PyExc_Warning, DeprecationWarning,
2478 "Base class for warnings about deprecated features.");
2479
2480
2481/*
2482 * PendingDeprecationWarning extends Warning
2483 */
2484SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
2485 "Base class for warnings about features which will be deprecated\n"
2486 "in the future.");
2487
2488
2489/*
2490 * SyntaxWarning extends Warning
2491 */
2492SimpleExtendsException(PyExc_Warning, SyntaxWarning,
2493 "Base class for warnings about dubious syntax.");
2494
2495
2496/*
2497 * RuntimeWarning extends Warning
2498 */
2499SimpleExtendsException(PyExc_Warning, RuntimeWarning,
2500 "Base class for warnings about dubious runtime behavior.");
2501
2502
2503/*
2504 * FutureWarning extends Warning
2505 */
2506SimpleExtendsException(PyExc_Warning, FutureWarning,
2507 "Base class for warnings about constructs that will change semantically\n"
2508 "in the future.");
2509
2510
2511/*
2512 * ImportWarning extends Warning
2513 */
2514SimpleExtendsException(PyExc_Warning, ImportWarning,
2515 "Base class for warnings about probable mistakes in module imports");
2516
2517
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002518/*
2519 * UnicodeWarning extends Warning
2520 */
2521SimpleExtendsException(PyExc_Warning, UnicodeWarning,
2522 "Base class for warnings about Unicode related problems, mostly\n"
2523 "related to conversion problems.");
2524
Georg Brandl08be72d2010-10-24 15:11:22 +00002525
Guido van Rossum98297ee2007-11-06 21:34:58 +00002526/*
2527 * BytesWarning extends Warning
2528 */
2529SimpleExtendsException(PyExc_Warning, BytesWarning,
2530 "Base class for warnings about bytes and buffer related problems, mostly\n"
2531 "related to conversion from str or comparing to str.");
2532
2533
Georg Brandl08be72d2010-10-24 15:11:22 +00002534/*
Inada Naoki48274832021-03-29 12:28:14 +09002535 * EncodingWarning extends Warning
2536 */
2537SimpleExtendsException(PyExc_Warning, EncodingWarning,
2538 "Base class for warnings about encodings.");
2539
2540
2541/*
Georg Brandl08be72d2010-10-24 15:11:22 +00002542 * ResourceWarning extends Warning
2543 */
2544SimpleExtendsException(PyExc_Warning, ResourceWarning,
2545 "Base class for warnings about resource usage.");
2546
2547
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002548
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002549#ifdef MS_WINDOWS
Antoine Pitrou7faf7052013-03-31 22:48:04 +02002550#include <winsock2.h>
Brian Curtin401f9f32012-05-13 11:19:23 -05002551/* The following constants were added to errno.h in VS2010 but have
2552 preferred WSA equivalents. */
2553#undef EADDRINUSE
2554#undef EADDRNOTAVAIL
2555#undef EAFNOSUPPORT
2556#undef EALREADY
2557#undef ECONNABORTED
2558#undef ECONNREFUSED
2559#undef ECONNRESET
2560#undef EDESTADDRREQ
2561#undef EHOSTUNREACH
2562#undef EINPROGRESS
2563#undef EISCONN
2564#undef ELOOP
2565#undef EMSGSIZE
2566#undef ENETDOWN
2567#undef ENETRESET
2568#undef ENETUNREACH
2569#undef ENOBUFS
2570#undef ENOPROTOOPT
2571#undef ENOTCONN
2572#undef ENOTSOCK
2573#undef EOPNOTSUPP
2574#undef EPROTONOSUPPORT
2575#undef EPROTOTYPE
2576#undef ETIMEDOUT
2577#undef EWOULDBLOCK
2578
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002579#if defined(WSAEALREADY) && !defined(EALREADY)
2580#define EALREADY WSAEALREADY
2581#endif
2582#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
2583#define ECONNABORTED WSAECONNABORTED
2584#endif
2585#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
2586#define ECONNREFUSED WSAECONNREFUSED
2587#endif
2588#if defined(WSAECONNRESET) && !defined(ECONNRESET)
2589#define ECONNRESET WSAECONNRESET
2590#endif
2591#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
2592#define EINPROGRESS WSAEINPROGRESS
2593#endif
2594#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
2595#define ESHUTDOWN WSAESHUTDOWN
2596#endif
2597#if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
2598#define ETIMEDOUT WSAETIMEDOUT
2599#endif
2600#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
2601#define EWOULDBLOCK WSAEWOULDBLOCK
2602#endif
2603#endif /* MS_WINDOWS */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002604
Victor Stinner331a6a52019-05-27 16:39:22 +02002605PyStatus
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002606_PyExc_Init(PyInterpreterState *interp)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002607{
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002608 struct _Py_exc_state *state = &interp->exc_state;
Victor Stinner281cce12020-06-23 22:55:46 +02002609
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002610#define PRE_INIT(TYPE) \
2611 if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
2612 if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002613 return _PyStatus_ERR("exceptions bootstrapping error."); \
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002614 } \
2615 Py_INCREF(PyExc_ ## TYPE); \
2616 }
2617
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002618#define ADD_ERRNO(TYPE, CODE) \
2619 do { \
2620 PyObject *_code = PyLong_FromLong(CODE); \
2621 assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
Serhiy Storchakaed1007c2020-11-21 19:17:46 +02002622 if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
2623 Py_XDECREF(_code); \
Victor Stinner331a6a52019-05-27 16:39:22 +02002624 return _PyStatus_ERR("errmap insertion problem."); \
Serhiy Storchakaed1007c2020-11-21 19:17:46 +02002625 } \
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002626 Py_DECREF(_code); \
2627 } while (0)
2628
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002629 PRE_INIT(BaseException);
2630 PRE_INIT(Exception);
2631 PRE_INIT(TypeError);
2632 PRE_INIT(StopAsyncIteration);
2633 PRE_INIT(StopIteration);
2634 PRE_INIT(GeneratorExit);
2635 PRE_INIT(SystemExit);
2636 PRE_INIT(KeyboardInterrupt);
2637 PRE_INIT(ImportError);
2638 PRE_INIT(ModuleNotFoundError);
2639 PRE_INIT(OSError);
2640 PRE_INIT(EOFError);
2641 PRE_INIT(RuntimeError);
2642 PRE_INIT(RecursionError);
2643 PRE_INIT(NotImplementedError);
2644 PRE_INIT(NameError);
2645 PRE_INIT(UnboundLocalError);
2646 PRE_INIT(AttributeError);
2647 PRE_INIT(SyntaxError);
2648 PRE_INIT(IndentationError);
2649 PRE_INIT(TabError);
2650 PRE_INIT(LookupError);
2651 PRE_INIT(IndexError);
2652 PRE_INIT(KeyError);
2653 PRE_INIT(ValueError);
2654 PRE_INIT(UnicodeError);
2655 PRE_INIT(UnicodeEncodeError);
2656 PRE_INIT(UnicodeDecodeError);
2657 PRE_INIT(UnicodeTranslateError);
2658 PRE_INIT(AssertionError);
2659 PRE_INIT(ArithmeticError);
2660 PRE_INIT(FloatingPointError);
2661 PRE_INIT(OverflowError);
2662 PRE_INIT(ZeroDivisionError);
2663 PRE_INIT(SystemError);
2664 PRE_INIT(ReferenceError);
2665 PRE_INIT(MemoryError);
2666 PRE_INIT(BufferError);
2667 PRE_INIT(Warning);
2668 PRE_INIT(UserWarning);
Inada Naoki48274832021-03-29 12:28:14 +09002669 PRE_INIT(EncodingWarning);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002670 PRE_INIT(DeprecationWarning);
2671 PRE_INIT(PendingDeprecationWarning);
2672 PRE_INIT(SyntaxWarning);
2673 PRE_INIT(RuntimeWarning);
2674 PRE_INIT(FutureWarning);
2675 PRE_INIT(ImportWarning);
2676 PRE_INIT(UnicodeWarning);
2677 PRE_INIT(BytesWarning);
2678 PRE_INIT(ResourceWarning);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002679
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002680 /* OSError subclasses */
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002681 PRE_INIT(ConnectionError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002682
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002683 PRE_INIT(BlockingIOError);
2684 PRE_INIT(BrokenPipeError);
2685 PRE_INIT(ChildProcessError);
2686 PRE_INIT(ConnectionAbortedError);
2687 PRE_INIT(ConnectionRefusedError);
2688 PRE_INIT(ConnectionResetError);
2689 PRE_INIT(FileExistsError);
2690 PRE_INIT(FileNotFoundError);
2691 PRE_INIT(IsADirectoryError);
2692 PRE_INIT(NotADirectoryError);
2693 PRE_INIT(InterruptedError);
2694 PRE_INIT(PermissionError);
2695 PRE_INIT(ProcessLookupError);
2696 PRE_INIT(TimeoutError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002697
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002698 if (preallocate_memerrors() < 0) {
Victor Stinner281cce12020-06-23 22:55:46 +02002699 return _PyStatus_NO_MEMORY();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002700 }
2701
2702 /* Add exceptions to errnomap */
Victor Stinner281cce12020-06-23 22:55:46 +02002703 assert(state->errnomap == NULL);
2704 state->errnomap = PyDict_New();
2705 if (!state->errnomap) {
2706 return _PyStatus_NO_MEMORY();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002707 }
2708
2709 ADD_ERRNO(BlockingIOError, EAGAIN);
2710 ADD_ERRNO(BlockingIOError, EALREADY);
2711 ADD_ERRNO(BlockingIOError, EINPROGRESS);
2712 ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
2713 ADD_ERRNO(BrokenPipeError, EPIPE);
2714#ifdef ESHUTDOWN
2715 ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
2716#endif
2717 ADD_ERRNO(ChildProcessError, ECHILD);
2718 ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
2719 ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
2720 ADD_ERRNO(ConnectionResetError, ECONNRESET);
2721 ADD_ERRNO(FileExistsError, EEXIST);
2722 ADD_ERRNO(FileNotFoundError, ENOENT);
2723 ADD_ERRNO(IsADirectoryError, EISDIR);
2724 ADD_ERRNO(NotADirectoryError, ENOTDIR);
2725 ADD_ERRNO(InterruptedError, EINTR);
2726 ADD_ERRNO(PermissionError, EACCES);
2727 ADD_ERRNO(PermissionError, EPERM);
2728 ADD_ERRNO(ProcessLookupError, ESRCH);
2729 ADD_ERRNO(TimeoutError, ETIMEDOUT);
2730
Victor Stinner331a6a52019-05-27 16:39:22 +02002731 return _PyStatus_OK();
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002732
2733#undef PRE_INIT
2734#undef ADD_ERRNO
2735}
2736
2737
2738/* Add exception types to the builtins module */
Victor Stinner331a6a52019-05-27 16:39:22 +02002739PyStatus
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002740_PyBuiltins_AddExceptions(PyObject *bltinmod)
2741{
2742#define POST_INIT(TYPE) \
2743 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002744 return _PyStatus_ERR("Module dictionary insertion problem."); \
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002745 }
2746
2747#define INIT_ALIAS(NAME, TYPE) \
2748 do { \
2749 Py_INCREF(PyExc_ ## TYPE); \
2750 Py_XDECREF(PyExc_ ## NAME); \
2751 PyExc_ ## NAME = PyExc_ ## TYPE; \
2752 if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \
Victor Stinner331a6a52019-05-27 16:39:22 +02002753 return _PyStatus_ERR("Module dictionary insertion problem."); \
Victor Stinner6d43f6f2019-01-22 21:18:05 +01002754 } \
2755 } while (0)
2756
2757 PyObject *bdict;
2758
Thomas Wouters477c8d52006-05-27 19:21:47 +00002759 bdict = PyModule_GetDict(bltinmod);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002760 if (bdict == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +02002761 return _PyStatus_ERR("exceptions bootstrapping error.");
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002762 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002763
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002764 POST_INIT(BaseException);
2765 POST_INIT(Exception);
2766 POST_INIT(TypeError);
2767 POST_INIT(StopAsyncIteration);
2768 POST_INIT(StopIteration);
2769 POST_INIT(GeneratorExit);
2770 POST_INIT(SystemExit);
2771 POST_INIT(KeyboardInterrupt);
2772 POST_INIT(ImportError);
2773 POST_INIT(ModuleNotFoundError);
2774 POST_INIT(OSError);
2775 INIT_ALIAS(EnvironmentError, OSError);
2776 INIT_ALIAS(IOError, OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002777#ifdef MS_WINDOWS
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002778 INIT_ALIAS(WindowsError, OSError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002779#endif
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002780 POST_INIT(EOFError);
2781 POST_INIT(RuntimeError);
2782 POST_INIT(RecursionError);
2783 POST_INIT(NotImplementedError);
2784 POST_INIT(NameError);
2785 POST_INIT(UnboundLocalError);
2786 POST_INIT(AttributeError);
2787 POST_INIT(SyntaxError);
2788 POST_INIT(IndentationError);
2789 POST_INIT(TabError);
2790 POST_INIT(LookupError);
2791 POST_INIT(IndexError);
2792 POST_INIT(KeyError);
2793 POST_INIT(ValueError);
2794 POST_INIT(UnicodeError);
2795 POST_INIT(UnicodeEncodeError);
2796 POST_INIT(UnicodeDecodeError);
2797 POST_INIT(UnicodeTranslateError);
2798 POST_INIT(AssertionError);
2799 POST_INIT(ArithmeticError);
2800 POST_INIT(FloatingPointError);
2801 POST_INIT(OverflowError);
2802 POST_INIT(ZeroDivisionError);
2803 POST_INIT(SystemError);
2804 POST_INIT(ReferenceError);
2805 POST_INIT(MemoryError);
2806 POST_INIT(BufferError);
2807 POST_INIT(Warning);
2808 POST_INIT(UserWarning);
Inada Naoki48274832021-03-29 12:28:14 +09002809 POST_INIT(EncodingWarning);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002810 POST_INIT(DeprecationWarning);
2811 POST_INIT(PendingDeprecationWarning);
2812 POST_INIT(SyntaxWarning);
2813 POST_INIT(RuntimeWarning);
2814 POST_INIT(FutureWarning);
2815 POST_INIT(ImportWarning);
2816 POST_INIT(UnicodeWarning);
2817 POST_INIT(BytesWarning);
2818 POST_INIT(ResourceWarning);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002819
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002820 /* OSError subclasses */
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002821 POST_INIT(ConnectionError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002822
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002823 POST_INIT(BlockingIOError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002824 POST_INIT(BrokenPipeError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002825 POST_INIT(ChildProcessError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002826 POST_INIT(ConnectionAbortedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002827 POST_INIT(ConnectionRefusedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002828 POST_INIT(ConnectionResetError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002829 POST_INIT(FileExistsError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002830 POST_INIT(FileNotFoundError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002831 POST_INIT(IsADirectoryError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002832 POST_INIT(NotADirectoryError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002833 POST_INIT(InterruptedError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002834 POST_INIT(PermissionError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002835 POST_INIT(ProcessLookupError);
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002836 POST_INIT(TimeoutError);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002837
Victor Stinner331a6a52019-05-27 16:39:22 +02002838 return _PyStatus_OK();
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002839
Victor Stinnerbf4ac2d2019-01-22 17:39:03 +01002840#undef POST_INIT
2841#undef INIT_ALIAS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002842}
2843
2844void
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002845_PyExc_Fini(PyInterpreterState *interp)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002846{
Victor Stinnerbcb094b2021-02-19 15:10:45 +01002847 struct _Py_exc_state *state = &interp->exc_state;
Victor Stinner281cce12020-06-23 22:55:46 +02002848 free_preallocated_memerrors(state);
2849 Py_CLEAR(state->errnomap);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002850}
Nick Coghlan8b097b42013-11-13 23:49:21 +10002851
2852/* Helper to do the equivalent of "raise X from Y" in C, but always using
2853 * the current exception rather than passing one in.
2854 *
2855 * We currently limit this to *only* exceptions that use the BaseException
2856 * tp_init and tp_new methods, since we can be reasonably sure we can wrap
2857 * those correctly without losing data and without losing backwards
2858 * compatibility.
2859 *
2860 * We also aim to rule out *all* exceptions that might be storing additional
2861 * state, whether by having a size difference relative to BaseException,
2862 * additional arguments passed in during construction or by having a
2863 * non-empty instance dict.
2864 *
2865 * We need to be very careful with what we wrap, since changing types to
2866 * a broader exception type would be backwards incompatible for
2867 * existing codecs, and with different init or new method implementations
2868 * may either not support instantiation with PyErr_Format or lose
2869 * information when instantiated that way.
2870 *
2871 * XXX (ncoghlan): This could be made more comprehensive by exploiting the
2872 * fact that exceptions are expected to support pickling. If more builtin
2873 * exceptions (e.g. AttributeError) start to be converted to rich
2874 * exceptions with additional attributes, that's probably a better approach
2875 * to pursue over adding special cases for particular stateful subclasses.
2876 *
2877 * Returns a borrowed reference to the new exception (if any), NULL if the
2878 * existing exception was left in place.
2879 */
2880PyObject *
2881_PyErr_TrySetFromCause(const char *format, ...)
2882{
2883 PyObject* msg_prefix;
2884 PyObject *exc, *val, *tb;
2885 PyTypeObject *caught_type;
Christian Heimes6a3db252013-11-14 01:47:14 +01002886 PyObject **dictptr;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002887 PyObject *instance_args;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002888 Py_ssize_t num_args, caught_type_size, base_exc_size;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002889 PyObject *new_exc, *new_val, *new_tb;
2890 va_list vargs;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002891 int same_basic_size;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002892
Nick Coghlan8b097b42013-11-13 23:49:21 +10002893 PyErr_Fetch(&exc, &val, &tb);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002894 caught_type = (PyTypeObject *)exc;
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002895 /* Ensure type info indicates no extra state is stored at the C level
2896 * and that the type can be reinstantiated using PyErr_Format
2897 */
2898 caught_type_size = caught_type->tp_basicsize;
2899 base_exc_size = _PyExc_BaseException.tp_basicsize;
2900 same_basic_size = (
2901 caught_type_size == base_exc_size ||
2902 (PyType_SUPPORTS_WEAKREFS(caught_type) &&
Victor Stinner12174a52014-08-15 23:17:38 +02002903 (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002904 )
2905 );
Benjamin Peterson079c9982013-11-13 23:25:01 -05002906 if (caught_type->tp_init != (initproc)BaseException_init ||
Nick Coghlan8b097b42013-11-13 23:49:21 +10002907 caught_type->tp_new != BaseException_new ||
Nick Coghlanf1de55f2013-11-19 22:33:10 +10002908 !same_basic_size ||
Benjamin Peterson079c9982013-11-13 23:25:01 -05002909 caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002910 /* We can't be sure we can wrap this safely, since it may contain
2911 * more state than just the exception type. Accordingly, we just
2912 * leave it alone.
2913 */
2914 PyErr_Restore(exc, val, tb);
2915 return NULL;
2916 }
2917
2918 /* Check the args are empty or contain a single string */
2919 PyErr_NormalizeException(&exc, &val, &tb);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002920 instance_args = ((PyBaseExceptionObject *)val)->args;
Nick Coghlan8b097b42013-11-13 23:49:21 +10002921 num_args = PyTuple_GET_SIZE(instance_args);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002922 if (num_args > 1 ||
Nick Coghlan8b097b42013-11-13 23:49:21 +10002923 (num_args == 1 &&
Benjamin Peterson079c9982013-11-13 23:25:01 -05002924 !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002925 /* More than 1 arg, or the one arg we do have isn't a string
2926 */
2927 PyErr_Restore(exc, val, tb);
2928 return NULL;
2929 }
2930
2931 /* Ensure the instance dict is also empty */
Christian Heimes6a3db252013-11-14 01:47:14 +01002932 dictptr = _PyObject_GetDictPtr(val);
Benjamin Peterson079c9982013-11-13 23:25:01 -05002933 if (dictptr != NULL && *dictptr != NULL &&
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03002934 PyDict_GET_SIZE(*dictptr) > 0) {
Nick Coghlan8b097b42013-11-13 23:49:21 +10002935 /* While we could potentially copy a non-empty instance dictionary
2936 * to the replacement exception, for now we take the more
2937 * conservative path of leaving exceptions with attributes set
2938 * alone.
2939 */
2940 PyErr_Restore(exc, val, tb);
2941 return NULL;
2942 }
2943
2944 /* For exceptions that we can wrap safely, we chain the original
2945 * exception to a new one of the exact same type with an
2946 * error message that mentions the additional details and the
2947 * original exception.
2948 *
2949 * It would be nice to wrap OSError and various other exception
2950 * types as well, but that's quite a bit trickier due to the extra
2951 * state potentially stored on OSError instances.
2952 */
Nick Coghlan77b286b2014-01-27 00:53:38 +10002953 /* Ensure the traceback is set correctly on the existing exception */
2954 if (tb != NULL) {
2955 PyException_SetTraceback(val, tb);
2956 Py_DECREF(tb);
2957 }
Benjamin Petersone109ee82013-11-13 23:49:49 -05002958
Christian Heimes507eabd2013-11-14 01:39:35 +01002959#ifdef HAVE_STDARG_PROTOTYPES
2960 va_start(vargs, format);
2961#else
2962 va_start(vargs);
2963#endif
Nick Coghlan8b097b42013-11-13 23:49:21 +10002964 msg_prefix = PyUnicode_FromFormatV(format, vargs);
Christian Heimes507eabd2013-11-14 01:39:35 +01002965 va_end(vargs);
Benjamin Petersone109ee82013-11-13 23:49:49 -05002966 if (msg_prefix == NULL) {
Nick Coghlan4b9b9362013-11-16 00:34:13 +10002967 Py_DECREF(exc);
Benjamin Petersone109ee82013-11-13 23:49:49 -05002968 Py_DECREF(val);
Nick Coghlan8b097b42013-11-13 23:49:21 +10002969 return NULL;
Benjamin Petersone109ee82013-11-13 23:49:49 -05002970 }
Nick Coghlan8b097b42013-11-13 23:49:21 +10002971
2972 PyErr_Format(exc, "%U (%s: %S)",
2973 msg_prefix, Py_TYPE(val)->tp_name, val);
Nick Coghlan4b9b9362013-11-16 00:34:13 +10002974 Py_DECREF(exc);
Benjamin Petersone109ee82013-11-13 23:49:49 -05002975 Py_DECREF(msg_prefix);
Nick Coghlan8b097b42013-11-13 23:49:21 +10002976 PyErr_Fetch(&new_exc, &new_val, &new_tb);
2977 PyErr_NormalizeException(&new_exc, &new_val, &new_tb);
2978 PyException_SetCause(new_val, val);
2979 PyErr_Restore(new_exc, new_val, new_tb);
2980 return new_val;
2981}
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10002982
2983
2984/* To help with migration from Python 2, SyntaxError.__init__ applies some
2985 * heuristics to try to report a more meaningful exception when print and
2986 * exec are used like statements.
2987 *
2988 * The heuristics are currently expected to detect the following cases:
2989 * - top level statement
2990 * - statement in a nested suite
2991 * - trailing section of a one line complex statement
2992 *
2993 * They're currently known not to trigger:
2994 * - after a semi-colon
2995 *
2996 * The error message can be a bit odd in cases where the "arguments" are
2997 * completely illegal syntactically, but that isn't worth the hassle of
2998 * fixing.
2999 *
3000 * We also can't do anything about cases that are legal Python 3 syntax
3001 * but mean something entirely different from what they did in Python 2
3002 * (omitting the arguments entirely, printing items preceded by a unary plus
3003 * or minus, using the stream redirection syntax).
3004 */
3005
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303006
3007// Static helper for setting legacy print error message
3008static int
3009_set_legacy_print_statement_msg(PySyntaxErrorObject *self, Py_ssize_t start)
3010{
Nitish Chandra43c0f1a2018-01-28 16:26:02 +05303011 // PRINT_OFFSET is to remove the `print ` prefix from the data.
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303012 const int PRINT_OFFSET = 6;
Sanyam Khuranad57f26c2018-01-20 08:42:22 +05303013 const int STRIP_BOTH = 2;
Nitish Chandra43c0f1a2018-01-28 16:26:02 +05303014 Py_ssize_t start_pos = start + PRINT_OFFSET;
3015 Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text);
3016 Py_UCS4 semicolon = ';';
3017 Py_ssize_t end_pos = PyUnicode_FindChar(self->text, semicolon,
3018 start_pos, text_len, 1);
3019 if (end_pos < -1) {
3020 return -1;
3021 } else if (end_pos == -1) {
3022 end_pos = text_len;
Sanyam Khuranad57f26c2018-01-20 08:42:22 +05303023 }
Nitish Chandra43c0f1a2018-01-28 16:26:02 +05303024
3025 PyObject *data = PyUnicode_Substring(self->text, start_pos, end_pos);
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303026 if (data == NULL) {
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303027 return -1;
3028 }
Nitish Chandra43c0f1a2018-01-28 16:26:02 +05303029
3030 PyObject *strip_sep_obj = PyUnicode_FromString(" \t\r\n");
3031 if (strip_sep_obj == NULL) {
3032 Py_DECREF(data);
3033 return -1;
3034 }
3035
Sanyam Khuranad57f26c2018-01-20 08:42:22 +05303036 PyObject *new_data = _PyUnicode_XStrip(data, STRIP_BOTH, strip_sep_obj);
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303037 Py_DECREF(data);
3038 Py_DECREF(strip_sep_obj);
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303039 if (new_data == NULL) {
3040 return -1;
3041 }
3042 // gets the modified text_len after stripping `print `
3043 text_len = PyUnicode_GET_LENGTH(new_data);
3044 const char *maybe_end_arg = "";
3045 if (text_len > 0 && PyUnicode_READ_CHAR(new_data, text_len-1) == ',') {
3046 maybe_end_arg = " end=\" \"";
3047 }
3048 PyObject *error_msg = PyUnicode_FromFormat(
3049 "Missing parentheses in call to 'print'. Did you mean print(%U%s)?",
3050 new_data, maybe_end_arg
3051 );
3052 Py_DECREF(new_data);
3053 if (error_msg == NULL)
3054 return -1;
3055
3056 Py_XSETREF(self->msg, error_msg);
3057 return 1;
3058}
3059
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10003060static int
3061_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start)
3062{
3063 /* Return values:
3064 * -1: an error occurred
3065 * 0: nothing happened
3066 * 1: the check triggered & the error message was changed
3067 */
3068 static PyObject *print_prefix = NULL;
3069 static PyObject *exec_prefix = NULL;
Zackery Spytza4b48f12018-10-12 02:20:59 -06003070 Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text), match;
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10003071 int kind = PyUnicode_KIND(self->text);
Serhiy Storchakacd8295f2020-04-11 10:48:40 +03003072 const void *data = PyUnicode_DATA(self->text);
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10003073
3074 /* Ignore leading whitespace */
3075 while (start < text_len) {
3076 Py_UCS4 ch = PyUnicode_READ(kind, data, start);
3077 if (!Py_UNICODE_ISSPACE(ch))
3078 break;
3079 start++;
3080 }
3081 /* Checking against an empty or whitespace-only part of the string */
3082 if (start == text_len) {
3083 return 0;
3084 }
3085
3086 /* Check for legacy print statements */
3087 if (print_prefix == NULL) {
3088 print_prefix = PyUnicode_InternFromString("print ");
3089 if (print_prefix == NULL) {
3090 return -1;
3091 }
3092 }
Zackery Spytza4b48f12018-10-12 02:20:59 -06003093 match = PyUnicode_Tailmatch(self->text, print_prefix,
3094 start, text_len, -1);
3095 if (match == -1) {
3096 return -1;
3097 }
3098 if (match) {
Sanyam Khurana3a7f0352017-06-20 19:01:32 +05303099 return _set_legacy_print_statement_msg(self, start);
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10003100 }
3101
3102 /* Check for legacy exec statements */
3103 if (exec_prefix == NULL) {
3104 exec_prefix = PyUnicode_InternFromString("exec ");
3105 if (exec_prefix == NULL) {
3106 return -1;
3107 }
3108 }
Zackery Spytza4b48f12018-10-12 02:20:59 -06003109 match = PyUnicode_Tailmatch(self->text, exec_prefix, start, text_len, -1);
3110 if (match == -1) {
3111 return -1;
3112 }
3113 if (match) {
3114 PyObject *msg = PyUnicode_FromString("Missing parentheses in call "
3115 "to 'exec'");
3116 if (msg == NULL) {
3117 return -1;
3118 }
3119 Py_XSETREF(self->msg, msg);
Nick Coghlan5b1fdc12014-06-16 19:48:02 +10003120 return 1;
3121 }
3122 /* Fall back to the default error message */
3123 return 0;
3124}
3125
3126static int
3127_report_missing_parentheses(PySyntaxErrorObject *self)
3128{
3129 Py_UCS4 left_paren = 40;
3130 Py_ssize_t left_paren_index;
3131 Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text);
3132 int legacy_check_result = 0;
3133
3134 /* Skip entirely if there is an opening parenthesis */
3135 left_paren_index = PyUnicode_FindChar(self->text, left_paren,
3136 0, text_len, 1);
3137 if (left_paren_index < -1) {
3138 return -1;
3139 }
3140 if (left_paren_index != -1) {
3141 /* Use default error message for any line with an opening paren */
3142 return 0;
3143 }
3144 /* Handle the simple statement case */
3145 legacy_check_result = _check_for_legacy_statements(self, 0);
3146 if (legacy_check_result < 0) {
3147 return -1;
3148
3149 }
3150 if (legacy_check_result == 0) {
3151 /* Handle the one-line complex statement case */
3152 Py_UCS4 colon = 58;
3153 Py_ssize_t colon_index;
3154 colon_index = PyUnicode_FindChar(self->text, colon,
3155 0, text_len, 1);
3156 if (colon_index < -1) {
3157 return -1;
3158 }
3159 if (colon_index >= 0 && colon_index < text_len) {
3160 /* Check again, starting from just after the colon */
3161 if (_check_for_legacy_statements(self, colon_index+1) < 0) {
3162 return -1;
3163 }
3164 }
3165 }
3166 return 0;
3167}