Coverage Report

Created: 2026-02-09 07:07

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
222k
{
31
222k
    PyInterpreterState *interp = _PyInterpreterState_GET();
32
222k
    return &interp->exc_state;
33
222k
}
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
231M
{
43
231M
    assert(PyExceptionInstance_Check(exc));
44
231M
    return (PyBaseExceptionObject *)exc;
45
231M
}
46
47
/*
48
 *    BaseException
49
 */
50
static PyObject *
51
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
52
26.3M
{
53
26.3M
    PyBaseExceptionObject *self;
54
55
26.3M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
56
26.3M
    if (!self)
57
0
        return NULL;
58
    /* the dict is created on the fly in PyObject_GenericSetAttr */
59
26.3M
    self->dict = NULL;
60
26.3M
    self->notes = NULL;
61
26.3M
    self->traceback = self->cause = self->context = NULL;
62
26.3M
    self->suppress_context = 0;
63
64
26.3M
    if (args) {
65
26.3M
        self->args = Py_NewRef(args);
66
26.3M
        return (PyObject *)self;
67
26.3M
    }
68
69
512
    self->args = PyTuple_New(0);
70
512
    if (!self->args) {
71
0
        Py_DECREF(self);
72
0
        return NULL;
73
0
    }
74
75
512
    return (PyObject *)self;
76
512
}
77
78
static int
79
BaseException_init(PyObject *op, PyObject *args, PyObject *kwds)
80
24.9M
{
81
24.9M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
82
24.9M
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
83
0
        return -1;
84
85
24.9M
    Py_XSETREF(self->args, Py_NewRef(args));
86
24.9M
    return 0;
87
24.9M
}
88
89
90
static PyObject *
91
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
92
                         size_t nargsf, PyObject *kwnames)
93
13.3M
{
94
13.3M
    PyTypeObject *type = _PyType_CAST(type_obj);
95
13.3M
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
96
0
        return NULL;
97
0
    }
98
99
13.3M
    PyBaseExceptionObject *self;
100
13.3M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
101
13.3M
    if (!self) {
102
0
        return NULL;
103
0
    }
104
105
    // The dict is created on the fly in PyObject_GenericSetAttr()
106
13.3M
    self->dict = NULL;
107
13.3M
    self->notes = NULL;
108
13.3M
    self->traceback = NULL;
109
13.3M
    self->cause = NULL;
110
13.3M
    self->context = NULL;
111
13.3M
    self->suppress_context = 0;
112
113
13.3M
    self->args = PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
114
13.3M
    if (!self->args) {
115
0
        Py_DECREF(self);
116
0
        return NULL;
117
0
    }
118
119
13.3M
    return (PyObject *)self;
120
13.3M
}
121
122
123
static int
124
BaseException_clear(PyObject *op)
125
40.0M
{
126
40.0M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
127
40.0M
    Py_CLEAR(self->dict);
128
40.0M
    Py_CLEAR(self->args);
129
40.0M
    Py_CLEAR(self->notes);
130
40.0M
    Py_CLEAR(self->traceback);
131
40.0M
    Py_CLEAR(self->cause);
132
40.0M
    Py_CLEAR(self->context);
133
40.0M
    return 0;
134
40.0M
}
135
136
static void
137
BaseException_dealloc(PyObject *op)
138
25.1M
{
139
25.1M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
140
25.1M
    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
25.1M
    (void)BaseException_clear(op);
145
25.1M
    Py_TYPE(self)->tp_free(self);
146
25.1M
}
147
148
static int
149
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
150
6.17M
{
151
6.17M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
152
6.17M
    Py_VISIT(self->dict);
153
6.17M
    Py_VISIT(self->args);
154
6.17M
    Py_VISIT(self->notes);
155
6.17M
    Py_VISIT(self->traceback);
156
6.17M
    Py_VISIT(self->cause);
157
6.17M
    Py_VISIT(self->context);
158
6.17M
    return 0;
159
6.17M
}
160
161
static PyObject *
162
BaseException_str(PyObject *op)
163
4.02M
{
164
4.02M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
165
166
4.02M
    PyObject *res;
167
4.02M
    Py_BEGIN_CRITICAL_SECTION(self);
168
4.02M
    switch (PyTuple_GET_SIZE(self->args)) {
169
0
    case 0:
170
0
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
171
0
        break;
172
4.02M
    case 1:
173
4.02M
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
174
4.02M
        break;
175
0
    default:
176
0
        res = PyObject_Str(self->args);
177
0
        break;
178
4.02M
    }
179
4.02M
    Py_END_CRITICAL_SECTION();
180
4.02M
    return res;
181
4.02M
}
182
183
static PyObject *
184
BaseException_repr(PyObject *op)
185
9.50k
{
186
187
9.50k
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
188
189
9.50k
    PyObject *res;
190
9.50k
    Py_BEGIN_CRITICAL_SECTION(self);
191
9.50k
    const char *name = _PyType_Name(Py_TYPE(self));
192
9.50k
    if (PyTuple_GET_SIZE(self->args) == 1) {
193
9.50k
        res = PyUnicode_FromFormat("%s(%R)", name,
194
9.50k
                                    PyTuple_GET_ITEM(self->args, 0));
195
9.50k
    }
196
0
    else {
197
0
        res = PyUnicode_FromFormat("%s%R", name, self->args);
198
0
    }
199
9.50k
    Py_END_CRITICAL_SECTION();
200
9.50k
    return res;
201
9.50k
}
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
41.4k
{
292
41.4k
    PyObject *notes;
293
41.4k
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
294
0
        return NULL;
295
0
    }
296
41.4k
    if (notes == NULL) {
297
41.4k
        notes = PyList_New(0);
298
41.4k
        if (notes == NULL) {
299
0
            return NULL;
300
0
        }
301
41.4k
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
302
0
            Py_DECREF(notes);
303
0
            return NULL;
304
0
        }
305
41.4k
    }
306
64
    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
41.4k
    if (PyList_Append(notes, note) < 0) {
312
0
        Py_DECREF(notes);
313
0
        return NULL;
314
0
    }
315
41.4k
    Py_DECREF(notes);
316
41.4k
    Py_RETURN_NONE;
317
41.4k
}
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
1.87M
{
353
1.87M
    PyObject *seq;
354
1.87M
    if (value == NULL) {
355
0
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
356
0
        return -1;
357
0
    }
358
1.87M
    seq = PySequence_Tuple(value);
359
1.87M
    if (!seq)
360
0
        return -1;
361
1.87M
    Py_XSETREF(self->args, seq);
362
1.87M
    return 0;
363
1.87M
}
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
45.3M
{
393
45.3M
    if (value == NULL) {
394
0
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
395
0
        return -1;
396
0
    }
397
45.3M
    if (PyTraceBack_Check(value)) {
398
45.3M
        Py_XSETREF(self->traceback, Py_NewRef(value));
399
45.3M
    }
400
3.88k
    else if (value == Py_None) {
401
3.88k
        Py_CLEAR(self->traceback);
402
3.88k
    }
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
45.3M
    return 0;
409
45.3M
}
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
77.9M
{
512
77.9M
    PyObject *traceback;
513
77.9M
    Py_BEGIN_CRITICAL_SECTION(self);
514
77.9M
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
515
77.9M
    Py_END_CRITICAL_SECTION();
516
77.9M
    return traceback;
517
77.9M
}
518
519
520
int
521
PyException_SetTraceback(PyObject *self, PyObject *tb)
522
45.3M
{
523
45.3M
    int res;
524
45.3M
    Py_BEGIN_CRITICAL_SECTION(self);
525
45.3M
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
526
45.3M
    Py_END_CRITICAL_SECTION();
527
45.3M
    return res;
528
45.3M
}
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
13.2k
{
544
13.2k
    Py_BEGIN_CRITICAL_SECTION(self);
545
13.2k
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
546
13.2k
    base_self->suppress_context = 1;
547
13.2k
    Py_XSETREF(base_self->cause, cause);
548
13.2k
    Py_END_CRITICAL_SECTION();
549
13.2k
}
550
551
PyObject *
552
PyException_GetContext(PyObject *self)
553
4.35M
{
554
4.35M
    PyObject *context;
555
4.35M
    Py_BEGIN_CRITICAL_SECTION(self);
556
4.35M
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
557
4.35M
    Py_END_CRITICAL_SECTION();
558
4.35M
    return context;
559
4.35M
}
560
561
/* Steals a reference to context */
562
void
563
PyException_SetContext(PyObject *self, PyObject *context)
564
3.55M
{
565
3.55M
    Py_BEGIN_CRITICAL_SECTION(self);
566
3.55M
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
567
3.55M
    Py_END_CRITICAL_SECTION();
568
3.55M
}
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
23.6M
{
740
23.6M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
741
23.6M
    return (PyStopIterationObject *)self;
742
23.6M
}
743
744
static int
745
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
746
11.8M
{
747
11.8M
    Py_ssize_t size = PyTuple_GET_SIZE(args);
748
11.8M
    PyObject *value;
749
750
11.8M
    if (BaseException_init(op, args, kwds) == -1)
751
0
        return -1;
752
11.8M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
753
11.8M
    Py_CLEAR(self->value);
754
11.8M
    if (size > 0)
755
2.06k
        value = PyTuple_GET_ITEM(args, 0);
756
11.8M
    else
757
11.8M
        value = Py_None;
758
11.8M
    self->value = Py_NewRef(value);
759
11.8M
    return 0;
760
11.8M
}
761
762
static int
763
StopIteration_clear(PyObject *op)
764
11.8M
{
765
11.8M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
766
11.8M
    Py_CLEAR(self->value);
767
11.8M
    return BaseException_clear(op);
768
11.8M
}
769
770
static void
771
StopIteration_dealloc(PyObject *self)
772
11.8M
{
773
11.8M
    PyObject_GC_UnTrack(self);
774
11.8M
    (void)StopIteration_clear(self);
775
11.8M
    Py_TYPE(self)->tp_free(self);
776
11.8M
}
777
778
static int
779
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
780
9
{
781
9
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
782
9
    Py_VISIT(self->value);
783
9
    return BaseException_traverse(op, visit, arg);
784
9
}
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
        return NULL;
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
32
create_exception_group_class(void) {
1765
32
    struct _Py_exc_state *state = get_exc_state();
1766
1767
32
    PyObject *bases = PyTuple_Pack(
1768
32
        2, PyExc_BaseExceptionGroup, PyExc_Exception);
1769
32
    if (bases == NULL) {
1770
0
        return NULL;
1771
0
    }
1772
1773
32
    assert(!state->PyExc_ExceptionGroup);
1774
32
    state->PyExc_ExceptionGroup = PyErr_NewException(
1775
32
        "builtins.ExceptionGroup", bases, NULL);
1776
1777
32
    Py_DECREF(bases);
1778
32
    return state->PyExc_ExceptionGroup;
1779
32
}
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
8.91k
{
1795
8.91k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
1796
8.91k
    return (PyImportErrorObject *)self;
1797
8.91k
}
1798
1799
static int
1800
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
1801
4.45k
{
1802
4.45k
    static char *kwlist[] = {"name", "path", "name_from", 0};
1803
4.45k
    PyObject *empty_tuple;
1804
4.45k
    PyObject *msg = NULL;
1805
4.45k
    PyObject *name = NULL;
1806
4.45k
    PyObject *path = NULL;
1807
4.45k
    PyObject *name_from = NULL;
1808
1809
4.45k
    if (BaseException_init(op, args, NULL) == -1)
1810
0
        return -1;
1811
1812
4.45k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1813
4.45k
    empty_tuple = PyTuple_New(0);
1814
4.45k
    if (!empty_tuple)
1815
0
        return -1;
1816
4.45k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
1817
4.45k
                                     &name, &path, &name_from)) {
1818
0
        Py_DECREF(empty_tuple);
1819
0
        return -1;
1820
0
    }
1821
4.45k
    Py_DECREF(empty_tuple);
1822
1823
4.45k
    Py_XSETREF(self->name, Py_XNewRef(name));
1824
4.45k
    Py_XSETREF(self->path, Py_XNewRef(path));
1825
4.45k
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));
1826
1827
4.45k
    if (PyTuple_GET_SIZE(args) == 1) {
1828
4.45k
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
1829
4.45k
    }
1830
4.45k
    Py_XSETREF(self->msg, msg);
1831
1832
4.45k
    return 0;
1833
4.45k
}
1834
1835
static int
1836
ImportError_clear(PyObject *op)
1837
4.45k
{
1838
4.45k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1839
4.45k
    Py_CLEAR(self->msg);
1840
4.45k
    Py_CLEAR(self->name);
1841
4.45k
    Py_CLEAR(self->path);
1842
4.45k
    Py_CLEAR(self->name_from);
1843
4.45k
    return BaseException_clear(op);
1844
4.45k
}
1845
1846
static void
1847
ImportError_dealloc(PyObject *self)
1848
4.45k
{
1849
4.45k
    _PyObject_GC_UNTRACK(self);
1850
4.45k
    (void)ImportError_clear(self);
1851
4.45k
    Py_TYPE(self)->tp_free(self);
1852
4.45k
}
1853
1854
static int
1855
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
1856
2
{
1857
2
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1858
2
    Py_VISIT(self->msg);
1859
2
    Py_VISIT(self->name);
1860
2
    Py_VISIT(self->path);
1861
2
    Py_VISIT(self->name_from);
1862
2
    return BaseException_traverse(op, visit, arg);
1863
2
}
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
 *    ModuleNotFoundError extends ImportError
