Coverage Report

Created: 2026-03-08 06:40

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