Coverage Report

Created: 2026-01-09 06:26

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