Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Objects/exceptions.c
Line
Count
Source (jump to first uncovered line)
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
#define PY_SSIZE_T_CLEAN
8
#include <Python.h>
9
#include <stdbool.h>
10
#include "pycore_ceval.h"         // _Py_EnterRecursiveCall
11
#include "pycore_exceptions.h"    // struct _Py_exc_state
12
#include "pycore_initconfig.h"
13
#include "pycore_object.h"
14
#include "structmember.h"         // PyMemberDef
15
#include "osdefs.h"               // SEP
16
17
18
/* Compatibility aliases */
19
PyObject *PyExc_EnvironmentError = NULL;  // borrowed ref
20
PyObject *PyExc_IOError = NULL;  // borrowed ref
21
#ifdef MS_WINDOWS
22
PyObject *PyExc_WindowsError = NULL;  // borrowed ref
23
#endif
24
25
26
static struct _Py_exc_state*
27
get_exc_state(void)
28
{
29
    PyInterpreterState *interp = _PyInterpreterState_GET();
30
    return &interp->exc_state;
31
}
32
33
34
/* NOTE: If the exception class hierarchy changes, don't forget to update
35
 * Lib/test/exception_hierarchy.txt
36
 */
37
38
/*
39
 *    BaseException
40
 */
41
static PyObject *
42
BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
43
{
44
    PyBaseExceptionObject *self;
45
46
    self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
47
    if (!self)
  Branch (47:9): [True: 0, False: 2.98M]
48
        return NULL;
49
    /* the dict is created on the fly in PyObject_GenericSetAttr */
50
    self->dict = NULL;
51
    self->notes = NULL;
52
    self->traceback = self->cause = self->context = NULL;
53
    self->suppress_context = 0;
54
55
    if (args) {
  Branch (55:9): [True: 2.98M, False: 1.71k]
56
        self->args = args;
57
        Py_INCREF(args);
58
        return (PyObject *)self;
59
    }
60
61
    self->args = PyTuple_New(0);
62
    if (!self->args) {
  Branch (62:9): [True: 0, False: 1.71k]
63
        Py_DECREF(self);
64
        return NULL;
65
    }
66
67
    return (PyObject *)self;
68
}
69
70
static int
71
BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
72
{
73
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
74
        return -1;
75
76
    Py_INCREF(args);
77
    Py_XSETREF(self->args, args);
78
79
    return 0;
80
}
81
82
static int
83
BaseException_clear(PyBaseExceptionObject *self)
84
{
85
    Py_CLEAR(self->dict);
86
    Py_CLEAR(self->args);
87
    Py_CLEAR(self->notes);
88
    Py_CLEAR(self->traceback);
89
    Py_CLEAR(self->cause);
90
    Py_CLEAR(self->context);
91
    return 0;
92
}
93
94
static void
95
BaseException_dealloc(PyBaseExceptionObject *self)
96
{
97
    PyObject_GC_UnTrack(self);
98
    // bpo-44348: The trashcan mechanism prevents stack overflow when deleting
99
    // long chains of exceptions. For example, exceptions can be chained
100
    // through the __context__ attributes or the __traceback__ attribute.
101
    Py_TRASHCAN_BEGIN(self, BaseException_dealloc)
102
    BaseException_clear(self);
103
    Py_TYPE(self)->tp_free((PyObject *)self);
104
    Py_TRASHCAN_END
105
}
106
107
static int
108
BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
109
{
110
    Py_VISIT(self->dict);
111
    Py_VISIT(self->args);
112
    Py_VISIT(self->notes);
113
    Py_VISIT(self->traceback);
114
    Py_VISIT(self->cause);
115
    Py_VISIT(self->context);
116
    return 0;
117
}
118
119
static PyObject *
120
BaseException_str(PyBaseExceptionObject *self)
121
{
122
    switch (PyTuple_GET_SIZE(self->args)) {
123
    case 0:
  Branch (123:5): [True: 195, False: 19.9k]
124
        return PyUnicode_FromString("");
125
    case 1:
  Branch (125:5): [True: 19.8k, False: 216]
126
        return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
127
    default:
  Branch (127:5): [True: 21, False: 20.0k]
128
        return PyObject_Str(self->args);
129
    }
130
}
131
132
static PyObject *
133
BaseException_repr(PyBaseExceptionObject *self)
134
{
135
    const char *name = _PyType_Name(Py_TYPE(self));
136
    if (PyTuple_GET_SIZE(self->args) == 1)
  Branch (136:9): [True: 1.62k, False: 548]
137
        return PyUnicode_FromFormat("%s(%R)", name,
138
                                    PyTuple_GET_ITEM(self->args, 0));
139
    else
140
        return PyUnicode_FromFormat("%s%R", name, self->args);
141
}
142
143
/* Pickling support */
144
static PyObject *
145
BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
146
{
147
    if (self->args && self->dict)
  Branch (147:9): [True: 221, False: 0]
  Branch (147:23): [True: 80, False: 141]
148
        return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
149
    else
150
        return PyTuple_Pack(2, Py_TYPE(self), self->args);
151
}
152
153
/*
154
 * Needed for backward compatibility, since exceptions used to store
155
 * all their attributes in the __dict__. Code is taken from cPickle's
156
 * load_build function.
157
 */
158
static PyObject *
159
BaseException_setstate(PyObject *self, PyObject *state)
160
{
161
    PyObject *d_key, *d_value;
162
    Py_ssize_t i = 0;
163
164
    if (state != Py_None) {
  Branch (164:9): [True: 164, False: 0]
165
        if (!PyDict_Check(state)) {
  Branch (165:13): [True: 0, False: 164]
166
            PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
167
            return NULL;
168
        }
169
        
while (164
PyDict_Next(state, &i, &d_key, &d_value)) {
  Branch (169:16): [True: 388, False: 164]
170
            if (PyObject_SetAttr(self, d_key, d_value) < 0)
  Branch (170:17): [True: 0, False: 388]
171
                return NULL;
172
        }
173
    }
174
    Py_RETURN_NONE;
175
}
176
177
static PyObject *
178
BaseException_with_traceback(PyObject *self, PyObject *tb) {
179
    if (PyException_SetTraceback(self, tb))
  Branch (179:9): [True: 0, False: 185k]
180
        return NULL;
181
182
    Py_INCREF(self);
183
    return self;
184
}
185
186
PyDoc_STRVAR(with_traceback_doc,
187
"Exception.with_traceback(tb) --\n\
188
    set self.__traceback__ to tb and return self.");
189
190
static inline PyBaseExceptionObject*
191
_PyBaseExceptionObject_cast(PyObject *exc)
192
{
193
    assert(PyExceptionInstance_Check(exc));
194
    return (PyBaseExceptionObject *)exc;
195
}
196
197
static PyObject *
198
BaseException_add_note(PyObject *self, PyObject *note)
199
{
200
    if (!PyUnicode_Check(note)) {
  Branch (200:9): [True: 3, False: 54]
201
        PyErr_Format(PyExc_TypeError,
202
                     "note must be a str, not '%s'",
203
                     Py_TYPE(note)->tp_name);
204
        return NULL;
205
    }
206
207
    if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) {
  Branch (207:9): [True: 32, False: 22]
208
        PyObject *new_notes = PyList_New(0);
209
        if (new_notes == NULL) {
  Branch (209:13): [True: 0, False: 32]
210
            return NULL;
211
        }
212
        if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) {
  Branch (212:13): [True: 0, False: 32]
213
            Py_DECREF(new_notes);
214
            return NULL;
215
        }
216
        Py_DECREF(new_notes);
217
    }
218
    PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__));
219
    if (notes == NULL) {
  Branch (219:9): [True: 0, False: 54]
220
        return NULL;
221
    }
222
    if (!PyList_Check(notes)) {
  Branch (222:9): [True: 3, False: 51]
223
        Py_DECREF(notes);
224
        PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
225
        return NULL;
226
    }
227
    if (PyList_Append(notes, note) < 0) {
  Branch (227:9): [True: 0, False: 51]
228
        Py_DECREF(notes);
229
        return NULL;
230
    }
231
    Py_DECREF(notes);
232
    Py_RETURN_NONE;
