Coverage Report

Created: 2026-02-26 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Objects/exceptions.c
Line
Count
Source
1
/*
2
 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
3
 *
4
 * Thanks go to Tim Peters and Michael Hudson for debugging.
5
 */
6
7
#include <Python.h>
8
#include <stdbool.h>
9
#include "pycore_abstract.h"      // _PyObject_RealIsSubclass()
10
#include "pycore_ceval.h"         // _Py_EnterRecursiveCall
11
#include "pycore_exceptions.h"    // struct _Py_exc_state
12
#include "pycore_initconfig.h"
13
#include "pycore_modsupport.h"    // _PyArg_NoKeywords()
14
#include "pycore_object.h"
15
#include "pycore_pyerrors.h"      // struct _PyErr_SetRaisedException
16
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
287k
{
31
287k
    PyInterpreterState *interp = _PyInterpreterState_GET();
32
287k
    return &interp->exc_state;
33
287k
}
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
300M
{
43
300M
    assert(PyExceptionInstance_Check(exc));
44
300M
    return (PyBaseExceptionObject *)exc;
45
300M
}
46
47
/*
48
 *    BaseException
49
 */
50
static PyObject *
51
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
52
30.6M
{
53
30.6M
    PyBaseExceptionObject *self;
54
55
30.6M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
56
30.6M
    if (!self)
57
0
        return NULL;
58
    /* the dict is created on the fly in PyObject_GenericSetAttr */
59
30.6M
    self->dict = NULL;
60
30.6M
    self->notes = NULL;
61
30.6M
    self->traceback = self->cause = self->context = NULL;
62
30.6M
    self->suppress_context = 0;
63
64
30.6M
    if (args) {
65
30.6M
        self->args = Py_NewRef(args);
66
30.6M
        return (PyObject *)self;
67
30.6M
    }
68
69
512
    self->args = PyTuple_New(0);
70
512
    if (!self->args) {
71
0
        Py_DECREF(self);
72
0
        return NULL;
73
0
    }
74
75
512
    return (PyObject *)self;
76
512
}
77
78
static int
79
BaseException_init(PyObject *op, PyObject *args, PyObject *kwds)
80
29.3M
{
81
29.3M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
82
29.3M
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
83
0
        return -1;
84
85
29.3M
    Py_XSETREF(self->args, Py_NewRef(args));
86
29.3M
    return 0;
87
29.3M
}
88
89
90
static PyObject *
91
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
92
                         size_t nargsf, PyObject *kwnames)
93
20.1M
{
94
20.1M
    PyTypeObject *type = _PyType_CAST(type_obj);
95
20.1M
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
96
0
        return NULL;
97
0
    }
98
99
20.1M
    PyBaseExceptionObject *self;
100
20.1M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
101
20.1M
    if (!self) {
102
0
        return NULL;
103
0
    }
104
105
    // The dict is created on the fly in PyObject_GenericSetAttr()
106
20.1M
    self->dict = NULL;
107
20.1M
    self->notes = NULL;
108
20.1M
    self->traceback = NULL;
109
20.1M
    self->cause = NULL;
110
20.1M
    self->context = NULL;
111
20.1M
    self->suppress_context = 0;
112
113
20.1M
    self->args = PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
114
20.1M
    if (!self->args) {
115
0
        Py_DECREF(self);
116
0
        return NULL;
117
0
    }
118
119
20.1M
    return (PyObject *)self;
120
20.1M
}
121
122
123
static int
124
BaseException_clear(PyObject *op)
125
51.0M
{
126
51.0M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
127
51.0M
    Py_CLEAR(self->dict);
128
51.0M
    Py_CLEAR(self->args);
129
51.0M
    Py_CLEAR(self->notes);
130
51.0M
    Py_CLEAR(self->traceback);
131
51.0M
    Py_CLEAR(self->cause);
132
51.0M
    Py_CLEAR(self->context);
133
51.0M
    return 0;
134
51.0M
}
135
136
static void
137
BaseException_dealloc(PyObject *op)
138
36.2M
{
139
36.2M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
140
36.2M
    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
36.2M
    (void)BaseException_clear(op);
145
36.2M
    Py_TYPE(self)->tp_free(self);
146
36.2M
}
147
148
static int
149
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
150
8.28M
{
151
8.28M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
152
8.28M
    Py_VISIT(self->dict);
153
8.28M
    Py_VISIT(self->args);
154
8.28M
    Py_VISIT(self->notes);
155
8.28M
    Py_VISIT(self->traceback);
156
8.28M
    Py_VISIT(self->cause);
157
8.28M
    Py_VISIT(self->context);
158
8.28M
    return 0;
159
8.28M
}
160
161
static PyObject *
162
BaseException_str(PyObject *op)
163
6.21M
{
164
6.21M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
165
166
6.21M
    PyObject *res;
167
6.21M
    Py_BEGIN_CRITICAL_SECTION(self);
168
6.21M
    switch (PyTuple_GET_SIZE(self->args)) {
169
0
    case 0:
170
0
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
171
0
        break;
172
6.21M
    case 1:
173
6.21M
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
174
6.21M
        break;
175
0
    default:
176
0
        res = PyObject_Str(self->args);
177
0
        break;
178
6.21M
    }
179
6.21M
    Py_END_CRITICAL_SECTION();
180
6.21M
    return res;
181
6.21M
}
182
183
static PyObject *
184
BaseException_repr(PyObject *op)
185
9.33k
{
186
187
9.33k
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
188
189
9.33k
    PyObject *res;
190
9.33k
    Py_BEGIN_CRITICAL_SECTION(self);
191
9.33k
    const char *name = _PyType_Name(Py_TYPE(self));
192
9.33k
    if (PyTuple_GET_SIZE(self->args) == 1) {
193
9.33k
        res = PyUnicode_FromFormat("%s(%R)", name,
194
9.33k
                                    PyTuple_GET_ITEM(self->args, 0));
195
9.33k
    }
196
0
    else {
197
0
        res = PyUnicode_FromFormat("%s%R", name, self->args);
198
0
    }
199
9.33k
    Py_END_CRITICAL_SECTION();
200
9.33k
    return res;
201
9.33k
}
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
58.1k
{
292
58.1k
    PyObject *notes;
293
58.1k
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
294
0
        return NULL;
295
0
    }
296
58.1k
    if (notes == NULL) {
297
58.0k
        notes = PyList_New(0);
298
58.0k
        if (notes == NULL) {
299
0
            return NULL;
300
0
        }
301
58.0k
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
302
0
            Py_DECREF(notes);
303
0
            return NULL;
304
0
        }
305
58.0k
    }
306
63
    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
58.1k
    if (PyList_Append(notes, note) < 0) {
312
0
        Py_DECREF(notes);
313
0
        return NULL;
314
0
    }
315
58.1k
    Py_DECREF(notes);
316
58.1k
    Py_RETURN_NONE;
317
58.1k
}
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
2.18M
{
353
2.18M
    PyObject *seq;
354
2.18M
    if (value == NULL) {
355
0
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
356
0
        return -1;
357
0
    }
358
2.18M
    seq = PySequence_Tuple(value);
359
2.18M
    if (!seq)
360
0
        return -1;
361
2.18M
    Py_XSETREF(self->args, seq);
362
2.18M
    return 0;
363
2.18M
}
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
58.8M
{
393
58.8M
    if (value == NULL) {
394
0
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
395
0
        return -1;
396
0
    }
397
58.8M
    if (PyTraceBack_Check(value)) {
398
58.7M
        Py_XSETREF(self->traceback, Py_NewRef(value));
399
58.7M
    }
400
3.73k
    else if (value == Py_None) {
401
3.73k
        Py_CLEAR(self->traceback);
402
3.73k
    }
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
58.8M
    return 0;
409
58.8M
}
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
98.9M
{
512
98.9M
    PyObject *traceback;
513
98.9M
    Py_BEGIN_CRITICAL_SECTION(self);
514
98.9M
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
515
98.9M
    Py_END_CRITICAL_SECTION();
516
98.9M
    return traceback;
517
98.9M
}
518
519
520
int
521
PyException_SetTraceback(PyObject *self, PyObject *tb)
522
58.8M
{
523
58.8M
    int res;
524
58.8M
    Py_BEGIN_CRITICAL_SECTION(self);
525
58.8M
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
526
58.8M
    Py_END_CRITICAL_SECTION();
527
58.8M
    return res;
528
58.8M
}
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.0k
{
544
13.0k
    Py_BEGIN_CRITICAL_SECTION(self);
545
13.0k
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
546
13.0k
    base_self->suppress_context = 1;
547
13.0k
    Py_XSETREF(base_self->cause, cause);
548
13.0k
    Py_END_CRITICAL_SECTION();
549
13.0k
}
550
551
PyObject *
552
PyException_GetContext(PyObject *self)
553
6.41M
{
554
6.41M
    PyObject *context;
555
6.41M
    Py_BEGIN_CRITICAL_SECTION(self);
556
6.41M
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
557
6.41M
    Py_END_CRITICAL_SECTION();
558
6.41M
    return context;
559
6.41M
}
560
561
/* Steals a reference to context */
562
void
563
PyException_SetContext(PyObject *self, PyObject *context)
564
5.41M
{
565
5.41M
    Py_BEGIN_CRITICAL_SECTION(self);
566
5.41M
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
567
5.41M
    Py_END_CRITICAL_SECTION();
568
5.41M
}
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
21.4M
{
740
21.4M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
741
21.4M
    return (PyStopIterationObject *)self;
742
21.4M
}
743
744
static int
745
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
746
10.7M
{
747
10.7M
    Py_ssize_t size = PyTuple_GET_SIZE(args);
748
10.7M
    PyObject *value;
749
750
10.7M
    if (BaseException_init(op, args, kwds) == -1)
751
0
        return -1;
752
10.7M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
753
10.7M
    Py_CLEAR(self->value);
754
10.7M
    if (size > 0)
755
2.05k
        value = PyTuple_GET_ITEM(args, 0);
756
10.7M
    else
757
10.7M
        value = Py_None;
758
10.7M
    self->value = Py_NewRef(value);
759
10.7M
    return 0;
760
10.7M
}
761
762
static int
763
StopIteration_clear(PyObject *op)
764
10.7M
{
765
10.7M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
766
10.7M
    Py_CLEAR(self->value);
767
10.7M
    return BaseException_clear(op);
768
10.7M
}
769
770
static void
771
StopIteration_dealloc(PyObject *self)
772
10.7M
{
773
10.7M
    PyObject_GC_UnTrack(self);
774
10.7M
    (void)StopIteration_clear(self);
775
10.7M
    Py_TYPE(self)->tp_free(self);
776
10.7M
}
777
778
static int
779
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
780
3
{
781
3
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
782
3
    Py_VISIT(self->value);
783
3
    return BaseException_traverse(op, visit, arg);
784
3
}
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
32
create_exception_group_class(void) {
1765
32
    struct _Py_exc_state *state = get_exc_state();
1766
1767
32
    PyObject *bases = PyTuple_Pack(
1768
32
        2, PyExc_BaseExceptionGroup, PyExc_Exception);
1769
32
    if (bases == NULL) {
1770
0
        return NULL;
1771
0
    }
1772
1773
32
    assert(!state->PyExc_ExceptionGroup);
1774
32
    state->PyExc_ExceptionGroup = PyErr_NewException(
1775
32
        "builtins.ExceptionGroup", bases, NULL);
1776
1777
32
    Py_DECREF(bases);
1778
32
    return state->PyExc_ExceptionGroup;
1779
32
}
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
8.62k
{
1795
8.62k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
1796
8.62k
    return (PyImportErrorObject *)self;
1797
8.62k
}
1798
1799
static int
1800
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
1801
4.31k
{
1802
4.31k
    static char *kwlist[] = {"name", "path", "name_from", 0};
1803
4.31k
    PyObject *empty_tuple;
1804
4.31k
    PyObject *msg = NULL;
1805
4.31k
    PyObject *name = NULL;
1806
4.31k
    PyObject *path = NULL;
1807
4.31k
    PyObject *name_from = NULL;
1808
1809
4.31k
    if (BaseException_init(op, args, NULL) == -1)
1810
0
        return -1;
1811
1812
4.31k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1813
4.31k
    empty_tuple = PyTuple_New(0);
1814
4.31k
    if (!empty_tuple)
1815
0
        return -1;
1816
4.31k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
1817
4.31k
                                     &name, &path, &name_from)) {
1818
0
        Py_DECREF(empty_tuple);
1819
0
        return -1;
1820
0
    }
1821
4.31k
    Py_DECREF(empty_tuple);
1822
1823
4.31k
    Py_XSETREF(self->name, Py_XNewRef(name));
1824
4.31k
    Py_XSETREF(self->path, Py_XNewRef(path));
1825
4.31k
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));
1826
1827
4.31k
    if (PyTuple_GET_SIZE(args) == 1) {
1828
4.31k
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
1829
4.31k
    }
1830
4.31k
    Py_XSETREF(self->msg, msg);
1831
1832
4.31k
    return 0;
