Coverage Report

Created: 2025-07-04 06:49

/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.8k
{
40
12.8k
    PyInterpreterState *interp = _PyInterpreterState_GET();
41
12.8k
    return &interp->exc_state;
42
12.8k
}
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
196M
{
52
196M
    assert(PyExceptionInstance_Check(exc));
53
196M
    return (PyBaseExceptionObject *)exc;
54
196M
}
55
56
/*
57
 *    BaseException
58
 */
59
static PyObject *
60
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
61
20.8M
{
62
20.8M
    PyBaseExceptionObject *self;
63
64
20.8M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
65
20.8M
    if (!self)
66
0
        return NULL;
67
    /* the dict is created on the fly in PyObject_GenericSetAttr */
68
20.8M
    self->dict = NULL;
69
20.8M
    self->notes = NULL;
70
20.8M
    self->traceback = self->cause = self->context = NULL;
71
20.8M
    self->suppress_context = 0;
72
73
20.8M
    if (args) {
74
20.8M
        self->args = Py_NewRef(args);
75
20.8M
        return (PyObject *)self;
76
20.8M
    }
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
19.4M
{
90
19.4M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
91
19.4M
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
92
0
        return -1;
93
94
19.4M
    Py_XSETREF(self->args, Py_NewRef(args));
95
19.4M
    return 0;
96
19.4M
}
97
98
99
static PyObject *
100
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
101
                         size_t nargsf, PyObject *kwnames)
102
19.1M
{
103
19.1M
    PyTypeObject *type = _PyType_CAST(type_obj);
104
19.1M
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
105
0
        return NULL;
106
0
    }
107
108
19.1M
    PyBaseExceptionObject *self;
109
19.1M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
110
19.1M
    if (!self) {
111
0
        return NULL;
112
0
    }
113
114
    // The dict is created on the fly in PyObject_GenericSetAttr()
115
19.1M
    self->dict = NULL;
116
19.1M
    self->notes = NULL;
117
19.1M
    self->traceback = NULL;
118
19.1M
    self->cause = NULL;
119
19.1M
    self->context = NULL;
120
19.1M
    self->suppress_context = 0;
121
122
19.1M
    self->args = _PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
123
19.1M
    if (!self->args) {
124
0
        Py_DECREF(self);
125
0
        return NULL;
126
0
    }
127
128
19.1M
    return (PyObject *)self;
129
19.1M
}
130
131
132
static int
133
BaseException_clear(PyObject *op)
134
40.0M
{
135
40.0M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
136
40.0M
    Py_CLEAR(self->dict);
137
40.0M
    Py_CLEAR(self->args);
138
40.0M
    Py_CLEAR(self->notes);
139
40.0M
    Py_CLEAR(self->traceback);
140
40.0M
    Py_CLEAR(self->cause);
141
40.0M
    Py_CLEAR(self->context);
142
40.0M
    return 0;
143
40.0M
}
144
145
static void
146
BaseException_dealloc(PyObject *op)
147
27.4M
{
148
27.4M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
149
27.4M
    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
27.4M
    (void)BaseException_clear(op);
154
27.4M
    Py_TYPE(self)->tp_free(self);
155
27.4M
}
156
157
static int
158
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
159
10.1M
{
160
10.1M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
161
10.1M
    Py_VISIT(self->dict);
162
10.1M
    Py_VISIT(self->args);
163
10.1M
    Py_VISIT(self->notes);
164
10.1M
    Py_VISIT(self->traceback);
165
10.1M
    Py_VISIT(self->cause);
166
10.1M
    Py_VISIT(self->context);
167
10.1M
    return 0;
168
10.1M
}
169
170
static PyObject *
171
BaseException_str(PyObject *op)
172
194
{
173
194
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
174
175
194
    PyObject *res;
176
194
    Py_BEGIN_CRITICAL_SECTION(self);
177
194
    switch (PyTuple_GET_SIZE(self->args)) {
178
0
    case 0:
179
0
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
180
0
        break;
181
194
    case 1:
182
194
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
183
194
        break;
184
0
    default:
185
0
        res = PyObject_Str(self->args);
186
0
        break;
187
194
    }
188
194
    Py_END_CRITICAL_SECTION();
189
194
    return res;
190
194
}
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
46.2k
{
301
46.2k
    PyObject *notes;
302
46.2k
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
303
0
        return NULL;
304
0
    }
305
46.2k
    if (notes == NULL) {
306
46.1k
        notes = PyList_New(0);
307
46.1k
        if (notes == NULL) {
308
0
            return NULL;
309
0
        }
310
46.1k
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
311
0
            Py_DECREF(notes);
312
0
            return NULL;
313
0
        }
