Coverage Report

Created: 2026-05-16 06:46

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
339k
{
32
339k
    PyInterpreterState *interp = _PyInterpreterState_GET();
33
339k
    return &interp->exc_state;
34
339k
}
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
316M
{
44
316M
    assert(PyExceptionInstance_Check(exc));
45
316M
    return (PyBaseExceptionObject *)exc;
46
316M
}
47
48
/*
49
 *    BaseException
50
 */
51
static PyObject *
52
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
53
34.5M
{
54
34.5M
    PyBaseExceptionObject *self;
55
56
34.5M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
57
34.5M
    if (!self)
58
0
        return NULL;
59
    /* the dict is created on the fly in PyObject_GenericSetAttr */
60
34.5M
    self->dict = NULL;
61
34.5M
    self->notes = NULL;
62
34.5M
    self->traceback = self->cause = self->context = NULL;
63
34.5M
    self->suppress_context = 0;
64
65
34.5M
    if (args) {
66
34.5M
        self->args = Py_NewRef(args);
67
34.5M
        return (PyObject *)self;
68
34.5M
    }
69
70
592
    self->args = PyTuple_New(0);
71
592
    if (!self->args) {
72
0
        Py_DECREF(self);
73
0
        return NULL;
74
0
    }
75
76
592
    return (PyObject *)self;
77
592
}
78
79
static int
80
BaseException_init(PyObject *op, PyObject *args, PyObject *kwds)
81
33.2M
{
82
33.2M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
83
33.2M
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
84
0
        return -1;
85
86
33.2M
    Py_XSETREF(self->args, Py_NewRef(args));
87
33.2M
    return 0;
88
33.2M
}
89
90
91
static PyObject *
92
BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
93
                         size_t nargsf, PyObject *kwnames)
94
15.4M
{
95
15.4M
    PyTypeObject *type = _PyType_CAST(type_obj);
96
15.4M
    if (!_PyArg_NoKwnames(type->tp_name, kwnames)) {
97
0
        return NULL;
98
0
    }
99
100
15.4M
    PyBaseExceptionObject *self;
101
15.4M
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
102
15.4M
    if (!self) {
103
0
        return NULL;
104
0
    }
105
106
    // The dict is created on the fly in PyObject_GenericSetAttr()
107
15.4M
    self->dict = NULL;
108
15.4M
    self->notes = NULL;
109
15.4M
    self->traceback = NULL;
110
15.4M
    self->cause = NULL;
111
15.4M
    self->context = NULL;
112
15.4M
    self->suppress_context = 0;
113
114
15.4M
    self->args = PyTuple_FromArray(args, PyVectorcall_NARGS(nargsf));
115
15.4M
    if (!self->args) {
116
0
        Py_DECREF(self);
117
0
        return NULL;
118
0
    }
119
120
15.4M
    return (PyObject *)self;
121
15.4M
}
122
123
124
static int
125
BaseException_clear(PyObject *op)
126
50.2M
{
127
50.2M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
128
50.2M
    Py_CLEAR(self->dict);
129
50.2M
    Py_CLEAR(self->args);
130
50.2M
    Py_CLEAR(self->notes);
131
50.2M
    Py_CLEAR(self->traceback);
132
50.2M
    Py_CLEAR(self->cause);
133
50.2M
    Py_CLEAR(self->context);
134
50.2M
    return 0;
135
50.2M
}
136
137
static void
138
BaseException_dealloc(PyObject *op)
139
29.9M
{
140
29.9M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
141
29.9M
    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
29.9M
    (void)BaseException_clear(op);
146
29.9M
    Py_TYPE(self)->tp_free(self);
147
29.9M
}
148
149
static int
150
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
151
20.3M
{
152
20.3M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
153
20.3M
    Py_VISIT(self->dict);
154
20.3M
    Py_VISIT(self->args);
155
20.3M
    Py_VISIT(self->notes);
156
20.3M
    Py_VISIT(self->traceback);
157
20.3M
    Py_VISIT(self->cause);
158
20.3M
    Py_VISIT(self->context);
159
20.3M
    return 0;
160
20.3M
}
161
162
static PyObject *
163
BaseException_str(PyObject *op)
164
5.29M
{
165
5.29M
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
166
167
5.29M
    PyObject *res;
168
5.29M
    Py_BEGIN_CRITICAL_SECTION(self);
169
5.29M
    switch (PyTuple_GET_SIZE(self->args)) {
170
0
    case 0:
171
0
        res = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
172
0
        break;
173
5.29M
    case 1:
174
5.29M
        res = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
175
5.29M
        break;
176
0
    default:
177
0
        res = PyObject_Str(self->args);
178
0
        break;
179
5.29M
    }
180
5.29M
    Py_END_CRITICAL_SECTION();
181
5.29M
    return res;
182
5.29M
}
183
184
static PyObject *
185
BaseException_repr(PyObject *op)
186
4.41k
{
187
188
4.41k
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
189
190
4.41k
    PyObject *res;
191
4.41k
    Py_BEGIN_CRITICAL_SECTION(self);
192
4.41k
    const char *name = _PyType_Name(Py_TYPE(self));
193
4.41k
    if (PyTuple_GET_SIZE(self->args) == 1) {
194
4.41k
        res = PyUnicode_FromFormat("%s(%R)", name,
195
4.41k
                                    PyTuple_GET_ITEM(self->args, 0));
196
4.41k
    }
197
0
    else {
198
0
        res = PyUnicode_FromFormat("%s%R", name, self->args);
199
0
    }
200
4.41k
    Py_END_CRITICAL_SECTION();
201
4.41k
    return res;
202
4.41k
}
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
59.0k
{
293
59.0k
    PyObject *notes;
294
59.0k
    if (PyObject_GetOptionalAttr((PyObject *)self, &_Py_ID(__notes__), &notes) < 0) {
295
0
        return NULL;
296
0
    }
297
59.0k
    if (notes == NULL) {
298
58.9k
        notes = PyList_New(0);
299
58.9k
        if (notes == NULL) {
300
0
            return NULL;
301
0
        }
302
58.9k
        if (PyObject_SetAttr((PyObject *)self, &_Py_ID(__notes__), notes) < 0) {
303
0
            Py_DECREF(notes);
304
0
            return NULL;
305
0
        }
306
58.9k
    }
307
65
    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
59.0k
    if (PyList_Append(notes, note) < 0) {
313
0
        Py_DECREF(notes);
314
0
        return NULL;
315
0
    }
316
59.0k
    Py_DECREF(notes);
317
59.0k
    Py_RETURN_NONE;
318
59.0k
}
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
63.0M
{
394
63.0M
    if (value == NULL) {
395
0
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
396
0
        return -1;
397
0
    }
398
63.0M
    if (PyTraceBack_Check(value)) {
399
63.0M
        Py_XSETREF(self->traceback, Py_NewRef(value));
400
63.0M
    }
401
5.78k
    else if (value == Py_None) {
402
5.78k
        Py_CLEAR(self->traceback);
403
5.78k
    }
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
63.0M
    return 0;
410
63.0M
}
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
103M
{
513
103M
    PyObject *traceback;
514
103M
    Py_BEGIN_CRITICAL_SECTION(self);
515
103M
    traceback = Py_XNewRef(PyBaseExceptionObject_CAST(self)->traceback);
516
103M
    Py_END_CRITICAL_SECTION();
517
103M
    return traceback;
518
103M
}
519
520
521
int
522
PyException_SetTraceback(PyObject *self, PyObject *tb)
523
63.0M
{
524
63.0M
    int res;
525
63.0M
    Py_BEGIN_CRITICAL_SECTION(self);
526
63.0M
    res = BaseException___traceback___set_impl(PyBaseExceptionObject_CAST(self), tb);
527
63.0M
    Py_END_CRITICAL_SECTION();
528
63.0M
    return res;
529
63.0M
}
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.79k
{
545
8.79k
    Py_BEGIN_CRITICAL_SECTION(self);
546
8.79k
    PyBaseExceptionObject *base_self = PyBaseExceptionObject_CAST(self);
547
8.79k
    base_self->suppress_context = 1;
548
8.79k
    Py_XSETREF(base_self->cause, cause);
549
8.79k
    Py_END_CRITICAL_SECTION();
550
8.79k
}
551
552
PyObject *
553
PyException_GetContext(PyObject *self)
554
5.70M
{
555
5.70M
    PyObject *context;
556
5.70M
    Py_BEGIN_CRITICAL_SECTION(self);
557
5.70M
    context = Py_XNewRef(PyBaseExceptionObject_CAST(self)->context);
558
5.70M
    Py_END_CRITICAL_SECTION();
559
5.70M
    return context;
560
5.70M
}
561
562
/* Steals a reference to context */
563
void
564
PyException_SetContext(PyObject *self, PyObject *context)
565
4.99M
{
566
4.99M
    Py_BEGIN_CRITICAL_SECTION(self);
567
4.99M
    Py_XSETREF(PyBaseExceptionObject_CAST(self)->context, context);
568
4.99M
    Py_END_CRITICAL_SECTION();
569
4.99M
}
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
27.6M
{
741
27.6M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_StopIteration));
742
27.6M
    return (PyStopIterationObject *)self;