1833
4.31k
}
1834
1835
static int
1836
ImportError_clear(PyObject *op)
1837
4.31k
{
1838
4.31k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1839
4.31k
    Py_CLEAR(self->msg);
1840
4.31k
    Py_CLEAR(self->name);
1841
4.31k
    Py_CLEAR(self->path);
1842
4.31k
    Py_CLEAR(self->name_from);
1843
4.31k
    return BaseException_clear(op);
1844
4.31k
}
1845
1846
static void
1847
ImportError_dealloc(PyObject *self)
1848
4.31k
{
1849
4.31k
    _PyObject_GC_UNTRACK(self);
1850
4.31k
    (void)ImportError_clear(self);
1851
4.31k
    Py_TYPE(self)->tp_free(self);
1852
4.31k
}
1853
1854
static int
1855
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
1856
2
{
1857
2
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1858
2
    Py_VISIT(self->msg);
1859
2
    Py_VISIT(self->name);
1860
2
    Py_VISIT(self->path);
1861
2
    Py_VISIT(self->name_from);
1862
2
    return BaseException_traverse(op, visit, arg);
1863
2
}
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
 *    ImportCycleError extends ImportError
2019
 */
2020
2021
MiddlingExtendsException(PyExc_ImportError, ImportCycleError, ImportError,
2022
                         "Import produces a cycle.");
2023
/*
2024
 *    ModuleNotFoundError extends ImportError
2025
 */
2026
2027
MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
2028
                         "Module not found.");
2029
2030
/*
2031
 *    OSError extends Exception
2032
 */
2033
2034
static inline PyOSErrorObject *
2035
PyOSErrorObject_CAST(PyObject *self)
2036
573k
{
2037
573k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
2038
573k
    return (PyOSErrorObject *)self;
2039
573k
}
2040
2041
#ifdef MS_WINDOWS
2042
#include "errmap.h"
2043
#endif
2044
2045
/* Where a function has a single filename, such as open() or some
2046
 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
2047
 * called, giving a third argument which is the filename.  But, so
2048
 * that old code using in-place unpacking doesn't break, e.g.:
2049
 *
2050
 * except OSError, (errno, strerror):
2051
 *
2052
 * we hack args so that it only contains two items.  This also
2053
 * means we need our own __str__() which prints out the filename
2054
 * when it was supplied.
2055
 *
2056
 * (If a function has two filenames, such as rename(), symlink(),
2057
 * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
2058
 * which allows passing in a second filename.)
2059
 */
2060
2061
/* This function doesn't cleanup on error, the caller should */
2062
static int
2063
oserror_parse_args(PyObject **p_args,
2064
                   PyObject **myerrno, PyObject **strerror,
2065
                   PyObject **filename, PyObject **filename2
2066
#ifdef MS_WINDOWS
2067
                   , PyObject **winerror
2068
#endif
2069
                  )
2070
286k
{
2071
286k
    Py_ssize_t nargs;
2072
286k
    PyObject *args = *p_args;
2073
286k
#ifndef MS_WINDOWS
2074
    /*
2075
     * ignored on non-Windows platforms,
2076
     * but parsed so OSError has a consistent signature
2077
     */
2078
286k
    PyObject *_winerror = NULL;
2079
286k
    PyObject **winerror = &_winerror;
2080
286k
#endif /* MS_WINDOWS */
2081
2082
286k
    nargs = PyTuple_GET_SIZE(args);
2083
2084
286k
    if (nargs >= 2 && nargs <= 5) {
2085
282k
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
2086
282k
                               myerrno, strerror,
2087
282k
                               filename, winerror, filename2))
2088
0
            return -1;
2089
#ifdef MS_WINDOWS
2090
        if (*winerror && PyLong_Check(*winerror)) {
2091
            long errcode, winerrcode;
2092
            PyObject *newargs;
2093
            Py_ssize_t i;
2094
2095
            winerrcode = PyLong_AsLong(*winerror);
2096
            if (winerrcode == -1 && PyErr_Occurred())
2097
                return -1;
2098
            errcode = winerror_to_errno(winerrcode);
2099
            *myerrno = PyLong_FromLong(errcode);
2100
            if (!*myerrno)
2101
                return -1;
2102
            newargs = PyTuple_New(nargs);
2103
            if (!newargs)
2104
                return -1;
2105
            PyTuple_SET_ITEM(newargs, 0, *myerrno);
2106
            for (i = 1; i < nargs; i++) {
2107
                PyObject *val = PyTuple_GET_ITEM(args, i);
2108
                PyTuple_SET_ITEM(newargs, i, Py_NewRef(val));
2109
            }
2110
            Py_DECREF(args);
2111
            args = *p_args = newargs;
2112
        }
2113
#endif /* MS_WINDOWS */
2114
282k
    }
2115
2116
286k
    return 0;
2117
286k
}
2118
2119
static int
2120
oserror_init(PyOSErrorObject *self, PyObject **p_args,
2121
             PyObject *myerrno, PyObject *strerror,
2122
             PyObject *filename, PyObject *filename2
2123
#ifdef MS_WINDOWS
2124
             , PyObject *winerror
2125
#endif
2126
             )
2127
286k
{
2128
286k
    PyObject *args = *p_args;
2129
286k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
2130
2131
    /* self->filename will remain Py_None otherwise */
2132
286k
    if (filename && filename != Py_None) {
2133
282k
        if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
2134
0
            PyNumber_Check(filename)) {
2135
            /* BlockingIOError's 3rd argument can be the number of
2136
             * characters written.
2137
             */
2138
0
            self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
2139
0
            if (self->written == -1 && PyErr_Occurred())
2140
0
                return -1;
2141
0
        }
2142
282k
        else {
2143
282k
            self->filename = Py_NewRef(filename);
2144
2145
282k
            if (filename2 && filename2 != Py_None) {
2146
0
                self->filename2 = Py_NewRef(filename2);
2147
0
            }
2148
2149
282k
            if (nargs >= 2 && nargs <= 5) {
2150
                /* filename, filename2, and winerror are removed from the args tuple
2151
                   (for compatibility purposes, see test_exceptions.py) */
2152
282k
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
2153
282k
                if (!subslice)
2154
0
                    return -1;
2155
2156
282k
                Py_DECREF(args);  /* replacing args */
2157
282k
                *p_args = args = subslice;
2158
282k
            }
2159
282k
        }
2160
282k
    }
2161
286k
    self->myerrno = Py_XNewRef(myerrno);
2162
286k
    self->strerror = Py_XNewRef(strerror);
2163
#ifdef MS_WINDOWS
2164
    self->winerror = Py_XNewRef(winerror);
2165
#endif
2166
2167
    /* Steals the reference to args */
2168
286k
    Py_XSETREF(self->args, args);
2169
286k
    *p_args = args = NULL;
2170
2171
286k
    return 0;
2172
286k
}
2173
2174
static PyObject *
2175
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
2176
static int
2177
OSError_init(PyObject *self, PyObject *args, PyObject *kwds);
2178
2179
static int
2180
oserror_use_init(PyTypeObject *type)
2181
859k
{
2182
    /* When __init__ is defined in an OSError subclass, we want any
2183
       extraneous argument to __new__ to be ignored.  The only reasonable
2184
       solution, given __new__ takes a variable number of arguments,
2185
       is to defer arg parsing and initialization to __init__.
2186
2187
       But when __new__ is overridden as well, it should call our __new__
2188
       with the right arguments.
2189
2190
       (see http://bugs.python.org/issue12555#msg148829 )
2191
    */
2192
859k
    if (type->tp_init != OSError_init && type->tp_new == OSError_new) {
2193
180
        assert((PyObject *) type != PyExc_OSError);
2194
180
        return 1;
2195
180
    }
2196
859k
    return 0;
2197
859k
}
2198
2199
static PyObject *
2200
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2201
286k
{
2202
286k
    PyOSErrorObject *self = NULL;
2203
286k
    PyObject *myerrno = NULL, *strerror = NULL;
2204
286k
    PyObject *filename = NULL, *filename2 = NULL;
2205
#ifdef MS_WINDOWS
2206
    PyObject *winerror = NULL;
2207
#endif
2208
2209
286k
    Py_INCREF(args);
2210
2211
286k
    if (!oserror_use_init(type)) {
2212
286k
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
2213
0
            goto error;
2214
2215
286k
        if (oserror_parse_args(&args, &myerrno, &strerror,
2216
286k
                               &filename, &filename2
2217
#ifdef MS_WINDOWS
2218
                               , &winerror
2219
#endif
2220
286k
            ))
2221
0
            goto error;
2222
2223
286k
        struct _Py_exc_state *state = get_exc_state();
2224
286k
        if (myerrno && PyLong_Check(myerrno) &&
2225
282k
            state->errnomap && (PyObject *) type == PyExc_OSError) {
2226
282k
            PyObject *newtype;
2227
282k
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
2228
282k
            if (newtype) {
2229
236k
                type = _PyType_CAST(newtype);
2230
236k
            }
2231
46.4k
            else if (PyErr_Occurred())
2232
0
                goto error;
2233
282k
        }
2234
286k
    }
2235
2236
286k
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
2237
286k
    if (!self)
2238
0
        goto error;
2239
2240
286k
    self->dict = NULL;
2241
286k
    self->traceback = self->cause = self->context = NULL;
2242
286k
    self->written = -1;
2243
2244
286k
    if (!oserror_use_init(type)) {
2245
286k
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2246
#ifdef MS_WINDOWS
2247
                         , winerror
2248
#endif
2249
286k
            ))
2250
0
            goto error;
2251
286k
    }
2252
60
    else {
2253
60
        self->args = PyTuple_New(0);
2254
60
        if (self->args == NULL)
2255
0
            goto error;
2256
60
    }
2257
2258
286k
    Py_XDECREF(args);
2259
286k
    return (PyObject *) self;
2260
2261
0
error:
2262
0
    Py_XDECREF(args);
2263
0
    Py_XDECREF(self);
2264
0
    return NULL;
2265
286k
}
2266
2267
static int
2268
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
2269
286k
{
2270
286k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2271
286k
    PyObject *myerrno = NULL, *strerror = NULL;
2272
286k
    PyObject *filename = NULL, *filename2 = NULL;
2273
#ifdef MS_WINDOWS
2274
    PyObject *winerror = NULL;
2275
#endif
2276
2277
286k
    if (!oserror_use_init(Py_TYPE(self)))
2278
        /* Everything already done in OSError_new */
2279
286k
        return 0;
2280
2281
60
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
2282
0
        return -1;
2283
2284
60
    Py_INCREF(args);
2285
60
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
2286
#ifdef MS_WINDOWS
2287
                           , &winerror
2288
#endif
2289
60
        ))
2290
0
        goto error;
2291
2292
60
    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2293
#ifdef MS_WINDOWS
2294
                     , winerror
2295
#endif
2296
60
        ))
2297
0
        goto error;
2298
2299
60
    return 0;
2300
2301
0
error:
2302
0
    Py_DECREF(args);
2303
0
    return -1;
2304
60
}
2305
2306
static int
2307
OSError_clear(PyObject *op)
2308
286k
{
2309
286k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2310
286k
    Py_CLEAR(self->myerrno);
2311
286k
    Py_CLEAR(self->strerror);
2312
286k
    Py_CLEAR(self->filename);
2313
286k
    Py_CLEAR(self->filename2);
2314
#ifdef MS_WINDOWS
2315
    Py_CLEAR(self->winerror);
2316
#endif
2317
286k
    return BaseException_clear(op);
2318
286k
}
2319
2320
static void
2321
OSError_dealloc(PyObject *self)
2322
286k
{
2323
286k
    _PyObject_GC_UNTRACK(self);
2324
286k
    (void)OSError_clear(self);
2325
286k
    Py_TYPE(self)->tp_free(self);
2326
286k
}
2327
2328
static int
2329
OSError_traverse(PyObject *op, visitproc visit, void *arg)
2330
5
{
2331
5
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2332
5
    Py_VISIT(self->myerrno);
2333
5
    Py_VISIT(self->strerror);
2334
5
    Py_VISIT(self->filename);
2335
5
    Py_VISIT(self->filename2);
2336
#ifdef MS_WINDOWS
2337
    Py_VISIT(self->winerror);
2338
#endif
2339
5
    return BaseException_traverse(op, visit, arg);
2340
5
}
2341
2342
static PyObject *
2343
OSError_str(PyObject *op)
2344
785
{
2345
785
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2346
1.56k
#define OR_NONE(x) ((x)?(x):Py_None)
2347
#ifdef MS_WINDOWS
2348
    /* If available, winerror has the priority over myerrno */
2349
    if (self->winerror && self->filename) {
2350
        if (self->filename2) {
2351
            return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
2352
                                        OR_NONE(self->winerror),
2353
                                        OR_NONE(self->strerror),
2354
                                        self->filename,
2355
                                        self->filename2);
2356
        } else {
2357
            return PyUnicode_FromFormat("[WinError %S] %S: %R",
2358
                                        OR_NONE(self->winerror),
2359
                                        OR_NONE(self->strerror),
2360
                                        self->filename);
2361
        }
2362
    }
2363
    if (self->winerror && self->strerror)
2364
        return PyUnicode_FromFormat("[WinError %S] %S",
2365
                                    self->winerror ? self->winerror: Py_None,
2366
                                    self->strerror ? self->strerror: Py_None);
