Coverage Report

Created: 2026-03-23 06:45

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