743
27.6M
}
744
745
static int
746
StopIteration_init(PyObject *op, PyObject *args, PyObject *kwds)
747
13.8M
{
748
13.8M
    Py_ssize_t size = PyTuple_GET_SIZE(args);
749
13.8M
    PyObject *value;
750
751
13.8M
    if (BaseException_init(op, args, kwds) == -1)
752
0
        return -1;
753
13.8M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
754
13.8M
    Py_CLEAR(self->value);
755
13.8M
    if (size > 0)
756
2.25k
        value = PyTuple_GET_ITEM(args, 0);
757
13.8M
    else
758
13.8M
        value = Py_None;
759
13.8M
    self->value = Py_NewRef(value);
760
13.8M
    return 0;
761
13.8M
}
762
763
static int
764
StopIteration_clear(PyObject *op)
765
13.8M
{
766
13.8M
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
767
13.8M
    Py_CLEAR(self->value);
768
13.8M
    return BaseException_clear(op);
769
13.8M
}
770
771
static void
772
StopIteration_dealloc(PyObject *self)
773
13.8M
{
774
13.8M
    PyObject_GC_UnTrack(self);
775
13.8M
    (void)StopIteration_clear(self);
776
13.8M
    Py_TYPE(self)->tp_free(self);
777
13.8M
}
778
779
static int
780
StopIteration_traverse(PyObject *op, visitproc visit, void *arg)
781
0
{
782
0
    PyStopIterationObject *self = PyStopIterationObject_CAST(op);
783
0
    Py_VISIT(self->value);
784
0
    return BaseException_traverse(op, visit, arg);
785
0
}
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
37
create_exception_group_class(void) {
1764
37
    struct _Py_exc_state *state = get_exc_state();
1765
1766
37
    PyObject *bases = _PyTuple_FromPair(
1767
37
        PyExc_BaseExceptionGroup, PyExc_Exception);
1768
37
    if (bases == NULL) {
1769
0
        return NULL;
1770
0
    }
1771
1772
37
    assert(!state->PyExc_ExceptionGroup);
1773
37
    state->PyExc_ExceptionGroup = PyErr_NewException(
1774
37
        "builtins.ExceptionGroup", bases, NULL);
1775
1776
37
    Py_DECREF(bases);
1777
37
    return state->PyExc_ExceptionGroup;
1778
37
}
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.7k
{
1794
12.7k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_ImportError));
1795
12.7k
    return (PyImportErrorObject *)self;
1796
12.7k
}
1797
1798
static int
1799
ImportError_init(PyObject *op, PyObject *args, PyObject *kwds)
1800
6.36k
{
1801
6.36k
    static char *kwlist[] = {"name", "path", "name_from", 0};
1802
6.36k
    PyObject *empty_tuple;
1803
6.36k
    PyObject *msg = NULL;
1804
6.36k
    PyObject *name = NULL;
1805
6.36k
    PyObject *path = NULL;
1806
6.36k
    PyObject *name_from = NULL;
1807
1808
6.36k
    if (BaseException_init(op, args, NULL) == -1)
1809
0
        return -1;
1810
1811
6.36k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1812
6.36k
    empty_tuple = PyTuple_New(0);
1813
6.36k
    if (!empty_tuple)
1814
0
        return -1;
1815
6.36k
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist,
1816
6.36k
                                     &name, &path, &name_from)) {
1817
0
        Py_DECREF(empty_tuple);
1818
0
        return -1;
1819
0
    }