2019
 */
2020
2021
MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
2022
                         "Module not found.");
2023
2024
/*
2025
 *    OSError extends Exception
2026
 */
2027
2028
static inline PyOSErrorObject *
2029
PyOSErrorObject_CAST(PyObject *self)
2030
444k
{
2031
444k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
2032
444k
    return (PyOSErrorObject *)self;
2033
444k
}
2034
2035
#ifdef MS_WINDOWS
2036
#include "errmap.h"
2037
#endif
2038
2039
/* Where a function has a single filename, such as open() or some
2040
 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
2041
 * called, giving a third argument which is the filename.  But, so
2042
 * that old code using in-place unpacking doesn't break, e.g.:
2043
 *
2044
 * except OSError, (errno, strerror):
2045
 *
2046
 * we hack args so that it only contains two items.  This also
2047
 * means we need our own __str__() which prints out the filename
2048
 * when it was supplied.
2049
 *
2050
 * (If a function has two filenames, such as rename(), symlink(),
2051
 * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
2052
 * which allows passing in a second filename.)
2053
 */
2054
2055
/* This function doesn't cleanup on error, the caller should */
2056
static int
2057
oserror_parse_args(PyObject **p_args,
2058
                   PyObject **myerrno, PyObject **strerror,
2059
                   PyObject **filename, PyObject **filename2
2060
#ifdef MS_WINDOWS
2061
                   , PyObject **winerror
2062
#endif
2063
                  )
2064
221k
{
2065
221k
    Py_ssize_t nargs;
2066
221k
    PyObject *args = *p_args;
2067
221k
#ifndef MS_WINDOWS
2068
    /*
2069
     * ignored on non-Windows platforms,
2070
     * but parsed so OSError has a consistent signature
2071
     */
2072
221k
    PyObject *_winerror = NULL;
2073
221k
    PyObject **winerror = &_winerror;
2074
221k
#endif /* MS_WINDOWS */
2075
2076
221k
    nargs = PyTuple_GET_SIZE(args);
2077
2078
221k
    if (nargs >= 2 && nargs <= 5) {
2079
217k
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
2080
217k
                               myerrno, strerror,
2081
217k
                               filename, winerror, filename2))
2082
0
            return -1;
2083
#ifdef MS_WINDOWS
2084
        if (*winerror && PyLong_Check(*winerror)) {
2085
            long errcode, winerrcode;
2086
            PyObject *newargs;
2087
            Py_ssize_t i;
2088
2089
            winerrcode = PyLong_AsLong(*winerror);
2090
            if (winerrcode == -1 && PyErr_Occurred())
2091
                return -1;
2092
            errcode = winerror_to_errno(winerrcode);
2093
            *myerrno = PyLong_FromLong(errcode);
2094
            if (!*myerrno)
2095
                return -1;
2096
            newargs = PyTuple_New(nargs);
2097
            if (!newargs)
2098
                return -1;
2099
            PyTuple_SET_ITEM(newargs, 0, *myerrno);
2100
            for (i = 1; i < nargs; i++) {
2101
                PyObject *val = PyTuple_GET_ITEM(args, i);
2102
                PyTuple_SET_ITEM(newargs, i, Py_NewRef(val));
2103
            }
2104
            Py_DECREF(args);
2105
            args = *p_args = newargs;
2106
        }
2107
#endif /* MS_WINDOWS */
2108
217k
    }
2109
2110
221k
    return 0;
2111
221k
}
2112
2113
static int
2114
oserror_init(PyOSErrorObject *self, PyObject **p_args,
2115
             PyObject *myerrno, PyObject *strerror,
2116
             PyObject *filename, PyObject *filename2
2117
#ifdef MS_WINDOWS
2118
             , PyObject *winerror
2119
#endif
2120
             )
2121
221k
{
2122
221k
    PyObject *args = *p_args;
2123
221k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
2124
2125
    /* self->filename will remain Py_None otherwise */
2126
221k
    if (filename && filename != Py_None) {
2127
217k
        if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
2128
0
            PyNumber_Check(filename)) {
2129
            /* BlockingIOError's 3rd argument can be the number of
2130
             * characters written.
2131
             */
2132
0
            self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
2133
0
            if (self->written == -1 && PyErr_Occurred())
2134
0
                return -1;
2135
0
        }
2136
217k
        else {
2137
217k
            self->filename = Py_NewRef(filename);
2138
2139
217k
            if (filename2 && filename2 != Py_None) {
2140
0
                self->filename2 = Py_NewRef(filename2);
2141
0
            }
2142
2143
217k
            if (nargs >= 2 && nargs <= 5) {
2144
                /* filename, filename2, and winerror are removed from the args tuple
2145
                   (for compatibility purposes, see test_exceptions.py) */
2146
217k
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
2147
217k
                if (!subslice)
2148
0
                    return -1;
2149
2150
217k
                Py_DECREF(args);  /* replacing args */
2151
217k
                *p_args = args = subslice;
2152
217k
            }
2153
217k
        }
2154
217k
    }
2155
221k
    self->myerrno = Py_XNewRef(myerrno);
2156
221k
    self->strerror = Py_XNewRef(strerror);
2157
#ifdef MS_WINDOWS
2158
    self->winerror = Py_XNewRef(winerror);
2159
#endif
2160
2161
    /* Steals the reference to args */
2162
221k
    Py_XSETREF(self->args, args);
2163
221k
    *p_args = args = NULL;
2164
2165
221k
    return 0;
2166
221k
}
2167
2168
static PyObject *
2169
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
2170
static int
2171
OSError_init(PyObject *self, PyObject *args, PyObject *kwds);
2172
2173
static int
2174
oserror_use_init(PyTypeObject *type)
2175
665k
{
2176
    /* When __init__ is defined in an OSError subclass, we want any
2177
       extraneous argument to __new__ to be ignored.  The only reasonable
2178
       solution, given __new__ takes a variable number of arguments,
2179
       is to defer arg parsing and initialization to __init__.
2180
2181
       But when __new__ is overridden as well, it should call our __new__
2182
       with the right arguments.
2183
2184
       (see http://bugs.python.org/issue12555#msg148829 )
2185
    */
2186
665k
    if (type->tp_init != OSError_init && type->tp_new == OSError_new) {
2187
177
        assert((PyObject *) type != PyExc_OSError);
2188
177
        return 1;
2189
177
    }
2190
665k
    return 0;
2191
665k
}
2192
2193
static PyObject *
2194
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2195
221k
{
2196
221k
    PyOSErrorObject *self = NULL;
2197
221k
    PyObject *myerrno = NULL, *strerror = NULL;
2198
221k
    PyObject *filename = NULL, *filename2 = NULL;
2199
#ifdef MS_WINDOWS
2200
    PyObject *winerror = NULL;
2201
#endif
2202
2203
221k
    Py_INCREF(args);
2204
2205
221k
    if (!oserror_use_init(type)) {
2206
221k
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
2207
0
            goto error;
2208
2209
221k
        if (oserror_parse_args(&args, &myerrno, &strerror,
2210
221k
                               &filename, &filename2
2211
#ifdef MS_WINDOWS
2212
                               , &winerror
2213
#endif
2214
221k
            ))
2215
0
            goto error;
2216
2217
221k
        struct _Py_exc_state *state = get_exc_state();
2218
221k
        if (myerrno && PyLong_Check(myerrno) &&
2219
217k
            state->errnomap && (PyObject *) type == PyExc_OSError) {
2220
217k
            PyObject *newtype;
2221
217k
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
2222
217k
            if (newtype) {
2223
185k
                type = _PyType_CAST(newtype);
2224
185k
            }
2225
31.9k
            else if (PyErr_Occurred())
2226
0
                goto error;
2227
217k
        }
2228
221k
    }
2229
2230
221k
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
2231
221k
    if (!self)
2232
0
        goto error;
2233
2234
221k
    self->dict = NULL;
2235
221k
    self->traceback = self->cause = self->context = NULL;
2236
221k
    self->written = -1;
2237
2238
221k
    if (!oserror_use_init(type)) {
2239
221k
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2240
#ifdef MS_WINDOWS
2241
                         , winerror
2242
#endif
2243
221k
            ))
2244
0
            goto error;
2245
221k
    }
2246
59
    else {
2247
59
        self->args = PyTuple_New(0);
2248
59
        if (self->args == NULL)
2249
0
            goto error;
2250
59
    }
2251
2252
221k
    Py_XDECREF(args);
2253
221k
    return (PyObject *) self;
2254
2255
0
error:
2256
0
    Py_XDECREF(args);
2257
0
    Py_XDECREF(self);
2258
0
    return NULL;
2259
221k
}
2260
2261
static int
2262
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
2263
221k
{
2264
221k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2265
221k
    PyObject *myerrno = NULL, *strerror = NULL;
2266
221k
    PyObject *filename = NULL, *filename2 = NULL;
2267
#ifdef MS_WINDOWS
2268
    PyObject *winerror = NULL;
2269
#endif
2270
2271
221k
    if (!oserror_use_init(Py_TYPE(self)))
2272
        /* Everything already done in OSError_new */
2273
221k
        return 0;
2274
2275
59
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
2276
0
        return -1;
2277
2278
59
    Py_INCREF(args);
2279
59
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
2280
#ifdef MS_WINDOWS
2281
                           , &winerror
2282
#endif
2283
59
        ))
2284
0
        goto error;
2285
2286
59
    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2287
#ifdef MS_WINDOWS
2288
                     , winerror
2289
#endif
2290
59
        ))
2291
0
        goto error;
2292
2293
59
    return 0;
2294
2295
0
error:
2296
0
    Py_DECREF(args);
2297
0
    return -1;
2298
59
}
2299
2300
static int
2301
OSError_clear(PyObject *op)
2302
221k
{
2303
221k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2304
221k
    Py_CLEAR(self->myerrno);
2305
221k
    Py_CLEAR(self->strerror);
2306
221k
    Py_CLEAR(self->filename);
2307
221k
    Py_CLEAR(self->filename2);
2308
#ifdef MS_WINDOWS
2309
    Py_CLEAR(self->winerror);
2310
#endif
2311
221k
    return BaseException_clear(op);
2312
221k
}
2313
2314
static void
2315
OSError_dealloc(PyObject *self)
2316
221k
{
2317
221k
    _PyObject_GC_UNTRACK(self);
2318
221k
    (void)OSError_clear(self);
2319
221k
    Py_TYPE(self)->tp_free(self);
2320
221k
}
2321
2322
static int
2323
OSError_traverse(PyObject *op, visitproc visit, void *arg)
2324
3
{
2325
3
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2326
3
    Py_VISIT(self->myerrno);
2327
3
    Py_VISIT(self->strerror);
2328
3
    Py_VISIT(self->filename);
2329
3
    Py_VISIT(self->filename2);
2330
#ifdef MS_WINDOWS
2331
    Py_VISIT(self->winerror);
2332
#endif
2333
3
    return BaseException_traverse(op, visit, arg);
2334
3
}
2335
2336
static PyObject *
2337
OSError_str(PyObject *op)
2338
713
{
2339
713
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2340
1.41k
#define OR_NONE(x) ((x)?(x):Py_None)
2341
#ifdef MS_WINDOWS
2342
    /* If available, winerror has the priority over myerrno */
2343
    if (self->winerror && self->filename) {
2344
        if (self->filename2) {
2345
            return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
2346
                                        OR_NONE(self->winerror),
2347
                                        OR_NONE(self->strerror),
2348
                                        self->filename,
2349
                                        self->filename2);
2350
        } else {
2351
            return PyUnicode_FromFormat("[WinError %S] %S: %R",
2352
                                        OR_NONE(self->winerror),
2353
                                        OR_NONE(self->strerror),
2354
                                        self->filename);
2355
        }
2356
    }
2357
    if (self->winerror && self->strerror)
2358
        return PyUnicode_FromFormat("[WinError %S] %S",
2359
                                    self->winerror ? self->winerror: Py_None,
2360
                                    self->strerror ? self->strerror: Py_None);
2361
#endif
2362
713
    if (self->filename) {
2363
708
        if (self->filename2) {
2364
0
            return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
2365
0
                                        OR_NONE(self->myerrno),
2366
0
                                        OR_NONE(self->strerror),
2367
0
                                        self->filename,
2368
0
                                        self->filename2);
2369
708
        } else {
2370
708
            return PyUnicode_FromFormat("[Errno %S] %S: %R",
2371
708
                                        OR_NONE(self->myerrno),
2372
708
                                        OR_NONE(self->strerror),
2373
708
                                        self->filename);
2374
708
        }
2375
708
    }
2376
5
    if (self->myerrno && self->strerror)
