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 "structmember.h"
10 #include "osdefs.h"
11
12 #define EXC_MODULE_NAME "exceptions."
13
14 /* NOTE: If the exception class hierarchy changes, don't forget to update
15 * Lib/test/exception_hierarchy.txt
16 */
17
18 PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
19 \n\
20 Exceptions found here are defined both in the exceptions module and the\n\
21 built-in namespace. It is recommended that user-defined exceptions\n\
22 inherit from Exception. See the documentation for the exception\n\
23 inheritance hierarchy.\n\
24 ");
25
26 /*
27 * BaseException
28 */
29 static PyObject *
BaseException_new(PyTypeObject * type,PyObject * args,PyObject * kwds)30 BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
31 {
32 PyBaseExceptionObject *self;
33
34 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
35 if (!self)
36 return NULL;
37 /* the dict is created on the fly in PyObject_GenericSetAttr */
38 self->message = self->dict = NULL;
39
40 self->args = PyTuple_New(0);
41 if (!self->args) {
42 Py_DECREF(self);
43 return NULL;
44 }
45
46 self->message = PyString_FromString("");
47 if (!self->message) {
48 Py_DECREF(self);
49 return NULL;
50 }
51
52 return (PyObject *)self;
53 }
54
55 static int
BaseException_init(PyBaseExceptionObject * self,PyObject * args,PyObject * kwds)56 BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
57 {
58 if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
59 return -1;
60
61 Py_INCREF(args);
62 Py_SETREF(self->args, args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
65 Py_INCREF(PyTuple_GET_ITEM(self->args, 0));
66 Py_XSETREF(self->message, PyTuple_GET_ITEM(self->args, 0));
67 }
68 return 0;
69 }
70
71 static int
BaseException_clear(PyBaseExceptionObject * self)72 BaseException_clear(PyBaseExceptionObject *self)
73 {
74 Py_CLEAR(self->dict);
75 Py_CLEAR(self->args);
76 Py_CLEAR(self->message);
77 return 0;
78 }
79
80 static void
BaseException_dealloc(PyBaseExceptionObject * self)81 BaseException_dealloc(PyBaseExceptionObject *self)
82 {
83 _PyObject_GC_UNTRACK(self);
84 BaseException_clear(self);
85 Py_TYPE(self)->tp_free((PyObject *)self);
86 }
87
88 static int
BaseException_traverse(PyBaseExceptionObject * self,visitproc visit,void * arg)89 BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
90 {
91 Py_VISIT(self->dict);
92 Py_VISIT(self->args);
93 Py_VISIT(self->message);
94 return 0;
95 }
96
97 static PyObject *
BaseException_str(PyBaseExceptionObject * self)98 BaseException_str(PyBaseExceptionObject *self)
99 {
100 PyObject *out;
101
102 switch (PyTuple_GET_SIZE(self->args)) {
103 case 0:
104 out = PyString_FromString("");
105 break;
106 case 1:
107 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
108 break;
109 default:
110 out = PyObject_Str(self->args);
111 break;
112 }
113
114 return out;
115 }
116
117 #ifdef Py_USING_UNICODE
118 static PyObject *
BaseException_unicode(PyBaseExceptionObject * self)119 BaseException_unicode(PyBaseExceptionObject *self)
120 {
121 PyObject *out;
122
123 /* issue6108: if __str__ has been overridden in the subclass, unicode()
124 should return the message returned by __str__ as used to happen
125 before this method was implemented. */
126 if (Py_TYPE(self)->tp_str != (reprfunc)BaseException_str) {
127 PyObject *str;
128 /* Unlike PyObject_Str, tp_str can return unicode (i.e. return the
129 equivalent of unicode(e.__str__()) instead of unicode(str(e))). */
130 str = Py_TYPE(self)->tp_str((PyObject*)self);
131 if (str == NULL)
132 return NULL;
133 out = PyObject_Unicode(str);
134 Py_DECREF(str);
135 return out;
136 }
137
138 switch (PyTuple_GET_SIZE(self->args)) {
139 case 0:
140 out = PyUnicode_FromString("");
141 break;
142 case 1:
143 out = PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
144 break;
145 default:
146 out = PyObject_Unicode(self->args);
147 break;
148 }
149
150 return out;
151 }
152 #endif
153
154 static PyObject *
BaseException_repr(PyBaseExceptionObject * self)155 BaseException_repr(PyBaseExceptionObject *self)
156 {
157 PyObject *repr_suffix;
158 PyObject *repr;
159 char *name;
160 char *dot;
161
162 repr_suffix = PyObject_Repr(self->args);
163 if (!repr_suffix)
164 return NULL;
165
166 name = (char *)Py_TYPE(self)->tp_name;
167 dot = strrchr(name, '.');
168 if (dot != NULL) name = dot+1;
169
170 repr = PyString_FromString(name);
171 if (!repr) {
172 Py_DECREF(repr_suffix);
173 return NULL;
174 }
175
176 PyString_ConcatAndDel(&repr, repr_suffix);
177 return repr;
178 }
179
180 /* Pickling support */
181 static PyObject *
BaseException_reduce(PyBaseExceptionObject * self)182 BaseException_reduce(PyBaseExceptionObject *self)
183 {
184 if (self->args && self->dict)
185 return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
186 else
187 return PyTuple_Pack(2, Py_TYPE(self), self->args);
188 }
189
190 /*
191 * Needed for backward compatibility, since exceptions used to store
192 * all their attributes in the __dict__. Code is taken from cPickle's
193 * load_build function.
194 */
195 static PyObject *
BaseException_setstate(PyObject * self,PyObject * state)196 BaseException_setstate(PyObject *self, PyObject *state)
197 {
198 PyObject *d_key, *d_value;
199 Py_ssize_t i = 0;
200
201 if (state != Py_None) {
202 if (!PyDict_Check(state)) {
203 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
204 return NULL;
205 }
206 while (PyDict_Next(state, &i, &d_key, &d_value)) {
207 if (PyObject_SetAttr(self, d_key, d_value) < 0)
208 return NULL;
209 }
210 }
211 Py_RETURN_NONE;
212 }
213
214
215 static PyMethodDef BaseException_methods[] = {
216 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
217 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
218 #ifdef Py_USING_UNICODE
219 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
220 #endif
221 {NULL, NULL, 0, NULL},
222 };
223
224
225
226 static PyObject *
BaseException_getitem(PyBaseExceptionObject * self,Py_ssize_t index)227 BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
228 {
229 if (PyErr_WarnPy3k("__getitem__ not supported for exception "
230 "classes in 3.x; use args attribute", 1) < 0)
231 return NULL;
232 return PySequence_GetItem(self->args, index);
233 }
234
235 static PyObject *
BaseException_getslice(PyBaseExceptionObject * self,Py_ssize_t start,Py_ssize_t stop)236 BaseException_getslice(PyBaseExceptionObject *self,
237 Py_ssize_t start, Py_ssize_t stop)
238 {
239 if (PyErr_WarnPy3k("__getslice__ not supported for exception "
240 "classes in 3.x; use args attribute", 1) < 0)
241 return NULL;
242 return PySequence_GetSlice(self->args, start, stop);
243 }
244
245 static PySequenceMethods BaseException_as_sequence = {
246 0, /* sq_length; */
247 0, /* sq_concat; */
248 0, /* sq_repeat; */
249 (ssizeargfunc)BaseException_getitem, /* sq_item; */
250 (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */
251 0, /* sq_ass_item; */
252 0, /* sq_ass_slice; */
253 0, /* sq_contains; */
254 0, /* sq_inplace_concat; */
255 0 /* sq_inplace_repeat; */
256 };
257
258 static PyObject *
BaseException_get_dict(PyBaseExceptionObject * self)259 BaseException_get_dict(PyBaseExceptionObject *self)
260 {
261 if (self->dict == NULL) {
262 self->dict = PyDict_New();
263 if (!self->dict)
264 return NULL;
265 }
266 Py_INCREF(self->dict);
267 return self->dict;
268 }
269
270 static int
BaseException_set_dict(PyBaseExceptionObject * self,PyObject * val)271 BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
272 {
273 if (val == NULL) {
274 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
275 return -1;
276 }
277 if (!PyDict_Check(val)) {
278 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
279 return -1;
280 }
281 Py_INCREF(val);
282 Py_XSETREF(self->dict, val);
283 return 0;
284 }
285
286 static PyObject *
BaseException_get_args(PyBaseExceptionObject * self)287 BaseException_get_args(PyBaseExceptionObject *self)
288 {
289 if (self->args == NULL) {
290 Py_INCREF(Py_None);
291 return Py_None;
292 }
293 Py_INCREF(self->args);
294 return self->args;
295 }
296
297 static int
BaseException_set_args(PyBaseExceptionObject * self,PyObject * val)298 BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
299 {
300 PyObject *seq;
301 if (val == NULL) {
302 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
303 return -1;
304 }
305 seq = PySequence_Tuple(val);
306 if (!seq)
307 return -1;
308 Py_XSETREF(self->args, seq);
309 return 0;
310 }
311
312 static PyObject *
BaseException_get_message(PyBaseExceptionObject * self)313 BaseException_get_message(PyBaseExceptionObject *self)
314 {
315 PyObject *msg;
316
317 /* if "message" is in self->dict, accessing a user-set message attribute */
318 if (self->dict &&
319 (msg = PyDict_GetItemString(self->dict, "message"))) {
320 Py_INCREF(msg);
321 return msg;
322 }
323
324 if (self->message == NULL) {
325 PyErr_SetString(PyExc_AttributeError, "message attribute was deleted");
326 return NULL;
327 }
328
329 /* accessing the deprecated "builtin" message attribute of Exception */
330 if (PyErr_WarnEx(PyExc_DeprecationWarning,
331 "BaseException.message has been deprecated as "
332 "of Python 2.6", 1) < 0)
333 return NULL;
334
335 Py_INCREF(self->message);
336 return self->message;
337 }
338
339 static int
BaseException_set_message(PyBaseExceptionObject * self,PyObject * val)340 BaseException_set_message(PyBaseExceptionObject *self, PyObject *val)
341 {
342 /* if val is NULL, delete the message attribute */
343 if (val == NULL) {
344 if (self->dict && PyDict_GetItemString(self->dict, "message")) {
345 if (PyDict_DelItemString(self->dict, "message") < 0)
346 return -1;
347 }
348 Py_CLEAR(self->message);
349 return 0;
350 }
351
352 /* else set it in __dict__, but may need to create the dict first */
353 if (self->dict == NULL) {
354 self->dict = PyDict_New();
355 if (!self->dict)
356 return -1;
357 }
358 return PyDict_SetItemString(self->dict, "message", val);
359 }
360
361 static PyGetSetDef BaseException_getset[] = {
362 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
363 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
364 {"message", (getter)BaseException_get_message,
365 (setter)BaseException_set_message},
366 {NULL},
367 };
368
369
370 static PyTypeObject _PyExc_BaseException = {
371 PyVarObject_HEAD_INIT(NULL, 0)
372 EXC_MODULE_NAME "BaseException", /*tp_name*/
373 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
374 0, /*tp_itemsize*/
375 (destructor)BaseException_dealloc, /*tp_dealloc*/
376 0, /*tp_print*/
377 0, /*tp_getattr*/
378 0, /*tp_setattr*/
379 0, /* tp_compare; */
380 (reprfunc)BaseException_repr, /*tp_repr*/
381 0, /*tp_as_number*/
382 &BaseException_as_sequence, /*tp_as_sequence*/
383 0, /*tp_as_mapping*/
384 0, /*tp_hash */
385 0, /*tp_call*/
386 (reprfunc)BaseException_str, /*tp_str*/
387 PyObject_GenericGetAttr, /*tp_getattro*/
388 PyObject_GenericSetAttr, /*tp_setattro*/
389 0, /*tp_as_buffer*/
390 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
391 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
392 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
393 (traverseproc)BaseException_traverse, /* tp_traverse */
394 (inquiry)BaseException_clear, /* tp_clear */
395 0, /* tp_richcompare */
396 0, /* tp_weaklistoffset */
397 0, /* tp_iter */
398 0, /* tp_iternext */
399 BaseException_methods, /* tp_methods */
400 0, /* tp_members */
401 BaseException_getset, /* tp_getset */
402 0, /* tp_base */
403 0, /* tp_dict */
404 0, /* tp_descr_get */
405 0, /* tp_descr_set */
406 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
407 (initproc)BaseException_init, /* tp_init */
408 0, /* tp_alloc */
409 BaseException_new, /* tp_new */
410 };
411 /* the CPython API expects exceptions to be (PyObject *) - both a hold-over
412 from the previous implmentation and also allowing Python objects to be used
413 in the API */
414 PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
415
416 /* note these macros omit the last semicolon so the macro invocation may
417 * include it and not look strange.
418 */
419 #define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
420 static PyTypeObject _PyExc_ ## EXCNAME = { \
421 PyVarObject_HEAD_INIT(NULL, 0) \
422 EXC_MODULE_NAME # EXCNAME, \
423 sizeof(PyBaseExceptionObject), \
424 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
425 0, 0, 0, 0, 0, 0, 0, \
426 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
427 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
428 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
429 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
430 (initproc)BaseException_init, 0, BaseException_new,\
431 }; \
432 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
433
434 #define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
435 static PyTypeObject _PyExc_ ## EXCNAME = { \
436 PyVarObject_HEAD_INIT(NULL, 0) \
437 EXC_MODULE_NAME # EXCNAME, \
438 sizeof(Py ## EXCSTORE ## Object), \
439 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
440 0, 0, 0, 0, 0, \
441 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
442 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
443 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
444 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
445 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
446 }; \
447 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
448
449 #define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
450 static PyTypeObject _PyExc_ ## EXCNAME = { \
451 PyVarObject_HEAD_INIT(NULL, 0) \
452 EXC_MODULE_NAME # EXCNAME, \
453 sizeof(Py ## EXCSTORE ## Object), 0, \
454 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
455 (reprfunc)EXCSTR, 0, 0, 0, \
456 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
457 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
458 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
459 EXCMEMBERS, 0, &_ ## EXCBASE, \
460 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
461 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
462 }; \
463 PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
464
465
466 /*
467 * Exception extends BaseException
468 */
469 SimpleExtendsException(PyExc_BaseException, Exception,
470 "Common base class for all non-exit exceptions.");
471
472
473 /*
474 * StandardError extends Exception
475 */
476 SimpleExtendsException(PyExc_Exception, StandardError,
477 "Base class for all standard Python exceptions that do not represent\n"
478 "interpreter exiting.");
479
480
481 /*
482 * TypeError extends StandardError
483 */
484 SimpleExtendsException(PyExc_StandardError, TypeError,
485 "Inappropriate argument type.");
486
487
488 /*
489 * StopIteration extends Exception
490 */
491 SimpleExtendsException(PyExc_Exception, StopIteration,
492 "Signal the end from iterator.next().");
493
494
495 /*
496 * GeneratorExit extends BaseException
497 */
498 SimpleExtendsException(PyExc_BaseException, GeneratorExit,
499 "Request that a generator exit.");
500
501
502 /*
503 * SystemExit extends BaseException
504 */
505
506 static int
SystemExit_init(PySystemExitObject * self,PyObject * args,PyObject * kwds)507 SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
508 {
509 Py_ssize_t size = PyTuple_GET_SIZE(args);
510
511 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
512 return -1;
513
514 if (size == 0)
515 return 0;
516 if (size == 1) {
517 Py_INCREF(PyTuple_GET_ITEM(args, 0));
518 Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0));
519 }
520 else { /* size > 1 */
521 Py_INCREF(args);
522 Py_XSETREF(self->code, args);
523 }
524 return 0;
525 }
526
527 static int
SystemExit_clear(PySystemExitObject * self)528 SystemExit_clear(PySystemExitObject *self)
529 {
530 Py_CLEAR(self->code);
531 return BaseException_clear((PyBaseExceptionObject *)self);
532 }
533
534 static void
SystemExit_dealloc(PySystemExitObject * self)535 SystemExit_dealloc(PySystemExitObject *self)
536 {
537 _PyObject_GC_UNTRACK(self);
538 SystemExit_clear(self);
539 Py_TYPE(self)->tp_free((PyObject *)self);
540 }
541
542 static int
SystemExit_traverse(PySystemExitObject * self,visitproc visit,void * arg)543 SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
544 {
545 Py_VISIT(self->code);
546 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
547 }
548
549 static PyMemberDef SystemExit_members[] = {
550 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
551 PyDoc_STR("exception code")},
552 {NULL} /* Sentinel */
553 };
554
555 ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
556 SystemExit_dealloc, 0, SystemExit_members, 0,
557 "Request to exit from the interpreter.");
558
559 /*
560 * KeyboardInterrupt extends BaseException
561 */
562 SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
563 "Program interrupted by user.");
564
565
566 /*
567 * ImportError extends StandardError
568 */
569 SimpleExtendsException(PyExc_StandardError, ImportError,
570 "Import can't find module, or can't find name in module.");
571
572
573 /*
574 * EnvironmentError extends StandardError
575 */
576
577 /* Where a function has a single filename, such as open() or some
578 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
579 * called, giving a third argument which is the filename. But, so
580 * that old code using in-place unpacking doesn't break, e.g.:
581 *
582 * except IOError, (errno, strerror):
583 *
584 * we hack args so that it only contains two items. This also
585 * means we need our own __str__() which prints out the filename
586 * when it was supplied.
587 */
588 static int
EnvironmentError_init(PyEnvironmentErrorObject * self,PyObject * args,PyObject * kwds)589 EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
590 PyObject *kwds)
591 {
592 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
593 PyObject *subslice = NULL;
594
595 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
596 return -1;
597
598 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
599 return 0;
600 }
601
602 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
603 &myerrno, &strerror, &filename)) {
604 return -1;
605 }
606 Py_INCREF(myerrno);
607 Py_XSETREF(self->myerrno, myerrno);
608
609 Py_INCREF(strerror);
610 Py_XSETREF(self->strerror, strerror);
611
612 /* self->filename will remain Py_None otherwise */
613 if (filename != NULL) {
614 Py_INCREF(filename);
615 Py_XSETREF(self->filename, filename);
616
617 subslice = PyTuple_GetSlice(args, 0, 2);
618 if (!subslice)
619 return -1;
620
621 Py_SETREF(self->args, subslice);
622 }
623 return 0;
624 }
625
626 static int
EnvironmentError_clear(PyEnvironmentErrorObject * self)627 EnvironmentError_clear(PyEnvironmentErrorObject *self)
628 {
629 Py_CLEAR(self->myerrno);
630 Py_CLEAR(self->strerror);
631 Py_CLEAR(self->filename);
632 return BaseException_clear((PyBaseExceptionObject *)self);
633 }
634
635 static void
EnvironmentError_dealloc(PyEnvironmentErrorObject * self)636 EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
637 {
638 _PyObject_GC_UNTRACK(self);
639 EnvironmentError_clear(self);
640 Py_TYPE(self)->tp_free((PyObject *)self);
641 }
642
643 static int
EnvironmentError_traverse(PyEnvironmentErrorObject * self,visitproc visit,void * arg)644 EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
645 void *arg)
646 {
647 Py_VISIT(self->myerrno);
648 Py_VISIT(self->strerror);
649 Py_VISIT(self->filename);
650 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
651 }
652
653 static PyObject *
EnvironmentError_str(PyEnvironmentErrorObject * self)654 EnvironmentError_str(PyEnvironmentErrorObject *self)
655 {
656 PyObject *rtnval = NULL;
657
658 if (self->filename) {
659 PyObject *fmt;
660 PyObject *repr;
661 PyObject *tuple;
662
663 fmt = PyString_FromString("[Errno %s] %s: %s");
664 if (!fmt)
665 return NULL;
666
667 repr = PyObject_Repr(self->filename);
668 if (!repr) {
669 Py_DECREF(fmt);
670 return NULL;
671 }
672 tuple = PyTuple_New(3);
673 if (!tuple) {
674 Py_DECREF(repr);
675 Py_DECREF(fmt);
676 return NULL;
677 }
678
679 if (self->myerrno) {
680 Py_INCREF(self->myerrno);
681 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
682 }
683 else {
684 Py_INCREF(Py_None);
685 PyTuple_SET_ITEM(tuple, 0, Py_None);
686 }
687 if (self->strerror) {
688 Py_INCREF(self->strerror);
689 PyTuple_SET_ITEM(tuple, 1, self->strerror);
690 }
691 else {
692 Py_INCREF(Py_None);
693 PyTuple_SET_ITEM(tuple, 1, Py_None);
694 }
695
696 PyTuple_SET_ITEM(tuple, 2, repr);
697
698 rtnval = PyString_Format(fmt, tuple);
699
700 Py_DECREF(fmt);
701 Py_DECREF(tuple);
702 }
703 else if (self->myerrno && self->strerror) {
704 PyObject *fmt;
705 PyObject *tuple;
706
707 fmt = PyString_FromString("[Errno %s] %s");
708 if (!fmt)
709 return NULL;
710
711 tuple = PyTuple_New(2);
712 if (!tuple) {
713 Py_DECREF(fmt);
714 return NULL;
715 }
716
717 if (self->myerrno) {
718 Py_INCREF(self->myerrno);
719 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
720 }
721 else {
722 Py_INCREF(Py_None);
723 PyTuple_SET_ITEM(tuple, 0, Py_None);
724 }
725 if (self->strerror) {
726 Py_INCREF(self->strerror);
727 PyTuple_SET_ITEM(tuple, 1, self->strerror);
728 }
729 else {
730 Py_INCREF(Py_None);
731 PyTuple_SET_ITEM(tuple, 1, Py_None);
732 }
733
734 rtnval = PyString_Format(fmt, tuple);
735
736 Py_DECREF(fmt);
737 Py_DECREF(tuple);
738 }
739 else
740 rtnval = BaseException_str((PyBaseExceptionObject *)self);
741
742 return rtnval;
743 }
744
745 static PyMemberDef EnvironmentError_members[] = {
746 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
747 PyDoc_STR("exception errno")},
748 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
749 PyDoc_STR("exception strerror")},
750 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
751 PyDoc_STR("exception filename")},
752 {NULL} /* Sentinel */
753 };
754
755
756 static PyObject *
EnvironmentError_reduce(PyEnvironmentErrorObject * self)757 EnvironmentError_reduce(PyEnvironmentErrorObject *self)
758 {
759 PyObject *args = self->args;
760 PyObject *res = NULL, *tmp;
761
762 /* self->args is only the first two real arguments if there was a
763 * file name given to EnvironmentError. */
764 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
765 args = PyTuple_New(3);
766 if (!args)
767 return NULL;
768
769 tmp = PyTuple_GET_ITEM(self->args, 0);
770 Py_INCREF(tmp);
771 PyTuple_SET_ITEM(args, 0, tmp);
772
773 tmp = PyTuple_GET_ITEM(self->args, 1);
774 Py_INCREF(tmp);
775 PyTuple_SET_ITEM(args, 1, tmp);
776
777 Py_INCREF(self->filename);
778 PyTuple_SET_ITEM(args, 2, self->filename);
779 } else
780 Py_INCREF(args);
781
782 if (self->dict)
783 res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
784 else
785 res = PyTuple_Pack(2, Py_TYPE(self), args);
786 Py_DECREF(args);
787 return res;
788 }
789
790
791 static PyMethodDef EnvironmentError_methods[] = {
792 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
793 {NULL}
794 };
795
796 ComplexExtendsException(PyExc_StandardError, EnvironmentError,
797 EnvironmentError, EnvironmentError_dealloc,
798 EnvironmentError_methods, EnvironmentError_members,
799 EnvironmentError_str,
800 "Base class for I/O related errors.");
801
802
803 /*
804 * IOError extends EnvironmentError
805 */
806 MiddlingExtendsException(PyExc_EnvironmentError, IOError,
807 EnvironmentError, "I/O operation failed.");
808
809
810 /*
811 * OSError extends EnvironmentError
812 */
813 MiddlingExtendsException(PyExc_EnvironmentError, OSError,
814 EnvironmentError, "OS system call failed.");
815
816
817 /*
818 * WindowsError extends OSError
819 */
820 #ifdef MS_WINDOWS
821 #include "errmap.h"
822
823 static int
WindowsError_clear(PyWindowsErrorObject * self)824 WindowsError_clear(PyWindowsErrorObject *self)
825 {
826 Py_CLEAR(self->myerrno);
827 Py_CLEAR(self->strerror);
828 Py_CLEAR(self->filename);
829 Py_CLEAR(self->winerror);
830 return BaseException_clear((PyBaseExceptionObject *)self);
831 }
832
833 static void
WindowsError_dealloc(PyWindowsErrorObject * self)834 WindowsError_dealloc(PyWindowsErrorObject *self)
835 {
836 _PyObject_GC_UNTRACK(self);
837 WindowsError_clear(self);
838 Py_TYPE(self)->tp_free((PyObject *)self);
839 }
840
841 static int
WindowsError_traverse(PyWindowsErrorObject * self,visitproc visit,void * arg)842 WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
843 {
844 Py_VISIT(self->myerrno);
845 Py_VISIT(self->strerror);
846 Py_VISIT(self->filename);
847 Py_VISIT(self->winerror);
848 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
849 }
850
851 static int
WindowsError_init(PyWindowsErrorObject * self,PyObject * args,PyObject * kwds)852 WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
853 {
854 PyObject *o_errcode = NULL;
855 long errcode;
856 long posix_errno;
857
858 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
859 == -1)
860 return -1;
861
862 if (self->myerrno == NULL)
863 return 0;
864
865 /* Set errno to the POSIX errno, and winerror to the Win32
866 error code. */
867 errcode = PyInt_AsLong(self->myerrno);
868 if (errcode == -1 && PyErr_Occurred())
869 return -1;
870 posix_errno = winerror_to_errno(errcode);
871
872 Py_XSETREF(self->winerror, self->myerrno);
873
874 o_errcode = PyInt_FromLong(posix_errno);
875 if (!o_errcode)
876 return -1;
877
878 self->myerrno = o_errcode;
879
880 return 0;
881 }
882
883
884 static PyObject *
WindowsError_str(PyWindowsErrorObject * self)885 WindowsError_str(PyWindowsErrorObject *self)
886 {
887 PyObject *rtnval = NULL;
888
889 if (self->filename) {
890 PyObject *fmt;
891 PyObject *repr;
892 PyObject *tuple;
893
894 fmt = PyString_FromString("[Error %s] %s: %s");
895 if (!fmt)
896 return NULL;
897
898 repr = PyObject_Repr(self->filename);
899 if (!repr) {
900 Py_DECREF(fmt);
901 return NULL;
902 }
903 tuple = PyTuple_New(3);
904 if (!tuple) {
905 Py_DECREF(repr);
906 Py_DECREF(fmt);
907 return NULL;
908 }
909
910 if (self->winerror) {
911 Py_INCREF(self->winerror);
912 PyTuple_SET_ITEM(tuple, 0, self->winerror);
913 }
914 else {
915 Py_INCREF(Py_None);
916 PyTuple_SET_ITEM(tuple, 0, Py_None);
917 }
918 if (self->strerror) {
919 Py_INCREF(self->strerror);
920 PyTuple_SET_ITEM(tuple, 1, self->strerror);
921 }
922 else {
923 Py_INCREF(Py_None);
924 PyTuple_SET_ITEM(tuple, 1, Py_None);
925 }
926
927 PyTuple_SET_ITEM(tuple, 2, repr);
928
929 rtnval = PyString_Format(fmt, tuple);
930
931 Py_DECREF(fmt);
932 Py_DECREF(tuple);
933 }
934 else if (self->winerror && self->strerror) {
935 PyObject *fmt;
936 PyObject *tuple;
937
938 fmt = PyString_FromString("[Error %s] %s");
939 if (!fmt)
940 return NULL;
941
942 tuple = PyTuple_New(2);
943 if (!tuple) {
944 Py_DECREF(fmt);
945 return NULL;
946 }
947
948 if (self->winerror) {
949 Py_INCREF(self->winerror);
950 PyTuple_SET_ITEM(tuple, 0, self->winerror);
951 }
952 else {
953 Py_INCREF(Py_None);
954 PyTuple_SET_ITEM(tuple, 0, Py_None);
955 }
956 if (self->strerror) {
957 Py_INCREF(self->strerror);
958 PyTuple_SET_ITEM(tuple, 1, self->strerror);
959 }
960 else {
961 Py_INCREF(Py_None);
962 PyTuple_SET_ITEM(tuple, 1, Py_None);
963 }
964
965 rtnval = PyString_Format(fmt, tuple);
966
967 Py_DECREF(fmt);
968 Py_DECREF(tuple);
969 }
970 else
971 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
972
973 return rtnval;
974 }
975
976 static PyMemberDef WindowsError_members[] = {
977 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
978 PyDoc_STR("POSIX exception code")},
979 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
980 PyDoc_STR("exception strerror")},
981 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
982 PyDoc_STR("exception filename")},
983 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
984 PyDoc_STR("Win32 exception code")},
985 {NULL} /* Sentinel */
986 };
987
988 ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
989 WindowsError_dealloc, 0, WindowsError_members,
990 WindowsError_str, "MS-Windows OS system call failed.");
991
992 #endif /* MS_WINDOWS */
993
994
995 /*
996 * VMSError extends OSError (I think)
997 */
998 #ifdef __VMS
999 MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
1000 "OpenVMS OS system call failed.");
1001 #endif
1002
1003
1004 /*
1005 * EOFError extends StandardError
1006 */
1007 SimpleExtendsException(PyExc_StandardError, EOFError,
1008 "Read beyond end of file.");
1009
1010
1011 /*
1012 * RuntimeError extends StandardError
1013 */
1014 SimpleExtendsException(PyExc_StandardError, RuntimeError,
1015 "Unspecified run-time error.");
1016
1017
1018 /*
1019 * NotImplementedError extends RuntimeError
1020 */
1021 SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
1022 "Method or function hasn't been implemented yet.");
1023
1024 /*
1025 * NameError extends StandardError
1026 */
1027 SimpleExtendsException(PyExc_StandardError, NameError,
1028 "Name not found globally.");
1029
1030 /*
1031 * UnboundLocalError extends NameError
1032 */
1033 SimpleExtendsException(PyExc_NameError, UnboundLocalError,
1034 "Local name referenced but not bound to a value.");
1035
1036 /*
1037 * AttributeError extends StandardError
1038 */
1039 SimpleExtendsException(PyExc_StandardError, AttributeError,
1040 "Attribute not found.");
1041
1042
1043 /*
1044 * SyntaxError extends StandardError
1045 */
1046
1047 static int
SyntaxError_init(PySyntaxErrorObject * self,PyObject * args,PyObject * kwds)1048 SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
1049 {
1050 PyObject *info = NULL;
1051 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
1052
1053 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1054 return -1;
1055
1056 if (lenargs >= 1) {
1057 Py_INCREF(PyTuple_GET_ITEM(args, 0));
1058 Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0));
1059 }
1060 if (lenargs == 2) {
1061 info = PyTuple_GET_ITEM(args, 1);
1062 info = PySequence_Tuple(info);
1063 if (!info)
1064 return -1;
1065
1066 if (PyTuple_GET_SIZE(info) != 4) {
1067 /* not a very good error message, but it's what Python 2.4 gives */
1068 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
1069 Py_DECREF(info);
1070 return -1;
1071 }
1072
1073 Py_INCREF(PyTuple_GET_ITEM(info, 0));
1074 Py_XSETREF(self->filename, PyTuple_GET_ITEM(info, 0));
1075
1076 Py_INCREF(PyTuple_GET_ITEM(info, 1));
1077 Py_XSETREF(self->lineno, PyTuple_GET_ITEM(info, 1));
1078
1079 Py_INCREF(PyTuple_GET_ITEM(info, 2));
1080 Py_XSETREF(self->offset, PyTuple_GET_ITEM(info, 2));
1081
1082 Py_INCREF(PyTuple_GET_ITEM(info, 3));
1083 Py_XSETREF(self->text, PyTuple_GET_ITEM(info, 3));
1084
1085 Py_DECREF(info);
1086 }
1087 return 0;
1088 }
1089
1090 static int
SyntaxError_clear(PySyntaxErrorObject * self)1091 SyntaxError_clear(PySyntaxErrorObject *self)
1092 {
1093 Py_CLEAR(self->msg);
1094 Py_CLEAR(self->filename);
1095 Py_CLEAR(self->lineno);
1096 Py_CLEAR(self->offset);
1097 Py_CLEAR(self->text);
1098 Py_CLEAR(self->print_file_and_line);
1099 return BaseException_clear((PyBaseExceptionObject *)self);
1100 }
1101
1102 static void
SyntaxError_dealloc(PySyntaxErrorObject * self)1103 SyntaxError_dealloc(PySyntaxErrorObject *self)
1104 {
1105 _PyObject_GC_UNTRACK(self);
1106 SyntaxError_clear(self);
1107 Py_TYPE(self)->tp_free((PyObject *)self);
1108 }
1109
1110 static int
SyntaxError_traverse(PySyntaxErrorObject * self,visitproc visit,void * arg)1111 SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1112 {
1113 Py_VISIT(self->msg);
1114 Py_VISIT(self->filename);
1115 Py_VISIT(self->lineno);
1116 Py_VISIT(self->offset);
1117 Py_VISIT(self->text);
1118 Py_VISIT(self->print_file_and_line);
1119 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1120 }
1121
1122 /* This is called "my_basename" instead of just "basename" to avoid name
1123 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1124 defined, and Python does define that. */
1125 static char *
my_basename(char * name)1126 my_basename(char *name)
1127 {
1128 char *cp = name;
1129 char *result = name;
1130
1131 if (name == NULL)
1132 return "???";
1133 while (*cp != '\0') {
1134 if (*cp == SEP)
1135 result = cp + 1;
1136 ++cp;
1137 }
1138 return result;
1139 }
1140
1141
1142 static PyObject *
SyntaxError_str(PySyntaxErrorObject * self)1143 SyntaxError_str(PySyntaxErrorObject *self)
1144 {
1145 PyObject *str;
1146 PyObject *result;
1147 int have_filename = 0;
1148 int have_lineno = 0;
1149 char *buffer = NULL;
1150 Py_ssize_t bufsize;
1151
1152 if (self->msg)
1153 str = PyObject_Str(self->msg);
1154 else
1155 str = PyObject_Str(Py_None);
1156 if (!str)
1157 return NULL;
1158 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1159 if (!PyString_Check(str))
1160 return str;
1161
1162 /* XXX -- do all the additional formatting with filename and
1163 lineno here */
1164
1165 have_filename = (self->filename != NULL) &&
1166 PyString_Check(self->filename);
1167 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
1168
1169 if (!have_filename && !have_lineno)
1170 return str;
1171
1172 bufsize = PyString_GET_SIZE(str) + 64;
1173 if (have_filename)
1174 bufsize += PyString_GET_SIZE(self->filename);
1175
1176 buffer = PyMem_MALLOC(bufsize);
1177 if (buffer == NULL)
1178 return str;
1179
1180 if (have_filename && have_lineno)
1181 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1182 PyString_AS_STRING(str),
1183 my_basename(PyString_AS_STRING(self->filename)),
1184 PyInt_AsLong(self->lineno));
1185 else if (have_filename)
1186 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1187 PyString_AS_STRING(str),
1188 my_basename(PyString_AS_STRING(self->filename)));
1189 else /* only have_lineno */
1190 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1191 PyString_AS_STRING(str),
1192 PyInt_AsLong(self->lineno));
1193
1194 result = PyString_FromString(buffer);
1195 PyMem_FREE(buffer);
1196
1197 if (result == NULL)
1198 result = str;
1199 else
1200 Py_DECREF(str);
1201 return result;
1202 }
1203
1204 static PyMemberDef SyntaxError_members[] = {
1205 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1206 PyDoc_STR("exception msg")},
1207 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1208 PyDoc_STR("exception filename")},
1209 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1210 PyDoc_STR("exception lineno")},
1211 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1212 PyDoc_STR("exception offset")},
1213 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1214 PyDoc_STR("exception text")},
1215 {"print_file_and_line", T_OBJECT,
1216 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1217 PyDoc_STR("exception print_file_and_line")},
1218 {NULL} /* Sentinel */
1219 };
1220
1221 ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1222 SyntaxError_dealloc, 0, SyntaxError_members,
1223 SyntaxError_str, "Invalid syntax.");
1224
1225
1226 /*
1227 * IndentationError extends SyntaxError
1228 */
1229 MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1230 "Improper indentation.");
1231
1232
1233 /*
1234 * TabError extends IndentationError
1235 */
1236 MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1237 "Improper mixture of spaces and tabs.");
1238
1239
1240 /*
1241 * LookupError extends StandardError
1242 */
1243 SimpleExtendsException(PyExc_StandardError, LookupError,
1244 "Base class for lookup errors.");
1245
1246
1247 /*
1248 * IndexError extends LookupError
1249 */
1250 SimpleExtendsException(PyExc_LookupError, IndexError,
1251 "Sequence index out of range.");
1252
1253
1254 /*
1255 * KeyError extends LookupError
1256 */
1257 static PyObject *
KeyError_str(PyBaseExceptionObject * self)1258 KeyError_str(PyBaseExceptionObject *self)
1259 {
1260 /* If args is a tuple of exactly one item, apply repr to args[0].
1261 This is done so that e.g. the exception raised by {}[''] prints
1262 KeyError: ''
1263 rather than the confusing
1264 KeyError
1265 alone. The downside is that if KeyError is raised with an explanatory
1266 string, that string will be displayed in quotes. Too bad.
1267 If args is anything else, use the default BaseException__str__().
1268 */
1269 if (PyTuple_GET_SIZE(self->args) == 1) {
1270 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
1271 }
1272 return BaseException_str(self);
1273 }
1274
1275 ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1276 0, 0, 0, KeyError_str, "Mapping key not found.");
1277
1278
1279 /*
1280 * ValueError extends StandardError
1281 */
1282 SimpleExtendsException(PyExc_StandardError, ValueError,
1283 "Inappropriate argument value (of correct type).");
1284
1285 /*
1286 * UnicodeError extends ValueError
1287 */
1288
1289 SimpleExtendsException(PyExc_ValueError, UnicodeError,
1290 "Unicode related error.");
1291
1292 #ifdef Py_USING_UNICODE
1293 static PyObject *
get_string(PyObject * attr,const char * name)1294 get_string(PyObject *attr, const char *name)
1295 {
1296 if (!attr) {
1297 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1298 return NULL;
1299 }
1300
1301 if (!PyString_Check(attr)) {
1302 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1303 return NULL;
1304 }
1305 Py_INCREF(attr);
1306 return attr;
1307 }
1308
1309
1310 static int
set_string(PyObject ** attr,const char * value)1311 set_string(PyObject **attr, const char *value)
1312 {
1313 PyObject *obj = PyString_FromString(value);
1314 if (!obj)
1315 return -1;
1316 Py_XSETREF(*attr, obj);
1317 return 0;
1318 }
1319
1320
1321 static PyObject *
get_unicode(PyObject * attr,const char * name)1322 get_unicode(PyObject *attr, const char *name)
1323 {
1324 if (!attr) {
1325 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1326 return NULL;
1327 }
1328
1329 if (!PyUnicode_Check(attr)) {
1330 PyErr_Format(PyExc_TypeError,
1331 "%.200s attribute must be unicode", name);
1332 return NULL;
1333 }
1334 Py_INCREF(attr);
1335 return attr;
1336 }
1337
1338 PyObject *
PyUnicodeEncodeError_GetEncoding(PyObject * exc)1339 PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1340 {
1341 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1342 }
1343
1344 PyObject *
PyUnicodeDecodeError_GetEncoding(PyObject * exc)1345 PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1346 {
1347 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1348 }
1349
1350 PyObject *
PyUnicodeEncodeError_GetObject(PyObject * exc)1351 PyUnicodeEncodeError_GetObject(PyObject *exc)
1352 {
1353 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1354 }
1355
1356 PyObject *
PyUnicodeDecodeError_GetObject(PyObject * exc)1357 PyUnicodeDecodeError_GetObject(PyObject *exc)
1358 {
1359 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1360 }
1361
1362 PyObject *
PyUnicodeTranslateError_GetObject(PyObject * exc)1363 PyUnicodeTranslateError_GetObject(PyObject *exc)
1364 {
1365 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1366 }
1367
1368 int
PyUnicodeEncodeError_GetStart(PyObject * exc,Py_ssize_t * start)1369 PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1370 {
1371 Py_ssize_t size;
1372 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1373 "object");
1374 if (!obj)
1375 return -1;
1376 *start = ((PyUnicodeErrorObject *)exc)->start;
1377 size = PyUnicode_GET_SIZE(obj);
1378 if (*start<0)
1379 *start = 0; /*XXX check for values <0*/
1380 if (*start>=size)
1381 *start = size-1;
1382 Py_DECREF(obj);
1383 return 0;
1384 }
1385
1386
1387 int
PyUnicodeDecodeError_GetStart(PyObject * exc,Py_ssize_t * start)1388 PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1389 {
1390 Py_ssize_t size;
1391 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1392 "object");
1393 if (!obj)
1394 return -1;
1395 size = PyString_GET_SIZE(obj);
1396 *start = ((PyUnicodeErrorObject *)exc)->start;
1397 if (*start<0)
1398 *start = 0;
1399 if (*start>=size)
1400 *start = size-1;
1401 Py_DECREF(obj);
1402 return 0;
1403 }
1404
1405
1406 int
PyUnicodeTranslateError_GetStart(PyObject * exc,Py_ssize_t * start)1407 PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1408 {
1409 return PyUnicodeEncodeError_GetStart(exc, start);
1410 }
1411
1412
1413 int
PyUnicodeEncodeError_SetStart(PyObject * exc,Py_ssize_t start)1414 PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1415 {
1416 ((PyUnicodeErrorObject *)exc)->start = start;
1417 return 0;
1418 }
1419
1420
1421 int
PyUnicodeDecodeError_SetStart(PyObject * exc,Py_ssize_t start)1422 PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1423 {
1424 ((PyUnicodeErrorObject *)exc)->start = start;
1425 return 0;
1426 }
1427
1428
1429 int
PyUnicodeTranslateError_SetStart(PyObject * exc,Py_ssize_t start)1430 PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1431 {
1432 ((PyUnicodeErrorObject *)exc)->start = start;
1433 return 0;
1434 }
1435
1436
1437 int
PyUnicodeEncodeError_GetEnd(PyObject * exc,Py_ssize_t * end)1438 PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1439 {
1440 Py_ssize_t size;
1441 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1442 "object");
1443 if (!obj)
1444 return -1;
1445 *end = ((PyUnicodeErrorObject *)exc)->end;
1446 size = PyUnicode_GET_SIZE(obj);
1447 if (*end<1)
1448 *end = 1;
1449 if (*end>size)
1450 *end = size;
1451 Py_DECREF(obj);
1452 return 0;
1453 }
1454
1455
1456 int
PyUnicodeDecodeError_GetEnd(PyObject * exc,Py_ssize_t * end)1457 PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1458 {
1459 Py_ssize_t size;
1460 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1461 "object");
1462 if (!obj)
1463 return -1;
1464 *end = ((PyUnicodeErrorObject *)exc)->end;
1465 size = PyString_GET_SIZE(obj);
1466 if (*end<1)
1467 *end = 1;
1468 if (*end>size)
1469 *end = size;
1470 Py_DECREF(obj);
1471 return 0;
1472 }
1473
1474
1475 int
PyUnicodeTranslateError_GetEnd(PyObject * exc,Py_ssize_t * start)1476 PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1477 {
1478 return PyUnicodeEncodeError_GetEnd(exc, start);
1479 }
1480
1481
1482 int
PyUnicodeEncodeError_SetEnd(PyObject * exc,Py_ssize_t end)1483 PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1484 {
1485 ((PyUnicodeErrorObject *)exc)->end = end;
1486 return 0;
1487 }
1488
1489
1490 int
PyUnicodeDecodeError_SetEnd(PyObject * exc,Py_ssize_t end)1491 PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1492 {
1493 ((PyUnicodeErrorObject *)exc)->end = end;
1494 return 0;
1495 }
1496
1497
1498 int
PyUnicodeTranslateError_SetEnd(PyObject * exc,Py_ssize_t end)1499 PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1500 {
1501 ((PyUnicodeErrorObject *)exc)->end = end;
1502 return 0;
1503 }
1504
1505 PyObject *
PyUnicodeEncodeError_GetReason(PyObject * exc)1506 PyUnicodeEncodeError_GetReason(PyObject *exc)
1507 {
1508 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1509 }
1510
1511
1512 PyObject *
PyUnicodeDecodeError_GetReason(PyObject * exc)1513 PyUnicodeDecodeError_GetReason(PyObject *exc)
1514 {
1515 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1516 }
1517
1518
1519 PyObject *
PyUnicodeTranslateError_GetReason(PyObject * exc)1520 PyUnicodeTranslateError_GetReason(PyObject *exc)
1521 {
1522 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1523 }
1524
1525
1526 int
PyUnicodeEncodeError_SetReason(PyObject * exc,const char * reason)1527 PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1528 {
1529 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1530 }
1531
1532
1533 int
PyUnicodeDecodeError_SetReason(PyObject * exc,const char * reason)1534 PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1535 {
1536 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1537 }
1538
1539
1540 int
PyUnicodeTranslateError_SetReason(PyObject * exc,const char * reason)1541 PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1542 {
1543 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1544 }
1545
1546
1547 static int
UnicodeError_init(PyUnicodeErrorObject * self,PyObject * args,PyObject * kwds,PyTypeObject * objecttype)1548 UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1549 PyTypeObject *objecttype)
1550 {
1551 Py_CLEAR(self->encoding);
1552 Py_CLEAR(self->object);
1553 Py_CLEAR(self->reason);
1554
1555 if (!PyArg_ParseTuple(args, "O!O!nnO!",
1556 &PyString_Type, &self->encoding,
1557 objecttype, &self->object,
1558 &self->start,
1559 &self->end,
1560 &PyString_Type, &self->reason)) {
1561 self->encoding = self->object = self->reason = NULL;
1562 return -1;
1563 }
1564
1565 Py_INCREF(self->encoding);
1566 Py_INCREF(self->object);
1567 Py_INCREF(self->reason);
1568
1569 return 0;
1570 }
1571
1572 static int
UnicodeError_clear(PyUnicodeErrorObject * self)1573 UnicodeError_clear(PyUnicodeErrorObject *self)
1574 {
1575 Py_CLEAR(self->encoding);
1576 Py_CLEAR(self->object);
1577 Py_CLEAR(self->reason);
1578 return BaseException_clear((PyBaseExceptionObject *)self);
1579 }
1580
1581 static void
UnicodeError_dealloc(PyUnicodeErrorObject * self)1582 UnicodeError_dealloc(PyUnicodeErrorObject *self)
1583 {
1584 _PyObject_GC_UNTRACK(self);
1585 UnicodeError_clear(self);
1586 Py_TYPE(self)->tp_free((PyObject *)self);
1587 }
1588
1589 static int
UnicodeError_traverse(PyUnicodeErrorObject * self,visitproc visit,void * arg)1590 UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1591 {
1592 Py_VISIT(self->encoding);
1593 Py_VISIT(self->object);
1594 Py_VISIT(self->reason);
1595 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1596 }
1597
1598 static PyMemberDef UnicodeError_members[] = {
1599 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1600 PyDoc_STR("exception encoding")},
1601 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1602 PyDoc_STR("exception object")},
1603 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
1604 PyDoc_STR("exception start")},
1605 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
1606 PyDoc_STR("exception end")},
1607 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1608 PyDoc_STR("exception reason")},
1609 {NULL} /* Sentinel */
1610 };
1611
1612
1613 /*
1614 * UnicodeEncodeError extends UnicodeError
1615 */
1616
1617 static int
UnicodeEncodeError_init(PyObject * self,PyObject * args,PyObject * kwds)1618 UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1619 {
1620 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1621 return -1;
1622 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1623 kwds, &PyUnicode_Type);
1624 }
1625
1626 static PyObject *
UnicodeEncodeError_str(PyObject * self)1627 UnicodeEncodeError_str(PyObject *self)
1628 {
1629 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
1630 PyObject *result = NULL;
1631 PyObject *reason_str = NULL;
1632 PyObject *encoding_str = NULL;
1633
1634 if (!uself->object)
1635 /* Not properly initialized. */
1636 return PyUnicode_FromString("");
1637
1638 /* Get reason and encoding as strings, which they might not be if
1639 they've been modified after we were constructed. */
1640 reason_str = PyObject_Str(uself->reason);
1641 if (reason_str == NULL)
1642 goto done;
1643 encoding_str = PyObject_Str(uself->encoding);
1644 if (encoding_str == NULL)
1645 goto done;
1646
1647 if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
1648 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
1649 char badchar_str[20];
1650 if (badchar <= 0xff)
1651 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1652 else if (badchar <= 0xffff)
1653 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1654 else
1655 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1656 result = PyString_FromFormat(
1657 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1658 PyString_AS_STRING(encoding_str),
1659 badchar_str,
1660 uself->start,
1661 PyString_AS_STRING(reason_str));
1662 }
1663 else {
1664 result = PyString_FromFormat(
1665 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1666 PyString_AS_STRING(encoding_str),
1667 uself->start,
1668 uself->end-1,
1669 PyString_AS_STRING(reason_str));
1670 }
1671 done:
1672 Py_XDECREF(reason_str);
1673 Py_XDECREF(encoding_str);
1674 return result;
1675 }
1676
1677 static PyTypeObject _PyExc_UnicodeEncodeError = {
1678 PyVarObject_HEAD_INIT(NULL, 0)
1679 EXC_MODULE_NAME "UnicodeEncodeError",
1680 sizeof(PyUnicodeErrorObject), 0,
1681 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1682 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1683 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1684 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1685 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1686 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
1687 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
1688 };
1689 PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1690
1691 PyObject *
PyUnicodeEncodeError_Create(const char * encoding,const Py_UNICODE * object,Py_ssize_t length,Py_ssize_t start,Py_ssize_t end,const char * reason)1692 PyUnicodeEncodeError_Create(
1693 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1694 Py_ssize_t start, Py_ssize_t end, const char *reason)
1695 {
1696 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
1697 encoding, object, length, start, end, reason);
1698 }
1699
1700
1701 /*
1702 * UnicodeDecodeError extends UnicodeError
1703 */
1704
1705 static int
UnicodeDecodeError_init(PyObject * self,PyObject * args,PyObject * kwds)1706 UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1707 {
1708 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1709 return -1;
1710 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1711 kwds, &PyString_Type);
1712 }
1713
1714 static PyObject *
UnicodeDecodeError_str(PyObject * self)1715 UnicodeDecodeError_str(PyObject *self)
1716 {
1717 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
1718 PyObject *result = NULL;
1719 PyObject *reason_str = NULL;
1720 PyObject *encoding_str = NULL;
1721
1722 if (!uself->object)
1723 /* Not properly initialized. */
1724 return PyUnicode_FromString("");
1725
1726 /* Get reason and encoding as strings, which they might not be if
1727 they've been modified after we were constructed. */
1728 reason_str = PyObject_Str(uself->reason);
1729 if (reason_str == NULL)
1730 goto done;
1731 encoding_str = PyObject_Str(uself->encoding);
1732 if (encoding_str == NULL)
1733 goto done;
1734
1735 if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
1736 /* FromFormat does not support %02x, so format that separately */
1737 char byte[4];
1738 PyOS_snprintf(byte, sizeof(byte), "%02x",
1739 ((int)PyString_AS_STRING(uself->object)[uself->start])&0xff);
1740 result = PyString_FromFormat(
1741 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1742 PyString_AS_STRING(encoding_str),
1743 byte,
1744 uself->start,
1745 PyString_AS_STRING(reason_str));
1746 }
1747 else {
1748 result = PyString_FromFormat(
1749 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1750 PyString_AS_STRING(encoding_str),
1751 uself->start,
1752 uself->end-1,
1753 PyString_AS_STRING(reason_str));
1754 }
1755 done:
1756 Py_XDECREF(reason_str);
1757 Py_XDECREF(encoding_str);
1758 return result;
1759 }
1760
1761 static PyTypeObject _PyExc_UnicodeDecodeError = {
1762 PyVarObject_HEAD_INIT(NULL, 0)
1763 EXC_MODULE_NAME "UnicodeDecodeError",
1764 sizeof(PyUnicodeErrorObject), 0,
1765 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1766 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1767 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1768 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1769 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1770 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
1771 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
1772 };
1773 PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1774
1775 PyObject *
PyUnicodeDecodeError_Create(const char * encoding,const char * object,Py_ssize_t length,Py_ssize_t start,Py_ssize_t end,const char * reason)1776 PyUnicodeDecodeError_Create(
1777 const char *encoding, const char *object, Py_ssize_t length,
1778 Py_ssize_t start, Py_ssize_t end, const char *reason)
1779 {
1780 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
1781 encoding, object, length, start, end, reason);
1782 }
1783
1784
1785 /*
1786 * UnicodeTranslateError extends UnicodeError
1787 */
1788
1789 static int
UnicodeTranslateError_init(PyUnicodeErrorObject * self,PyObject * args,PyObject * kwds)1790 UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1791 PyObject *kwds)
1792 {
1793 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1794 return -1;
1795
1796 Py_CLEAR(self->object);
1797 Py_CLEAR(self->reason);
1798
1799 if (!PyArg_ParseTuple(args, "O!nnO!",
1800 &PyUnicode_Type, &self->object,
1801 &self->start,
1802 &self->end,
1803 &PyString_Type, &self->reason)) {
1804 self->object = self->reason = NULL;
1805 return -1;
1806 }
1807
1808 Py_INCREF(self->object);
1809 Py_INCREF(self->reason);
1810
1811 return 0;
1812 }
1813
1814
1815 static PyObject *
UnicodeTranslateError_str(PyObject * self)1816 UnicodeTranslateError_str(PyObject *self)
1817 {
1818 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
1819 PyObject *result = NULL;
1820 PyObject *reason_str = NULL;
1821
1822 if (!uself->object)
1823 /* Not properly initialized. */
1824 return PyUnicode_FromString("");
1825
1826 /* Get reason as a string, which it might not be if it's been
1827 modified after we were constructed. */
1828 reason_str = PyObject_Str(uself->reason);
1829 if (reason_str == NULL)
1830 goto done;
1831
1832 if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
1833 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
1834 char badchar_str[20];
1835 if (badchar <= 0xff)
1836 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1837 else if (badchar <= 0xffff)
1838 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1839 else
1840 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1841 result = PyString_FromFormat(
1842 "can't translate character u'\\%s' in position %zd: %.400s",
1843 badchar_str,
1844 uself->start,
1845 PyString_AS_STRING(reason_str));
1846 } else {
1847 result = PyString_FromFormat(
1848 "can't translate characters in position %zd-%zd: %.400s",
1849 uself->start,
1850 uself->end-1,
1851 PyString_AS_STRING(reason_str));
1852 }
1853 done:
1854 Py_XDECREF(reason_str);
1855 return result;
1856 }
1857
1858 static PyTypeObject _PyExc_UnicodeTranslateError = {
1859 PyVarObject_HEAD_INIT(NULL, 0)
1860 EXC_MODULE_NAME "UnicodeTranslateError",
1861 sizeof(PyUnicodeErrorObject), 0,
1862 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1863 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1864 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1865 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
1866 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1867 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
1868 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
1869 };
1870 PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1871
1872 PyObject *
PyUnicodeTranslateError_Create(const Py_UNICODE * object,Py_ssize_t length,Py_ssize_t start,Py_ssize_t end,const char * reason)1873 PyUnicodeTranslateError_Create(
1874 const Py_UNICODE *object, Py_ssize_t length,
1875 Py_ssize_t start, Py_ssize_t end, const char *reason)
1876 {
1877 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
1878 object, length, start, end, reason);
1879 }
1880 #endif
1881
1882
1883 /*
1884 * AssertionError extends StandardError
1885 */
1886 SimpleExtendsException(PyExc_StandardError, AssertionError,
1887 "Assertion failed.");
1888
1889
1890 /*
1891 * ArithmeticError extends StandardError
1892 */
1893 SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1894 "Base class for arithmetic errors.");
1895
1896
1897 /*
1898 * FloatingPointError extends ArithmeticError
1899 */
1900 SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1901 "Floating point operation failed.");
1902
1903
1904 /*
1905 * OverflowError extends ArithmeticError
1906 */
1907 SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1908 "Result too large to be represented.");
1909
1910
1911 /*
1912 * ZeroDivisionError extends ArithmeticError
1913 */
1914 SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1915 "Second argument to a division or modulo operation was zero.");
1916
1917
1918 /*
1919 * SystemError extends StandardError
1920 */
1921 SimpleExtendsException(PyExc_StandardError, SystemError,
1922 "Internal error in the Python interpreter.\n"
1923 "\n"
1924 "Please report this to the Python maintainer, along with the traceback,\n"
1925 "the Python version, and the hardware/OS platform and version.");
1926
1927
1928 /*
1929 * ReferenceError extends StandardError
1930 */
1931 SimpleExtendsException(PyExc_StandardError, ReferenceError,
1932 "Weak ref proxy used after referent went away.");
1933
1934
1935 /*
1936 * MemoryError extends StandardError
1937 */
1938 SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1939
1940 /*
1941 * BufferError extends StandardError
1942 */
1943 SimpleExtendsException(PyExc_StandardError, BufferError, "Buffer error.");
1944
1945
1946 /* Warning category docstrings */
1947
1948 /*
1949 * Warning extends Exception
1950 */
1951 SimpleExtendsException(PyExc_Exception, Warning,
1952 "Base class for warning categories.");
1953
1954
1955 /*
1956 * UserWarning extends Warning
1957 */
1958 SimpleExtendsException(PyExc_Warning, UserWarning,
1959 "Base class for warnings generated by user code.");
1960
1961
1962 /*
1963 * DeprecationWarning extends Warning
1964 */
1965 SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1966 "Base class for warnings about deprecated features.");
1967
1968
1969 /*
1970 * PendingDeprecationWarning extends Warning
1971 */
1972 SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1973 "Base class for warnings about features which will be deprecated\n"
1974 "in the future.");
1975
1976
1977 /*
1978 * SyntaxWarning extends Warning
1979 */
1980 SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1981 "Base class for warnings about dubious syntax.");
1982
1983
1984 /*
1985 * RuntimeWarning extends Warning
1986 */
1987 SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1988 "Base class for warnings about dubious runtime behavior.");
1989
1990
1991 /*
1992 * FutureWarning extends Warning
1993 */
1994 SimpleExtendsException(PyExc_Warning, FutureWarning,
1995 "Base class for warnings about constructs that will change semantically\n"
1996 "in the future.");
1997
1998
1999 /*
2000 * ImportWarning extends Warning
2001 */
2002 SimpleExtendsException(PyExc_Warning, ImportWarning,
2003 "Base class for warnings about probable mistakes in module imports");
2004
2005
2006 /*
2007 * UnicodeWarning extends Warning
2008 */
2009 SimpleExtendsException(PyExc_Warning, UnicodeWarning,
2010 "Base class for warnings about Unicode related problems, mostly\n"
2011 "related to conversion problems.");
2012
2013 /*
2014 * BytesWarning extends Warning
2015 */
2016 SimpleExtendsException(PyExc_Warning, BytesWarning,
2017 "Base class for warnings about bytes and bytearray related problems, \n"
2018 "mostly related to comparing to str.");
2019
2020 /* Pre-computed MemoryError instance. Best to create this as early as
2021 * possible and not wait until a MemoryError is actually raised!
2022 */
2023 PyObject *PyExc_MemoryErrorInst=NULL;
2024
2025 /* Pre-computed RuntimeError instance for when recursion depth is reached.
2026 Meant to be used when normalizing the exception for exceeding the recursion
2027 depth will cause its own infinite recursion.
2028 */
2029 PyObject *PyExc_RecursionErrorInst = NULL;
2030
2031 /* module global functions */
2032 static PyMethodDef functions[] = {
2033 /* Sentinel */
2034 {NULL, NULL}
2035 };
2036
2037 #define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
2038 Py_FatalError("exceptions bootstrapping error.");
2039
2040 #define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
2041 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
2042 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
2043 Py_FatalError("Module dictionary insertion problem.");
2044
2045
2046 PyMODINIT_FUNC
_PyExc_Init(void)2047 _PyExc_Init(void)
2048 {
2049 PyObject *m, *bltinmod, *bdict;
2050
2051 PRE_INIT(BaseException)
2052 PRE_INIT(Exception)
2053 PRE_INIT(StandardError)
2054 PRE_INIT(TypeError)
2055 PRE_INIT(StopIteration)
2056 PRE_INIT(GeneratorExit)
2057 PRE_INIT(SystemExit)
2058 PRE_INIT(KeyboardInterrupt)
2059 PRE_INIT(ImportError)
2060 PRE_INIT(EnvironmentError)
2061 PRE_INIT(IOError)
2062 PRE_INIT(OSError)
2063 #ifdef MS_WINDOWS
2064 PRE_INIT(WindowsError)
2065 #endif
2066 #ifdef __VMS
2067 PRE_INIT(VMSError)
2068 #endif
2069 PRE_INIT(EOFError)
2070 PRE_INIT(RuntimeError)
2071 PRE_INIT(NotImplementedError)
2072 PRE_INIT(NameError)
2073 PRE_INIT(UnboundLocalError)
2074 PRE_INIT(AttributeError)
2075 PRE_INIT(SyntaxError)
2076 PRE_INIT(IndentationError)
2077 PRE_INIT(TabError)
2078 PRE_INIT(LookupError)
2079 PRE_INIT(IndexError)
2080 PRE_INIT(KeyError)
2081 PRE_INIT(ValueError)
2082 PRE_INIT(UnicodeError)
2083 #ifdef Py_USING_UNICODE
2084 PRE_INIT(UnicodeEncodeError)
2085 PRE_INIT(UnicodeDecodeError)
2086 PRE_INIT(UnicodeTranslateError)
2087 #endif
2088 PRE_INIT(AssertionError)
2089 PRE_INIT(ArithmeticError)
2090 PRE_INIT(FloatingPointError)
2091 PRE_INIT(OverflowError)
2092 PRE_INIT(ZeroDivisionError)
2093 PRE_INIT(SystemError)
2094 PRE_INIT(ReferenceError)
2095 PRE_INIT(MemoryError)
2096 PRE_INIT(BufferError)
2097 PRE_INIT(Warning)
2098 PRE_INIT(UserWarning)
2099 PRE_INIT(DeprecationWarning)
2100 PRE_INIT(PendingDeprecationWarning)
2101 PRE_INIT(SyntaxWarning)
2102 PRE_INIT(RuntimeWarning)
2103 PRE_INIT(FutureWarning)
2104 PRE_INIT(ImportWarning)
2105 PRE_INIT(UnicodeWarning)
2106 PRE_INIT(BytesWarning)
2107
2108 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2109 (PyObject *)NULL, PYTHON_API_VERSION);
2110 if (m == NULL)
2111 return;
2112
2113 bltinmod = PyImport_ImportModule("__builtin__");
2114 if (bltinmod == NULL)
2115 Py_FatalError("exceptions bootstrapping error.");
2116 bdict = PyModule_GetDict(bltinmod);
2117 if (bdict == NULL)
2118 Py_FatalError("exceptions bootstrapping error.");
2119
2120 POST_INIT(BaseException)
2121 POST_INIT(Exception)
2122 POST_INIT(StandardError)
2123 POST_INIT(TypeError)
2124 POST_INIT(StopIteration)
2125 POST_INIT(GeneratorExit)
2126 POST_INIT(SystemExit)
2127 POST_INIT(KeyboardInterrupt)
2128 POST_INIT(ImportError)
2129 POST_INIT(EnvironmentError)
2130 POST_INIT(IOError)
2131 POST_INIT(OSError)
2132 #ifdef MS_WINDOWS
2133 POST_INIT(WindowsError)
2134 #endif
2135 #ifdef __VMS
2136 POST_INIT(VMSError)
2137 #endif
2138 POST_INIT(EOFError)
2139 POST_INIT(RuntimeError)
2140 POST_INIT(NotImplementedError)
2141 POST_INIT(NameError)
2142 POST_INIT(UnboundLocalError)
2143 POST_INIT(AttributeError)
2144 POST_INIT(SyntaxError)
2145 POST_INIT(IndentationError)
2146 POST_INIT(TabError)
2147 POST_INIT(LookupError)
2148 POST_INIT(IndexError)
2149 POST_INIT(KeyError)
2150 POST_INIT(ValueError)
2151 POST_INIT(UnicodeError)
2152 #ifdef Py_USING_UNICODE
2153 POST_INIT(UnicodeEncodeError)
2154 POST_INIT(UnicodeDecodeError)
2155 POST_INIT(UnicodeTranslateError)
2156 #endif
2157 POST_INIT(AssertionError)
2158 POST_INIT(ArithmeticError)
2159 POST_INIT(FloatingPointError)
2160 POST_INIT(OverflowError)
2161 POST_INIT(ZeroDivisionError)
2162 POST_INIT(SystemError)
2163 POST_INIT(ReferenceError)
2164 POST_INIT(MemoryError)
2165 POST_INIT(BufferError)
2166 POST_INIT(Warning)
2167 POST_INIT(UserWarning)
2168 POST_INIT(DeprecationWarning)
2169 POST_INIT(PendingDeprecationWarning)
2170 POST_INIT(SyntaxWarning)
2171 POST_INIT(RuntimeWarning)
2172 POST_INIT(FutureWarning)
2173 POST_INIT(ImportWarning)
2174 POST_INIT(UnicodeWarning)
2175 POST_INIT(BytesWarning)
2176
2177 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2178 if (!PyExc_MemoryErrorInst)
2179 Py_FatalError("Cannot pre-allocate MemoryError instance");
2180
2181 PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
2182 if (!PyExc_RecursionErrorInst)
2183 Py_FatalError("Cannot pre-allocate RuntimeError instance for "
2184 "recursion errors");
2185 else {
2186 PyBaseExceptionObject *err_inst =
2187 (PyBaseExceptionObject *)PyExc_RecursionErrorInst;
2188 PyObject *args_tuple;
2189 PyObject *exc_message;
2190 exc_message = PyString_FromString("maximum recursion depth exceeded");
2191 if (!exc_message)
2192 Py_FatalError("cannot allocate argument for RuntimeError "
2193 "pre-allocation");
2194 args_tuple = PyTuple_Pack(1, exc_message);
2195 if (!args_tuple)
2196 Py_FatalError("cannot allocate tuple for RuntimeError "
2197 "pre-allocation");
2198 Py_DECREF(exc_message);
2199 if (BaseException_init(err_inst, args_tuple, NULL))
2200 Py_FatalError("init of pre-allocated RuntimeError failed");
2201 Py_DECREF(args_tuple);
2202 }
2203 Py_DECREF(bltinmod);
2204 }
2205
2206 void
_PyExc_Fini(void)2207 _PyExc_Fini(void)
2208 {
2209 Py_CLEAR(PyExc_MemoryErrorInst);
2210 Py_CLEAR(PyExc_RecursionErrorInst);
2211 }
2212