1820
6.36k
    Py_DECREF(empty_tuple);
1821
1822
6.36k
    Py_XSETREF(self->name, Py_XNewRef(name));
1823
6.36k
    Py_XSETREF(self->path, Py_XNewRef(path));
1824
6.36k
    Py_XSETREF(self->name_from, Py_XNewRef(name_from));
1825
1826
6.36k
    if (PyTuple_GET_SIZE(args) == 1) {
1827
6.36k
        msg = Py_NewRef(PyTuple_GET_ITEM(args, 0));
1828
6.36k
    }
1829
6.36k
    Py_XSETREF(self->msg, msg);
1830
1831
6.36k
    return 0;
1832
6.36k
}
1833
1834
static int
1835
ImportError_clear(PyObject *op)
1836
6.36k
{
1837
6.36k
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1838
6.36k
    Py_CLEAR(self->msg);
1839
6.36k
    Py_CLEAR(self->name);
1840
6.36k
    Py_CLEAR(self->path);
1841
6.36k
    Py_CLEAR(self->name_from);
1842
6.36k
    return BaseException_clear(op);
1843
6.36k
}
1844
1845
static void
1846
ImportError_dealloc(PyObject *self)
1847
6.36k
{
1848
6.36k
    _PyObject_GC_UNTRACK(self);
1849
6.36k
    (void)ImportError_clear(self);
1850
6.36k
    Py_TYPE(self)->tp_free(self);
1851
6.36k
}
1852
1853
static int
1854
ImportError_traverse(PyObject *op, visitproc visit, void *arg)
1855
14
{
1856
14
    PyImportErrorObject *self = PyImportErrorObject_CAST(op);
1857
14
    Py_VISIT(self->msg);
1858
14
    Py_VISIT(self->name);
1859
14
    Py_VISIT(self->path);
1860
14
    Py_VISIT(self->name_from);
1861
14
    return BaseException_traverse(op, visit, arg);
1862
14
}
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
677k
{
2036
677k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_OSError));
2037
677k
    return (PyOSErrorObject *)self;
2038
677k
}
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
338k
{
2070
338k
    Py_ssize_t nargs;
2071
338k
    PyObject *args = *p_args;
2072
338k
#ifndef MS_WINDOWS
2073
    /*
2074
     * ignored on non-Windows platforms,
2075
     * but parsed so OSError has a consistent signature
2076
     */
2077
338k
    PyObject *_winerror = NULL;
2078
338k
    PyObject **winerror = &_winerror;
2079
338k
#endif /* MS_WINDOWS */
2080
2081
338k
    nargs = PyTuple_GET_SIZE(args);
2082
2083
338k
    if (nargs >= 2 && nargs <= 5) {
2084
336k
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
2085
336k
                               myerrno, strerror,
2086
336k
                               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
336k
    }
2114
2115
338k
    return 0;
2116
338k
}
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
338k
{
2127
338k
    PyObject *args = *p_args;
2128
338k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
2129
2130
    /* self->filename will remain Py_None otherwise */
2131
338k
    if (filename && filename != Py_None) {
2132
336k
        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
336k
        else {
2142
336k
            self->filename = Py_NewRef(filename);
2143
2144
336k
            if (filename2 && filename2 != Py_None) {
2145
0
                self->filename2 = Py_NewRef(filename2);
2146
0
            }
2147
2148
336k
            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
336k
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
2152
336k
                if (!subslice)
2153
0
                    return -1;
2154
2155
336k
                Py_DECREF(args);  /* replacing args */
2156
336k
                *p_args = args = subslice;
2157
336k
            }
2158
336k
        }
2159
336k
    }
2160
338k
    self->myerrno = Py_XNewRef(myerrno);
2161
338k
    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
338k
    Py_XSETREF(self->args, args);
2168
338k
    *p_args = args = NULL;
2169
2170
338k
    return 0;
2171
338k
}
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.01M
{
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.01M
    if (type->tp_init != OSError_init && type->tp_new == OSError_new) {
2192
165
        assert((PyObject *) type != PyExc_OSError);
2193
165
        return 1;
2194
165
    }
2195
1.01M
    return 0;
2196
1.01M
}
2197
2198
static PyObject *
2199
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2200
338k
{
2201
338k
    PyOSErrorObject *self = NULL;
2202
338k
    PyObject *myerrno = NULL, *strerror = NULL;
2203
338k
    PyObject *filename = NULL, *filename2 = NULL;
2204
#ifdef MS_WINDOWS
2205
    PyObject *winerror = NULL;
2206
#endif
2207
2208
338k
    Py_INCREF(args);
2209
2210
338k
    if (!oserror_use_init(type)) {
2211
338k
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
2212
0
            goto error;
2213
2214
338k
        if (oserror_parse_args(&args, &myerrno, &strerror,
2215
338k
                               &filename, &filename2
2216
#ifdef MS_WINDOWS
2217
                               , &winerror
2218
#endif
2219
338k
            ))
2220
0
            goto error;
2221
2222
338k
        struct _Py_exc_state *state = get_exc_state();
2223
338k
        if (myerrno && PyLong_Check(myerrno) &&
2224
336k
            state->errnomap && (PyObject *) type == PyExc_OSError) {
2225
336k
            PyObject *newtype;
2226
336k
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
2227
336k
            if (newtype) {
2228
293k
                type = _PyType_CAST(newtype);
2229
293k
            }
2230
43.0k
            else if (PyErr_Occurred())
2231
0
                goto error;
2232
336k
        }
2233
338k
    }
2234
2235
338k
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
2236
338k
    if (!self)
2237
0
        goto error;
2238
2239
338k
    self->dict = NULL;
2240
338k
    self->traceback = self->cause = self->context = NULL;
2241
338k
    self->written = -1;
2242
2243
338k
    if (!oserror_use_init(type)) {
2244
338k
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2245
#ifdef MS_WINDOWS
2246
                         , winerror
2247
#endif
2248
338k
            ))
2249
0
            goto error;
2250
338k
    }
2251
55
    else {
2252
55
        self->args = PyTuple_New(0);
2253
55
        if (self->args == NULL)
2254
0
            goto error;
2255
55
    }
2256
2257
338k
    Py_XDECREF(args);
2258
338k
    return (PyObject *) self;
2259
2260
0
error:
2261
0
    Py_XDECREF(args);
2262
0
    Py_XDECREF(self);
