Coverage Report

Created: 2026-06-21 06:15

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