2367
#endif
2368
785
    if (self->filename) {
2369
782
        if (self->filename2) {
2370
0
            return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
2371
0
                                        OR_NONE(self->myerrno),
2372
0
                                        OR_NONE(self->strerror),
2373
0
                                        self->filename,
2374
0
                                        self->filename2);
2375
782
        } else {
2376
782
            return PyUnicode_FromFormat("[Errno %S] %S: %R",
2377
782
                                        OR_NONE(self->myerrno),
2378
782
                                        OR_NONE(self->strerror),
2379
782
                                        self->filename);
2380
782
        }
2381
782
    }
2382
3
    if (self->myerrno && self->strerror)
2383
0
        return PyUnicode_FromFormat("[Errno %S] %S",
2384
0
                                    self->myerrno, self->strerror);
2385
3
    return BaseException_str(op);
2386
3
}
2387
2388
static PyObject *
2389
OSError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
2390
0
{
2391
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2392
0
    PyObject *args = self->args;
2393
0
    PyObject *res = NULL;
2394
2395
    /* self->args is only the first two real arguments if there was a
2396
     * file name given to OSError. */
2397
0
    if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
2398
0
        Py_ssize_t size = self->filename2 ? 5 : 3;
2399
0
        args = PyTuple_New(size);
2400
0
        if (!args)
2401
0
            return NULL;
2402
2403
0
        PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0)));
2404
0
        PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1)));
2405
0
        PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename));
2406
2407
0
        if (self->filename2) {
2408
            /*
2409
             * This tuple is essentially used as OSError(*args).
2410
             * So, to recreate filename2, we need to pass in
2411
             * winerror as well.
2412
             */
2413
0
            PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None));
2414
2415
            /* filename2 */
2416
0
            PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2));
2417
0
        }
2418
0
    } else
2419
0
        Py_INCREF(args);
2420
2421
0
    if (self->dict)
2422
0
        res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
2423
0
    else
2424
0
        res = PyTuple_Pack(2, Py_TYPE(self), args);
2425
0
    Py_DECREF(args);
2426
0
    return res;
2427
0
}
2428
2429
static PyObject *
2430
OSError_written_get(PyObject *op, void *context)
2431
0
{
2432
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2433
0
    if (self->written == -1) {
2434
0
        PyErr_SetString(PyExc_AttributeError, "characters_written");
2435
0
        return NULL;
2436
0
    }
2437
0
    return PyLong_FromSsize_t(self->written);
2438
0
}
2439
2440
static int
2441
OSError_written_set(PyObject *op, PyObject *arg, void *context)
2442
0
{
2443
0
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2444
0
    if (arg == NULL) {
2445
0
        if (self->written == -1) {
2446
0
            PyErr_SetString(PyExc_AttributeError, "characters_written");
2447
0
            return -1;
2448
0
        }
2449
0
        self->written = -1;
2450
0
        return 0;
2451
0
    }
2452
0
    Py_ssize_t n;
2453
0
    n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
2454
0
    if (n == -1 && PyErr_Occurred())
2455
0
        return -1;
2456
0
    self->written = n;
2457
0
    return 0;
2458
0
}
2459
2460
static PyMemberDef OSError_members[] = {
2461
    {"errno", _Py_T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
2462
        PyDoc_STR("POSIX exception code")},
2463
    {"strerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
2464
        PyDoc_STR("exception strerror")},
2465
    {"filename", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
2466
        PyDoc_STR("exception filename")},
2467
    {"filename2", _Py_T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
2468
        PyDoc_STR("second exception filename")},
2469
#ifdef MS_WINDOWS
2470
    {"winerror", _Py_T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
2471
        PyDoc_STR("Win32 exception code")},
2472
#endif
2473
    {NULL}  /* Sentinel */
2474
};
2475
2476
static PyMethodDef OSError_methods[] = {
2477
    {"__reduce__", OSError_reduce, METH_NOARGS},
2478
    {NULL}
2479
};
2480
2481
static PyGetSetDef OSError_getset[] = {
2482
    {"characters_written", OSError_written_get,
2483
                           OSError_written_set, NULL},
2484
    {NULL}
2485
};
2486
2487
2488
ComplexExtendsException(PyExc_Exception, OSError,
2489
                        OSError, OSError_new,
2490
                        OSError_methods, OSError_members, OSError_getset,
2491
                        OSError_str, 0,
2492
                        "Base class for I/O related errors.");
2493
2494
2495
/*
2496
 *    Various OSError subclasses
2497
 */
2498
MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
2499
                         "I/O operation would block.");
2500
MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
2501
                         "Connection error.");
2502
MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
2503
                         "Child process error.");
2504
MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
2505
                         "Broken pipe.");
2506
MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
2507
                         "Connection aborted.");
2508
MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
2509
                         "Connection refused.");
2510
MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
2511
                         "Connection reset.");
2512
MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
2513
                         "File already exists.");
2514
MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
2515
                         "File not found.");
2516
MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
2517
                         "Operation doesn't work on directories.");
2518
MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
2519
                         "Operation only works on directories.");
2520
MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
2521
                         "Interrupted by signal.");
2522
MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
2523
                         "Not enough permissions.");
2524
MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
2525
                         "Process not found.");
2526
MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
2527
                         "Timeout expired.");
2528
2529
/* Compatibility aliases */
2530
PyObject *PyExc_EnvironmentError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2531
PyObject *PyExc_IOError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2532
#ifdef MS_WINDOWS
2533
PyObject *PyExc_WindowsError = (PyObject *)&_PyExc_OSError;  // borrowed ref
2534
#endif
2535
2536
/*
2537
 *    EOFError extends Exception
2538
 */
2539
SimpleExtendsException(PyExc_Exception, EOFError,
2540
                       "Read beyond end of file.");
2541
2542
2543
/*
2544
 *    RuntimeError extends Exception
2545
 */
2546
SimpleExtendsException(PyExc_Exception, RuntimeError,
2547
                       "Unspecified run-time error.");
2548
2549
/*
2550
 *    RecursionError extends RuntimeError
2551
 */
2552
SimpleExtendsException(PyExc_RuntimeError, RecursionError,
2553
                       "Recursion limit exceeded.");
2554
2555
// PythonFinalizationError extends RuntimeError
2556
SimpleExtendsException(PyExc_RuntimeError, PythonFinalizationError,
2557
                       "Operation blocked during Python finalization.");
2558
2559
/*
2560
 *    NotImplementedError extends RuntimeError
2561
 */
2562
SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
2563
                       "Method or function hasn't been implemented yet.");
2564
2565
/*
2566
 *    NameError extends Exception
2567
 */
2568
2569
static inline PyNameErrorObject *
2570
PyNameErrorObject_CAST(PyObject *self)
2571
78
{
2572
78
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_NameError));
2573
78
    return (PyNameErrorObject *)self;
2574
78
}
2575
2576
static int
2577
NameError_init(PyObject *op, PyObject *args, PyObject *kwds)
2578
39
{
2579
39
    static char *kwlist[] = {"name", NULL};
2580
39
    PyObject *name = NULL;
2581
2582
39
    if (BaseException_init(op, args, NULL) == -1) {
2583
0
        return -1;
2584
0
    }
2585
2586
39
    PyObject *empty_tuple = PyTuple_New(0);
2587
39
    if (!empty_tuple) {
2588
0
        return -1;
2589
0
    }
2590
39
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
2591
39
                                     &name)) {
2592
0
        Py_DECREF(empty_tuple);
2593
0
        return -1;
2594
0
    }
2595
39
    Py_DECREF(empty_tuple);
2596
2597
39
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2598
39
    Py_XSETREF(self->name, Py_XNewRef(name));
2599
2600
39
    return 0;
2601
39
}
2602
2603
static int
2604
NameError_clear(PyObject *op)
2605
39
{
2606
39
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2607
39
    Py_CLEAR(self->name);
2608
39
    return BaseException_clear(op);
2609
39
}
2610
2611
static void
2612
NameError_dealloc(PyObject *self)
2613
39
{
2614
39
    _PyObject_GC_UNTRACK(self);
2615
39
    (void)NameError_clear(self);
2616
39
    Py_TYPE(self)->tp_free(self);
2617
39
}
2618
2619
static int
2620
NameError_traverse(PyObject *op, visitproc visit, void *arg)
2621
0
{
2622
0
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2623
0
    Py_VISIT(self->name);
2624
0
    return BaseException_traverse(op, visit, arg);
2625
0
}
2626
2627
static PyMemberDef NameError_members[] = {
2628
        {"name", _Py_T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
2629
        {NULL}  /* Sentinel */
2630
};
2631
2632
static PyMethodDef NameError_methods[] = {
2633
        {NULL}  /* Sentinel */
2634
};
2635
2636
ComplexExtendsException(PyExc_Exception, NameError,
2637
                        NameError, 0,
2638
                        NameError_methods, NameError_members,
2639
                        0, BaseException_str, 0, "Name not found globally.");
2640
2641
/*
2642
 *    UnboundLocalError extends NameError
2643
 */
2644
2645
MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
2646
                       "Local name referenced but not bound to a value.");
2647
2648
/*
2649
 *    AttributeError extends Exception
2650
 */
2651
2652
static inline PyAttributeErrorObject *
2653
PyAttributeErrorObject_CAST(PyObject *self)
2654
1.93M
{
2655
1.93M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
2656
1.93M
    return (PyAttributeErrorObject *)self;
2657
1.93M
}
2658
2659
static int
2660
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
2661
968k
{
2662
968k
    static char *kwlist[] = {"name", "obj", NULL};
2663
968k
    PyObject *name = NULL;
2664
968k
    PyObject *obj = NULL;
2665
2666
968k
    if (BaseException_init(op, args, NULL) == -1) {
2667
0
        return -1;
2668
0
    }
2669
2670
968k
    PyObject *empty_tuple = PyTuple_New(0);
2671
968k
    if (!empty_tuple) {
2672
0
        return -1;
2673
0
    }
2674
968k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2675
968k
                                     &name, &obj)) {
2676
0
        Py_DECREF(empty_tuple);
2677
0
        return -1;
2678
0
    }
2679
968k
    Py_DECREF(empty_tuple);
2680
2681
968k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2682
968k
    Py_XSETREF(self->name, Py_XNewRef(name));
2683
968k
    Py_XSETREF(self->obj, Py_XNewRef(obj));
2684
2685
968k
    return 0;
2686
968k
}
2687
2688
static int
2689
AttributeError_clear(PyObject *op)
2690
968k
{
2691
968k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2692
968k
    Py_CLEAR(self->obj);
2693
968k
    Py_CLEAR(self->name);
2694
968k
    return BaseException_clear(op);
2695
968k
}
2696
2697
static void
2698
AttributeError_dealloc(PyObject *self)
2699
968k
{
2700
968k
    _PyObject_GC_UNTRACK(self);
2701
968k
    (void)AttributeError_clear(self);
2702
968k
    Py_TYPE(self)->tp_free(self);
2703
968k
}
2704
2705
static int
2706
AttributeError_traverse(PyObject *op, visitproc visit, void *arg)
2707
434
{
2708
434
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2709
434
    Py_VISIT(self->obj);
2710
434
    Py_VISIT(self->name);
2711
434
    return BaseException_traverse(op, visit, arg);
2712
434
}
2713
2714
/* Pickling support */
2715
static PyObject *
2716
AttributeError_getstate(PyObject *op, PyObject *Py_UNUSED(ignored))
2717
0
{
2718
0
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2719
0
    PyObject *dict = self->dict;
2720
0
    if (self->name || self->args) {
2721
0
        dict = dict ? PyDict_Copy(dict) : PyDict_New();
2722
0
        if (dict == NULL) {
2723
0
            return NULL;
2724
0
        }
2725
0
        if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) {
2726
0
            Py_DECREF(dict);
2727
0
            return NULL;
2728
0
        }
2729
        /* We specifically are not pickling the obj attribute since there are many
2730
        cases where it is unlikely to be picklable. See GH-103352.
2731
        */
2732
0
        if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) {
2733
0
            Py_DECREF(dict);
2734
0
            return NULL;
2735
0
        }
2736
0
        return dict;
2737
0
    }
2738
0
    else if (dict) {
2739
0
        return Py_NewRef(dict);
2740
0
    }
2741
0
    Py_RETURN_NONE;
2742
0
}
2743
2744
static PyObject *
2745
AttributeError_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
2746
0
{
2747
0
    PyObject *state = AttributeError_getstate(op, NULL);
2748
0
    if (state == NULL) {
2749
0
        return NULL;
2750
0
    }
2751
2752
0
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2753
0
    PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state);
2754
0
    Py_DECREF(state);
2755
0
    return return_value;