233
}
234
235
PyDoc_STRVAR(add_note_doc,
236
"Exception.add_note(note) --\n\
237
    add a note to the exception");
238
239
static PyMethodDef BaseException_methods[] = {
240
   {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
241
   {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
242
   {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
243
    with_traceback_doc},
244
   {"add_note", (PyCFunction)BaseException_add_note, METH_O,
245
    add_note_doc},
246
   {NULL, NULL, 0, NULL},
247
};
248
249
static PyObject *
250
BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
251
{
252
    if (self->args == NULL) {
  Branch (252:9): [True: 0, False: 7.63k]
253
        Py_RETURN_NONE;
254
    }
255
    Py_INCREF(self->args);
256
    return self->args;
257
}
258
259
static int
260
BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
261
{
262
    PyObject *seq;
263
    if (val == NULL) {
  Branch (263:9): [True: 0, False: 1.26k]
264
        PyErr_SetString(PyExc_TypeError, "args may not be deleted");
265
        return -1;
266
    }
267
    seq = PySequence_Tuple(val);
268
    if (!seq)
  Branch (268:9): [True: 0, False: 1.26k]
269
        return -1;
270
    Py_XSETREF(self->args, seq);
271
    return 0;
272
}
273
274
static PyObject *
275
BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
276
{
277
    if (self->traceback == NULL) {
  Branch (277:9): [True: 10.2k, False: 4.09k]
278
        Py_RETURN_NONE;
279
    }
280
    Py_INCREF(self->traceback);
281
    return self->traceback;
282
}
283
284
static int
285
BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
286
{
287
    if (tb == NULL) {
  Branch (287:9): [True: 0, False: 3.41M]
288
        PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
289
        return -1;
290
    }
291
    else if (!(tb == Py_None || PyTraceBack_Check(tb))) {
  Branch (291:16): [True: 185k, False: 3.23M]
292
        PyErr_SetString(PyExc_TypeError,
293
                        "__traceback__ must be a traceback or None");
294
        return -1;
295
    }
296
297
    Py_INCREF(tb);
298
    Py_XSETREF(self->traceback, tb);
299
    return 0;
300
}
301
302
static PyObject *
303
BaseException_get_context(PyObject *self, void *Py_UNUSED(ignored))
304
{
305
    PyObject *res = PyException_GetContext(self);
306
    if (res)
  Branch (306:9): [True: 6.45k, False: 13.1k]
307
        return res;  /* new reference already returned above */
308
    
Py_RETURN_NONE13.1k
;
309
}
310
311
static int
312
BaseException_set_context(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
313
{
314
    if (arg == NULL) {
  Branch (314:9): [True: 1, False: 130]
315
        PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
316
        return -1;
317
    } else if (arg == Py_None) {
  Branch (317:16): [True: 100, False: 30]
318
        arg = NULL;
319
    } else 
if (30
!30
PyExceptionInstance_Check30
(arg)) {
  Branch (319:16): [True: 1, False: 29]
320
        PyErr_SetString(PyExc_TypeError, "exception context must be None "
321
                        "or derive from BaseException");
322
        return -1;
323
    } else {
324
        /* PyException_SetContext steals this reference */
325
        Py_INCREF(arg);
326
    }
327
    PyException_SetContext(self, arg);
328
    return 0;
329
}
330
331
static PyObject *
332
BaseException_get_cause(PyObject *self, void *Py_UNUSED(ignored))
333
{
334
    PyObject *res = PyException_GetCause(self);
335
    if (res)
  Branch (335:9): [True: 210, False: 13.7k]
336
        return res;  /* new reference already returned above */
337
    
Py_RETURN_NONE13.7k
;
338
}
339
340
static int
341
BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
342
{
343
    if (arg == NULL) {
  Branch (343:9): [True: 1, False: 293]
344
        PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
345
        return -1;
346
    } else if (arg == Py_None) {
  Branch (346:16): [True: 1, False: 292]
347
        arg = NULL;
348
    } else if (!PyExceptionInstance_Check(arg)) {
  Branch (348:16): [True: 1, False: 291]
349
        PyErr_SetString(PyExc_TypeError, "exception cause must be None "
350
                        "or derive from BaseException");
351
        return -1;
352
    } else {
353
        /* PyException_SetCause steals this reference */
354
        Py_INCREF(arg);
355
    }
356
    PyException_SetCause(self, arg);
357
    return 0;
358
}
359
360
361
static PyGetSetDef BaseException_getset[] = {
362
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
363
    {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
364
    {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
365
    {"__context__", BaseException_get_context,
366
     BaseException_set_context, PyDoc_STR("exception context")},
367
    {"__cause__", BaseException_get_cause,
368
     BaseException_set_cause, PyDoc_STR("exception cause")},
369
    {NULL},
370
};
371
372
373
PyObject *
374
PyException_GetTraceback(PyObject *self)
375
{
376
    PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
377
    Py_XINCREF(base_self->traceback);
378
    return base_self->traceback;
379
}
380
381
382
int
383
PyException_SetTraceback(PyObject *self, PyObject *tb)
384
{
385
    return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
386
}
387
388
PyObject *
389
PyException_GetCause(PyObject *self)
390
{
391
    PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
392
    Py_XINCREF(cause);
393
    return cause;
394
}
395
396
/* Steals a reference to cause */
397
void
398
PyException_SetCause(PyObject *self, PyObject *cause)
399
{
400
    PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
401
    base_self->suppress_context = 1;
402
    Py_XSETREF(base_self->cause, cause);
403
}
404
405
PyObject *
406
PyException_GetContext(PyObject *self)
407
{
408
    PyObject *context = _PyBaseExceptionObject_cast(self)->context;
409
    Py_XINCREF(context);
410
    return context;
411
}
412
413
/* Steals a reference to context */
414
void
415
PyException_SetContext(PyObject *self, PyObject *context)
416
{
417
    Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
418
}
419
420
const char *
421
PyExceptionClass_Name(PyObject *ob)
422
{
423
    assert(PyExceptionClass_Check(ob));
424
    return ((PyTypeObject*)ob)->tp_name;
425
}
426
427
static struct PyMemberDef BaseException_members[] = {
428
    {"__suppress_context__", T_BOOL,
429
     offsetof(PyBaseExceptionObject, suppress_context)},
430
    {NULL}
431
};
432
433
434
static PyTypeObject _PyExc_BaseException = {
435
    PyVarObject_HEAD_INIT(NULL, 0)
436
    "BaseException", /*tp_name*/
437
    sizeof(PyBaseExceptionObject), /*tp_basicsize*/
438
    0,                          /*tp_itemsize*/
439
    (destructor)BaseException_dealloc, /*tp_dealloc*/
440
    0,                          /*tp_vectorcall_offset*/
441
    0,                          /*tp_getattr*/
442
    0,                          /*tp_setattr*/
443
    0,                          /*tp_as_async*/
444
    (reprfunc)BaseException_repr, /*tp_repr*/
445
    0,                          /*tp_as_number*/
446
    0,                          /*tp_as_sequence*/
447
    0,                          /*tp_as_mapping*/
448
    0,                          /*tp_hash */
449
    0,                          /*tp_call*/
450
    (reprfunc)BaseException_str,  /*tp_str*/
451
    PyObject_GenericGetAttr,    /*tp_getattro*/
452
    PyObject_GenericSetAttr,    /*tp_setattro*/
453
    0,                          /*tp_as_buffer*/
454
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
455
        Py_TPFLAGS_BASE_EXC_SUBCLASS,  /*tp_flags*/
456
    PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
457
    (traverseproc)BaseException_traverse, /* tp_traverse */
458
    (inquiry)BaseException_clear, /* tp_clear */
459
    0,                          /* tp_richcompare */
460
    0,                          /* tp_weaklistoffset */
461
    0,                          /* tp_iter */
462
    0,                          /* tp_iternext */
463
    BaseException_methods,      /* tp_methods */
464
    BaseException_members,      /* tp_members */
465
    BaseException_getset,       /* tp_getset */
466
    0,                          /* tp_base */
467
    0,                          /* tp_dict */
468
    0,                          /* tp_descr_get */
469
    0,                          /* tp_descr_set */
470
    offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
471
    (initproc)BaseException_init, /* tp_init */
472
    0,                          /* tp_alloc */
473
    BaseException_new,          /* tp_new */
474
};
475
/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
476
from the previous implementation and also allowing Python objects to be used
477
in the API */
478
PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
479
480
/* note these macros omit the last semicolon so the macro invocation may
481
 * include it and not look strange.
482
 */
483
#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
484
static PyTypeObject _PyExc_ ## EXCNAME = { \
485
    PyVarObject_HEAD_INIT(NULL, 0) \
486
    # EXCNAME, \
487
    sizeof(PyBaseExceptionObject), \
488
    0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
489
    0, 0, 0, 0, 0, 0, 0, \
490
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
491
    PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
492
    (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
493
    0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
494
    (initproc)BaseException_init, 0, BaseException_new,\
495
}; \
496
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
497
498
#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
499
static PyTypeObject _PyExc_ ## EXCNAME = { \
500
    PyVarObject_HEAD_INIT(NULL, 0) \
501
    # EXCNAME, \
502
    sizeof(Py ## EXCSTORE ## Object), \
503
    0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
504
    0, 0, 0, 0, 0, \
505
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
506
    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
507
    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
508
    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
509
    (initproc)EXCSTORE ## _init, 0, 0, \
510
}; \
511
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
512
513
#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
514
                                EXCMETHODS, EXCMEMBERS, EXCGETSET, \
515
                                EXCSTR, EXCDOC) \
516
static PyTypeObject _PyExc_ ## EXCNAME = { \
517
    PyVarObject_HEAD_INIT(NULL, 0) \
518
    # EXCNAME, \
519
    sizeof(Py ## EXCSTORE ## Object), 0, \
520
    (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
521
    (reprfunc)EXCSTR, 0, 0, 0, \
522
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
523
    PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
524
    (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
525
    EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
526
    0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
527
    (initproc)EXCSTORE ## _init, 0, EXCNEW,\
528
}; \
529
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
530
531
532
/*
533
 *    Exception extends BaseException
534
 */
535
SimpleExtendsException(PyExc_BaseException, Exception,
536
                       "Common base class for all non-exit exceptions.");
537
538
539
/*
540
 *    TypeError extends Exception
541
 */
542
SimpleExtendsException(PyExc_Exception, TypeError,
543
                       "Inappropriate argument type.");
544
545
546
/*
547
 *    StopAsyncIteration extends Exception
548
 */
549
SimpleExtendsException(PyExc_Exception, StopAsyncIteration,
550
                       "Signal the end from iterator.__anext__().");
551
552
553
/*
554
 *    StopIteration extends Exception
555
 */
556
557
static PyMemberDef StopIteration_members[] = {
558
    {"value", T_OBJECT, offsetof(PyStopIterationObject, value), 0,
559
        PyDoc_STR("generator return value")},
560
    {NULL}  /* Sentinel */
561
};
562
563
static int
564
StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds)
565
{
566
    Py_ssize_t size = PyTuple_GET_SIZE(args);
567
    PyObject *value;
568
569
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (569:9): [True: 0, False: 665k]
570
        return -1;
571
    Py_CLEAR(self->value);
572
    if (size > 0)
  Branch (572:9): [True: 844, False: 664k]
573
        value = PyTuple_GET_ITEM(args, 0);
574
    else
575
        value = Py_None;
576
    Py_INCREF(value);
577
    self->value = value;
578
    return 0;
579
}
580
581
static int
582
StopIteration_clear(PyStopIterationObject *self)
583
{
584
    Py_CLEAR(self->value);
585
    return BaseException_clear((PyBaseExceptionObject *)self);
586
}
587
588
static void
589
StopIteration_dealloc(PyStopIterationObject *self)
590
{
591
    PyObject_GC_UnTrack(self);
592
    StopIteration_clear(self);
593
    Py_TYPE(self)->tp_free((PyObject *)self);
594
}
595
596
static int
597
StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
598
{
599
    Py_VISIT(self->value);
600
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
601
}
602
603
ComplexExtendsException(
604
    PyExc_Exception,       /* base */
605
    StopIteration,         /* name */
606
    StopIteration,         /* prefix for *_init, etc */
607
    0,                     /* new */
608
    0,                     /* methods */
609
    StopIteration_members, /* members */
610
    0,                     /* getset */
611
    0,                     /* str */
612
    "Signal the end from iterator.__next__()."
613
);
614
615
616
/*
617
 *    GeneratorExit extends BaseException
618
 */
619
SimpleExtendsException(PyExc_BaseException, GeneratorExit,
620
                       "Request that a generator exit.");
621
622
623
/*
624
 *    SystemExit extends BaseException
625
 */
626
627
static int
628
SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
629
{
630
    Py_ssize_t size = PyTuple_GET_SIZE(args);
631
632
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (632:9): [True: 0, False: 2.29k]
633
        return -1;
634
635
    if (size == 0)
  Branch (635:9): [True: 21, False: 2.27k]
636
        return 0;
637
    if (size == 1) {
  Branch (637:9): [True: 2.27k, False: 1]
638
        Py_INCREF(PyTuple_GET_ITEM(args, 0));
639
        Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
640
    }
641
    else { /* size > 1 */
642
        Py_INCREF(args);
643
        Py_XSETREF(self->code, args);
644
    }
645
    return 0;
646
}
647
648
static int
649
SystemExit_clear(PySystemExitObject *self)
650
{
651
    Py_CLEAR(self->code);
652
    return BaseException_clear((PyBaseExceptionObject *)self);
653
}
654
655
static void
656
SystemExit_dealloc(PySystemExitObject *self)
657
{
658
    _PyObject_GC_UNTRACK(self);
659
    SystemExit_clear(self);
660
    Py_TYPE(self)->tp_free((PyObject *)self);
661
}
662
663
static int
664
SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
665
{
666
    Py_VISIT(self->code);
667
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
668
}
669
670
static PyMemberDef SystemExit_members[] = {
671
    {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
672
        PyDoc_STR("exception code")},
673
    {NULL}  /* Sentinel */
674
};
675
676
ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
677
                        0, 0, SystemExit_members, 0, 0,
678
                        "Request to exit from the interpreter.");
679
680
/*
681
 *    BaseExceptionGroup extends BaseException
682
 *    ExceptionGroup extends BaseExceptionGroup and Exception
683
 */
684
685
686
static inline PyBaseExceptionGroupObject*
687
_PyBaseExceptionGroupObject_cast(PyObject *exc)
688
{
689
    assert(_PyBaseExceptionGroup_Check(exc));
690
    return (PyBaseExceptionGroupObject *)exc;
691
}
692
693
static PyObject *
694
BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
695
{
696
    struct _Py_exc_state *state = get_exc_state();
697
    PyTypeObject *PyExc_ExceptionGroup =
698
        (PyTypeObject*)state->PyExc_ExceptionGroup;
699
700
    PyObject *message = NULL;
701
    PyObject *exceptions = NULL;
702
703
    if (!PyArg_ParseTuple(args,
  Branch (703:9): [True: 7, False: 10.7k]
704
                          "UO:BaseExceptionGroup.__new__",
705
                          &message,
706
                          &exceptions)) {
707
        return NULL;
708
    }
709
710
    if (!PySequence_Check(exceptions)) {
  Branch (710:9): [True: 2, False: 10.7k]
711
        PyErr_SetString(
712
            PyExc_TypeError,
713
            "second argument (exceptions) must be a sequence");
714
        return NULL;
715
    }
716
717
    exceptions = PySequence_Tuple(exceptions);
718
    if (!exceptions) {
  Branch (718:9): [True: 0, False: 10.7k]
719
        return NULL;
720
    }
721
722
    /* We are now holding a ref to the exceptions tuple */
723
724
    Py_ssize_t numexcs = PyTuple_GET_SIZE(exceptions);
725
    if (numexcs == 0) {
  Branch (725:9): [True: 1, False: 10.7k]
726
        PyErr_SetString(
727
            PyExc_ValueError,
728
            "second argument (exceptions) must be a non-empty sequence");
729
        goto error;
730
    }
731
732
    bool nested_base_exceptions = false;
733
    for (Py_ssize_t i = 0; i < numexcs; 
i++17.1k
) {
  Branch (733:28): [True: 17.1k, False: 10.7k]
734
        PyObject *exc = PyTuple_GET_ITEM(exceptions, i);
735
        if (!exc) {
  Branch (735:13): [True: 0, False: 17.1k]
736
            goto error;
737
        }
738
        if (!PyExceptionInstance_Check(exc)) {
  Branch (738:13): [True: 2, False: 17.1k]
739
            PyErr_Format(
740
                PyExc_ValueError,
741
                "Item %d of second argument (exceptions) is not an exception",
742
                i);
743
            goto error;
744
        }
745
        int is_nonbase_exception = PyObject_IsInstance(exc, PyExc_Exception);
746
        if (is_nonbase_exception < 0) {
  Branch (746:13): [True: 0, False: 17.1k]
747
            goto error;
748
        }
749
        else if (is_nonbase_exception == 0) {
  Branch (749:18): [True: 23, False: 17.1k]
750
            nested_base_exceptions = true;
751
        }
752
    }
753
754
    PyTypeObject *cls = type;
755
    if (cls == PyExc_ExceptionGroup) {
  Branch (755:9): [True: 10.2k, False: 528]
756
        if (nested_base_exceptions) {
  Branch (756:13): [True: 1, False: 10.2k]
757
            PyErr_SetString(PyExc_TypeError,
758
                "Cannot nest BaseExceptions in an ExceptionGroup");
759
            goto error;
760
        }
761
    }
762
    else if (cls == (PyTypeObject*)PyExc_BaseExceptionGroup) {
  Branch (762:14): [True: 486, False: 42]
763
        if (!nested_base_exceptions) {
  Branch (763:13): [True: 468, False: 18]
764
            /* All nested exceptions are Exception subclasses,
765
             * wrap them in an ExceptionGroup
766
             */
767
            cls = PyExc_ExceptionGroup;
768
        }
769
    }
770
    else {
771
        /* Do nothing - we don't interfere with subclasses */
772
    }
773
774
    if (!cls) {
  Branch (774:9): [True: 0, False: 10.7k]
775
        /* Don't crash during interpreter shutdown
776
         * (PyExc_ExceptionGroup may have been cleared)
777
         */
778
        cls = (PyTypeObject*)PyExc_BaseExceptionGroup;
779
    }
780
    PyBaseExceptionGroupObject *self =
781
        _PyBaseExceptionGroupObject_cast(BaseException_new(cls, args, kwds));
782
    if (!self) {
  Branch (782:9): [True: 0, False: 10.7k]
783
        goto error;
784
    }
785
786
    self->msg = Py_NewRef(message);
787
    self->excs = exceptions;
788
    return (PyObject*)self;
789
error:
790
    Py_DECREF(exceptions);
791
    return NULL;
792
}
793
794
PyObject *
795
_PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs)
796
{
797
    PyObject *msg = PyUnicode_FromString(msg_str);
798
    if (!msg) {
  Branch (798:9): [True: 0, False: 50]
799
        return NULL;
800
    }
801
    PyObject *args = PyTuple_Pack(2, msg, excs);
802
    Py_DECREF(msg);
803
    if (!args) {
  Branch (803:9): [True: 0, False: 50]
804
        return NULL;
805
    }
806
    PyObject *result = PyObject_CallObject(PyExc_BaseExceptionGroup, args);
807
    Py_DECREF(args);
808
    return result;
809
}
810
811
static int
812
BaseExceptionGroup_init(PyBaseExceptionGroupObject *self,
813
    PyObject *args, PyObject *kwds)
814
{
815
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) {
816
        return -1;
817
    }
818
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) {
  Branch (818:9): [True: 0, False: 10.7k]
819
        return -1;
820
    }
821
    return 0;
822
}
823
824
static int
825
BaseExceptionGroup_clear(PyBaseExceptionGroupObject *self)
826
{
827
    Py_CLEAR(self->msg);
828
    Py_CLEAR(self->excs);
829
    return BaseException_clear((PyBaseExceptionObject *)self);
830
}
831
832
static void
833
BaseExceptionGroup_dealloc(PyBaseExceptionGroupObject *self)
834
{
835
    _PyObject_GC_UNTRACK(self);
836
    BaseExceptionGroup_clear(self);
837
    Py_TYPE(self)->tp_free((PyObject *)self);
838
}
839
840
static int
841
BaseExceptionGroup_traverse(PyBaseExceptionGroupObject *self,
842
     visitproc visit, void *arg)
843
{
844
    Py_VISIT(self->msg);
845
    Py_VISIT(self->excs);
846
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
847
}
848
849
static PyObject *
850
BaseExceptionGroup_str(PyBaseExceptionGroupObject *self)
851
{
852
    assert(self->msg);
853
    assert(PyUnicode_Check(self->msg));
854
855
    assert(PyTuple_CheckExact(self->excs));
856
    Py_ssize_t num_excs = PyTuple_Size(self->excs);
857
    return PyUnicode_FromFormat(
858
        "%S (%zd sub-exception%s)",
859
        self->msg, num_excs, num_excs > 1 ? 
"s"2.06k
:
""2.01k
);
  Branch (859:30): [True: 2.06k, False: 2.01k]
860
}
861
862
static PyObject *
863
BaseExceptionGroup_derive(PyObject *self_, PyObject *args)
864
{
865
    PyBaseExceptionGroupObject *self = _PyBaseExceptionGroupObject_cast(self_);
866
    PyObject *excs = NULL;
867
    if (!PyArg_ParseTuple(args, "O", &excs)) {
  Branch (867:9): [True: 0, False: 416]
868
        return NULL;
869
    }
870
    PyObject *init_args = PyTuple_Pack(2, self->msg, excs);
871
    if (!init_args) {
  Branch (871:9): [True: 0, False: 416]
872
        return NULL;
873
    }
874
    PyObject *eg = PyObject_CallObject(
875
        PyExc_BaseExceptionGroup, init_args);
876
    Py_DECREF(init_args);
877
    return eg;
878
}
879
880
static int
881
exceptiongroup_subset(
882
    PyBaseExceptionGroupObject *_orig, PyObject *excs, PyObject **result)
883
{
884
    /* Sets *result to an ExceptionGroup wrapping excs with metadata from
885
     * _orig. If excs is empty, sets *result to NULL.
886
     * Returns 0 on success and -1 on error.
887
888
     * This function is used by split() to construct the match/rest parts,
889
     * so excs is the matching or non-matching sub-sequence of orig->excs
890
     * (this function does not verify that it is a subsequence).
891
     */
892
    PyObject *orig = (PyObject *)_orig;
893
894
    *result = NULL;
895
    Py_ssize_t num_excs = PySequence_Size(excs);
896
    if (num_excs < 0) {
  Branch (896:9): [True: 0, False: 601]
897
        return -1;
898
    }
899
    else if (num_excs == 0) {
  Branch (899:14): [True: 161, False: 440]
900
        return 0;
901
    }
902
903
    PyObject *eg = PyObject_CallMethod(
904
        orig, "derive", "(O)", excs);
905
    if (!eg) {
  Branch (905:9): [True: 0, False: 440]
906
        return -1;
907
    }
908
909
    if (!_PyBaseExceptionGroup_Check(eg)) {
  Branch (909:9): [True: 0, False: 440]
910
        PyErr_SetString(PyExc_TypeError,
911
            "derive must return an instance of BaseExceptionGroup");
912
        goto error;
913
    }
914
915
    /* Now we hold a reference to the new eg */
916
917
    PyObject *tb = PyException_GetTraceback(orig);
918
    if (tb) {
  Branch (918:9): [True: 328, False: 112]
919
        int res = PyException_SetTraceback(eg, tb);
920
        Py_DECREF(tb);
921
        if (res < 0) {
  Branch (921:13): [True: 0, False: 328]
922
            goto error;
923
        }
924
    }
925
    PyException_SetContext(eg, PyException_GetContext(orig));
926
    PyException_SetCause(eg, PyException_GetCause(orig));
927
928
    if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) {
  Branch (928:9): [True: 15, False: 425]
929
        PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__));
930
        if (notes == NULL) {
  Branch (930:13): [True: 0, False: 15]
931
            goto error;
932
        }
933
        if (PySequence_Check(notes)) {
  Branch (933:13): [True: 13, False: 2]
934
            /* Make a copy so the parts have independent notes lists. */
935
            PyObject *notes_copy = PySequence_List(notes);
936
            Py_DECREF(notes);
937
            if (notes_copy == NULL) {
  Branch (937:17): [True: 0, False: 13]
938
                goto error;
939
            }
940
            int res = PyObject_SetAttr(eg, &_Py_ID(__notes__), notes_copy);
941
            Py_DECREF(notes_copy);
942
            if (res < 0) {
  Branch (942:17): [True: 0, False: 13]
943
                goto error;
944
            }
945
        }
946
        else {
947
            /* __notes__ is supposed to be a list, and split() is not a
948
             * good place to report earlier user errors, so we just ignore
949
             * notes of non-sequence type.
950
             */
951
            Py_DECREF(notes);
952
        }
953
    }
954
955
    *result = eg;
956
    return 0;
957
error:
958
    Py_DECREF(eg);
959
    return -1;
960
}
961
962
typedef enum {
963
    /* Exception type or tuple of thereof */
964
    EXCEPTION_GROUP_MATCH_BY_TYPE = 0,
965
    /* A PyFunction returning True for matching exceptions */
966
    EXCEPTION_GROUP_MATCH_BY_PREDICATE = 1,
967
    /* A set of leaf exceptions to include in the result.
968
     * This matcher type is used internally by the interpreter
969
     * to construct reraised exceptions.
970
     */
971
    EXCEPTION_GROUP_MATCH_INSTANCES = 2
972
} _exceptiongroup_split_matcher_type;
973
974
static int
975
get_matcher_type(PyObject *value,
976
                 _exceptiongroup_split_matcher_type *type)
977
{
978
    assert(value);
979
980
    if (PyFunction_Check(value)) {
981
        *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE;
982
        return 0;
983
    }
984
985
    if (PyExceptionClass_Check(value)) {
986
        *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
987
        return 0;
988
    }
989
990
    if (PyTuple_CheckExact(value)) {
991
        Py_ssize_t n = PyTuple_GET_SIZE(value);
992
        for (Py_ssize_t i=0; i<n; 
i++52
) {
  Branch (992:30): [True: 54, False: 25]
993
            if (!PyExceptionClass_Check(PyTuple_GET_ITEM(value, i))) {
994
                goto error;
995
            }
996
        }
997
        *type = EXCEPTION_GROUP_MATCH_BY_TYPE;
998
        return 0;
999
    }
1000
1001
error:
1002
    PyErr_SetString(
1003
        PyExc_TypeError,
1004
        "expected a function, exception type or tuple of exception types");
1005
    return -1;
1006
}
1007
1008
static int
1009
exceptiongroup_split_check_match(PyObject *exc,
1010
                                 _exceptiongroup_split_matcher_type matcher_type,
1011
                                 PyObject *matcher_value)