2263
0
    return NULL;
2264
338k
}
2265
2266
static int
2267
OSError_init(PyObject *op, PyObject *args, PyObject *kwds)
2268
338k
{
2269
338k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2270
338k
    PyObject *myerrno = NULL, *strerror = NULL;
2271
338k
    PyObject *filename = NULL, *filename2 = NULL;
2272
#ifdef MS_WINDOWS
2273
    PyObject *winerror = NULL;
2274
#endif
2275
2276
338k
    if (!oserror_use_init(Py_TYPE(self)))
2277
        /* Everything already done in OSError_new */
2278
338k
        return 0;
2279
2280
55
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
2281
0
        return -1;
2282
2283
55
    Py_INCREF(args);
2284
55
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
2285
#ifdef MS_WINDOWS
2286
                           , &winerror
2287
#endif
2288
55
        ))
2289
0
        goto error;
2290
2291
55
    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
2292
#ifdef MS_WINDOWS
2293
                     , winerror
2294
#endif
2295
55
        ))
2296
0
        goto error;
2297
2298
55
    return 0;
2299
2300
0
error:
2301
0
    Py_DECREF(args);
2302
0
    return -1;
2303
55
}
2304
2305
static int
2306
OSError_clear(PyObject *op)
2307
338k
{
2308
338k
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2309
338k
    Py_CLEAR(self->myerrno);
2310
338k
    Py_CLEAR(self->strerror);
2311
338k
    Py_CLEAR(self->filename);
2312
338k
    Py_CLEAR(self->filename2);
2313
#ifdef MS_WINDOWS
2314
    Py_CLEAR(self->winerror);
2315
#endif
2316
338k
    return BaseException_clear(op);
2317
338k
}
2318
2319
static void
2320
OSError_dealloc(PyObject *self)
2321
338k
{
2322
338k
    _PyObject_GC_UNTRACK(self);
2323
338k
    (void)OSError_clear(self);
2324
338k
    Py_TYPE(self)->tp_free(self);
2325
338k
}
2326
2327
static int
2328
OSError_traverse(PyObject *op, visitproc visit, void *arg)
2329
12
{
2330
12
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2331
12
    Py_VISIT(self->myerrno);
2332
12
    Py_VISIT(self->strerror);
2333
12
    Py_VISIT(self->filename);
2334
12
    Py_VISIT(self->filename2);
2335
#ifdef MS_WINDOWS
2336
    Py_VISIT(self->winerror);
2337
#endif
2338
12
    return BaseException_traverse(op, visit, arg);
2339
12
}
2340
2341
static PyObject *
2342
OSError_str(PyObject *op)
2343
749
{
2344
749
    PyOSErrorObject *self = PyOSErrorObject_CAST(op);
2345
1.46k
#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
749
    if (self->filename) {
2368
734
        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
734
        } else {
2375
734
            return PyUnicode_FromFormat("[Errno %S] %S: %R",
2376
734
                                        OR_NONE(self->myerrno),
2377
734
                                        OR_NONE(self->strerror),
2378
734
                                        self->filename);
2379
734
        }
2380
734
    }
2381
15
    if (self->myerrno && self->strerror)
2382
0
        return PyUnicode_FromFormat("[Errno %S] %S",
2383
0
                                    self->myerrno, self->strerror);
2384
15
    return BaseException_str(op);
2385
15
}
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
14
{
2571
14
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_NameError));
2572
14
    return (PyNameErrorObject *)self;
2573
14
}
2574
2575
static int
2576
NameError_init(PyObject *op, PyObject *args, PyObject *kwds)
2577
6
{
2578
6
    static char *kwlist[] = {"name", NULL};
2579
6
    PyObject *name = NULL;
2580
2581
6
    if (BaseException_init(op, args, NULL) == -1) {
2582
0
        return -1;
2583
0
    }
2584
2585
6
    PyObject *empty_tuple = PyTuple_New(0);
2586
6
    if (!empty_tuple) {
2587
0
        return -1;
2588
0
    }
2589
6
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
2590
6
                                     &name)) {
2591
0
        Py_DECREF(empty_tuple);
2592
0
        return -1;
2593
0
    }
2594
6
    Py_DECREF(empty_tuple);
2595
2596
6
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2597
6
    Py_XSETREF(self->name, Py_XNewRef(name));
2598
2599
6
    return 0;
2600
6
}
2601
2602
static int
2603
NameError_clear(PyObject *op)
2604
6
{
2605
6
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2606
6
    Py_CLEAR(self->name);
2607
6
    return BaseException_clear(op);
2608
6
}
2609
2610
static void
2611
NameError_dealloc(PyObject *self)
2612
6
{
2613
6
    _PyObject_GC_UNTRACK(self);
2614
6
    (void)NameError_clear(self);
2615
6
    Py_TYPE(self)->tp_free(self);
2616
6
}
2617
2618
static int
2619
NameError_traverse(PyObject *op, visitproc visit, void *arg)
2620
2
{
2621
2
    PyNameErrorObject *self = PyNameErrorObject_CAST(op);
2622
2
    Py_VISIT(self->name);
2623
2
    return BaseException_traverse(op, visit, arg);
2624
2
}
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.01M
{
2654
6.01M
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_AttributeError));
2655
6.01M
    return (PyAttributeErrorObject *)self;
2656
6.01M
}
2657
2658
static int
2659
AttributeError_init(PyObject *op, PyObject *args, PyObject *kwds)
2660
3.00M
{
2661
3.00M
    static char *kwlist[] = {"name", "obj", NULL};
2662
3.00M
    PyObject *name = NULL;
2663
3.00M
    PyObject *obj = NULL;
2664
2665
3.00M
    if (BaseException_init(op, args, NULL) == -1) {
2666
0
        return -1;
2667
0
    }
2668
2669
3.00M
    PyObject *empty_tuple = PyTuple_New(0);
2670
3.00M
    if (!empty_tuple) {
2671
0
        return -1;
2672
0
    }
2673
3.00M
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
2674
3.00M
                                     &name, &obj)) {
2675
0
        Py_DECREF(empty_tuple);
2676
0
        return -1;
2677
0
    }
2678
3.00M
    Py_DECREF(empty_tuple);
2679
2680
3.00M
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2681
3.00M
    Py_XSETREF(self->name, Py_XNewRef(name));
2682
3.00M
    Py_XSETREF(self->obj, Py_XNewRef(obj));
