Coverage Report

Created: 2026-10-31 06:21

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