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