Coverage Report

Created: 2026-06-09 06:53

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
322k
{
32
322k
    PyInterpreterState *interp = _PyInterpreterState_GET();
33
322k
    return &interp->exc_state;
34
322k
}
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
320M
{
44
320M
    assert(PyExceptionInstance_Check(exc));
45
320M
    return (PyBaseExceptionObject *)exc;
46
320M
}
47
48
/*
49
 *    BaseException
50
 */
51
static PyObject *
52
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
53
34.5M
{
54
34.5M
    PyBaseExceptionObject *self;
55
56
34.5M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
57
34.5M
    if (!self)
58
0
        return NULL;
59
    /* the dict is created on the fly in PyObject_GenericSetAttr */
60
34.5M
    self->dict = NULL;
61
34.5M
    self->notes = NULL;
62
34.5M
    self->traceback = self->cause = self->context = NULL;
63
34.5M
    self->suppress_context = 0;
64
65
34.5M
    if (args) {
66
34.5M
        self->args = Py_NewRef(args);
67
34.5M
        return (PyObject *)self;
68
34.5M
    }
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
33.2M
{
82
33.2M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
83
33.2M
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
84
0
        return -1;
85
86
33.2M
    Py_XSETREF(self->args, Py_NewRef(args));
87
33.2M
    return 0;
88
33.2M
}
89
90
91
static PyObject *
92
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
93
                         size_t nargsf, PyObject *kwnames)
94
16.0M
{
95
16.0M
    PyTypeObject *type = _PyType_CAST(type_obj);
96
16.0M
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
97
0
        return NULL;
98
0
    }
99
100
16.0M
    PyBaseExceptionObject *self;
101
16.0M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
102
16.0M
    if (!self) {
103
0
        return NULL;
104
0
    }
105
106
    // The dict is created on the fly in PyObject_GenericSetAttr()
107
16.0M
    self->dict = NULL;
108
16.0M
    self->notes = NULL;
109
16.0M
    self->traceback = NULL;
110
16.0M
    self->cause = NULL;
111
16.0M
    self->context = NULL;
112
16.0M
    self->suppress_context = 0;
113
114
16.0M
    self->args = PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
115
16.0M
    if (!self->args) {
116
0
        Py_DECREF(self);
117
0
        return NULL;
118
0
    }
119
120
16.0M
    return (PyObject *)self;
121
16.0M
}
122
123
124
static int
125
BaseException_clear(PyObject *op)
126
50.9M
{
127
50.9M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
128
50.9M
    Py_CLEAR(self->dict);
129
50.9M
    Py_CLEAR(self->args);
130
50.9M
    Py_CLEAR(self->notes);
131
50.9M
    Py_CLEAR(self->traceback);
132
50.9M
    Py_CLEAR(self->cause);
133
50.9M
    Py_CLEAR(self->context);
134
50.9M
    return 0;
135
50.9M
}
136
137
static void
138
BaseException_dealloc(PyObject *op)
139
29.8M
{
140
29.8M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
141
29.8M
    PyObject_GC_UnTrack(self);
142
    // bpo-44348: The trashcan mechanism prevents stack overflow when deleting
143
    // long chains of exceptions. For example, exceptions can be chained
144
    // through the __context__ attributes or the __traceback__ attribute.
145
29.8M
    (void)BaseException_clear(op);
146
29.8M
    Py_TYPE(self)->tp_free(self);
147
29.8M
}
148
149
static int
150
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
151
16.8M
{
152
16.8M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
153
16.8M
    Py_VISIT(self->dict);
154
16.8M
    Py_VISIT(self->args);
155
16.8M
    Py_VISIT(self->notes);
156
16.8M
    Py_VISIT(self->traceback);
157
16.8M
    Py_VISIT(self->cause);
158
16.8M
    Py_VISIT(self->context);
159
16.8M
    return 0;
160
16.8M
}
161
162
static PyObject *
163
BaseException_str(PyObject *op)
164
5.45M
{
165
5.45M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
166
167
5.45M
    PyObject *res;
168
5.45M
    Py_BEGIN_CRITICAL_SECTION(self);
169
5.45M
    switch (PyTuple_GET_SIZE(self->args)) {
170
0
    case 0:
171
0
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
172
0
        break;
173
5.45M
    case 1:
174
5.45M
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
175
5.45M
        break;
176
0
    default:
177
0
        res = PyObject_Str(self->args);
178
0
        break;
179
5.45M
    }
180
5.45M
    Py_END_CRITICAL_SECTION();
181
5.45M
    return res;
182
5.45M
}
183
184
static PyObject *
185
BaseException_repr(PyObject *op)
186
4.83k
{
187
188
4.83k
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
189
190
4.83k
    PyObject *res;
191
4.83k
    Py_BEGIN_CRITICAL_SECTION(self);
192
4.83k
    const char *name = _PyType_Name(Py_TYPE(self));
193
4.83k
    if (PyTuple_GET_SIZE(self->args) == 1) {
194
4.83k
        res = PyUnicode_FromFormat("%s(%R)", name,
195
4.83k
                                    PyTuple_GET_ITEM(self->args, 0));
196
4.83k
    }
197
0
    else {
198
0
        res = PyUnicode_FromFormat("%s%R", name, self->args);
199
0
    }
200
4.83k
    Py_END_CRITICAL_SECTION();
201
4.83k
    return res;
202
4.83k
}
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
86.2k
{
293
86.2k
    PyObject *notes;
294
86.2k
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
295
0
        return NULL;
296
0
    }