314
46.1k
    }
315
66
    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
46.2k
    if (PyList_Append(notes, note) < 0) {
321
0
        Py_DECREF(notes);
322
0
        return NULL;
323
0
    }
324
46.2k
    Py_DECREF(notes);
325
46.2k
    Py_RETURN_NONE;
326
46.2k
}
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
963
{
362
963
    PyObject *seq;
363
963
    if (value == NULL) {
364
0
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
365
0
        return -1;
366
0
    }
367
963
    seq = PySequence_Tuple(value);
368
963
    if (!seq)
369
0
        return -1;
370
963
    Py_XSETREF(self->args, seq);
371
963
    return 0;
372
963
}
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
33.4M
{
402
33.4M
    if (value == NULL) {
403
0
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
404
0
        return -1;
405
0
    }
406
33.4M
    if (PyTraceBack_Check(value)) {
407
33.4M
        Py_XSETREF(self->traceback, Py_NewRef(value));
408
33.4M
    }
409
1.51k
    else if (value == Py_None) {
410
1.51k
        Py_CLEAR(self->traceback);
411
1.51k
    }
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
33.4M
    return 0;
418
33.4M
}
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
65.6M
{
521
65.6M
    PyObject *traceback;
522
65.6M
    Py_BEGIN_CRITICAL_SECTION(self);
523
65.6M
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
524
65.6M
    Py_END_CRITICAL_SECTION();
525
65.6M
    return traceback;
526
65.6M
}
527
528
529
int
530
PyException_SetTraceback(PyObject *self, PyObject *tb)
531
33.4M
{
532
33.4M
    int res;
533
33.4M
    Py_BEGIN_CRITICAL_SECTION(self);
534
33.4M
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
535
33.4M
    Py_END_CRITICAL_SECTION();
536
33.4M
    return res;
537
33.4M
}
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.55k
{
553
2.55k
    Py_BEGIN_CRITICAL_SECTION(self);
554
2.55k
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
555
2.55k
    base_self->suppress_context = 1;
556
2.55k
    Py_XSETREF(base_self->cause, cause);
557
2.55k
    Py_END_CRITICAL_SECTION();
558
2.55k
}
559
560
PyObject *
561
PyException_GetContext(PyObject *self)
562
367k
{
563
367k
    PyObject *context;
564
367k
    Py_BEGIN_CRITICAL_SECTION(self);
565
367k
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
566
367k
    Py_END_CRITICAL_SECTION();
567
367k
    return context;
568
367k
}
569
570
/* Steals a reference to context */
571
void
572
PyException_SetContext(PyObject *self, PyObject *context)
573
266k
{
574
266k
    Py_BEGIN_CRITICAL_SECTION(self);
575
266k
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
576
266k
    Py_END_CRITICAL_SECTION();
577
266k
}
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
24.5M
{
749
24.5M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
750
24.5M
    return (PyStopIterationObject *)self;
751
24.5M
}
752
753
static int
754
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
755
12.2M
{
756
12.2M
    Py_ssize_t size = PyTuple_GET_SIZE(args);
757
12.2M
    PyObject *value;
758
759
12.2M
    if (BaseException_init(op, args, kwds) == -1)
760
0
        return -1;
761
12.2M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
762
12.2M
    Py_CLEAR(self->value);
763
12.2M
    if (size > 0)
764
1.97k
        value = PyTuple_GET_ITEM(args, 0);
765
12.2M
    else
766
12.2M
        value = Py_None;
767
12.2M
    self->value = Py_NewRef(value);
768
12.2M
    return 0;
769
12.2M
}
770
771
static int
772
StopIteration_clear(PyObject *op)
773
12.2M
{
774
12.2M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
775
12.2M
    Py_CLEAR(self->value);
776
12.2M
    return BaseException_clear(op);
777
12.2M
}
778
779
static void
780
StopIteration_dealloc(PyObject *self)
781
12.2M
{
782
12.2M
    PyObject_GC_UnTrack(self);
783
12.2M
    (void)StopIteration_clear(self);
784
12.2M
    Py_TYPE(self)->tp_free(self);
785
12.2M
}
786
787
static int
788
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
789
27
{
790
27
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
791
27
    Py_VISIT(self->value);
792
27
    return BaseException_traverse(op, visit, arg);
793
27
}
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.77k
{
1739
3.77k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
1740
3.77k
    return (PyImportErrorObject *)self;
1741
3.77k
}
1742
1743
static int
1744
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
1745
1.88k
{
1746
1.88k
    static char *kwlist[] = {"name", "path", "name_from", 0};
1747
1.88k
    PyObject *empty_tuple;
1748
1.88k
    PyObject *msg = NULL;
1749
1.88k
    PyObject *name = NULL;
1750
1.88k
    PyObject *path = NULL;
1751
1.88k
    PyObject *name_from = NULL;
1752
1753
1.88k
    if (BaseException_init(op, args, NULL) == -1)
1754
0
        return -1;
1755
1756
1.88k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1757
1.88k
    empty_tuple = PyTuple_New(0);
1758
1.88k
    if (!empty_tuple)
1759
0
        return -1;
1760
1.88k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
1761
1.88k
                                     &name, &path, &name_from)) {
1762
0
        Py_DECREF(empty_tuple);
1763
0
        return -1;
1764
0
    }