1012
{
1013
    switch (matcher_type) {
  Branch (1013:13): [True: 0, False: 3.01k]
1014
    case EXCEPTION_GROUP_MATCH_BY_TYPE: {
  Branch (1014:5): [True: 2.59k, False: 427]
1015
        assert(PyExceptionClass_Check(matcher_value) ||
1016
               PyTuple_CheckExact(matcher_value));
1017
        return PyErr_GivenExceptionMatches(exc, matcher_value);
1018
    }
1019
    case EXCEPTION_GROUP_MATCH_BY_PREDICATE: {
  Branch (1019:5): [True: 34, False: 2.98k]
1020
        assert(PyFunction_Check(matcher_value));
1021
        PyObject *exc_matches = PyObject_CallOneArg(matcher_value, exc);
1022
        if (exc_matches == NULL) {
  Branch (1022:13): [True: 0, False: 34]
1023
            return -1;
1024
        }
1025
        int is_true = PyObject_IsTrue(exc_matches);
1026
        Py_DECREF(exc_matches);
1027
        return is_true;
1028
    }
1029
    case EXCEPTION_GROUP_MATCH_INSTANCES: {
  Branch (1029:5): [True: 393, False: 2.62k]
1030
        assert(PySet_Check(matcher_value));
1031
        if (!_PyBaseExceptionGroup_Check(exc)) {
  Branch (1031:13): [True: 244, False: 149]
1032
            return PySet_Contains(matcher_value, exc);
1033
        }
1034
        return 0;
1035
    }
1036
    }
1037
    return 0;
1038
}
1039
1040
typedef struct {
1041
    PyObject *match;
1042
    PyObject *rest;
1043
} _exceptiongroup_split_result;
1044
1045
static int
1046
exceptiongroup_split_recursive(PyObject *exc,
1047
                               _exceptiongroup_split_matcher_type matcher_type,
1048
                               PyObject *matcher_value,
1049
                               bool construct_rest,
1050
                               _exceptiongroup_split_result *result)
1051
{
1052
    result->match = NULL;
1053
    result->rest = NULL;
1054
1055
    int is_match = exceptiongroup_split_check_match(
1056
        exc, matcher_type, matcher_value);
1057
    if (is_match < 0) {
  Branch (1057:9): [True: 0, False: 3.01k]
1058
        return -1;
1059
    }
1060
1061
    if (is_match) {
  Branch (1061:9): [True: 332, False: 2.68k]
1062
        /* Full match */
1063
        result->match = Py_NewRef(exc);
1064
        return 0;
1065
    }
1066
    else if (!_PyBaseExceptionGroup_Check(exc)) {
  Branch (1066:14): [True: 348, False: 2.33k]
1067
        /* Leaf exception and no match */
1068
        if (construct_rest) {
  Branch (1068:13): [True: 154, False: 194]
1069
            result->rest = Py_NewRef(exc);
1070
        }
1071
        return 0;
1072
    }
1073
1074
    /* Partial match */
1075
1076
    PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
1077
    assert(PyTuple_CheckExact(eg->excs));
1078
    Py_ssize_t num_excs = PyTuple_Size(eg->excs);
1079
    if (num_excs < 0) {
  Branch (1079:9): [True: 0, False: 2.33k]
1080
        return -1;
1081
    }
1082
    assert(num_excs > 0); /* checked in constructor, and excs is read-only */
1083
1084
    int retval = -1;
1085
    PyObject *match_list = PyList_New(0);
1086
    if (!match_list) {
  Branch (1086:9): [True: 0, False: 2.33k]
1087
        return -1;
1088
    }
1089
1090
    PyObject *rest_list = NULL;
1091
    if (construct_rest) {
  Branch (1091:9): [True: 1.17k, False: 1.16k]
1092
        rest_list = PyList_New(0);
1093
        if (!rest_list) {
  Branch (1093:13): [True: 0, False: 1.17k]
1094
            goto done;
1095
        }
1096
    }
1097
    /* recursive calls */
1098
    
for (Py_ssize_t i = 0; 2.33k
i < num_excs;
i++805
) {
  Branch (1098:28): [True: 2.74k, False: 399]
1099
        PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
1100
        _exceptiongroup_split_result rec_result;
1101
        if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
  Branch (1101:13): [True: 2, False: 2.74k]
1102
            goto done;
1103
        }
1104
        if (exceptiongroup_split_recursive(
  Branch (1104:13): [True: 1.93k, False: 805]
1105
                e, matcher_type, matcher_value,
1106
                construct_rest, &rec_result) < 0) {
1107
            assert(!rec_result.match);
1108
            assert(!rec_result.rest);
1109
            _Py_LeaveRecursiveCall();
1110
            goto done;
1111
        }
1112
        _Py_LeaveRecursiveCall();
1113
        if (rec_result.match) {
  Branch (1113:13): [True: 418, False: 387]
1114
            assert(PyList_CheckExact(match_list));
1115
            if (PyList_Append(match_list, rec_result.match) < 0) {
  Branch (1115:17): [True: 0, False: 418]
1116
                Py_DECREF(rec_result.match);
1117
                goto done;
1118
            }
1119
            Py_DECREF(rec_result.match);
1120
        }
1121
        if (rec_result.rest) {
  Branch (1121:13): [True: 204, False: 601]
1122
            assert(construct_rest);
1123
            assert(PyList_CheckExact(rest_list));
1124
            if (PyList_Append(rest_list, rec_result.rest) < 0) {
  Branch (1124:17): [True: 0, False: 204]
1125
                Py_DECREF(rec_result.rest);
1126
                goto done;
1127
            }
1128
            Py_DECREF(rec_result.rest);
1129
        }
1130
    }
1131
1132
    /* construct result */
1133
    if (exceptiongroup_subset(eg, match_list, &result->match) < 0) {
  Branch (1133:9): [True: 0, False: 399]
1134
        goto done;
1135
    }
1136
1137
    if (construct_rest) {
  Branch (1137:9): [True: 202, False: 197]
1138
        assert(PyList_CheckExact(rest_list));
1139
        if (exceptiongroup_subset(eg, rest_list, &result->rest) < 0) {
  Branch (1139:13): [True: 0, False: 202]
1140
            Py_CLEAR(result->match);
1141
            goto done;
1142
        }
1143
    }
1144
    retval = 0;
1145
done:
1146
    Py_DECREF(match_list);
1147
    Py_XDECREF(rest_list);
1148
    if (retval < 0) {
  Branch (1148:9): [True: 1.93k, False: 399]
1149
        Py_CLEAR(result->match);
1150
        Py_CLEAR(result->rest);
1151
    }
1152
    return retval;
1153
}
1154
1155
static PyObject *
1156
BaseExceptionGroup_split(PyObject *self, PyObject *args)
1157
{
1158
    PyObject *matcher_value = NULL;
1159
    if (!PyArg_UnpackTuple(args, "split", 1, 1, &matcher_value)) {
  Branch (1159:9): [True: 0, False: 145]
1160
        return NULL;
1161
    }
1162
1163
    _exceptiongroup_split_matcher_type matcher_type;
1164
    if (get_matcher_type(matcher_value, &matcher_type) < 0) {
  Branch (1164:9): [True: 4, False: 141]
1165
        return NULL;
1166
    }
1167
1168
    _exceptiongroup_split_result split_result;
1169
    bool construct_rest = true;
1170
    if (exceptiongroup_split_recursive(
  Branch (1170:9): [True: 1, False: 140]
1171
            self, matcher_type, matcher_value,
1172
            construct_rest, &split_result) < 0) {
1173
        return NULL;
1174
    }
1175
1176
    PyObject *result = PyTuple_Pack(
1177
            2,
1178
            split_result.match ? 
split_result.match124
:
Py_None16
,
  Branch (1178:13): [True: 124, False: 16]
1179
            split_result.rest ? 
split_result.rest96
:
Py_None44
);
  Branch (1179:13): [True: 96, False: 44]
1180
1181
    Py_XDECREF(split_result.match);
1182
    Py_XDECREF(split_result.rest);
1183
    return result;
1184
}
1185
1186
static PyObject *
1187
BaseExceptionGroup_subgroup(PyObject *self, PyObject *args)
1188
{
1189
    PyObject *matcher_value = NULL;
1190
    if (!PyArg_UnpackTuple(args, "subgroup", 1, 1, &matcher_value)) {
  Branch (1190:9): [True: 0, False: 39]
1191
        return NULL;
1192
    }
1193
1194
    _exceptiongroup_split_matcher_type matcher_type;
1195
    if (get_matcher_type(matcher_value, &matcher_type) < 0) {
  Branch (1195:9): [True: 4, False: 35]
1196
        return NULL;
1197
    }
1198
1199
    _exceptiongroup_split_result split_result;
1200
    bool construct_rest = false;
1201
    if (exceptiongroup_split_recursive(
  Branch (1201:9): [True: 1, False: 34]
1202
            self, matcher_type, matcher_value,
1203
            construct_rest, &split_result) < 0) {
1204
        return NULL;
1205
    }
1206
1207
    PyObject *result = Py_NewRef(
1208
            split_result.match ? split_result.match : Py_None);
1209
1210
    Py_XDECREF(split_result.match);
1211
    assert(!split_result.rest);
1212
    return result;
1213
}
1214
1215
static int
1216
collect_exception_group_leaves(PyObject *exc, PyObject *leaves)
1217
{
1218
    if (Py_IsNone(exc)) {
1219
        return 0;
1220
    }
1221
1222
    assert(PyExceptionInstance_Check(exc));
1223
    assert(PySet_Check(leaves));
1224
1225
    /* Add all leaf exceptions in exc to the leaves set */
1226
1227
    if (!_PyBaseExceptionGroup_Check(exc)) {
  Branch (1227:9): [True: 94, False: 101]
1228
        if (PySet_Add(leaves, exc) < 0) {
  Branch (1228:13): [True: 0, False: 94]
1229
            return -1;
1230
        }
1231
        return 0;
1232
    }
1233
    PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc);
1234
    Py_ssize_t num_excs = PyTuple_GET_SIZE(eg->excs);
1235
    /* recursive calls */
1236
    for (Py_ssize_t i = 0; i < num_excs; 
i++131
) {
  Branch (1236:28): [True: 131, False: 101]
1237
        PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
1238
        if (_Py_EnterRecursiveCall(" in collect_exception_group_leaves")) {
  Branch (1238:13): [True: 0, False: 131]
1239
            return -1;
1240
        }
1241
        int res = collect_exception_group_leaves(e, leaves);
1242
        _Py_LeaveRecursiveCall();
1243
        if (res < 0) {
  Branch (1243:13): [True: 0, False: 131]
1244
            return -1;
1245
        }
1246
    }
1247
    return 0;
1248
}
1249
1250
/* This function is used by the interpreter to construct reraised
1251
 * exception groups. It takes an exception group eg and a list
1252
 * of exception groups keep and returns the sub-exception group
1253
 * of eg which contains all leaf exceptions that are contained
1254
 * in any exception group in keep.
1255
 */
1256
static PyObject *
1257
exception_group_projection(PyObject *eg, PyObject *keep)
1258
{
1259
    assert(_PyBaseExceptionGroup_Check(eg));
1260
    assert(PyList_CheckExact(keep));
1261
1262
    PyObject *leaves = PySet_New(NULL);
1263
    if (!leaves) {
  Branch (1263:9): [True: 0, False: 100]
1264
        return NULL;
1265
    }
1266
1267
    Py_ssize_t n = PyList_GET_SIZE(keep);
1268
    for (Py_ssize_t i = 0; i < n; 
i++64
) {
  Branch (1268:28): [True: 64, False: 100]
1269
        PyObject *e = PyList_GET_ITEM(keep, i);
1270
        assert(e != NULL);
1271
        assert(_PyBaseExceptionGroup_Check(e));
1272
        if (collect_exception_group_leaves(e, leaves) < 0) {
  Branch (1272:13): [True: 0, False: 64]
1273
            Py_DECREF(leaves);
1274
            return NULL;
1275
        }
1276
    }
1277
1278
    _exceptiongroup_split_result split_result;
1279
    bool construct_rest = false;
1280
    int err = exceptiongroup_split_recursive(
1281
                eg, EXCEPTION_GROUP_MATCH_INSTANCES, leaves,
1282
                construct_rest, &split_result);
1283
    Py_DECREF(leaves);
1284
    if (err < 0) {
  Branch (1284:9): [True: 0, False: 100]
1285
        return NULL;
1286
    }
1287
1288
    PyObject *result = split_result.match ?
  Branch (1288:24): [True: 57, False: 43]
1289
        split_result.match : 
Py_NewRef43
(Py_None);
1290
    assert(split_result.rest == NULL);
1291
    return result;
1292
}
1293
1294
static bool
1295
is_same_exception_metadata(PyObject *exc1, PyObject *exc2)
1296
{
1297
    assert(PyExceptionInstance_Check(exc1));
1298
    assert(PyExceptionInstance_Check(exc2));
1299
1300
    PyBaseExceptionObject *e1 = (PyBaseExceptionObject *)exc1;
1301
    PyBaseExceptionObject *e2 = (PyBaseExceptionObject *)exc2;
1302
1303
    return (e1->notes == e2->notes &&
  Branch (1303:13): [True: 80, False: 0]
1304
            e1->traceback == e2->traceback &&
  Branch (1304:13): [True: 64, False: 16]
1305
            
e1->cause == e2->cause64
&&
  Branch (1305:13): [True: 64, False: 0]
1306
            
e1->context == e2->context64
);
  Branch (1306:13): [True: 64, False: 0]
1307
}
1308
1309
/*
1310
   This function is used by the interpreter to calculate
1311
   the exception group to be raised at the end of a
1312
   try-except* construct.
1313
1314
   orig: the original except that was caught.
1315
   excs: a list of exceptions that were raised/reraised
1316
         in the except* clauses.
1317
1318
   Calculates an exception group to raise. It contains
1319
   all exceptions in excs, where those that were reraised
1320
   have same nesting structure as in orig, and those that
1321
   were raised (if any) are added as siblings in a new EG.
1322
1323
   Returns NULL and sets an exception on failure.
1324
*/
1325
PyObject *
1326
_PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
1327
{
1328
    assert(PyExceptionInstance_Check(orig));
1329
    assert(PyList_Check(excs));
1330
1331
    Py_ssize_t numexcs = PyList_GET_SIZE(excs);
1332
1333
    if (numexcs == 0) {
  Branch (1333:9): [True: 0, False: 150]
1334
        return Py_NewRef(Py_None);
1335
    }
1336
1337
    if (!_PyBaseExceptionGroup_Check(orig)) {
  Branch (1337:9): [True: 50, False: 100]
1338
        /* a naked exception was caught and wrapped. Only one except* clause
1339
         * could have executed,so there is at most one exception to raise.
1340
         */
1341
1342
        assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None));
1343
1344
        PyObject *e = PyList_GET_ITEM(excs, 0);
1345
        assert(e != NULL);
1346
        return Py_NewRef(e);
1347
    }
1348
1349
    PyObject *raised_list = PyList_New(0);
1350
    if (raised_list == NULL) {
  Branch (1350:9): [True: 0, False: 100]
1351
        return NULL;
1352
    }
1353
    PyObject* reraised_list = PyList_New(0);
1354
    if (reraised_list == NULL) {
  Branch (1354:9): [True: 0, False: 100]
1355
        Py_DECREF(raised_list);
1356
        return NULL;
1357
    }
1358
1359
    /* Now we are holding refs to raised_list and reraised_list */
1360
1361
    PyObject *result = NULL;
1362
1363
    /* Split excs into raised and reraised by comparing metadata with orig */
1364
    for (Py_ssize_t i = 0; i < numexcs; 
i++128
) {
  Branch (1364:28): [True: 128, False: 100]
1365
        PyObject *e = PyList_GET_ITEM(excs, i);
1366
        assert(e != NULL);
1367
        if (Py_IsNone(e)) {
1368
            continue;
1369
        }
1370
        bool is_reraise = is_same_exception_metadata(e, orig);
1371
        PyObject *append_list = is_reraise ? 
reraised_list64
:
raised_list16
;
  Branch (1371:33): [True: 64, False: 16]
1372
        if (PyList_Append(append_list, e) < 0) {
  Branch (1372:13): [True: 0, False: 80]
1373
            goto done;
1374
        }
1375
    }
1376
1377
    PyObject *reraised_eg = exception_group_projection(orig, reraised_list);
1378
    if (reraised_eg == NULL) {
  Branch (1378:9): [True: 0, False: 100]
1379
        goto done;
1380
    }
1381
1382
    if (!Py_IsNone(reraised_eg)) {
  Branch (1382:9): [True: 57, False: 43]
1383
        assert(is_same_exception_metadata(reraised_eg, orig));
1384
    }
1385
    Py_ssize_t num_raised = PyList_GET_SIZE(raised_list);
1386
    if (num_raised == 0) {
  Branch (1386:9): [True: 88, False: 12]
1387
        result = reraised_eg;
1388
    }
1389
    else if (num_raised > 0) {
  Branch (1389:14): [True: 12, False: 0]
1390
        int res = 0;
1391
        if (!Py_IsNone(reraised_eg)) {
  Branch (1391:13): [True: 4, False: 8]
1392
            res = PyList_Append(raised_list, reraised_eg);
1393
        }
1394
        Py_DECREF(reraised_eg);
1395
        if (res < 0) {
  Branch (1395:13): [True: 0, False: 12]
1396
            goto done;
1397
        }
1398
        result = _PyExc_CreateExceptionGroup("", raised_list);
1399
        if (result == NULL) {
  Branch (1399:13): [True: 0, False: 12]
1400
            goto done;
1401
        }
1402
    }
1403
1404
done:
1405
    Py_XDECREF(raised_list);
1406
    Py_XDECREF(reraised_list);
1407
    return result;