2756
0
}
2757
2758
static PyMemberDef AttributeError_members[] = {
2759
    {"name", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
2760
    {"obj", _Py_T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
2761
    {NULL}  /* Sentinel */
2762
};
2763
2764
static PyMethodDef AttributeError_methods[] = {
2765
    {"__getstate__", AttributeError_getstate, METH_NOARGS},
2766
    {"__reduce__", AttributeError_reduce, METH_NOARGS },
2767
    {NULL}
2768
};
2769
2770
ComplexExtendsException(PyExc_Exception, AttributeError,
2771
                        AttributeError, 0,
2772
                        AttributeError_methods, AttributeError_members,
2773
                        0, BaseException_str, 0, "Attribute not found.");
2774
2775
/*
2776
 *    SyntaxError extends Exception
2777
 */
2778
2779
static inline PySyntaxErrorObject *
2780
PySyntaxErrorObject_CAST(PyObject *self)
2781
60.2k
{
2782
60.2k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
2783
60.2k
    return (PySyntaxErrorObject *)self;
2784
60.2k
}
2785
2786
static int
2787
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
2788
30.1k
{
2789
30.1k
    PyObject *info = NULL;
2790
30.1k
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2791
2792
30.1k
    if (BaseException_init(op, args, kwds) == -1)
2793
0
        return -1;
2794
2795
30.1k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2796
30.1k
    if (lenargs >= 1) {
2797
30.1k
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
2798
30.1k
    }
2799
30.1k
    if (lenargs == 2) {
2800
12.6k
        info = PyTuple_GET_ITEM(args, 1);
2801
12.6k
        info = PySequence_Tuple(info);
2802
12.6k
        if (!info) {
2803
0
            return -1;
2804
0
        }
2805
2806
12.6k
        self->end_lineno = NULL;
2807
12.6k
        self->end_offset = NULL;
2808
12.6k
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
2809
12.6k
                              &self->filename, &self->lineno,
2810
12.6k
                              &self->offset, &self->text,
2811
12.6k
                              &self->end_lineno, &self->end_offset, &self->metadata)) {
2812
0
            Py_DECREF(info);
2813
0
            return -1;
2814
0
        }
2815
2816
12.6k
        Py_INCREF(self->filename);
2817
12.6k
        Py_INCREF(self->lineno);
2818
12.6k
        Py_INCREF(self->offset);
2819
12.6k
        Py_INCREF(self->text);
2820
12.6k
        Py_XINCREF(self->end_lineno);
2821
12.6k
        Py_XINCREF(self->end_offset);
2822
12.6k
        Py_XINCREF(self->metadata);
2823
12.6k
        Py_DECREF(info);
2824
2825
12.6k
        if (self->end_lineno != NULL && self->end_offset == NULL) {
2826
0
            PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
2827
0
            return -1;
2828
0
        }
2829
12.6k
    }
2830
30.1k
    return 0;
2831
30.1k
}
2832
2833
static int
2834
SyntaxError_clear(PyObject *op)
2835
30.1k
{
2836
30.1k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2837
30.1k
    Py_CLEAR(self->msg);
2838
30.1k
    Py_CLEAR(self->filename);
2839
30.1k
    Py_CLEAR(self->lineno);
2840
30.1k
    Py_CLEAR(self->offset);
2841
30.1k
    Py_CLEAR(self->end_lineno);
2842
30.1k
    Py_CLEAR(self->end_offset);
2843
30.1k
    Py_CLEAR(self->text);
2844
30.1k
    Py_CLEAR(self->print_file_and_line);
2845
30.1k
    Py_CLEAR(self->metadata);
2846
30.1k
    return BaseException_clear(op);
2847
30.1k
}
2848
2849
static void
2850
SyntaxError_dealloc(PyObject *self)
2851
30.1k
{
2852
30.1k
    _PyObject_GC_UNTRACK(self);
2853
30.1k
    (void)SyntaxError_clear(self);
2854
30.1k
    Py_TYPE(self)->tp_free(self);
2855
30.1k
}
2856
2857
static int
2858
SyntaxError_traverse(PyObject *op, visitproc visit, void *arg)
2859
0
{
2860
0
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2861
0
    Py_VISIT(self->msg);
2862
0
    Py_VISIT(self->filename);
2863
0
    Py_VISIT(self->lineno);
2864
0
    Py_VISIT(self->offset);
2865
0
    Py_VISIT(self->end_lineno);
2866
0
    Py_VISIT(self->end_offset);
2867
0
    Py_VISIT(self->text);
2868
0
    Py_VISIT(self->print_file_and_line);
2869
0
    Py_VISIT(self->metadata);
2870
0
    return BaseException_traverse(op, visit, arg);
2871
0
}
2872
2873
/* This is called "my_basename" instead of just "basename" to avoid name
2874
   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
2875
   defined, and Python does define that. */
2876
static PyObject*
2877
my_basename(PyObject *name)
2878
0
{
2879
0
    Py_ssize_t i, size, offset;
2880
0
    int kind;
2881
0
    const void *data;
2882
2883
0
    kind = PyUnicode_KIND(name);
2884
0
    data = PyUnicode_DATA(name);
2885
0
    size = PyUnicode_GET_LENGTH(name);
2886
0
    offset = 0;
2887
0
    for(i=0; i < size; i++) {
2888
0
        if (PyUnicode_READ(kind, data, i) == SEP) {
2889
0
            offset = i + 1;
2890
0
        }
2891
0
    }
2892
0
    if (offset != 0) {
2893
0
        return PyUnicode_Substring(name, offset, size);
2894
0
    }
2895
0
    else {
2896
0
        return Py_NewRef(name);
2897
0
    }
2898
0
}
2899
2900
2901
static PyObject *
2902
SyntaxError_str(PyObject *op)
2903
0
{
2904
0
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2905
0
    int have_lineno = 0;
2906
0
    PyObject *filename;
2907
0
    PyObject *result;
2908
    /* Below, we always ignore overflow errors, just printing -1.
2909
       Still, we cannot allow an OverflowError to be raised, so
2910
       we need to call PyLong_AsLongAndOverflow. */
2911
0
    int overflow;
2912
2913
    /* XXX -- do all the additional formatting with filename and
2914
       lineno here */
2915
2916
0
    if (self->filename && PyUnicode_Check(self->filename)) {
2917
0
        filename = my_basename(self->filename);
2918
0
        if (filename == NULL)
2919
0
            return NULL;
2920
0
    } else {
2921
0
        filename = NULL;
2922
0
    }
2923
0
    have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
2924
2925
0
    if (!filename && !have_lineno)
2926
0
        return PyObject_Str(self->msg ? self->msg : Py_None);
2927
2928
    // Even if 'filename' can be an instance of a subclass of 'str',
2929
    // we only render its "true" content and do not use str(filename).
2930
0
    if (filename && have_lineno)
2931
0
        result = PyUnicode_FromFormat("%S (%U, line %ld)",
2932
0
                   self->msg ? self->msg : Py_None,
2933
0
                   filename,
2934
0
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2935
0
    else if (filename)
2936
0
        result = PyUnicode_FromFormat("%S (%U)",
2937
0
                   self->msg ? self->msg : Py_None,
2938
0
                   filename);
2939
0
    else /* only have_lineno */
2940
0
        result = PyUnicode_FromFormat("%S (line %ld)",
2941
0
                   self->msg ? self->msg : Py_None,
2942
0
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2943
0
    Py_XDECREF(filename);
2944
0
    return result;
2945
0
}
2946
2947
static PyMemberDef SyntaxError_members[] = {
2948
    {"msg", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
2949
        PyDoc_STR("exception msg")},
2950
    {"filename", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
2951
        PyDoc_STR("exception filename")},
2952
    {"lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
2953
        PyDoc_STR("exception lineno")},
2954
    {"offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
2955
        PyDoc_STR("exception offset")},
2956
    {"text", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
2957
        PyDoc_STR("exception text")},
2958
    {"end_lineno", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
2959
                   PyDoc_STR("exception end lineno")},
2960
    {"end_offset", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
2961
                   PyDoc_STR("exception end offset")},
2962
    {"print_file_and_line", _Py_T_OBJECT,
2963
        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
2964
        PyDoc_STR("exception print_file_and_line")},
2965
    {"_metadata", _Py_T_OBJECT, offsetof(PySyntaxErrorObject, metadata), 0,
2966
                   PyDoc_STR("exception private metadata")},
2967
    {NULL}  /* Sentinel */
2968
};
2969
2970
ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
2971
                        0, 0, SyntaxError_members, 0,
2972
                        SyntaxError_str, 0, "Invalid syntax.");
2973
2974
2975
/*
2976
 *    IndentationError extends SyntaxError
2977
 */
2978
MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
2979
                         "Improper indentation.");
2980
2981
2982
/*
2983
 *    TabError extends IndentationError
2984
 */
2985
MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
2986
                         "Improper mixture of spaces and tabs.");
2987
2988
/*
2989
 *    IncompleteInputError extends SyntaxError
2990
 */
2991
MiddlingExtendsExceptionEx(PyExc_SyntaxError, IncompleteInputError, _IncompleteInputError,
2992
                           SyntaxError, "incomplete input.");
2993
2994
/*
2995
 *    LookupError extends Exception
2996
 */
2997
SimpleExtendsException(PyExc_Exception, LookupError,
2998
                       "Base class for lookup errors.");
2999
3000
3001
/*
3002
 *    IndexError extends LookupError
3003
 */
3004
SimpleExtendsException(PyExc_LookupError, IndexError,
3005
                       "Sequence index out of range.");
3006
3007
3008
/*
3009
 *    KeyError extends LookupError
3010
 */
3011
3012
static PyObject *
3013
KeyError_str(PyObject *op)
3014
0
{
3015
    /* If args is a tuple of exactly one item, apply repr to args[0].
3016
       This is done so that e.g. the exception raised by {}[''] prints
3017
         KeyError: ''
3018
       rather than the confusing
3019
         KeyError
3020
       alone.  The downside is that if KeyError is raised with an explanatory
3021
       string, that string will be displayed in quotes.  Too bad.
3022
       If args is anything else, use the default BaseException__str__().
3023
    */
3024
0
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
3025
0
    if (PyTuple_GET_SIZE(self->args) == 1) {
3026
0
        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
3027
0
    }
3028
0
    return BaseException_str(op);
3029
0
}
3030
3031
ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
3032
                        0, 0, 0, 0, KeyError_str, 0, "Mapping key not found.");
3033
3034
3035
/*
3036
 *    ValueError extends Exception
3037
 */
3038
SimpleExtendsException(PyExc_Exception, ValueError,
3039
                       "Inappropriate argument value (of correct type).");
3040
3041
/*
3042
 *    UnicodeError extends ValueError
3043
 */
3044
3045
SimpleExtendsException(PyExc_ValueError, UnicodeError,
3046
                       "Unicode related error.");
3047
3048
3049
/*
3050
 * Check the validity of 'attr' as a unicode or bytes object depending
3051
 * on 'as_bytes'.
3052
 *
3053
 * The 'name' is the attribute name and is only used for error reporting.
3054
 *
3055
 * On success, this returns 0.
3056
 * On failure, this sets a TypeError and returns -1.
3057
 */
3058
static int
3059
check_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
3060
615k
{
3061
615k
    assert(as_bytes == 0 || as_bytes == 1);
3062
615k
    if (attr == NULL) {
3063
0
        PyErr_Format(PyExc_TypeError,
3064
0
                     "UnicodeError '%s' attribute is not set",
3065
0
                     name);
3066
0
        return -1;
3067
0
    }
3068
615k
    if (!(as_bytes ? PyBytes_Check(attr) : PyUnicode_Check(attr))) {
3069
0
        PyErr_Format(PyExc_TypeError,
3070
0
                     "UnicodeError '%s' attribute must be a %s",
3071
0
                     name, as_bytes ? "bytes" : "string");
3072
0
        return -1;
3073
0
    }
3074
615k
    return 0;
3075
615k
}
3076
3077
3078
/*
3079
 * Check the validity of 'attr' as a unicode or bytes object depending
3080
 * on 'as_bytes' and return a new reference on it if it is the case.
3081
 *
3082
 * The 'name' is the attribute name and is only used for error reporting.
3083
 *
3084
 * On success, this returns a strong reference on 'attr'.
3085
 * On failure, this sets a TypeError and returns NULL.
3086
 */
3087
static PyObject *
3088
as_unicode_error_attribute(PyObject *attr, const char *name, int as_bytes)
3089
613k
{
3090
613k
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
3091
613k
    return rc < 0 ? NULL : Py_NewRef(attr);
3092
613k
}
3093
3094
3095
#define PyUnicodeError_Check(PTR)   \
3096
1.30M
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3097
#define PyUnicodeError_CAST(PTR)    \
3098
1.36M
    (assert(PyUnicodeError_Check(PTR)), ((PyUnicodeErrorObject *)(PTR)))
3099
3100
3101
/* class names to use when reporting errors */
3102
0
#define Py_UNICODE_ENCODE_ERROR_NAME        "UnicodeEncodeError"
3103
1.30M
#define Py_UNICODE_DECODE_ERROR_NAME        "UnicodeDecodeError"
3104
0
#define Py_UNICODE_TRANSLATE_ERROR_NAME     "UnicodeTranslateError"
3105
3106
3107
/*
3108
 * Check that 'self' is a UnicodeError object.
3109
 *
3110
 * On success, this returns 0.
3111
 * On failure, this sets a TypeError exception and returns -1.
3112
 *
3113
 * The 'expect_type' is the name of the expected type, which is
3114
 * only used for error reporting.
3115
 *
3116
 * As an implementation detail, the `PyUnicode*Error_*` functions
3117
 * currently allow *any* subclass of UnicodeError as 'self'.
3118
 *
3119
 * Use one of the `Py_UNICODE_*_ERROR_NAME` macros to avoid typos.
3120
 */