1765
1.88k
    Py_DECREF(empty_tuple);
1766
1767
1.88k
    Py_XSETREF(self->name, Py_XNewRef(name));
1768
1.88k
    Py_XSETREF(self->path, Py_XNewRef(path));
1769
1.88k
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));
1770
1771
1.88k
    if (PyTuple_GET_SIZE(args) == 1) {
1772
1.88k
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
1773
1.88k
    }
1774
1.88k
    Py_XSETREF(self->msg, msg);
1775
1776
1.88k
    return 0;
1777
1.88k
}
1778
1779
static int
1780
ImportError_clear(PyObject *op)
1781
1.88k
{
1782
1.88k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1783
1.88k
    Py_CLEAR(self->msg);
1784
1.88k
    Py_CLEAR(self->name);
1785
1.88k
    Py_CLEAR(self->path);
1786
1.88k
    Py_CLEAR(self->name_from);
1787
1.88k
    return BaseException_clear(op);
1788
1.88k
}
1789
1790
static void
1791
ImportError_dealloc(PyObject *self)
1792
1.88k
{
1793
1.88k
    _PyObject_GC_UNTRACK(self);
1794
1.88k
    (void)ImportError_clear(self);
1795
1.88k
    Py_TYPE(self)->tp_free(self);
1796
1.88k
}
1797
1798
static int
1799
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
1800
1
{
1801
1
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1802
1
    Py_VISIT(self->msg);
1803
1
    Py_VISIT(self->name);
1804
1
    Py_VISIT(self->path);
1805
1
    Py_VISIT(self->name_from);
1806
1
    return BaseException_traverse(op, visit, arg);
1807
1
}
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.5k
{
1905
24.5k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
1906
24.5k
    return (PyOSErrorObject *)self;
1907
24.5k
}
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.2k
{
1939
12.2k
    Py_ssize_t nargs;
1940
12.2k
    PyObject *args = *p_args;
1941
12.2k
#ifndef MS_WINDOWS
1942
    /*
1943
     * ignored on non-Windows platforms,
1944
     * but parsed so OSError has a consistent signature
1945
     */
1946
12.2k
    PyObject *_winerror = NULL;
1947
12.2k
    PyObject **winerror = &_winerror;
1948
12.2k
#endif /* MS_WINDOWS */
1949
1950
12.2k
    nargs = PyTuple_GET_SIZE(args);
1951
1952
12.2k
    if (nargs >= 2 && nargs <= 5) {
1953
12.2k
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
1954
12.2k
                               myerrno, strerror,
1955
12.2k
                               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.2k
    }
1983
1984
12.2k
    return 0;
1985
12.2k
}
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.2k
{
1996
12.2k
    PyObject *args = *p_args;
1997
12.2k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1998
1999
    /* self->filename will remain Py_None otherwise */
2000
12.2k
    if (filename && filename != Py_None) {
2001
12.1k
        if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
2002
12.1k
            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.1k
        else {
2011
12.1k
            self->filename = Py_NewRef(filename);
2012
2013
12.1k
            if (filename2 && filename2 != Py_None) {
2014
0
                self->filename2 = Py_NewRef(filename2);
2015
0
            }
2016
2017
12.1k
            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.1k
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
2021
12.1k
                if (!subslice)
2022
0
                    return -1;
2023
2024
12.1k
                Py_DECREF(args);  /* replacing args */
2025
12.1k
                *p_args = args = subslice;
2026
12.1k
            }
2027
12.1k
        }
2028
12.1k
    }
2029
12.2k
    self->myerrno = Py_XNewRef(myerrno);
2030
12.2k
    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.2k
    Py_XSETREF(self->args, args);
2037
12.2k
    *p_args = args = NULL;
2038
2039
12.2k
    return 0;
