Coverage Report

Created: 2026-10-17 06:15

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