2377
0
        return PyUnicode_FromFormat("[Errno %S] %S",
2378
0
                                    self->myerrno, self->strerror);
2379
5
    return BaseException_str(op);
2380
5
}
2381
2382
static PyObject *
2383
OSError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
2384
0
{
2385
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2386
0
    PyObject *args = self->args;
2387
0
    PyObject *res = NULL;
2388
2389
    /* self->args is only the first two real arguments if there was a
2390
     * file name given to OSError. */
2391
0
    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
2392
0
        Py_ssize_t size = self->filename2 ? 5 : 3;
2393
0
        args = PyTuple_New(size);
2394
0
        if (!args)
2395
0
            return NULL;
2396
2397
0
        PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0)));
2398
0
        PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1)));
2399
0
        PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename));
2400
2401
0
        if (self->filename2) {
2402
            /*
2403
             * This tuple is essentially used as OSError(*args).
2404
             * So, to recreate filename2, we need to pass in
2405
             * winerror as well.
2406
             */
2407
0
            PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None));
2408
2409
            /* filename2 */
2410
0
            PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2));
2411
0
        }
2412
0
    } else
2413
0
        Py_INCREF(args);
2414
2415
0
    if (self->dict)
2416
0
        res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
2417
0
    else
2418
0
        res = PyTuple_Pack(2, Py_TYPE(self), args);
2419
0
    Py_DECREF(args);
2420
0
    return res;
2421
0
}
2422
2423
static PyObject *
2424
OSError_written_get(PyObject *op, void *context)
2425
0
{
2426
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2427
0
    if (self->written == -1) {
2428
0
        PyErr_SetString(PyExc_AttributeError, "characters_written");
2429
0
        return NULL;
2430
0
    }
2431
0
    return PyLong_FromSsize_t(self->written);
2432
0
}
2433
2434
static int
2435
OSError_written_set(PyObject *op, PyObject *arg, void *context)
2436
0
{
2437
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2438
0
    if (arg == NULL) {
2439
0
        if (self->written == -1) {
2440
0
            PyErr_SetString(PyExc_AttributeError, "characters_written");
2441
0
            return -1;
2442
0
        }
2443
0
        self->written = -1;
2444
0
        return 0;
2445
0
    }
2446
0
    Py_ssize_t n;
2447
0
    n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
2448
0
    if (n == -1 && PyErr_Occurred())
2449
0
        return -1;
2450
0
    self->written = n;
2451
0
    return 0;
2452
0
}
2453
2454
static PyMemberDef OSError_members[] = {
2455
    {"errno", _Py_T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
2456
        PyDoc_STR("POSIX exception code")},
2457
    {"strerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
2458
        PyDoc_STR("exception strerror")},
2459
    {"filename", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
2460
        PyDoc_STR("exception filename")},
2461
    {"filename2", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
2462
        PyDoc_STR("second exception filename")},
2463
#ifdef MS_WINDOWS
2464
    {"winerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
2465
        PyDoc_STR("Win32 exception code")},
2466
#endif
2467
    {NULL}  /* Sentinel */
2468
};
2469
2470
static PyMethodDef OSError_methods[] = {
2471
    {"__reduce__", OSError_reduce, METH_NOARGS},
2472
    {NULL}
2473
};
2474
2475
static PyGetSetDef OSError_getset[] = {
2476
    {"characters_written", OSError_written_get,
2477
                           OSError_written_set, NULL},
2478
    {NULL}
2479
};
2480
2481
2482
ComplexExtendsException(PyExc_Exception, OSError,
2483
                        OSError, OSError_new,
2484
                        OSError_methods, OSError_members, OSError_getset,
2485
                        OSError_str, 0,
2486
                        "Base class for I/O related errors.");
2487
2488
2489
/*
2490
 *    Various OSError subclasses
2491
 */
2492
MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
2493
                         "I/O operation would block.");
2494
MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
2495
                         "Connection error.");
2496
MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
2497
                         "Child process error.");
2498
MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
2499
                         "Broken pipe.");
2500
MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
2501
                         "Connection aborted.");
2502
MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
2503
                         "Connection refused.");
2504
MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
2505
                         "Connection reset.");
2506
MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
2507
                         "File already exists.");
2508
MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
2509
                         "File not found.");
2510
MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
2511
                         "Operation doesn't work on directories.");
2512
MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
2513
                         "Operation only works on directories.");
2514
MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
2515
                         "Interrupted by signal.");
2516
MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
2517
                         "Not enough permissions.");
2518
MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
2519
                         "Process not found.");
2520
MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
2521
                         "Timeout expired.");
2522
2523
/* Compatibility aliases */
2524
PyObject *PyExc_EnvironmentError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2525
PyObject *PyExc_IOError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2526
#ifdef MS_WINDOWS
2527
PyObject *PyExc_WindowsError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2528
#endif
2529
2530
/*
2531
 *    EOFError extends Exception
2532
 */
2533
SimpleExtendsException(PyExc_Exception, EOFError,
2534
                       "Read beyond end of file.");
2535
2536
2537
/*
2538
 *    RuntimeError extends Exception
2539
 */
2540
SimpleExtendsException(PyExc_Exception, RuntimeError,
2541
                       "Unspecified run-time error.");
2542
2543
/*
2544
 *    RecursionError extends RuntimeError
2545
 */
2546
SimpleExtendsException(PyExc_RuntimeError, RecursionError,
2547
                       "Recursion limit exceeded.");
2548
2549
// PythonFinalizationError extends RuntimeError
2550
SimpleExtendsException(PyExc_RuntimeError, PythonFinalizationError,
2551
                       "Operation blocked during Python finalization.");
2552
2553
/*
2554
 *    NotImplementedError extends RuntimeError
2555
 */
2556
SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
2557
                       "Method or function hasn't been implemented yet.");
2558
2559
/*
2560
 *    NameError extends Exception
2561
 */
2562
2563
static inline PyNameErrorObject *
2564
PyNameErrorObject_CAST(PyObject *self)
2565
78
{
2566
78
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_NameError));
2567
78
    return (PyNameErrorObject *)self;
2568
78
}
2569
2570
static int
2571
NameError_init(PyObject *op, PyObject *args, PyObject *kwds)
2572
39
{
2573
39
    static char *kwlist[] = {"name", NULL};
2574
39
    PyObject *name = NULL;
2575
2576
39
    if (BaseException_init(op, args, NULL) == -1) {
2577
0
        return -1;
2578
0
    }
2579
2580
39
    PyObject *empty_tuple = PyTuple_New(0);
2581
39
    if (!empty_tuple) {
2582
0
        return -1;
2583
0
    }
2584
39
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
2585
39
                                     &name)) {
2586
0
        Py_DECREF(empty_tuple);
2587
0
        return -1;
2588
0
    }
2589
39
    Py_DECREF(empty_tuple);
2590
2591
39
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2592
39
    Py_XSETREF(self->name, Py_XNewRef(name));
2593
2594
39
    return 0;
2595
39
}
2596
2597
static int
2598
NameError_clear(PyObject *op)
2599
39
{
2600
39
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2601
39
    Py_CLEAR(self->name);
2602
39
    return BaseException_clear(op);
2603
39
}
2604
2605
static void
2606
NameError_dealloc(PyObject *self)
2607
39
{
2608
39
    _PyObject_GC_UNTRACK(self);
2609
39
    (void)NameError_clear(self);
2610
39
    Py_TYPE(self)->tp_free(self);
2611
39
}
2612
2613
static int
2614
NameError_traverse(PyObject *op, visitproc visit, void *arg)
2615
0
{
2616
0
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2617
0
    Py_VISIT(self->name);
2618
0
    return BaseException_traverse(op, visit, arg);
2619
0
}
2620
2621
static PyMemberDef NameError_members[] = {
2622
        {"name", _Py_T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
2623
        {NULL}  /* Sentinel */
2624
};
2625
2626
static PyMethodDef NameError_methods[] = {
2627
        {NULL}  /* Sentinel */
2628
};
2629
2630
ComplexExtendsException(PyExc_Exception, NameError,
2631
                        NameError, 0,
2632
                        NameError_methods, NameError_members,
2633
                        0, BaseException_str, 0, "Name not found globally.");
2634
2635
/*
2636
 *    UnboundLocalError extends NameError
2637
 */
2638
2639
MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
2640
                       "Local name referenced but not bound to a value.");
2641
2642
/*
2643
 *    AttributeError extends Exception
2644
 */
2645
2646
static inline PyAttributeErrorObject *
2647
PyAttributeErrorObject_CAST(PyObject *self)
2648
1.56M
{
2649
1.56M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
2650
1.56M
    return (PyAttributeErrorObject *)self;
2651
1.56M
}
2652
2653
static int
2654
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
2655
782k
{
2656
782k
    static char *kwlist[] = {"name", "obj", NULL};
2657
782k
    PyObject *name = NULL;
2658
782k
    PyObject *obj = NULL;
2659
2660
782k
    if (BaseException_init(op, args, NULL) == -1) {
2661
0
        return -1;
2662
0
    }
2663
2664
782k
    PyObject *empty_tuple = PyTuple_New(0);
2665
782k
    if (!empty_tuple) {
2666
0
        return -1;
2667
0
    }
2668
782k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2669
782k
                                     &name, &obj)) {
2670
0
        Py_DECREF(empty_tuple);
2671
0
        return -1;
2672
0
    }
2673
782k
    Py_DECREF(empty_tuple);
2674
2675
782k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2676
782k
    Py_XSETREF(self->name, Py_XNewRef(name));
2677
782k
    Py_XSETREF(self->obj, Py_XNewRef(obj));
2678
2679
782k
    return 0;
2680
782k
}
2681
2682
static int
2683
AttributeError_clear(PyObject *op)
2684
782k
{
2685
782k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2686
782k
    Py_CLEAR(self->obj);
2687
782k
    Py_CLEAR(self->name);
2688
782k
    return BaseException_clear(op);
2689
782k
}
2690
2691
static void
2692
AttributeError_dealloc(PyObject *self)
2693
782k
{
2694
782k
    _PyObject_GC_UNTRACK(self);
2695
782k
    (void)AttributeError_clear(self);
2696
782k
    Py_TYPE(self)->tp_free(self);
2697
782k
}
2698
2699
static int
2700
AttributeError_traverse(PyObject *op, visitproc visit, void *arg)
2701
278
{
2702
278
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2703
278
    Py_VISIT(self->obj);
2704
278
    Py_VISIT(self->name);
2705
278
    return BaseException_traverse(op, visit, arg);
2706
278
}
2707
2708
/* Pickling support */
2709
static PyObject *
2710
AttributeError_getstate(PyObject *op, PyObject *Py_UNUSED(ignored))
2711
0
{
2712
0
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2713
0
    PyObject *dict = self->dict;
2714
0
    if (self->name || self->args) {
2715
0
        dict = dict ? PyDict_Copy(dict) : PyDict_New();
2716
0
        if (dict == NULL) {
2717
0
            return NULL;
2718
0
        }
2719
0
        if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) {
2720
0
            Py_DECREF(dict);
2721
0
            return NULL;
2722
0
        }
2723
        /* We specifically are not pickling the obj attribute since there are many
2724
        cases where it is unlikely to be picklable. See GH-103352.
2725
        */
2726
0
        if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) {
2727
0
            Py_DECREF(dict);
2728
0
            return NULL;
2729
0
        }
2730
0
        return dict;
2731
0
    }
2732
0
    else if (dict) {
2733
0
        return Py_NewRef(dict);
2734
0
    }
2735
0
    Py_RETURN_NONE;
2736
0
}
2737
2738
static PyObject *
2739
AttributeError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
2740
0
{
2741
0
    PyObject *state = AttributeError_getstate(op, NULL);
2742
0
    if (state == NULL) {
2743
0
        return NULL;
2744
0
    }
2745
2746
0
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2747
0
    PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state);
2748
0
    Py_DECREF(state);
2749
0
    return return_value;