2040
12.2k
}
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.7k
{
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.7k
    if (type->tp_init != OSError_init && type->tp_new == OSError_new) {
2061
156
        assert((PyObject *) type != PyExc_OSError);
2062
156
        return 1;
2063
156
    }
2064
36.6k
    return 0;
2065
36.7k
}
2066
2067
static PyObject *
2068
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2069
12.2k
{
2070
12.2k
    PyOSErrorObject *self = NULL;
2071
12.2k
    PyObject *myerrno = NULL, *strerror = NULL;
2072
12.2k
    PyObject *filename = NULL, *filename2 = NULL;
2073
#ifdef MS_WINDOWS
2074
    PyObject *winerror = NULL;
2075
#endif
2076
2077
12.2k
    Py_INCREF(args);
2078
2079
12.2k
    if (!oserror_use_init(type)) {
2080
12.2k
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
2081
0
            goto error;
2082
2083
12.2k
        if (oserror_parse_args(&args, &myerrno, &strerror,
2084
12.2k
                               &filename, &filename2
2085
#ifdef MS_WINDOWS
2086
                               , &winerror
2087
#endif
2088
12.2k
            ))
2089
0
            goto error;
2090
2091
12.2k
        struct _Py_exc_state *state = get_exc_state();
2092
12.2k
        if (myerrno && PyLong_Check(myerrno) &&
2093
12.2k
            state->errnomap && (PyObject *) type == PyExc_OSError) {
2094
12.2k
            PyObject *newtype;
2095
12.2k
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
2096
12.2k
            if (newtype) {
2097
12.2k
                type = _PyType_CAST(newtype);
2098
12.2k
            }
2099
0
            else if (PyErr_Occurred())
2100
0
                goto error;
2101
12.2k
        }
2102
12.2k
    }
2103
2104
12.2k
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
2105
12.2k
    if (!self)
2106
0
        goto error;
2107
2108
12.2k
    self->dict = NULL;
2109
12.2k
    self->traceback = self->cause = self->context = NULL;
2110
12.2k
    self->written = -1;
2111
2112
12.2k
    if (!oserror_use_init(type)) {
2113
12.2k
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2114
#ifdef MS_WINDOWS
2115
                         , winerror
2116
#endif
2117
12.2k
            ))
2118
0
            goto error;
2119
12.2k
    }
2120
52
    else {
2121
52
        self->args = PyTuple_New(0);
2122
52
        if (self->args == NULL)
2123
0
            goto error;
2124
52
    }
2125
2126
12.2k
    Py_XDECREF(args);
2127
12.2k
    return (PyObject *) self;
2128
2129
0
error:
2130
0
    Py_XDECREF(args);
2131
0
    Py_XDECREF(self);
2132
0
    return NULL;
2133
12.2k
}
2134
2135
static int
2136
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
2137
12.2k
{
2138
12.2k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2139
12.2k
    PyObject *myerrno = NULL, *strerror = NULL;
2140
12.2k
    PyObject *filename = NULL, *filename2 = NULL;
2141
#ifdef MS_WINDOWS
2142
    PyObject *winerror = NULL;
2143
#endif
2144
2145
12.2k
    if (!oserror_use_init(Py_TYPE(self)))
2146
        /* Everything already done in OSError_new */
2147
12.2k
        return 0;
2148
2149
52
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
2150
0
        return -1;
2151
2152
52
    Py_INCREF(args);
2153
52
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
2154
#ifdef MS_WINDOWS
2155
                           , &winerror
2156
#endif
2157
52
        ))
2158
0
        goto error;
2159
2160
52
    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2161
#ifdef MS_WINDOWS
2162
                     , winerror
2163
#endif
2164
52
        ))
2165
0
        goto error;
2166
2167
52
    return 0;
2168
2169
0
error:
2170
0
    Py_DECREF(args);
2171
0
    return -1;