1408
}
1409
1410
static PyMemberDef BaseExceptionGroup_members[] = {
1411
    {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY,
1412
        PyDoc_STR("exception message")},
1413
    {"exceptions", T_OBJECT, offsetof(PyBaseExceptionGroupObject, excs), READONLY,
1414
        PyDoc_STR("nested exceptions")},
1415
    {NULL}  /* Sentinel */
1416
};
1417
1418
static PyMethodDef BaseExceptionGroup_methods[] = {
1419
    {"__class_getitem__", (PyCFunction)Py_GenericAlias,
1420
      METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
1421
    {"derive", (PyCFunction)BaseExceptionGroup_derive, METH_VARARGS},
1422
    {"split", (PyCFunction)BaseExceptionGroup_split, METH_VARARGS},
1423
    {"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_VARARGS},
1424
    {NULL}
1425
};
1426
1427
ComplexExtendsException(PyExc_BaseException, BaseExceptionGroup,
1428
    BaseExceptionGroup, BaseExceptionGroup_new /* new */,
1429
    BaseExceptionGroup_methods, BaseExceptionGroup_members,
1430
    0 /* getset */, BaseExceptionGroup_str,
1431
    "A combination of multiple unrelated exceptions.");
1432
1433
/*
1434
 *    ExceptionGroup extends BaseExceptionGroup, Exception
1435
 */
1436
static PyObject*
1437
create_exception_group_class(void) {
1438
    struct _Py_exc_state *state = get_exc_state();
1439
1440
    PyObject *bases = PyTuple_Pack(
1441
        2, PyExc_BaseExceptionGroup, PyExc_Exception);
1442
    if (bases == NULL) {
  Branch (1442:9): [True: 0, False: 278]
1443
        return NULL;
1444
    }
1445
1446
    assert(!state->PyExc_ExceptionGroup);
1447
    state->PyExc_ExceptionGroup = PyErr_NewException(
1448
        "builtins.ExceptionGroup", bases, NULL);
1449
1450
    Py_DECREF(bases);
1451
    return state->PyExc_ExceptionGroup;
1452
}
1453
1454
/*
1455
 *    KeyboardInterrupt extends BaseException
1456
 */
1457
SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
1458
                       "Program interrupted by user.");
1459
1460
1461
/*
1462
 *    ImportError extends Exception
1463
 */
1464
1465
static int
1466
ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds)
1467
{
1468
    static char *kwlist[] = {"name", "path", 0};
1469
    PyObject *empty_tuple;
1470
    PyObject *msg = NULL;
1471
    PyObject *name = NULL;
1472
    PyObject *path = NULL;
1473
1474
    if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1)
  Branch (1474:9): [True: 0, False: 5.32k]
1475
        return -1;
1476
1477
    empty_tuple = PyTuple_New(0);
1478
    if (!empty_tuple)
  Branch (1478:9): [True: 0, False: 5.32k]
1479
        return -1;
1480
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist,
  Branch (1480:9): [True: 6, False: 5.31k]
1481
                                     &name, &path)) {
1482
        Py_DECREF(empty_tuple);
1483
        return -1;
1484
    }
1485
    Py_DECREF(empty_tuple);
1486
1487
    Py_XINCREF(name);
1488
    Py_XSETREF(self->name, name);
1489
1490
    Py_XINCREF(path);
1491
    Py_XSETREF(self->path, path);
1492
1493
    if (PyTuple_GET_SIZE(args) == 1) {
  Branch (1493:9): [True: 5.25k, False: 63]
1494
        msg = PyTuple_GET_ITEM(args, 0);
1495
        Py_INCREF(msg);
1496
    }
1497
    Py_XSETREF(self->msg, msg);
1498
1499
    return 0;
1500
}
1501
1502
static int
1503
ImportError_clear(PyImportErrorObject *self)
1504
{
1505
    Py_CLEAR(self->msg);
1506
    Py_CLEAR(self->name);
1507
    Py_CLEAR(self->path);
1508
    return BaseException_clear((PyBaseExceptionObject *)self);
1509
}
1510
1511
static void
1512
ImportError_dealloc(PyImportErrorObject *self)
1513
{
1514
    _PyObject_GC_UNTRACK(self);
1515
    ImportError_clear(self);
1516
    Py_TYPE(self)->tp_free((PyObject *)self);
1517
}
1518
1519
static int
1520
ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg)
1521
{
1522
    Py_VISIT(self->msg);
1523
    Py_VISIT(self->name);
1524
    Py_VISIT(self->path);
1525
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1526
}
1527
1528
static PyObject *
1529
ImportError_str(PyImportErrorObject *self)
1530
{
1531
    if (self->msg && PyUnicode_CheckExact(self->msg)) {
  Branch (1531:9): [True: 82, False: 0]
1532
        Py_INCREF(self->msg);
1533
        return self->msg;
1534
    }
1535
    else {
1536
        return BaseException_str((PyBaseExceptionObject *)self);
1537
    }
1538
}
1539
1540
static PyObject *
1541
ImportError_getstate(PyImportErrorObject *self)
1542
{
1543
    PyObject *dict = ((PyBaseExceptionObject *)self)->dict;
1544
    if (self->name || 
self->path22
) {
  Branch (1544:9): [True: 16, False: 22]
  Branch (1544:23): [True: 8, False: 14]
1545
        dict = dict ? 
PyDict_Copy(dict)0
: PyDict_New();
  Branch (1545:16): [True: 0, False: 24]
1546
        if (dict == NULL)
  Branch (1546:13): [True: 0, False: 24]
1547
            return NULL;
1548
        if (self->name && 
PyDict_SetItem(dict, &16
_Py_ID16
(name), self->name) < 0) {
  Branch (1548:13): [True: 16, False: 8]
  Branch (1548:27): [True: 0, False: 16]
1549
            Py_DECREF(dict);
1550
            return NULL;
1551
        }
1552
        if (self->path && 
PyDict_SetItem(dict, &16
_Py_ID16
(path), self->path) < 0) {
  Branch (1552:13): [True: 16, False: 8]
  Branch (1552:27): [True: 0, False: 16]
1553
            Py_DECREF(dict);
1554
            return NULL;
1555
        }
1556
        return dict;
1557
    }
1558
    else if (dict) {
  Branch (1558:14): [True: 0, False: 14]
1559
        Py_INCREF(dict);
1560
        return dict;
1561
    }
1562
    else {
1563
        Py_RETURN_NONE;
1564
    }
1565
}
1566
1567
/* Pickling support */
1568
static PyObject *
1569
ImportError_reduce(PyImportErrorObject *self, PyObject *Py_UNUSED(ignored))
1570
{
1571
    PyObject *res;
1572
    PyObject *args;
1573
    PyObject *state = ImportError_getstate(self);
1574
    if (state == NULL)
  Branch (1574:9): [True: 0, False: 38]
1575
        return NULL;
1576
    args = ((PyBaseExceptionObject *)self)->args;
1577
    if (state == Py_None)
  Branch (1577:9): [True: 14, False: 24]
1578
        res = PyTuple_Pack(2, Py_TYPE(self), args);
1579
    else
1580
        res = PyTuple_Pack(3, Py_TYPE(self), args, state);
1581
    Py_DECREF(state);
1582
    return res;
1583
}
1584
1585
static PyMemberDef ImportError_members[] = {
1586
    {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
1587
        PyDoc_STR("exception message")},
1588
    {"name", T_OBJECT, offsetof(PyImportErrorObject, name), 0,
1589
        PyDoc_STR("module name")},
1590
    {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0,
1591
        PyDoc_STR("module path")},
1592
    {NULL}  /* Sentinel */
1593
};
1594
1595
static PyMethodDef ImportError_methods[] = {
1596
    {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
1597
    {NULL}
1598
};
1599
1600
ComplexExtendsException(PyExc_Exception, ImportError,
1601
                        ImportError, 0 /* new */,
1602
                        ImportError_methods, ImportError_members,
1603
                        0 /* getset */, ImportError_str,
1604
                        "Import can't find module, or can't find name in "
1605
                        "module.");
1606
1607
/*
1608
 *    ModuleNotFoundError extends ImportError
1609
 */
1610
1611
MiddlingExtendsException(PyExc_ImportError, ModuleNotFoundError, ImportError,
1612
                         "Module not found.");
1613
1614
/*
1615
 *    OSError extends Exception
1616
 */
1617
1618
#ifdef MS_WINDOWS
1619
#include "errmap.h"
1620
#endif
1621
1622
/* Where a function has a single filename, such as open() or some
1623
 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
1624
 * called, giving a third argument which is the filename.  But, so
1625
 * that old code using in-place unpacking doesn't break, e.g.:
1626
 *
1627
 * except OSError, (errno, strerror):
1628
 *
1629
 * we hack args so that it only contains two items.  This also
1630
 * means we need our own __str__() which prints out the filename
1631
 * when it was supplied.
1632
 *
1633
 * (If a function has two filenames, such as rename(), symlink(),
1634
 * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called,
1635
 * which allows passing in a second filename.)
1636
 */
1637
1638
/* This function doesn't cleanup on error, the caller should */
1639
static int
1640
oserror_parse_args(PyObject **p_args,
1641
                   PyObject **myerrno, PyObject **strerror,
1642
                   PyObject **filename, PyObject **filename2
1643
#ifdef MS_WINDOWS
1644
                   , PyObject **winerror
1645
#endif
1646
                  )
1647
{
1648
    Py_ssize_t nargs;
1649
    PyObject *args = *p_args;
1650
#ifndef MS_WINDOWS
1651
    /*
1652
     * ignored on non-Windows platforms,
1653
     * but parsed so OSError has a consistent signature
1654
     */
1655
    PyObject *_winerror = NULL;
1656
    PyObject **winerror = &_winerror;
1657
#endif /* MS_WINDOWS */
1658
1659
    nargs = PyTuple_GET_SIZE(args);
1660
1661
    if (nargs >= 2 && 
nargs <= 5177k
) {
  Branch (1661:9): [True: 177k, False: 2.11k]
  Branch (1661:23): [True: 177k, False: 0]
1662
        if (!PyArg_UnpackTuple(args, "OSError", 2, 5,
  Branch (1662:13): [True: 0, False: 177k]
1663
                               myerrno, strerror,
1664
                               filename, winerror, filename2))
1665
            return -1;
1666
#ifdef MS_WINDOWS
1667
        if (*winerror && PyLong_Check(*winerror)) {
1668
            long errcode, winerrcode;
1669
            PyObject *newargs;
1670
            Py_ssize_t i;
1671
1672
            winerrcode = PyLong_AsLong(*winerror);
1673
            if (winerrcode == -1 && PyErr_Occurred())
1674
                return -1;
1675
            errcode = winerror_to_errno(winerrcode);
1676
            *myerrno = PyLong_FromLong(errcode);
1677
            if (!*myerrno)
1678
                return -1;
1679
            newargs = PyTuple_New(nargs);
1680
            if (!newargs)
1681
                return -1;
1682
            PyTuple_SET_ITEM(newargs, 0, *myerrno);
1683
            for (i = 1; i < nargs; i++) {
1684
                PyObject *val = PyTuple_GET_ITEM(args, i);
1685
                Py_INCREF(val);
1686
                PyTuple_SET_ITEM(newargs, i, val);
1687
            }
1688
            Py_DECREF(args);
1689
            args = *p_args = newargs;
1690
        }
1691
#endif /* MS_WINDOWS */
1692
    }
1693
1694
    return 0;
1695
}
1696
1697
static int
1698
oserror_init(PyOSErrorObject *self, PyObject **p_args,
1699
             PyObject *myerrno, PyObject *strerror,
1700
             PyObject *filename, PyObject *filename2
1701
#ifdef MS_WINDOWS
1702
             , PyObject *winerror
1703
#endif
1704
             )
1705
{
1706
    PyObject *args = *p_args;
1707
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1708
1709
    /* self->filename will remain Py_None otherwise */
1710
    if (filename && 
filename != 150k
Py_None150k
) {
  Branch (1710:9): [True: 150k, False: 28.8k]
  Branch (1710:21): [True: 150k, False: 9]
1711
        if (Py_IS_TYPE(self, (PyTypeObject *) PyExc_BlockingIOError) &&
1712
            
PyNumber_Check(filename)35
) {
  Branch (1712:13): [True: 32, False: 3]
1713
            /* BlockingIOError's 3rd argument can be the number of
1714
             * characters written.
1715
             */
1716
            self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
1717
            if (self->written == -1 && 
PyErr_Occurred()0
)
  Branch (1717:17): [True: 0, False: 32]
  Branch (1717:40): [True: 0, False: 0]
1718
                return -1;
1719
        }
1720
        else {
1721
            Py_INCREF(filename);
1722
            self->filename = filename;
1723
1724
            if (filename2 && 
filename2 != 135
Py_None135
) {
  Branch (1724:17): [True: 135, False: 150k]
  Branch (1724:30): [True: 135, False: 0]
1725
                Py_INCREF(filename2);
1726
                self->filename2 = filename2;
1727
            }
1728
1729
            if (nargs >= 2 && nargs <= 5) {
  Branch (1729:17): [True: 150k, False: 0]
  Branch (1729:31): [True: 150k, False: 0]
1730
                /* filename, filename2, and winerror are removed from the args tuple
1731
                   (for compatibility purposes, see test_exceptions.py) */
1732
                PyObject *subslice = PyTuple_GetSlice(args, 0, 2);
1733
                if (!subslice)
  Branch (1733:21): [True: 0, False: 150k]
1734
                    return -1;
1735
1736
                Py_DECREF(args);  /* replacing args */
1737
                *p_args = args = subslice;
1738
            }
1739
        }
1740
    }
1741
    Py_XINCREF(myerrno);
1742
    self->myerrno = myerrno;
1743
1744
    Py_XINCREF(strerror);
1745
    self->strerror = strerror;
1746
1747
#ifdef MS_WINDOWS
1748
    Py_XINCREF(winerror);
1749
    self->winerror = winerror;
1750
#endif
1751
1752
    /* Steals the reference to args */
1753
    Py_XSETREF(self->args, args);
1754
    *p_args = args = NULL;
1755
1756
    return 0;
1757
}
1758
1759
static PyObject *
1760
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1761
static int
1762
OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds);
1763
1764
static int
1765
oserror_use_init(PyTypeObject *type)
1766
{
1767
    /* When __init__ is defined in an OSError subclass, we want any
1768
       extraneous argument to __new__ to be ignored.  The only reasonable
1769
       solution, given __new__ takes a variable number of arguments,
1770
       is to defer arg parsing and initialization to __init__.
1771
1772
       But when __new__ is overridden as well, it should call our __new__
1773
       with the right arguments.
1774
1775
       (see http://bugs.python.org/issue12555#msg148829 )
1776
    */
1777
    if (type->tp_init != (initproc) OSError_init &&
  Branch (1777:9): [True: 155, False: 537k]
1778
        
type->tp_new == (newfunc) OSError_new155
) {
  Branch (1778:9): [True: 149, False: 6]
1779
        assert((PyObject *) type != PyExc_OSError);
1780
        return 1;
1781
    }
1782
    return 0;
1783
}
1784
1785
static PyObject *
1786
OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1787
{
1788
    PyOSErrorObject *self = NULL;
1789
    PyObject *myerrno = NULL, *strerror = NULL;
1790
    PyObject *filename = NULL, *filename2 = NULL;
1791
#ifdef MS_WINDOWS
1792
    PyObject *winerror = NULL;
1793
#endif
1794
1795
    Py_INCREF(args);
1796
1797
    if (!oserror_use_init(type)) {
  Branch (1797:9): [True: 179k, False: 71]
1798
        if (!_PyArg_NoKeywords(type->tp_name, kwds))
1799
            goto error;
1800
1801
        if (oserror_parse_args(&args, &myerrno, &strerror,
  Branch (1801:13): [True: 0, False: 179k]
1802
                               &filename, &filename2
1803
#ifdef MS_WINDOWS
1804
                               , &winerror
1805
#endif
1806
            ))
1807
            goto error;
1808
1809
        struct _Py_exc_state *state = get_exc_state();
1810
        if (myerrno && PyLong_Check(myerrno) &&
  Branch (1810:13): [True: 177k, False: 2.10k]
1811
            
state->errnomap177k
&&
(PyObject *) type == PyExc_OSError177k
) {
  Branch (1811:13): [True: 177k, False: 0]
  Branch (1811:32): [True: 151k, False: 25.1k]
1812
            PyObject *newtype;
1813
            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
1814
            if (newtype) {
  Branch (1814:17): [True: 140k, False: 11.5k]
1815
                type = _PyType_CAST(newtype);
1816
            }
1817
            else if (PyErr_Occurred())
  Branch (1817:22): [True: 0, False: 11.5k]
1818
                goto error;
1819
        }
1820
    }
1821
1822
    self = (PyOSErrorObject *) type->tp_alloc(type, 0);
1823
    if (!self)
  Branch (1823:9): [True: 0, False: 179k]
1824
        goto error;
1825
1826
    self->dict = NULL;
1827
    self->traceback = self->cause = self->context = NULL;
1828
    self->written = -1;
1829
1830
    if (!oserror_use_init(type)) {
  Branch (1830:9): [True: 179k, False: 71]
1831
        if (oserror_init(self, &args, myerrno, strerror, filename, filename2
  Branch (1831:13): [True: 0, False: 179k]
1832
#ifdef MS_WINDOWS
1833
                         , winerror
1834
#endif
1835
            ))
1836
            goto error;
1837
    }
1838
    else {
1839
        self->args = PyTuple_New(0);
1840
        if (self->args == NULL)
  Branch (1840:13): [True: 0, False: 71]
1841
            goto error;
1842
    }
1843
1844
    Py_XDECREF(args);
1845
    return (PyObject *) self;
1846
1847
error:
1848
    Py_XDECREF(args);
1849
    Py_XDECREF(self);
1850
    return NULL;
1851
}
1852
1853
static int
1854
OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds)
1855
{
1856
    PyObject *myerrno = NULL, *strerror = NULL;
1857
    PyObject *filename = NULL, *filename2 = NULL;
1858
#ifdef MS_WINDOWS
1859
    PyObject *winerror = NULL;
1860
#endif
1861
1862
    if (!oserror_use_init(Py_TYPE(self)))
  Branch (1862:9): [True: 179k, False: 7]
1863
        /* Everything already done in OSError_new */
1864
        return 0;
1865
1866
    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
1867
        return -1;
1868
1869
    Py_INCREF(args);
1870
    if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2
  Branch (1870:9): [True: 0, False: 7]
1871
#ifdef MS_WINDOWS
1872
                           , &winerror
1873
#endif
1874
        ))