2750
0
}
2751
2752
static PyMemberDef AttributeError_members[] = {
2753
    {"name", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
2754
    {"obj", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
2755
    {NULL}  /* Sentinel */
2756
};
2757
2758
static PyMethodDef AttributeError_methods[] = {
2759
    {"__getstate__", AttributeError_getstate, METH_NOARGS},
2760
    {"__reduce__", AttributeError_reduce, METH_NOARGS },
2761
    {NULL}
2762
};
2763
2764
ComplexExtendsException(PyExc_Exception, AttributeError,
2765
                        AttributeError, 0,
2766
                        AttributeError_methods, AttributeError_members,
2767
                        0, BaseException_str, 0, "Attribute not found.");
2768
2769
/*
2770
 *    SyntaxError extends Exception
2771
 */
2772
2773
static inline PySyntaxErrorObject *
2774
PySyntaxErrorObject_CAST(PyObject *self)
2775
58.0k
{
2776
58.0k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
2777
58.0k
    return (PySyntaxErrorObject *)self;
2778
58.0k
}
2779
2780
static int
2781
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
2782
29.0k
{
2783
29.0k
    PyObject *info = NULL;
2784
29.0k
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2785
2786
29.0k
    if (BaseException_init(op, args, kwds) == -1)
2787
0
        return -1;
2788
2789
29.0k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2790
29.0k
    if (lenargs >= 1) {
2791
29.0k
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
2792
29.0k
    }
2793
29.0k
    if (lenargs == 2) {
2794
12.6k
        info = PyTuple_GET_ITEM(args, 1);
2795
12.6k
        info = PySequence_Tuple(info);
2796
12.6k
        if (!info) {
2797
0
            return -1;
2798
0
        }
2799
2800
12.6k
        self->end_lineno = NULL;
2801
12.6k
        self->end_offset = NULL;
2802
12.6k
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
2803
12.6k
                              &self->filename, &self->lineno,
2804
12.6k
                              &self->offset, &self->text,
2805
12.6k
                              &self->end_lineno, &self->end_offset, &self->metadata)) {
2806
0
            Py_DECREF(info);
2807
0
            return -1;
2808
0
        }
2809
2810
12.6k
        Py_INCREF(self->filename);
2811
12.6k
        Py_INCREF(self->lineno);
2812
12.6k
        Py_INCREF(self->offset);
2813
12.6k
        Py_INCREF(self->text);
2814
12.6k
        Py_XINCREF(self->end_lineno);
2815
12.6k
        Py_XINCREF(self->end_offset);
2816
12.6k
        Py_XINCREF(self->metadata);
2817
12.6k
        Py_DECREF(info);
2818
2819
12.6k
        if (self->end_lineno != NULL && self->end_offset == NULL) {
2820
0
            PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
2821
0
            return -1;
2822
0
        }
2823
12.6k
    }
2824
29.0k
    return 0;
2825
29.0k
}
2826
2827
static int
2828
SyntaxError_clear(PyObject *op)
2829
29.0k
{
2830
29.0k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2831
29.0k
    Py_CLEAR(self->msg);
2832
29.0k
    Py_CLEAR(self->filename);
2833
29.0k
    Py_CLEAR(self->lineno);
2834
29.0k
    Py_CLEAR(self->offset);
2835
29.0k
    Py_CLEAR(self->end_lineno);
2836
29.0k
    Py_CLEAR(self->end_offset);
2837
29.0k
    Py_CLEAR(self->text);
2838
29.0k
    Py_CLEAR(self->print_file_and_line);
2839
29.0k
    Py_CLEAR(self->metadata);
2840
29.0k
    return BaseException_clear(op);
2841
29.0k
}
2842
2843
static void
2844
SyntaxError_dealloc(PyObject *self)
2845
29.0k
{
2846
29.0k
    _PyObject_GC_UNTRACK(self);
2847
29.0k
    (void)SyntaxError_clear(self);
2848
29.0k
    Py_TYPE(self)->tp_free(self);
2849
29.0k
}
2850
2851
static int
2852
SyntaxError_traverse(PyObject *op, visitproc visit, void *arg)
2853
0
{
2854
0
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2855
0
    Py_VISIT(self->msg);
2856
0
    Py_VISIT(self->filename);
2857
0
    Py_VISIT(self->lineno);
2858
0
    Py_VISIT(self->offset);
2859
0
    Py_VISIT(self->end_lineno);
2860
0
    Py_VISIT(self->end_offset);
2861
0
    Py_VISIT(self->text);
2862
0
    Py_VISIT(self->print_file_and_line);
2863
0
    Py_VISIT(self->metadata);
2864
0
    return BaseException_traverse(op, visit, arg);
2865
0
}
2866
2867
/* This is called "my_basename" instead of just "basename" to avoid name
2868
   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
2869
   defined, and Python does define that. */
2870
static PyObject*
2871
my_basename(PyObject *name)
2872
0
{
2873
0
    Py_ssize_t i, size, offset;
2874
0
    int kind;
2875
0
    const void *data;
2876
2877
0
    kind = PyUnicode_KIND(name);
2878
0
    data = PyUnicode_DATA(name);
2879
0
    size = PyUnicode_GET_LENGTH(name);
2880
0
    offset = 0;
2881
0
    for(i=0; i < size; i++) {
2882
0
        if (PyUnicode_READ(kind, data, i) == SEP) {
2883
0
            offset = i + 1;
2884
0
        }
2885
0
    }
2886
0
    if (offset != 0) {
2887
0
        return PyUnicode_Substring(name, offset, size);
2888
0
    }
2889
0
    else {
2890
0
        return Py_NewRef(name);
2891
0
    }
2892
0
}
2893
2894
2895
static PyObject *
2896
SyntaxError_str(PyObject *op)
2897
0
{
2898
0
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2899
0
    int have_lineno = 0;
2900
0
    PyObject *filename;
2901
0
    PyObject *result;
2902
    /* Below, we always ignore overflow errors, just printing -1.
2903
       Still, we cannot allow an OverflowError to be raised, so
2904
       we need to call PyLong_AsLongAndOverflow. */
2905
0
    int overflow;
2906
2907
    /* XXX -- do all the additional formatting with filename and
2908
       lineno here */
2909
2910
0
    if (self->filename && PyUnicode_Check(self->filename)) {
2911
0
        filename = my_basename(self->filename);
2912
0
        if (filename == NULL)
2913
0
            return NULL;
2914
0
    } else {
2915
0
        filename = NULL;
2916
0
    }
2917
0
    have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
2918
2919
0
    if (!filename && !have_lineno)
2920
0
        return PyObject_Str(self->msg ? self->msg : Py_None);
2921
2922
    // Even if 'filename' can be an instance of a subclass of 'str',
2923
    // we only render its "true" content and do not use str(filename).
2924
0
    if (filename && have_lineno)
2925
0
        result = PyUnicode_FromFormat("%S (%U, line %ld)",
2926
0
                   self->msg ? self->msg : Py_None,
2927
0
                   filename,
2928
0
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2929
0
    else if (filename)
2930
0
        result = PyUnicode_FromFormat("%S (%U)",
2931
0
                   self->msg ? self->msg : Py_None,
2932
0
                   filename);
2933
0
    else /* only have_lineno */
2934
0
        result = PyUnicode_FromFormat("%S (line %ld)",
2935
0
                   self->msg ? self->msg : Py_None,
2936
0
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2937
0
    Py_XDECREF(filename);
2938
0
    return result;
2939
0
}
2940
2941
static PyMemberDef SyntaxError_members[] = {
2942
    {"msg", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
2943
        PyDoc_STR("exception msg")},
2944
    {"filename", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
2945
        PyDoc_STR("exception filename")},
2946
    {"lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
2947
        PyDoc_STR("exception lineno")},
2948
    {"offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
2949
        PyDoc_STR("exception offset")},
2950
    {"text", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
2951
        PyDoc_STR("exception text")},
2952
    {"end_lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
2953
                   PyDoc_STR("exception end lineno")},
2954
    {"end_offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
2955
                   PyDoc_STR("exception end offset")},
2956
    {"print_file_and_line", _Py_T_OBJECT,
2957
        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
2958
        PyDoc_STR("exception print_file_and_line")},
2959
    {"_metadata", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, metadata), 0,
2960
                   PyDoc_STR("exception private metadata")},
2961
    {NULL}  /* Sentinel */
2962
};
2963
2964
ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
2965
                        0, 0, SyntaxError_members, 0,
2966
                        SyntaxError_str, 0, "Invalid syntax.");
2967
2968
2969
/*
2970
 *    IndentationError extends SyntaxError
2971
 */
2972
MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
2973
                         "Improper indentation.");
2974
2975
2976
/*
2977
 *    TabError extends IndentationError
2978
 */
2979
MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
2980
                         "Improper mixture of spaces and tabs.");
2981
2982
/*
2983
 *    IncompleteInputError extends SyntaxError
2984
 */
2985
MiddlingExtendsExceptionEx(PyExc_SyntaxError, IncompleteInputError, _IncompleteInputError,
2986
                           SyntaxError, "incomplete input.");
2987
2988
/*
2989
 *    LookupError extends Exception
2990
 */
2991
SimpleExtendsException(PyExc_Exception, LookupError,
2992
                       "Base class for lookup errors.");
2993
2994
2995
/*
2996
 *    IndexError extends LookupError
2997
 */
2998
SimpleExtendsException(PyExc_LookupError, IndexError,
2999
                       "Sequence index out of range.");
3000
3001
3002
/*
3003
 *    KeyError extends LookupError
3004
 */
3005
3006
static PyObject *
3007
KeyError_str(PyObject *op)
3008
0
{
3009
    /* If args is a tuple of exactly one item, apply repr to args[0].
3010
       This is done so that e.g. the exception raised by {}[''] prints
3011
         KeyError: ''
3012
       rather than the confusing
3013
         KeyError
3014
       alone.  The downside is that if KeyError is raised with an explanatory
3015
       string, that string will be displayed in quotes.  Too bad.
3016
       If args is anything else, use the default BaseException__str__().
3017
    */
3018
0
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
3019
0
    if (PyTuple_GET_SIZE(self->args) == 1) {
3020
0
        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
3021
0
    }
3022
0
    return BaseException_str(op);
3023
0
}
3024
3025
ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
3026
                        0, 0, 0, 0, KeyError_str, 0, "Mapping key not found.");
3027
3028
3029
/*
3030
 *    ValueError extends Exception
3031
 */
3032
SimpleExtendsException(PyExc_Exception, ValueError,
3033
                       "Inappropriate argument value (of correct type).");
3034
3035
/*
3036
 *    UnicodeError extends ValueError
3037
 */
3038
3039
SimpleExtendsException(PyExc_ValueError, UnicodeError,
3040
                       "Unicode related error.");
3041
3042
3043
/*
3044
 * Check the validity of 'attr' as a unicode or bytes object depending
3045
 * on 'as_bytes'.
3046
 *
3047
 * The 'name' is the attribute name and is only used for error reporting.
3048
 *
3049
 * On success, this returns 0.
3050
 * On failure, this sets a TypeError and returns -1.
3051
 */
3052
static int
3053
check_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
3054
655k
{
3055
655k
    assert(as_bytes == 0 || as_bytes == 1);
3056
655k
    if (attr == NULL) {
3057
0
        PyErr_Format(PyExc_TypeError,
3058
0
                     "UnicodeError '%s' attribute is not set",
3059
0
                     name);
3060
0
        return -1;
3061
0
    }
3062
655k
    if (!(as_bytes ? PyBytes_Check(attr) : PyUnicode_Check(attr))) {
3063
0
        PyErr_Format(PyExc_TypeError,
3064
0
                     "UnicodeError '%s' attribute must be a %s",
3065
0
                     name, as_bytes ? "bytes" : "string");
3066
0
        return -1;
3067
0
    }
3068
655k
    return 0;
3069
655k
}
3070
3071
3072
/*
3073
 * Check the validity of 'attr' as a unicode or bytes object depending
3074
 * on 'as_bytes' and return a new reference on it if it is the case.
3075
 *
3076
 * The 'name' is the attribute name and is only used for error reporting.
3077
 *
3078
 * On success, this returns a strong reference on 'attr'.
3079
 * On failure, this sets a TypeError and returns NULL.
3080
 */
3081
static PyObject *
3082
as_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
3083
654k
{
3084
654k
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
3085
654k
    return rc < 0 ? NULL : Py_NewRef(attr);
3086
654k
}
3087
3088
3089
#define PyUnicodeError_Check(PTR)   \
3090
1.42M
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3091
#define PyUnicodeError_CAST(PTR)    \
3092
1.47M
    (assert(PyUnicodeError_Check(PTR)), ((PyUnicodeErrorObject *)(PTR)))
3093
3094
3095
/* class names to use when reporting errors */
3096
0
#define Py_UNICODE_ENCODE_ERROR_NAME        "UnicodeEncodeError"
3097
1.42M
#define Py_UNICODE_DECODE_ERROR_NAME        "UnicodeDecodeError"
3098
0
#define Py_UNICODE_TRANSLATE_ERROR_NAME     "UnicodeTranslateError"
3099
3100
3101
/*
3102
 * Check that 'self' is a UnicodeError object.
3103
 *
3104
 * On success, this returns 0.
3105
 * On failure, this sets a TypeError exception and returns -1.
3106
 *
3107
 * The 'expect_type' is the name of the expected type, which is
3108
 * only used for error reporting.
3109
 *
3110
 * As an implementation detail, the `PyUnicode*Error_*` functions
3111
 * currently allow *any* subclass of UnicodeError as 'self'.
3112
 *
3113
 * Use one of the `Py_UNICODE_*_ERROR_NAME` macros to avoid typos.
3114
 */
3115
static inline int
3116
check_unicode_error_type(PyObject *self, const char *expect_type)
3117
1.42M
{
3118
1.42M
    assert(self != NULL);
3119
1.42M
    if (!PyUnicodeError_Check(self)) {
3120
0
        PyErr_Format(PyExc_TypeError,
3121
0
                     "expecting a %s object, got %T", expect_type, self);
3122
0
        return -1;
3123
0
    }
3124
1.42M
    return 0;
3125
1.42M
}
3126
3127
3128
// --- PyUnicodeEncodeObject: internal helpers --------------------------------
3129
//
3130
// In the helpers below, the caller is responsible to ensure that 'self'
3131
// is a PyUnicodeErrorObject, although this is verified on DEBUG builds
3132
// through PyUnicodeError_CAST().
3133
3134
/*
3135
 * Return the underlying (str) 'encoding' attribute of a UnicodeError object.
3136
 */