2172
52
}
2173
2174
static int
2175
OSError_clear(PyObject *op)
2176
12.2k
{
2177
12.2k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2178
12.2k
    Py_CLEAR(self->myerrno);
2179
12.2k
    Py_CLEAR(self->strerror);
2180
12.2k
    Py_CLEAR(self->filename);
2181
12.2k
    Py_CLEAR(self->filename2);
2182
#ifdef MS_WINDOWS
2183
    Py_CLEAR(self->winerror);
2184
#endif
2185
12.2k
    return BaseException_clear(op);
2186
12.2k
}
2187
2188
static void
2189
OSError_dealloc(PyObject *self)
2190
12.2k
{
2191
12.2k
    _PyObject_GC_UNTRACK(self);
2192
12.2k
    (void)OSError_clear(self);
2193
12.2k
    Py_TYPE(self)->tp_free(self);
2194
12.2k
}
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.84k
{
2516
6.84k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
2517
6.84k
    return (PyAttributeErrorObject *)self;
2518
6.84k
}
2519
2520
static int
2521
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
2522
3.42k
{
2523
3.42k
    static char *kwlist[] = {"name", "obj", NULL};
2524
3.42k
    PyObject *name = NULL;
2525
3.42k
    PyObject *obj = NULL;
2526
2527
3.42k
    if (BaseException_init(op, args, NULL) == -1) {
2528
0
        return -1;
2529
0
    }
2530
2531
3.42k
    PyObject *empty_tuple = PyTuple_New(0);
2532
3.42k
    if (!empty_tuple) {
2533
0
        return -1;
2534
0
    }
2535
3.42k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2536
3.42k
                                     &name, &obj)) {
2537
0
        Py_DECREF(empty_tuple);
2538
0
        return -1;
2539
0
    }
2540
3.42k
    Py_DECREF(empty_tuple);
2541
2542
3.42k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2543
3.42k
    Py_XSETREF(self->name, Py_XNewRef(name));
2544
3.42k
    Py_XSETREF(self->obj, Py_XNewRef(obj));
2545
2546
3.42k
    return 0;
2547
3.42k
}
2548
2549
static int
2550
AttributeError_clear(PyObject *op)
2551
3.42k
{
2552
3.42k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2553
3.42k
    Py_CLEAR(self->obj);
2554
3.42k
    Py_CLEAR(self->name);
2555
3.42k
    return BaseException_clear(op);
2556
3.42k
}
2557
2558
static void
2559
AttributeError_dealloc(PyObject *self)
2560
3.42k
{
2561
3.42k
    _PyObject_GC_UNTRACK(self);
2562
3.42k
    (void)AttributeError_clear(self);
2563
3.42k
    Py_TYPE(self)->tp_free(self);
2564
3.42k
}
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
32.6k
{
2643
32.6k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
2644
32.6k
    return (PySyntaxErrorObject *)self;
2645
32.6k
}
2646
2647
static int
2648
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
2649
16.3k
{
2650
16.3k
    PyObject *info = NULL;
2651
16.3k
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2652
2653
16.3k
    if (BaseException_init(op, args, kwds) == -1)
2654
0
        return -1;
2655
2656
16.3k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2657
16.3k
    if (lenargs >= 1) {
2658
16.3k
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
2659
16.3k
    }
2660
16.3k
    if (lenargs == 2) {
2661
16.2k
        info = PyTuple_GET_ITEM(args, 1);
2662
16.2k
        info = PySequence_Tuple(info);
2663
16.2k
        if (!info) {
2664
0
            return -1;
2665
0
        }
2666
2667
16.2k
        self->end_lineno = NULL;
2668
16.2k
        self->end_offset = NULL;
2669
16.2k
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
2670
16.2k
                              &self->filename, &self->lineno,
2671
16.2k
                              &self->offset, &self->text,
2672
16.2k
                              &self->end_lineno, &self->end_offset, &self->metadata)) {
2673
0
            Py_DECREF(info);
2674
0
            return -1;
2675
0
        }
2676
2677
16.2k
        Py_INCREF(self->filename);
2678
16.2k
        Py_INCREF(self->lineno);
2679
16.2k
        Py_INCREF(self->offset);
2680
16.2k
        Py_INCREF(self->text);
2681
16.2k
        Py_XINCREF(self->end_lineno);
2682
16.2k
        Py_XINCREF(self->end_offset);
2683
16.2k
        Py_XINCREF(self->metadata);
2684
16.2k
        Py_DECREF(info);
2685
2686
16.2k
        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
16.2k
    }
2691
16.3k
    return 0;