297
86.2k
    if (notes == NULL) {
298
86.1k
        notes = PyList_New(0);
299
86.1k
        if (notes == NULL) {
300
0
            return NULL;
301
0
        }
302
86.1k
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
303
0
            Py_DECREF(notes);
304
0
            return NULL;
305
0
        }
306
86.1k
    }
307
61
    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
86.2k
    if (PyList_Append(notes, note) < 0) {
313
0
        Py_DECREF(notes);
314
0
        return NULL;
315
0
    }
316
86.2k
    Py_DECREF(notes);
317
86.2k
    Py_RETURN_NONE;
318
86.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
65.6M
{
394
65.6M
    if (value == NULL) {
395
0
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
396
0
        return -1;
397
0
    }
398
65.6M
    if (PyTraceBack_Check(value)) {
399
65.6M
        Py_XSETREF(self->traceback, Py_NewRef(value));
400
65.6M
    }
401
5.76k
    else if (value == Py_None) {
402
5.76k
        Py_CLEAR(self->traceback);
403
5.76k
    }
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
65.6M
    return 0;
410
65.6M
}
411
412
/*[clinic input]
413
@critical_section
414
@getter
415
BaseException.__context__
416
[clinic start generated code]*/
417
418
static PyObject *
419
BaseException___context___get_impl(PyBaseExceptionObject *self)
420
/*[clinic end generated code: output=6ec5d296ce8d1c93 input=b2d22687937e66ab]*/
421
0
{
422
0
    if (self->context == NULL) {
423
0
        Py_RETURN_NONE;
424
0
    }
425
0
    return Py_NewRef(self->context);
426
0
}
427
428
/*[clinic input]
429
@critical_section
430
@setter
431
BaseException.__context__
432
[clinic start generated code]*/
433
434
static int
435
BaseException___context___set_impl(PyBaseExceptionObject *self,
436
                                   PyObject *value)
437
/*[clinic end generated code: output=b4cb52dcca1da3bd input=c0971adf47fa1858]*/
438
0
{
439
0
    if (value == NULL) {
440
0
        PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
441
0
        return -1;
442
0
    } else if (value == Py_None) {
443
0
        value = NULL;
444
0
    } else if (!PyExceptionInstance_Check(value)) {
445
0
        PyErr_SetString(PyExc_TypeError, "exception context must be None "
446
0
                        "or derive from BaseException");
447
0
        return -1;
448
0
    } else {
449
0
        Py_INCREF(value);
450
0
    }
451
0
    Py_XSETREF(self->context, value);
452
0
    return 0;
453
0
}
454
455
/*[clinic input]
456
@critical_section
457
@getter
458
BaseException.__cause__
459
[clinic start generated code]*/
460
461
static PyObject *
462
BaseException___cause___get_impl(PyBaseExceptionObject *self)
463
/*[clinic end generated code: output=987f6c4d8a0bdbab input=40e0eac427b6e602]*/
464
0
{
465
0
    if (self->cause == NULL) {
466
0
        Py_RETURN_NONE;
467
0
    }
468
0
    return Py_NewRef(self->cause);
469
0
}
470
471
/*[clinic input]
472
@critical_section
473
@setter
474
BaseException.__cause__
475
[clinic start generated code]*/
476
477
static int
478
BaseException___cause___set_impl(PyBaseExceptionObject *self,
479
                                 PyObject *value)
