Coverage Report

Created: 2025-08-26 06:26

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