3137
static inline PyObject *
3138
unicode_error_get_encoding_impl(PyObject *self)
3139
0
{
3140
0
    assert(self != NULL);
3141
0
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3142
0
    return as_unicode_error_attribute(exc->encoding, "encoding", false);
3143
0
}
3144
3145
3146
/*
3147
 * Return the underlying 'object' attribute of a UnicodeError object
3148
 * as a bytes or a string instance, depending on the 'as_bytes' flag.
3149
 */
3150
static inline PyObject *
3151
unicode_error_get_object_impl(PyObject *self, int as_bytes)
3152
315k
{
3153
315k
    assert(self != NULL);
3154
315k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3155
315k
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
3156
315k
}
3157
3158
3159
/*
3160
 * Return the underlying (str) 'reason' attribute of a UnicodeError object.
3161
 */
3162
static inline PyObject *
3163
unicode_error_get_reason_impl(PyObject *self)
3164
0
{
3165
0
    assert(self != NULL);
3166
0
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3167
0
    return as_unicode_error_attribute(exc->reason, "reason", false);
3168
0
}
3169
3170
3171
/*
3172
 * Set the underlying (str) 'reason' attribute of a UnicodeError object.
3173
 *
3174
 * Return 0 on success and -1 on failure.
3175
 */
3176
static inline int
3177
unicode_error_set_reason_impl(PyObject *self, const char *reason)
3178
273k
{
3179
273k
    assert(self != NULL);
3180
273k
    PyObject *value = PyUnicode_FromString(reason);
3181
273k
    if (value == NULL) {
3182
0
        return -1;
3183
0
    }
3184
273k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3185
273k
    Py_XSETREF(exc->reason, value);
3186
273k
    return 0;
3187
273k
}
3188
3189
3190
/*
3191
 * Set the 'start' attribute of a UnicodeError object.
3192
 *
3193
 * Return 0 on success and -1 on failure.
3194
 */
3195
static inline int
3196
unicode_error_set_start_impl(PyObject *self, Py_ssize_t start)
3197
273k
{
3198
273k
    assert(self != NULL);
3199
273k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3200
273k
    exc->start = start;
3201
273k
    return 0;
3202
273k
}
3203
3204
3205
/*
3206
 * Set the 'end' attribute of a UnicodeError object.
3207
 *
3208
 * Return 0 on success and -1 on failure.
3209
 */
3210
static inline int
3211
unicode_error_set_end_impl(PyObject *self, Py_ssize_t end)
3212
273k
{
3213
273k
    assert(self != NULL);
3214
273k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3215
273k
    exc->end = end;
3216
273k
    return 0;
3217
273k
}
3218
3219
// --- PyUnicodeEncodeObject: internal getters --------------------------------
3220
3221
/*
3222
 * Adjust the (inclusive) 'start' value of a UnicodeError object.
3223
 *
3224
 * The 'start' can be negative or not, but when adjusting the value,
3225
 * we clip it in [0, max(0, objlen - 1)] and do not interpret it as
3226
 * a relative offset.
3227
 *
3228
 * This function always succeeds.
3229
 */
3230
static Py_ssize_t
3231
unicode_error_adjust_start(Py_ssize_t start, Py_ssize_t objlen)
3232
52.8k
{
3233
52.8k
    assert(objlen >= 0);
3234
52.8k
    if (start < 0) {
3235
0
        start = 0;
3236
0
    }
3237
52.8k
    if (start >= objlen) {
3238
0
        start = objlen == 0 ? 0 : objlen - 1;
3239
0
    }
3240
52.8k
    return start;
3241
52.8k
}
3242
3243
3244
/* Assert some properties of the adjusted 'start' value. */
3245
#ifndef NDEBUG
3246
static void
3247
assert_adjusted_unicode_error_start(Py_ssize_t start, Py_ssize_t objlen)
3248
{
3249
    assert(objlen >= 0);
3250
    /* in the future, `min_start` may be something else */
3251
    Py_ssize_t min_start = 0;
3252
    assert(start >= min_start);
3253
    /* in the future, `max_start` may be something else */
3254
    Py_ssize_t max_start = Py_MAX(min_start, objlen - 1);
3255
    assert(start <= max_start);
3256
}
3257
#else
3258
#define assert_adjusted_unicode_error_start(...)
3259
#endif
3260
3261
3262
/*
3263
 * Adjust the (exclusive) 'end' value of a UnicodeError object.
3264
 *
3265
 * The 'end' can be negative or not, but when adjusting the value,
3266
 * we clip it in [min(1, objlen), max(min(1, objlen), objlen)] and
3267
 * do not interpret it as a relative offset.
3268
 *
3269
 * This function always succeeds.
3270
 */
3271
static Py_ssize_t
3272
unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
3273
338k
{
3274
338k
    assert(objlen >= 0);
3275
338k
    if (end < 1) {
3276
0
        end = 1;
3277
0
    }
3278
338k
    if (end > objlen) {
3279
0
        end = objlen;
3280
0
    }
3281
338k
    return end;
3282
338k
}
3283
3284
#define PyUnicodeError_Check(PTR)   \
3285
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3286
#define PyUnicodeErrorObject_CAST(op)   \
3287
4.05M
    (assert(PyUnicodeError_Check(op)), ((PyUnicodeErrorObject *)(op)))
3288
3289
/* Assert some properties of the adjusted 'end' value. */
3290
#ifndef NDEBUG
3291
static void
3292
assert_adjusted_unicode_error_end(Py_ssize_t end, Py_ssize_t objlen)
3293
{
3294
    assert(objlen >= 0);
3295
    /* in the future, `min_end` may be something else */
3296
    Py_ssize_t min_end = Py_MIN(1, objlen);
3297
    assert(end >= min_end);
3298
    /* in the future, `max_end` may be something else */
3299
    Py_ssize_t max_end = Py_MAX(min_end, objlen);
3300
    assert(end <= max_end);
3301
}
3302
#else
3303
#define assert_adjusted_unicode_error_end(...)
3304
#endif
3305
3306
3307
/*
3308
 * Adjust the length of the range described by a UnicodeError object.
3309
 *
3310
 * The 'start' and 'end' arguments must have been obtained by
3311
 * unicode_error_adjust_start() and unicode_error_adjust_end().
3312
 *
3313
 * The result is clipped in [0, objlen]. By construction, it
3314
 * will always be smaller than 'objlen' as 'start' and 'end'
3315
 * are smaller than 'objlen'.
3316
 */
3317
static Py_ssize_t
3318
unicode_error_adjust_len(Py_ssize_t start, Py_ssize_t end, Py_ssize_t objlen)
3319
52.8k
{
3320
52.8k
    assert_adjusted_unicode_error_start(start, objlen);
3321
52.8k
    assert_adjusted_unicode_error_end(end, objlen);
3322
52.8k
    Py_ssize_t ranlen = end - start;
3323
52.8k
    assert(ranlen <= objlen);
3324
52.8k
    return ranlen < 0 ? 0 : ranlen;
3325
52.8k
}
3326
3327
3328
/* Assert some properties of the adjusted range 'len' value. */
3329
#ifndef NDEBUG
3330
static void
3331
assert_adjusted_unicode_error_len(Py_ssize_t ranlen, Py_ssize_t objlen)
3332
{
3333
    assert(objlen >= 0);
3334
    assert(ranlen >= 0);
3335
    assert(ranlen <= objlen);
3336
}
3337
#else
3338
#define assert_adjusted_unicode_error_len(...)
3339
#endif
3340
3341
3342
/*
3343
 * Get various common parameters of a UnicodeError object.
3344
 *
3345
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3346
 * although this condition is verified by this function on DEBUG builds.
3347
 *
3348
 * Return 0 on success and -1 on failure.
3349
 *
3350
 * Output parameters:
3351
 *
3352
 *     obj          A strong reference to the 'object' attribute.
3353
 *     objlen       The 'object' length.
3354
 *     start        The clipped 'start' attribute.
3355
 *     end          The clipped 'end' attribute.
3356
 *     slen         The length of the slice described by the clipped 'start'
3357
 *                  and 'end' values. It always lies in [0, objlen].
3358
 *
3359
 * An output parameter can be NULL to indicate that
3360
 * the corresponding value does not need to be stored.
3361
 *
3362
 * Input parameter:
3363
 *
3364
 *     as_bytes     If true, the error's 'object' attribute must be a `bytes`,
3365
 *                  i.e. 'self' is a `UnicodeDecodeError` instance. Otherwise,
3366
 *                  the 'object' attribute must be a string.
3367
 *
3368
 *                  A TypeError is raised if the 'object' type is incompatible.
3369
 */
3370
int
3371
_PyUnicodeError_GetParams(PyObject *self,
3372
                          PyObject **obj, Py_ssize_t *objlen,
3373
                          Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t *slen,
3374
                          int as_bytes)
3375
338k
{
3376
338k
    assert(self != NULL);
3377
338k
    assert(as_bytes == 0 || as_bytes == 1);
3378
338k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3379
338k
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
3380
338k
    if (r == NULL) {
3381
0
        return -1;
3382
0
    }
3383
3384
338k
    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
3385
338k
    if (objlen != NULL) {
3386
0
        *objlen = n;
3387
0
    }
3388
3389
338k
    Py_ssize_t start_value = -1;
3390
338k
    if (start != NULL || slen != NULL) {
3391
52.8k
        start_value = unicode_error_adjust_start(exc->start, n);
3392
52.8k
    }
3393
338k
    if (start != NULL) {
3394
52.8k
        assert_adjusted_unicode_error_start(start_value, n);
3395
52.8k
        *start = start_value;
3396
52.8k
    }
3397
3398
338k
    Py_ssize_t end_value = -1;
3399
338k
    if (end != NULL || slen != NULL) {
3400
338k
        end_value = unicode_error_adjust_end(exc->end, n);
3401
338k
    }
3402
338k
    if (end != NULL) {
3403
338k
        assert_adjusted_unicode_error_end(end_value, n);
3404
338k
        *end = end_value;
3405
338k
    }
3406
3407
338k
    if (slen != NULL) {
3408
52.8k
        *slen = unicode_error_adjust_len(start_value, end_value, n);
3409
52.8k
        assert_adjusted_unicode_error_len(*slen, n);
3410
52.8k
    }
3411
3412
338k
    if (obj != NULL) {
3413
52.8k
        *obj = r;
3414
52.8k
    }
3415
286k
    else {
3416
286k
        Py_DECREF(r);
3417
286k
    }
3418
338k
    return 0;
3419
338k
}
3420
3421
3422
// --- PyUnicodeEncodeObject: 'encoding' getters ------------------------------
3423
// Note: PyUnicodeTranslateError does not have an 'encoding' attribute.
3424
3425
PyObject *
3426
PyUnicodeEncodeError_GetEncoding(PyObject *self)
3427
0
{
3428
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3429
0
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
3430
0
}
3431
3432
3433
PyObject *
3434
PyUnicodeDecodeError_GetEncoding(PyObject *self)
3435
0
{
3436
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3437
0
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
3438
0
}
3439
3440
3441
// --- PyUnicodeEncodeObject: 'object' getters --------------------------------
3442
3443
PyObject *
3444
PyUnicodeEncodeError_GetObject(PyObject *self)
3445
0
{
3446
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3447
0
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
3448
0
}
3449
3450
3451
PyObject *
3452
PyUnicodeDecodeError_GetObject(PyObject *self)
3453
315k
{
3454
315k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3455
315k
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
3456
315k
}
3457
3458
3459
PyObject *
3460
PyUnicodeTranslateError_GetObject(PyObject *self)
3461
0
{
3462
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3463
0
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
3464
0
}
3465
3466
3467
// --- PyUnicodeEncodeObject: 'start' getters ---------------------------------
3468
3469
/*
3470
 * Specialization of _PyUnicodeError_GetParams() for the 'start' attribute.
3471
 *
3472
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3473
 * although this condition is verified by this function on DEBUG builds.
3474
 */
3475
static inline int
3476
unicode_error_get_start_impl(PyObject *self, Py_ssize_t *start, int as_bytes)
3477
0
{
3478
0
    assert(self != NULL);
3479
0
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3480
0
                                     start, NULL, NULL,
3481
0
                                     as_bytes);