480
/*[clinic end generated code: output=6161315398aaf541 input=e1b403c0bde3f62a]*/
481
0
{
482
0
    if (value == NULL) {
483
0
        PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
484
0
        return -1;
485
0
    } else if (value == Py_None) {
486
0
        value = NULL;
487
0
    } else if (!PyExceptionInstance_Check(value)) {
488
0
        PyErr_SetString(PyExc_TypeError, "exception cause must be None "
489
0
                        "or derive from BaseException");
490
0
        return -1;
491
0
    } else {
492
        /* PyException_SetCause steals this reference */
493
0
        Py_INCREF(value);
494
0
    }
495
0
    PyException_SetCause((PyObject *)self, value);
496
0
    return 0;
497
0
}
498
499
500
static PyGetSetDef BaseException_getset[] = {
501
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
502
     BASEEXCEPTION_ARGS_GETSETDEF
503
     BASEEXCEPTION___TRACEBACK___GETSETDEF
504
     BASEEXCEPTION___CONTEXT___GETSETDEF
505
     BASEEXCEPTION___CAUSE___GETSETDEF
506
    {NULL},
507
};
508
509
510
PyObject *
511
PyException_GetTraceback(PyObject *self)
512
107M
{
513
107M
    PyObject *traceback;
514
107M
    Py_BEGIN_CRITICAL_SECTION(self);
515
107M
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
516
107M
    Py_END_CRITICAL_SECTION();
517
107M
    return traceback;
518
107M
}
519
520
521
int
522
PyException_SetTraceback(PyObject *self, PyObject *tb)
523
65.6M
{
524
65.6M
    int res;
525
65.6M
    Py_BEGIN_CRITICAL_SECTION(self);
526
65.6M
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
527
65.6M
    Py_END_CRITICAL_SECTION();
528
65.6M
    return res;
529
65.6M
}
530
531
PyObject *
532
PyException_GetCause(PyObject *self)
533
0
{
534
0
    PyObject *cause;
535
0
    Py_BEGIN_CRITICAL_SECTION(self);
536
0
    cause = Py_XNewRef(PyBaseExceptionObject_CAST(self)->cause);
537
0
    Py_END_CRITICAL_SECTION();
538
0
    return cause;
539
0
}
540
541
/* Steals a reference to cause */
542
void
543
PyException_SetCause(PyObject *self, PyObject *cause)
544
9.14k
{
545
9.14k
    Py_BEGIN_CRITICAL_SECTION(self);
546
9.14k
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
547
9.14k
    base_self->suppress_context = 1;
548
9.14k
    Py_XSETREF(base_self->cause, cause);
549
9.14k
    Py_END_CRITICAL_SECTION();
550
9.14k
}
551
552
PyObject *
553
PyException_GetContext(PyObject *self)
554
5.87M
{
555
5.87M
    PyObject *context;
556
5.87M
    Py_BEGIN_CRITICAL_SECTION(self);
557
5.87M
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
558
5.87M
    Py_END_CRITICAL_SECTION();
559
5.87M
    return context;
560
5.87M
}
561
562
/* Steals a reference to context */
563
void
564
PyException_SetContext(PyObject *self, PyObject *context)
565
5.16M
{
566
5.16M
    Py_BEGIN_CRITICAL_SECTION(self);
567
5.16M
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
568
5.16M
    Py_END_CRITICAL_SECTION();
569
5.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.2M
{
741
29.2M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
742
29.2M
    return (PyStopIterationObject *)self;
743
29.2M
}
744
745
static int
746
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
747
14.6M
{
748
14.6M
    Py_ssize_t size = PyTuple_GET_SIZE(args);
749
14.6M
    PyObject *value;
750
751
14.6M
    if (BaseException_init(op, args, kwds) == -1)
752
0
        return -1;
753
14.6M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
754
14.6M
    Py_CLEAR(self->value);
755
14.6M
    if (size > 0)
756
2.10k
        value = PyTuple_GET_ITEM(args, 0);
757
14.6M
    else
758
14.6M
        value = Py_None;
759
14.6M
    self->value = Py_NewRef(value);
760
14.6M
    return 0;
761
14.6M
}
762
763
static int
764
StopIteration_clear(PyObject *op)
765
14.6M
{
766
14.6M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
767
14.6M
    Py_CLEAR(self->value);
768
14.6M
    return BaseException_clear(op);
769
14.6M
}
770
771
static void
772
StopIteration_dealloc(PyObject *self)
773
14.6M
{
774
14.6M
    PyObject_GC_UnTrack(self);
775
14.6M
    (void)StopIteration_clear(self);
776
14.6M
    Py_TYPE(self)->tp_free(self);
777
14.6M
}
778
779
static int
780
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
781
2
{
782
2
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
783
2
    Py_VISIT(self->value);
784
2
    return BaseException_traverse(op, visit, arg);
785
2
}
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
12.7k
{
1795
12.7k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
1796
12.7k
    return (PyImportErrorObject *)self;
1797
12.7k
}
1798
1799
static int
1800
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
1801
6.34k
{
1802
6.34k
    static char *kwlist[] = {"name", "path", "name_from", 0};
1803
6.34k
    PyObject *empty_tuple;
1804
6.34k
    PyObject *msg = NULL;
1805
6.34k
    PyObject *name = NULL;
1806
6.34k
    PyObject *path = NULL;
1807
6.34k
    PyObject *name_from = NULL;
1808
1809
6.34k
    if (BaseException_init(op, args, NULL) == -1)
1810
0
        return -1;
1811
1812
6.34k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1813
6.34k
    empty_tuple = PyTuple_New(0);
1814
6.34k
    if (!empty_tuple)
1815
0
        return -1;
1816
6.34k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
1817
6.34k
                                     &name, &path, &name_from)) {
1818
0
        Py_DECREF(empty_tuple);
1819
0
        return -1;
1820
0
    }
1821
6.34k
    Py_DECREF(empty_tuple);
1822
1823
6.34k
    Py_XSETREF(self->name, Py_XNewRef(name));
1824
6.34k
    Py_XSETREF(self->path, Py_XNewRef(path));
1825
6.34k
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));
1826
1827
6.34k
    if (PyTuple_GET_SIZE(args) == 1) {
1828
6.34k
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
1829
6.34k
    }
1830
6.34k
    Py_XSETREF(self->msg, msg);