2692
16.3k
}
2693
2694
static int
2695
SyntaxError_clear(PyObject *op)
2696
16.3k
{
2697
16.3k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2698
16.3k
    Py_CLEAR(self->msg);
2699
16.3k
    Py_CLEAR(self->filename);
2700
16.3k
    Py_CLEAR(self->lineno);
2701
16.3k
    Py_CLEAR(self->offset);
2702
16.3k
    Py_CLEAR(self->end_lineno);
2703
16.3k
    Py_CLEAR(self->end_offset);
2704
16.3k
    Py_CLEAR(self->text);
2705
16.3k
    Py_CLEAR(self->print_file_and_line);
2706
16.3k
    Py_CLEAR(self->metadata);
2707
16.3k
    return BaseException_clear(op);
2708
16.3k
}
2709
2710
static void
2711
SyntaxError_dealloc(PyObject *self)
2712
16.3k
{
2713
16.3k
    _PyObject_GC_UNTRACK(self);
2714
16.3k
    (void)SyntaxError_clear(self);
2715
16.3k
    Py_TYPE(self)->tp_free(self);
2716
16.3k
}
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
468k
{
2922
468k
    assert(as_bytes == 0 || as_bytes == 1);
2923
468k
    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
468k
    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
468k
    return 0;
2936
468k
}
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
465k
{
2951
465k
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
2952
465k
    return rc < 0 ? NULL : Py_NewRef(attr);
2953
465k
}
2954
2955
2956
#define PyUnicodeError_Check(PTR)   \
2957
1.02M
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
2958
#define PyUnicodeError_CAST(PTR)    \
2959
1.07M
    (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
1.02M
#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
1.02M
{
2985
1.02M
    assert(self != NULL);
2986
1.02M
    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
1.02M
    return 0;
2992
1.02M
}
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
222k
{
3020
222k
    assert(self != NULL);
3021
222k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3022
222k
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
3023
222k
}
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
201k
{
3046
201k
    assert(self != NULL);
3047
201k
    PyObject *value = PyUnicode_FromString(reason);
3048
201k
    if (value == NULL) {
3049
0
        return -1;
3050
0
    }
3051
201k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3052
201k
    Py_XSETREF(exc->reason, value);
3053
201k
    return 0;
3054
201k
}
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
201k
{
3065
201k
    assert(self != NULL);
3066
201k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3067
201k
    exc->start = start;
3068
201k
    return 0;
3069
201k
}
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
201k
{
3080
201k
    assert(self != NULL);
3081
201k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3082
201k
    exc->end = end;
3083
201k
    return 0;
3084
201k
}
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
48.9k
{
3100
48.9k
    assert(objlen >= 0);
3101
48.9k
    if (start < 0) {
3102
0
        start = 0;
3103
0
    }
3104
48.9k
    if (start >= objlen) {
3105
0
        start = objlen == 0 ? 0 : objlen - 1;
3106
0
    }
3107
48.9k
    return start;
3108
48.9k
}
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
243k
{
3141
243k
    assert(objlen >= 0);
3142
243k
    if (end < 1) {
3143
0
        end = 1;
3144
0
    }
3145
243k
    if (end > objlen) {
3146
0
        end = objlen;
3147
0
    }
3148
243k
    return end;
3149
243k
}
3150
3151
#define PyUnicodeError_Check(PTR)   \
3152
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3153
#define PyUnicodeErrorObject_CAST(op)   \
3154
492k
    (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
48.9k
{
3187
48.9k
    assert_adjusted_unicode_error_start(start, objlen);
3188
48.9k
    assert_adjusted_unicode_error_end(end, objlen);
3189
48.9k
    Py_ssize_t ranlen = end - start;
3190
48.9k
    assert(ranlen <= objlen);
3191
48.9k
    return ranlen < 0 ? 0 : ranlen;
3192
48.9k
}
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
243k
{
3243
243k
    assert(self != NULL);
3244
243k
    assert(as_bytes == 0 || as_bytes == 1);
3245
243k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3246
243k
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
3247
243k
    if (r == NULL) {
3248
0
        return -1;
3249
0
    }
3250
3251
243k
    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
3252
243k
    if (objlen != NULL) {
3253
0
        *objlen = n;
3254
0
    }
3255
3256
243k
    Py_ssize_t start_value = -1;
3257
243k
    if (start != NULL || slen != NULL) {
3258
48.9k
        start_value = unicode_error_adjust_start(exc->start, n);
3259
48.9k
    }
3260
243k
    if (start != NULL) {
3261
48.9k
        assert_adjusted_unicode_error_start(start_value, n);
3262
48.9k
        *start = start_value;
3263
48.9k
    }
3264
3265
243k
    Py_ssize_t end_value = -1;
3266
243k
    if (end != NULL || slen != NULL) {
3267
243k
        end_value = unicode_error_adjust_end(exc->end, n);
3268
243k
    }
3269
243k
    if (end != NULL) {
3270
243k
        assert_adjusted_unicode_error_end(end_value, n);
3271
243k
        *end = end_value;
3272
243k
    }
3273
3274
243k
    if (slen != NULL) {
3275
48.9k
        *slen = unicode_error_adjust_len(start_value, end_value, n);
3276
48.9k
        assert_adjusted_unicode_error_len(*slen, n);
3277
48.9k
    }
3278
3279
243k
    if (obj != NULL) {
3280
48.9k
        *obj = r;
3281
48.9k
    }
3282
194k
    else {
3283
194k
        Py_DECREF(r);
3284
194k
    }
3285
243k
    return 0;
3286
243k
}
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
222k
{
3321
222k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3322
222k
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
3323
222k
}
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
201k
{
3389
201k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3390
201k
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3391
201k
}
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
194k
{
3413
194k
    assert(self != NULL);
3414
194k
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3415
194k
                                     NULL, end, NULL,
3416
194k
                                     as_bytes);
3417
194k
}
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
194k
{
3431
194k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3432
194k
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, true);
3433
194k
}
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
201k
{
3457
201k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3458
201k
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3459
201k
}
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
201k
{
3509
201k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3510
201k
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3511
201k
}
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
245k
{
3525
245k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3526
245k
    Py_CLEAR(exc->encoding);
3527
245k
    Py_CLEAR(exc->object);
3528
245k
    Py_CLEAR(exc->reason);
3529
245k
    return BaseException_clear(self);
3530
245k
}
3531
3532
static void
3533
UnicodeError_dealloc(PyObject *self)
3534
245k
{
3535
245k
    PyTypeObject *type = Py_TYPE(self);
3536
245k
    _PyObject_GC_UNTRACK(self);
3537
245k
    (void)UnicodeError_clear(self);
3538
245k
    type->tp_free(self);
3539
245k
}
3540
3541
static int
3542
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
3543
98
{
3544
98
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3545
98
    Py_VISIT(exc->encoding);
3546
98
    Py_VISIT(exc->object);
3547
98
    Py_VISIT(exc->reason);
3548
98
    return BaseException_traverse(self, visit, arg);
3549
98
}
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
173k
{
3573
173k
    if (BaseException_init(self, args, kwds) == -1) {
3574
0
        return -1;
3575
0
    }
3576
3577
173k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3578
173k
    Py_ssize_t start = -1, end = -1;
3579
3580
173k
    if (!PyArg_ParseTuple(args, "UUnnU",
3581
173k
                          &encoding, &object, &start, &end, &reason))
3582
0
    {
3583
0
        return -1;
3584
0
    }
3585
3586
173k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3587
173k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3588
173k
    Py_XSETREF(exc->object, Py_NewRef(object));
3589
173k
    exc->start = start;
3590
173k
    exc->end = end;
3591
173k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3592
173k
    return 0;
3593
173k
}
3594
3595
static PyObject *
3596
UnicodeEncodeError_str(PyObject *self)
3597
57
{
3598
57
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3599
57
    PyObject *result = NULL;
3600
57
    PyObject *reason_str = NULL;
3601
57
    PyObject *encoding_str = NULL;
3602
3603
57
    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
57
    reason_str = PyObject_Str(exc->reason);
3611
57
    if (reason_str == NULL) {
3612
0
        goto done;
3613
0
    }
3614
57
    encoding_str = PyObject_Str(exc->encoding);
3615
57
    if (encoding_str == NULL) {
3616
0
        goto done;
3617
0
    }
3618
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3619
57
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3620
0
        goto done;
3621
0
    }