2683
2684
3.00M
    return 0;
2685
3.00M
}
2686
2687
static int
2688
AttributeError_clear(PyObject *op)
2689
3.00M
{
2690
3.00M
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2691
3.00M
    Py_CLEAR(self->obj);
2692
3.00M
    Py_CLEAR(self->name);
2693
3.00M
    return BaseException_clear(op);
2694
3.00M
}
2695
2696
static void
2697
AttributeError_dealloc(PyObject *self)
2698
3.00M
{
2699
3.00M
    _PyObject_GC_UNTRACK(self);
2700
3.00M
    (void)AttributeError_clear(self);
2701
3.00M
    Py_TYPE(self)->tp_free(self);
2702
3.00M
}
2703
2704
static int
2705
AttributeError_traverse(PyObject *op, visitproc visit, void *arg)
2706
1.56k
{
2707
1.56k
    PyAttributeErrorObject *self = PyAttributeErrorObject_CAST(op);
2708
1.56k
    Py_VISIT(self->obj);
2709
1.56k
    Py_VISIT(self->name);
2710
1.56k
    return BaseException_traverse(op, visit, arg);
2711
1.56k
}
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
231k
{
2781
231k
    assert(PyObject_TypeCheck(self, (PyTypeObject *)PyExc_SyntaxError));
2782
231k
    return (PySyntaxErrorObject *)self;
2783
231k
}
2784
2785
static int
2786
SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
2787
115k
{
2788
115k
    PyObject *info = NULL;
2789
115k
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2790
2791
115k
    if (BaseException_init(op, args, kwds) == -1)
2792
0
        return -1;
2793
2794
115k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2795
115k
    if (lenargs >= 1) {
2796
115k
        Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0)));
2797
115k
    }
2798
115k
    if (lenargs == 2) {
2799
95.7k
        info = PyTuple_GET_ITEM(args, 1);
2800
95.7k
        info = PySequence_Tuple(info);
2801
95.7k
        if (!info) {
2802
0
            return -1;
2803
0
        }
2804
2805
95.7k
        PyObject *filename, *lineno, *offset, *text;
2806
95.7k
        PyObject *end_lineno = NULL;
2807
95.7k
        PyObject *end_offset = NULL;
2808
95.7k
        PyObject *metadata = NULL;
2809
95.7k
        if (!PyArg_ParseTuple(info, "OOOO|OOO",
2810
95.7k
                              &filename, &lineno,
2811
95.7k
                              &offset, &text,
2812
95.7k
                              &end_lineno, &end_offset, &metadata)) {
2813
0
            Py_DECREF(info);
2814
0
            return -1;
2815
0
        }
2816
2817
95.7k
        Py_XSETREF(self->filename, Py_NewRef(filename));
2818
95.7k
        Py_XSETREF(self->lineno, Py_NewRef(lineno));
2819
95.7k
        Py_XSETREF(self->offset, Py_NewRef(offset));
2820
95.7k
        Py_XSETREF(self->text, Py_NewRef(text));
2821
95.7k
        Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2822
95.7k
        Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
2823
95.7k
        Py_XSETREF(self->metadata, Py_XNewRef(metadata));
2824
95.7k
        Py_DECREF(info);
2825
2826
95.7k
        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.7k
    }
2831
115k
    return 0;