1875
        goto error;
1876
1877
    if (oserror_init(self, &args, myerrno, strerror, filename, filename2
  Branch (1877:9): [True: 0, False: 7]
1878
#ifdef MS_WINDOWS
1879
                     , winerror
1880
#endif
1881
        ))
1882
        goto error;
1883
1884
    return 0;
1885
1886
error:
1887
    Py_DECREF(args);
1888
    return -1;
1889
}
1890
1891
static int
1892
OSError_clear(PyOSErrorObject *self)
1893
{
1894
    Py_CLEAR(self->myerrno);
1895
    Py_CLEAR(self->strerror);
1896
    Py_CLEAR(self->filename);
1897
    Py_CLEAR(self->filename2);
1898
#ifdef MS_WINDOWS
1899
    Py_CLEAR(self->winerror);
1900
#endif
1901
    return BaseException_clear((PyBaseExceptionObject *)self);
1902
}
1903
1904
static void
1905
OSError_dealloc(PyOSErrorObject *self)
1906
{
1907
    _PyObject_GC_UNTRACK(self);
1908
    OSError_clear(self);
1909
    Py_TYPE(self)->tp_free((PyObject *)self);
1910
}
1911
1912
static int
1913
OSError_traverse(PyOSErrorObject *self, visitproc visit,
1914
        void *arg)
1915
{
1916
    Py_VISIT(self->myerrno);
1917
    Py_VISIT(self->strerror);
1918
    Py_VISIT(self->filename);
1919
    Py_VISIT(self->filename2);
1920
#ifdef MS_WINDOWS
1921
    Py_VISIT(self->winerror);
1922
#endif
1923
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1924
}
1925
1926
static PyObject *
1927
OSError_str(PyOSErrorObject *self)
1928
{
1929
#define OR_NONE(x) ((x)?(x):
Py_None0
)
1930
#ifdef MS_WINDOWS
1931
    /* If available, winerror has the priority over myerrno */
1932
    if (self->winerror && self->filename) {
1933
        if (self->filename2) {
1934
            return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R",
1935
                                        OR_NONE(self->winerror),
1936
                                        OR_NONE(self->strerror),
1937
                                        self->filename,
1938
                                        self->filename2);
1939
        } else {
1940
            return PyUnicode_FromFormat("[WinError %S] %S: %R",
1941
                                        OR_NONE(self->winerror),
1942
                                        OR_NONE(self->strerror),
1943
                                        self->filename);
1944
        }
1945
    }
1946
    if (self->winerror && self->strerror)
1947
        return PyUnicode_FromFormat("[WinError %S] %S",
1948
                                    self->winerror ? self->winerror: Py_None,
1949
                                    self->strerror ? self->strerror: Py_None);
1950
#endif
1951
    if (self->filename) {
  Branch (1951:9): [True: 114, False: 65]
1952
        if (self->filename2) {
  Branch (1952:13): [True: 4, False: 110]
1953
            return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R",
1954
                                        OR_NONE(self->myerrno),
1955
                                        OR_NONE(self->strerror),
1956
                                        self->filename,
1957
                                        self->filename2);
1958
        } else {
1959
            return PyUnicode_FromFormat("[Errno %S] %S: %R",
1960
                                        OR_NONE(self->myerrno),
1961
                                        OR_NONE(self->strerror),
1962
                                        self->filename);
1963
        }
1964
    }
1965
    if (self->myerrno && 
self->strerror10
)
  Branch (1965:9): [True: 10, False: 55]
  Branch (1965:26): [True: 10, False: 0]
1966
        return PyUnicode_FromFormat("[Errno %S] %S",
1967
                                    self->myerrno, self->strerror);
1968
    return BaseException_str((PyBaseExceptionObject *)self);
1969
}
1970
1971
static PyObject *
1972
OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored))
1973
{
1974
    PyObject *args = self->args;
1975
    PyObject *res = NULL, *tmp;
1976
1977
    /* self->args is only the first two real arguments if there was a
1978
     * file name given to OSError. */
1979
    if (PyTuple_GET_SIZE(args) == 2 && 
self->filename30
) {
  Branch (1979:9): [True: 30, False: 6]
  Branch (1979:40): [True: 24, False: 6]
1980
        Py_ssize_t size = self->filename2 ? 
56
:
318
;
  Branch (1980:27): [True: 6, False: 18]
1981
        args = PyTuple_New(size);
1982
        if (!args)
  Branch (1982:13): [True: 0, False: 24]
1983
            return NULL;
1984
1985
        tmp = PyTuple_GET_ITEM(self->args, 0);
1986
        Py_INCREF(tmp);
1987
        PyTuple_SET_ITEM(args, 0, tmp);
1988
1989
        tmp = PyTuple_GET_ITEM(self->args, 1);
1990
        Py_INCREF(tmp);
1991
        PyTuple_SET_ITEM(args, 1, tmp);
1992
1993
        Py_INCREF(self->filename);
1994
        PyTuple_SET_ITEM(args, 2, self->filename);
1995
1996
        if (self->filename2) {
  Branch (1996:13): [True: 6, False: 18]
1997
            /*
1998
             * This tuple is essentially used as OSError(*args).
1999
             * So, to recreate filename2, we need to pass in
2000
             * winerror as well.
2001
             */
2002
            Py_INCREF(Py_None);
2003
            PyTuple_SET_ITEM(args, 3, Py_None);
2004
2005
            /* filename2 */
2006
            Py_INCREF(self->filename2);
2007
            PyTuple_SET_ITEM(args, 4, self->filename2);
2008
        }
2009
    } else
2010
        Py_INCREF(args);
2011
2012
    if (self->dict)
  Branch (2012:9): [True: 0, False: 36]
2013
        res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
2014
    else
2015
        res = PyTuple_Pack(2, Py_TYPE(self), args);
2016
    Py_DECREF(args);
2017
    return res;
2018
}
2019
2020
static PyObject *
2021
OSError_written_get(PyOSErrorObject *self, void *context)
2022
{
2023
    if (self->written == -1) {
  Branch (2023:9): [True: 7, False: 30]
2024
        PyErr_SetString(PyExc_AttributeError, "characters_written");
2025
        return NULL;
2026
    }
2027
    return PyLong_FromSsize_t(self->written);
2028
}
2029
2030
static int
2031
OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
2032
{
2033
    if (arg == NULL) {
  Branch (2033:9): [True: 7, False: 1]
2034
        if (self->written == -1) {
  Branch (2034:13): [True: 6, False: 1]
2035
            PyErr_SetString(PyExc_AttributeError, "characters_written");
2036
            return -1;
2037
        }
2038
        self->written = -1;
2039
        return 0;
2040
    }
2041
    Py_ssize_t n;
2042
    n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
2043
    if (n == -1 && 
PyErr_Occurred()0
)
  Branch (2043:9): [True: 0, False: 1]
  Branch (2043:20): [True: 0, False: 0]
2044
        return -1;
2045
    self->written = n;
2046
    return 0;
2047
}
2048
2049
static PyMemberDef OSError_members[] = {
2050
    {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
2051
        PyDoc_STR("POSIX exception code")},
2052
    {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
2053
        PyDoc_STR("exception strerror")},
2054
    {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
2055
        PyDoc_STR("exception filename")},
2056
    {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0,
2057
        PyDoc_STR("second exception filename")},
2058
#ifdef MS_WINDOWS
2059
    {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
2060
        PyDoc_STR("Win32 exception code")},
2061
#endif
2062
    {NULL}  /* Sentinel */
2063
};
2064
2065
static PyMethodDef OSError_methods[] = {
2066
    {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
2067
    {NULL}
2068
};
2069
2070
static PyGetSetDef OSError_getset[] = {
2071
    {"characters_written", (getter) OSError_written_get,
2072
                           (setter) OSError_written_set, NULL},
2073
    {NULL}
2074
};
2075
2076
2077
ComplexExtendsException(PyExc_Exception, OSError,
2078
                        OSError, OSError_new,
2079
                        OSError_methods, OSError_members, OSError_getset,
2080
                        OSError_str,
2081
                        "Base class for I/O related errors.");
2082
2083
2084
/*
2085
 *    Various OSError subclasses
2086
 */
2087
MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
2088
                         "I/O operation would block.");
2089
MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
2090
                         "Connection error.");
2091
MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
2092
                         "Child process error.");
2093
MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
2094
                         "Broken pipe.");
2095
MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
2096
                         "Connection aborted.");
2097
MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
2098
                         "Connection refused.");
2099
MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
2100
                         "Connection reset.");
2101
MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
2102
                         "File already exists.");
2103
MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
2104
                         "File not found.");
2105
MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
2106
                         "Operation doesn't work on directories.");
2107
MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
2108
                         "Operation only works on directories.");
2109
MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
2110
                         "Interrupted by signal.");
2111
MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
2112
                         "Not enough permissions.");
2113
MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
2114
                         "Process not found.");
2115
MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
2116
                         "Timeout expired.");
2117
2118
/*
2119
 *    EOFError extends Exception
2120
 */
2121
SimpleExtendsException(PyExc_Exception, EOFError,
2122
                       "Read beyond end of file.");
2123
2124
2125
/*
2126
 *    RuntimeError extends Exception
2127
 */
2128
SimpleExtendsException(PyExc_Exception, RuntimeError,
2129
                       "Unspecified run-time error.");
2130
2131
/*
2132
 *    RecursionError extends RuntimeError
2133
 */
2134
SimpleExtendsException(PyExc_RuntimeError, RecursionError,
2135
                       "Recursion limit exceeded.");
2136
2137
/*
2138
 *    NotImplementedError extends RuntimeError
2139
 */
2140
SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
2141
                       "Method or function hasn't been implemented yet.");
2142
2143
/*
2144
 *    NameError extends Exception
2145
 */
2146
2147
static int
2148
NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds)
2149
{
2150
    static char *kwlist[] = {"name", NULL};
2151
    PyObject *name = NULL;
2152
2153
    if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
  Branch (2153:9): [True: 0, False: 210]
2154
        return -1;
2155
    }
2156
2157
    PyObject *empty_tuple = PyTuple_New(0);
2158
    if (!empty_tuple) {
  Branch (2158:9): [True: 0, False: 210]
2159
        return -1;
2160
    }
2161
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist,
  Branch (2161:9): [True: 0, False: 210]
2162
                                     &name)) {
2163
        Py_DECREF(empty_tuple);
2164
        return -1;
2165
    }
2166
    Py_DECREF(empty_tuple);
2167
2168
    Py_XINCREF(name);
2169
    Py_XSETREF(self->name, name);
2170
2171
    return 0;
2172
}
2173
2174
static int
2175
NameError_clear(PyNameErrorObject *self)
2176
{
2177
    Py_CLEAR(self->name);
2178
    return BaseException_clear((PyBaseExceptionObject *)self);
2179
}
2180
2181
static void
2182
NameError_dealloc(PyNameErrorObject *self)
2183
{
2184
    _PyObject_GC_UNTRACK(self);
2185
    NameError_clear(self);
2186
    Py_TYPE(self)->tp_free((PyObject *)self);
2187
}
2188
2189
static int
2190
NameError_traverse(PyNameErrorObject *self, visitproc visit, void *arg)
2191
{
2192
    Py_VISIT(self->name);
2193
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2194
}
2195
2196
static PyMemberDef NameError_members[] = {
2197
        {"name", T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")},
2198
        {NULL}  /* Sentinel */
2199
};
2200
2201
static PyMethodDef NameError_methods[] = {
2202
        {NULL}  /* Sentinel */
2203
};
2204
2205
ComplexExtendsException(PyExc_Exception, NameError,
2206
                        NameError, 0,
2207
                        NameError_methods, NameError_members,
2208
                        0, BaseException_str, "Name not found globally.");
2209
2210
/*
2211
 *    UnboundLocalError extends NameError
2212
 */
2213
2214
MiddlingExtendsException(PyExc_NameError, UnboundLocalError, NameError,
2215
                       "Local name referenced but not bound to a value.");
2216
2217
/*
2218
 *    AttributeError extends Exception
2219
 */
2220
2221
static int
2222
AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds)
2223
{
2224
    static char *kwlist[] = {"name", "obj", NULL};
2225
    PyObject *name = NULL;
2226
    PyObject *obj = NULL;
2227
2228
    if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) {
  Branch (2228:9): [True: 0, False: 494k]
2229
        return -1;
2230
    }
2231
2232
    PyObject *empty_tuple = PyTuple_New(0);
2233
    if (!empty_tuple) {
  Branch (2233:9): [True: 0, False: 494k]
2234
        return -1;
2235
    }
2236
    if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist,
  Branch (2236:9): [True: 0, False: 494k]
2237
                                     &name, &obj)) {
2238
        Py_DECREF(empty_tuple);
2239
        return -1;
2240
    }
2241
    Py_DECREF(empty_tuple);
2242
2243
    Py_XINCREF(name);
2244
    Py_XSETREF(self->name, name);
2245
2246
    Py_XINCREF(obj);
2247
    Py_XSETREF(self->obj, obj);
2248
2249
    return 0;