3622
57
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3623
57
    Py_ssize_t start = exc->start, end = exc->end;
3624
3625
57
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3626
37
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3627
37
        const char *fmt;
3628
37
        if (badchar <= 0xff) {
3629
0
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
3630
0
        }
3631
37
        else if (badchar <= 0xffff) {
3632
37
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
3633
37
        }
3634
0
        else {
3635
0
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
3636
0
        }
3637
37
        result = PyUnicode_FromFormat(
3638
37
            fmt,
3639
37
            encoding_str,
3640
37
            (int)badchar,
3641
37
            start,
3642
37
            reason_str);
3643
37
    }
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
57
done:
3653
57
    Py_XDECREF(reason_str);
3654
57
    Py_XDECREF(encoding_str);
3655
57
    return result;
3656
57
}
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
71.3k
{
3680
71.3k
    if (BaseException_init(self, args, kwds) == -1) {
3681
0
        return -1;
3682
0
    }
3683
3684
71.3k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3685
71.3k
    Py_ssize_t start = -1, end = -1;
3686
3687
71.3k
    if (!PyArg_ParseTuple(args, "UOnnU",
3688
71.3k
                          &encoding, &object, &start, &end, &reason))
3689
98
    {
3690
98
        return -1;
3691
98
    }
3692
3693
71.2k
    if (PyBytes_Check(object)) {
3694
71.2k
        Py_INCREF(object);  // make 'object' a strong reference
3695
71.2k
    }
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
71.2k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3710
71.2k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3711
71.2k
    Py_XSETREF(exc->object, object /* already a strong reference */);
3712
71.2k
    exc->start = start;
3713
71.2k
    exc->end = end;
3714
71.2k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3715
71.2k
    return 0;
3716
71.2k
}
3717
3718
static PyObject *
3719
UnicodeDecodeError_str(PyObject *self)
3720
2.71k
{
3721
2.71k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3722
2.71k
    PyObject *result = NULL;
3723
2.71k
    PyObject *reason_str = NULL;
3724
2.71k
    PyObject *encoding_str = NULL;
3725
3726
2.71k
    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.71k
    reason_str = PyObject_Str(exc->reason);
3734
2.71k
    if (reason_str == NULL) {
3735
0
        goto done;
3736
0
    }
3737
2.71k
    encoding_str = PyObject_Str(exc->encoding);
3738
2.71k
    if (encoding_str == NULL) {
3739
0
        goto done;
3740
0
    }
3741
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3742
2.71k
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
3743
0
        goto done;
3744
0
    }