1831
1832
6.34k
    return 0;
1833
6.34k
}
1834
1835
static int
1836
ImportError_clear(PyObject *op)
1837
6.34k
{
1838
6.34k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1839
6.34k
    Py_CLEAR(self->msg);
1840
6.34k
    Py_CLEAR(self->name);
1841
6.34k
    Py_CLEAR(self->path);
1842
6.34k
    Py_CLEAR(self->name_from);
1843
6.34k
    return BaseException_clear(op);
1844
6.34k
}
1845
1846
static void
1847
ImportError_dealloc(PyObject *self)
1848
6.34k
{
1849
6.34k
    _PyObject_GC_UNTRACK(self);
1850
6.34k
    (void)ImportError_clear(self);
1851
6.34k
    Py_TYPE(self)->tp_free(self);
1852
6.34k
}
1853
1854
static int
1855
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
1856
86
{
1857
86
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1858
86
    Py_VISIT(self->msg);
1859
86
    Py_VISIT(self->name);
1860
86
    Py_VISIT(self->path);
1861
86
    Py_VISIT(self->name_from);
1862
86
    return BaseException_traverse(op, visit, arg);
1863
86
}
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
643k
{
2037
643k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
2038
643k
    return (PyOSErrorObject *)self;
2039
643k
}
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
321k
{
2071
321k
    Py_ssize_t nargs;
2072
321k
    PyObject *args = *p_args;
2073
321k
#ifndef MS_WINDOWS
2074
    /*
2075
     * ignored on non-Windows platforms,
2076
     * but parsed so OSError has a consistent signature
2077
     */
2078
321k
    PyObject *_winerror = NULL;
2079
321k
    PyObject **winerror = &_winerror;
2080
321k
#endif /* MS_WINDOWS */
2081
2082
321k
    nargs = PyTuple_GET_SIZE(args);
2083
2084
321k
    if (nargs >= 2 && nargs <= 5) {
2085
319k
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
2086
319k
                               myerrno, strerror,
2087
319k
                               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
319k
    }
2115
2116
321k
    return 0;
2117
321k
}
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
321k
{
2128
321k
    PyObject *args = *p_args;
2129
321k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
2130
2131
    /* self->filename will remain Py_None otherwise */
2132
321k
    if (filename && filename != Py_None) {
2133
319k
        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
319k
        else {
2143
319k
            self->filename = Py_NewRef(filename);
2144
2145
319k
            if (filename2 && filename2 != Py_None) {
2146
0
                self->filename2 = Py_NewRef(filename2);
2147
0
            }
2148
2149
319k
            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
319k
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
2153
319k
                if (!subslice)
2154
0
                    return -1;
2155
2156
319k
                Py_DECREF(args);  /* replacing args */
2157
319k
                *p_args = args = subslice;
2158
319k
            }
2159
319k
        }
2160
319k
    }
2161
321k
    self->myerrno = Py_XNewRef(myerrno);
2162
321k
    self->strerror = Py_XNewRef(strerror);
2163
#ifdef MS_WINDOWS
2164
    self->winerror = Py_XNewRef(winerror);
2165
#endif
2166
2167
    /* Steals the reference to args */
2168
321k
    Py_XSETREF(self->args, args);
2169
321k
    *p_args = args = NULL;
2170
2171
321k
    return 0;
2172
321k
}
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
964k
{
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
964k
    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
964k
    return 0;
2197
964k
}
2198
2199
static PyObject *
2200
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2201
321k
{
2202
321k
    PyOSErrorObject *self = NULL;
2203
321k
    PyObject *myerrno = NULL, *strerror = NULL;
2204
321k
    PyObject *filename = NULL, *filename2 = NULL;
2205
#ifdef MS_WINDOWS
2206
    PyObject *winerror = NULL;
2207
#endif
2208
2209
321k
    Py_INCREF(args);
2210
2211
321k
    if (!oserror_use_init(type)) {
2212
321k
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
2213
0
            goto error;
2214
2215
321k
        if (oserror_parse_args(&args, &myerrno, &strerror,
2216
321k
                               &filename, &filename2
2217
#ifdef MS_WINDOWS
2218
                               , &winerror
2219
#endif
2220
321k
            ))
2221
0
            goto error;
2222
2223
321k
        struct _Py_exc_state *state = get_exc_state();
2224
321k
        if (myerrno && PyLong_Check(myerrno) &&
2225
319k
            state->errnomap && (PyObject *) type == PyExc_OSError) {
2226
319k
            PyObject *newtype;
2227
319k
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
2228
319k
            if (newtype) {
2229
281k
                type = _PyType_CAST(newtype);
2230
281k
            }
2231
38.1k
            else if (PyErr_Occurred())
2232
0
                goto error;
2233
319k
        }
2234
321k
    }
2235
2236
321k
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
2237
321k
    if (!self)
2238
0
        goto error;
2239
2240
321k
    self->dict = NULL;
2241
321k
    self->traceback = self->cause = self->context = NULL;
2242
321k
    self->written = -1;
2243
2244
321k
    if (!oserror_use_init(type)) {
2245
321k
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2246
#ifdef MS_WINDOWS
2247
                         , winerror
2248
#endif
2249
321k
            ))
