Coverage Report

Created: 2025-10-12 06:48

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