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