2250
}
2251
2252
static int
2253
AttributeError_clear(PyAttributeErrorObject *self)
2254
{
2255
    Py_CLEAR(self->obj);
2256
    Py_CLEAR(self->name);
2257
    return BaseException_clear((PyBaseExceptionObject *)self);
2258
}
2259
2260
static void
2261
AttributeError_dealloc(PyAttributeErrorObject *self)
2262
{
2263
    _PyObject_GC_UNTRACK(self);
2264
    AttributeError_clear(self);
2265
    Py_TYPE(self)->tp_free((PyObject *)self);
2266
}
2267
2268
static int
2269
AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg)
2270
{
2271
    Py_VISIT(self->obj);
2272
    Py_VISIT(self->name);
2273
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2274
}
2275
2276
static PyMemberDef AttributeError_members[] = {
2277
    {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")},
2278
    {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")},
2279
    {NULL}  /* Sentinel */
2280
};
2281
2282
static PyMethodDef AttributeError_methods[] = {
2283
    {NULL}  /* Sentinel */
2284
};
2285
2286
ComplexExtendsException(PyExc_Exception, AttributeError,
2287
                        AttributeError, 0,
2288
                        AttributeError_methods, AttributeError_members,
2289
                        0, BaseException_str, "Attribute not found.");
2290
2291
/*
2292
 *    SyntaxError extends Exception
2293
 */
2294
2295
static int
2296
SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
2297
{
2298
    PyObject *info = NULL;
2299
    Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
2300
2301
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (2301:9): [True: 0, False: 2.48k]
2302
        return -1;
2303
2304
    if (lenargs >= 1) {
  Branch (2304:9): [True: 2.44k, False: 39]
2305
        Py_INCREF(PyTuple_GET_ITEM(args, 0));
2306
        Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
2307
    }
2308
    if (lenargs == 2) {
  Branch (2308:9): [True: 2.14k, False: 339]
2309
        info = PyTuple_GET_ITEM(args, 1);
2310
        info = PySequence_Tuple(info);
2311
        if (!info) {
  Branch (2311:13): [True: 0, False: 2.14k]
2312
            return -1;
2313
        }
2314
2315
        self->end_lineno = NULL;
2316
        self->end_offset = NULL;
2317
        if (!PyArg_ParseTuple(info, "OOOO|OO",
  Branch (2317:13): [True: 2, False: 2.14k]
2318
                              &self->filename, &self->lineno,
2319
                              &self->offset, &self->text,
2320
                              &self->end_lineno, &self->end_offset)) {
2321
            Py_DECREF(info);
2322
            return -1;
2323
        }
2324
2325
        Py_INCREF(self->filename);
2326
        Py_INCREF(self->lineno);
2327
        Py_INCREF(self->offset);
2328
        Py_INCREF(self->text);
2329
        Py_XINCREF(self->end_lineno);
2330
        Py_XINCREF(self->end_offset);
2331
        Py_DECREF(info);
2332
2333
        if (self->end_lineno != NULL && 
self->end_offset == NULL2.04k
) {
  Branch (2333:13): [True: 2.04k, False: 105]
  Branch (2333:41): [True: 1, False: 2.03k]
2334
            PyErr_SetString(PyExc_TypeError, "end_offset must be provided when end_lineno is provided");
2335
            return -1;
2336
        }
2337
    }
2338
    return 0;
2339
}
2340
2341
static int
2342
SyntaxError_clear(PySyntaxErrorObject *self)
2343
{
2344
    Py_CLEAR(self->msg);
2345
    Py_CLEAR(self->filename);
2346
    Py_CLEAR(self->lineno);
2347
    Py_CLEAR(self->offset);
2348
    Py_CLEAR(self->end_lineno);
2349
    Py_CLEAR(self->end_offset);
2350
    Py_CLEAR(self->text);
2351
    Py_CLEAR(self->print_file_and_line);
2352
    return BaseException_clear((PyBaseExceptionObject *)self);
2353
}
2354
2355
static void
2356
SyntaxError_dealloc(PySyntaxErrorObject *self)
2357
{
2358
    _PyObject_GC_UNTRACK(self);
2359
    SyntaxError_clear(self);
2360
    Py_TYPE(self)->tp_free((PyObject *)self);
2361
}
2362
2363
static int
2364
SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
2365
{
2366
    Py_VISIT(self->msg);
2367
    Py_VISIT(self->filename);
2368
    Py_VISIT(self->lineno);
2369
    Py_VISIT(self->offset);
2370
    Py_VISIT(self->end_lineno);
2371
    Py_VISIT(self->end_offset);
2372
    Py_VISIT(self->text);
2373
    Py_VISIT(self->print_file_and_line);
2374
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2375
}
2376
2377
/* This is called "my_basename" instead of just "basename" to avoid name
2378
   conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
2379
   defined, and Python does define that. */
2380
static PyObject*
2381
my_basename(PyObject *name)
2382
{
2383
    Py_ssize_t i, size, offset;
2384
    int kind;
2385
    const void *data;
2386
2387
    if (PyUnicode_READY(name))
2388
        return NULL;
2389
    kind = PyUnicode_KIND(name);
2390
    data = PyUnicode_DATA(name);
2391
    size = PyUnicode_GET_LENGTH(name);
2392
    offset = 0;
2393
    for(i=0; i < size; 
i++33.3k
) {
  Branch (2393:14): [True: 33.3k, False: 1.72k]
2394
        if (PyUnicode_READ(kind, data, i) == SEP) {
  Branch (2394:13): [True: 272, False: 33.0k]
2395
            offset = i + 1;
2396
        }
2397
    }
2398
    if (offset != 0) {
  Branch (2398:9): [True: 41, False: 1.67k]
2399
        return PyUnicode_Substring(name, offset, size);
2400
    }
2401
    else {
2402
        Py_INCREF(name);
2403
        return name;
2404
    }
2405
}
2406
2407
2408
static PyObject *
2409
SyntaxError_str(PySyntaxErrorObject *self)
2410
{
2411
    int have_lineno = 0;
2412
    PyObject *filename;
2413
    PyObject *result;
2414
    /* Below, we always ignore overflow errors, just printing -1.
2415
       Still, we cannot allow an OverflowError to be raised, so
2416
       we need to call PyLong_AsLongAndOverflow. */
2417
    int overflow;
2418
2419
    /* XXX -- do all the additional formatting with filename and
2420
       lineno here */
2421
2422
    if (self->filename && 
PyUnicode_Check1.72k
(self->filename)) {
  Branch (2422:9): [True: 1.72k, False: 57]
2423
        filename = my_basename(self->filename);
2424
        if (filename == NULL)
  Branch (2424:13): [True: 0, False: 1.72k]
2425
            return NULL;
2426
    } else {
2427
        filename = NULL;
2428
    }
2429
    have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
  Branch (2429:19): [True: 1.71k, False: 58]
2430
2431
    if (!filename && 
!have_lineno57
)
  Branch (2431:9): [True: 57, False: 1.72k]
  Branch (2431:22): [True: 55, False: 2]
2432
        return PyObject_Str(self->msg ? 
self->msg54
:
Py_None1
);
  Branch (2432:29): [True: 54, False: 1]
2433
2434
    if (filename && 
have_lineno1.72k
)
  Branch (2434:9): [True: 1.72k, False: 2]
  Branch (2434:21): [True: 1.71k, False: 4]
2435
        result = PyUnicode_FromFormat("%S (%U, line %ld)",
2436
                   self->msg ? self->msg : 
Py_None0
,
  Branch (2436:20): [True: 1.71k, False: 0]
2437
                   filename,
2438
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2439
    else if (filename)
  Branch (2439:14): [True: 4, False: 2]
2440
        result = PyUnicode_FromFormat("%S (%U)",
2441
                   self->msg ? self->msg : 
Py_None0
,
  Branch (2441:20): [True: 4, False: 0]
2442
                   filename);
2443
    else /* only have_lineno */
2444
        result = PyUnicode_FromFormat("%S (line %ld)",
2445
                   self->msg ? self->msg : 
Py_None0
,
  Branch (2445:20): [True: 2, False: 0]
2446
                   PyLong_AsLongAndOverflow(self->lineno, &overflow));
2447
    Py_XDECREF(filename);
2448
    return result;
2449
}
2450
2451
static PyMemberDef SyntaxError_members[] = {
2452
    {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
2453
        PyDoc_STR("exception msg")},
2454
    {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
2455
        PyDoc_STR("exception filename")},
2456
    {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
2457
        PyDoc_STR("exception lineno")},
2458
    {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
2459
        PyDoc_STR("exception offset")},
2460
    {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
2461
        PyDoc_STR("exception text")},
2462
    {"end_lineno", T_OBJECT, offsetof(PySyntaxErrorObject, end_lineno), 0,
2463
                   PyDoc_STR("exception end lineno")},
2464
    {"end_offset", T_OBJECT, offsetof(PySyntaxErrorObject, end_offset), 0,
2465
                   PyDoc_STR("exception end offset")},
2466
    {"print_file_and_line", T_OBJECT,
2467
        offsetof(PySyntaxErrorObject, print_file_and_line), 0,
2468
        PyDoc_STR("exception print_file_and_line")},
2469
    {NULL}  /* Sentinel */
2470
};
2471
2472
ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
2473
                        0, 0, SyntaxError_members, 0,
2474
                        SyntaxError_str, "Invalid syntax.");
2475
2476
2477
/*
2478
 *    IndentationError extends SyntaxError
2479
 */
2480
MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
2481
                         "Improper indentation.");
2482
2483
2484
/*
2485
 *    TabError extends IndentationError
2486
 */
2487
MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
2488
                         "Improper mixture of spaces and tabs.");
2489
2490
2491
/*
2492
 *    LookupError extends Exception
2493
 */
2494
SimpleExtendsException(PyExc_Exception, LookupError,
2495
                       "Base class for lookup errors.");
2496
2497
2498
/*
2499
 *    IndexError extends LookupError
2500
 */
2501
SimpleExtendsException(PyExc_LookupError, IndexError,
2502
                       "Sequence index out of range.");
2503
2504
2505
/*
2506
 *    KeyError extends LookupError
2507
 */
2508
static PyObject *
2509
KeyError_str(PyBaseExceptionObject *self)
2510
{
2511
    /* If args is a tuple of exactly one item, apply repr to args[0].
2512
       This is done so that e.g. the exception raised by {}[''] prints
2513
         KeyError: ''
2514
       rather than the confusing
2515
         KeyError
2516
       alone.  The downside is that if KeyError is raised with an explanatory
2517
       string, that string will be displayed in quotes.  Too bad.
2518
       If args is anything else, use the default BaseException__str__().
2519
    */
2520
    if (PyTuple_GET_SIZE(self->args) == 1) {
  Branch (2520:9): [True: 19, False: 22]
2521
        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
2522
    }
2523
    return BaseException_str(self);
2524
}
2525
2526
ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
2527
                        0, 0, 0, 0, KeyError_str, "Mapping key not found.");
2528
2529
2530
/*
2531
 *    ValueError extends Exception
2532
 */
2533
SimpleExtendsException(PyExc_Exception, ValueError,
2534
                       "Inappropriate argument value (of correct type).");
2535
2536
/*
2537
 *    UnicodeError extends ValueError
2538
 */
2539
2540
SimpleExtendsException(PyExc_ValueError, UnicodeError,
2541
                       "Unicode related error.");
2542
2543
static PyObject *
2544
get_string(PyObject *attr, const char *name)
2545
{
2546
    if (!attr) {
  Branch (2546:9): [True: 0, False: 5.98k]
2547
        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
2548
        return NULL;
2549
    }
2550
2551
    if (!PyBytes_Check(attr)) {
  Branch (2551:9): [True: 8, False: 5.97k]
2552
        PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
2553
        return NULL;
2554
    }
2555
    Py_INCREF(attr);
2556
    return attr;
2557
}
2558
2559
static PyObject *
2560
get_unicode(PyObject *attr, const char *name)
2561
{
2562
    if (!attr) {
  Branch (2562:9): [True: 0, False: 18.9k]
2563
        PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
2564
        return NULL;
2565
    }
2566
2567
    if (!PyUnicode_Check(attr)) {
  Branch (2567:9): [True: 1, False: 18.9k]
2568
        PyErr_Format(PyExc_TypeError,
2569
                     "%.200s attribute must be unicode", name);
2570
        return NULL;
2571
    }
2572
    Py_INCREF(attr);
2573
    return attr;
2574
}
2575
2576
static int
2577
set_unicodefromstring(PyObject **attr, const char *value)
2578
{
2579
    PyObject *obj = PyUnicode_FromString(value);
2580
    if (!obj)
  Branch (2580:9): [True: 0, False: 10.7k]
2581
        return -1;
2582
    Py_XSETREF(*attr, obj);
2583
    return 0;
2584
}
2585
2586
PyObject *
2587
PyUnicodeEncodeError_GetEncoding(PyObject *exc)
2588
{
2589
    return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
2590
}
2591
2592
PyObject *
2593
PyUnicodeDecodeError_GetEncoding(PyObject *exc)
2594
{
2595
    return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
2596
}
2597
2598
PyObject *
2599
PyUnicodeEncodeError_GetObject(PyObject *exc)
2600
{
2601
    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
2602
}
2603
2604
PyObject *
2605
PyUnicodeDecodeError_GetObject(PyObject *exc)
2606
{
2607
    return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2608
}
2609
2610
PyObject *
2611
PyUnicodeTranslateError_GetObject(PyObject *exc)
2612
{
2613
    return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
2614
}
2615
2616
int
2617
PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
2618
{
2619
    Py_ssize_t size;
2620
    PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
2621
                                "object");
2622
    if (!obj)
  Branch (2622:9): [True: 1, False: 5.29k]
2623
        return -1;
2624
    *start = ((PyUnicodeErrorObject *)exc)->start;
2625
    size = PyUnicode_GET_LENGTH(obj);
2626
    if (*start<0)
  Branch (2626:9): [True: 0, False: 5.29k]
2627
        *start = 0; /*XXX check for values <0*/
2628
    if (*start>=size)
  Branch (2628:9): [True: 0, False: 5.29k]
2629
        *start = size-1;
2630
    Py_DECREF(obj);
2631
    return 0;
2632
}
2633
2634
2635
int
2636
PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
2637
{
2638
    Py_ssize_t size;
2639
    PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2640
    if (!obj)
  Branch (2640:9): [True: 0, False: 671]
2641
        return -1;
2642
    size = PyBytes_GET_SIZE(obj);
2643
    *start = ((PyUnicodeErrorObject *)exc)->start;
2644
    if (*start<0)
  Branch (2644:9): [True: 0, False: 671]
2645
        *start = 0;
2646
    if (*start>=size)
  Branch (2646:9): [True: 0, False: 671]
2647
        *start = size-1;
2648
    Py_DECREF(obj);
2649
    return 0;
2650
}
2651
2652
2653
int
2654
PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
2655
{
2656
    return PyUnicodeEncodeError_GetStart(exc, start);
2657
}
2658
2659
2660
int
2661
PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
2662
{
2663
    ((PyUnicodeErrorObject *)exc)->start = start;
2664
    return 0;
2665
}
2666
2667
2668
int
2669
PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
2670
{
2671
    ((PyUnicodeErrorObject *)exc)->start = start;
2672
    return 0;
2673
}
2674
2675
2676
int
2677
PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
2678
{
2679
    ((PyUnicodeErrorObject *)exc)->start = start;
2680
    return 0;
2681
}
2682
2683
2684
int
2685
PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
2686
{
2687
    Py_ssize_t size;
2688
    PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
2689
                                "object");
2690
    if (!obj)
  Branch (2690:9): [True: 0, False: 8.71k]
2691
        return -1;
2692
    *end = ((PyUnicodeErrorObject *)exc)->end;
2693
    size = PyUnicode_GET_LENGTH(obj);
2694
    if (*end<1)
  Branch (2694:9): [True: 0, False: 8.71k]
2695
        *end = 1;
2696
    if (*end>size)
  Branch (2696:9): [True: 0, False: 8.71k]
2697
        *end = size;
2698
    Py_DECREF(obj);
2699
    return 0;
2700
}
2701
2702
2703
int
2704
PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
2705
{
2706
    Py_ssize_t size;
2707
    PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
2708
    if (!obj)
  Branch (2708:9): [True: 1, False: 2.18k]
2709
        return -1;
2710
    size = PyBytes_GET_SIZE(obj);
2711
    *end = ((PyUnicodeErrorObject *)exc)->end;
2712
    if (*end<1)
  Branch (2712:9): [True: 0, False: 2.18k]
2713
        *end = 1;
2714
    if (*end>size)
  Branch (2714:9): [True: 0, False: 2.18k]
2715
        *end = size;
2716
    Py_DECREF(obj);
2717
    return 0;
2718
}
2719
2720
2721
int
2722
PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)
2723
{
2724
    return PyUnicodeEncodeError_GetEnd(exc, end);
2725
}
2726
2727
2728
int
2729
PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
2730
{
2731
    ((PyUnicodeErrorObject *)exc)->end = end;
2732
    return 0;
2733
}
2734
2735
2736
int
2737
PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
2738
{
2739
    ((PyUnicodeErrorObject *)exc)->end = end;
2740
    return 0;
2741
}
2742
2743
2744
int
2745
PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
2746
{
2747
    ((PyUnicodeErrorObject *)exc)->end = end;
2748
    return 0;
2749
}
2750
2751
PyObject *
2752
PyUnicodeEncodeError_GetReason(PyObject *exc)
2753
{
2754
    return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2755
}
2756
2757
2758
PyObject *
2759
PyUnicodeDecodeError_GetReason(PyObject *exc)
2760
{
2761
    return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2762
}
2763
2764
2765
PyObject *
2766
PyUnicodeTranslateError_GetReason(PyObject *exc)
2767
{
2768
    return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
2769
}
2770
2771
2772
int
2773
PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
2774
{
2775
    return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2776
                                 reason);
2777
}
2778
2779
2780
int
2781
PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
2782
{
2783
    return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2784
                                 reason);
2785
}
2786
2787
2788
int
2789
PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
2790
{
2791
    return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
2792
                                 reason);
2793
}
2794
2795
2796
static int
2797
UnicodeError_clear(PyUnicodeErrorObject *self)
2798
{
2799
    Py_CLEAR(self->encoding);
2800
    Py_CLEAR(self->object);
2801
    Py_CLEAR(self->reason);
2802
    return BaseException_clear((PyBaseExceptionObject *)self);
2803
}
2804
2805
static void
2806
UnicodeError_dealloc(PyUnicodeErrorObject *self)
2807
{
2808
    _PyObject_GC_UNTRACK(self);
2809
    UnicodeError_clear(self);
2810
    Py_TYPE(self)->tp_free((PyObject *)self);
2811
}
2812
2813
static int
2814
UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
2815
{
2816
    Py_VISIT(self->encoding);
2817
    Py_VISIT(self->object);
2818
    Py_VISIT(self->reason);
2819
    return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
2820
}
2821
2822
static PyMemberDef UnicodeError_members[] = {
2823
    {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
2824
        PyDoc_STR("exception encoding")},
2825
    {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
2826
        PyDoc_STR("exception object")},
2827
    {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
2828
        PyDoc_STR("exception start")},
2829
    {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
2830
        PyDoc_STR("exception end")},
2831
    {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
2832
        PyDoc_STR("exception reason")},
2833
    {NULL}  /* Sentinel */
2834
};
2835
2836
2837
/*
2838
 *    UnicodeEncodeError extends UnicodeError
2839
 */