3482
0
}
3483
3484
3485
int
3486
PyUnicodeEncodeError_GetStart(PyObject *self, Py_ssize_t *start)
3487
0
{
3488
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3489
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
3490
0
}
3491
3492
3493
int
3494
PyUnicodeDecodeError_GetStart(PyObject *self, Py_ssize_t *start)
3495
0
{
3496
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3497
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, true);
3498
0
}
3499
3500
3501
int
3502
PyUnicodeTranslateError_GetStart(PyObject *self, Py_ssize_t *start)
3503
0
{
3504
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3505
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
3506
0
}
3507
3508
3509
// --- PyUnicodeEncodeObject: 'start' setters ---------------------------------
3510
3511
int
3512
PyUnicodeEncodeError_SetStart(PyObject *self, Py_ssize_t start)
3513
0
{
3514
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3515
0
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3516
0
}
3517
3518
3519
int
3520
PyUnicodeDecodeError_SetStart(PyObject *self, Py_ssize_t start)
3521
273k
{
3522
273k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3523
273k
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3524
273k
}
3525
3526
3527
int
3528
PyUnicodeTranslateError_SetStart(PyObject *self, Py_ssize_t start)
3529
0
{
3530
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3531
0
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3532
0
}
3533
3534
3535
// --- PyUnicodeEncodeObject: 'end' getters -----------------------------------
3536
3537
/*
3538
 * Specialization of _PyUnicodeError_GetParams() for the 'end' attribute.
3539
 *
3540
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3541
 * although this condition is verified by this function on DEBUG builds.
3542
 */
3543
static inline int
3544
unicode_error_get_end_impl(PyObject *self, Py_ssize_t *end, int as_bytes)
3545
286k
{
3546
286k
    assert(self != NULL);
3547
286k
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3548
286k
                                     NULL, end, NULL,
3549
286k
                                     as_bytes);
3550
286k
}
3551
3552
3553
int
3554
PyUnicodeEncodeError_GetEnd(PyObject *self, Py_ssize_t *end)
3555
0
{
3556
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3557
0
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
3558
0
}
3559
3560
3561
int
3562
PyUnicodeDecodeError_GetEnd(PyObject *self, Py_ssize_t *end)
3563
286k
{
3564
286k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3565
286k
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, true);
3566
286k
}
3567
3568
3569
int
3570
PyUnicodeTranslateError_GetEnd(PyObject *self, Py_ssize_t *end)
3571
0
{
3572
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3573
0
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
3574
0
}
3575
3576
3577
// --- PyUnicodeEncodeObject: 'end' setters -----------------------------------
3578
3579
int
3580
PyUnicodeEncodeError_SetEnd(PyObject *self, Py_ssize_t end)
3581
0
{
3582
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3583
0
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3584
0
}
3585
3586
3587
int
3588
PyUnicodeDecodeError_SetEnd(PyObject *self, Py_ssize_t end)
3589
273k
{
3590
273k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3591
273k
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3592
273k
}
3593
3594
3595
int
3596
PyUnicodeTranslateError_SetEnd(PyObject *self, Py_ssize_t end)
3597
0
{
3598
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3599
0
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3600
0
}
3601
3602
3603
// --- PyUnicodeEncodeObject: 'reason' getters --------------------------------
3604
3605
PyObject *
3606
PyUnicodeEncodeError_GetReason(PyObject *self)
3607
0
{
3608
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3609
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3610
0
}
3611
3612
3613
PyObject *
3614
PyUnicodeDecodeError_GetReason(PyObject *self)
3615
0
{
3616
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3617
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3618
0
}
3619
3620
3621
PyObject *
3622
PyUnicodeTranslateError_GetReason(PyObject *self)
3623
0
{
3624
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3625
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3626
0
}
3627
3628
3629
// --- PyUnicodeEncodeObject: 'reason' setters --------------------------------
3630
3631
int
3632
PyUnicodeEncodeError_SetReason(PyObject *self, const char *reason)
3633
0
{
3634
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3635
0
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3636
0
}
3637
3638
3639
int
3640
PyUnicodeDecodeError_SetReason(PyObject *self, const char *reason)
3641
273k
{
3642
273k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3643
273k
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3644
273k
}
3645
3646
3647
int
3648
PyUnicodeTranslateError_SetReason(PyObject *self, const char *reason)
3649
0
{
3650
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3651
0
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3652
0
}
3653
3654
3655
static int
3656
UnicodeError_clear(PyObject *self)
3657
2.02M
{
3658
2.02M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3659
2.02M
    Py_CLEAR(exc->encoding);
3660
2.02M
    Py_CLEAR(exc->object);
3661
2.02M
    Py_CLEAR(exc->reason);
3662
2.02M
    return BaseException_clear(self);
3663
2.02M
}
3664
3665
static void
3666
UnicodeError_dealloc(PyObject *self)
3667
2.02M
{
3668
2.02M
    PyTypeObject *type = Py_TYPE(self);
3669
2.02M
    _PyObject_GC_UNTRACK(self);
3670
2.02M
    (void)UnicodeError_clear(self);
3671
2.02M
    type->tp_free(self);
3672
2.02M
}
3673
3674
static int
3675
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
3676
135
{
3677
135
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3678
135
    Py_VISIT(exc->encoding);
3679
135
    Py_VISIT(exc->object);
3680
135
    Py_VISIT(exc->reason);
3681
135
    return BaseException_traverse(self, visit, arg);
3682
135
}
3683
3684
static PyMemberDef UnicodeError_members[] = {
3685
    {"encoding", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
3686
        PyDoc_STR("exception encoding")},
3687
    {"object", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
3688
        PyDoc_STR("exception object")},
3689
    {"start", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
3690
        PyDoc_STR("exception start")},
3691
    {"end", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
3692
        PyDoc_STR("exception end")},
3693
    {"reason", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
3694
        PyDoc_STR("exception reason")},
3695
    {NULL}  /* Sentinel */
3696
};
3697
3698
3699
/*
3700
 *    UnicodeEncodeError extends UnicodeError
3701
 */
3702
3703
static int
3704
UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
3705
168k
{
3706
168k
    if (BaseException_init(self, args, kwds) == -1) {
3707
0
        return -1;
3708
0
    }
3709
3710
168k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3711
168k
    Py_ssize_t start = -1, end = -1;
3712
3713
168k
    if (!PyArg_ParseTuple(args, "UUnnU",
3714
168k
                          &encoding, &object, &start, &end, &reason))
3715
0
    {
3716
0
        return -1;
3717
0
    }
3718
3719
168k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3720
168k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3721
168k
    Py_XSETREF(exc->object, Py_NewRef(object));
3722
168k
    exc->start = start;
3723
168k
    exc->end = end;
3724
168k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3725
168k
    return 0;
3726
168k
}
3727
3728
static PyObject *
3729
UnicodeEncodeError_str(PyObject *self)
3730
31
{
3731
31
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3732
31
    PyObject *result = NULL;
3733
31
    PyObject *reason_str = NULL;
3734
31
    PyObject *encoding_str = NULL;
3735
3736
31
    if (exc->object == NULL) {
3737
        /* Not properly initialized. */
3738
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3739
0
    }
3740
3741
    /* Get reason and encoding as strings, which they might not be if
3742
       they've been modified after we were constructed. */
3743
31
    reason_str = PyObject_Str(exc->reason);
3744
31
    if (reason_str == NULL) {
3745
0
        goto done;
3746
0
    }
3747
31
    encoding_str = PyObject_Str(exc->encoding);
3748
31
    if (encoding_str == NULL) {
3749
0
        goto done;
3750
0
    }
3751
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3752
31
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3753
0
        goto done;
3754
0
    }
3755
31
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3756
31
    Py_ssize_t start = exc->start, end = exc->end;
3757
3758
31
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3759
16
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3760
16
        const char *fmt;
3761
16
        if (badchar <= 0xff) {
3762
0
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
3763
0
        }
3764
16
        else if (badchar <= 0xffff) {
3765
16
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
3766
16
        }
3767
0
        else {
3768
0
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
3769
0
        }
3770
16
        result = PyUnicode_FromFormat(
3771
16
            fmt,
3772
16
            encoding_str,
3773
16
            (int)badchar,
3774
16
            start,
3775
16
            reason_str);
3776
16
    }
3777
15
    else {
3778
15
        result = PyUnicode_FromFormat(
3779
15
            "'%U' codec can't encode characters in position %zd-%zd: %U",
3780
15
            encoding_str,
3781
15
            start,
3782
15
            end - 1,
3783
15
            reason_str);
3784
15
    }
3785
31
done:
3786
31
    Py_XDECREF(reason_str);
3787
31
    Py_XDECREF(encoding_str);
3788
31
    return result;
3789
31
}
3790
3791
static PyTypeObject _PyExc_UnicodeEncodeError = {
3792
    PyVarObject_HEAD_INIT(NULL, 0)
3793
    "UnicodeEncodeError",
3794
    sizeof(PyUnicodeErrorObject), 0,
3795
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3796
    UnicodeEncodeError_str, 0, 0, 0,
3797
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3798
    PyDoc_STR("Unicode encoding error."), UnicodeError_traverse,
3799
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3800
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3801
    UnicodeEncodeError_init, 0, BaseException_new,
3802
};
3803
PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
3804
3805
3806
/*
3807
 *    UnicodeDecodeError extends UnicodeError
3808
 */
3809
3810
static int
3811
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
3812
1.86M
{
3813
1.86M
    if (BaseException_init(self, args, kwds) == -1) {
3814
0
        return -1;
3815
0
    }
3816
3817
1.86M
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3818
1.86M
    Py_ssize_t start = -1, end = -1;
3819
3820
1.86M
    if (!PyArg_ParseTuple(args, "UOnnU",
3821
1.86M
                          &encoding, &object, &start, &end, &reason))
3822
103
    {
3823
103
        return -1;
3824
103
    }
3825
3826
1.86M
    if (PyBytes_Check(object)) {
3827
1.86M
        Py_INCREF(object);  // make 'object' a strong reference
3828
1.86M
    }
3829
0
    else {
3830
0
        Py_buffer view;
3831
0
        if (PyObject_GetBuffer(object, &view, PyBUF_SIMPLE) != 0) {
3832
0
            return -1;
3833
0
        }
3834
        // 'object' is borrowed, so we can re-use the variable
3835
0
        object = PyBytes_FromStringAndSize(view.buf, view.len);
3836
0
        PyBuffer_Release(&view);
3837
0
        if (object == NULL) {
3838
0
            return -1;
3839
0
        }
3840
0
    }
3841
3842
1.86M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3843
1.86M
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3844
1.86M
    Py_XSETREF(exc->object, object /* already a strong reference */);
3845
1.86M
    exc->start = start;
3846
1.86M
    exc->end = end;
3847
1.86M
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3848
1.86M
    return 0;
3849
1.86M
}
3850
3851
static PyObject *
3852
UnicodeDecodeError_str(PyObject *self)
3853
1.16k
{
3854
1.16k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3855
1.16k
    PyObject *result = NULL;
3856
1.16k
    PyObject *reason_str = NULL;
3857
1.16k
    PyObject *encoding_str = NULL;
3858
3859
1.16k
    if (exc->object == NULL) {
3860
        /* Not properly initialized. */
3861
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3862
0
    }
3863
3864
    /* Get reason and encoding as strings, which they might not be if
3865
       they've been modified after we were constructed. */
3866
1.16k
    reason_str = PyObject_Str(exc->reason);
3867
1.16k
    if (reason_str == NULL) {
3868
0
        goto done;
3869
0
    }
3870
1.16k
    encoding_str = PyObject_Str(exc->encoding);
3871
1.16k
    if (encoding_str == NULL) {
3872
0
        goto done;
3873
0
    }
3874
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3875
1.16k
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
3876
0
        goto done;
3877
0
    }
3878
1.16k
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
3879
1.16k
    Py_ssize_t start = exc->start, end = exc->end;
3880
3881
1.16k
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3882
634
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
3883
634
        result = PyUnicode_FromFormat(
3884
634
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3885
634
            encoding_str,
3886
634
            badbyte,
3887
634
            start,
3888
634
            reason_str);
3889
634
    }
3890
533
    else {
3891
533
        result = PyUnicode_FromFormat(
3892
533
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3893
533
            encoding_str,
3894
533
            start,
3895
533
            end - 1,
3896
533
            reason_str);
3897
533
    }
3898
1.16k
done:
3899
1.16k
    Py_XDECREF(reason_str);
3900
1.16k
    Py_XDECREF(encoding_str);
3901
1.16k
    return result;
3902
1.16k
}
3903
3904
static PyTypeObject _PyExc_UnicodeDecodeError = {
3905
    PyVarObject_HEAD_INIT(NULL, 0)
3906
    "UnicodeDecodeError",
3907
    sizeof(PyUnicodeErrorObject), 0,
3908
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3909
    UnicodeDecodeError_str, 0, 0, 0,
3910
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3911
    PyDoc_STR("Unicode decoding error."), UnicodeError_traverse,
3912
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3913
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3914
    UnicodeDecodeError_init, 0, BaseException_new,
3915
};
3916
PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
3917
3918
PyObject *
3919
PyUnicodeDecodeError_Create(
3920
    const char *encoding, const char *object, Py_ssize_t length,
3921
    Py_ssize_t start, Py_ssize_t end, const char *reason)
3922
1.85M
{
3923
1.85M
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3924
1.85M
                                 encoding, object, length, start, end, reason);