2250
0
            goto error;
2251
321k
    }
2252
54
    else {
2253
54
        self->args = PyTuple_New(0);
2254
54
        if (self->args == NULL)
2255
0
            goto error;
2256
54
    }
2257
2258
321k
    Py_XDECREF(args);
2259
321k
    return (PyObject *) self;
2260
2261
0
error:
2262
0
    Py_XDECREF(args);
2263
0
    Py_XDECREF(self);
2264
0
    return NULL;
2265
321k
}
2266
2267
static int
2268
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
2269
321k
{
2270
321k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2271
321k
    PyObject *myerrno = NULL, *strerror = NULL;
2272
321k
    PyObject *filename = NULL, *filename2 = NULL;
2273
#ifdef MS_WINDOWS
2274
    PyObject *winerror = NULL;
2275
#endif
2276
2277
321k
    if (!oserror_use_init(Py_TYPE(self)))
2278
        /* Everything already done in OSError_new */
2279
321k
        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
321k
{
2309
321k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2310
321k
    Py_CLEAR(self->myerrno);
2311
321k
    Py_CLEAR(self->strerror);
2312
321k
    Py_CLEAR(self->filename);
2313
321k
    Py_CLEAR(self->filename2);
2314
#ifdef MS_WINDOWS
2315
    Py_CLEAR(self->winerror);
2316
#endif
2317
321k
    return BaseException_clear(op);
2318
321k
}
2319
2320
static void
2321
OSError_dealloc(PyObject *self)
2322
321k
{
2323
321k
    _PyObject_GC_UNTRACK(self);
2324
321k
    (void)OSError_clear(self);
2325
321k
    Py_TYPE(self)->tp_free(self);
2326
321k
}
2327
2328
static int
2329
OSError_traverse(PyObject *op, visitproc visit, void *arg)
2330
12
{
2331
12
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2332
12
    Py_VISIT(self->myerrno);
2333
12
    Py_VISIT(self->strerror);
2334
12
    Py_VISIT(self->filename);
2335
12
    Py_VISIT(self->filename2);
2336
#ifdef MS_WINDOWS
2337
    Py_VISIT(self->winerror);
2338
#endif
2339
12
    return BaseException_traverse(op, visit, arg);
2340
12
}
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
5.91M
{
2655
5.91M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
2656
5.91M
    return (PyAttributeErrorObject *)self;
2657
5.91M
}
2658
2659
static int
2660
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
2661
2.95M
{
2662
2.95M
    static char *kwlist[] = {"name", "obj", NULL};
2663
2.95M
    PyObject *name = NULL;
2664
2.95M
    PyObject *obj = NULL;
2665
2666
2.95M
    if (BaseException_init(op, args, NULL) == -1) {
2667
0
        return -1;
2668
0
    }
2669
2670
2.95M
    PyObject *empty_tuple = PyTuple_New(0);
2671
2.95M
    if (!empty_tuple) {
2672
0
        return -1;
2673
0
    }
2674
2.95M
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2675
2.95M
                                     &name, &obj)) {
2676
0
        Py_DECREF(empty_tuple);
2677
0
        return -1;
2678
0
    }
2679
2.95M
    Py_DECREF(empty_tuple);
2680
2681
2.95M
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2682
2.95M
    Py_XSETREF(self->name, Py_XNewRef(name));
2683
2.95M
    Py_XSETREF(self->obj, Py_XNewRef(obj));
2684
2685
2.95M
    return 0;
2686
2.95M
}
2687
2688
static int
2689
AttributeError_clear(PyObject *op)
2690
2.95M
{
2691
2.95M
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2692
2.95M
    Py_CLEAR(self->obj);
2693
2.95M
    Py_CLEAR(self->name);
2694
2.95M
    return BaseException_clear(op);
2695
2.95M
}
2696
2697
static void
2698
AttributeError_dealloc(PyObject *self)
2699
2.95M
{
2700
2.95M
    _PyObject_GC_UNTRACK(self);
2701
2.95M
    (void)AttributeError_clear(self);
2702
2.95M
    Py_TYPE(self)->tp_free(self);
2703
2.95M
}
2704
2705
static int
2706
AttributeError_traverse(PyObject *op, visitproc visit, void *arg)
2707
1.48k
{
2708
1.48k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2709
1.48k
    Py_VISIT(self->obj);
2710
1.48k
    Py_VISIT(self->name);
2711
1.48k
    return BaseException_traverse(op, visit, arg);
2712
1.48k
}
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
233k
{
2782
233k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
2783
233k
    return (PySyntaxErrorObject *)self;
2784
233k
}
2785
2786
static int
2787
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
2788
116k
{
2789
116k
    PyObject *info = NULL;
2790
116k
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2791
2792
116k
    if (BaseException_init(op, args, kwds) == -1)
2793
0
        return -1;
2794
2795
116k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2796
116k
    if (lenargs >= 1) {
2797
116k
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
2798
116k
    }
2799
116k
    if (lenargs == 2) {
2800
96.3k
        info = PyTuple_GET_ITEM(args, 1);
2801
96.3k
        info = PySequence_Tuple(info);
2802
96.3k
        if (!info) {
2803
0
            return -1;
2804
0
        }
2805
2806
96.3k
        PyObject *filename, *lineno, *offset, *text;
2807
96.3k
        PyObject *end_lineno = NULL;
2808
96.3k
        PyObject *end_offset = NULL;
2809
96.3k
        PyObject *metadata = NULL;
2810
96.3k
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
2811
96.3k
                              &filename, &lineno,
2812
96.3k
                              &offset, &text,
2813
96.3k
                              &end_lineno, &end_offset, &metadata)) {
2814
0
            Py_DECREF(info);
2815
0
            return -1;
2816
0
        }