3745
2.71k
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
3746
2.71k
    Py_ssize_t start = exc->start, end = exc->end;
3747
3748
2.71k
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3749
1.53k
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
3750
1.53k
        result = PyUnicode_FromFormat(
3751
1.53k
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3752
1.53k
            encoding_str,
3753
1.53k
            badbyte,
3754
1.53k
            start,
3755
1.53k
            reason_str);
3756
1.53k
    }
3757
1.17k
    else {
3758
1.17k
        result = PyUnicode_FromFormat(
3759
1.17k
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3760
1.17k
            encoding_str,
3761
1.17k
            start,
3762
1.17k
            end - 1,
3763
1.17k
            reason_str);
3764
1.17k
    }
3765
2.71k
done:
3766
2.71k
    Py_XDECREF(reason_str);
3767
2.71k
    Py_XDECREF(encoding_str);
3768
2.71k
    return result;
3769
2.71k
}
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
66.9k
{
3790
66.9k
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3791
66.9k
                                 encoding, object, length, start, end, reason);
3792
66.9k
}
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
865
#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
642
# define MEMERRORS_LOCK(state) ((void)0)
3963
642
# define MEMERRORS_UNLOCK(state) ((void)0)
3964
#endif
3965
3966
static PyObject *
3967
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
3968
321
{
3969
321
    PyBaseExceptionObject *self = NULL;
3970
321
    struct _Py_exc_state *state = get_exc_state();
3971
3972
321
    MEMERRORS_LOCK(state);
3973
321
    if (state->memerrors_freelist != NULL) {
3974
        /* Fetch MemoryError from freelist and initialize it */
3975
65
        self = state->memerrors_freelist;
3976
65
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
3977
65
        state->memerrors_numfree--;
3978
65
        self->dict = NULL;
3979
65
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
3980
65
        _Py_NewReference((PyObject *)self);
3981
65
        _PyObject_GC_TRACK(self);
3982
65
    }
3983
321
    MEMERRORS_UNLOCK(state);
3984
3985
321
    if (self != NULL) {
3986
65
        return (PyObject *)self;
3987
65
    }
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
321
{
4000
    /* If this is a subclass of MemoryError, don't use the freelist
4001
     * and just return a fresh object */
4002
321
    if (type != (PyTypeObject *) PyExc_MemoryError) {
4003
0
        return BaseException_new(type, args, kwds);
4004
0
    }
4005
321
    return get_memory_error(1, args, kwds);
4006
321
}
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
321
{
4027
321
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
4028
321
    _PyObject_GC_UNTRACK(self);
4029
4030
321
    (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
321
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
4035
0
        Py_TYPE(self)->tp_free(op);
4036
0
        return;
4037
0
    }
4038
4039
321
    struct _Py_exc_state *state = get_exc_state();
4040
321
    MEMERRORS_LOCK(state);
4041
321
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
4042
321
        self->dict = (PyObject *) state->memerrors_freelist;
4043
321
        state->memerrors_freelist = self;
4044
321
        state->memerrors_numfree++;
4045
321
        MEMERRORS_UNLOCK(state);
4046
321
        return;
4047
321
    }
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
46.2k
{
4508
46.2k
    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
46.2k
    PyObject *r = BaseException_add_note(exc, note);
4515
46.2k
    int res = r == NULL ? -1 : 0;
4516
46.2k
    Py_XDECREF(r);
4517
46.2k
    return res;
4518
46.2k
}
4519