2832
115k
}
2833
2834
static int
2835
SyntaxError_clear(PyObject *op)
2836
115k
{
2837
115k
    PySyntaxErrorObject *self = PySyntaxErrorObject_CAST(op);
2838
115k
    Py_CLEAR(self->msg);
2839
115k
    Py_CLEAR(self->filename);
2840
115k
    Py_CLEAR(self->lineno);
2841
115k
    Py_CLEAR(self->offset);
2842
115k
    Py_CLEAR(self->end_lineno);
2843
115k
    Py_CLEAR(self->end_offset);
2844
115k
    Py_CLEAR(self->text);
2845
115k
    Py_CLEAR(self->print_file_and_line);
2846
115k
    Py_CLEAR(self->metadata);
2847
115k
    return BaseException_clear(op);
2848
115k
}
2849
2850
static void
2851
SyntaxError_dealloc(PyObject *self)
2852
115k
{
2853
115k
    _PyObject_GC_UNTRACK(self);
2854
115k
    (void)SyntaxError_clear(self);
2855
115k
    Py_TYPE(self)->tp_free(self);
2856
115k
}
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
535k
{
3062
535k
    assert(as_bytes == 0 || as_bytes == 1);
3063
535k
    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
535k
    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
535k
    return 0;
3076
535k
}
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
533k
{
3091
533k
    int rc = check_unicode_error_attribute(attr, name, as_bytes);
3092
533k
    return rc < 0 ? NULL : Py_NewRef(attr);
3093
533k
}
3094
3095
3096
#define PyUnicodeError_Check(PTR)   \
3097
1.10M
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3098
#define PyUnicodeError_CAST(PTR)    \
3099
1.17M
    (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.10M
#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.10M
{
3125
1.10M
    assert(self != NULL);
3126
1.10M
    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.10M
    return 0;
3132
1.10M
}
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
8
{
3147
8
    assert(self != NULL);
3148
8
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3149
8
    return as_unicode_error_attribute(exc->encoding, "encoding", false);
3150
8
}
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
252k
{
3160
252k
    assert(self != NULL);
3161
252k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3162
252k
    return as_unicode_error_attribute(exc->object, "object", as_bytes);
3163
252k
}
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
213k
{
3186
213k
    assert(self != NULL);
3187
213k
    PyObject *value = PyUnicode_FromString(reason);
3188
213k
    if (value == NULL) {
3189
0
        return -1;
3190
0
    }
3191
213k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3192
213k
    Py_XSETREF(exc->reason, value);
3193
213k
    return 0;
3194
213k
}
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
213k
{
3205
213k
    assert(self != NULL);
3206
213k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3207
213k
    exc->start = start;
3208
213k
    return 0;
3209
213k
}
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
213k
{
3220
213k
    assert(self != NULL);
3221
213k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3222
213k
    exc->end = end;
3223
213k
    return 0;
3224
213k
}
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
69.6k
{
3240
69.6k
    assert(objlen >= 0);
3241
69.6k
    if (start < 0) {
3242
0
        start = 0;
3243
0
    }
3244
69.6k
    if (start >= objlen) {
3245
0
        start = objlen == 0 ? 0 : objlen - 1;
3246
0
    }
3247
69.6k
    return start;
3248
69.6k
}
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
281k
{
3281
281k
    assert(objlen >= 0);
3282
281k
    if (end < 1) {
3283
0
        end = 1;
3284
0
    }
3285
281k
    if (end > objlen) {
3286
0
        end = objlen;
3287
0
    }
3288
281k
    return end;
3289
281k
}
3290
3291
#define PyUnicodeError_Check(PTR)   \
3292
    PyObject_TypeCheck((PTR), (PyTypeObject *)PyExc_UnicodeError)
3293
#define PyUnicodeErrorObject_CAST(op)   \
3294
6.02M
    (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
69.6k
{
3327
69.6k
    assert_adjusted_unicode_error_start(start, objlen);
3328
69.6k
    assert_adjusted_unicode_error_end(end, objlen);
3329
69.6k
    Py_ssize_t ranlen = end - start;
3330
69.6k
    assert(ranlen <= objlen);
3331
69.6k
    return ranlen < 0 ? 0 : ranlen;
3332
69.6k
}
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
281k
{
3383
281k
    assert(self != NULL);
3384
281k
    assert(as_bytes == 0 || as_bytes == 1);
3385
281k
    PyUnicodeErrorObject *exc = PyUnicodeError_CAST(self);
3386
281k
    PyObject *r = as_unicode_error_attribute(exc->object, "object", as_bytes);
3387
281k
    if (r == NULL) {
3388
0
        return -1;
3389
0
    }
3390
3391
281k
    Py_ssize_t n = as_bytes ? PyBytes_GET_SIZE(r) : PyUnicode_GET_LENGTH(r);
3392
281k
    if (objlen != NULL) {
3393
8
        *objlen = n;
3394
8
    }
3395
3396
281k
    Py_ssize_t start_value = -1;
3397
281k
    if (start != NULL || slen != NULL) {
3398
69.6k
        start_value = unicode_error_adjust_start(exc->start, n);
3399
69.6k
    }
3400
281k
    if (start != NULL) {
3401
69.6k
        assert_adjusted_unicode_error_start(start_value, n);
3402
69.6k
        *start = start_value;
3403
69.6k
    }
3404
3405
281k
    Py_ssize_t end_value = -1;
3406
281k
    if (end != NULL || slen != NULL) {
3407
281k
        end_value = unicode_error_adjust_end(exc->end, n);
3408
281k
    }
3409
281k
    if (end != NULL) {
3410
281k
        assert_adjusted_unicode_error_end(end_value, n);
3411
281k
        *end = end_value;
3412
281k
    }
3413
3414
281k
    if (slen != NULL) {
3415
69.6k
        *slen = unicode_error_adjust_len(start_value, end_value, n);
3416
69.6k
        assert_adjusted_unicode_error_len(*slen, n);
3417
69.6k
    }
3418
3419
281k
    if (obj != NULL) {
3420
69.6k
        *obj = r;
3421
69.6k
    }
3422
211k
    else {
3423
211k
        Py_DECREF(r);
3424
211k
    }
3425
281k
    return 0;
3426
281k
}
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
8
{
3443
8
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3444
8
    return rc < 0 ? NULL : unicode_error_get_encoding_impl(self);
3445
8
}
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
252k
{
3461
252k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3462
252k
    return rc < 0 ? NULL : unicode_error_get_object_impl(self, true);
3463
252k
}
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
213k
{
3529
213k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3530
213k
    return rc < 0 ? -1 : unicode_error_set_start_impl(self, start);
3531
213k
}
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
211k
{
3553
211k
    assert(self != NULL);
3554
211k
    return _PyUnicodeError_GetParams(self, NULL, NULL,
3555
211k
                                     NULL, end, NULL,
3556
211k
                                     as_bytes);
3557
211k
}
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
211k
{
3571
211k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3572
211k
    return rc < 0 ? -1 : unicode_error_get_end_impl(self, end, true);
3573
211k
}
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
213k
{
3597
213k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3598
213k
    return rc < 0 ? -1 : unicode_error_set_end_impl(self, end);
3599
213k
}
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
213k
{
3649
213k
    int rc = check_unicode_error_type(self, Py_UNICODE_DECODE_ERROR_NAME);
3650
213k
    return rc < 0 ? -1 : unicode_error_set_reason_impl(self, reason);
3651
213k
}
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
3.01M
{
3665
3.01M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3666
3.01M
    Py_CLEAR(exc->encoding);
3667
3.01M
    Py_CLEAR(exc->object);
3668
3.01M
    Py_CLEAR(exc->reason);
3669
3.01M
    return BaseException_clear(self);
3670
3.01M
}
3671
3672
static void
3673
UnicodeError_dealloc(PyObject *self)
3674
3.01M
{
3675
3.01M
    PyTypeObject *type = Py_TYPE(self);
3676
3.01M
    _PyObject_GC_UNTRACK(self);
3677
3.01M
    (void)UnicodeError_clear(self);
3678
3.01M
    type->tp_free(self);
3679
3.01M
}
3680
3681
static int
3682
UnicodeError_traverse(PyObject *self, visitproc visit, void *arg)
3683
192
{
3684
192
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3685
192
    Py_VISIT(exc->encoding);
3686
192
    Py_VISIT(exc->object);
3687
192
    Py_VISIT(exc->reason);
3688
192
    return BaseException_traverse(self, visit, arg);
3689
192
}
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
734k
{
3713
734k
    if (BaseException_init(self, args, kwds) == -1) {
3714
0
        return -1;
3715
0
    }
3716
3717
734k
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3718
734k
    Py_ssize_t start = -1, end = -1;
3719
3720
734k
    if (!PyArg_ParseTuple(args, "UUnnU",
3721
734k
                          &encoding, &object, &start, &end, &reason))
3722
0
    {
3723
0
        return -1;
3724
0
    }
3725
3726
734k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3727
734k
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3728
734k
    Py_XSETREF(exc->object, Py_NewRef(object));
3729
734k
    exc->start = start;
3730
734k
    exc->end = end;
3731
734k
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3732
734k
    return 0;
3733
734k
}
3734
3735
static PyObject *
3736
UnicodeEncodeError_str(PyObject *self)
3737
47
{
3738
47
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3739
47
    PyObject *result = NULL;
3740
47
    PyObject *reason_str = NULL;
3741
47
    PyObject *encoding_str = NULL;
3742
3743
47
    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
47
    reason_str = PyObject_Str(exc->reason);
3751
47
    if (reason_str == NULL) {
3752
0
        goto done;
3753
0
    }
3754
47
    encoding_str = PyObject_Str(exc->encoding);
3755
47
    if (encoding_str == NULL) {
3756
0
        goto done;
3757
0
    }
3758
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3759
47
    if (check_unicode_error_attribute(exc->object, "object", false) < 0) {
3760
0
        goto done;
3761
0
    }
3762
47
    Py_ssize_t len = PyUnicode_GET_LENGTH(exc->object);
3763
47
    Py_ssize_t start = exc->start, end = exc->end;
3764
3765
47
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3766
29
        Py_UCS4 badchar = PyUnicode_ReadChar(exc->object, start);
3767
29
        const char *fmt;
3768
29
        if (badchar <= 0xff) {
3769
0
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
3770
0
        }
3771
29
        else if (badchar <= 0xffff) {
3772
29
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
3773
29
        }
3774
0
        else {
3775
0
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
3776
0
        }
3777
29
        result = PyUnicode_FromFormat(
3778
29
            fmt,
3779
29
            encoding_str,
3780
29
            (int)badchar,
3781
29
            start,
3782
29
            reason_str);
3783
29
    }
3784
18
    else {
3785
18
        result = PyUnicode_FromFormat(
3786
18
            "'%U' codec can't encode characters in position %zd-%zd: %U",
3787
18
            encoding_str,
3788
18
            start,
3789
18
            end - 1,
3790
18
            reason_str);
3791
18
    }
3792
47
done:
3793
47
    Py_XDECREF(reason_str);
3794
47
    Py_XDECREF(encoding_str);
3795
47
    return result;
3796
47
}
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.27M
{
3820
2.27M
    if (BaseException_init(self, args, kwds) == -1) {
3821
0
        return -1;
3822
0
    }
3823
3824
2.27M
    PyObject *encoding = NULL, *object = NULL, *reason = NULL;  // borrowed
3825
2.27M
    Py_ssize_t start = -1, end = -1;
3826
3827
2.27M
    if (!PyArg_ParseTuple(args, "UOnnU",
3828
2.27M
                          &encoding, &object, &start, &end, &reason))
3829
137
    {
3830
137
        return -1;
3831
137
    }
3832
3833
2.27M
    if (PyBytes_Check(object)) {
3834
2.27M
        Py_INCREF(object);  // make 'object' a strong reference
3835
2.27M
    }
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.27M
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3850
2.27M
    Py_XSETREF(exc->encoding, Py_NewRef(encoding));
3851
2.27M
    Py_XSETREF(exc->object, object /* already a strong reference */);
3852
2.27M
    exc->start = start;
3853
2.27M
    exc->end = end;
3854
2.27M
    Py_XSETREF(exc->reason, Py_NewRef(reason));
3855
2.27M
    return 0;
3856
2.27M
}
3857
3858
static PyObject *
3859
UnicodeDecodeError_str(PyObject *self)
3860
1.79k
{
3861
1.79k
    PyUnicodeErrorObject *exc = PyUnicodeErrorObject_CAST(self);
3862
1.79k
    PyObject *result = NULL;
3863
1.79k
    PyObject *reason_str = NULL;
3864
1.79k
    PyObject *encoding_str = NULL;
3865
3866
1.79k
    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.79k
    reason_str = PyObject_Str(exc->reason);
3874
1.79k
    if (reason_str == NULL) {
3875
0
        goto done;
3876
0
    }
3877
1.79k
    encoding_str = PyObject_Str(exc->encoding);
3878
1.79k
    if (encoding_str == NULL) {
3879
0
        goto done;
3880
0
    }
3881
    // calls to PyObject_Str(...) above might mutate 'exc->object'
3882
1.79k
    if (check_unicode_error_attribute(exc->object, "object", true) < 0) {
3883
0
        goto done;
3884
0
    }
3885
1.79k
    Py_ssize_t len = PyBytes_GET_SIZE(exc->object);
3886
1.79k
    Py_ssize_t start = exc->start, end = exc->end;
3887
3888
1.79k
    if ((start >= 0 && start < len) && (end >= 0 && end <= len) && end == start + 1) {
3889
717
        int badbyte = (int)(PyBytes_AS_STRING(exc->object)[start] & 0xff);
3890
717
        result = PyUnicode_FromFormat(
3891
717
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3892
717
            encoding_str,
3893
717
            badbyte,
3894
717
            start,
3895
717
            reason_str);
3896
717
    }
3897
1.08k
    else {
3898
1.08k
        result = PyUnicode_FromFormat(
3899
1.08k
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3900
1.08k
            encoding_str,
3901
1.08k
            start,
3902
1.08k
            end - 1,
3903
1.08k
            reason_str);
3904
1.08k
    }
3905
1.79k
done:
3906
1.79k
    Py_XDECREF(reason_str);
3907
1.79k
    Py_XDECREF(encoding_str);
3908
1.79k
    return result;
3909
1.79k
}
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.27M
{
3930
2.27M
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3931
2.27M
                                 encoding, object, length, start, end, reason);
3932
2.27M
}
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.89k
#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.27k
# define MEMERRORS_LOCK(state) ((void)0)
4103
1.27k
# define MEMERRORS_UNLOCK(state) ((void)0)
4104
#endif
4105
4106
static PyObject *
4107
get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds)
4108
639
{
4109
639
    PyBaseExceptionObject *self = NULL;
4110
639
    struct _Py_exc_state *state = get_exc_state();
4111
4112
639
    MEMERRORS_LOCK(state);
4113
639
    if (state->memerrors_freelist != NULL) {
4114
        /* Fetch MemoryError from freelist and initialize it */
4115
47
        self = state->memerrors_freelist;
4116
47
        state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
4117
47
        state->memerrors_numfree--;
4118
47
        self->dict = NULL;
4119
47
        self->args = (PyObject *)&_Py_SINGLETON(tuple_empty);
4120
47
        _Py_NewReference((PyObject *)self);
4121
47
        _PyObject_GC_TRACK(self);
4122
47
    }
4123
639
    MEMERRORS_UNLOCK(state);
4124
4125
639
    if (self != NULL) {
4126
47
        return (PyObject *)self;
4127
47
    }
4128
4129
592
    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
592
    return BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds);