3121
static inline int
3122
check_unicode_error_type(PyObject *self, const char *expect_type)
3123
1.30M
{
3124
1.30M
    assert(self != NULL);
3125
1.30M
    if (!PyUnicodeError_Check(self)) {
3126
0
        PyErr_Format(PyExc_TypeError,
3127
0
                     "expecting a %s object, got %T", expect_type, self);
3128
0
        return -1;
3129
0
    }
3130
1.30M
    return 0;
3131
1.30M
}
3132
3133
3134
// --- PyUnicodeEncodeObject: internal helpers --------------------------------
3135
//
3136
// In the helpers below, the caller is responsible to ensure that 'self'
3137
// is a PyUnicodeErrorObject, although this is verified on DEBUG builds
3138
// through PyUnicodeError_CAST().
3139
3140
/*
3141
 * Return the underlying (str) 'encoding' attribute of a UnicodeError object.
3142
 */
3143
static inline PyObject *
3144
unicode_error_get_encoding_impl(PyObject *self)
3145
0
{
3146
0
    assert(self != NULL);
3147
0
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3148
0
    return as_unicode_error_attribute(exc->encoding, "encoding", false);
3149
0
}
3150
3151
3152
/*
3153
 * Return the underlying 'object' attribute of a UnicodeError object
3154
 * as a bytes or a string instance, depending on the 'as_bytes' flag.
3155
 */
3156
static inline PyObject *
3157
unicode_error_get_object_impl(PyObject *self, int as_bytes)
3158
291k
{
3159
291k
    assert(self != NULL);
3160
291k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3161
291k
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
3162
291k
}
3163
3164
3165
/*
3166
 * Return the underlying (str) 'reason' attribute of a UnicodeError object.
3167
 */
3168
static inline PyObject *
3169
unicode_error_get_reason_impl(PyObject *self)
3170
0
{
3171
0
    assert(self != NULL);
3172
0
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3173
0
    return as_unicode_error_attribute(exc->reason, "reason", false);
3174
0
}
3175
3176
3177
/*
3178
 * Set the underlying (str) 'reason' attribute of a UnicodeError object.
3179
 *
3180
 * Return 0 on success and -1 on failure.
3181
 */
3182
static inline int
3183
unicode_error_set_reason_impl(PyObject *self, const char *reason)
3184
251k
{
3185
251k
    assert(self != NULL);
3186
251k
    PyObject *value = PyUnicode_FromString(reason);
3187
251k
    if (value == NULL) {
3188
0
        return -1;
3189
0
    }
3190
251k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3191
251k
    Py_XSETREF(exc->reason, value);
3192
251k
    return 0;
3193
251k
}
3194
3195
3196
/*
3197
 * Set the 'start' attribute of a UnicodeError object.
3198
 *
3199
 * Return 0 on success and -1 on failure.
3200
 */
3201
static inline int
3202
unicode_error_set_start_impl(PyObject *self, Py_ssize_t start)
3203
251k
{
3204
251k
    assert(self != NULL);
3205
251k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3206
251k
    exc->start = start;
3207
251k
    return 0;
3208
251k
}
3209
3210
3211
/*
3212
 * Set the 'end' attribute of a UnicodeError object.
3213
 *
3214
 * Return 0 on success and -1 on failure.
3215
 */
3216
static inline int
3217
unicode_error_set_end_impl(PyObject *self, Py_ssize_t end)
3218
251k
{
3219
251k
    assert(self != NULL);
3220
251k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3221
251k
    exc->end = end;
3222
251k
    return 0;
3223
251k
}
3224
3225
// --- PyUnicodeEncodeObject: internal getters --------------------------------
3226
3227
/*
3228
 * Adjust the (inclusive) 'start' value of a UnicodeError object.
3229
 *
3230
 * The 'start' can be negative or not, but when adjusting the value,
3231
 * we clip it in [0, max(0, objlen - 1)] and do not interpret it as
3232
 * a relative offset.
3233
 *
3234
 * This function always succeeds.
3235
 */
3236
static Py_ssize_t
3237
unicode_error_adjust_start(Py_ssize_t start, Py_ssize_t objlen)
3238
65.4k
{
3239
65.4k
    assert(objlen >= 0);
3240
65.4k
    if (start < 0) {
3241
0
        start = 0;
3242
0
    }
3243
65.4k
    if (start >= objlen) {
3244
0
        start = objlen == 0 ? 0 : objlen - 1;
3245
0
    }
3246
65.4k
    return start;
3247
65.4k
}
3248
3249
3250
/* Assert some properties of the adjusted 'start' value. */
3251
#ifndef NDEBUG
3252
static void
3253
assert_adjusted_unicode_error_start(Py_ssize_t start, Py_ssize_t objlen)
3254
{
3255
    assert(objlen >= 0);
3256
    /* in the future, `min_start` may be something else */
3257
    Py_ssize_t min_start = 0;
3258
    assert(start >= min_start);
3259
    /* in the future, `max_start` may be something else */
3260
    Py_ssize_t max_start = Py_MAX(min_start, objlen - 1);
3261
    assert(start <= max_start);
3262
}
3263
#else
3264
#define assert_adjusted_unicode_error_start(...)
3265
#endif
3266
3267
3268
/*
3269
 * Adjust the (exclusive) 'end' value of a UnicodeError object.
3270
 *
3271
 * The 'end' can be negative or not, but when adjusting the value,
3272
 * we clip it in [min(1, objlen), max(min(1, objlen), objlen)] and
3273
 * do not interpret it as a relative offset.
3274
 *
3275
 * This function always succeeds.
3276
 */
3277
static Py_ssize_t
3278
unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
3279
321k
{
3280
321k
    assert(objlen >= 0);
3281
321k
    if (end < 1) {
3282
0
        end = 1;
3283
0
    }
3284
321k
    if (end > objlen) {
3285
0
        end = objlen;
3286
0
    }
3287
321k
    return end;
3288
321k
}
3289
3290
#define PyUnicodeError_Check(PTR)   \
3291
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3292
#define PyUnicodeErrorObject_CAST(op)   \
3293
5.76M
    (assert(PyUnicodeError_Check(op)), ((PyUnicodeErrorObject *)(op)))
3294
3295
/* Assert some properties of the adjusted 'end' value. */
3296
#ifndef NDEBUG
3297
static void
3298
assert_adjusted_unicode_error_end(Py_ssize_t end, Py_ssize_t objlen)
3299
{
3300
    assert(objlen >= 0);
3301
    /* in the future, `min_end` may be something else */
3302
    Py_ssize_t min_end = Py_MIN(1, objlen);
3303
    assert(end >= min_end);
3304
    /* in the future, `max_end` may be something else */
3305
    Py_ssize_t max_end = Py_MAX(min_end, objlen);
3306
    assert(end <= max_end);
3307
}
3308
#else
3309
#define assert_adjusted_unicode_error_end(...)
3310
#endif
3311
3312
3313
/*
3314
 * Adjust the length of the range described by a UnicodeError object.
3315
 *
3316
 * The 'start' and 'end' arguments must have been obtained by
3317
 * unicode_error_adjust_start() and unicode_error_adjust_end().
3318
 *
3319
 * The result is clipped in [0, objlen]. By construction, it
3320
 * will always be smaller than 'objlen' as 'start' and 'end'
3321
 * are smaller than 'objlen'.
3322
 */
3323
static Py_ssize_t
3324
unicode_error_adjust_len(Py_ssize_t start, Py_ssize_t end, Py_ssize_t objlen)
3325
65.4k
{
3326
65.4k
    assert_adjusted_unicode_error_start(start, objlen);
3327
65.4k
    assert_adjusted_unicode_error_end(end, objlen);
3328
65.4k
    Py_ssize_t ranlen = end - start;
3329
65.4k
    assert(ranlen <= objlen);
3330
65.4k
    return ranlen < 0 ? 0 : ranlen;
3331
65.4k
}
3332
3333
3334
/* Assert some properties of the adjusted range 'len' value. */
3335
#ifndef NDEBUG
3336
static void
3337
assert_adjusted_unicode_error_len(Py_ssize_t ranlen, Py_ssize_t objlen)
3338
{
3339
    assert(objlen >= 0);
3340
    assert(ranlen >= 0);
3341
    assert(ranlen <= objlen);
3342
}
3343
#else
3344
#define assert_adjusted_unicode_error_len(...)
3345
#endif
3346
3347
3348
/*
3349
 * Get various common parameters of a UnicodeError object.
3350
 *
3351
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3352
 * although this condition is verified by this function on DEBUG builds.
3353
 *
3354
 * Return 0 on success and -1 on failure.
3355
 *
3356
 * Output parameters:
3357
 *
3358
 *     obj          A strong reference to the 'object' attribute.
3359
 *     objlen       The 'object' length.
3360
 *     start        The clipped 'start' attribute.
3361
 *     end          The clipped 'end' attribute.
3362
 *     slen         The length of the slice described by the clipped 'start'
3363
 *                  and 'end' values. It always lies in [0, objlen].
3364
 *
3365
 * An output parameter can be NULL to indicate that
3366
 * the corresponding value does not need to be stored.
3367
 *
3368
 * Input parameter:
3369
 *
3370
 *     as_bytes     If true, the error's 'object' attribute must be a `bytes`,
3371
 *                  i.e. 'self' is a `UnicodeDecodeError` instance. Otherwise,
3372
 *                  the 'object' attribute must be a string.
3373
 *
3374
 *                  A TypeError is raised if the 'object' type is incompatible.
3375
 */
3376
int
3377
_PyUnicodeError_GetParams(PyObject *self,
3378
                          PyObject **obj, Py_ssize_t *objlen,
3379
                          Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t *slen,
3380
                          int as_bytes)
3381
321k
{
3382
321k
    assert(self != NULL);
3383
321k
    assert(as_bytes == 0 || as_bytes == 1);
3384
321k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3385
321k
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
3386
321k
    if (r == NULL) {
3387
0
        return -1;
3388
0
    }
3389
3390
321k
    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
3391
321k
    if (objlen != NULL) {
3392
0
        *objlen = n;
3393
0
    }
3394
3395
321k
    Py_ssize_t start_value = -1;
3396
321k
    if (start != NULL || slen != NULL) {
3397
65.4k
        start_value = unicode_error_adjust_start(exc->start, n);
3398
65.4k
    }
3399
321k
    if (start != NULL) {
3400
65.4k
        assert_adjusted_unicode_error_start(start_value, n);
3401
65.4k
        *start = start_value;
3402
65.4k
    }
3403
3404
321k
    Py_ssize_t end_value = -1;
3405
321k
    if (end != NULL || slen != NULL) {
3406
321k
        end_value = unicode_error_adjust_end(exc->end, n);
3407
321k
    }
3408
321k
    if (end != NULL) {
3409
321k
        assert_adjusted_unicode_error_end(end_value, n);
3410
321k
        *end = end_value;
3411
321k
    }
3412
3413
321k
    if (slen != NULL) {
3414
65.4k
        *slen = unicode_error_adjust_len(start_value, end_value, n);
3415
65.4k
        assert_adjusted_unicode_error_len(*slen, n);
3416
65.4k
    }
3417
3418
321k
    if (obj != NULL) {
3419
65.4k
        *obj = r;
3420
65.4k
    }
3421
256k
    else {
3422
256k
        Py_DECREF(r);
3423
256k
    }
3424
321k
    return 0;
3425
321k
}
3426
3427
3428
// --- PyUnicodeEncodeObject: 'encoding' getters ------------------------------
3429
// Note: PyUnicodeTranslateError does not have an 'encoding' attribute.
3430
3431
PyObject *
3432
PyUnicodeEncodeError_GetEncoding(PyObject *self)
3433
0
{
3434
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3435
0
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
3436
0
}
3437
3438
3439
PyObject *
3440
PyUnicodeDecodeError_GetEncoding(PyObject *self)
3441
0
{
3442
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3443
0
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
3444
0
}
3445
3446
3447
// --- PyUnicodeEncodeObject: 'object' getters --------------------------------
3448
3449
PyObject *
3450
PyUnicodeEncodeError_GetObject(PyObject *self)
3451
0
{
3452
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3453
0
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
3454
0
}
3455
3456
3457
PyObject *
3458
PyUnicodeDecodeError_GetObject(PyObject *self)
3459
291k
{
3460
291k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3461
291k
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
3462
291k
}
3463
3464
3465
PyObject *
3466
PyUnicodeTranslateError_GetObject(PyObject *self)
3467
0
{
3468
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3469
0
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, false);
3470
0
}
3471
3472
3473
// --- PyUnicodeEncodeObject: 'start' getters ---------------------------------
3474
3475
/*
3476
 * Specialization of _PyUnicodeError_GetParams() for the 'start' attribute.
3477
 *
3478
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3479
 * although this condition is verified by this function on DEBUG builds.
3480
 */
3481
static inline int
3482
unicode_error_get_start_impl(PyObject *self, Py_ssize_t *start, int as_bytes)
3483
0
{
3484
0
    assert(self != NULL);
3485
0
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3486
0
                                     start, NULL, NULL,
3487
0
                                     as_bytes);