2840
2841
static int
2842
UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2843
{
2844
    PyUnicodeErrorObject *err;
2845
2846
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (2846:9): [True: 0, False: 2.30k]
2847
        return -1;
2848
2849
    err = (PyUnicodeErrorObject *)self;
2850
2851
    Py_CLEAR(err->encoding);
2852
    Py_CLEAR(err->object);
2853
    Py_CLEAR(err->reason);
2854
2855
    if (!PyArg_ParseTuple(args, "UUnnU",
  Branch (2855:9): [True: 163, False: 2.14k]
2856
                          &err->encoding, &err->object,
2857
                          &err->start, &err->end, &err->reason)) {
2858
        err->encoding = err->object = err->reason = NULL;
2859
        return -1;
2860
    }
2861
2862
    Py_INCREF(err->encoding);
2863
    Py_INCREF(err->object);
2864
    Py_INCREF(err->reason);
2865
2866
    return 0;
2867
}
2868
2869
static PyObject *
2870
UnicodeEncodeError_str(PyObject *self)
2871
{
2872
    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2873
    PyObject *result = NULL;
2874
    PyObject *reason_str = NULL;
2875
    PyObject *encoding_str = NULL;
2876
2877
    if (!uself->object)
  Branch (2877:9): [True: 1, False: 17]
2878
        /* Not properly initialized. */
2879
        return PyUnicode_FromString("");
2880
2881
    /* Get reason and encoding as strings, which they might not be if
2882
       they've been modified after we were constructed. */
2883
    reason_str = PyObject_Str(uself->reason);
2884
    if (reason_str == NULL)
  Branch (2884:9): [True: 0, False: 17]
2885
        goto done;
2886
    encoding_str = PyObject_Str(uself->encoding);
2887
    if (encoding_str == NULL)
  Branch (2887:9): [True: 0, False: 17]
2888
        goto done;
2889
2890
    if (uself->start < PyUnicode_GET_LENGTH(uself->object) && 
uself->end == uself->start+116
) {
  Branch (2890:9): [True: 16, False: 1]
  Branch (2890:63): [True: 11, False: 5]
2891
        Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
2892
        const char *fmt;
2893
        if (badchar <= 0xff)
  Branch (2893:13): [True: 5, False: 6]
2894
            fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
2895
        else if (badchar <= 0xffff)
  Branch (2895:18): [True: 5, False: 1]
2896
            fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
2897
        else
2898
            fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
2899
        result = PyUnicode_FromFormat(
2900
            fmt,
2901
            encoding_str,
2902
            (int)badchar,
2903
            uself->start,
2904
            reason_str);
2905
    }
2906
    else {
2907
        result = PyUnicode_FromFormat(
2908
            "'%U' codec can't encode characters in position %zd-%zd: %U",
2909
            encoding_str,
2910
            uself->start,
2911
            uself->end-1,
2912
            reason_str);
2913
    }
2914
done:
2915
    Py_XDECREF(reason_str);
2916
    Py_XDECREF(encoding_str);
2917
    return result;
2918
}
2919
2920
static PyTypeObject _PyExc_UnicodeEncodeError = {
2921
    PyVarObject_HEAD_INIT(NULL, 0)
2922
    "UnicodeEncodeError",
2923
    sizeof(PyUnicodeErrorObject), 0,
2924
    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2925
    (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
2926
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2927
    PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
2928
    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
2929
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
2930
    (initproc)UnicodeEncodeError_init, 0, BaseException_new,
2931
};
2932
PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
2933
2934
2935
/*
2936
 *    UnicodeDecodeError extends UnicodeError
2937
 */
2938
2939
static int
2940
UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
2941
{
2942
    PyUnicodeErrorObject *ude;
2943
2944
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (2944:9): [True: 0, False: 2.28k]
2945
        return -1;
2946
2947
    ude = (PyUnicodeErrorObject *)self;
2948
2949
    Py_CLEAR(ude->encoding);
2950
    Py_CLEAR(ude->object);
2951
    Py_CLEAR(ude->reason);
2952
2953
    if (!PyArg_ParseTuple(args, "UOnnU",
  Branch (2953:9): [True: 57, False: 2.22k]
2954
                          &ude->encoding, &ude->object,
2955
                          &ude->start, &ude->end, &ude->reason)) {
2956
             ude->encoding = ude->object = ude->reason = NULL;
2957
             return -1;
2958
    }
2959
2960
    Py_INCREF(ude->encoding);
2961
    Py_INCREF(ude->object);
2962
    Py_INCREF(ude->reason);
2963
2964
    if (!PyBytes_Check(ude->object)) {
  Branch (2964:9): [True: 36, False: 2.19k]
2965
        Py_buffer view;
2966
        if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0)
  Branch (2966:13): [True: 0, False: 36]
2967
            goto error;
2968
        Py_XSETREF(ude->object, PyBytes_FromStringAndSize(view.buf, view.len));
2969
        PyBuffer_Release(&view);
2970
        if (!ude->object)
  Branch (2970:13): [True: 0, False: 36]
2971
            goto error;
2972
    }
2973
    return 0;
2974
2975
error:
2976
    Py_CLEAR(ude->encoding);
2977
    Py_CLEAR(ude->object);
2978
    Py_CLEAR(ude->reason);
2979
    return -1;
2980
}
2981
2982
static PyObject *
2983
UnicodeDecodeError_str(PyObject *self)
2984
{
2985
    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
2986
    PyObject *result = NULL;
2987
    PyObject *reason_str = NULL;
2988
    PyObject *encoding_str = NULL;
2989
2990
    if (!uself->object)
  Branch (2990:9): [True: 1, False: 297]
2991
        /* Not properly initialized. */
2992
        return PyUnicode_FromString("");
2993
2994
    /* Get reason and encoding as strings, which they might not be if
2995
       they've been modified after we were constructed. */
2996
    reason_str = PyObject_Str(uself->reason);
2997
    if (reason_str == NULL)
  Branch (2997:9): [True: 0, False: 297]
2998
        goto done;
2999
    encoding_str = PyObject_Str(uself->encoding);
3000
    if (encoding_str == NULL)
  Branch (3000:9): [True: 0, False: 297]
3001
        goto done;
3002
3003
    if (uself->start < PyBytes_GET_SIZE(uself->object) && 
uself->end == uself->start+1296
) {
  Branch (3003:9): [True: 296, False: 1]
  Branch (3003:59): [True: 76, False: 220]
3004
        int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
3005
        result = PyUnicode_FromFormat(
3006
            "'%U' codec can't decode byte 0x%02x in position %zd: %U",
3007
            encoding_str,
3008
            byte,
3009
            uself->start,
3010
            reason_str);
3011
    }
3012
    else {
3013
        result = PyUnicode_FromFormat(
3014
            "'%U' codec can't decode bytes in position %zd-%zd: %U",
3015
            encoding_str,
3016
            uself->start,
3017
            uself->end-1,
3018
            reason_str
3019
            );
3020
    }
3021
done:
3022
    Py_XDECREF(reason_str);
3023
    Py_XDECREF(encoding_str);
3024
    return result;
3025
}
3026
3027
static PyTypeObject _PyExc_UnicodeDecodeError = {
3028
    PyVarObject_HEAD_INIT(NULL, 0)
3029
    "UnicodeDecodeError",
3030
    sizeof(PyUnicodeErrorObject), 0,
3031
    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3032
    (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
3033
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3034
    PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
3035
    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3036
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3037
    (initproc)UnicodeDecodeError_init, 0, BaseException_new,
3038
};
3039
PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
3040
3041
PyObject *
3042
PyUnicodeDecodeError_Create(
3043
    const char *encoding, const char *object, Py_ssize_t length,
3044
    Py_ssize_t start, Py_ssize_t end, const char *reason)
3045
{
3046
    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
3047
                                 encoding, object, length, start, end, reason);
3048
}
3049
3050
3051
/*
3052
 *    UnicodeTranslateError extends UnicodeError
3053
 */
3054
3055
static int
3056
UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
3057
                           PyObject *kwds)
3058
{
3059
    if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
  Branch (3059:9): [True: 0, False: 144]
3060
        return -1;
3061
3062
    Py_CLEAR(self->object);
3063
    Py_CLEAR(self->reason);
3064
3065
    if (!PyArg_ParseTuple(args, "UnnU",
  Branch (3065:9): [True: 111, False: 33]
3066
                          &self->object,
3067
                          &self->start, &self->end, &self->reason)) {
3068
        self->object = self->reason = NULL;
3069
        return -1;
3070
    }
3071
3072
    Py_INCREF(self->object);
3073
    Py_INCREF(self->reason);
3074
3075
    return 0;
3076
}
3077
3078
3079
static PyObject *
3080
UnicodeTranslateError_str(PyObject *self)
3081
{
3082
    PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
3083
    PyObject *result = NULL;
3084
    PyObject *reason_str = NULL;
3085
3086
    if (!uself->object)
  Branch (3086:9): [True: 1, False: 10]
3087
        /* Not properly initialized. */
3088
        return PyUnicode_FromString("");
3089
3090
    /* Get reason as a string, which it might not be if it's been
3091
       modified after we were constructed. */
3092
    reason_str = PyObject_Str(uself->reason);
3093
    if (reason_str == NULL)
  Branch (3093:9): [True: 0, False: 10]
3094
        goto done;
3095
3096
    if (uself->start < PyUnicode_GET_LENGTH(uself->object) && 
uself->end == uself->start+19
) {
  Branch (3096:9): [True: 9, False: 1]
  Branch (3096:63): [True: 6, False: 3]
3097
        Py_UCS4 badchar = PyUnicode_ReadChar(uself->object, uself->start);
3098
        const char *fmt;
3099
        if (badchar <= 0xff)
  Branch (3099:13): [True: 2, False: 4]
3100
            fmt = "can't translate character '\\x%02x' in position %zd: %U";
3101
        else if (badchar <= 0xffff)
  Branch (3101:18): [True: 3, False: 1]
3102
            fmt = "can't translate character '\\u%04x' in position %zd: %U";
3103
        else
3104
            fmt = "can't translate character '\\U%08x' in position %zd: %U";
3105
        result = PyUnicode_FromFormat(
3106
            fmt,
3107
            (int)badchar,
3108
            uself->start,
3109
            reason_str
3110
        );
3111
    } else {
3112
        result = PyUnicode_FromFormat(
3113
            "can't translate characters in position %zd-%zd: %U",
3114
            uself->start,
3115
            uself->end-1,
3116
            reason_str
3117
            );
3118
    }
3119
done:
3120
    Py_XDECREF(reason_str);
3121
    return result;
3122
}
3123
3124
static PyTypeObject _PyExc_UnicodeTranslateError = {
3125
    PyVarObject_HEAD_INIT(NULL, 0)
3126
    "UnicodeTranslateError",
3127
    sizeof(PyUnicodeErrorObject), 0,
3128
    (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3129
    (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
3130
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3131
    PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
3132
    (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
3133
    0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
3134
    (initproc)UnicodeTranslateError_init, 0, BaseException_new,
3135
};
3136
PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
3137
3138
PyObject *
3139
_PyUnicodeTranslateError_Create(
3140
    PyObject *object,
3141
    Py_ssize_t start, Py_ssize_t end, const char *reason)
3142
{
3143
    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns",
3144
                                 object, start, end, reason);
3145
}
3146
3147
/*
3148
 *    AssertionError extends Exception
3149
 */
3150
SimpleExtendsException(PyExc_Exception, AssertionError,
3151
                       "Assertion failed.");
3152
3153
3154
/*
3155
 *    ArithmeticError extends Exception
3156
 */
3157
SimpleExtendsException(PyExc_Exception, ArithmeticError,
3158
                       "Base class for arithmetic errors.");
3159
3160
3161
/*
3162
 *    FloatingPointError extends ArithmeticError
3163
 */
3164
SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
3165
                       "Floating point operation failed.");
3166
3167
3168
/*
3169
 *    OverflowError extends ArithmeticError
3170
 */
3171
SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
3172
                       "Result too large to be represented.");
3173
3174
3175
/*
3176
 *    ZeroDivisionError extends ArithmeticError
3177
 */
3178
SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
3179
          "Second argument to a division or modulo operation was zero.");
3180
3181
3182
/*
3183
 *    SystemError extends Exception
3184
 */
3185
SimpleExtendsException(PyExc_Exception, SystemError,
3186
    "Internal error in the Python interpreter.\n"
3187
    "\n"
3188
    "Please report this to the Python maintainer, along with the traceback,\n"
3189
    "the Python version, and the hardware/OS platform and version.");
3190
3191
3192
/*
3193
 *    ReferenceError extends Exception
3194
 */
3195
SimpleExtendsException(PyExc_Exception, ReferenceError,
3196
                       "Weak ref proxy used after referent went away.");
3197
3198
3199
/*
3200
 *    MemoryError extends Exception
3201
 */
3202
3203
#define MEMERRORS_SAVE 16
3204
3205
static PyObject *
3206
MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3207
{
3208
    PyBaseExceptionObject *self;
3209
3210
    /* If this is a subclass of MemoryError, don't use the freelist
3211
     * and just return a fresh object */
3212
    if (type != (PyTypeObject *) PyExc_MemoryError) {
  Branch (3212:9): [True: 1, False: 1.78k]
3213
        return BaseException_new(type, args, kwds);
3214
    }
3215
3216
    struct _Py_exc_state *state = get_exc_state();
3217
    if (state->memerrors_freelist == NULL) {
  Branch (3217:9): [True: 1.71k, False: 69]
3218
        return BaseException_new(type, args, kwds);
3219
    }
3220
3221
    /* Fetch object from freelist and revive it */
3222
    self = state->memerrors_freelist;
3223
    self->args = PyTuple_New(0);
3224
    /* This shouldn't happen since the empty tuple is persistent */
3225
    if (self->args == NULL) {
  Branch (3225:9): [True: 0, False: 69]
3226
        return NULL;
3227
    }
3228
3229
    state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
3230
    state->memerrors_numfree--;
3231
    self->dict = NULL;
3232
    _Py_NewReference((PyObject *)self);
3233
    _PyObject_GC_TRACK(self);
3234
    return (PyObject *)self;
3235
}
3236
3237
static void
3238
MemoryError_dealloc(PyBaseExceptionObject *self)
3239
{
3240
    BaseException_clear(self);
3241
3242
    /* If this is a subclass of MemoryError, we don't need to
3243
     * do anything in the free-list*/
3244
    if (!Py_IS_TYPE(self, (PyTypeObject *) PyExc_MemoryError)) {
  Branch (3244:9): [True: 1, False: 1.78k]
3245
        Py_TYPE(self)->tp_free((PyObject *)self);
3246
        return;
3247
    }
3248
3249
    _PyObject_GC_UNTRACK(self);
3250
3251
    struct _Py_exc_state *state = get_exc_state();
3252
    if (state->memerrors_numfree >= MEMERRORS_SAVE) {
  Branch (3252:9): [True: 3, False: 1.78k]
3253
        Py_TYPE(self)->tp_free((PyObject *)self);
3254
    }
3255
    else {
3256
        self->dict = (PyObject *) state->memerrors_freelist;
3257
        state->memerrors_freelist = self;
3258
        state->memerrors_numfree++;
3259
    }
3260
}
3261
3262
static int
3263
preallocate_memerrors(void)
3264
{
3265
    /* We create enough MemoryErrors and then decref them, which will fill
3266
       up the freelist. */
3267
    int i;
3268
    PyObject *errors[MEMERRORS_SAVE];
3269
    for (i = 0; i < MEMERRORS_SAVE; 
i++1.71k
) {
  Branch (3269:17): [True: 1.71k, False: 107]
3270
        errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
3271
                                    NULL, NULL);
3272
        if (!errors[i]) {
  Branch (3272:13): [True: 0, False: 1.71k]
3273
            return -1;
3274
        }
3275
    }
3276
    
for (i = 0; 107
i < MEMERRORS_SAVE;
i++1.71k
) {
  Branch (3276:17): [True: 1.71k, False: 107]
3277
        Py_DECREF(errors[i]);
3278
    }
3279
    return 0;
3280
}
3281
3282
static void
3283
free_preallocated_memerrors(struct _Py_exc_state *state)
3284
{
3285
    while (state->memerrors_freelist != NULL) {
  Branch (3285:12): [True: 1.64k, False: 272]
3286
        PyObject *self = (PyObject *) state->memerrors_freelist;
3287
        state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
3288
        Py_TYPE(self)->tp_free((PyObject *)self);
3289
    }
3290
}
3291
3292
3293
static PyTypeObject _PyExc_MemoryError = {
3294
    PyVarObject_HEAD_INIT(NULL, 0)
3295
    "MemoryError",
3296
    sizeof(PyBaseExceptionObject),
3297
    0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
3298
    0, 0, 0, 0, 0, 0, 0,
3299
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
3300
    PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
3301
    (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
3302
    0, 0, 0, offsetof(PyBaseExceptionObject, dict),
3303
    (initproc)BaseException_init, 0, MemoryError_new
3304
};
3305
PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
3306
3307
3308
/*
3309
 *    BufferError extends Exception
3310
 */
3311
SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
3312
3313
3314
/* Warning category docstrings */
3315
3316
/*
3317
 *    Warning extends Exception
3318
 */
3319
SimpleExtendsException(PyExc_Exception, Warning,
3320
                       "Base class for warning categories.");
3321
3322
3323
/*
3324
 *    UserWarning extends Warning
3325
 */
3326
SimpleExtendsException(PyExc_Warning, UserWarning,
3327
                       "Base class for warnings generated by user code.");
3328
3329
3330
/*
3331
 *    DeprecationWarning extends Warning
3332
 */
3333
SimpleExtendsException(PyExc_Warning, DeprecationWarning,
3334
                       "Base class for warnings about deprecated features.");
3335
3336
3337
/*
3338
 *    PendingDeprecationWarning extends Warning
3339
 */
3340
SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
3341
    "Base class for warnings about features which will be deprecated\n"
3342
    "in the future.");
3343
3344
3345
/*
3346
 *    SyntaxWarning extends Warning
3347
 */
3348
SimpleExtendsException(PyExc_Warning, SyntaxWarning,
3349
                       "Base class for warnings about dubious syntax.");
3350
3351
3352
/*
3353
 *    RuntimeWarning extends Warning
3354
 */
3355
SimpleExtendsException(PyExc_Warning, RuntimeWarning,
3356
                 "Base class for warnings about dubious runtime behavior.");
3357
3358
3359
/*
3360
 *    FutureWarning extends Warning
3361
 */
3362
SimpleExtendsException(PyExc_Warning, FutureWarning,
3363
    "Base class for warnings about constructs that will change semantically\n"
3364
    "in the future.");
3365
3366
3367
/*
3368
 *    ImportWarning extends Warning
3369
 */
3370
SimpleExtendsException(PyExc_Warning, ImportWarning,
3371
          "Base class for warnings about probable mistakes in module imports");
3372
3373
3374
/*
3375
 *    UnicodeWarning extends Warning
3376
 */
3377
SimpleExtendsException(PyExc_Warning, UnicodeWarning,
3378
    "Base class for warnings about Unicode related problems, mostly\n"
3379
    "related to conversion problems.");
3380
3381
3382
/*
3383
 *    BytesWarning extends Warning
3384
 */
3385
SimpleExtendsException(PyExc_Warning, BytesWarning,
3386
    "Base class for warnings about bytes and buffer related problems, mostly\n"
3387
    "related to conversion from str or comparing to str.");
3388
3389
3390
/*
3391
 *    EncodingWarning extends Warning
3392
 */
3393
SimpleExtendsException(PyExc_Warning, EncodingWarning,
3394
    "Base class for warnings about encodings.");
3395
3396
3397
/*
3398
 *    ResourceWarning extends Warning
3399
 */
3400
SimpleExtendsException(PyExc_Warning, ResourceWarning,
3401
    "Base class for warnings about resource usage.");
3402
3403
3404
3405
#ifdef MS_WINDOWS
3406
#include <winsock2.h>
3407
/* The following constants were added to errno.h in VS2010 but have
3408
   preferred WSA equivalents. */
