Coverage Report

Created: 2026-04-12 06:54

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