3488
0
}
3489
3490
3491
int
3492
PyUnicodeEncodeError_GetStart(PyObject *self, Py_ssize_t *start)
3493
0
{
3494
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3495
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
3496
0
}
3497
3498
3499
int
3500
PyUnicodeDecodeError_GetStart(PyObject *self, Py_ssize_t *start)
3501
0
{
3502
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3503
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, true);
3504
0
}
3505
3506
3507
int
3508
PyUnicodeTranslateError_GetStart(PyObject *self, Py_ssize_t *start)
3509
0
{
3510
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3511
0
    return rc < 0 ? -1 : unicode_error_get_start_impl(self, start, false);
3512
0
}
3513
3514
3515
// --- PyUnicodeEncodeObject: 'start' setters ---------------------------------
3516
3517
int
3518
PyUnicodeEncodeError_SetStart(PyObject *self, Py_ssize_t start)
3519
0
{
3520
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3521
0
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3522
0
}
3523
3524
3525
int
3526
PyUnicodeDecodeError_SetStart(PyObject *self, Py_ssize_t start)
3527
251k
{
3528
251k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3529
251k
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3530
251k
}
3531
3532
3533
int
3534
PyUnicodeTranslateError_SetStart(PyObject *self, Py_ssize_t start)
3535
0
{
3536
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3537
0
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3538
0
}
3539
3540
3541
// --- PyUnicodeEncodeObject: 'end' getters -----------------------------------
3542
3543
/*
3544
 * Specialization of _PyUnicodeError_GetParams() for the 'end' attribute.
3545
 *
3546
 * The caller is responsible to ensure that 'self' is a PyUnicodeErrorObject,
3547
 * although this condition is verified by this function on DEBUG builds.
3548
 */
3549
static inline int
3550
unicode_error_get_end_impl(PyObject *self, Py_ssize_t *end, int as_bytes)
3551
256k
{
3552
256k
    assert(self != NULL);
3553
256k
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3554
256k
                                     NULL, end, NULL,
3555
256k
                                     as_bytes);
3556
256k
}
3557
3558
3559
int
3560
PyUnicodeEncodeError_GetEnd(PyObject *self, Py_ssize_t *end)
3561
0
{
3562
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3563
0
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
3564
0
}
3565
3566
3567
int
3568
PyUnicodeDecodeError_GetEnd(PyObject *self, Py_ssize_t *end)
3569
256k
{
3570
256k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3571
256k
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, true);
3572
256k
}
3573
3574
3575
int
3576
PyUnicodeTranslateError_GetEnd(PyObject *self, Py_ssize_t *end)
3577
0
{
3578
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3579
0
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, false);
3580
0
}
3581
3582
3583
// --- PyUnicodeEncodeObject: 'end' setters -----------------------------------
3584
3585
int
3586
PyUnicodeEncodeError_SetEnd(PyObject *self, Py_ssize_t end)
3587
0
{
3588
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3589
0
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3590
0
}
3591
3592
3593
int
3594
PyUnicodeDecodeError_SetEnd(PyObject *self, Py_ssize_t end)
3595
251k
{
3596
251k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3597
251k
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3598
251k
}
3599
3600
3601
int
3602
PyUnicodeTranslateError_SetEnd(PyObject *self, Py_ssize_t end)
3603
0
{
3604
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3605
0
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3606
0
}
3607
3608
3609
// --- PyUnicodeEncodeObject: 'reason' getters --------------------------------
3610
3611
PyObject *
3612
PyUnicodeEncodeError_GetReason(PyObject *self)
3613
0
{
3614
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3615
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3616
0
}
3617
3618
3619
PyObject *
3620
PyUnicodeDecodeError_GetReason(PyObject *self)
3621
0
{
3622
0
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3623
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3624
0
}
3625
3626
3627
PyObject *
3628
PyUnicodeTranslateError_GetReason(PyObject *self)
3629
0
{
3630
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3631
0
    return rc < 0 ? NULL : unicode_error_get_reason_impl(self);
3632
0
}
3633
3634
3635
// --- PyUnicodeEncodeObject: 'reason' setters --------------------------------
3636
3637
int
3638
PyUnicodeEncodeError_SetReason(PyObject *self, const char *reason)
3639
0
{
3640
0
    int rc = check_unicode_error_type(self, Py_UNICODE_ENCODE_ERROR_NAME);
3641
0
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3642
0
}
3643
3644
3645
int
3646
PyUnicodeDecodeError_SetReason(PyObject *self, const char *reason)
3647
251k
{
3648
251k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3649
251k
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3650
251k
}
3651
3652
3653
int
3654
PyUnicodeTranslateError_SetReason(PyObject *self, const char *reason)
3655
0
{
3656
0
    int rc = check_unicode_error_type(self, Py_UNICODE_TRANSLATE_ERROR_NAME);
3657
0
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3658
0
}
3659
3660
3661
static int
3662
UnicodeError_clear(PyObject *self)
3663
2.88M
{
3664
2.88M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3665
2.88M
    Py_CLEAR(exc->encoding);
3666
2.88M
    Py_CLEAR(exc->object);
3667
2.88M
    Py_CLEAR(exc->reason);
3668
2.88M
    return BaseException_clear(self);
3669
2.88M
}
3670
3671
static void
3672
UnicodeError_dealloc(PyObject *self)
3673
2.88M
{
3674
2.88M
    PyTypeObject *type = Py_TYPE(self);
3675
2.88M
    _PyObject_GC_UNTRACK(self);
3676
2.88M
    (void)UnicodeError_clear(self);
3677
2.88M
    type->tp_free(self);
3678
2.88M
}
3679
3680
static int
3681
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
3682
130
{
3683
130
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3684
130
    Py_VISIT(exc->encoding);
3685
130
    Py_VISIT(exc->object);
3686
130
    Py_VISIT(exc->reason);
3687
130
    return BaseException_traverse(self, visit, arg);
3688
130
}
3689
3690
static PyMemberDef UnicodeError_members[] = {
3691
    {"encoding", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
3692
        PyDoc_STR("exception encoding")},
3693
    {"object", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
3694
        PyDoc_STR("exception object")},
3695
    {"start", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
3696
        PyDoc_STR("exception start")},
3697
    {"end", Py_T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
3698
        PyDoc_STR("exception end")},
3699
    {"reason", _Py_T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
3700
        PyDoc_STR("exception reason")},
3701
    {NULL}  /* Sentinel */
3702
};
3703
3704
3705
/*
3706
 *    UnicodeEncodeError extends UnicodeError
3707
 */
3708
3709
static int
3710
UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
3711
195k
{
3712
195k
    if (BaseException_init(self, args, kwds) == -1) {
3713
0
        return -1;
3714
0
    }
3715
3716
195k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3717
195k
    Py_ssize_t start = -1, end = -1;
3718
3719
195k
    if (!PyArg_ParseTuple(args, "UUnnU",
3720
195k
                          &encoding, &object, &start, &end, &reason))
3721
0
    {
3722
0
        return -1;
3723
0
    }
3724
3725
195k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3726
195k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3727
195k
    Py_XSETREF(exc->object, Py_NewRef(object));
3728
195k
    exc->start = start;
3729
195k
    exc->end = end;
3730
195k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3731
195k
    return 0;
3732
195k
}
3733
3734
static PyObject *
3735
UnicodeEncodeError_str(PyObject *self)
3736
29
{
3737
29
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3738
29
    PyObject *result = NULL;
3739
29
    PyObject *reason_str = NULL;
3740
29
    PyObject *encoding_str = NULL;
3741
3742
29
    if (exc->object == NULL) {
3743
        /* Not properly initialized. */
3744
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3745
0
    }
3746
3747
    /* Get reason and encoding as strings, which they might not be if
3748
       they've been modified after we were constructed. */
3749
29
    reason_str = PyObject_Str(exc->reason);
3750
29
    if (reason_str == NULL) {
3751
0
        goto done;
3752
0
    }
3753
29
    encoding_str = PyObject_Str(exc->encoding);
3754
29
    if (encoding_str == NULL) {
3755
0
        goto done;
3756
0
    }
3757
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3758
29
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3759
0
        goto done;
3760
0
    }
3761
29
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3762
29
    Py_ssize_t start = exc->start, end = exc->end;
3763
3764
29
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3765
15
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3766
15
        const char *fmt;
3767
15
        if (badchar <= 0xff) {
3768
0
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
3769
0
        }
3770
15
        else if (badchar <= 0xffff) {
3771
15
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
3772
15
        }
3773
0
        else {
3774
0
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
3775
0
        }
3776
15
        result = PyUnicode_FromFormat(
3777
15
            fmt,
3778
15
            encoding_str,
3779
15
            (int)badchar,
3780
15
            start,
3781
15
            reason_str);
3782
15
    }
3783
14
    else {
3784
14
        result = PyUnicode_FromFormat(
3785
14
            "'%U' codec can't encode characters in position %zd-%zd: %U",
3786
14
            encoding_str,
3787
14
            start,
3788
14
            end - 1,
3789
14
            reason_str);
3790
14
    }
3791
29
done:
3792
29
    Py_XDECREF(reason_str);
3793
29
    Py_XDECREF(encoding_str);
3794
29
    return result;
3795
29
}
3796
3797
static PyTypeObject _PyExc_UnicodeEncodeError = {
3798
    PyVarObject_HEAD_INIT(NULL, 0)
3799
    "UnicodeEncodeError",
3800
    sizeof(PyUnicodeErrorObject), 0,
3801
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3802
    UnicodeEncodeError_str, 0, 0, 0,
3803
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3804
    PyDoc_STR("Unicode encoding error."), UnicodeError_traverse,
3805
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3806
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3807
    UnicodeEncodeError_init, 0, BaseException_new,
3808
};
3809
PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
3810
3811
3812
/*
3813
 *    UnicodeDecodeError extends UnicodeError
3814
 */
3815
3816
static int
3817
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
3818
2.68M
{
3819
2.68M
    if (BaseException_init(self, args, kwds) == -1) {
3820
0
        return -1;
3821
0
    }
3822
3823
2.68M
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3824
2.68M
    Py_ssize_t start = -1, end = -1;
3825
3826
2.68M
    if (!PyArg_ParseTuple(args, "UOnnU",
3827
2.68M
                          &encoding, &object, &start, &end, &reason))
3828
93
    {
3829
93
        return -1;
3830
93
    }
3831
3832
2.68M
    if (PyBytes_Check(object)) {
3833
2.68M
        Py_INCREF(object);  // make 'object' a strong reference
3834
2.68M
    }
3835
0
    else {
3836
0
        Py_buffer view;
3837
0
        if (PyObject_GetBuffer(object, &view, PyBUF_SIMPLE) != 0) {
3838
0
            return -1;
3839
0
        }
3840
        // 'object' is borrowed, so we can re-use the variable
3841
0
        object = PyBytes_FromStringAndSize(view.buf, view.len);
3842
0
        PyBuffer_Release(&view);
3843
0
        if (object == NULL) {
3844
0
            return -1;
3845
0
        }
3846
0
    }
3847
3848
2.68M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3849
2.68M
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3850
2.68M
    Py_XSETREF(exc->object, object /* already a strong reference */);
3851
2.68M
    exc->start = start;
3852
2.68M
    exc->end = end;
3853
2.68M
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3854
2.68M
    return 0;
3855
2.68M
}
3856
3857
static PyObject *
3858
UnicodeDecodeError_str(PyObject *self)
3859
1.30k
{
3860
1.30k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3861
1.30k
    PyObject *result = NULL;
3862
1.30k
    PyObject *reason_str = NULL;
3863
1.30k
    PyObject *encoding_str = NULL;
3864
3865
1.30k
    if (exc->object == NULL) {
3866
        /* Not properly initialized. */
3867
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3868
0
    }
3869
3870
    /* Get reason and encoding as strings, which they might not be if
3871
       they've been modified after we were constructed. */
3872
1.30k
    reason_str = PyObject_Str(exc->reason);
3873
1.30k
    if (reason_str == NULL) {
3874
0
        goto done;
3875
0
    }
3876
1.30k
    encoding_str = PyObject_Str(exc->encoding);
3877
1.30k
    if (encoding_str == NULL) {
3878
0
        goto done;
3879
0
    }
3880
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3881
1.30k
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
3882
0
        goto done;
3883
0
    }
3884
1.30k
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
3885
1.30k
    Py_ssize_t start = exc->start, end = exc->end;
3886
3887
1.30k
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3888
720
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
3889
720
        result = PyUnicode_FromFormat(
3890
720
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3891
720
            encoding_str,
3892
720
            badbyte,
3893
720
            start,
3894
720
            reason_str);
3895
720
    }
3896
587
    else {
3897
587
        result = PyUnicode_FromFormat(
3898
587
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3899
587
            encoding_str,
3900
587
            start,
3901
587
            end - 1,
3902
587
            reason_str);
3903
587
    }
3904
1.30k
done:
3905
1.30k
    Py_XDECREF(reason_str);
3906
1.30k
    Py_XDECREF(encoding_str);
3907
1.30k
    return result;
3908
1.30k
}
3909
3910
static PyTypeObject _PyExc_UnicodeDecodeError = {
3911
    PyVarObject_HEAD_INIT(NULL, 0)
3912
    "UnicodeDecodeError",
3913
    sizeof(PyUnicodeErrorObject), 0,
3914
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3915
    UnicodeDecodeError_str, 0, 0, 0,
3916
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3917
    PyDoc_STR("Unicode decoding error."), UnicodeError_traverse,
3918
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3919
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3920
    UnicodeDecodeError_init, 0, BaseException_new,
3921
};
3922
PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
3923
3924
PyObject *
3925
PyUnicodeDecodeError_Create(
3926
    const char *encoding, const char *object, Py_ssize_t length,
3927
    Py_ssize_t start, Py_ssize_t end, const char *reason)