3925
1.85M
}
3926
3927
3928
/*
3929
 *    UnicodeTranslateError extends UnicodeError
3930
 */
3931
3932
static int
3933
UnicodeTranslateError_init(PyObject *self, PyObject *args, PyObject *kwds)
3934
0
{
3935
0
    if (BaseException_init(self, args, kwds) == -1) {
3936
0
        return -1;
3937
0
    }
3938
3939
0
    PyObject *object = NULL, *reason = NULL;  // borrowed
3940
0
    Py_ssize_t start = -1, end = -1;
3941
3942
0
    if (!PyArg_ParseTuple(args, "UnnU", &object, &start, &end, &reason)) {
3943
0
        return -1;
3944
0
    }
3945
3946
0
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3947
0
    Py_XSETREF(exc->object, Py_NewRef(object));
3948
0
    exc->start = start;
3949
0
    exc->end = end;
3950
0
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3951
0
    return 0;
3952
0
}
3953
3954
3955
static PyObject *
3956
UnicodeTranslateError_str(PyObject *self)
3957
0
{
3958
0
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3959
0
    PyObject *result = NULL;
3960
0
    PyObject *reason_str = NULL;
3961
3962
0
    if (exc->object == NULL) {
3963
        /* Not properly initialized. */
3964
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3965
0
    }
3966
3967
    /* Get reason as a string, which it might not be if it's been
3968
       modified after we were constructed. */
3969
0
    reason_str = PyObject_Str(exc->reason);
3970
0
    if (reason_str == NULL) {
3971
0
        goto done;
3972
0
    }
3973
    // call to PyObject_Str(...) above might mutate 'exc->object'
3974
0
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3975
0
        goto done;
3976
0
    }
3977
0
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3978
0
    Py_ssize_t start = exc->start, end = exc->end;
3979
3980
0
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3981
0
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3982
0
        const char *fmt;
3983
0
        if (badchar <= 0xff) {
3984
0
            fmt = "can't translate character '\\x%02x' in position %zd: %U";
3985
0
        }
3986
0
        else if (badchar <= 0xffff) {
3987
0
            fmt = "can't translate character '\\u%04x' in position %zd: %U";
3988
0
        }
3989
0
        else {
3990
0
            fmt = "can't translate character '\\U%08x' in position %zd: %U";
3991
0
        }
3992
0
        result = PyUnicode_FromFormat(
3993
0
            fmt,
3994
0
            (int)badchar,
3995
0
            start,
3996
0
            reason_str);
3997
0
    }
3998
0
    else {
3999
0
        result = PyUnicode_FromFormat(
4000
0
            "can't translate characters in position %zd-%zd: %U",
4001
0
            start,
4002
0
            end - 1,
4003
0
            reason_str);
4004
0
    }
4005
0
done:
4006
0
    Py_XDECREF(reason_str);
4007
0
    return result;
4008
0
}
4009
4010
static PyTypeObject _PyExc_UnicodeTranslateError = {
4011
    PyVarObject_HEAD_INIT(NULL, 0)
4012
    "UnicodeTranslateError",
4013
    sizeof(PyUnicodeErrorObject), 0,
4014
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4015
    UnicodeTranslateError_str, 0, 0, 0,
4016
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
4017
    PyDoc_STR("Unicode translation error."), UnicodeError_traverse,
4018
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
4019
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
4020
    UnicodeTranslateError_init, 0, BaseException_new,
4021
};
4022
PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
4023
4024
PyObject *
4025
_PyUnicodeTranslateError_Create(
4026
    PyObject *object,
4027
    Py_ssize_t start, Py_ssize_t end, const char *reason)
4028
0
{
4029
0
    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
4030
0
                                 object, start, end, reason);
4031
0
}
4032
4033
/*
4034
 *    AssertionError extends Exception
4035
 */
4036
SimpleExtendsException(PyExc_Exception, AssertionError,
4037
                       "Assertion failed.");
4038
4039
4040
/*
4041
 *    ArithmeticError extends Exception
4042
 */
4043
SimpleExtendsException(PyExc_Exception, ArithmeticError,
4044
                       "Base class for arithmetic errors.");
4045
4046
4047
/*
4048
 *    FloatingPointError extends ArithmeticError
4049
 */
4050
SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
4051
                       "Floating-point operation failed.");
4052
4053
4054
/*
4055
 *    OverflowError extends ArithmeticError
4056
 */
4057
SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
4058
                       "Result too large to be represented.");
4059
4060
4061
/*
4062
 *    ZeroDivisionError extends ArithmeticError
4063
 */
4064
SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
4065
          "Second argument to a division or modulo operation was zero.");
4066
4067
4068
/*
4069
 *    SystemError extends Exception
4070
 */
4071
SimpleExtendsException(PyExc_Exception, SystemError,
4072
    "Internal error in the Python interpreter.\n"
4073
    "\n"
4074
    "Please report this to the Python maintainer, along with the traceback,\n"
4075
    "the Python version, and the hardware/OS platform and version.");
4076
4077
4078
/*
4079
 *    ReferenceError extends Exception
4080
 */
4081
SimpleExtendsException(PyExc_Exception, ReferenceError,
4082
                       "Weak ref proxy used after referent went away.");
4083
4084
4085
/*
4086
 *    MemoryError extends Exception
4087
 */
4088
4089
1.60k
#define MEMERRORS_SAVE 16
4090
4091
#ifdef Py_GIL_DISABLED
4092
# define MEMERRORS_LOCK(state) PyMutex_LockFlags(&state->memerrors_lock, _Py_LOCK_DONT_DETACH)
4093
# define MEMERRORS_UNLOCK(state) PyMutex_Unlock(&state->memerrors_lock)
4094
#else
4095
1.04k
# define MEMERRORS_LOCK(state) ((void)0)
4096
1.04k
# define MEMERRORS_UNLOCK(state) ((void)0)
4097
#endif
4098
4099
static PyObject *
4100
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
4101
521
{
4102
521
    PyBaseExceptionObject *self = NULL;
4103
521
    struct _Py_exc_state *state = get_exc_state();
4104
4105
521
    MEMERRORS_LOCK(state);
4106
521
    if (state->memerrors_freelist != NULL) {
4107
        /* Fetch MemoryError from freelist and initialize it */
4108
9
        self = state->memerrors_freelist;
4109
9
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
4110
9
        state->memerrors_numfree--;
4111
9
        self->dict = NULL;
4112
9
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
4113
9
        _Py_NewReference((PyObject *)self);
4114
9
        _PyObject_GC_TRACK(self);
4115
9
    }
4116
521
    MEMERRORS_UNLOCK(state);
4117
4118
521
    if (self != NULL) {
4119
9
        return (PyObject *)self;
4120
9
    }
4121
4122
512
    if (!allow_allocation) {
4123
0
        PyInterpreterState *interp = _PyInterpreterState_GET();
4124
0
        return Py_NewRef(
4125
0
            &_Py_INTERP_SINGLETON(interp, last_resort_memory_error));
4126
0
    }
4127
512
    return BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds);
4128
512
}
4129
4130
static PyObject *
4131
MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4132
521
{
4133
    /* If this is a subclass of MemoryError, don't use the freelist
4134
     * and just return a fresh object */
4135
521
    if (type != (PyTypeObject *) PyExc_MemoryError) {
4136
0
        return BaseException_new(type, args, kwds);
4137
0
    }
4138
521
    return get_memory_error(1, args, kwds);
4139
521
}
4140
4141
PyObject *
4142
_PyErr_NoMemory(PyThreadState *tstate)
4143
0
{
4144
0
    if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
4145
        /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
4146
           initialized by _PyExc_Init() */
4147
0
        Py_FatalError("Out of memory and PyExc_MemoryError is not "
4148
0
                      "initialized yet");
4149
0
    }
4150
0
    PyObject *err = get_memory_error(0, NULL, NULL);
4151
0
    if (err != NULL) {
4152
0
        _PyErr_SetRaisedException(tstate, err);
4153
0
    }
4154
0
    return NULL;
4155
0
}
4156
4157
static void
4158
MemoryError_dealloc(PyObject *op)
4159
521
{
4160
521
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
4161
521
    _PyObject_GC_UNTRACK(self);
4162
4163
521
    (void)BaseException_clear(op);
4164
4165
    /* If this is a subclass of MemoryError, we don't need to
4166
     * do anything in the free-list*/
4167
521
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
4168
0
        Py_TYPE(self)->tp_free(op);
4169
0
        return;
4170
0
    }
4171
4172
521
    struct _Py_exc_state *state = get_exc_state();
4173
521
    MEMERRORS_LOCK(state);
4174
521
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
4175
521
        self->dict = (PyObject *) state->memerrors_freelist;
4176
521
        state->memerrors_freelist = self;
4177
521
        state->memerrors_numfree++;
4178
521
        MEMERRORS_UNLOCK(state);
4179
521
        return;
4180
521
    }
4181
0
    MEMERRORS_UNLOCK(state);
4182
4183
0
    Py_TYPE(self)->tp_free((PyObject *)self);
4184
0
}
4185
4186
static int
4187
preallocate_memerrors(void)
4188
32
{
4189
    /* We create enough MemoryErrors and then decref them, which will fill
4190
       up the freelist. */
4191
32
    int i;
4192
4193
32
    PyObject *errors[MEMERRORS_SAVE];
4194
544
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4195
512
        errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
4196
512
                                    NULL, NULL);
4197
512
        if (!errors[i]) {
4198
0
            return -1;
4199
0
        }
4200
512
    }
4201
544
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4202
512
        Py_DECREF(errors[i]);
4203
512
    }
4204
32
    return 0;
4205
32
}
4206
4207
static void
4208
free_preallocated_memerrors(struct _Py_exc_state *state)
4209
0
{
4210
0
    while (state->memerrors_freelist != NULL) {
4211
0
        PyObject *self = (PyObject *) state->memerrors_freelist;
4212
0
        state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
4213
0
        Py_TYPE(self)->tp_free(self);
4214
0
    }
4215
0
}
4216
4217
4218
PyTypeObject _PyExc_MemoryError = {
4219
    PyVarObject_HEAD_INIT(NULL, 0)
4220
    "MemoryError",
4221
    sizeof(PyBaseExceptionObject),
4222
    0, MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
4223
    0, 0, 0, 0, 0, 0, 0,
4224
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
4225
    PyDoc_STR("Out of memory."), BaseException_traverse,
4226
    BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
4227
    0, 0, 0, offsetof(PyBaseExceptionObject, dict),
4228
    BaseException_init, 0, MemoryError_new
4229
};
4230
PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
4231
4232
4233
/*
4234
 *    BufferError extends Exception
4235
 */
4236
SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
4237
4238
4239
/* Warning category docstrings */
4240
4241
/*
4242
 *    Warning extends Exception
4243
 */
4244
SimpleExtendsException(PyExc_Exception, Warning,
4245
                       "Base class for warning categories.");
4246
4247
4248
/*
4249
 *    UserWarning extends Warning
4250
 */
4251
SimpleExtendsException(PyExc_Warning, UserWarning,
4252
                       "Base class for warnings generated by user code.");
4253
4254
4255
/*
4256
 *    DeprecationWarning extends Warning
4257
 */
4258
SimpleExtendsException(PyExc_Warning, DeprecationWarning,
4259
                       "Base class for warnings about deprecated features.");
4260
4261
4262
/*
4263
 *    PendingDeprecationWarning extends Warning
4264
 */
4265
SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
4266
    "Base class for warnings about features which will be deprecated\n"
4267
    "in the future.");
4268
4269
4270
/*
4271
 *    SyntaxWarning extends Warning
4272
 */
4273
SimpleExtendsException(PyExc_Warning, SyntaxWarning,
4274
                       "Base class for warnings about dubious syntax.");
4275
4276
4277
/*
4278
 *    RuntimeWarning extends Warning
4279
 */
4280
SimpleExtendsException(PyExc_Warning, RuntimeWarning,
4281
                 "Base class for warnings about dubious runtime behavior.");
4282
4283
4284
/*
4285
 *    FutureWarning extends Warning
4286
 */
4287
SimpleExtendsException(PyExc_Warning, FutureWarning,
4288
    "Base class for warnings about constructs that will change semantically\n"
4289
    "in the future.");
4290
4291
4292
/*
4293
 *    ImportWarning extends Warning
4294
 */
4295
SimpleExtendsException(PyExc_Warning, ImportWarning,
4296
          "Base class for warnings about probable mistakes in module imports");
4297
4298
4299
/*
4300
 *    UnicodeWarning extends Warning
4301
 */
4302
SimpleExtendsException(PyExc_Warning, UnicodeWarning,
4303
    "Base class for warnings about Unicode related problems, mostly\n"
4304
    "related to conversion problems.");
4305
4306
4307
/*
4308
 *    BytesWarning extends Warning
4309
 */
4310
SimpleExtendsException(PyExc_Warning, BytesWarning,
4311
    "Base class for warnings about bytes and buffer related problems, mostly\n"
4312
    "related to conversion from str or comparing to str.");
4313
4314
4315
/*
4316
 *    EncodingWarning extends Warning
4317
 */
