Coverage Report

Created: 2026-09-03 06:36

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