Coverage Report

Created: 2025-12-14 07:06

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