4135
592
}
4136
4137
static PyObject *
4138
MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4139
639
{
4140
    /* If this is a subclass of MemoryError, don't use the freelist
4141
     * and just return a fresh object */
4142
639
    if (type != (PyTypeObject *) PyExc_MemoryError) {
4143
0
        return BaseException_new(type, args, kwds);
4144
0
    }
4145
639
    return get_memory_error(1, args, kwds);
4146
639
}
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
639
{
4167
639
    PyBaseExceptionObject *self = PyBaseExceptionObject_CAST(op);
4168
639
    _PyObject_GC_UNTRACK(self);
4169
4170
639
    (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
639
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
4175
0
        Py_TYPE(self)->tp_free(op);
4176
0
        return;
4177
0
    }
4178
4179
639
    struct _Py_exc_state *state = get_exc_state();
4180
639
    MEMERRORS_LOCK(state);
4181
639
    if (state->memerrors_numfree < MEMERRORS_SAVE) {
4182
639
        self->dict = (PyObject *) state->memerrors_freelist;
4183
639
        state->memerrors_freelist = self;
4184
639
        state->memerrors_numfree++;
4185
639
        MEMERRORS_UNLOCK(state);
4186
639
        return;
4187
639
    }
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
37
{
4196
    /* We create enough MemoryErrors and then decref them, which will fill
4197
       up the freelist. */
4198
37
    int i;
4199
4200
37
    PyObject *errors[MEMERRORS_SAVE];
4201
629
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4202
592
        errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
4203
592
                                    NULL, NULL);
4204
592
        if (!errors[i]) {
4205
0
            return -1;
4206
0
        }
4207
592
    }