4318
SimpleExtendsException(PyExc_Warning, EncodingWarning,
4319
    "Base class for warnings about encodings.");
4320
4321
4322
/*
4323
 *    ResourceWarning extends Warning
4324
 */
4325
SimpleExtendsException(PyExc_Warning, ResourceWarning,
4326
    "Base class for warnings about resource usage.");
4327
4328
4329
4330
#ifdef MS_WINDOWS
4331
#include <winsock2.h>
4332
/* The following constants were added to errno.h in VS2010 but have
4333
   preferred WSA equivalents. */
4334
#undef EADDRINUSE
4335
#undef EADDRNOTAVAIL
4336
#undef EAFNOSUPPORT
4337
#undef EALREADY
4338
#undef ECONNABORTED
4339
#undef ECONNREFUSED
4340
#undef ECONNRESET
4341
#undef EDESTADDRREQ
4342
#undef EHOSTUNREACH
4343
#undef EINPROGRESS
4344
#undef EISCONN
4345
#undef ELOOP
4346
#undef EMSGSIZE
4347
#undef ENETDOWN
4348
#undef ENETRESET
4349
#undef ENETUNREACH
4350
#undef ENOBUFS
4351
#undef ENOPROTOOPT
4352
#undef ENOTCONN
4353
#undef ENOTSOCK
4354
#undef EOPNOTSUPP
4355
#undef EPROTONOSUPPORT
4356
#undef EPROTOTYPE
4357
#undef EWOULDBLOCK
4358
4359
#if defined(WSAEALREADY) && !defined(EALREADY)
4360
#define EALREADY WSAEALREADY
4361
#endif
4362
#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
4363
#define ECONNABORTED WSAECONNABORTED
4364
#endif
4365
#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
4366
#define ECONNREFUSED WSAECONNREFUSED
4367
#endif
4368
#if defined(WSAECONNRESET) && !defined(ECONNRESET)
4369
#define ECONNRESET WSAECONNRESET
4370
#endif
4371
#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
4372
#define EINPROGRESS WSAEINPROGRESS
4373
#endif
4374
#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
4375
#define ESHUTDOWN WSAESHUTDOWN
4376
#endif
4377
#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
4378
#define EWOULDBLOCK WSAEWOULDBLOCK
4379
#endif
4380
#endif /* MS_WINDOWS */
4381
4382
struct static_exception {
4383
    PyTypeObject *exc;
4384
    const char *name;
4385
};
4386
4387
static struct static_exception static_exceptions[] = {
4388
#define ITEM(NAME) {&_PyExc_##NAME, #NAME}
4389
    // Level 1
4390
    ITEM(BaseException),
4391
4392
    // Level 2: BaseException subclasses
4393
    ITEM(BaseExceptionGroup),
4394
    ITEM(Exception),
4395
    ITEM(GeneratorExit),
4396
    ITEM(KeyboardInterrupt),
4397
    ITEM(SystemExit),
4398
4399
    // Level 3: Exception(BaseException) subclasses
4400
    ITEM(ArithmeticError),
4401
    ITEM(AssertionError),
4402
    ITEM(AttributeError),
4403
    ITEM(BufferError),
4404
    ITEM(EOFError),
4405
    //ITEM(ExceptionGroup),
4406
    ITEM(ImportError),
4407
    ITEM(LookupError),
4408
    ITEM(MemoryError),
4409
    ITEM(NameError),
4410
    ITEM(OSError),
4411
    ITEM(ReferenceError),
4412
    ITEM(RuntimeError),
4413
    ITEM(StopAsyncIteration),
4414
    ITEM(StopIteration),
4415
    ITEM(SyntaxError),
4416
    ITEM(SystemError),
4417
    ITEM(TypeError),
4418
    ITEM(ValueError),
4419
    ITEM(Warning),
4420
4421
    // Level 4: ArithmeticError(Exception) subclasses
4422
    ITEM(FloatingPointError),
4423
    ITEM(OverflowError),
4424
    ITEM(ZeroDivisionError),
4425
4426
    // Level 4: Warning(Exception) subclasses
4427
    ITEM(BytesWarning),
4428
    ITEM(DeprecationWarning),
4429
    ITEM(EncodingWarning),
4430
    ITEM(FutureWarning),
4431
    ITEM(ImportWarning),
4432
    ITEM(PendingDeprecationWarning),
4433
    ITEM(ResourceWarning),
4434
    ITEM(RuntimeWarning),
4435
    ITEM(SyntaxWarning),
4436
    ITEM(UnicodeWarning),
4437
    ITEM(UserWarning),
4438
4439
    // Level 4: OSError(Exception) subclasses
4440
    ITEM(BlockingIOError),
4441
    ITEM(ChildProcessError),
4442
    ITEM(ConnectionError),
4443
    ITEM(FileExistsError),
4444
    ITEM(FileNotFoundError),
4445
    ITEM(InterruptedError),
4446
    ITEM(IsADirectoryError),
4447
    ITEM(NotADirectoryError),
4448
    ITEM(PermissionError),
4449
    ITEM(ProcessLookupError),
4450
    ITEM(TimeoutError),
4451
4452
    // Level 4: Other subclasses
4453
    ITEM(IndentationError), // base: SyntaxError(Exception)
4454
    {&_PyExc_IncompleteInputError, "_IncompleteInputError"}, // base: SyntaxError(Exception)
4455
    ITEM(IndexError),  // base: LookupError(Exception)
4456
    ITEM(KeyError),  // base: LookupError(Exception)
4457
    ITEM(ModuleNotFoundError), // base: ImportError(Exception)
4458
    ITEM(NotImplementedError),  // base: RuntimeError(Exception)
4459
    ITEM(PythonFinalizationError),  // base: RuntimeError(Exception)
4460
    ITEM(RecursionError),  // base: RuntimeError(Exception)
4461
    ITEM(UnboundLocalError), // base: NameError(Exception)
4462
    ITEM(UnicodeError),  // base: ValueError(Exception)
4463
4464
    // Level 5: ConnectionError(OSError) subclasses
4465
    ITEM(BrokenPipeError),
4466
    ITEM(ConnectionAbortedError),
4467
    ITEM(ConnectionRefusedError),
4468
    ITEM(ConnectionResetError),
4469
4470
    // Level 5: IndentationError(SyntaxError) subclasses
4471
    ITEM(TabError),  // base: IndentationError
4472
4473
    // Level 5: UnicodeError(ValueError) subclasses
4474
    ITEM(UnicodeDecodeError),
4475
    ITEM(UnicodeEncodeError),
4476
    ITEM(UnicodeTranslateError),
4477
#undef ITEM
4478
};
4479
4480
4481
int
4482
_PyExc_InitTypes(PyInterpreterState *interp)
4483
32
{
4484
2.20k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4485
2.17k
        PyTypeObject *exc = static_exceptions[i].exc;
4486
2.17k
        if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
4487
0
            return -1;
4488
0
        }
4489
2.17k
        if (exc->tp_new == BaseException_new
4490
1.60k
            && exc->tp_init == BaseException_init)
4491
1.15k
        {
4492
1.15k
            exc->tp_vectorcall = BaseException_vectorcall;
4493
1.15k
        }
4494
2.17k
    }
4495
32
    return 0;
4496
32
}
4497
4498
4499
static void
4500
_PyExc_FiniTypes(PyInterpreterState *interp)
4501
0
{
4502
0
    for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
4503
0
        PyTypeObject *exc = static_exceptions[i].exc;
4504
0
        _PyStaticType_FiniBuiltin(interp, exc);
4505
0
    }
4506
0
}
4507
4508
4509
PyStatus
4510
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
4511
32
{
4512
32
    if (preallocate_memerrors() < 0) {
4513
0
        return _PyStatus_NO_MEMORY();
4514
0
    }
4515
32
    return _PyStatus_OK();
4516
32
}
4517
4518
PyStatus
4519
_PyExc_InitState(PyInterpreterState *interp)
4520
32
{
4521
32
    struct _Py_exc_state *state = &interp->exc_state;
4522
4523
32
#define ADD_ERRNO(TYPE, CODE) \
4524
608
    do { \
4525
608
        PyObject *_code = PyLong_FromLong(CODE); \
4526
608
        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
4527
608
        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
4528
0
            Py_XDECREF(_code); \
4529
0
            return _PyStatus_ERR("errmap insertion problem."); \
4530
0
        } \
4531
608
        Py_DECREF(_code); \
4532
608
    } while (0)
4533
4534
    /* Add exceptions to errnomap */
4535
32
    assert(state->errnomap == NULL);
4536
32
    state->errnomap = PyDict_New();
4537
32
    if (!state->errnomap) {
4538
0
        return _PyStatus_NO_MEMORY();
4539
0
    }
4540
4541
32
    ADD_ERRNO(BlockingIOError, EAGAIN);
4542
32
    ADD_ERRNO(BlockingIOError, EALREADY);
4543
32
    ADD_ERRNO(BlockingIOError, EINPROGRESS);
4544
32
    ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
4545
32
    ADD_ERRNO(BrokenPipeError, EPIPE);
4546
32
#ifdef ESHUTDOWN
4547
32
    ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
4548
32
#endif
4549
32
    ADD_ERRNO(ChildProcessError, ECHILD);
4550
32
    ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
4551
32
    ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
4552
32
    ADD_ERRNO(ConnectionResetError, ECONNRESET);
4553
32
    ADD_ERRNO(FileExistsError, EEXIST);
4554
32
    ADD_ERRNO(FileNotFoundError, ENOENT);
4555
32
    ADD_ERRNO(IsADirectoryError, EISDIR);
4556
32
    ADD_ERRNO(NotADirectoryError, ENOTDIR);
4557
32
    ADD_ERRNO(InterruptedError, EINTR);
4558
32
    ADD_ERRNO(PermissionError, EACCES);
4559
32
    ADD_ERRNO(PermissionError, EPERM);
4560
#ifdef ENOTCAPABLE
4561
    // Extension for WASI capability-based security. Process lacks
4562
    // capability to access a resource.
4563
    ADD_ERRNO(PermissionError, ENOTCAPABLE);
4564
#endif
4565
32
    ADD_ERRNO(ProcessLookupError, ESRCH);
4566
32
    ADD_ERRNO(TimeoutError, ETIMEDOUT);
4567
#ifdef WSAETIMEDOUT
4568
    ADD_ERRNO(TimeoutError, WSAETIMEDOUT);
4569
#endif
4570
4571
32
    return _PyStatus_OK();
4572
4573
32
#undef ADD_ERRNO
4574
32
}
4575
4576
4577
/* Add exception types to the builtins module */
4578
int
4579
_PyBuiltins_AddExceptions(PyObject *bltinmod)
4580
32
{
4581
32
    PyObject *mod_dict = PyModule_GetDict(bltinmod);
4582
32
    if (mod_dict == NULL) {
4583
0
        return -1;
4584
0
    }
4585
4586
2.20k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4587
2.17k
        struct static_exception item = static_exceptions[i];
4588
4589
2.17k
        if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
4590
0
            return -1;
4591
0
        }
4592
2.17k
    }
4593
4594
32
    PyObject *PyExc_ExceptionGroup = create_exception_group_class();
4595
32
    if (!PyExc_ExceptionGroup) {
4596
0
        return -1;
4597
0
    }
4598
32
    if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
4599
0
        return -1;
4600
0
    }
4601
32
    if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) {
4602
0
        return -1;
4603
0
    }
4604
32
    if (PyDict_SetItemString(mod_dict, "IOError", PyExc_OSError)) {
4605
0
        return -1;
4606
0
    }
4607
#ifdef MS_WINDOWS
4608
    if (PyDict_SetItemString(mod_dict, "WindowsError", PyExc_OSError)) {
4609
        return -1;
4610
    }
4611
#endif
4612
32
    return 0;
4613
32
}
4614
4615
void
4616
_PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
4617
0
{
4618
0
    struct _Py_exc_state *state = &interp->exc_state;
4619
0
    Py_CLEAR(state->PyExc_ExceptionGroup);
4620
0
}
4621
4622
void
4623
_PyExc_Fini(PyInterpreterState *interp)
4624
0
{
4625
0
    struct _Py_exc_state *state = &interp->exc_state;
4626
0
    free_preallocated_memerrors(state);
4627
0
    Py_CLEAR(state->errnomap);
4628
4629
0
    _PyExc_FiniTypes(interp);
4630
0
}
4631
4632
int
4633
_PyException_AddNote(PyObject *exc, PyObject *note)
4634
41.4k
{
4635
41.4k
    if (!PyExceptionInstance_Check(exc)) {
4636
0
        PyErr_Format(PyExc_TypeError,
4637
0
                     "exc must be an exception, not '%s'",
4638
0
                     Py_TYPE(exc)->tp_name);
4639
0
        return -1;
4640
0
    }
4641
41.4k
    PyObject *r = BaseException_add_note(exc, note);
4642
41.4k
    int res = r == NULL ? -1 : 0;
4643
41.4k
    Py_XDECREF(r);
4644
41.4k
    return res;
4645
41.4k
}
4646