Line data Source code
1 : /*
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 :
7 : #define PY_SSIZE_T_CLEAN
8 : #include <Python.h>
9 : #include <stdbool.h>
10 : #include "pycore_ceval.h" // _Py_EnterRecursiveCall
11 : #include "pycore_exceptions.h" // struct _Py_exc_state
12 : #include "pycore_initconfig.h"
13 : #include "pycore_object.h"
14 : #include "structmember.h" // PyMemberDef
15 : #include "osdefs.h" // SEP
16 :
17 :
18 : /* Compatibility aliases */
19 : PyObject *PyExc_EnvironmentError = NULL; // borrowed ref
20 : PyObject *PyExc_IOError = NULL; // borrowed ref
21 : #ifdef MS_WINDOWS
22 : PyObject *PyExc_WindowsError = NULL; // borrowed ref
23 : #endif
24 :
25 :
26 : static struct _Py_exc_state*
27 1495020 : get_exc_state(void)
28 : {
29 1495020 : PyInterpreterState *interp = _PyInterpreterState_GET();
30 1495020 : return &interp->exc_state;
31 : }
32 :
33 :
34 : /* NOTE: If the exception class hierarchy changes, don't forget to update
35 : * Lib/test/exception_hierarchy.txt
36 : */
37 :
38 : /*
39 : * BaseException
40 : */
41 : static PyObject *
42 4882480 : BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
43 : {
44 : PyBaseExceptionObject *self;
45 :
46 4882480 : self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
47 4882480 : if (!self)
48 1 : return NULL;
49 : /* the dict is created on the fly in PyObject_GenericSetAttr */
50 4882480 : self->dict = NULL;
51 4882480 : self->notes = NULL;
52 4882480 : self->traceback = self->cause = self->context = NULL;
53 4882480 : self->suppress_context = 0;
54 :
55 4882480 : if (args) {
56 4835080 : self->args = args;
57 4835080 : Py_INCREF(args);
58 4835080 : return (PyObject *)self;
59 : }
60 :
61 47408 : self->args = PyTuple_New(0);
62 47408 : if (!self->args) {
63 0 : Py_DECREF(self);
64 0 : return NULL;
65 : }
66 :
67 47408 : return (PyObject *)self;
68 : }
69 :
70 : static int
71 4798170 : BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
72 : {
73 4798170 : if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
74 1 : return -1;
75 :
76 4798170 : Py_INCREF(args);
77 4798170 : Py_XSETREF(self->args, args);
78 :
79 4798170 : return 0;
80 : }
81 :
82 : static int
83 6273470 : BaseException_clear(PyBaseExceptionObject *self)
84 : {
85 6273470 : Py_CLEAR(self->dict);
86 6273470 : Py_CLEAR(self->args);
87 6273470 : Py_CLEAR(self->notes);
88 6273470 : Py_CLEAR(self->traceback);
89 6273470 : Py_CLEAR(self->cause);
90 6273470 : Py_CLEAR(self->context);
91 6273470 : return 0;
92 : }
93 :
94 : static void
95 1995650 : BaseException_dealloc(PyBaseExceptionObject *self)
96 : {
97 1995650 : PyObject_GC_UnTrack(self);
98 : // bpo-44348: The trashcan mechanism prevents stack overflow when deleting
99 : // long chains of exceptions. For example, exceptions can be chained
100 : // through the __context__ attributes or the __traceback__ attribute.
101 1995650 : Py_TRASHCAN_BEGIN(self, BaseException_dealloc)
102 1995200 : BaseException_clear(self);
103 1995200 : Py_TYPE(self)->tp_free((PyObject *)self);
104 1995200 : Py_TRASHCAN_END
105 1995650 : }
106 :
107 : static int
108 101275 : BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
109 : {
110 101275 : Py_VISIT(self->dict);
111 101275 : Py_VISIT(self->args);
112 101275 : Py_VISIT(self->notes);
113 101275 : Py_VISIT(self->traceback);
114 101275 : Py_VISIT(self->cause);
115 101275 : Py_VISIT(self->context);
116 101275 : return 0;
117 : }
118 :
119 : static PyObject *
120 20650 : BaseException_str(PyBaseExceptionObject *self)
121 : {
122 20650 : switch (PyTuple_GET_SIZE(self->args)) {
123 213 : case 0:
124 213 : return PyUnicode_FromString("");
125 20418 : case 1:
126 20418 : return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
127 19 : default:
128 19 : return PyObject_Str(self->args);
129 : }
130 : }
131 :
132 : static PyObject *
133 2382 : BaseException_repr(PyBaseExceptionObject *self)
134 : {
135 2382 : const char *name = _PyType_Name(Py_TYPE(self));
136 2382 : if (PyTuple_GET_SIZE(self->args) == 1)
137 1797 : return PyUnicode_FromFormat("%s(%R)", name,
138 1797 : PyTuple_GET_ITEM(self->args, 0));
139 : else
140 585 : return PyUnicode_FromFormat("%s%R", name, self->args);
141 : }
142 :
143 : /* Pickling support */
144 : static PyObject *
145 318 : BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
146 : {
147 318 : if (self->args && self->dict)
148 100 : return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
149 : else
150 218 : return PyTuple_Pack(2, Py_TYPE(self), self->args);
151 : }
152 :
153 : /*
154 : * Needed for backward compatibility, since exceptions used to store
155 : * all their attributes in the __dict__. Code is taken from cPickle's
156 : * load_build function.
157 : */
158 : static PyObject *
159 164 : BaseException_setstate(PyObject *self, PyObject *state)
160 : {
161 : PyObject *d_key, *d_value;
162 164 : Py_ssize_t i = 0;
163 :
164 164 : if (state != Py_None) {
165 164 : if (!PyDict_Check(state)) {
166 0 : PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
167 0 : return NULL;
168 : }
169 552 : while (PyDict_Next(state, &i, &d_key, &d_value)) {
170 388 : if (PyObject_SetAttr(self, d_key, d_value) < 0)
171 0 : return NULL;
172 : }
173 : }
174 164 : Py_RETURN_NONE;
175 : }
176 :
177 : static PyObject *
178 187822 : BaseException_with_traceback(PyObject *self, PyObject *tb) {
179 187822 : if (PyException_SetTraceback(self, tb))
180 0 : return NULL;
181 :
182 187822 : Py_INCREF(self);
183 187822 : return self;
184 : }
185 :
186 : PyDoc_STRVAR(with_traceback_doc,
187 : "Exception.with_traceback(tb) --\n\
188 : set self.__traceback__ to tb and return self.");
189 :
190 : static inline PyBaseExceptionObject*
191 61337700 : _PyBaseExceptionObject_cast(PyObject *exc)
192 : {
193 61337700 : assert(PyExceptionInstance_Check(exc));
194 61337700 : return (PyBaseExceptionObject *)exc;
195 : }
196 :
197 : static PyObject *
198 57 : BaseException_add_note(PyObject *self, PyObject *note)
199 : {
200 57 : if (!PyUnicode_Check(note)) {
201 3 : PyErr_Format(PyExc_TypeError,
202 : "note must be a str, not '%s'",
203 3 : Py_TYPE(note)->tp_name);
204 3 : return NULL;
205 : }
206 :
207 54 : if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) {
208 32 : PyObject *new_notes = PyList_New(0);
209 32 : if (new_notes == NULL) {
210 0 : return NULL;
211 : }
212 32 : if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) {
213 0 : Py_DECREF(new_notes);
214 0 : return NULL;
215 : }
216 32 : Py_DECREF(new_notes);
217 : }
218 54 : PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__));
219 54 : if (notes == NULL) {
220 0 : return NULL;
221 : }
222 54 : if (!PyList_Check(notes)) {
223 3 : Py_DECREF(notes);
224 3 : PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
225 3 : return NULL;
226 : }
227 51 : if (PyList_Append(notes, note) < 0) {
228 0 : Py_DECREF(notes);
229 0 : return NULL;
230 : }
231 51 : Py_DECREF(notes);
232 51 : Py_RETURN_NONE;
233 : }
234 :
235 : PyDoc_STRVAR(add_note_doc,
236 : "Exception.add_note(note) --\n\
237 : add a note to the exception");
238 :
239 : static PyMethodDef BaseException_methods[] = {
240 : {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
241 : {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
242 : {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
243 : with_traceback_doc},
244 : {"add_note", (PyCFunction)BaseException_add_note, METH_O,
245 : add_note_doc},
246 : {NULL, NULL, 0, NULL},
247 : };
248 :
249 : static PyObject *
250 2472 : BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
251 : {
252 2472 : if (self->args == NULL) {
253 0 : Py_RETURN_NONE;
254 : }
255 2472 : Py_INCREF(self->args);
256 2472 : return self->args;
257 : }
258 :
259 : static int
260 25751 : BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
261 : {
262 : PyObject *seq;
263 25751 : if (val == NULL) {
264 0 : PyErr_SetString(PyExc_TypeError, "args may not be deleted");
265 0 : return -1;
266 : }
267 25751 : seq = PySequence_Tuple(val);
268 25751 : if (!seq)
269 0 : return -1;
270 25751 : Py_XSETREF(self->args, seq);
271 25751 : return 0;
272 : }
273 :
274 : static PyObject *
275 18242 : BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
276 : {
277 18242 : if (self->traceback == NULL) {
278 10279 : Py_RETURN_NONE;
279 : }
280 7963 : Py_INCREF(self->traceback);
281 7963 : return self->traceback;
282 : }
283 :
284 : static int
285 5534570 : BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
286 : {
287 5534570 : if (tb == NULL) {
288 0 : PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
289 0 : return -1;
290 : }
291 5534570 : else if (!(tb == Py_None || PyTraceBack_Check(tb))) {
292 1 : PyErr_SetString(PyExc_TypeError,
293 : "__traceback__ must be a traceback or None");
294 1 : return -1;
295 : }
296 :
297 5534570 : Py_INCREF(tb);
298 5534570 : Py_XSETREF(self->traceback, tb);
299 5534570 : return 0;
300 : }
301 :
302 : static PyObject *
303 19829 : BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
304 : {
305 19829 : PyObject *res = PyException_GetContext(self);
306 19829 : if (res)
307 6494 : return res; /* new reference already returned above */
308 13335 : Py_RETURN_NONE;
309 : }
310 :
311 : static int
312 131 : BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
313 : {
314 131 : if (arg == NULL) {
315 1 : PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
316 1 : return -1;
317 130 : } else if (arg == Py_None) {
318 100 : arg = NULL;
319 30 : } else if (!PyExceptionInstance_Check(arg)) {
320 1 : PyErr_SetString(PyExc_TypeError, "exception context must be None "
321 : "or derive from BaseException");
322 1 : return -1;
323 : } else {
324 : /* PyException_SetContext steals this reference */
325 29 : Py_INCREF(arg);
326 : }
327 129 : PyException_SetContext(self, arg);
328 129 : return 0;
329 : }
330 :
331 : static PyObject *
332 14182 : BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
333 : {
334 14182 : PyObject *res = PyException_GetCause(self);
335 14182 : if (res)
336 210 : return res; /* new reference already returned above */
337 13972 : Py_RETURN_NONE;
338 : }
339 :
340 : static int
341 298 : BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
342 : {
343 298 : if (arg == NULL) {
344 1 : PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
345 1 : return -1;
346 297 : } else if (arg == Py_None) {
347 1 : arg = NULL;
348 296 : } else if (!PyExceptionInstance_Check(arg)) {
349 1 : PyErr_SetString(PyExc_TypeError, "exception cause must be None "
350 : "or derive from BaseException");
351 1 : return -1;
352 : } else {
353 : /* PyException_SetCause steals this reference */
354 295 : Py_INCREF(arg);
355 : }
356 296 : PyException_SetCause(self, arg);
357 296 : return 0;
358 : }
359 :
360 :
361 : static PyGetSetDef BaseException_getset[] = {
362 : {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
363 : {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
364 : {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
365 : {"__context__", BaseException_get_context,
366 : BaseException_set_context, PyDoc_STR("exception context")},
367 : {"__cause__", BaseException_get_cause,
368 : BaseException_set_cause, PyDoc_STR("exception cause")},
369 : {NULL},
370 : };
371 :
372 :
373 : PyObject *
374 2955510 : PyException_GetTraceback(PyObject *self)
375 : {
376 2955510 : PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
377 2955510 : Py_XINCREF(base_self->traceback);
378 2955510 : return base_self->traceback;
379 : }
380 :
381 :
382 : int
383 5532520 : PyException_SetTraceback(PyObject *self, PyObject *tb)
384 : {
385 5532520 : return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
386 : }
387 :
388 : PyObject *
389 15067 : PyException_GetCause(PyObject *self)
390 : {
391 15067 : PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
392 15067 : Py_XINCREF(cause);
393 15067 : return cause;
394 : }
395 :
396 : /* Steals a reference to cause */
397 : void
398 122908 : PyException_SetCause(PyObject *self, PyObject *cause)
399 : {
400 122908 : PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
401 122908 : base_self->suppress_context = 1;
402 122908 : Py_XSETREF(base_self->cause, cause);
403 122908 : }
404 :
405 : PyObject *
406 51660400 : PyException_GetContext(PyObject *self)
407 : {
408 51660400 : PyObject *context = _PyBaseExceptionObject_cast(self)->context;
409 51660400 : Py_XINCREF(context);
410 51660400 : return context;
411 : }
412 :
413 : /* Steals a reference to context */
414 : void
415 525653 : PyException_SetContext(PyObject *self, PyObject *context)
416 : {
417 525653 : Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
418 525653 : }
419 :
420 : const char *
421 0 : PyExceptionClass_Name(PyObject *ob)
422 : {
423 0 : assert(PyExceptionClass_Check(ob));
424 0 : return ((PyTypeObject*)ob)->tp_name;
425 : }
426 :
427 : static struct PyMemberDef BaseException_members[] = {
428 : {"__suppress_context__", T_BOOL,
429 : offsetof(PyBaseExceptionObject, suppress_context)},
430 : {NULL}
431 : };
432 :
433 :
434 : static PyTypeObject _PyExc_BaseException = {
435 : PyVarObject_HEAD_INIT(NULL, 0)
436 : "BaseException", /*tp_name*/
437 : sizeof(PyBaseExceptionObject), /*tp_basicsize*/
438 : 0, /*tp_itemsize*/
439 : (destructor)BaseException_dealloc, /*tp_dealloc*/
440 : 0, /*tp_vectorcall_offset*/
441 : 0, /*tp_getattr*/
442 : 0, /*tp_setattr*/
443 : 0, /*tp_as_async*/
444 : (reprfunc)BaseException_repr, /*tp_repr*/
445 : 0, /*tp_as_number*/
446 : 0, /*tp_as_sequence*/
447 : 0, /*tp_as_mapping*/
448 : 0, /*tp_hash */
449 : 0, /*tp_call*/
450 : (reprfunc)BaseException_str, /*tp_str*/
451 : PyObject_GenericGetAttr, /*tp_getattro*/
452 : PyObject_GenericSetAttr, /*tp_setattro*/
453 : 0, /*tp_as_buffer*/
454 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
455 : Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
456 : PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
457 : (traverseproc)BaseException_traverse, /* tp_traverse */
458 : (inquiry)BaseException_clear, /* tp_clear */
459 : 0, /* tp_richcompare */
460 : 0, /* tp_weaklistoffset */
461 : 0, /* tp_iter */
462 : 0, /* tp_iternext */
463 : BaseException_methods, /* tp_methods */
464 : BaseException_members, /* tp_members */
465 : BaseException_getset, /* tp_getset */
466 : 0, /* tp_base */
467 : 0, /* tp_dict */
468 : 0, /* tp_descr_get */
469 : 0, /* tp_descr_set */
470 : offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
471 : (initproc)BaseException_init, /* tp_init */
472 : 0, /* tp_alloc */
473 : BaseException_new, /* tp_new */
474 : };
475 : /* the CPython API expects exceptions to be (PyObject *) - both a hold-over
476 : from the previous implementation and also allowing Python objects to be used
477 : in the API */
478 : PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
479 :
480 : /* note these macros omit the last semicolon so the macro invocation may
481 : * include it and not look strange.
482 : */
483 : #define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
484 : static PyTypeObject _PyExc_ ## EXCNAME = { \
485 : PyVarObject_HEAD_INIT(NULL, 0) \
486 : # EXCNAME, \
487 : sizeof(PyBaseExceptionObject), \
488 : 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
489 : 0, 0, 0, 0, 0, 0, 0, \
490 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
491 : PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
492 : (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
493 : 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
494 : (initproc)BaseException_init, 0, BaseException_new,\
495 : }; \
496 : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
497 :
498 : #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
499 : static PyTypeObject _PyExc_ ## EXCNAME = { \
500 : PyVarObject_HEAD_INIT(NULL, 0) \
501 : # EXCNAME, \
502 : sizeof(Py ## EXCSTORE ## Object), \
503 : 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
504 : 0, 0, 0, 0, 0, \
505 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
506 : PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
507 : (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
508 : 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
509 : (initproc)EXCSTORE ## _init, 0, 0, \
510 : }; \
511 : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
512 :
513 : #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
514 : EXCMETHODS, EXCMEMBERS, EXCGETSET, \
515 : EXCSTR, EXCDOC) \
516 : static PyTypeObject _PyExc_ ## EXCNAME = { \
517 : PyVarObject_HEAD_INIT(NULL, 0) \
518 : # EXCNAME, \
519 : sizeof(Py ## EXCSTORE ## Object), 0, \
520 : (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
521 : (reprfunc)EXCSTR, 0, 0, 0, \
522 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
523 : PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
524 : (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
525 : EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
526 : 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
527 : (initproc)EXCSTORE ## _init, 0, EXCNEW,\
528 : }; \
529 : PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
530 :
531 :
532 : /*
533 : * Exception extends BaseException
534 : */
535 : SimpleExtendsException(PyExc_BaseException, Exception,
536 : "Common base class for all non-exit exceptions.");
537 :
538 :
539 : /*
540 : * TypeError extends Exception
541 : */
542 : SimpleExtendsException(PyExc_Exception, TypeError,
543 : "Inappropriate argument type.");
544 :
545 :
546 : /*
547 : * StopAsyncIteration extends Exception
548 : */
549 : SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
550 : "Signal the end from iterator.__anext__().");
551 :
552 :
553 : /*
554 : * StopIteration extends Exception
555 : */
556 :
557 : static PyMemberDef StopIteration_members[] = {
558 : {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
559 : PyDoc_STR("generator return value")},
560 : {NULL} /* Sentinel */
561 : };
562 :
563 : static int
564 1160820 : StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds)
565 : {
566 1160820 : Py_ssize_t size = PyTuple_GET_SIZE(args);
567 : PyObject *value;
568 :
569 1160820 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
570 0 : return -1;
571 1160820 : Py_CLEAR(self->value);
572 1160820 : if (size > 0)
573 844 : value = PyTuple_GET_ITEM(args, 0);
574 : else
575 1159970 : value = Py_None;
576 1160820 : Py_INCREF(value);
577 1160820 : self->value = value;
578 1160820 : return 0;
579 : }
580 :
581 : static int
582 1160820 : StopIteration_clear(PyStopIterationObject *self)
583 : {
584 1160820 : Py_CLEAR(self->value);
585 1160820 : return BaseException_clear((PyBaseExceptionObject *)self);
586 : }
587 :
588 : static void
589 1160820 : StopIteration_dealloc(PyStopIterationObject *self)
590 : {
591 1160820 : PyObject_GC_UnTrack(self);
592 1160820 : StopIteration_clear(self);
593 1160820 : Py_TYPE(self)->tp_free((PyObject *)self);
594 1160820 : }
595 :
596 : static int
597 68 : StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
598 : {
599 68 : Py_VISIT(self->value);
600 68 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
601 : }
602 :
603 : ComplexExtendsException(
604 : PyExc_Exception, /* base */
605 : StopIteration, /* name */
606 : StopIteration, /* prefix for *_init, etc */
607 : 0, /* new */
608 : 0, /* methods */
609 : StopIteration_members, /* members */
610 : 0, /* getset */
611 : 0, /* str */
612 : "Signal the end from iterator.__next__()."
613 : );
614 :
615 :
616 : /*
617 : * GeneratorExit extends BaseException
618 : */
619 : SimpleExtendsException(PyExc_BaseException, GeneratorExit,
620 : "Request that a generator exit.");
621 :
622 :
623 : /*
624 : * SystemExit extends BaseException
625 : */
626 :
627 : static int
628 3643 : SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
629 : {
630 3643 : Py_ssize_t size = PyTuple_GET_SIZE(args);
631 :
632 3643 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
633 0 : return -1;
634 :
635 3643 : if (size == 0)
636 66 : return 0;
637 3577 : if (size == 1) {
638 3576 : Py_INCREF(PyTuple_GET_ITEM(args, 0));
639 3576 : Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
640 : }
641 : else { /* size > 1 */
642 1 : Py_INCREF(args);
643 1 : Py_XSETREF(self->code, args);
644 : }
645 3577 : return 0;
646 : }
647 :
648 : static int
649 3647 : SystemExit_clear(PySystemExitObject *self)
650 : {
651 3647 : Py_CLEAR(self->code);
652 3647 : return BaseException_clear((PyBaseExceptionObject *)self);
653 : }
654 :
655 : static void
656 3643 : SystemExit_dealloc(PySystemExitObject *self)
657 : {
658 3643 : _PyObject_GC_UNTRACK(self);
659 3643 : SystemExit_clear(self);
660 3643 : Py_TYPE(self)->tp_free((PyObject *)self);
661 3643 : }
662 :
663 : static int
664 116 : SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
665 : {
666 116 : Py_VISIT(self->code);
667 116 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
668 : }
669 :
670 : static PyMemberDef SystemExit_members[] = {
671 : {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
672 : PyDoc_STR("exception code")},
673 : {NULL} /* Sentinel */
674 : };
675 :
676 : ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
677 : 0, 0, SystemExit_members, 0, 0,
678 : "Request to exit from the interpreter.");
679 :
680 : /*
681 : * BaseExceptionGroup extends BaseException
682 : * ExceptionGroup extends BaseExceptionGroup and Exception
683 : */
684 :
685 :
686 : static inline PyBaseExceptionGroupObject*
687 13608 : _PyBaseExceptionGroupObject_cast(PyObject *exc)
688 : {
689 13608 : assert(_PyBaseExceptionGroup_Check(exc));
690 13608 : return (PyBaseExceptionGroupObject *)exc;
691 : }
692 :
693 : static PyObject *
694 10767 : BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
695 : {
696 10767 : struct _Py_exc_state *state = get_exc_state();
697 10767 : PyTypeObject *PyExc_ExceptionGroup =
698 : (PyTypeObject*)state->PyExc_ExceptionGroup;
699 :
700 10767 : PyObject *message = NULL;
701 10767 : PyObject *exceptions = NULL;
702 :
703 10767 : if (!PyArg_ParseTuple(args,
704 : "UO:BaseExceptionGroup.__new__",
705 : &message,
706 : &exceptions)) {
707 7 : return NULL;
708 : }
709 :
710 10760 : if (!PySequence_Check(exceptions)) {
711 2 : PyErr_SetString(
712 : PyExc_TypeError,
713 : "second argument (exceptions) must be a sequence");
714 2 : return NULL;
715 : }
716 :
717 10758 : exceptions = PySequence_Tuple(exceptions);
718 10758 : if (!exceptions) {
719 0 : return NULL;
720 : }
721 :
722 : /* We are now holding a ref to the exceptions tuple */
723 :
724 10758 : Py_ssize_t numexcs = PyTuple_GET_SIZE(exceptions);
725 10758 : if (numexcs == 0) {
726 1 : PyErr_SetString(
727 : PyExc_ValueError,
728 : "second argument (exceptions) must be a non-empty sequence");
729 1 : goto error;
730 : }
731 :
732 10757 : bool nested_base_exceptions = false;
733 27924 : for (Py_ssize_t i = 0; i < numexcs; i++) {
734 17169 : PyObject *exc = PyTuple_GET_ITEM(exceptions, i);
735 17169 : if (!exc) {
736 0 : goto error;
737 : }
738 17169 : if (!PyExceptionInstance_Check(exc)) {
739 2 : PyErr_Format(
740 : PyExc_ValueError,
741 : "Item %d of second argument (exceptions) is not an exception",
742 : i);
743 2 : goto error;
744 : }
745 17167 : int is_nonbase_exception = PyObject_IsInstance(exc, PyExc_Exception);
746 17167 : if (is_nonbase_exception < 0) {
747 0 : goto error;
748 : }
749 17167 : else if (is_nonbase_exception == 0) {
750 23 : nested_base_exceptions = true;
751 : }
752 : }
753 :
754 10755 : PyTypeObject *cls = type;
755 10755 : if (cls == PyExc_ExceptionGroup) {
756 10227 : if (nested_base_exceptions) {
757 1 : PyErr_SetString(PyExc_TypeError,
758 : "Cannot nest BaseExceptions in an ExceptionGroup");
759 1 : goto error;
760 : }
761 : }
762 528 : else if (cls == (PyTypeObject*)PyExc_BaseExceptionGroup) {
763 486 : if (!nested_base_exceptions) {
764 : /* All nested exceptions are Exception subclasses,
765 : * wrap them in an ExceptionGroup
766 : */
767 468 : cls = PyExc_ExceptionGroup;
768 : }
769 : }
770 : else {
771 : /* Do nothing - we don't interfere with subclasses */
772 : }
773 :
774 10754 : if (!cls) {
775 : /* Don't crash during interpreter shutdown
776 : * (PyExc_ExceptionGroup may have been cleared)
777 : */
778 0 : cls = (PyTypeObject*)PyExc_BaseExceptionGroup;
779 : }
780 : PyBaseExceptionGroupObject *self =
781 10754 : _PyBaseExceptionGroupObject_cast(BaseException_new(cls, args, kwds));
782 10754 : if (!self) {
783 0 : goto error;
784 : }
785 :
786 10754 : self->msg = Py_NewRef(message);
787 10754 : self->excs = exceptions;
788 10754 : return (PyObject*)self;
789 4 : error:
790 4 : Py_DECREF(exceptions);
791 4 : return NULL;
792 : }
793 :
794 : PyObject *
795 50 : _PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs)
796 : {
797 50 : PyObject *msg = PyUnicode_FromString(msg_str);
798 50 : if (!msg) {
799 0 : return NULL;
800 : }
801 50 : PyObject *args = PyTuple_Pack(2, msg, excs);
802 50 : Py_DECREF(msg);
803 50 : if (!args) {
804 0 : return NULL;
805 : }
806 50 : PyObject *result = PyObject_CallObject(PyExc_BaseExceptionGroup, args);
807 50 : Py_DECREF(args);
808 50 : return result;
809 : }
810 :
811 : static int
812 10754 : BaseExceptionGroup_init(PyBaseExceptionGroupObject *self,
813 : PyObject *args, PyObject *kwds)
814 : {
815 10754 : if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) {
816 0 : return -1;
817 : }
818 10754 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) {
819 0 : return -1;
820 : }
821 10754 : return 0;
822 : }
823 :
824 : static int
825 10886 : BaseExceptionGroup_clear(PyBaseExceptionGroupObject *self)
826 : {
827 10886 : Py_CLEAR(self->msg);
828 10886 : Py_CLEAR(self->excs);
829 10886 : return BaseException_clear((PyBaseExceptionObject *)self);
830 : }
831 :
832 : static void
833 10754 : BaseExceptionGroup_dealloc(PyBaseExceptionGroupObject *self)
834 : {
835 10754 : _PyObject_GC_UNTRACK(self);
836 10754 : BaseExceptionGroup_clear(self);
837 10754 : Py_TYPE(self)->tp_free((PyObject *)self);
838 10754 : }
839 :
840 : static int
841 28364 : BaseExceptionGroup_traverse(PyBaseExceptionGroupObject *self,
842 : visitproc visit, void *arg)
843 : {
844 28364 : Py_VISIT(self->msg);
845 28364 : Py_VISIT(self->excs);
846 28364 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
847 : }
848 :
849 : static PyObject *
850 4081 : BaseExceptionGroup_str(PyBaseExceptionGroupObject *self)
851 : {
852 4081 : assert(self->msg);
853 4081 : assert(PyUnicode_Check(self->msg));
854 :
855 4081 : assert(PyTuple_CheckExact(self->excs));
856 4081 : Py_ssize_t num_excs = PyTuple_Size(self->excs);
857 4081 : return PyUnicode_FromFormat(
858 : "%S (%zd sub-exception%s)",
859 : self->msg, num_excs, num_excs > 1 ? "s" : "");
860 : }
861 :
862 : static PyObject *
863 416 : BaseExceptionGroup_derive(PyObject *self_, PyObject *args)
864 : {
865 416 : PyBaseExceptionGroupObject *self = _PyBaseExceptionGroupObject_cast(self_);
866 416 : PyObject *excs = NULL;
867 416 : if (!PyArg_ParseTuple(args, "O", &excs)) {
868 0 : return NULL;
869 : }
870 416 : PyObject *init_args = PyTuple_Pack(2, self->msg, excs);
871 416 : if (!init_args) {
872 0 : return NULL;
873 : }
874 416 : PyObject *eg = PyObject_CallObject(
875 : PyExc_BaseExceptionGroup, init_args);
876 416 : Py_DECREF(init_args);
877 416 : return eg;
878 : }
879 :
880 : static int
881 601 : exceptiongroup_subset(
882 : PyBaseExceptionGroupObject *_orig, PyObject *excs, PyObject **result)
883 : {
884 : /* Sets *result to an ExceptionGroup wrapping excs with metadata from
885 : * _orig. If excs is empty, sets *result to NULL.
886 : * Returns 0 on success and -1 on error.
887 :
888 : * This function is used by split() to construct the match/rest parts,
889 : * so excs is the matching or non-matching sub-sequence of orig->excs
890 : * (this function does not verify that it is a subsequence).
891 : */
892 601 : PyObject *orig = (PyObject *)_orig;
893 :
894 601 : *result = NULL;
895 601 : Py_ssize_t num_excs = PySequence_Size(excs);
896 601 : if (num_excs < 0) {
897 0 : return -1;
898 : }
899 601 : else if (num_excs == 0) {
900 161 : return 0;
901 : }
902 :
903 440 : PyObject *eg = PyObject_CallMethod(
904 : orig, "derive", "(O)", excs);
905 440 : if (!eg) {
906 0 : return -1;
907 : }
908 :
909 440 : if (!_PyBaseExceptionGroup_Check(eg)) {
910 0 : PyErr_SetString(PyExc_TypeError,
911 : "derive must return an instance of BaseExceptionGroup");
912 0 : goto error;
913 : }
914 :
915 : /* Now we hold a reference to the new eg */
916 :
917 440 : PyObject *tb = PyException_GetTraceback(orig);
918 440 : if (tb) {
919 328 : int res = PyException_SetTraceback(eg, tb);
920 328 : Py_DECREF(tb);
921 328 : if (res < 0) {
922 0 : goto error;
923 : }
924 : }
925 440 : PyException_SetContext(eg, PyException_GetContext(orig));
926 440 : PyException_SetCause(eg, PyException_GetCause(orig));
927 :
928 440 : if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) {
929 15 : PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__));
930 15 : if (notes == NULL) {
931 0 : goto error;
932 : }
933 15 : if (PySequence_Check(notes)) {
934 : /* Make a copy so the parts have independent notes lists. */
935 13 : PyObject *notes_copy = PySequence_List(notes);
936 13 : Py_DECREF(notes);
937 13 : if (notes_copy == NULL) {
938 0 : goto error;
939 : }
940 13 : int res = PyObject_SetAttr(eg, &_Py_ID(__notes__), notes_copy);
941 13 : Py_DECREF(notes_copy);
942 13 : if (res < 0) {
943 0 : goto error;
944 : }
945 : }
946 : else {
947 : /* __notes__ is supposed to be a list, and split() is not a
948 : * good place to report earlier user errors, so we just ignore
949 : * notes of non-sequence type.
950 : */
951 2 : Py_DECREF(notes);
952 : }
953 : }
954 :
955 440 : *result = eg;
956 440 : return 0;
957 0 : error:
958 0 : Py_DECREF(eg);
959 0 : return -1;
960 : }
961 :
962 : typedef enum {
963 : /* Exception type or tuple of thereof */
964 : EXCEPTION_GROUP_MATCH_BY_TYPE = 0,
965 : /* A PyFunction returning True for matching exceptions */
966 : EXCEPTION_GROUP_MATCH_BY_PREDICATE = 1,
967 : /* A set of leaf exceptions to include in the result.
968 : * This matcher type is used internally by the interpreter
969 : * to construct reraised exceptions.
970 : */
971 : EXCEPTION_GROUP_MATCH_INSTANCES = 2
972 : } _exceptiongroup_split_matcher_type;
973 :
974 : static int
975 184 : get_matcher_type(PyObject *value,
976 : _exceptiongroup_split_matcher_type *type)
977 : {
978 184 : assert(value);
979 :
980 184 : if (PyFunction_Check(value)) {
981 10 : *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE;
982 10 : return 0;
983 : }
984 :
985 174 : if (PyExceptionClass_Check(value)) {
986 141 : *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
987 141 : return 0;
988 : }
989 :
990 33 : if (PyTuple_CheckExact(value)) {
991 27 : Py_ssize_t n = PyTuple_GET_SIZE(value);
992 79 : for (Py_ssize_t i=0; i<n; i++) {
993 54 : if (!PyExceptionClass_Check(PyTuple_GET_ITEM(value, i))) {
994 2 : goto error;
995 : }
996 : }
997 25 : *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
998 25 : return 0;
999 : }
1000 :
1001 6 : error:
1002 8 : PyErr_SetString(
1003 : PyExc_TypeError,
1004 : "expected a function, exception type or tuple of exception types");
1005 8 : return -1;
1006 : }
1007 :
1008 : static int
1009 3017 : exceptiongroup_split_check_match(PyObject *exc,
1010 : _exceptiongroup_split_matcher_type matcher_type,
1011 : PyObject *matcher_value)
1012 : {
1013 3017 : switch (matcher_type) {
1014 2590 : case EXCEPTION_GROUP_MATCH_BY_TYPE: {
1015 2590 : assert(PyExceptionClass_Check(matcher_value) ||
1016 : PyTuple_CheckExact(matcher_value));
1017 2590 : return PyErr_GivenExceptionMatches(exc, matcher_value);
1018 : }
1019 34 : case EXCEPTION_GROUP_MATCH_BY_PREDICATE: {
1020 34 : assert(PyFunction_Check(matcher_value));
1021 34 : PyObject *exc_matches = PyObject_CallOneArg(matcher_value, exc);
1022 34 : if (exc_matches == NULL) {
1023 0 : return -1;
1024 : }
1025 34 : int is_true = PyObject_IsTrue(exc_matches);
1026 34 : Py_DECREF(exc_matches);
1027 34 : return is_true;
1028 : }
1029 393 : case EXCEPTION_GROUP_MATCH_INSTANCES: {
1030 393 : assert(PySet_Check(matcher_value));
1031 393 : if (!_PyBaseExceptionGroup_Check(exc)) {
1032 244 : return PySet_Contains(matcher_value, exc);
1033 : }
1034 149 : return 0;
1035 : }
1036 : }
1037 0 : return 0;
1038 : }
1039 :
1040 : typedef struct {
1041 : PyObject *match;
1042 : PyObject *rest;
1043 : } _exceptiongroup_split_result;
1044 :
1045 : static int
1046 3017 : exceptiongroup_split_recursive(PyObject *exc,
1047 : _exceptiongroup_split_matcher_type matcher_type,
1048 : PyObject *matcher_value,
1049 : bool construct_rest,
1050 : _exceptiongroup_split_result *result)
1051 : {
1052 3017 : result->match = NULL;
1053 3017 : result->rest = NULL;
1054 :
1055 3017 : int is_match = exceptiongroup_split_check_match(
1056 : exc, matcher_type, matcher_value);
1057 3017 : if (is_match < 0) {
1058 0 : return -1;
1059 : }
1060 :
1061 3017 : if (is_match) {
1062 : /* Full match */
1063 332 : result->match = Py_NewRef(exc);
1064 332 : return 0;
1065 : }
1066 2685 : else if (!_PyBaseExceptionGroup_Check(exc)) {
1067 : /* Leaf exception and no match */
1068 348 : if (construct_rest) {
1069 154 : result->rest = Py_NewRef(exc);
1070 : }
1071 348 : return 0;
1072 : }
1073 :
1074 : /* Partial match */
1075 :
1076 2337 : PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
1077 2337 : assert(PyTuple_CheckExact(eg->excs));
1078 2337 : Py_ssize_t num_excs = PyTuple_Size(eg->excs);
1079 2337 : if (num_excs < 0) {
1080 0 : return -1;
1081 : }
1082 2337 : assert(num_excs > 0); /* checked in constructor, and excs is read-only */
1083 :
1084 2337 : int retval = -1;
1085 2337 : PyObject *match_list = PyList_New(0);
1086 2337 : if (!match_list) {
1087 0 : return -1;
1088 : }
1089 :
1090 2337 : PyObject *rest_list = NULL;
1091 2337 : if (construct_rest) {
1092 1171 : rest_list = PyList_New(0);
1093 1171 : if (!rest_list) {
1094 0 : goto done;
1095 : }
1096 : }
1097 : /* recursive calls */
1098 3142 : for (Py_ssize_t i = 0; i < num_excs; i++) {
1099 2743 : PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
1100 : _exceptiongroup_split_result rec_result;
1101 2743 : if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
1102 1938 : goto done;
1103 : }
1104 2741 : if (exceptiongroup_split_recursive(
1105 : e, matcher_type, matcher_value,
1106 : construct_rest, &rec_result) < 0) {
1107 1936 : assert(!rec_result.match);
1108 1936 : assert(!rec_result.rest);
1109 1936 : _Py_LeaveRecursiveCall();
1110 1936 : goto done;
1111 : }
1112 805 : _Py_LeaveRecursiveCall();
1113 805 : if (rec_result.match) {
1114 418 : assert(PyList_CheckExact(match_list));
1115 418 : if (PyList_Append(match_list, rec_result.match) < 0) {
1116 0 : Py_DECREF(rec_result.match);
1117 0 : goto done;
1118 : }
1119 418 : Py_DECREF(rec_result.match);
1120 : }
1121 805 : if (rec_result.rest) {
1122 204 : assert(construct_rest);
1123 204 : assert(PyList_CheckExact(rest_list));
1124 204 : if (PyList_Append(rest_list, rec_result.rest) < 0) {
1125 0 : Py_DECREF(rec_result.rest);
1126 0 : goto done;
1127 : }
1128 204 : Py_DECREF(rec_result.rest);
1129 : }
1130 : }
1131 :
1132 : /* construct result */
1133 399 : if (exceptiongroup_subset(eg, match_list, &result->match) < 0) {
1134 0 : goto done;
1135 : }
1136 :
1137 399 : if (construct_rest) {
1138 202 : assert(PyList_CheckExact(rest_list));
1139 202 : if (exceptiongroup_subset(eg, rest_list, &result->rest) < 0) {
1140 0 : Py_CLEAR(result->match);
1141 0 : goto done;
1142 : }
1143 : }
1144 399 : retval = 0;
1145 2337 : done:
1146 2337 : Py_DECREF(match_list);
1147 2337 : Py_XDECREF(rest_list);
1148 2337 : if (retval < 0) {
1149 1938 : Py_CLEAR(result->match);
1150 1938 : Py_CLEAR(result->rest);
1151 : }
1152 2337 : return retval;
1153 : }
1154 :
1155 : static PyObject *
1156 145 : BaseExceptionGroup_split(PyObject *self, PyObject *args)
1157 : {
1158 145 : PyObject *matcher_value = NULL;
1159 145 : if (!PyArg_UnpackTuple(args, "split", 1, 1, &matcher_value)) {
1160 0 : return NULL;
1161 : }
1162 :
1163 : _exceptiongroup_split_matcher_type matcher_type;
1164 145 : if (get_matcher_type(matcher_value, &matcher_type) < 0) {
1165 4 : return NULL;
1166 : }
1167 :
1168 : _exceptiongroup_split_result split_result;
1169 141 : bool construct_rest = true;
1170 141 : if (exceptiongroup_split_recursive(
1171 : self, matcher_type, matcher_value,
1172 : construct_rest, &split_result) < 0) {
1173 1 : return NULL;
1174 : }
1175 :
1176 280 : PyObject *result = PyTuple_Pack(
1177 : 2,
1178 140 : split_result.match ? split_result.match : Py_None,
1179 140 : split_result.rest ? split_result.rest : Py_None);
1180 :
1181 140 : Py_XDECREF(split_result.match);
1182 140 : Py_XDECREF(split_result.rest);
1183 140 : return result;
1184 : }
1185 :
1186 : static PyObject *
1187 39 : BaseExceptionGroup_subgroup(PyObject *self, PyObject *args)
1188 : {
1189 39 : PyObject *matcher_value = NULL;
1190 39 : if (!PyArg_UnpackTuple(args, "subgroup", 1, 1, &matcher_value)) {
1191 0 : return NULL;
1192 : }
1193 :
1194 : _exceptiongroup_split_matcher_type matcher_type;
1195 39 : if (get_matcher_type(matcher_value, &matcher_type) < 0) {
1196 4 : return NULL;
1197 : }
1198 :
1199 : _exceptiongroup_split_result split_result;
1200 35 : bool construct_rest = false;
1201 35 : if (exceptiongroup_split_recursive(
1202 : self, matcher_type, matcher_value,
1203 : construct_rest, &split_result) < 0) {
1204 1 : return NULL;
1205 : }
1206 :
1207 34 : PyObject *result = Py_NewRef(
1208 : split_result.match ? split_result.match : Py_None);
1209 :
1210 34 : Py_XDECREF(split_result.match);
1211 34 : assert(!split_result.rest);
1212 34 : return result;
1213 : }
1214 :
1215 : static int
1216 195 : collect_exception_group_leaves(PyObject *exc, PyObject *leaves)
1217 : {
1218 195 : if (Py_IsNone(exc)) {
1219 0 : return 0;
1220 : }
1221 :
1222 195 : assert(PyExceptionInstance_Check(exc));
1223 195 : assert(PySet_Check(leaves));
1224 :
1225 : /* Add all leaf exceptions in exc to the leaves set */
1226 :
1227 195 : if (!_PyBaseExceptionGroup_Check(exc)) {
1228 94 : if (PySet_Add(leaves, exc) < 0) {
1229 0 : return -1;
1230 : }
1231 94 : return 0;
1232 : }
1233 101 : PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
1234 101 : Py_ssize_t num_excs = PyTuple_GET_SIZE(eg->excs);
1235 : /* recursive calls */
1236 232 : for (Py_ssize_t i = 0; i < num_excs; i++) {
1237 131 : PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
1238 131 : if (_Py_EnterRecursiveCall(" in collect_exception_group_leaves")) {
1239 0 : return -1;
1240 : }
1241 131 : int res = collect_exception_group_leaves(e, leaves);
1242 131 : _Py_LeaveRecursiveCall();
1243 131 : if (res < 0) {
1244 0 : return -1;
1245 : }
1246 : }
1247 101 : return 0;
1248 : }
1249 :
1250 : /* This function is used by the interpreter to construct reraised
1251 : * exception groups. It takes an exception group eg and a list
1252 : * of exception groups keep and returns the sub-exception group
1253 : * of eg which contains all leaf exceptions that are contained
1254 : * in any exception group in keep.
1255 : */
1256 : static PyObject *
1257 100 : exception_group_projection(PyObject *eg, PyObject *keep)
1258 : {
1259 100 : assert(_PyBaseExceptionGroup_Check(eg));
1260 100 : assert(PyList_CheckExact(keep));
1261 :
1262 100 : PyObject *leaves = PySet_New(NULL);
1263 100 : if (!leaves) {
1264 0 : return NULL;
1265 : }
1266 :
1267 100 : Py_ssize_t n = PyList_GET_SIZE(keep);
1268 164 : for (Py_ssize_t i = 0; i < n; i++) {
1269 64 : PyObject *e = PyList_GET_ITEM(keep, i);
1270 64 : assert(e != NULL);
1271 64 : assert(_PyBaseExceptionGroup_Check(e));
1272 64 : if (collect_exception_group_leaves(e, leaves) < 0) {
1273 0 : Py_DECREF(leaves);
1274 0 : return NULL;
1275 : }
1276 : }
1277 :
1278 : _exceptiongroup_split_result split_result;
1279 100 : bool construct_rest = false;
1280 100 : int err = exceptiongroup_split_recursive(
1281 : eg, EXCEPTION_GROUP_MATCH_INSTANCES, leaves,
1282 : construct_rest, &split_result);
1283 100 : Py_DECREF(leaves);
1284 100 : if (err < 0) {
1285 0 : return NULL;
1286 : }
1287 :
1288 200 : PyObject *result = split_result.match ?
1289 100 : split_result.match : Py_NewRef(Py_None);
1290 100 : assert(split_result.rest == NULL);
1291 100 : return result;
1292 : }
1293 :
1294 : static bool
1295 137 : is_same_exception_metadata(PyObject *exc1, PyObject *exc2)
1296 : {
1297 137 : assert(PyExceptionInstance_Check(exc1));
1298 137 : assert(PyExceptionInstance_Check(exc2));
1299 :
1300 137 : PyBaseExceptionObject *e1 = (PyBaseExceptionObject *)exc1;
1301 137 : PyBaseExceptionObject *e2 = (PyBaseExceptionObject *)exc2;
1302 :
1303 274 : return (e1->notes == e2->notes &&
1304 137 : e1->traceback == e2->traceback &&
1305 395 : e1->cause == e2->cause &&
1306 121 : e1->context == e2->context);
1307 : }
1308 :
1309 : /*
1310 : This function is used by the interpreter to calculate
1311 : the exception group to be raised at the end of a
1312 : try-except* construct.
1313 :
1314 : orig: the original except that was caught.
1315 : excs: a list of exceptions that were raised/reraised
1316 : in the except* clauses.
1317 :
1318 : Calculates an exception group to raise. It contains
1319 : all exceptions in excs, where those that were reraised
1320 : have same nesting structure as in orig, and those that
1321 : were raised (if any) are added as siblings in a new EG.
1322 :
1323 : Returns NULL and sets an exception on failure.
1324 : */
1325 : PyObject *
1326 150 : _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
1327 : {
1328 150 : assert(PyExceptionInstance_Check(orig));
1329 150 : assert(PyList_Check(excs));
1330 :
1331 150 : Py_ssize_t numexcs = PyList_GET_SIZE(excs);
1332 :
1333 150 : if (numexcs == 0) {
1334 0 : return Py_NewRef(Py_None);
1335 : }
1336 :
1337 150 : if (!_PyBaseExceptionGroup_Check(orig)) {
1338 : /* a naked exception was caught and wrapped. Only one except* clause
1339 : * could have executed,so there is at most one exception to raise.
1340 : */
1341 :
1342 50 : assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None));
1343 :
1344 50 : PyObject *e = PyList_GET_ITEM(excs, 0);
1345 50 : assert(e != NULL);
1346 50 : return Py_NewRef(e);
1347 : }
1348 :
1349 100 : PyObject *raised_list = PyList_New(0);
1350 100 : if (raised_list == NULL) {
1351 0 : return NULL;
1352 : }
1353 100 : PyObject* reraised_list = PyList_New(0);
1354 100 : if (reraised_list == NULL) {
1355 0 : Py_DECREF(raised_list);
1356 0 : return NULL;
1357 : }
1358 :
1359 : /* Now we are holding refs to raised_list and reraised_list */
1360 :
1361 100 : PyObject *result = NULL;
1362 :
1363 : /* Split excs into raised and reraised by comparing metadata with orig */
1364 228 : for (Py_ssize_t i = 0; i < numexcs; i++) {
1365 128 : PyObject *e = PyList_GET_ITEM(excs, i);
1366 128 : assert(e != NULL);
1367 128 : if (Py_IsNone(e)) {
1368 48 : continue;
1369 : }
1370 80 : bool is_reraise = is_same_exception_metadata(e, orig);
1371 80 : PyObject *append_list = is_reraise ? reraised_list : raised_list;
1372 80 : if (PyList_Append(append_list, e) < 0) {
1373 0 : goto done;
1374 : }
1375 : }
1376 :
1377 100 : PyObject *reraised_eg = exception_group_projection(orig, reraised_list);
1378 100 : if (reraised_eg == NULL) {
1379 0 : goto done;
1380 : }
1381 :
1382 100 : if (!Py_IsNone(reraised_eg)) {
1383 57 : assert(is_same_exception_metadata(reraised_eg, orig));
1384 : }
1385 100 : Py_ssize_t num_raised = PyList_GET_SIZE(raised_list);
1386 100 : if (num_raised == 0) {
1387 88 : result = reraised_eg;
1388 : }
1389 12 : else if (num_raised > 0) {
1390 12 : int res = 0;
1391 12 : if (!Py_IsNone(reraised_eg)) {
1392 4 : res = PyList_Append(raised_list, reraised_eg);
1393 : }
1394 12 : Py_DECREF(reraised_eg);
1395 12 : if (res < 0) {
1396 0 : goto done;
1397 : }
1398 12 : result = _PyExc_CreateExceptionGroup("", raised_list);
1399 12 : if (result == NULL) {
1400 0 : goto done;
1401 : }
1402 : }
1403 :
1404 12 : done:
1405 100 : Py_XDECREF(raised_list);
1406 100 : Py_XDECREF(reraised_list);
1407 100 : return result;
1408 : }
1409 :
1410 : static PyMemberDef BaseExceptionGroup_members[] = {
1411 : {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY,
1412 : PyDoc_STR("exception message")},
1413 : {"exceptions", T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), READONLY,
1414 : PyDoc_STR("nested exceptions")},
1415 : {NULL} /* Sentinel */
1416 : };
1417 :
1418 : static PyMethodDef BaseExceptionGroup_methods[] = {
1419 : {"__class_getitem__", (PyCFunction)Py_GenericAlias,
1420 : METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
1421 : {"derive", (PyCFunction)BaseExceptionGroup_derive, METH_VARARGS},
1422 : {"split", (PyCFunction)BaseExceptionGroup_split, METH_VARARGS},
1423 : {"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_VARARGS},
1424 : {NULL}
1425 : };
1426 :
1427 : ComplexExtendsException(PyExc_BaseException, BaseExceptionGroup,
1428 : BaseExceptionGroup, BaseExceptionGroup_new /* new */,
1429 : BaseExceptionGroup_methods, BaseExceptionGroup_members,
1430 : 0 /* getset */, BaseExceptionGroup_str,
1431 : "A combination of multiple unrelated exceptions.");
1432 :
1433 : /*
1434 : * ExceptionGroup extends BaseExceptionGroup, Exception
1435 : */
1436 : static PyObject*
1437 3134 : create_exception_group_class(void) {
1438 3134 : struct _Py_exc_state *state = get_exc_state();
1439 :
1440 3134 : PyObject *bases = PyTuple_Pack(
1441 : 2, PyExc_BaseExceptionGroup, PyExc_Exception);
1442 3134 : if (bases == NULL) {
1443 0 : return NULL;
1444 : }
1445 :
1446 3134 : assert(!state->PyExc_ExceptionGroup);
1447 3134 : state->PyExc_ExceptionGroup = PyErr_NewException(
1448 : "builtins.ExceptionGroup", bases, NULL);
1449 :
1450 3134 : Py_DECREF(bases);
1451 3134 : return state->PyExc_ExceptionGroup;
1452 : }
1453 :
1454 : /*
1455 : * KeyboardInterrupt extends BaseException
1456 : */
1457 : SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
1458 : "Program interrupted by user.");
1459 :
1460 :
1461 : /*
1462 : * ImportError extends Exception
1463 : */
1464 :
1465 : static int
1466 56297 : ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
1467 : {
1468 : static char *kwlist[] = {"name", "path", 0};
1469 : PyObject *empty_tuple;
1470 56297 : PyObject *msg = NULL;
1471 56297 : PyObject *name = NULL;
1472 56297 : PyObject *path = NULL;
1473 :
1474 56297 : if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1)
1475 0 : return -1;
1476 :
1477 56297 : empty_tuple = PyTuple_New(0);
1478 56297 : if (!empty_tuple)
1479 0 : return -1;
1480 56297 : if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist,
1481 : &name, &path)) {
1482 6 : Py_DECREF(empty_tuple);
1483 6 : return -1;
1484 : }
1485 56291 : Py_DECREF(empty_tuple);
1486 :
1487 56291 : Py_XINCREF(name);
1488 56291 : Py_XSETREF(self->name, name);
1489 :
1490 56291 : Py_XINCREF(path);
1491 56291 : Py_XSETREF(self->path, path);
1492 :
1493 56291 : if (PyTuple_GET_SIZE(args) == 1) {
1494 56228 : msg = PyTuple_GET_ITEM(args, 0);
1495 56228 : Py_INCREF(msg);
1496 : }
1497 56291 : Py_XSETREF(self->msg, msg);
1498 :
1499 56291 : return 0;
1500 : }
1501 :
1502 : static int
1503 56349 : ImportError_clear(PyImportErrorObject *self)
1504 : {
1505 56349 : Py_CLEAR(self->msg);
1506 56349 : Py_CLEAR(self->name);
1507 56349 : Py_CLEAR(self->path);
1508 56349 : return BaseException_clear((PyBaseExceptionObject *)self);
1509 : }
1510 :
1511 : static void
1512 56296 : ImportError_dealloc(PyImportErrorObject *self)
1513 : {
1514 56296 : _PyObject_GC_UNTRACK(self);
1515 56296 : ImportError_clear(self);
1516 56296 : Py_TYPE(self)->tp_free((PyObject *)self);
1517 56296 : }
1518 :
1519 : static int
1520 526 : ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg)
1521 : {
1522 526 : Py_VISIT(self->msg);
1523 526 : Py_VISIT(self->name);
1524 526 : Py_VISIT(self->path);
1525 526 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1526 : }
1527 :
1528 : static PyObject *
1529 156 : ImportError_str(PyImportErrorObject *self)
1530 : {
1531 156 : if (self->msg && PyUnicode_CheckExact(self->msg)) {
1532 152 : Py_INCREF(self->msg);
1533 152 : return self->msg;
1534 : }
1535 : else {
1536 4 : return BaseException_str((PyBaseExceptionObject *)self);
1537 : }
1538 : }
1539 :
1540 : static PyObject *
1541 38 : ImportError_getstate(PyImportErrorObject *self)
1542 : {
1543 38 : PyObject *dict = ((PyBaseExceptionObject *)self)->dict;
1544 38 : if (self->name || self->path) {
1545 24 : dict = dict ? PyDict_Copy(dict) : PyDict_New();
1546 24 : if (dict == NULL)
1547 0 : return NULL;
1548 24 : if (self->name && PyDict_SetItem(dict, &_Py_ID(name), self->name) < 0) {
1549 0 : Py_DECREF(dict);
1550 0 : return NULL;
1551 : }
1552 24 : if (self->path && PyDict_SetItem(dict, &_Py_ID(path), self->path) < 0) {
1553 0 : Py_DECREF(dict);
1554 0 : return NULL;
1555 : }
1556 24 : return dict;
1557 : }
1558 14 : else if (dict) {
1559 0 : Py_INCREF(dict);
1560 0 : return dict;
1561 : }
1562 : else {
1563 14 : Py_RETURN_NONE;
1564 : }
1565 : }
1566 :
1567 : /* Pickling support */
1568 : static PyObject *
1569 38 : ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored))
1570 : {
1571 : PyObject *res;
1572 : PyObject *args;
1573 38 : PyObject *state = ImportError_getstate(self);
1574 38 : if (state == NULL)
1575 0 : return NULL;
1576 38 : args = ((PyBaseExceptionObject *)self)->args;
1577 38 : if (state == Py_None)
1578 14 : res = PyTuple_Pack(2, Py_TYPE(self), args);
1579 : else
1580 24 : res = PyTuple_Pack(3, Py_TYPE(self), args, state);
1581 38 : Py_DECREF(state);
1582 38 : return res;
1583 : }
1584 :
1585 : static PyMemberDef ImportError_members[] = {
1586 : {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
1587 : PyDoc_STR("exception message")},
1588 : {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0,
1589 : PyDoc_STR("module name")},
1590 : {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0,
1591 : PyDoc_STR("module path")},
1592 : {NULL} /* Sentinel */
1593 : };
1594 :
1595 : static PyMethodDef ImportError_methods[] = {
1596 : {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
1597 : {NULL}
1598 : };
1599 :
1600 : ComplexExtendsException(PyExc_Exception, ImportError,
1601 : ImportError, 0 /* new */,
1602 : ImportError_methods, ImportError_members,
1603 : 0 /* getset */, ImportError_str,
1604 : "Import can't find module, or can't find name in "
1605 : "module.");
1606 :
1607 : /*
1608 : * ModuleNotFoundError extends ImportError
1609 : */
1610 :
1611 : MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
1612 : "Module not found.");
1613 :
1614 : /*
1615 : * OSError extends Exception
1616 : */
1617 :
1618 : #ifdef MS_WINDOWS
1619 : #include "errmap.h"
1620 : #endif
1621 :
1622 : /* Where a function has a single filename, such as open() or some
1623 : * of the os module functions, PyErr_SetFromErrnoWithFilename() is
1624 : * called, giving a third argument which is the filename. But, so
1625 : * that old code using in-place unpacking doesn't break, e.g.:
1626 : *
1627 : * except OSError, (errno, strerror):
1628 : *
1629 : * we hack args so that it only contains two items. This also
1630 : * means we need our own __str__() which prints out the filename
1631 : * when it was supplied.
1632 : *
1633 : * (If a function has two filenames, such as rename(), symlink(),
1634 : * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
1635 : * which allows passing in a second filename.)
1636 : */
1637 :
1638 : /* This function doesn't cleanup on error, the caller should */
1639 : static int
1640 1385960 : oserror_parse_args(PyObject **p_args,
1641 : PyObject **myerrno, PyObject **strerror,
1642 : PyObject **filename, PyObject **filename2
1643 : #ifdef MS_WINDOWS
1644 : , PyObject **winerror
1645 : #endif
1646 : )
1647 : {
1648 : Py_ssize_t nargs;
1649 1385960 : PyObject *args = *p_args;
1650 : #ifndef MS_WINDOWS
1651 : /*
1652 : * ignored on non-Windows platforms,
1653 : * but parsed so OSError has a consistent signature
1654 : */
1655 1385960 : PyObject *_winerror = NULL;
1656 1385960 : PyObject **winerror = &_winerror;
1657 : #endif /* MS_WINDOWS */
1658 :
1659 1385960 : nargs = PyTuple_GET_SIZE(args);
1660 :
1661 1385960 : if (nargs >= 2 && nargs <= 5) {
1662 1383730 : if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
1663 : myerrno, strerror,
1664 : filename, winerror, filename2))
1665 0 : return -1;
1666 : #ifdef MS_WINDOWS
1667 : if (*winerror && PyLong_Check(*winerror)) {
1668 : long errcode, winerrcode;
1669 : PyObject *newargs;
1670 : Py_ssize_t i;
1671 :
1672 : winerrcode = PyLong_AsLong(*winerror);
1673 : if (winerrcode == -1 && PyErr_Occurred())
1674 : return -1;
1675 : errcode = winerror_to_errno(winerrcode);
1676 : *myerrno = PyLong_FromLong(errcode);
1677 : if (!*myerrno)
1678 : return -1;
1679 : newargs = PyTuple_New(nargs);
1680 : if (!newargs)
1681 : return -1;
1682 : PyTuple_SET_ITEM(newargs, 0, *myerrno);
1683 : for (i = 1; i < nargs; i++) {
1684 : PyObject *val = PyTuple_GET_ITEM(args, i);
1685 : Py_INCREF(val);
1686 : PyTuple_SET_ITEM(newargs, i, val);
1687 : }
1688 : Py_DECREF(args);
1689 : args = *p_args = newargs;
1690 : }
1691 : #endif /* MS_WINDOWS */
1692 : }
1693 :
1694 1385960 : return 0;
1695 : }
1696 :
1697 : static int
1698 1385960 : oserror_init(PyOSErrorObject *self, PyObject **p_args,
1699 : PyObject *myerrno, PyObject *strerror,
1700 : PyObject *filename, PyObject *filename2
1701 : #ifdef MS_WINDOWS
1702 : , PyObject *winerror
1703 : #endif
1704 : )
1705 : {
1706 1385960 : PyObject *args = *p_args;
1707 1385960 : Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1708 :
1709 : /* self->filename will remain Py_None otherwise */
1710 1385960 : if (filename && filename != Py_None) {
1711 284338 : if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
1712 35 : PyNumber_Check(filename)) {
1713 : /* BlockingIOError's 3rd argument can be the number of
1714 : * characters written.
1715 : */
1716 32 : self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
1717 32 : if (self->written == -1 && PyErr_Occurred())
1718 0 : return -1;
1719 : }
1720 : else {
1721 284271 : Py_INCREF(filename);
1722 284271 : self->filename = filename;
1723 :
1724 284271 : if (filename2 && filename2 != Py_None) {
1725 135 : Py_INCREF(filename2);
1726 135 : self->filename2 = filename2;
1727 : }
1728 :
1729 284271 : if (nargs >= 2 && nargs <= 5) {
1730 : /* filename, filename2, and winerror are removed from the args tuple
1731 : (for compatibility purposes, see test_exceptions.py) */
1732 284271 : PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
1733 284271 : if (!subslice)
1734 0 : return -1;
1735 :
1736 284271 : Py_DECREF(args); /* replacing args */
1737 284271 : *p_args = args = subslice;
1738 : }
1739 : }
1740 : }
1741 1385960 : Py_XINCREF(myerrno);
1742 1385960 : self->myerrno = myerrno;
1743 :
1744 1385960 : Py_XINCREF(strerror);
1745 1385960 : self->strerror = strerror;
1746 :
1747 : #ifdef MS_WINDOWS
1748 : Py_XINCREF(winerror);
1749 : self->winerror = winerror;
1750 : #endif
1751 :
1752 : /* Steals the reference to args */
1753 1385960 : Py_XSETREF(self->args, args);
1754 1385960 : *p_args = args = NULL;
1755 :
1756 1385960 : return 0;
1757 : }
1758 :
1759 : static PyObject *
1760 : OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1761 : static int
1762 : OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds);
1763 :
1764 : static int
1765 4158030 : oserror_use_init(PyTypeObject *type)
1766 : {
1767 : /* When __init__ is defined in an OSError subclass, we want any
1768 : extraneous argument to __new__ to be ignored. The only reasonable
1769 : solution, given __new__ takes a variable number of arguments,
1770 : is to defer arg parsing and initialization to __init__.
1771 :
1772 : But when __new__ is overridden as well, it should call our __new__
1773 : with the right arguments.
1774 :
1775 : (see http://bugs.python.org/issue12555#msg148829 )
1776 : */
1777 4158030 : if (type->tp_init != (initproc) OSError_init &&
1778 171 : type->tp_new == (newfunc) OSError_new) {
1779 165 : assert((PyObject *) type != PyExc_OSError);
1780 165 : return 1;
1781 : }
1782 4157860 : return 0;
1783 : }
1784 :
1785 : static PyObject *
1786 1386030 : OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1787 : {
1788 1386030 : PyOSErrorObject *self = NULL;
1789 1386030 : PyObject *myerrno = NULL, *strerror = NULL;
1790 1386030 : PyObject *filename = NULL, *filename2 = NULL;
1791 : #ifdef MS_WINDOWS
1792 : PyObject *winerror = NULL;
1793 : #endif
1794 :
1795 1386030 : Py_INCREF(args);
1796 :
1797 1386030 : if (!oserror_use_init(type)) {
1798 1385960 : if (!_PyArg_NoKeywords(type->tp_name, kwds))
1799 0 : goto error;
1800 :
1801 1385960 : if (oserror_parse_args(&args, &myerrno, &strerror,
1802 : &filename, &filename2
1803 : #ifdef MS_WINDOWS
1804 : , &winerror
1805 : #endif
1806 : ))
1807 0 : goto error;
1808 :
1809 1385960 : struct _Py_exc_state *state = get_exc_state();
1810 1385960 : if (myerrno && PyLong_Check(myerrno) &&
1811 1383680 : state->errnomap && (PyObject *) type == PyExc_OSError) {
1812 : PyObject *newtype;
1813 1361430 : newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
1814 1361430 : if (newtype) {
1815 283962 : type = _PyType_CAST(newtype);
1816 : }
1817 1077470 : else if (PyErr_Occurred())
1818 0 : goto error;
1819 : }
1820 : }
1821 :
1822 1386030 : self = (PyOSErrorObject *) type->tp_alloc(type, 0);
1823 1386030 : if (!self)
1824 0 : goto error;
1825 :
1826 1386030 : self->dict = NULL;
1827 1386030 : self->traceback = self->cause = self->context = NULL;
1828 1386030 : self->written = -1;
1829 :
1830 1386030 : if (!oserror_use_init(type)) {
1831 1385960 : if (oserror_init(self, &args, myerrno, strerror, filename, filename2
1832 : #ifdef MS_WINDOWS
1833 : , winerror
1834 : #endif
1835 : ))
1836 0 : goto error;
1837 : }
1838 : else {
1839 79 : self->args = PyTuple_New(0);
1840 79 : if (self->args == NULL)
1841 0 : goto error;
1842 : }
1843 :
1844 1386030 : Py_XDECREF(args);
1845 1386030 : return (PyObject *) self;
1846 :
1847 0 : error:
1848 0 : Py_XDECREF(args);
1849 0 : Py_XDECREF(self);
1850 0 : return NULL;
1851 : }
1852 :
1853 : static int
1854 1385960 : OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds)
1855 : {
1856 1385960 : PyObject *myerrno = NULL, *strerror = NULL;
1857 1385960 : PyObject *filename = NULL, *filename2 = NULL;
1858 : #ifdef MS_WINDOWS
1859 : PyObject *winerror = NULL;
1860 : #endif
1861 :
1862 1385960 : if (!oserror_use_init(Py_TYPE(self)))
1863 : /* Everything already done in OSError_new */
1864 1385960 : return 0;
1865 :
1866 7 : if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
1867 0 : return -1;
1868 :
1869 7 : Py_INCREF(args);
1870 7 : if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
1871 : #ifdef MS_WINDOWS
1872 : , &winerror
1873 : #endif
1874 : ))
1875 0 : goto error;
1876 :
1877 7 : if (oserror_init(self, &args, myerrno, strerror, filename, filename2
1878 : #ifdef MS_WINDOWS
1879 : , winerror
1880 : #endif
1881 : ))
1882 0 : goto error;
1883 :
1884 7 : return 0;
1885 :
1886 0 : error:
1887 0 : Py_DECREF(args);
1888 0 : return -1;
1889 : }
1890 :
1891 : static int
1892 1386150 : OSError_clear(PyOSErrorObject *self)
1893 : {
1894 1386150 : Py_CLEAR(self->myerrno);
1895 1386150 : Py_CLEAR(self->strerror);
1896 1386150 : Py_CLEAR(self->filename);
1897 1386150 : Py_CLEAR(self->filename2);
1898 : #ifdef MS_WINDOWS
1899 : Py_CLEAR(self->winerror);
1900 : #endif
1901 1386150 : return BaseException_clear((PyBaseExceptionObject *)self);
1902 : }
1903 :
1904 : static void
1905 1386030 : OSError_dealloc(PyOSErrorObject *self)
1906 : {
1907 1386030 : _PyObject_GC_UNTRACK(self);
1908 1386030 : OSError_clear(self);
1909 1386030 : Py_TYPE(self)->tp_free((PyObject *)self);
1910 1386030 : }
1911 :
1912 : static int
1913 1868 : OSError_traverse(PyOSErrorObject *self, visitproc visit,
1914 : void *arg)
1915 : {
1916 1868 : Py_VISIT(self->myerrno);
1917 1868 : Py_VISIT(self->strerror);
1918 1868 : Py_VISIT(self->filename);
1919 1868 : Py_VISIT(self->filename2);
1920 : #ifdef MS_WINDOWS
1921 : Py_VISIT(self->winerror);
1922 : #endif
1923 1868 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1924 : }
1925 :
1926 : static PyObject *
1927 176 : OSError_str(PyOSErrorObject *self)
1928 : {
1929 : #define OR_NONE(x) ((x)?(x):Py_None)
1930 : #ifdef MS_WINDOWS
1931 : /* If available, winerror has the priority over myerrno */
1932 : if (self->winerror && self->filename) {
1933 : if (self->filename2) {
1934 : return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
1935 : OR_NONE(self->winerror),
1936 : OR_NONE(self->strerror),
1937 : self->filename,
1938 : self->filename2);
1939 : } else {
1940 : return PyUnicode_FromFormat("[WinError %S] %S: %R",
1941 : OR_NONE(self->winerror),
1942 : OR_NONE(self->strerror),
1943 : self->filename);
1944 : }
1945 : }
1946 : if (self->winerror && self->strerror)
1947 : return PyUnicode_FromFormat("[WinError %S] %S",
1948 : self->winerror ? self->winerror: Py_None,
1949 : self->strerror ? self->strerror: Py_None);
1950 : #endif
1951 176 : if (self->filename) {
1952 91 : if (self->filename2) {
1953 8 : return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
1954 4 : OR_NONE(self->myerrno),
1955 4 : OR_NONE(self->strerror),
1956 : self->filename,
1957 : self->filename2);
1958 : } else {
1959 174 : return PyUnicode_FromFormat("[Errno %S] %S: %R",
1960 87 : OR_NONE(self->myerrno),
1961 87 : OR_NONE(self->strerror),
1962 : self->filename);
1963 : }
1964 : }
1965 85 : if (self->myerrno && self->strerror)
1966 20 : return PyUnicode_FromFormat("[Errno %S] %S",
1967 : self->myerrno, self->strerror);
1968 65 : return BaseException_str((PyBaseExceptionObject *)self);
1969 : }
1970 :
1971 : static PyObject *
1972 37 : OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored))
1973 : {
1974 37 : PyObject *args = self->args;
1975 37 : PyObject *res = NULL, *tmp;
1976 :
1977 : /* self->args is only the first two real arguments if there was a
1978 : * file name given to OSError. */
1979 61 : if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
1980 24 : Py_ssize_t size = self->filename2 ? 5 : 3;
1981 24 : args = PyTuple_New(size);
1982 24 : if (!args)
1983 0 : return NULL;
1984 :
1985 24 : tmp = PyTuple_GET_ITEM(self->args, 0);
1986 24 : Py_INCREF(tmp);
1987 24 : PyTuple_SET_ITEM(args, 0, tmp);
1988 :
1989 24 : tmp = PyTuple_GET_ITEM(self->args, 1);
1990 24 : Py_INCREF(tmp);
1991 24 : PyTuple_SET_ITEM(args, 1, tmp);
1992 :
1993 24 : Py_INCREF(self->filename);
1994 24 : PyTuple_SET_ITEM(args, 2, self->filename);
1995 :
1996 24 : if (self->filename2) {
1997 : /*
1998 : * This tuple is essentially used as OSError(*args).
1999 : * So, to recreate filename2, we need to pass in
2000 : * winerror as well.
2001 : */
2002 6 : Py_INCREF(Py_None);
2003 6 : PyTuple_SET_ITEM(args, 3, Py_None);
2004 :
2005 : /* filename2 */
2006 6 : Py_INCREF(self->filename2);
2007 6 : PyTuple_SET_ITEM(args, 4, self->filename2);
2008 : }
2009 : } else
2010 13 : Py_INCREF(args);
2011 :
2012 37 : if (self->dict)
2013 0 : res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
2014 : else
2015 37 : res = PyTuple_Pack(2, Py_TYPE(self), args);
2016 37 : Py_DECREF(args);
2017 37 : return res;
2018 : }
2019 :
2020 : static PyObject *
2021 37 : OSError_written_get(PyOSErrorObject *self, void *context)
2022 : {
2023 37 : if (self->written == -1) {
2024 7 : PyErr_SetString(PyExc_AttributeError, "characters_written");
2025 7 : return NULL;
2026 : }
2027 30 : return PyLong_FromSsize_t(self->written);
2028 : }
2029 :
2030 : static int
2031 8 : OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
2032 : {
2033 8 : if (arg == NULL) {
2034 7 : if (self->written == -1) {
2035 6 : PyErr_SetString(PyExc_AttributeError, "characters_written");
2036 6 : return -1;
2037 : }
2038 1 : self->written = -1;
2039 1 : return 0;
2040 : }
2041 : Py_ssize_t n;
2042 1 : n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
2043 1 : if (n == -1 && PyErr_Occurred())
2044 0 : return -1;
2045 1 : self->written = n;
2046 1 : return 0;
2047 : }
2048 :
2049 : static PyMemberDef OSError_members[] = {
2050 : {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
2051 : PyDoc_STR("POSIX exception code")},
2052 : {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
2053 : PyDoc_STR("exception strerror")},
2054 : {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
2055 : PyDoc_STR("exception filename")},
2056 : {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
2057 : PyDoc_STR("second exception filename")},
2058 : #ifdef MS_WINDOWS
2059 : {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
2060 : PyDoc_STR("Win32 exception code")},
2061 : #endif
2062 : {NULL} /* Sentinel */
2063 : };
2064 :
2065 : static PyMethodDef OSError_methods[] = {
2066 : {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
2067 : {NULL}
2068 : };
2069 :
2070 : static PyGetSetDef OSError_getset[] = {
2071 : {"characters_written", (getter) OSError_written_get,
2072 : (setter) OSError_written_set, NULL},
2073 : {NULL}
2074 : };
2075 :
2076 :
2077 : ComplexExtendsException(PyExc_Exception, OSError,
2078 : OSError, OSError_new,
2079 : OSError_methods, OSError_members, OSError_getset,
2080 : OSError_str,
2081 : "Base class for I/O related errors.");
2082 :
2083 :
2084 : /*
2085 : * Various OSError subclasses
2086 : */
2087 : MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
2088 : "I/O operation would block.");
2089 : MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
2090 : "Connection error.");
2091 : MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
2092 : "Child process error.");
2093 : MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
2094 : "Broken pipe.");
2095 : MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
2096 : "Connection aborted.");
2097 : MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
2098 : "Connection refused.");
2099 : MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
2100 : "Connection reset.");
2101 : MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
2102 : "File already exists.");
2103 : MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
2104 : "File not found.");
2105 : MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
2106 : "Operation doesn't work on directories.");
2107 : MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
2108 : "Operation only works on directories.");
2109 : MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
2110 : "Interrupted by signal.");
2111 : MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
2112 : "Not enough permissions.");
2113 : MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
2114 : "Process not found.");
2115 : MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
2116 : "Timeout expired.");
2117 :
2118 : /*
2119 : * EOFError extends Exception
2120 : */
2121 : SimpleExtendsException(PyExc_Exception, EOFError,
2122 : "Read beyond end of file.");
2123 :
2124 :
2125 : /*
2126 : * RuntimeError extends Exception
2127 : */
2128 : SimpleExtendsException(PyExc_Exception, RuntimeError,
2129 : "Unspecified run-time error.");
2130 :
2131 : /*
2132 : * RecursionError extends RuntimeError
2133 : */
2134 : SimpleExtendsException(PyExc_RuntimeError, RecursionError,
2135 : "Recursion limit exceeded.");
2136 :
2137 : /*
2138 : * NotImplementedError extends RuntimeError
2139 : */
2140 : SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
2141 : "Method or function hasn't been implemented yet.");
2142 :
2143 : /*
2144 : * NameError extends Exception
2145 : */
2146 :
2147 : static int
2148 994 : NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds)
2149 : {
2150 : static char *kwlist[] = {"name", NULL};
2151 994 : PyObject *name = NULL;
2152 :
2153 994 : if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
2154 0 : return -1;
2155 : }
2156 :
2157 994 : PyObject *empty_tuple = PyTuple_New(0);
2158 994 : if (!empty_tuple) {
2159 0 : return -1;
2160 : }
2161 994 : if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
2162 : &name)) {
2163 0 : Py_DECREF(empty_tuple);
2164 0 : return -1;
2165 : }
2166 994 : Py_DECREF(empty_tuple);
2167 :
2168 994 : Py_XINCREF(name);
2169 994 : Py_XSETREF(self->name, name);
2170 :
2171 994 : return 0;
2172 : }
2173 :
2174 : static int
2175 1015 : NameError_clear(PyNameErrorObject *self)
2176 : {
2177 1015 : Py_CLEAR(self->name);
2178 1015 : return BaseException_clear((PyBaseExceptionObject *)self);
2179 : }
2180 :
2181 : static void
2182 994 : NameError_dealloc(PyNameErrorObject *self)
2183 : {
2184 994 : _PyObject_GC_UNTRACK(self);
2185 994 : NameError_clear(self);
2186 994 : Py_TYPE(self)->tp_free((PyObject *)self);
2187 994 : }
2188 :
2189 : static int
2190 164 : NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg)
2191 : {
2192 164 : Py_VISIT(self->name);
2193 164 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2194 : }
2195 :
2196 : static PyMemberDef NameError_members[] = {
2197 : {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
2198 : {NULL} /* Sentinel */
2199 : };
2200 :
2201 : static PyMethodDef NameError_methods[] = {
2202 : {NULL} /* Sentinel */
2203 : };
2204 :
2205 : ComplexExtendsException(PyExc_Exception, NameError,
2206 : NameError, 0,
2207 : NameError_methods, NameError_members,
2208 : 0, BaseException_str, "Name not found globally.");
2209 :
2210 : /*
2211 : * UnboundLocalError extends NameError
2212 : */
2213 :
2214 : MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
2215 : "Local name referenced but not bound to a value.");
2216 :
2217 : /*
2218 : * AttributeError extends Exception
2219 : */
2220 :
2221 : static int
2222 1596110 : AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds)
2223 : {
2224 : static char *kwlist[] = {"name", "obj", NULL};
2225 1596110 : PyObject *name = NULL;
2226 1596110 : PyObject *obj = NULL;
2227 :
2228 1596110 : if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
2229 0 : return -1;
2230 : }
2231 :
2232 1596110 : PyObject *empty_tuple = PyTuple_New(0);
2233 1596110 : if (!empty_tuple) {
2234 0 : return -1;
2235 : }
2236 1596110 : if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2237 : &name, &obj)) {
2238 0 : Py_DECREF(empty_tuple);
2239 0 : return -1;
2240 : }
2241 1596110 : Py_DECREF(empty_tuple);
2242 :
2243 1596110 : Py_XINCREF(name);
2244 1596110 : Py_XSETREF(self->name, name);
2245 :
2246 1596110 : Py_XINCREF(obj);
2247 1596110 : Py_XSETREF(self->obj, obj);
2248 :
2249 1596110 : return 0;
2250 : }
2251 :
2252 : static int
2253 1596160 : AttributeError_clear(PyAttributeErrorObject *self)
2254 : {
2255 1596160 : Py_CLEAR(self->obj);
2256 1596160 : Py_CLEAR(self->name);
2257 1596160 : return BaseException_clear((PyBaseExceptionObject *)self);
2258 : }
2259 :
2260 : static void
2261 1596110 : AttributeError_dealloc(PyAttributeErrorObject *self)
2262 : {
2263 1596110 : _PyObject_GC_UNTRACK(self);
2264 1596110 : AttributeError_clear(self);
2265 1596110 : Py_TYPE(self)->tp_free((PyObject *)self);
2266 1596110 : }
2267 :
2268 : static int
2269 1112 : AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg)
2270 : {
2271 1112 : Py_VISIT(self->obj);
2272 1112 : Py_VISIT(self->name);
2273 1112 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2274 : }
2275 :
2276 : static PyMemberDef AttributeError_members[] = {
2277 : {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
2278 : {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
2279 : {NULL} /* Sentinel */
2280 : };
2281 :
2282 : static PyMethodDef AttributeError_methods[] = {
2283 : {NULL} /* Sentinel */
2284 : };
2285 :
2286 : ComplexExtendsException(PyExc_Exception, AttributeError,
2287 : AttributeError, 0,
2288 : AttributeError_methods, AttributeError_members,
2289 : 0, BaseException_str, "Attribute not found.");
2290 :
2291 : /*
2292 : * SyntaxError extends Exception
2293 : */
2294 :
2295 : static int
2296 2984 : SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
2297 : {
2298 2984 : PyObject *info = NULL;
2299 2984 : Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2300 :
2301 2984 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2302 0 : return -1;
2303 :
2304 2984 : if (lenargs >= 1) {
2305 2945 : Py_INCREF(PyTuple_GET_ITEM(args, 0));
2306 2945 : Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
2307 : }
2308 2984 : if (lenargs == 2) {
2309 2641 : info = PyTuple_GET_ITEM(args, 1);
2310 2641 : info = PySequence_Tuple(info);
2311 2641 : if (!info) {
2312 0 : return -1;
2313 : }
2314 :
2315 2641 : self->end_lineno = NULL;
2316 2641 : self->end_offset = NULL;
2317 2641 : if (!PyArg_ParseTuple(info, "OOOO|OO",
2318 : &self->filename, &self->lineno,
2319 : &self->offset, &self->text,
2320 : &self->end_lineno, &self->end_offset)) {
2321 2 : Py_DECREF(info);
2322 2 : return -1;
2323 : }
2324 :
2325 2639 : Py_INCREF(self->filename);
2326 2639 : Py_INCREF(self->lineno);
2327 2639 : Py_INCREF(self->offset);
2328 2639 : Py_INCREF(self->text);
2329 2639 : Py_XINCREF(self->end_lineno);
2330 2639 : Py_XINCREF(self->end_offset);
2331 2639 : Py_DECREF(info);
2332 :
2333 2639 : if (self->end_lineno != NULL && self->end_offset == NULL) {
2334 1 : PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
2335 1 : return -1;
2336 : }
2337 : }
2338 2981 : return 0;
2339 : }
2340 :
2341 : static int
2342 3035 : SyntaxError_clear(PySyntaxErrorObject *self)
2343 : {
2344 3035 : Py_CLEAR(self->msg);
2345 3035 : Py_CLEAR(self->filename);
2346 3035 : Py_CLEAR(self->lineno);
2347 3035 : Py_CLEAR(self->offset);
2348 3035 : Py_CLEAR(self->end_lineno);
2349 3035 : Py_CLEAR(self->end_offset);
2350 3035 : Py_CLEAR(self->text);
2351 3035 : Py_CLEAR(self->print_file_and_line);
2352 3035 : return BaseException_clear((PyBaseExceptionObject *)self);
2353 : }
2354 :
2355 : static void
2356 2984 : SyntaxError_dealloc(PySyntaxErrorObject *self)
2357 : {
2358 2984 : _PyObject_GC_UNTRACK(self);
2359 2984 : SyntaxError_clear(self);
2360 2984 : Py_TYPE(self)->tp_free((PyObject *)self);
2361 2984 : }
2362 :
2363 : static int
2364 191 : SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
2365 : {
2366 191 : Py_VISIT(self->msg);
2367 191 : Py_VISIT(self->filename);
2368 191 : Py_VISIT(self->lineno);
2369 191 : Py_VISIT(self->offset);
2370 191 : Py_VISIT(self->end_lineno);
2371 191 : Py_VISIT(self->end_offset);
2372 191 : Py_VISIT(self->text);
2373 191 : Py_VISIT(self->print_file_and_line);
2374 191 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2375 : }
2376 :
2377 : /* This is called "my_basename" instead of just "basename" to avoid name
2378 : conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
2379 : defined, and Python does define that. */
2380 : static PyObject*
2381 1735 : my_basename(PyObject *name)
2382 : {
2383 : Py_ssize_t i, size, offset;
2384 : int kind;
2385 : const void *data;
2386 :
2387 1735 : if (PyUnicode_READY(name))
2388 0 : return NULL;
2389 1735 : kind = PyUnicode_KIND(name);
2390 1735 : data = PyUnicode_DATA(name);
2391 1735 : size = PyUnicode_GET_LENGTH(name);
2392 1735 : offset = 0;
2393 35915 : for(i=0; i < size; i++) {
2394 34180 : if (PyUnicode_READ(kind, data, i) == SEP) {
2395 339 : offset = i + 1;
2396 : }
2397 : }
2398 1735 : if (offset != 0) {
2399 52 : return PyUnicode_Substring(name, offset, size);
2400 : }
2401 : else {
2402 1683 : Py_INCREF(name);
2403 1683 : return name;
2404 : }
2405 : }
2406 :
2407 :
2408 : static PyObject *
2409 1796 : SyntaxError_str(PySyntaxErrorObject *self)
2410 : {
2411 1796 : int have_lineno = 0;
2412 : PyObject *filename;
2413 : PyObject *result;
2414 : /* Below, we always ignore overflow errors, just printing -1.
2415 : Still, we cannot allow an OverflowError to be raised, so
2416 : we need to call PyLong_AsLongAndOverflow. */
2417 : int overflow;
2418 :
2419 : /* XXX -- do all the additional formatting with filename and
2420 : lineno here */
2421 :
2422 1796 : if (self->filename && PyUnicode_Check(self->filename)) {
2423 1735 : filename = my_basename(self->filename);
2424 1735 : if (filename == NULL)
2425 0 : return NULL;
2426 : } else {
2427 61 : filename = NULL;
2428 : }
2429 1796 : have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
2430 :
2431 1796 : if (!filename && !have_lineno)
2432 59 : return PyObject_Str(self->msg ? self->msg : Py_None);
2433 :
2434 1737 : if (filename && have_lineno)
2435 3462 : result = PyUnicode_FromFormat("%S (%U, line %ld)",
2436 1731 : self->msg ? self->msg : Py_None,
2437 : filename,
2438 : PyLong_AsLongAndOverflow(self->lineno, &overflow));
2439 6 : else if (filename)
2440 4 : result = PyUnicode_FromFormat("%S (%U)",
2441 4 : self->msg ? self->msg : Py_None,
2442 : filename);
2443 : else /* only have_lineno */
2444 4 : result = PyUnicode_FromFormat("%S (line %ld)",
2445 2 : self->msg ? self->msg : Py_None,
2446 : PyLong_AsLongAndOverflow(self->lineno, &overflow));
2447 1737 : Py_XDECREF(filename);
2448 1737 : return result;
2449 : }
2450 :
2451 : static PyMemberDef SyntaxError_members[] = {
2452 : {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
2453 : PyDoc_STR("exception msg")},
2454 : {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
2455 : PyDoc_STR("exception filename")},
2456 : {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
2457 : PyDoc_STR("exception lineno")},
2458 : {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
2459 : PyDoc_STR("exception offset")},
2460 : {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
2461 : PyDoc_STR("exception text")},
2462 : {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
2463 : PyDoc_STR("exception end lineno")},
2464 : {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
2465 : PyDoc_STR("exception end offset")},
2466 : {"print_file_and_line", T_OBJECT,
2467 : offsetof(PySyntaxErrorObject, print_file_and_line), 0,
2468 : PyDoc_STR("exception print_file_and_line")},
2469 : {NULL} /* Sentinel */
2470 : };
2471 :
2472 : ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
2473 : 0, 0, SyntaxError_members, 0,
2474 : SyntaxError_str, "Invalid syntax.");
2475 :
2476 :
2477 : /*
2478 : * IndentationError extends SyntaxError
2479 : */
2480 : MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
2481 : "Improper indentation.");
2482 :
2483 :
2484 : /*
2485 : * TabError extends IndentationError
2486 : */
2487 : MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
2488 : "Improper mixture of spaces and tabs.");
2489 :
2490 :
2491 : /*
2492 : * LookupError extends Exception
2493 : */
2494 : SimpleExtendsException(PyExc_Exception, LookupError,
2495 : "Base class for lookup errors.");
2496 :
2497 :
2498 : /*
2499 : * IndexError extends LookupError
2500 : */
2501 : SimpleExtendsException(PyExc_LookupError, IndexError,
2502 : "Sequence index out of range.");
2503 :
2504 :
2505 : /*
2506 : * KeyError extends LookupError
2507 : */
2508 : static PyObject *
2509 45 : KeyError_str(PyBaseExceptionObject *self)
2510 : {
2511 : /* If args is a tuple of exactly one item, apply repr to args[0].
2512 : This is done so that e.g. the exception raised by {}[''] prints
2513 : KeyError: ''
2514 : rather than the confusing
2515 : KeyError
2516 : alone. The downside is that if KeyError is raised with an explanatory
2517 : string, that string will be displayed in quotes. Too bad.
2518 : If args is anything else, use the default BaseException__str__().
2519 : */
2520 45 : if (PyTuple_GET_SIZE(self->args) == 1) {
2521 23 : return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
2522 : }
2523 22 : return BaseException_str(self);
2524 : }
2525 :
2526 : ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
2527 : 0, 0, 0, 0, KeyError_str, "Mapping key not found.");
2528 :
2529 :
2530 : /*
2531 : * ValueError extends Exception
2532 : */
2533 : SimpleExtendsException(PyExc_Exception, ValueError,
2534 : "Inappropriate argument value (of correct type).");
2535 :
2536 : /*
2537 : * UnicodeError extends ValueError
2538 : */
2539 :
2540 : SimpleExtendsException(PyExc_ValueError, UnicodeError,
2541 : "Unicode related error.");
2542 :
2543 : static PyObject *
2544 9309 : get_string(PyObject *attr, const char *name)
2545 : {
2546 9309 : if (!attr) {
2547 0 : PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
2548 0 : return NULL;
2549 : }
2550 :
2551 9309 : if (!PyBytes_Check(attr)) {
2552 8 : PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
2553 8 : return NULL;
2554 : }
2555 9301 : Py_INCREF(attr);
2556 9301 : return attr;
2557 : }
2558 :
2559 : static PyObject *
2560 19761 : get_unicode(PyObject *attr, const char *name)
2561 : {
2562 19761 : if (!attr) {
2563 0 : PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
2564 0 : return NULL;
2565 : }
2566 :
2567 19761 : if (!PyUnicode_Check(attr)) {
2568 1 : PyErr_Format(PyExc_TypeError,
2569 : "%.200s attribute must be unicode", name);
2570 1 : return NULL;
2571 : }
2572 19760 : Py_INCREF(attr);
2573 19760 : return attr;
2574 : }
2575 :
2576 : static int
2577 10656 : set_unicodefromstring(PyObject **attr, const char *value)
2578 : {
2579 10656 : PyObject *obj = PyUnicode_FromString(value);
2580 10656 : if (!obj)
2581 0 : return -1;
2582 10656 : Py_XSETREF(*attr, obj);
2583 10656 : return 0;
2584 : }
2585 :
2586 : PyObject *
2587 53 : PyUnicodeEncodeError_GetEncoding(PyObject *exc)
2588 : {
2589 53 : return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
2590 : }
2591 :
2592 : PyObject *
2593 1440 : PyUnicodeDecodeError_GetEncoding(PyObject *exc)
2594 : {
2595 1440 : return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
2596 : }
2597 :
2598 : PyObject *
2599 4253 : PyUnicodeEncodeError_GetObject(PyObject *exc)
2600 : {
2601 4253 : return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
2602 : }
2603 :
2604 : PyObject *
2605 4790 : PyUnicodeDecodeError_GetObject(PyObject *exc)
2606 : {
2607 4790 : return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2608 : }
2609 :
2610 : PyObject *
2611 12 : PyUnicodeTranslateError_GetObject(PyObject *exc)
2612 : {
2613 12 : return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
2614 : }
2615 :
2616 : int
2617 5290 : PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
2618 : {
2619 : Py_ssize_t size;
2620 5290 : PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
2621 : "object");
2622 5290 : if (!obj)
2623 1 : return -1;
2624 5289 : *start = ((PyUnicodeErrorObject *)exc)->start;
2625 5289 : size = PyUnicode_GET_LENGTH(obj);
2626 5289 : if (*start<0)
2627 0 : *start = 0; /*XXX check for values <0*/
2628 5289 : if (*start>=size)
2629 0 : *start = size-1;
2630 5289 : Py_DECREF(obj);
2631 5289 : return 0;
2632 : }
2633 :
2634 :
2635 : int
2636 1503 : PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
2637 : {
2638 : Py_ssize_t size;
2639 1503 : PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2640 1503 : if (!obj)
2641 0 : return -1;
2642 1503 : size = PyBytes_GET_SIZE(obj);
2643 1503 : *start = ((PyUnicodeErrorObject *)exc)->start;
2644 1503 : if (*start<0)
2645 0 : *start = 0;
2646 1503 : if (*start>=size)
2647 0 : *start = size-1;
2648 1503 : Py_DECREF(obj);
2649 1503 : return 0;
2650 : }
2651 :
2652 :
2653 : int
2654 13 : PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
2655 : {
2656 13 : return PyUnicodeEncodeError_GetStart(exc, start);
2657 : }
2658 :
2659 :
2660 : int
2661 8901 : PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
2662 : {
2663 8901 : ((PyUnicodeErrorObject *)exc)->start = start;
2664 8901 : return 0;
2665 : }
2666 :
2667 :
2668 : int
2669 1755 : PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
2670 : {
2671 1755 : ((PyUnicodeErrorObject *)exc)->start = start;
2672 1755 : return 0;
2673 : }
2674 :
2675 :
2676 : int
2677 0 : PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
2678 : {
2679 0 : ((PyUnicodeErrorObject *)exc)->start = start;
2680 0 : return 0;
2681 : }
2682 :
2683 :
2684 : int
2685 8713 : PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
2686 : {
2687 : Py_ssize_t size;
2688 8713 : PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
2689 : "object");
2690 8713 : if (!obj)
2691 0 : return -1;
2692 8713 : *end = ((PyUnicodeErrorObject *)exc)->end;
2693 8713 : size = PyUnicode_GET_LENGTH(obj);
2694 8713 : if (*end<1)
2695 0 : *end = 1;
2696 8713 : if (*end>size)
2697 0 : *end = size;
2698 8713 : Py_DECREF(obj);
2699 8713 : return 0;
2700 : }
2701 :
2702 :
2703 : int
2704 3016 : PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
2705 : {
2706 : Py_ssize_t size;
2707 3016 : PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2708 3016 : if (!obj)
2709 1 : return -1;
2710 3015 : size = PyBytes_GET_SIZE(obj);
2711 3015 : *end = ((PyUnicodeErrorObject *)exc)->end;
2712 3015 : if (*end<1)
2713 0 : *end = 1;
2714 3015 : if (*end>size)
2715 0 : *end = size;
2716 3015 : Py_DECREF(obj);
2717 3015 : return 0;
2718 : }
2719 :
2720 :
2721 : int
2722 14 : PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
2723 : {
2724 14 : return PyUnicodeEncodeError_GetEnd(exc, end);
2725 : }
2726 :
2727 :
2728 : int
2729 8901 : PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
2730 : {
2731 8901 : ((PyUnicodeErrorObject *)exc)->end = end;
2732 8901 : return 0;
2733 : }
2734 :
2735 :
2736 : int
2737 1755 : PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
2738 : {
2739 1755 : ((PyUnicodeErrorObject *)exc)->end = end;
2740 1755 : return 0;
2741 : }
2742 :
2743 :
2744 : int
2745 0 : PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
2746 : {
2747 0 : ((PyUnicodeErrorObject *)exc)->end = end;
2748 0 : return 0;
2749 : }
2750 :
2751 : PyObject *
2752 0 : PyUnicodeEncodeError_GetReason(PyObject *exc)
2753 : {
2754 0 : return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2755 : }
2756 :
2757 :
2758 : PyObject *
2759 0 : PyUnicodeDecodeError_GetReason(PyObject *exc)
2760 : {
2761 0 : return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2762 : }
2763 :
2764 :
2765 : PyObject *
2766 0 : PyUnicodeTranslateError_GetReason(PyObject *exc)
2767 : {
2768 0 : return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2769 : }
2770 :
2771 :
2772 : int
2773 8901 : PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
2774 : {
2775 8901 : return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2776 : reason);
2777 : }
2778 :
2779 :
2780 : int
2781 1755 : PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
2782 : {
2783 1755 : return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2784 : reason);
2785 : }
2786 :
2787 :
2788 : int
2789 0 : PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
2790 : {
2791 0 : return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2792 : reason);
2793 : }
2794 :
2795 :
2796 : static int
2797 8281 : UnicodeError_clear(PyUnicodeErrorObject *self)
2798 : {
2799 8281 : Py_CLEAR(self->encoding);
2800 8281 : Py_CLEAR(self->object);
2801 8281 : Py_CLEAR(self->reason);
2802 8281 : return BaseException_clear((PyBaseExceptionObject *)self);
2803 : }
2804 :
2805 : static void
2806 8279 : UnicodeError_dealloc(PyUnicodeErrorObject *self)
2807 : {
2808 8279 : _PyObject_GC_UNTRACK(self);
2809 8279 : UnicodeError_clear(self);
2810 8279 : Py_TYPE(self)->tp_free((PyObject *)self);
2811 8279 : }
2812 :
2813 : static int
2814 14 : UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
2815 : {
2816 14 : Py_VISIT(self->encoding);
2817 14 : Py_VISIT(self->object);
2818 14 : Py_VISIT(self->reason);
2819 14 : return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2820 : }
2821 :
2822 : static PyMemberDef UnicodeError_members[] = {
2823 : {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
2824 : PyDoc_STR("exception encoding")},
2825 : {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
2826 : PyDoc_STR("exception object")},
2827 : {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
2828 : PyDoc_STR("exception start")},
2829 : {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
2830 : PyDoc_STR("exception end")},
2831 : {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
2832 : PyDoc_STR("exception reason")},
2833 : {NULL} /* Sentinel */
2834 : };
2835 :
2836 :
2837 : /*
2838 : * UnicodeEncodeError extends UnicodeError
2839 : */
2840 :
2841 : static int
2842 2343 : UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2843 : {
2844 : PyUnicodeErrorObject *err;
2845 :
2846 2343 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2847 0 : return -1;
2848 :
2849 2343 : err = (PyUnicodeErrorObject *)self;
2850 :
2851 2343 : Py_CLEAR(err->encoding);
2852 2343 : Py_CLEAR(err->object);
2853 2343 : Py_CLEAR(err->reason);
2854 :
2855 2343 : if (!PyArg_ParseTuple(args, "UUnnU",
2856 : &err->encoding, &err->object,
2857 : &err->start, &err->end, &err->reason)) {
2858 163 : err->encoding = err->object = err->reason = NULL;
2859 163 : return -1;
2860 : }
2861 :
2862 2180 : Py_INCREF(err->encoding);
2863 2180 : Py_INCREF(err->object);
2864 2180 : Py_INCREF(err->reason);
2865 :
2866 2180 : return 0;
2867 : }
2868 :
2869 : static PyObject *
2870 22 : UnicodeEncodeError_str(PyObject *self)
2871 : {
2872 22 : PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2873 22 : PyObject *result = NULL;
2874 22 : PyObject *reason_str = NULL;
2875 22 : PyObject *encoding_str = NULL;
2876 :
2877 22 : if (!uself->object)
2878 : /* Not properly initialized. */
2879 1 : return PyUnicode_FromString("");
2880 :
2881 : /* Get reason and encoding as strings, which they might not be if
2882 : they've been modified after we were constructed. */
2883 21 : reason_str = PyObject_Str(uself->reason);
2884 21 : if (reason_str == NULL)
2885 0 : goto done;
2886 21 : encoding_str = PyObject_Str(uself->encoding);
2887 21 : if (encoding_str == NULL)
2888 0 : goto done;
2889 :
2890 36 : if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
2891 15 : Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
2892 : const char *fmt;
2893 15 : if (badchar <= 0xff)
2894 8 : fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
2895 7 : else if (badchar <= 0xffff)
2896 6 : fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
2897 : else
2898 1 : fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
2899 15 : result = PyUnicode_FromFormat(
2900 : fmt,
2901 : encoding_str,
2902 : (int)badchar,
2903 : uself->start,
2904 : reason_str);
2905 : }
2906 : else {
2907 6 : result = PyUnicode_FromFormat(
2908 : "'%U' codec can't encode characters in position %zd-%zd: %U",
2909 : encoding_str,
2910 : uself->start,
2911 6 : uself->end-1,
2912 : reason_str);
2913 : }
2914 21 : done:
2915 21 : Py_XDECREF(reason_str);
2916 21 : Py_XDECREF(encoding_str);
2917 21 : return result;
2918 : }
2919 :
2920 : static PyTypeObject _PyExc_UnicodeEncodeError = {
2921 : PyVarObject_HEAD_INIT(NULL, 0)
2922 : "UnicodeEncodeError",
2923 : sizeof(PyUnicodeErrorObject), 0,
2924 : (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2925 : (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
2926 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2927 : PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
2928 : (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2929 : 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
2930 : (initproc)UnicodeEncodeError_init, 0, BaseException_new,
2931 : };
2932 : PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
2933 :
2934 :
2935 : /*
2936 : * UnicodeDecodeError extends UnicodeError
2937 : */
2938 :
2939 : static int
2940 5789 : UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2941 : {
2942 : PyUnicodeErrorObject *ude;
2943 :
2944 5789 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
2945 0 : return -1;
2946 :
2947 5789 : ude = (PyUnicodeErrorObject *)self;
2948 :
2949 5789 : Py_CLEAR(ude->encoding);
2950 5789 : Py_CLEAR(ude->object);
2951 5789 : Py_CLEAR(ude->reason);
2952 :
2953 5789 : if (!PyArg_ParseTuple(args, "UOnnU",
2954 : &ude->encoding, &ude->object,
2955 : &ude->start, &ude->end, &ude->reason)) {
2956 57 : ude->encoding = ude->object = ude->reason = NULL;
2957 57 : return -1;
2958 : }
2959 :
2960 5732 : Py_INCREF(ude->encoding);
2961 5732 : Py_INCREF(ude->object);
2962 5732 : Py_INCREF(ude->reason);
2963 :
2964 5732 : if (!PyBytes_Check(ude->object)) {
2965 : Py_buffer view;
2966 36 : if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
2967 0 : goto error;
2968 36 : Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
2969 36 : PyBuffer_Release(&view);
2970 36 : if (!ude->object)
2971 0 : goto error;
2972 : }
2973 5732 : return 0;
2974 :
2975 0 : error:
2976 0 : Py_CLEAR(ude->encoding);
2977 0 : Py_CLEAR(ude->object);
2978 0 : Py_CLEAR(ude->reason);
2979 0 : return -1;
2980 : }
2981 :
2982 : static PyObject *
2983 760 : UnicodeDecodeError_str(PyObject *self)
2984 : {
2985 760 : PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2986 760 : PyObject *result = NULL;
2987 760 : PyObject *reason_str = NULL;
2988 760 : PyObject *encoding_str = NULL;
2989 :
2990 760 : if (!uself->object)
2991 : /* Not properly initialized. */
2992 1 : return PyUnicode_FromString("");
2993 :
2994 : /* Get reason and encoding as strings, which they might not be if
2995 : they've been modified after we were constructed. */
2996 759 : reason_str = PyObject_Str(uself->reason);
2997 759 : if (reason_str == NULL)
2998 0 : goto done;
2999 759 : encoding_str = PyObject_Str(uself->encoding);
3000 759 : if (encoding_str == NULL)
3001 0 : goto done;
3002 :
3003 835 : if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) {
3004 76 : int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
3005 76 : result = PyUnicode_FromFormat(
3006 : "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3007 : encoding_str,
3008 : byte,
3009 : uself->start,
3010 : reason_str);
3011 : }
3012 : else {
3013 683 : result = PyUnicode_FromFormat(
3014 : "'%U' codec can't decode bytes in position %zd-%zd: %U",
3015 : encoding_str,
3016 : uself->start,
3017 683 : uself->end-1,
3018 : reason_str
3019 : );
3020 : }
3021 759 : done:
3022 759 : Py_XDECREF(reason_str);
3023 759 : Py_XDECREF(encoding_str);
3024 759 : return result;
3025 : }
3026 :
3027 : static PyTypeObject _PyExc_UnicodeDecodeError = {
3028 : PyVarObject_HEAD_INIT(NULL, 0)
3029 : "UnicodeDecodeError",
3030 : sizeof(PyUnicodeErrorObject), 0,
3031 : (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3032 : (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
3033 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3034 : PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
3035 : (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3036 : 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3037 : (initproc)UnicodeDecodeError_init, 0, BaseException_new,
3038 : };
3039 : PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
3040 :
3041 : PyObject *
3042 5682 : PyUnicodeDecodeError_Create(
3043 : const char *encoding, const char *object, Py_ssize_t length,
3044 : Py_ssize_t start, Py_ssize_t end, const char *reason)
3045 : {
3046 5682 : return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3047 : encoding, object, length, start, end, reason);
3048 : }
3049 :
3050 :
3051 : /*
3052 : * UnicodeTranslateError extends UnicodeError
3053 : */
3054 :
3055 : static int
3056 144 : UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
3057 : PyObject *kwds)
3058 : {
3059 144 : if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
3060 0 : return -1;
3061 :
3062 144 : Py_CLEAR(self->object);
3063 144 : Py_CLEAR(self->reason);
3064 :
3065 144 : if (!PyArg_ParseTuple(args, "UnnU",
3066 : &self->object,
3067 : &self->start, &self->end, &self->reason)) {
3068 111 : self->object = self->reason = NULL;
3069 111 : return -1;
3070 : }
3071 :
3072 33 : Py_INCREF(self->object);
3073 33 : Py_INCREF(self->reason);
3074 :
3075 33 : return 0;
3076 : }
3077 :
3078 :
3079 : static PyObject *
3080 11 : UnicodeTranslateError_str(PyObject *self)
3081 : {
3082 11 : PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
3083 11 : PyObject *result = NULL;
3084 11 : PyObject *reason_str = NULL;
3085 :
3086 11 : if (!uself->object)
3087 : /* Not properly initialized. */
3088 1 : return PyUnicode_FromString("");
3089 :
3090 : /* Get reason as a string, which it might not be if it's been
3091 : modified after we were constructed. */
3092 10 : reason_str = PyObject_Str(uself->reason);
3093 10 : if (reason_str == NULL)
3094 0 : goto done;
3095 :
3096 16 : if (uself->start < PyUnicode_GET_LENGTH(uself->object) && uself->end == uself->start+1) {
3097 6 : Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
3098 : const char *fmt;
3099 6 : if (badchar <= 0xff)
3100 2 : fmt = "can't translate character '\\x%02x' in position %zd: %U";
3101 4 : else if (badchar <= 0xffff)
3102 3 : fmt = "can't translate character '\\u%04x' in position %zd: %U";
3103 : else
3104 1 : fmt = "can't translate character '\\U%08x' in position %zd: %U";
3105 6 : result = PyUnicode_FromFormat(
3106 : fmt,
3107 : (int)badchar,
3108 : uself->start,
3109 : reason_str
3110 : );
3111 : } else {
3112 4 : result = PyUnicode_FromFormat(
3113 : "can't translate characters in position %zd-%zd: %U",
3114 : uself->start,
3115 4 : uself->end-1,
3116 : reason_str
3117 : );
3118 : }
3119 10 : done:
3120 10 : Py_XDECREF(reason_str);
3121 10 : return result;
3122 : }
3123 :
3124 : static PyTypeObject _PyExc_UnicodeTranslateError = {
3125 : PyVarObject_HEAD_INIT(NULL, 0)
3126 : "UnicodeTranslateError",
3127 : sizeof(PyUnicodeErrorObject), 0,
3128 : (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3129 : (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
3130 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3131 : PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
3132 : (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3133 : 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3134 : (initproc)UnicodeTranslateError_init, 0, BaseException_new,
3135 : };
3136 : PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
3137 :
3138 : PyObject *
3139 0 : _PyUnicodeTranslateError_Create(
3140 : PyObject *object,
3141 : Py_ssize_t start, Py_ssize_t end, const char *reason)
3142 : {
3143 0 : return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
3144 : object, start, end, reason);
3145 : }
3146 :
3147 : /*
3148 : * AssertionError extends Exception
3149 : */
3150 : SimpleExtendsException(PyExc_Exception, AssertionError,
3151 : "Assertion failed.");
3152 :
3153 :
3154 : /*
3155 : * ArithmeticError extends Exception
3156 : */
3157 : SimpleExtendsException(PyExc_Exception, ArithmeticError,
3158 : "Base class for arithmetic errors.");
3159 :
3160 :
3161 : /*
3162 : * FloatingPointError extends ArithmeticError
3163 : */
3164 : SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
3165 : "Floating point operation failed.");
3166 :
3167 :
3168 : /*
3169 : * OverflowError extends ArithmeticError
3170 : */
3171 : SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
3172 : "Result too large to be represented.");
3173 :
3174 :
3175 : /*
3176 : * ZeroDivisionError extends ArithmeticError
3177 : */
3178 : SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
3179 : "Second argument to a division or modulo operation was zero.");
3180 :
3181 :
3182 : /*
3183 : * SystemError extends Exception
3184 : */
3185 : SimpleExtendsException(PyExc_Exception, SystemError,
3186 : "Internal error in the Python interpreter.\n"
3187 : "\n"
3188 : "Please report this to the Python maintainer, along with the traceback,\n"
3189 : "the Python version, and the hardware/OS platform and version.");
3190 :
3191 :
3192 : /*
3193 : * ReferenceError extends Exception
3194 : */
3195 : SimpleExtendsException(PyExc_Exception, ReferenceError,
3196 : "Weak ref proxy used after referent went away.");
3197 :
3198 :
3199 : /*
3200 : * MemoryError extends Exception
3201 : */
3202 :
3203 : #define MEMERRORS_SAVE 16
3204 :
3205 : static PyObject *
3206 47583 : MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3207 : {
3208 : PyBaseExceptionObject *self;
3209 :
3210 : /* If this is a subclass of MemoryError, don't use the freelist
3211 : * and just return a fresh object */
3212 47583 : if (type != (PyTypeObject *) PyExc_MemoryError) {
3213 1 : return BaseException_new(type, args, kwds);
3214 : }
3215 :
3216 47582 : struct _Py_exc_state *state = get_exc_state();
3217 47582 : if (state->memerrors_freelist == NULL) {
3218 47411 : return BaseException_new(type, args, kwds);
3219 : }
3220 :
3221 : /* Fetch object from freelist and revive it */
3222 171 : self = state->memerrors_freelist;
3223 171 : self->args = PyTuple_New(0);
3224 : /* This shouldn't happen since the empty tuple is persistent */
3225 171 : if (self->args == NULL) {
3226 0 : return NULL;
3227 : }
3228 :
3229 171 : state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
3230 171 : state->memerrors_numfree--;
3231 171 : self->dict = NULL;
3232 171 : _Py_NewReference((PyObject *)self);
3233 171 : _PyObject_GC_TRACK(self);
3234 171 : return (PyObject *)self;
3235 : }
3236 :
3237 : static void
3238 47583 : MemoryError_dealloc(PyBaseExceptionObject *self)
3239 : {
3240 47583 : BaseException_clear(self);
3241 :
3242 : /* If this is a subclass of MemoryError, we don't need to
3243 : * do anything in the free-list*/
3244 47583 : if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
3245 1 : Py_TYPE(self)->tp_free((PyObject *)self);
3246 1 : return;
3247 : }
3248 :
3249 47582 : _PyObject_GC_UNTRACK(self);
3250 :
3251 47582 : struct _Py_exc_state *state = get_exc_state();
3252 47582 : if (state->memerrors_numfree >= MEMERRORS_SAVE) {
3253 3 : Py_TYPE(self)->tp_free((PyObject *)self);
3254 : }
3255 : else {
3256 47579 : self->dict = (PyObject *) state->memerrors_freelist;
3257 47579 : state->memerrors_freelist = self;
3258 47579 : state->memerrors_numfree++;
3259 : }
3260 : }
3261 :
3262 : static int
3263 2963 : preallocate_memerrors(void)
3264 : {
3265 : /* We create enough MemoryErrors and then decref them, which will fill
3266 : up the freelist. */
3267 : int i;
3268 : PyObject *errors[MEMERRORS_SAVE];
3269 50371 : for (i = 0; i < MEMERRORS_SAVE; i++) {
3270 47408 : errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
3271 : NULL, NULL);
3272 47408 : if (!errors[i]) {
3273 0 : return -1;
3274 : }
3275 : }
3276 50371 : for (i = 0; i < MEMERRORS_SAVE; i++) {
3277 47408 : Py_DECREF(errors[i]);
3278 : }
3279 2963 : return 0;
3280 : }
3281 :
3282 : static void
3283 3120 : free_preallocated_memerrors(struct _Py_exc_state *state)
3284 : {
3285 50336 : while (state->memerrors_freelist != NULL) {
3286 47216 : PyObject *self = (PyObject *) state->memerrors_freelist;
3287 47216 : state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
3288 47216 : Py_TYPE(self)->tp_free((PyObject *)self);
3289 : }
3290 3120 : }
3291 :
3292 :
3293 : static PyTypeObject _PyExc_MemoryError = {
3294 : PyVarObject_HEAD_INIT(NULL, 0)
3295 : "MemoryError",
3296 : sizeof(PyBaseExceptionObject),
3297 : 0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
3298 : 0, 0, 0, 0, 0, 0, 0,
3299 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3300 : PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
3301 : (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
3302 : 0, 0, 0, offsetof(PyBaseExceptionObject, dict),
3303 : (initproc)BaseException_init, 0, MemoryError_new
3304 : };
3305 : PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
3306 :
3307 :
3308 : /*
3309 : * BufferError extends Exception
3310 : */
3311 : SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
3312 :
3313 :
3314 : /* Warning category docstrings */
3315 :
3316 : /*
3317 : * Warning extends Exception
3318 : */
3319 : SimpleExtendsException(PyExc_Exception, Warning,
3320 : "Base class for warning categories.");
3321 :
3322 :
3323 : /*
3324 : * UserWarning extends Warning
3325 : */
3326 : SimpleExtendsException(PyExc_Warning, UserWarning,
3327 : "Base class for warnings generated by user code.");
3328 :
3329 :
3330 : /*
3331 : * DeprecationWarning extends Warning
3332 : */
3333 : SimpleExtendsException(PyExc_Warning, DeprecationWarning,
3334 : "Base class for warnings about deprecated features.");
3335 :
3336 :
3337 : /*
3338 : * PendingDeprecationWarning extends Warning
3339 : */
3340 : SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
3341 : "Base class for warnings about features which will be deprecated\n"
3342 : "in the future.");
3343 :
3344 :
3345 : /*
3346 : * SyntaxWarning extends Warning
3347 : */
3348 : SimpleExtendsException(PyExc_Warning, SyntaxWarning,
3349 : "Base class for warnings about dubious syntax.");
3350 :
3351 :
3352 : /*
3353 : * RuntimeWarning extends Warning
3354 : */
3355 : SimpleExtendsException(PyExc_Warning, RuntimeWarning,
3356 : "Base class for warnings about dubious runtime behavior.");
3357 :
3358 :
3359 : /*
3360 : * FutureWarning extends Warning
3361 : */
3362 : SimpleExtendsException(PyExc_Warning, FutureWarning,
3363 : "Base class for warnings about constructs that will change semantically\n"
3364 : "in the future.");
3365 :
3366 :
3367 : /*
3368 : * ImportWarning extends Warning
3369 : */
3370 : SimpleExtendsException(PyExc_Warning, ImportWarning,
3371 : "Base class for warnings about probable mistakes in module imports");
3372 :
3373 :
3374 : /*
3375 : * UnicodeWarning extends Warning
3376 : */
3377 : SimpleExtendsException(PyExc_Warning, UnicodeWarning,
3378 : "Base class for warnings about Unicode related problems, mostly\n"
3379 : "related to conversion problems.");
3380 :
3381 :
3382 : /*
3383 : * BytesWarning extends Warning
3384 : */
3385 : SimpleExtendsException(PyExc_Warning, BytesWarning,
3386 : "Base class for warnings about bytes and buffer related problems, mostly\n"
3387 : "related to conversion from str or comparing to str.");
3388 :
3389 :
3390 : /*
3391 : * EncodingWarning extends Warning
3392 : */
3393 : SimpleExtendsException(PyExc_Warning, EncodingWarning,
3394 : "Base class for warnings about encodings.");
3395 :
3396 :
3397 : /*
3398 : * ResourceWarning extends Warning
3399 : */
3400 : SimpleExtendsException(PyExc_Warning, ResourceWarning,
3401 : "Base class for warnings about resource usage.");
3402 :
3403 :
3404 :
3405 : #ifdef MS_WINDOWS
3406 : #include <winsock2.h>
3407 : /* The following constants were added to errno.h in VS2010 but have
3408 : preferred WSA equivalents. */
3409 : #undef EADDRINUSE
3410 : #undef EADDRNOTAVAIL
3411 : #undef EAFNOSUPPORT
3412 : #undef EALREADY
3413 : #undef ECONNABORTED
3414 : #undef ECONNREFUSED
3415 : #undef ECONNRESET
3416 : #undef EDESTADDRREQ
3417 : #undef EHOSTUNREACH
3418 : #undef EINPROGRESS
3419 : #undef EISCONN
3420 : #undef ELOOP
3421 : #undef EMSGSIZE
3422 : #undef ENETDOWN
3423 : #undef ENETRESET
3424 : #undef ENETUNREACH
3425 : #undef ENOBUFS
3426 : #undef ENOPROTOOPT
3427 : #undef ENOTCONN
3428 : #undef ENOTSOCK
3429 : #undef EOPNOTSUPP
3430 : #undef EPROTONOSUPPORT
3431 : #undef EPROTOTYPE
3432 : #undef ETIMEDOUT
3433 : #undef EWOULDBLOCK
3434 :
3435 : #if defined(WSAEALREADY) && !defined(EALREADY)
3436 : #define EALREADY WSAEALREADY
3437 : #endif
3438 : #if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
3439 : #define ECONNABORTED WSAECONNABORTED
3440 : #endif
3441 : #if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
3442 : #define ECONNREFUSED WSAECONNREFUSED
3443 : #endif
3444 : #if defined(WSAECONNRESET) && !defined(ECONNRESET)
3445 : #define ECONNRESET WSAECONNRESET
3446 : #endif
3447 : #if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
3448 : #define EINPROGRESS WSAEINPROGRESS
3449 : #endif
3450 : #if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
3451 : #define ESHUTDOWN WSAESHUTDOWN
3452 : #endif
3453 : #if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
3454 : #define ETIMEDOUT WSAETIMEDOUT
3455 : #endif
3456 : #if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
3457 : #define EWOULDBLOCK WSAEWOULDBLOCK
3458 : #endif
3459 : #endif /* MS_WINDOWS */
3460 :
3461 : struct static_exception {
3462 : PyTypeObject *exc;
3463 : const char *name;
3464 : };
3465 :
3466 : static struct static_exception static_exceptions[] = {
3467 : #define ITEM(NAME) {&_PyExc_##NAME, #NAME}
3468 : // Level 1
3469 : ITEM(BaseException),
3470 :
3471 : // Level 2: BaseException subclasses
3472 : ITEM(BaseExceptionGroup),
3473 : ITEM(Exception),
3474 : ITEM(GeneratorExit),
3475 : ITEM(KeyboardInterrupt),
3476 : ITEM(SystemExit),
3477 :
3478 : // Level 3: Exception(BaseException) subclasses
3479 : ITEM(ArithmeticError),
3480 : ITEM(AssertionError),
3481 : ITEM(AttributeError),
3482 : ITEM(BufferError),
3483 : ITEM(EOFError),
3484 : //ITEM(ExceptionGroup),
3485 : ITEM(ImportError),
3486 : ITEM(LookupError),
3487 : ITEM(MemoryError),
3488 : ITEM(NameError),
3489 : ITEM(OSError),
3490 : ITEM(ReferenceError),
3491 : ITEM(RuntimeError),
3492 : ITEM(StopAsyncIteration),
3493 : ITEM(StopIteration),
3494 : ITEM(SyntaxError),
3495 : ITEM(SystemError),
3496 : ITEM(TypeError),
3497 : ITEM(ValueError),
3498 : ITEM(Warning),
3499 :
3500 : // Level 4: ArithmeticError(Exception) subclasses
3501 : ITEM(FloatingPointError),
3502 : ITEM(OverflowError),
3503 : ITEM(ZeroDivisionError),
3504 :
3505 : // Level 4: Warning(Exception) subclasses
3506 : ITEM(BytesWarning),
3507 : ITEM(DeprecationWarning),
3508 : ITEM(EncodingWarning),
3509 : ITEM(FutureWarning),
3510 : ITEM(ImportWarning),
3511 : ITEM(PendingDeprecationWarning),
3512 : ITEM(ResourceWarning),
3513 : ITEM(RuntimeWarning),
3514 : ITEM(SyntaxWarning),
3515 : ITEM(UnicodeWarning),
3516 : ITEM(UserWarning),
3517 :
3518 : // Level 4: OSError(Exception) subclasses
3519 : ITEM(BlockingIOError),
3520 : ITEM(ChildProcessError),
3521 : ITEM(ConnectionError),
3522 : ITEM(FileExistsError),
3523 : ITEM(FileNotFoundError),
3524 : ITEM(InterruptedError),
3525 : ITEM(IsADirectoryError),
3526 : ITEM(NotADirectoryError),
3527 : ITEM(PermissionError),
3528 : ITEM(ProcessLookupError),
3529 : ITEM(TimeoutError),
3530 :
3531 : // Level 4: Other subclasses
3532 : ITEM(IndentationError), // base: SyntaxError(Exception)
3533 : ITEM(IndexError), // base: LookupError(Exception)
3534 : ITEM(KeyError), // base: LookupError(Exception)
3535 : ITEM(ModuleNotFoundError), // base: ImportError(Exception)
3536 : ITEM(NotImplementedError), // base: RuntimeError(Exception)
3537 : ITEM(RecursionError), // base: RuntimeError(Exception)
3538 : ITEM(UnboundLocalError), // base: NameError(Exception)
3539 : ITEM(UnicodeError), // base: ValueError(Exception)
3540 :
3541 : // Level 5: ConnectionError(OSError) subclasses
3542 : ITEM(BrokenPipeError),
3543 : ITEM(ConnectionAbortedError),
3544 : ITEM(ConnectionRefusedError),
3545 : ITEM(ConnectionResetError),
3546 :
3547 : // Level 5: IndentationError(SyntaxError) subclasses
3548 : ITEM(TabError), // base: IndentationError
3549 :
3550 : // Level 5: UnicodeError(ValueError) subclasses
3551 : ITEM(UnicodeDecodeError),
3552 : ITEM(UnicodeEncodeError),
3553 : ITEM(UnicodeTranslateError),
3554 : #undef ITEM
3555 : };
3556 :
3557 :
3558 : int
3559 3134 : _PyExc_InitTypes(PyInterpreterState *interp)
3560 : {
3561 3134 : if (!_Py_IsMainInterpreter(interp)) {
3562 171 : return 0;
3563 : }
3564 :
3565 198521 : for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
3566 195558 : PyTypeObject *exc = static_exceptions[i].exc;
3567 :
3568 195558 : if (PyType_Ready(exc) < 0) {
3569 0 : return -1;
3570 : }
3571 : }
3572 2963 : return 0;
3573 : }
3574 :
3575 :
3576 : static void
3577 3120 : _PyExc_FiniTypes(PyInterpreterState *interp)
3578 : {
3579 3120 : if (!_Py_IsMainInterpreter(interp)) {
3580 169 : return;
3581 : }
3582 :
3583 197717 : for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
3584 194766 : PyTypeObject *exc = static_exceptions[i].exc;
3585 194766 : _PyStaticType_Dealloc(exc);
3586 : }
3587 : }
3588 :
3589 :
3590 : PyStatus
3591 3134 : _PyExc_InitGlobalObjects(PyInterpreterState *interp)
3592 : {
3593 3134 : if (!_Py_IsMainInterpreter(interp)) {
3594 171 : return _PyStatus_OK();
3595 : }
3596 :
3597 2963 : if (preallocate_memerrors() < 0) {
3598 0 : return _PyStatus_NO_MEMORY();
3599 : }
3600 2963 : return _PyStatus_OK();
3601 : }
3602 :
3603 : PyStatus
3604 3134 : _PyExc_InitState(PyInterpreterState *interp)
3605 : {
3606 3134 : struct _Py_exc_state *state = &interp->exc_state;
3607 :
3608 : #define ADD_ERRNO(TYPE, CODE) \
3609 : do { \
3610 : PyObject *_code = PyLong_FromLong(CODE); \
3611 : assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
3612 : if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
3613 : Py_XDECREF(_code); \
3614 : return _PyStatus_ERR("errmap insertion problem."); \
3615 : } \
3616 : Py_DECREF(_code); \
3617 : } while (0)
3618 :
3619 : /* Add exceptions to errnomap */
3620 3134 : assert(state->errnomap == NULL);
3621 3134 : state->errnomap = PyDict_New();
3622 3134 : if (!state->errnomap) {
3623 0 : return _PyStatus_NO_MEMORY();
3624 : }
3625 :
3626 3134 : ADD_ERRNO(BlockingIOError, EAGAIN);
3627 3134 : ADD_ERRNO(BlockingIOError, EALREADY);
3628 3134 : ADD_ERRNO(BlockingIOError, EINPROGRESS);
3629 3134 : ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
3630 3134 : ADD_ERRNO(BrokenPipeError, EPIPE);
3631 : #ifdef ESHUTDOWN
3632 3134 : ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
3633 : #endif
3634 3134 : ADD_ERRNO(ChildProcessError, ECHILD);
3635 3134 : ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
3636 3134 : ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
3637 3134 : ADD_ERRNO(ConnectionResetError, ECONNRESET);
3638 3134 : ADD_ERRNO(FileExistsError, EEXIST);
3639 3134 : ADD_ERRNO(FileNotFoundError, ENOENT);
3640 3134 : ADD_ERRNO(IsADirectoryError, EISDIR);
3641 3134 : ADD_ERRNO(NotADirectoryError, ENOTDIR);
3642 3134 : ADD_ERRNO(InterruptedError, EINTR);
3643 3134 : ADD_ERRNO(PermissionError, EACCES);
3644 3134 : ADD_ERRNO(PermissionError, EPERM);
3645 3134 : ADD_ERRNO(ProcessLookupError, ESRCH);
3646 3134 : ADD_ERRNO(TimeoutError, ETIMEDOUT);
3647 :
3648 3134 : return _PyStatus_OK();
3649 :
3650 : #undef ADD_ERRNO
3651 : }
3652 :
3653 :
3654 : /* Add exception types to the builtins module */
3655 : int
3656 3134 : _PyBuiltins_AddExceptions(PyObject *bltinmod)
3657 : {
3658 3134 : PyObject *mod_dict = PyModule_GetDict(bltinmod);
3659 3134 : if (mod_dict == NULL) {
3660 0 : return -1;
3661 : }
3662 :
3663 209978 : for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
3664 206844 : struct static_exception item = static_exceptions[i];
3665 :
3666 206844 : if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
3667 0 : return -1;
3668 : }
3669 : }
3670 :
3671 3134 : PyObject *PyExc_ExceptionGroup = create_exception_group_class();
3672 3134 : if (!PyExc_ExceptionGroup) {
3673 0 : return -1;
3674 : }
3675 3134 : if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
3676 0 : return -1;
3677 : }
3678 :
3679 : #define INIT_ALIAS(NAME, TYPE) \
3680 : do { \
3681 : PyExc_ ## NAME = PyExc_ ## TYPE; \
3682 : if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \
3683 : return -1; \
3684 : } \
3685 : } while (0)
3686 :
3687 3134 : INIT_ALIAS(EnvironmentError, OSError);
3688 3134 : INIT_ALIAS(IOError, OSError);
3689 : #ifdef MS_WINDOWS
3690 : INIT_ALIAS(WindowsError, OSError);
3691 : #endif
3692 :
3693 : #undef INIT_ALIAS
3694 :
3695 3134 : return 0;
3696 : }
3697 :
3698 : void
3699 3120 : _PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
3700 : {
3701 3120 : struct _Py_exc_state *state = &interp->exc_state;
3702 3120 : Py_CLEAR(state->PyExc_ExceptionGroup);
3703 3120 : }
3704 :
3705 : void
3706 3120 : _PyExc_Fini(PyInterpreterState *interp)
3707 : {
3708 3120 : struct _Py_exc_state *state = &interp->exc_state;
3709 3120 : free_preallocated_memerrors(state);
3710 3120 : Py_CLEAR(state->errnomap);
3711 :
3712 3120 : _PyExc_FiniTypes(interp);
3713 3120 : }
3714 :
3715 : /* Helper to do the equivalent of "raise X from Y" in C, but always using
3716 : * the current exception rather than passing one in.
3717 : *
3718 : * We currently limit this to *only* exceptions that use the BaseException
3719 : * tp_init and tp_new methods, since we can be reasonably sure we can wrap
3720 : * those correctly without losing data and without losing backwards
3721 : * compatibility.
3722 : *
3723 : * We also aim to rule out *all* exceptions that might be storing additional
3724 : * state, whether by having a size difference relative to BaseException,
3725 : * additional arguments passed in during construction or by having a
3726 : * non-empty instance dict.
3727 : *
3728 : * We need to be very careful with what we wrap, since changing types to
3729 : * a broader exception type would be backwards incompatible for
3730 : * existing codecs, and with different init or new method implementations
3731 : * may either not support instantiation with PyErr_Format or lose
3732 : * information when instantiated that way.
3733 : *
3734 : * XXX (ncoghlan): This could be made more comprehensive by exploiting the
3735 : * fact that exceptions are expected to support pickling. If more builtin
3736 : * exceptions (e.g. AttributeError) start to be converted to rich
3737 : * exceptions with additional attributes, that's probably a better approach
3738 : * to pursue over adding special cases for particular stateful subclasses.
3739 : *
3740 : * Returns a borrowed reference to the new exception (if any), NULL if the
3741 : * existing exception was left in place.
3742 : */
3743 : PyObject *
3744 141 : _PyErr_TrySetFromCause(const char *format, ...)
3745 : {
3746 : PyObject* msg_prefix;
3747 : PyObject *exc, *val, *tb;
3748 : PyTypeObject *caught_type;
3749 : PyObject *instance_args;
3750 : Py_ssize_t num_args, caught_type_size, base_exc_size;
3751 : PyObject *new_exc, *new_val, *new_tb;
3752 : va_list vargs;
3753 : int same_basic_size;
3754 :
3755 141 : PyErr_Fetch(&exc, &val, &tb);
3756 141 : caught_type = (PyTypeObject *)exc;
3757 : /* Ensure type info indicates no extra state is stored at the C level
3758 : * and that the type can be reinstantiated using PyErr_Format
3759 : */
3760 141 : caught_type_size = caught_type->tp_basicsize;
3761 141 : base_exc_size = _PyExc_BaseException.tp_basicsize;
3762 141 : same_basic_size = (
3763 221 : caught_type_size == base_exc_size ||
3764 66 : (_PyType_SUPPORTS_WEAKREFS(caught_type) &&
3765 14 : (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))
3766 : )
3767 : );
3768 141 : if (caught_type->tp_init != (initproc)BaseException_init ||
3769 85 : caught_type->tp_new != BaseException_new ||
3770 81 : !same_basic_size ||
3771 81 : caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) {
3772 : /* We can't be sure we can wrap this safely, since it may contain
3773 : * more state than just the exception type. Accordingly, we just
3774 : * leave it alone.
3775 : */
3776 60 : PyErr_Restore(exc, val, tb);
3777 60 : return NULL;
3778 : }
3779 :
3780 : /* Check the args are empty or contain a single string */
3781 81 : PyErr_NormalizeException(&exc, &val, &tb);
3782 81 : instance_args = ((PyBaseExceptionObject *)val)->args;
3783 81 : num_args = PyTuple_GET_SIZE(instance_args);
3784 81 : if (num_args > 1 ||
3785 73 : (num_args == 1 &&
3786 73 : !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) {
3787 : /* More than 1 arg, or the one arg we do have isn't a string
3788 : */
3789 8 : PyErr_Restore(exc, val, tb);
3790 8 : return NULL;
3791 : }
3792 :
3793 : /* Ensure the instance dict is also empty */
3794 73 : if (!_PyObject_IsInstanceDictEmpty(val)) {
3795 : /* While we could potentially copy a non-empty instance dictionary
3796 : * to the replacement exception, for now we take the more
3797 : * conservative path of leaving exceptions with attributes set
3798 : * alone.
3799 : */
3800 4 : PyErr_Restore(exc, val, tb);
3801 4 : return NULL;
3802 : }
3803 :
3804 : /* For exceptions that we can wrap safely, we chain the original
3805 : * exception to a new one of the exact same type with an
3806 : * error message that mentions the additional details and the
3807 : * original exception.
3808 : *
3809 : * It would be nice to wrap OSError and various other exception
3810 : * types as well, but that's quite a bit trickier due to the extra
3811 : * state potentially stored on OSError instances.
3812 : */
3813 : /* Ensure the traceback is set correctly on the existing exception */
3814 69 : if (tb != NULL) {
3815 62 : PyException_SetTraceback(val, tb);
3816 62 : Py_DECREF(tb);
3817 : }
3818 :
3819 69 : va_start(vargs, format);
3820 69 : msg_prefix = PyUnicode_FromFormatV(format, vargs);
3821 69 : va_end(vargs);
3822 69 : if (msg_prefix == NULL) {
3823 0 : Py_DECREF(exc);
3824 0 : Py_DECREF(val);
3825 0 : return NULL;
3826 : }
3827 :
3828 69 : PyErr_Format(exc, "%U (%s: %S)",
3829 69 : msg_prefix, Py_TYPE(val)->tp_name, val);
3830 69 : Py_DECREF(exc);
3831 69 : Py_DECREF(msg_prefix);
3832 69 : PyErr_Fetch(&new_exc, &new_val, &new_tb);
3833 69 : PyErr_NormalizeException(&new_exc, &new_val, &new_tb);
3834 69 : PyException_SetCause(new_val, val);
3835 69 : PyErr_Restore(new_exc, new_val, new_tb);
3836 69 : return new_val;
3837 : }
|