4208
629
    for (i = 0; i < MEMERRORS_SAVE; i++) {
4209
592
        Py_DECREF(errors[i]);
4210
592
    }
4211
37
    return 0;
4212
37
}
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
37
{
4492
2.59k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4493
2.55k
        PyTypeObject *exc = static_exceptions[i].exc;
4494
2.55k
        if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
4495
0
            return -1;
4496
0
        }
4497
2.55k
        if (exc->tp_new == BaseException_new
4498
1.88k
            && exc->tp_init == BaseException_init)
4499
1.33k
        {
4500
1.33k
            exc->tp_vectorcall = BaseException_vectorcall;
4501
1.33k
        }
4502
2.55k
    }
4503
37
    return 0;
4504
37
}
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
37
{
4520
37
    if (preallocate_memerrors() < 0) {
4521
0
        return _PyStatus_NO_MEMORY();
4522
0
    }
4523
37
    return _PyStatus_OK();
4524
37
}
4525
4526
PyStatus
4527
_PyExc_InitState(PyInterpreterState *interp)
4528
37
{
4529
37
    struct _Py_exc_state *state = &interp->exc_state;
4530
4531
37
#define ADD_ERRNO(TYPE, CODE) \
4532
703
    do { \
4533
703
        PyObject *_code = PyLong_FromLong(CODE); \
4534
703
        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
4535
703
        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
703
        Py_DECREF(_code); \
4540
703
    } while (0)
4541
4542
    /* Add exceptions to errnomap */
4543
37
    assert(state->errnomap == NULL);
4544
37
    state->errnomap = PyDict_New();
4545
37
    if (!state->errnomap) {
4546
0
        return _PyStatus_NO_MEMORY();
4547
0
    }
4548
4549
37
    ADD_ERRNO(BlockingIOError, EAGAIN);
4550
37
    ADD_ERRNO(BlockingIOError, EALREADY);
4551
37
    ADD_ERRNO(BlockingIOError, EINPROGRESS);
4552
37
    ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
4553
37
    ADD_ERRNO(BrokenPipeError, EPIPE);
4554
37
#ifdef ESHUTDOWN
4555
37
    ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
4556
37
#endif
4557
37
    ADD_ERRNO(ChildProcessError, ECHILD);
4558
37
    ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
4559
37
    ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
4560
37
    ADD_ERRNO(ConnectionResetError, ECONNRESET);
4561
37
    ADD_ERRNO(FileExistsError, EEXIST);
4562
37
    ADD_ERRNO(FileNotFoundError, ENOENT);
4563
37
    ADD_ERRNO(IsADirectoryError, EISDIR);
4564
37
    ADD_ERRNO(NotADirectoryError, ENOTDIR);
4565
37
    ADD_ERRNO(InterruptedError, EINTR);
4566
37
    ADD_ERRNO(PermissionError, EACCES);
4567
37
    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
37
    ADD_ERRNO(ProcessLookupError, ESRCH);
4574
37
    ADD_ERRNO(TimeoutError, ETIMEDOUT);
4575
#ifdef WSAETIMEDOUT
4576
    ADD_ERRNO(TimeoutError, WSAETIMEDOUT);
4577
#endif
4578
4579
37
    return _PyStatus_OK();
4580
4581
37
#undef ADD_ERRNO
4582
37
}
4583
4584
4585
/* Add exception types to the builtins module */
4586
int
4587
_PyBuiltins_AddExceptions(PyObject *bltinmod)
4588
37
{
4589
37
    PyObject *mod_dict = PyModule_GetDict(bltinmod);
4590
37
    if (mod_dict == NULL) {
4591
0
        return -1;
4592
0
    }
4593
4594
2.59k
    for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
4595
2.55k
        struct static_exception item = static_exceptions[i];
4596
4597
2.55k
        if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
4598
0
            return -1;
4599
0
        }
4600
2.55k
    }
4601
4602
37
    PyObject *PyExc_ExceptionGroup = create_exception_group_class();
4603
37
    if (!PyExc_ExceptionGroup) {
4604
0
        return -1;
4605
0
    }
4606
37
    if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
4607
0
        return -1;
4608
0
    }
4609
37
    if (PyDict_SetItemString(mod_dict, "EnvironmentError", PyExc_OSError)) {
4610
0
        return -1;
4611
0
    }
4612
37
    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
37
    return 0;
4621
37
}
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
59.0k
{
4643
59.0k
    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
59.0k
    PyObject *r = BaseException_add_note(exc, note);
4650
59.0k
    int res = r == NULL ? -1 : 0;
4651
59.0k
    Py_XDECREF(r);
4652
59.0k
    return res;
4653
59.0k
}