3409
#undef EADDRINUSE
3410
#undef EADDRNOTAVAIL
3411
#undef EAFNOSUPPORT
3412
#undef EALREADY
3413
#undef ECONNABORTED
3414
#undef ECONNREFUSED
3415
#undef ECONNRESET
3416
#undef EDESTADDRREQ
3417
#undef EHOSTUNREACH
3418
#undef EINPROGRESS
3419
#undef EISCONN
3420
#undef ELOOP
3421
#undef EMSGSIZE
3422
#undef ENETDOWN
3423
#undef ENETRESET
3424
#undef ENETUNREACH
3425
#undef ENOBUFS
3426
#undef ENOPROTOOPT
3427
#undef ENOTCONN
3428
#undef ENOTSOCK
3429
#undef EOPNOTSUPP
3430
#undef EPROTONOSUPPORT
3431
#undef EPROTOTYPE
3432
#undef ETIMEDOUT
3433
#undef EWOULDBLOCK
3434
3435
#if defined(WSAEALREADY) && !defined(EALREADY)
3436
#define EALREADY WSAEALREADY
3437
#endif
3438
#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
3439
#define ECONNABORTED WSAECONNABORTED
3440
#endif
3441
#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
3442
#define ECONNREFUSED WSAECONNREFUSED
3443
#endif
3444
#if defined(WSAECONNRESET) && !defined(ECONNRESET)
3445
#define ECONNRESET WSAECONNRESET
3446
#endif
3447
#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
3448
#define EINPROGRESS WSAEINPROGRESS
3449
#endif
3450
#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
3451
#define ESHUTDOWN WSAESHUTDOWN
3452
#endif
3453
#if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
3454
#define ETIMEDOUT WSAETIMEDOUT
3455
#endif
3456
#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
3457
#define EWOULDBLOCK WSAEWOULDBLOCK
3458
#endif
3459
#endif /* MS_WINDOWS */
3460
3461
struct static_exception {
3462
    PyTypeObject *exc;
3463
    const char *name;
3464
};
3465
3466
static struct static_exception static_exceptions[] = {
3467
#define ITEM(NAME) {&_PyExc_##NAME, #NAME}
3468
    // Level 1
3469
    ITEM(BaseException),
3470
3471
    // Level 2: BaseException subclasses
3472
    ITEM(BaseExceptionGroup),
3473
    ITEM(Exception),
3474
    ITEM(GeneratorExit),
3475
    ITEM(KeyboardInterrupt),
3476
    ITEM(SystemExit),
3477
3478
    // Level 3: Exception(BaseException) subclasses
3479
    ITEM(ArithmeticError),
3480
    ITEM(AssertionError),
3481
    ITEM(AttributeError),
3482
    ITEM(BufferError),
3483
    ITEM(EOFError),
3484
    //ITEM(ExceptionGroup),
3485
    ITEM(ImportError),
3486
    ITEM(LookupError),
3487
    ITEM(MemoryError),
3488
    ITEM(NameError),
3489
    ITEM(OSError),
3490
    ITEM(ReferenceError),
3491
    ITEM(RuntimeError),
3492
    ITEM(StopAsyncIteration),
3493
    ITEM(StopIteration),
3494
    ITEM(SyntaxError),
3495
    ITEM(SystemError),
3496
    ITEM(TypeError),
3497
    ITEM(ValueError),
3498
    ITEM(Warning),
3499
3500
    // Level 4: ArithmeticError(Exception) subclasses
3501
    ITEM(FloatingPointError),
3502
    ITEM(OverflowError),
3503
    ITEM(ZeroDivisionError),
3504
3505
    // Level 4: Warning(Exception) subclasses
3506
    ITEM(BytesWarning),
3507
    ITEM(DeprecationWarning),
3508
    ITEM(EncodingWarning),
3509
    ITEM(FutureWarning),
3510
    ITEM(ImportWarning),
3511
    ITEM(PendingDeprecationWarning),
3512
    ITEM(ResourceWarning),
3513
    ITEM(RuntimeWarning),
3514
    ITEM(SyntaxWarning),
3515
    ITEM(UnicodeWarning),
3516
    ITEM(UserWarning),
3517
3518
    // Level 4: OSError(Exception) subclasses
3519
    ITEM(BlockingIOError),
3520
    ITEM(ChildProcessError),
3521
    ITEM(ConnectionError),
3522
    ITEM(FileExistsError),
3523
    ITEM(FileNotFoundError),
3524
    ITEM(InterruptedError),
3525
    ITEM(IsADirectoryError),
3526
    ITEM(NotADirectoryError),
3527
    ITEM(PermissionError),
3528
    ITEM(ProcessLookupError),
3529
    ITEM(TimeoutError),
3530
3531
    // Level 4: Other subclasses
3532
    ITEM(IndentationError), // base: SyntaxError(Exception)
3533
    ITEM(IndexError),  // base: LookupError(Exception)
3534
    ITEM(KeyError),  // base: LookupError(Exception)
3535
    ITEM(ModuleNotFoundError), // base: ImportError(Exception)
3536
    ITEM(NotImplementedError),  // base: RuntimeError(Exception)
3537
    ITEM(RecursionError),  // base: RuntimeError(Exception)
3538
    ITEM(UnboundLocalError), // base: NameError(Exception)
3539
    ITEM(UnicodeError),  // base: ValueError(Exception)
3540
3541
    // Level 5: ConnectionError(OSError) subclasses
3542
    ITEM(BrokenPipeError),
3543
    ITEM(ConnectionAbortedError),
3544
    ITEM(ConnectionRefusedError),
3545
    ITEM(ConnectionResetError),
3546
3547
    // Level 5: IndentationError(SyntaxError) subclasses
3548
    ITEM(TabError),  // base: IndentationError
3549
3550
    // Level 5: UnicodeError(ValueError) subclasses
3551
    ITEM(UnicodeDecodeError),
3552
    ITEM(UnicodeEncodeError),
3553
    ITEM(UnicodeTranslateError),
3554
#undef ITEM
3555
};
3556
3557
3558
int
3559
_PyExc_InitTypes(PyInterpreterState *interp)
3560
{
3561
    if (!_Py_IsMainInterpreter(interp)) {
  Branch (3561:9): [True: 171, False: 107]
3562
        return 0;
3563
    }
3564
3565
    
for (size_t i=0; 107
i < Py_ARRAY_LENGTH(static_exceptions);
i++7.06k
) {
  Branch (3565:22): [True: 7.06k, False: 107]
3566
        PyTypeObject *exc = static_exceptions[i].exc;
3567
3568
        if (PyType_Ready(exc) < 0) {
  Branch (3568:13): [True: 0, False: 7.06k]
3569
            return -1;
3570
        }
3571
    }
3572
    return 0;
3573
}
3574
3575
3576
static void
3577
_PyExc_FiniTypes(PyInterpreterState *interp)
3578
{
3579
    if (!_Py_IsMainInterpreter(interp)) {
  Branch (3579:9): [True: 169, False: 103]
3580
        return;
3581
    }
3582
3583
    
for (Py_ssize_t i=103
Py_ARRAY_LENGTH103
(static_exceptions) - 1; i >= 0;
i--6.79k
) {
  Branch (3583:63): [True: 6.79k, False: 103]
3584
        PyTypeObject *exc = static_exceptions[i].exc;
3585
        _PyStaticType_Dealloc(exc);
3586
    }
3587
}
3588
3589
3590
PyStatus
3591
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
3592
{
3593
    if (!_Py_IsMainInterpreter(interp)) {
  Branch (3593:9): [True: 171, False: 107]
3594
        return _PyStatus_OK();
3595
    }
3596
3597
    if (preallocate_memerrors() < 0) {
  Branch (3597:9): [True: 0, False: 107]
3598
        return _PyStatus_NO_MEMORY();
3599
    }
3600
    return _PyStatus_OK();
3601
}
3602
3603
PyStatus
3604
_PyExc_InitState(PyInterpreterState *interp)
3605
{
3606
    struct _Py_exc_state *state = &interp->exc_state;
3607
3608
#define ADD_ERRNO(TYPE, CODE) \
3609
    do { \
3610
        PyObject *_code = PyLong_FromLong(CODE); \
3611
        assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
3612
        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
3613
            Py_XDECREF(_code); \
3614
            return _PyStatus_ERR("errmap insertion problem."); \
3615
        } \
3616
        Py_DECREF(_code); \
3617
    } while (0)
3618
3619
    /* Add exceptions to errnomap */
3620
    assert(state->errnomap == NULL);
3621
    state->errnomap = PyDict_New();
3622
    if (!state->errnomap) {
  Branch (3622:9): [True: 0, False: 278]
3623
        return _PyStatus_NO_MEMORY();
3624
    }
3625
3626
    ADD_ERRNO(BlockingIOError, EAGAIN);
3627
    ADD_ERRNO(BlockingIOError, EALREADY);
3628
    ADD_ERRNO(BlockingIOError, EINPROGRESS);
3629
    ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
3630
    ADD_ERRNO(BrokenPipeError, EPIPE);
3631
#ifdef ESHUTDOWN
3632
    ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
3633
#endif
3634
    ADD_ERRNO(ChildProcessError, ECHILD);
3635
    ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
3636
    ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
3637
    ADD_ERRNO(ConnectionResetError, ECONNRESET);
3638
    ADD_ERRNO(FileExistsError, EEXIST);
3639
    ADD_ERRNO(FileNotFoundError, ENOENT);
3640
    ADD_ERRNO(IsADirectoryError, EISDIR);
3641
    ADD_ERRNO(NotADirectoryError, ENOTDIR);
3642
    ADD_ERRNO(InterruptedError, EINTR);
3643
    ADD_ERRNO(PermissionError, EACCES);
3644
    ADD_ERRNO(PermissionError, EPERM);
3645
    ADD_ERRNO(ProcessLookupError, ESRCH);
3646
    ADD_ERRNO(TimeoutError, ETIMEDOUT);
3647
3648
    return _PyStatus_OK();
3649
3650
#undef ADD_ERRNO
3651
}
3652
3653
3654
/* Add exception types to the builtins module */
3655
int
3656
_PyBuiltins_AddExceptions(PyObject *bltinmod)
3657
{
3658
    PyObject *mod_dict = PyModule_GetDict(bltinmod);
3659
    if (mod_dict == NULL) {
  Branch (3659:9): [True: 0, False: 278]
3660
        return -1;
3661
    }
3662
3663
    
for (size_t i=0; 278
i < Py_ARRAY_LENGTH(static_exceptions);
i++18.3k
) {
  Branch (3663:22): [True: 18.3k, False: 278]
3664
        struct static_exception item = static_exceptions[i];
3665
3666
        if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
  Branch (3666:13): [True: 0, False: 18.3k]
3667
            return -1;
3668
        }
3669
    }
3670
3671
    PyObject *PyExc_ExceptionGroup = create_exception_group_class();
3672
    if (!PyExc_ExceptionGroup) {
  Branch (3672:9): [True: 0, False: 278]
3673
        return -1;
3674
    }
3675
    if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
  Branch (3675:9): [True: 0, False: 278]
3676
        return -1;
3677
    }
3678
3679
#define INIT_ALIAS(NAME, TYPE) \
3680
    do { \
3681
        PyExc_ ## NAME = PyExc_ ## TYPE; \
3682
        if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \
3683
            return -1; \
3684
        } \
3685
    } while (0)
3686
3687
    INIT_ALIAS(EnvironmentError, OSError);
3688
    INIT_ALIAS(IOError, OSError);
3689
#ifdef MS_WINDOWS
3690
    INIT_ALIAS(WindowsError, OSError);
3691
#endif
3692
3693
#undef INIT_ALIAS
3694
3695
    return 0;
3696
}
3697
3698
void
3699
_PyExc_ClearExceptionGroupType(PyInterpreterState *interp)
3700
{
3701
    struct _Py_exc_state *state = &interp->exc_state;
3702
    Py_CLEAR(state->PyExc_ExceptionGroup);
3703
}
3704
3705
void
3706
_PyExc_Fini(PyInterpreterState *interp)
3707
{
3708
    struct _Py_exc_state *state = &interp->exc_state;
3709
    free_preallocated_memerrors(state);
3710
    Py_CLEAR(state->errnomap);
3711
3712
    _PyExc_FiniTypes(interp);
3713
}
3714
3715
/* Helper to do the equivalent of "raise X from Y" in C, but always using
3716
 * the current exception rather than passing one in.
3717
 *
3718
 * We currently limit this to *only* exceptions that use the BaseException
3719
 * tp_init and tp_new methods, since we can be reasonably sure we can wrap
3720
 * those correctly without losing data and without losing backwards
3721
 * compatibility.
3722
 *
3723
 * We also aim to rule out *all* exceptions that might be storing additional
3724
 * state, whether by having a size difference relative to BaseException,
3725
 * additional arguments passed in during construction or by having a
3726
 * non-empty instance dict.
3727
 *
3728
 * We need to be very careful with what we wrap, since changing types to
3729
 * a broader exception type would be backwards incompatible for
3730
 * existing codecs, and with different init or new method implementations
3731
 * may either not support instantiation with PyErr_Format or lose
3732
 * information when instantiated that way.
3733
 *
3734
 * XXX (ncoghlan): This could be made more comprehensive by exploiting the
3735
 * fact that exceptions are expected to support pickling. If more builtin
3736
 * exceptions (e.g. AttributeError) start to be converted to rich
3737
 * exceptions with additional attributes, that's probably a better approach
3738
 * to pursue over adding special cases for particular stateful subclasses.
3739
 *
3740
 * Returns a borrowed reference to the new exception (if any), NULL if the
3741
 * existing exception was left in place.
3742
 */
3743
PyObject *
3744
_PyErr_TrySetFromCause(const char *format, ...)
3745
{
3746
    PyObject* msg_prefix;
3747
    PyObject *exc, *val, *tb;
3748
    PyTypeObject *caught_type;
3749
    PyObject *instance_args;
3750
    Py_ssize_t num_args, caught_type_size, base_exc_size;
3751
    PyObject *new_exc, *new_val, *new_tb;
3752
    va_list vargs;
3753
    int same_basic_size;
3754
3755
    PyErr_Fetch(&exc, &val, &tb);
3756
    caught_type = (PyTypeObject *)exc;
3757
    /* Ensure type info indicates no extra state is stored at the C level
3758
     * and that the type can be reinstantiated using PyErr_Format
3759
     */
3760
    caught_type_size = caught_type->tp_basicsize;
3761
    base_exc_size = _PyExc_BaseException.tp_basicsize;
3762
    same_basic_size = (
3763
        caught_type_size == base_exc_size ||
  Branch (3763:9): [True: 75, False: 66]
3764
        
(66
_PyType_SUPPORTS_WEAKREFS(caught_type)66
&&
  Branch (3764:10): [True: 14, False: 52]
3765
            
(caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *))14
  Branch (3765:13): [True: 14, False: 0]
3766
        )
3767
    );
3768
    if (caught_type->tp_init != (initproc)BaseException_init ||
  Branch (3768:9): [True: 56, False: 85]
3769
        
caught_type->tp_new != BaseException_new85
||
  Branch (3769:9): [True: 4, False: 81]
3770
        
!same_basic_size81
||
  Branch (3770:9): [True: 0, False: 81]
3771
        
caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize81
) {
  Branch (3771:9): [True: 0, False: 81]
3772
        /* We can't be sure we can wrap this safely, since it may contain
3773
         * more state than just the exception type. Accordingly, we just
3774
         * leave it alone.
3775
         */
3776
        PyErr_Restore(exc, val, tb);
3777
        return NULL;
3778
    }
3779
3780
    /* Check the args are empty or contain a single string */
3781
    PyErr_NormalizeException(&exc, &val, &tb);
3782
    instance_args = ((PyBaseExceptionObject *)val)->args;
3783
    num_args = PyTuple_GET_SIZE(instance_args);
3784
    if (num_args > 1 ||
  Branch (3784:9): [True: 4, False: 77]
3785
        
(77
num_args == 177
&&
  Branch (3785:10): [True: 73, False: 4]
3786
         
!73
PyUnicode_CheckExact73
(PyTuple_GET_ITEM(instance_args, 0)))) {
  Branch (3786:10): [True: 4, False: 69]
3787
        /* More than 1 arg, or the one arg we do have isn't a string
3788
         */
3789
        PyErr_Restore(exc, val, tb);
3790
        return NULL;
3791
    }
3792
3793
    /* Ensure the instance dict is also empty */
3794
    if (!_PyObject_IsInstanceDictEmpty(val)) {
  Branch (3794:9): [True: 4, False: 69]
3795
        /* While we could potentially copy a non-empty instance dictionary
3796
         * to the replacement exception, for now we take the more
3797
         * conservative path of leaving exceptions with attributes set
3798
         * alone.
3799
         */
3800
        PyErr_Restore(exc, val, tb);
3801
        return NULL;
3802
    }
3803
3804
    /* For exceptions that we can wrap safely, we chain the original
3805
     * exception to a new one of the exact same type with an
3806
     * error message that mentions the additional details and the
3807
     * original exception.
3808
     *
3809
     * It would be nice to wrap OSError and various other exception
3810
     * types as well, but that's quite a bit trickier due to the extra
3811
     * state potentially stored on OSError instances.
3812
     */
3813
    /* Ensure the traceback is set correctly on the existing exception */
3814
    if (tb != NULL) {
  Branch (3814:9): [True: 62, False: 7]
3815
        PyException_SetTraceback(val, tb);
3816
        Py_DECREF(tb);
3817
    }
3818
3819
    va_start(vargs, format);
3820
    msg_prefix = PyUnicode_FromFormatV(format, vargs);
3821
    va_end(vargs);
3822
    if (msg_prefix == NULL) {
  Branch (3822:9): [True: 0, False: 69]
3823
        Py_DECREF(exc);
3824
        Py_DECREF(val);
3825
        return NULL;
3826
    }
3827
3828
    PyErr_Format(exc, "%U (%s: %S)",
3829
                 msg_prefix, Py_TYPE(val)->tp_name, val);
3830
    Py_DECREF(exc);
3831
    Py_DECREF(msg_prefix);
3832
    PyErr_Fetch(&new_exc, &new_val, &new_tb);
3833
    PyErr_NormalizeException(&new_exc, &new_val, &new_tb);
3834
    PyException_SetCause(new_val, val);
3835
    PyErr_Restore(new_exc, new_val, new_tb);
3836
    return new_val;
3837
}