2817
2818
96.3k
        Py_XSETREF(self->filename, Py_NewRef(filename));
2819
96.3k
        Py_XSETREF(self->lineno, Py_NewRef(lineno));
2820
96.3k
        Py_XSETREF(self->offset, Py_NewRef(offset));
2821
96.3k
        Py_XSETREF(self->text, Py_NewRef(text));
2822
96.3k
        Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2823
96.3k
        Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
2824
96.3k
        Py_XSETREF(self->metadata, Py_XNewRef(metadata));
2825
96.3k
        Py_DECREF(info);
2826
2827
96.3k
        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
96.3k
    }
2832
116k
    return 0;
2833
116k
}
2834
2835
static int
2836
SyntaxError_clear(PyObject *op)
2837
116k
{
2838
116k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2839
116k
    Py_CLEAR(self->msg);
2840
116k
    Py_CLEAR(self->filename);
2841
116k
    Py_CLEAR(self->lineno);
2842
116k
    Py_CLEAR(self->offset);
2843
116k
    Py_CLEAR(self->end_lineno);
2844
116k
    Py_CLEAR(self->end_offset);
2845
116k
    Py_CLEAR(self->text);
2846
116k
    Py_CLEAR(self->print_file_and_line);
2847
116k
    Py_CLEAR(self->metadata);
2848
116k
    return BaseException_clear(op);
2849
116k
}
2850
2851
static void
2852
SyntaxError_dealloc(PyObject *self)
2853
116k
{
2854
116k
    _PyObject_GC_UNTRACK(self);
2855
116k
    (void)SyntaxError_clear(self);
2856
116k
    Py_TYPE(self)->tp_free(self);
2857
116k
}
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
614k
{
3063
614k
    assert(as_bytes == 0 || as_bytes == 1);
3064
614k
    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
614k
    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
614k
    return 0;
3077
614k
}
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
612k
{
3092
612k
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
3093
612k
    return rc < 0 ? NULL : Py_NewRef(attr);
3094
612k
}
3095
3096
3097
#define PyUnicodeError_Check(PTR)   \
3098
1.24M
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3099
#define PyUnicodeError_CAST(PTR)    \
3100
1.34M
    (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.24M
#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.24M
{
3126
1.24M
    assert(self != NULL);
3127
1.24M
    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.24M
    return 0;
3133
1.24M
}
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
284k
{
3161
284k
    assert(self != NULL);
3162
284k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3163
284k
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
3164
284k
}
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
243k
{
3187
243k
    assert(self != NULL);
3188
243k
    PyObject *value = PyUnicode_FromString(reason);
3189
243k
    if (value == NULL) {
3190
0
        return -1;
3191
0
    }
3192
243k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3193
243k
    Py_XSETREF(exc->reason, value);
3194
243k
    return 0;
3195
243k
}
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
243k
{
3206
243k
    assert(self != NULL);
3207
243k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3208
243k
    exc->start = start;
3209
243k
    return 0;
3210
243k
}
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
243k
{
3221
243k
    assert(self != NULL);
3222
243k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3223
243k
    exc->end = end;
3224
243k
    return 0;
3225
243k
}
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
98.8k
{
3241
98.8k
    assert(objlen >= 0);
3242
98.8k
    if (start < 0) {
3243
0
        start = 0;
3244
0
    }
3245
98.8k
    if (start >= objlen) {
3246
0
        start = objlen == 0 ? 0 : objlen - 1;
3247
0
    }
3248
98.8k
    return start;
3249
98.8k
}
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
327k
{
3282
327k
    assert(objlen >= 0);
3283
327k
    if (end < 1) {
3284
0
        end = 1;
3285
0
    }
3286
327k
    if (end > objlen) {
3287
0
        end = objlen;
3288
0
    }
3289
327k
    return end;
3290
327k
}
3291
3292
#define PyUnicodeError_Check(PTR)   \
3293
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3294
#define PyUnicodeErrorObject_CAST(op)   \
3295
6.30M
    (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
98.8k
{
3328
98.8k
    assert_adjusted_unicode_error_start(start, objlen);
3329
98.8k
    assert_adjusted_unicode_error_end(end, objlen);
3330
98.8k
    Py_ssize_t ranlen = end - start;
3331
98.8k
    assert(ranlen <= objlen);
3332
98.8k
    return ranlen < 0 ? 0 : ranlen;
3333
98.8k
}
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
327k
{
3384
327k
    assert(self != NULL);
3385
327k
    assert(as_bytes == 0 || as_bytes == 1);
3386
327k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3387
327k
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
3388
327k
    if (r == NULL) {
3389
0
        return -1;
3390
0
    }
3391
3392
327k
    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
3393
327k
    if (objlen != NULL) {
3394
8
        *objlen = n;
3395
8
    }
3396
3397
327k
    Py_ssize_t start_value = -1;
3398
327k
    if (start != NULL || slen != NULL) {
3399
98.8k
        start_value = unicode_error_adjust_start(exc->start, n);
3400
98.8k
    }
3401
327k
    if (start != NULL) {
3402
98.8k
        assert_adjusted_unicode_error_start(start_value, n);
3403
98.8k
        *start = start_value;
3404
98.8k
    }
3405
3406
327k
    Py_ssize_t end_value = -1;
3407
327k
    if (end != NULL || slen != NULL) {
3408
327k
        end_value = unicode_error_adjust_end(exc->end, n);
3409
327k
    }
3410
327k
    if (end != NULL) {
3411
327k
        assert_adjusted_unicode_error_end(end_value, n);
3412
327k
        *end = end_value;
3413
327k
    }
3414
3415
327k
    if (slen != NULL) {
3416
98.8k
        *slen = unicode_error_adjust_len(start_value, end_value, n);
3417
98.8k
        assert_adjusted_unicode_error_len(*slen, n);
3418
98.8k
    }
3419
3420
327k
    if (obj != NULL) {
3421
98.8k
        *obj = r;
3422
98.8k
    }
3423
228k
    else {
3424
228k
        Py_DECREF(r);
3425
228k
    }
3426
327k
    return 0;
3427
327k
}
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
284k
{
3462
284k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3463
284k
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
3464
284k
}
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
243k
{
3530
243k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3531
243k
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3532
243k
}
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
243k
{
3598
243k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3599
243k
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3600
243k
}
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
243k
{
3650
243k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3651
243k
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3652
243k
}
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.15M
{
3666
3.15M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3667
3.15M
    Py_CLEAR(exc->encoding);
3668
3.15M
    Py_CLEAR(exc->object);
3669
3.15M
    Py_CLEAR(exc->reason);
3670
3.15M
    return BaseException_clear(self);
3671
3.15M
}
3672
3673
static void
3674
UnicodeError_dealloc(PyObject *self)
3675
3.15M
{
3676
3.15M
    PyTypeObject *type = Py_TYPE(self);
3677
3.15M
    _PyObject_GC_UNTRACK(self);
3678
3.15M
    (void)UnicodeError_clear(self);
3679
3.15M
    type->tp_free(self);
3680
3.15M
}
3681
3682
static int
3683
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
3684
356
{
3685
356
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3686
356
    Py_VISIT(exc->encoding);
3687
356
    Py_VISIT(exc->object);
3688
356
    Py_VISIT(exc->reason);
3689
356
    return BaseException_traverse(self, visit, arg);
3690
356
}
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
741k
{
3714
741k
    if (BaseException_init(self, args, kwds) == -1) {
3715
0
        return -1;
3716
0
    }
3717
3718
741k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3719
741k
    Py_ssize_t start = -1, end = -1;
3720
3721
741k
    if (!PyArg_ParseTuple(args, "UUnnU",
3722
741k
                          &encoding, &object, &start, &end, &reason))
3723
0
    {
3724
0
        return -1;
3725
0
    }
3726
3727
741k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3728
741k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3729
741k
    Py_XSETREF(exc->object, Py_NewRef(object));
3730
741k
    exc->start = start;
3731
741k
    exc->end = end;
3732
741k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3733
741k
    return 0;
3734
741k
}
3735
3736
static PyObject *
3737
UnicodeEncodeError_str(PyObject *self)
3738
54
{
3739
54
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3740
54
    PyObject *result = NULL;
3741
54
    PyObject *reason_str = NULL;
3742
54
    PyObject *encoding_str = NULL;
3743
3744
54
    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
54
    reason_str = PyObject_Str(exc->reason);
3752
54
    if (reason_str == NULL) {
3753
0
        goto done;
3754
0
    }
3755
54
    encoding_str = PyObject_Str(exc->encoding);
3756
54
    if (encoding_str == NULL) {
3757
0
        goto done;
3758
0
    }
3759
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3760
54
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3761
0
        goto done;
3762
0
    }
3763
54
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3764
54
    Py_ssize_t start = exc->start, end = exc->end;
3765
3766
54
    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
21
    else {
3786
21
        result = PyUnicode_FromFormat(
3787
21
            "'%U' codec can't encode characters in position %zd-%zd: %U",
3788
21
            encoding_str,
3789
21
            start,
3790
21
            end - 1,
3791
21
            reason_str);
3792
21
    }
3793
54
done:
3794
54
    Py_XDECREF(reason_str);
3795
54
    Py_XDECREF(encoding_str);
3796
54
    return result;
3797
54
}
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
2.41M
{
3821
2.41M
    if (BaseException_init(self, args, kwds) == -1) {
3822
0
        return -1;
3823
0
    }
3824
3825
2.41M
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3826
2.41M
    Py_ssize_t start = -1, end = -1;
3827
3828
2.41M
    if (!PyArg_ParseTuple(args, "UOnnU",
3829
2.41M
                          &encoding, &object, &start, &end, &reason))
3830
134
    {
3831
134
        return -1;
3832
134
    }
3833
3834
2.40M
    if (PyBytes_Check(object)) {
3835
2.40M
        Py_INCREF(object);  // make 'object' a strong reference
3836
2.40M
    }
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
2.40M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3851
2.40M
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3852
2.40M
    Py_XSETREF(exc->object, object /* already a strong reference */);
3853
2.40M
    exc->start = start;
3854
2.40M
    exc->end = end;
3855
2.40M
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3856
2.40M
    return 0;
3857
2.40M
}
3858
3859
static PyObject *
3860
UnicodeDecodeError_str(PyObject *self)
3861
1.79k
{
3862
1.79k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3863
1.79k
    PyObject *result = NULL;
3864
1.79k
    PyObject *reason_str = NULL;
3865
1.79k
    PyObject *encoding_str = NULL;
3866
3867
1.79k
    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.79k
    reason_str = PyObject_Str(exc->reason);
3875
1.79k
    if (reason_str == NULL) {
3876
0
        goto done;
3877
0
    }
3878
1.79k
    encoding_str = PyObject_Str(exc->encoding);
3879
1.79k
    if (encoding_str == NULL) {
3880
0
        goto done;
3881
0
    }
3882
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3883
1.79k
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
3884
0
        goto done;
3885
0
    }
3886
1.79k
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
3887
1.79k
    Py_ssize_t start = exc->start, end = exc->end;
3888
3889
1.79k
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3890
728
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
3891
728
        result = PyUnicode_FromFormat(
3892
728
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3893
728
            encoding_str,
3894
728
            badbyte,
3895
728
            start,
3896
728
            reason_str);
3897
728
    }