3928
2.68M
{
3929
2.68M
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3930
2.68M
                                 encoding, object, length, start, end, reason);
3931
2.68M
}
3932
3933
3934
/*
3935
 *    UnicodeTranslateError extends UnicodeError
3936
 */
3937
3938
static int
3939
UnicodeTranslateError_init(PyObject *self, PyObject *args, PyObject *kwds)
3940
0
{
3941
0
    if (BaseException_init(self, args, kwds) == -1) {
3942
0
        return -1;
3943
0
    }
3944
3945
0
    PyObject *object = NULL, *reason = NULL;  // borrowed
3946
0
    Py_ssize_t start = -1, end = -1;
3947
3948
0
    if (!PyArg_ParseTuple(args, "UnnU", &object, &start, &end, &reason)) {
3949
0
        return -1;
3950
0
    }
3951
3952
0
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3953
0
    Py_XSETREF(exc->object, Py_NewRef(object));
3954
0
    exc->start = start;
3955
0
    exc->end = end;
3956
0
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3957
0
    return 0;
3958
0
}
3959
3960
3961
static PyObject *
3962
UnicodeTranslateError_str(PyObject *self)
3963
0
{
3964
0
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3965
0
    PyObject *result = NULL;
3966
0
    PyObject *reason_str = NULL;
3967
3968
0
    if (exc->object == NULL) {
3969
        /* Not properly initialized. */
3970
0
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
3971
0
    }
3972
3973
    /* Get reason as a string, which it might not be if it's been
3974
       modified after we were constructed. */
3975
0
    reason_str = PyObject_Str(exc->reason);
3976
0
    if (reason_str == NULL) {
3977
0
        goto done;
3978
0
    }
3979
    // call to PyObject_Str(...) above might mutate 'exc->object'
3980
0
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3981
0
        goto done;
3982
0
    }
3983
0
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3984
0
    Py_ssize_t start = exc->start, end = exc->end;
3985
3986
0
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3987
0
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3988
0
        const char *fmt;
3989
0
        if (badchar <= 0xff) {
3990
0
            fmt = "can't translate character '\\x%02x' in position %zd: %U";
3991
0
        }
3992
0
        else if (badchar <= 0xffff) {
3993
0
            fmt = "can't translate character '\\u%04x' in position %zd: %U";
3994
0
        }
3995
0
        else {
3996
0
            fmt = "can't translate character '\\U%08x' in position %zd: %U";
3997
0
        }
3998
0
        result = PyUnicode_FromFormat(
3999
0
            fmt,
4000
0
            (int)badchar,
4001
0
            start,
4002
0
            reason_str);
4003
0
    }
4004
0
    else {
4005
0
        result = PyUnicode_FromFormat(
4006
0
            "can't translate characters in position %zd-%zd: %U",
4007
0
            start,
4008
0
            end - 1,
4009
0
            reason_str);
4010
0
    }
4011
0
done:
4012
0
    Py_XDECREF(reason_str);
4013
0
    return result;
4014
0
}
4015
4016
static PyTypeObject _PyExc_UnicodeTranslateError = {
4017
    PyVarObject_HEAD_INIT(NULL, 0)
4018
    "UnicodeTranslateError",
4019
    sizeof(PyUnicodeErrorObject), 0,
4020
    UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4021
    UnicodeTranslateError_str, 0, 0, 0,
4022
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
4023
    PyDoc_STR("Unicode translation error."), UnicodeError_traverse,
4024
    UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
4025
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
4026
    UnicodeTranslateError_init, 0, BaseException_new,
4027
};
4028
PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
4029
4030
PyObject *
4031
_PyUnicodeTranslateError_Create(
4032
    PyObject *object,
4033
    Py_ssize_t start, Py_ssize_t end, const char *reason)
4034
0
{
4035
0
    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
4036
0
                                 object, start, end, reason);
4037
0
}
4038
4039
/*
4040
 *    AssertionError extends Exception
4041
 */
4042
SimpleExtendsException(PyExc_Exception, AssertionError,
4043
                       "Assertion failed.");
4044
4045
4046
/*
4047
 *    ArithmeticError extends Exception
4048
 */
4049
SimpleExtendsException(PyExc_Exception, ArithmeticError,
4050
                       "Base class for arithmetic errors.");
4051
4052
4053
/*
4054
 *    FloatingPointError extends ArithmeticError
4055
 */
4056
SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
4057
                       "Floating-point operation failed.");
4058
4059
4060
/*
4061
 *    OverflowError extends ArithmeticError
4062
 */
4063
SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
4064
                       "Result too large to be represented.");
4065
4066
4067
/*
4068
 *    ZeroDivisionError extends ArithmeticError
4069
 */
4070
SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
4071
          "Second argument to a division or modulo operation was zero.");
4072
4073
4074
/*
4075
 *    SystemError extends Exception
4076
 */
4077
SimpleExtendsException(PyExc_Exception, SystemError,
4078
    "Internal error in the Python interpreter.\n"
4079
    "\n"
4080
    "Please report this to the Python maintainer, along with the traceback,\n"
4081
    "the Python version, and the hardware/OS platform and version.");
4082
4083
4084
/*
4085
 *    ReferenceError extends Exception
4086
 */
4087
SimpleExtendsException(PyExc_Exception, ReferenceError,
4088
                       "Weak ref proxy used after referent went away.");
4089
4090
4091
/*
4092
 *    MemoryError extends Exception
4093
 */
4094
4095
1.61k
#define MEMERRORS_SAVE 16
4096
4097
#ifdef Py_GIL_DISABLED
4098
# define MEMERRORS_LOCK(state) PyMutex_LockFlags(&state->memerrors_lock, _Py_LOCK_DONT_DETACH)
4099
# define MEMERRORS_UNLOCK(state) PyMutex_Unlock(&state->memerrors_lock)
4100
#else
4101
1.05k
# define MEMERRORS_LOCK(state) ((void)0)
4102
1.05k
# define MEMERRORS_UNLOCK(state) ((void)0)
4103
#endif
4104
4105
static PyObject *
4106
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
4107
525
{
4108
525
    PyBaseExceptionObject *self = NULL;
4109
525
    struct _Py_exc_state *state = get_exc_state();
4110
4111
525
    MEMERRORS_LOCK(state);
4112
525
    if (state->memerrors_freelist != NULL) {
4113
        /* Fetch MemoryError from freelist and initialize it */
4114
13
        self = state->memerrors_freelist;
4115
13
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
4116
13
        state->memerrors_numfree--;
4117
13
        self->dict = NULL;
4118
13
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
4119
13
        _Py_NewReference((PyObject *)self);
4120
13
        _PyObject_GC_TRACK(self);
4121
13
    }
4122
525
    MEMERRORS_UNLOCK(state);
4123
4124
525
    if (self != NULL) {
4125
13
        return (PyObject *)self;
4126
13
    }
4127
4128
512
    if (!allow_allocation) {
4129
0
        PyInterpreterState *interp = _PyInterpreterState_GET();
4130
0
        return Py_NewRef(
4131
0
            &_Py_INTERP_SINGLETON(interp, last_resort_memory_error));
4132
0
    }
4133
512
    return BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds);
4134
512
}
4135
4136
static PyObject *
4137
MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4138
525
{
4139
    /* If this is a subclass of MemoryError, don't use the freelist
4140
     * and just return a fresh object */
4141
525
    if (type != (PyTypeObject *) PyExc_MemoryError) {
4142
0
        return BaseException_new(type, args, kwds);
4143
0
    }
4144
525
    return get_memory_error(1, args, kwds);
4145
525
}
4146
4147
PyObject *
4148
_PyErr_NoMemory(PyThreadState *tstate)
4149
0
{
4150
0
    if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
4151
        /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
4152
           initialized by _PyExc_Init() */
4153
0
        Py_FatalError("Out of memory and PyExc_MemoryError is not "
4154
0
                      "initialized yet");
4155
0
    }
4156
0
    PyObject *err = get_memory_error(0, NULL, NULL);
4157
0
    if (err != NULL) {
4158
0
        _PyErr_SetRaisedException(tstate, err);
4159
0
    }
4160
0
    return NULL;
4161
0
}
4162
4163
static void
4164
MemoryError_dealloc(PyObject *op)
4165
525
{
4166
525
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
4167
525
    _PyObject_GC_UNTRACK(self);
4168
4169
525
    (void)BaseException_clear(op);
4170
4171
    /* If this is a subclass of MemoryError, we don't need to
4172
     * do anything in the free-list*/
4173
525
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
4174
0
        Py_TYPE(self)->tp_free(op);
4175
0
        return;
4176
0
    }
4177
4178
525
    struct _Py_exc_state *state = get_exc_state();
4179
525
    MEMERRORS_LOCK(state);
4180
525
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
4181
525
        self->dict = (PyObject *) state->memerrors_freelist;
4182
525
        state->memerrors_freelist = self;
4183
525
        state->memerrors_numfree++;
4184
525
        MEMERRORS_UNLOCK(state);
4185
525
        return;
4186
525
    }
4187
0
    MEMERRORS_UNLOCK(state);
4188
4189
0
    Py_TYPE(self)->tp_free((PyObject *)self);
4190
0
}
4191
4192
static int
4193
preallocate_memerrors(void)
4194
32
{
4195
    /* We create enough MemoryErrors and then decref them, which will fill
4196
       up the freelist. */
4197
32
    int i;
4198
4199
32
    PyObject *errors[MEMERRORS_SAVE];
4200
544
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4201
512
        errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
4202
512
                                    NULL, NULL);
4203
512
        if (!errors[i]) {
4204
0
            return -1;
4205
0
        }
4206
512
    }
4207
544
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4208
512
        Py_DECREF(errors[i]);
4209
512
    }
4210
32
    return 0;
4211
32
}
4212
4213
static void
4214
free_preallocated_memerrors(struct _Py_exc_state *state)
4215
0
{
4216
0
    while (state->memerrors_freelist != NULL) {
4217
0
        PyObject *self = (PyObject *) state->memerrors_freelist;
4218
0
        state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
4219
0
        Py_TYPE(self)->tp_free(self);
4220
0
    }
4221
0
}
4222
4223
4224
PyTypeObject _PyExc_MemoryError = {
4225
    PyVarObject_HEAD_INIT(NULL, 0)
4226
    "MemoryError",
4227
    sizeof(PyBaseExceptionObject),
4228
    0, MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
4229
    0, 0, 0, 0, 0, 0, 0,
4230
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
4231
    PyDoc_STR("Out of memory."), BaseException_traverse,
4232
    BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
4233
    0, 0, 0, offsetof(PyBaseExceptionObject, dict),
4234
    BaseException_init, 0, MemoryError_new
4235
};
4236
PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
4237
4238
4239
/*
4240
 *    BufferError extends Exception
4241
 */
4242
SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
4243
4244
4245
/* Warning category docstrings */
4246
4247
/*
4248
 *    Warning extends Exception
4249
 */
4250
SimpleExtendsException(PyExc_Exception, Warning,
4251
                       "Base class for warning categories.");
4252
4253
4254
/*
4255
 *    UserWarning extends Warning
4256
 */
4257
SimpleExtendsException(PyExc_Warning, UserWarning,
4258
                       "Base class for warnings generated by user code.");
4259
4260
4261
/*
4262
 *    DeprecationWarning extends Warning
4263
 */
4264
SimpleExtendsException(PyExc_Warning, DeprecationWarning,
4265
                       "Base class for warnings about deprecated features.");
4266
4267
4268
/*
4269
 *    PendingDeprecationWarning extends Warning
4270
 */
4271
SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
4272
    "Base class for warnings about features which will be deprecated\n"
4273
    "in the future.");
4274
4275
4276
/*
4277
 *    SyntaxWarning extends Warning
4278
 */
4279
SimpleExtendsException(PyExc_Warning, SyntaxWarning,
4280
                       "Base class for warnings about dubious syntax.");
4281
4282
4283
/*
4284
 *    RuntimeWarning extends Warning
4285
 */
4286
SimpleExtendsException(PyExc_Warning, RuntimeWarning,
4287
                 "Base class for warnings about dubious runtime behavior.");
4288
4289
4290
/*
4291
 *    FutureWarning extends Warning
4292
 */
4293
SimpleExtendsException(PyExc_Warning, FutureWarning,
4294
    "Base class for warnings about constructs that will change semantically\n"
4295
    "in the future.");
4296
4297
4298
/*
4299
 *    ImportWarning extends Warning
4300
 */
4301
SimpleExtendsException(PyExc_Warning, ImportWarning,
4302
          "Base class for warnings about probable mistakes in module imports");
4303
4304
4305
/*
4306
 *    UnicodeWarning extends Warning
4307
 */
4308
SimpleExtendsException(PyExc_Warning, UnicodeWarning,
4309
    "Base class for warnings about Unicode related problems, mostly\n"
4310
    "related to conversion problems.");
4311
4312
4313
/*
4314
 *    BytesWarning extends Warning
4315
 */
4316
SimpleExtendsException(PyExc_Warning, BytesWarning,
4317
    "Base class for warnings about bytes and buffer related problems, mostly\n"
4318
    "related to conversion from str or comparing to str.");
