Coverage Report

Created: 2025-07-11 06:24

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