3898
1.06k
    else {
3899
1.06k
        result = PyUnicode_FromFormat(
3900
1.06k
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3901
1.06k
            encoding_str,
3902
1.06k
            start,
3903
1.06k
            end - 1,
3904
1.06k
            reason_str);
3905
1.06k
    }
3906
1.79k
done:
3907
1.79k
    Py_XDECREF(reason_str);
3908
1.79k
    Py_XDECREF(encoding_str);
3909
1.79k
    return result;
3910
1.79k
}
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
2.40M
{
3931
2.40M
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3932
2.40M
                                 encoding, object, length, start, end, reason);
3933
2.40M
}
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.85k
#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.26k
# define MEMERRORS_LOCK(state) ((void)0)
4104
1.26k
# define MEMERRORS_UNLOCK(state) ((void)0)
4105
#endif
4106
4107
static PyObject *
4108
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
4109
631
{
4110
631
    PyBaseExceptionObject *self = NULL;
4111
631
    struct _Py_exc_state *state = get_exc_state();
4112
4113
631
    MEMERRORS_LOCK(state);
4114
631
    if (state->memerrors_freelist != NULL) {
4115
        /* Fetch MemoryError from freelist and initialize it */
4116
55
        self = state->memerrors_freelist;
4117
55
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
4118
55
        state->memerrors_numfree--;
4119
55
        self->dict = NULL;
4120
55
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
4121
55
        _Py_NewReference((PyObject *)self);
4122
55
        _PyObject_GC_TRACK(self);
4123
55
    }
4124
631
    MEMERRORS_UNLOCK(state);
4125
4126
631
    if (self != NULL) {
4127
55
        return (PyObject *)self;
4128
55
    }
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
631
{
4141
    /* If this is a subclass of MemoryError, don't use the freelist
4142
     * and just return a fresh object */
4143
631
    if (type != (PyTypeObject *) PyExc_MemoryError) {
4144
0
        return BaseException_new(type, args, kwds);
4145
0
    }
4146
631
    return get_memory_error(1, args, kwds);
4147
631
}
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
631
{
4168
631
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
4169
631
    _PyObject_GC_UNTRACK(self);
4170
4171
631
    (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
631
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
4176
0
        Py_TYPE(self)->tp_free(op);
4177
0
        return;
4178
0
    }
4179
4180
631
    struct _Py_exc_state *state = get_exc_state();
4181
631
    MEMERRORS_LOCK(state);
4182
631
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
4183
631
        self->dict = (PyObject *) state->memerrors_freelist;
4184
631
        state->memerrors_freelist = self;
4185
631
        state->memerrors_numfree++;
4186
631
        MEMERRORS_UNLOCK(state);
4187
631
        return;
4188
631
    }
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
86.2k
{
4644
86.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
86.2k
    PyObject *r = BaseException_add_note(exc, note);
4651
86.2k
    int res = r == NULL ? -1 : 0;
4652
86.2k
    Py_XDECREF(r);
4653
86.2k
    return res;
4654
86.2k
}