4319
4320
4321
/*
4322
 *    EncodingWarning extends Warning
4323
 */
4324
SimpleExtendsException(PyExc_Warning, EncodingWarning,
4325
    "Base class for warnings about encodings.");
4326
4327
4328
/*
4329
 *    ResourceWarning extends Warning
4330
 */
4331
SimpleExtendsException(PyExc_Warning, ResourceWarning,
4332
    "Base class for warnings about resource usage.");
4333
4334
4335
4336
#ifdef MS_WINDOWS
4337
#include <winsock2.h>
4338
/* The following constants were added to errno.h in VS2010 but have
4339
   preferred WSA equivalents. */
4340
#undef EADDRINUSE
4341
#undef EADDRNOTAVAIL
4342
#undef EAFNOSUPPORT
4343
#undef EALREADY
4344
#undef ECONNABORTED
4345
#undef ECONNREFUSED
4346
#undef ECONNRESET
4347
#undef EDESTADDRREQ
4348
#undef EHOSTUNREACH
4349
#undef EINPROGRESS
4350
#undef EISCONN
4351
#undef ELOOP
4352
#undef EMSGSIZE
4353
#undef ENETDOWN
4354
#undef ENETRESET
4355
#undef ENETUNREACH
4356
#undef ENOBUFS
4357
#undef ENOPROTOOPT
4358
#undef ENOTCONN
4359
#undef ENOTSOCK
4360
#undef EOPNOTSUPP
4361
#undef EPROTONOSUPPORT
4362
#undef EPROTOTYPE
4363
#undef EWOULDBLOCK
4364
4365
#if defined(WSAEALREADY) && !defined(EALREADY)
4366
#define EALREADY WSAEALREADY
4367
#endif
4368
#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
4369
#define ECONNABORTED WSAECONNABORTED
4370
#endif
4371
#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
4372
#define ECONNREFUSED WSAECONNREFUSED
4373
#endif
4374
#if defined(WSAECONNRESET) && !defined(ECONNRESET)
4375
#define ECONNRESET WSAECONNRESET
4376
#endif
4377
#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
4378
#define EINPROGRESS WSAEINPROGRESS
4379
#endif
4380
#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
4381
#define ESHUTDOWN WSAESHUTDOWN
4382
#endif
4383
#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
4384
#define EWOULDBLOCK WSAEWOULDBLOCK
4385
#endif
4386
#endif /* MS_WINDOWS */
4387
4388
struct static_exception {
4389
    PyTypeObject *exc;
4390
    const char *name;
4391
};
4392
4393
static struct static_exception static_exceptions[] = {
4394
#define ITEM(NAME) {&_PyExc_##NAME, #NAME}
4395
    // Level 1
4396
    ITEM(BaseException),
4397
4398
    // Level 2: BaseException subclasses
4399
    ITEM(BaseExceptionGroup),
4400
    ITEM(Exception),
4401
    ITEM(GeneratorExit),
4402
    ITEM(KeyboardInterrupt),
4403
    ITEM(SystemExit),
4404
4405
    // Level 3: Exception(BaseException) subclasses
4406
    ITEM(ArithmeticError),
4407
    ITEM(AssertionError),
4408
    ITEM(AttributeError),
4409
    ITEM(BufferError),
4410
    ITEM(EOFError),
4411
    //ITEM(ExceptionGroup),
4412
    ITEM(ImportError),
4413
    ITEM(LookupError),
4414
    ITEM(MemoryError),
4415
    ITEM(NameError),
4416
    ITEM(OSError),
4417
    ITEM(ReferenceError),
4418
    ITEM(RuntimeError),
4419
    ITEM(StopAsyncIteration),
4420
    ITEM(StopIteration),
4421
    ITEM(SyntaxError),
4422
    ITEM(SystemError),
4423
    ITEM(TypeError),
4424
    ITEM(ValueError),
4425
    ITEM(Warning),
4426
4427
    // Level 4: ArithmeticError(Exception) subclasses
4428
    ITEM(FloatingPointError),
4429
    ITEM(OverflowError),
4430
    ITEM(ZeroDivisionError),
4431
4432
    // Level 4: Warning(Exception) subclasses
4433
    ITEM(BytesWarning),
4434
    ITEM(DeprecationWarning),
4435
    ITEM(EncodingWarning),
4436
    ITEM(FutureWarning),
4437
    ITEM(ImportWarning),
4438
    ITEM(PendingDeprecationWarning),
4439
    ITEM(ResourceWarning),
4440
    ITEM(RuntimeWarning),
4441
    ITEM(SyntaxWarning),
4442
    ITEM(UnicodeWarning),
4443
    ITEM(UserWarning),
4444
4445
    // Level 4: OSError(Exception) subclasses
4446
    ITEM(BlockingIOError),
4447
    ITEM(ChildProcessError),
4448
    ITEM(ConnectionError),
4449
    ITEM(FileExistsError),
4450
    ITEM(FileNotFoundError),
4451
    ITEM(InterruptedError),
4452
    ITEM(IsADirectoryError),
4453
    ITEM(NotADirectoryError),
4454
    ITEM(PermissionError),
4455
    ITEM(ProcessLookupError),
4456
    ITEM(TimeoutError),
4457
4458
    // Level 4: Other subclasses
4459
    ITEM(IndentationError), // base: SyntaxError(Exception)
4460
    {&_PyExc_IncompleteInputError, "_IncompleteInputError"}, // base: SyntaxError(Exception)
4461
    ITEM(IndexError),  // base: LookupError(Exception)
4462
    ITEM(KeyError),  // base: LookupError(Exception)
4463
    ITEM(ImportCycleError), // base: ImportError(Exception)
4464
    ITEM(ModuleNotFoundError), // base: ImportError(Exception)
4465
    ITEM(NotImplementedError),  // base: RuntimeError(Exception)
4466
    ITEM(PythonFinalizationError),  // base: RuntimeError(Exception)
4467
    ITEM(RecursionError),  // base: RuntimeError(Exception)
4468
    ITEM(UnboundLocalError), // base: NameError(Exception)
4469
    ITEM(UnicodeError),  // base: ValueError(Exception)
4470
4471
    // Level 5: ConnectionError(OSError) subclasses
4472
    ITEM(BrokenPipeError),
4473
    ITEM(ConnectionAbortedError),
4474
    ITEM(ConnectionRefusedError),
4475
    ITEM(ConnectionResetError),
4476
4477
    // Level 5: IndentationError(SyntaxError) subclasses
4478
    ITEM(TabError),  // base: IndentationError
4479
4480
    // Level 5: UnicodeError(ValueError) subclasses
4481
    ITEM(UnicodeDecodeError),
4482
    ITEM(UnicodeEncodeError),
4483
    ITEM(UnicodeTranslateError),
4484
#undef ITEM
4485
};
4486
4487
4488
int
4489
_PyExc_InitTypes(PyInterpreterState *interp)
4490
32
{
4491
2.24k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4492
2.20k
        PyTypeObject *exc = static_exceptions[i].exc;
4493
2.20k
        if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
4494
0
            return -1;
4495
0
        }
4496
2.20k
        if (exc->tp_new == BaseException_new
4497
1.63k
            && exc->tp_init == BaseException_init)
4498
1.15k
        {
4499
1.15k
            exc->tp_vectorcall = BaseException_vectorcall;
4500
1.15k
        }
4501
2.20k
    }
4502
32
    return 0;
4503
32
}
4504
4505
4506
static void
4507
_PyExc_FiniTypes(PyInterpreterState *interp)
4508
0
{
4509
0
    for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
4510
0
        PyTypeObject *exc = static_exceptions[i].exc;
4511
0
        _PyStaticType_FiniBuiltin(interp, exc);
4512
0
    }
4513
0
}
4514
4515
4516
PyStatus
4517
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
4518
32
{
4519
32
    if (preallocate_memerrors() < 0) {
4520
0
        return _PyStatus_NO_MEMORY();
4521
0
    }
4522
32
    return _PyStatus_OK();
4523
32
}
4524
4525
PyStatus
4526
_PyExc_InitState(PyInterpreterState *interp)
4527
32
{
4528
32
    struct _Py_exc_state *state = &interp->exc_state;
4529
4530
32
#define ADD_ERRNO(TYPE, CODE) \
4531
608
    do { \
4532
608
        PyObject *_code = PyLong_FromLong(CODE); \
4533
608
        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
4534
608
        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
4535
0
            Py_XDECREF(_code); \
4536
0
            return _PyStatus_ERR("errmap insertion problem."); \
4537
0
        } \
4538
608
        Py_DECREF(_code); \
4539
608
    } while (0)
4540
4541
    /* Add exceptions to errnomap */
4542
32
    assert(state->errnomap == NULL);
4543
32
    state->errnomap = PyDict_New();
4544
32
    if (!state->errnomap) {
4545
0
        return _PyStatus_NO_MEMORY();
4546
0
    }
4547
4548
32
    ADD_ERRNO(BlockingIOError, EAGAIN);
4549
32
    ADD_ERRNO(BlockingIOError, EALREADY);
4550
32
    ADD_ERRNO(BlockingIOError, EINPROGRESS);
4551
32
    ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
4552
32
    ADD_ERRNO(BrokenPipeError, EPIPE);
4553
32
#ifdef ESHUTDOWN
4554
32
    ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
4555
32
#endif
4556
32
    ADD_ERRNO(ChildProcessError, ECHILD);
4557
32
    ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
4558
32
    ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
4559
32
    ADD_ERRNO(ConnectionResetError, ECONNRESET);
4560
32
    ADD_ERRNO(FileExistsError, EEXIST);
4561
32
    ADD_ERRNO(FileNotFoundError, ENOENT);
4562
32
    ADD_ERRNO(IsADirectoryError, EISDIR);
4563
32
    ADD_ERRNO(NotADirectoryError, ENOTDIR);
4564
32
    ADD_ERRNO(InterruptedError, EINTR);
4565
32
    ADD_ERRNO(PermissionError, EACCES);
4566
32
    ADD_ERRNO(PermissionError, EPERM);
4567
#ifdef ENOTCAPABLE
4568
    // Extension for WASI capability-based security. Process lacks
4569
    // capability to access a resource.
4570
    ADD_ERRNO(PermissionError, ENOTCAPABLE);
4571
#endif
4572
32
    ADD_ERRNO(ProcessLookupError, ESRCH);
4573
32
    ADD_ERRNO(TimeoutError, ETIMEDOUT);
4574
#ifdef WSAETIMEDOUT
4575
    ADD_ERRNO(TimeoutError, WSAETIMEDOUT);
4576
#endif
4577
4578
32
    return _PyStatus_OK();
4579
4580
32
#undef ADD_ERRNO
4581
32
}
4582
4583
4584
/* Add exception types to the builtins module */
4585
int
4586
_PyBuiltins_AddExceptions(PyObject *bltinmod)
4587
32
{
4588
32
    PyObject *mod_dict = PyModule_GetDict(bltinmod);
4589
32
    if (mod_dict == NULL) {
4590
0
        return -1;
4591
0
    }
4592
4593
2.24k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4594
2.20k
        struct static_exception item = static_exceptions[i];
4595
4596
2.20k
        if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
4597
0
            return -1;
4598
0
        }
4599
2.20k
    }
4600
4601
32
    PyObject *PyExc_ExceptionGroup = create_exception_group_class();
4602
32
    if (!PyExc_ExceptionGroup) {
4603
0
        return -1;
4604
0
    }
4605
32
    if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
4606
0
        return -1;
4607
0
    }
4608
32
    if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) {
4609
0
        return -1;
4610
0
    }
4611
32
    if (PyDict_SetItemString(mod_dict, "IOError", PyExc_OSError)) {
4612
0
        return -1;
4613
0
    }
4614
#ifdef MS_WINDOWS
4615
    if (PyDict_SetItemString(mod_dict, "WindowsError", PyExc_OSError)) {
4616
        return -1;
4617
    }
4618
#endif
4619
32
    return 0;
4620
32
}
4621
4622
void
4623
_PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
4624
0
{
4625
0
    struct _Py_exc_state *state = &interp->exc_state;
4626
0
    Py_CLEAR(state->PyExc_ExceptionGroup);
4627
0
}
4628
4629
void
4630
_PyExc_Fini(PyInterpreterState *interp)
4631
0
{
4632
0
    struct _Py_exc_state *state = &interp->exc_state;
4633
0
    free_preallocated_memerrors(state);
4634
0
    Py_CLEAR(state->errnomap);
4635
4636
0
    _PyExc_FiniTypes(interp);
4637
0
}
4638
4639
int
4640
_PyException_AddNote(PyObject *exc, PyObject *note)
4641
58.1k
{
4642
58.1k
    if (!PyExceptionInstance_Check(exc)) {
4643
0
        PyErr_Format(PyExc_TypeError,
4644
0
                     "exc must be an exception, not '%s'",
4645
0
                     Py_TYPE(exc)->tp_name);
4646
0
        return -1;
4647
0
    }
4648
58.1k
    PyObject *r = BaseException_add_note(exc, note);
4649
58.1k
    int res = r == NULL ? -1 : 0;
4650
58.1k
    Py_XDECREF(r);
4651
58.1k
    return res;
4652
58.1k
}