blob: 2726519c025e55ae0b68f67bffb54f0df6b23dfc [file] [log] [blame]
Barry Warsaw675ac282000-05-26 19:05:16 +00001/* This module provides the suite of standard class-based exceptions for
2 * Python's builtin module. This is a complete C implementation of what,
3 * in Python 1.5.2, was contained in the exceptions.py module. The problem
4 * there was that if exceptions.py could not be imported for some reason,
5 * the entire interpreter would abort.
6 *
7 * By moving the exceptions into C and statically linking, we can guarantee
8 * that the standard exceptions will always be available.
9 *
10 * history:
11 * 98-08-19 fl created (for pyexe)
12 * 00-02-08 fl updated for 1.5.2
13 * 26-May-2000 baw vetted for Python 1.6
14 *
15 * written by Fredrik Lundh
16 * modifications, additions, cleanups, and proofreading by Barry Warsaw
17 *
18 * Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved.
19 */
20
21#include "Python.h"
22
23static char
24module__doc__[] =
25"Python's standard exception class hierarchy.\n\
26\n\
27Before Python 1.5, the standard exceptions were all simple string objects.\n\
28In Python 1.5, the standard exceptions were converted to classes organized\n\
29into a relatively flat hierarchy. String-based standard exceptions were\n\
30optional, or used as a fallback if some problem occurred while importing\n\
31the exception module. With Python 1.6, optional string-based standard\n\
32exceptions were removed (along with the -X command line flag).\n\
33\n\
34The class exceptions were implemented in such a way as to be almost\n\
35completely backward compatible. Some tricky uses of IOError could\n\
36potentially have broken, but by Python 1.6, all of these should have\n\
37been fixed. As of Python 1.6, the class-based standard exceptions are\n\
38now implemented in C, and are guaranteed to exist in the Python\n\
39interpreter.\n\
40\n\
41Here is a rundown of the class hierarchy. The classes found here are\n\
42inserted into both the exceptions module and the `built-in' module. It is\n\
43recommended that user defined class based exceptions be derived from the\n\
44`Exception' class, although this is currently not enforced.\n\
45\n\
46Exception\n\
47 |\n\
48 +-- SystemExit\n\
49 +-- StandardError\n\
50 |\n\
51 +-- KeyboardInterrupt\n\
52 +-- ImportError\n\
53 +-- EnvironmentError\n\
54 | |\n\
55 | +-- IOError\n\
56 | +-- OSError\n\
57 | |\n\
58 | +-- WindowsError\n\
59 |\n\
60 +-- EOFError\n\
61 +-- RuntimeError\n\
62 | |\n\
63 | +-- NotImplementedError\n\
64 |\n\
65 +-- NameError\n\
66 | |\n\
67 | +-- UnboundLocalError\n\
68 |\n\
69 +-- AttributeError\n\
70 +-- SyntaxError\n\
71 +-- TypeError\n\
72 +-- AssertionError\n\
73 +-- LookupError\n\
74 | |\n\
75 | +-- IndexError\n\
76 | +-- KeyError\n\
77 |\n\
78 +-- ArithmeticError\n\
79 | |\n\
80 | +-- OverflowError\n\
81 | +-- ZeroDivisionError\n\
82 | +-- FloatingPointError\n\
83 |\n\
84 +-- ValueError\n\
85 | |\n\
86 | +-- UnicodeError\n\
87 |\n\
88 +-- SystemError\n\
89 +-- MemoryError";
90
91
92/* Helper function for populating a dictionary with method wrappers. */
93static int
94populate_methods(PyObject* klass, PyObject* dict, PyMethodDef* methods)
95{
96 if (!methods)
97 return 0;
98
99 while (methods->ml_name) {
100 /* get a wrapper for the built-in function */
101 PyObject* func = PyCFunction_New(methods, NULL);
102 PyObject* meth;
103 int status;
104
105 if (!func)
106 return -1;
107
108 /* turn the function into an unbound method */
109 if (!(meth = PyMethod_New(func, NULL, klass))) {
110 Py_DECREF(func);
111 return -1;
112 }
113
114 /* add method to dictionary */
115 status = PyDict_SetItemString(dict, methods->ml_name, meth);
116 Py_DECREF(meth);
117 Py_DECREF(func);
118
119 /* stop now if an error occurred, otherwise do the next method */
120 if (status)
121 return status;
122
123 methods++;
124 }
125 return 0;
126}
127
128
129
130/* This function is used to create all subsequent exception classes. */
131static int
132make_class(PyObject** klass, PyObject* base,
133 char* name, PyMethodDef* methods,
134 char* docstr)
135{
136 PyObject* dict = PyDict_New();
137 PyObject* str = NULL;
138 int status = -1;
139
140 if (!dict)
141 return -1;
142
143 /* If an error occurs from here on, goto finally instead of explicitly
144 * returning NULL.
145 */
146
147 if (docstr) {
148 if (!(str = PyString_FromString(docstr)))
149 goto finally;
150 if (PyDict_SetItemString(dict, "__doc__", str))
151 goto finally;
152 }
153
154 if (!(*klass = PyErr_NewException(name, base, dict)))
155 goto finally;
156
157 if (populate_methods(*klass, dict, methods)) {
158 Py_DECREF(*klass);
159 *klass = NULL;
160 }
161
162 status = 0;
163
164 finally:
165 Py_XDECREF(dict);
166 Py_XDECREF(str);
167 return status;
168}
169
170
171/* Use this for *args signatures, otherwise just use PyArg_ParseTuple() */
172static PyObject* get_self(PyObject* args)
173{
174 PyObject* self = PyTuple_GetItem(args, 0);
175 if (!self) {
176 /* Watch out for being called to early in the bootstapping process */
177 if (PyExc_TypeError) {
178 PyErr_SetString(PyExc_TypeError,
179 "unbound method must be called with class instance 1st argument");
180 }
181 return NULL;
182 }
183 return self;
184}
185
186
187
188/* Notes on bootstrapping the exception classes.
189 *
190 * First thing we create is the base class for all exceptions, called
191 * appropriately enough: Exception. Creation of this class makes no
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000192 * assumptions about the existence of any other exception class -- except
Barry Warsaw675ac282000-05-26 19:05:16 +0000193 * for TypeError, which can conditionally exist.
194 *
195 * Next, StandardError is created (which is quite simple) followed by
196 * TypeError, because the instantiation of other exceptions can potentially
197 * throw a TypeError. Once these exceptions are created, all the others
198 * can be created in any order. See the static exctable below for the
199 * explicit bootstrap order.
200 *
201 * All classes after Exception can be created using PyErr_NewException().
202 */
203
204static char
205Exception__doc__[] = "Common base class for all exceptions.";
206
207
208static PyObject*
209Exception__init__(PyObject* self, PyObject* args)
210{
211 int status;
212
213 if (!(self = get_self(args)))
214 return NULL;
215
216 /* set args attribute */
217 args = PySequence_GetSlice(args, 1, PySequence_Length(args));
218 if (!args)
219 return NULL;
220 status = PyObject_SetAttrString(self, "args", args);
221 Py_DECREF(args);
222 if (status < 0)
223 return NULL;
224
225 Py_INCREF(Py_None);
226 return Py_None;
227}
228
229
230static PyObject*
231Exception__str__(PyObject* self, PyObject* args)
232{
233 PyObject* out;
234 PyObject* tmp;
235
236 if (!PyArg_ParseTuple(args, "O", &self))
237 return NULL;
238
239 args = PyObject_GetAttrString(self, "args");
240 if (!args)
241 return NULL;
242
243 switch (PySequence_Length(args)) {
244 case 0:
245 out = PyString_FromString("");
246 break;
247 case 1:
248 if (!(tmp = PySequence_GetItem(args, 0)))
249 out = NULL;
250 else
251 out = PyObject_Str(tmp);
252 break;
253 default:
254 out = PyObject_Str(args);
255 break;
256 }
257
258 Py_DECREF(args);
259 return out;
260}
261
262
263static PyObject*
264Exception__getitem__(PyObject* self, PyObject* args)
265{
266 PyObject* out;
267 PyObject* index;
268
269 if (!PyArg_ParseTuple(args, "OO", &self, &index))
270 return NULL;
271
272 args = PyObject_GetAttrString(self, "args");
273 if (!args)
274 return NULL;
275
276 out = PyObject_GetItem(args, index);
277 Py_DECREF(args);
278 return out;
279}
280
281
282static PyMethodDef
283Exception_methods[] = {
284 /* methods for the Exception class */
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000285 { "__getitem__", Exception__getitem__, METH_VARARGS},
286 { "__str__", Exception__str__, METH_VARARGS},
287 { "__init__", Exception__init__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000288 { NULL, NULL }
289};
290
291
292static int
293make_Exception(char* modulename)
294{
295 PyObject* dict = PyDict_New();
296 PyObject* str = NULL;
297 PyObject* name = NULL;
298 int status = -1;
299
300 if (!dict)
301 return -1;
302
303 /* If an error occurs from here on, goto finally instead of explicitly
304 * returning NULL.
305 */
306
307 if (!(str = PyString_FromString(modulename)))
308 goto finally;
309 if (PyDict_SetItemString(dict, "__module__", str))
310 goto finally;
311 Py_DECREF(str);
312 if (!(str = PyString_FromString(Exception__doc__)))
313 goto finally;
314 if (PyDict_SetItemString(dict, "__doc__", str))
315 goto finally;
316
317 if (!(name = PyString_FromString("Exception")))
318 goto finally;
319
320 if (!(PyExc_Exception = PyClass_New(NULL, dict, name)))
321 goto finally;
322
323 /* Now populate the dictionary with the method suite */
324 if (populate_methods(PyExc_Exception, dict, Exception_methods))
325 /* Don't need to reclaim PyExc_Exception here because that'll
326 * happen during interpreter shutdown.
327 */
328 goto finally;
329
330 status = 0;
331
332 finally:
333 Py_XDECREF(dict);
334 Py_XDECREF(str);
335 Py_XDECREF(name);
336 return status;
337}
338
339
340
341static char
342StandardError__doc__[] = "Base class for all standard Python exceptions.";
343
344static char
345TypeError__doc__[] = "Inappropriate argument type.";
346
347
348
349static char
350SystemExit__doc__[] = "Request to exit from the interpreter.";
351
352
353static PyObject*
354SystemExit__init__(PyObject* self, PyObject* args)
355{
356 PyObject* code;
357 int status;
358
359 if (!(self = get_self(args)))
360 return NULL;
361
362 /* Set args attribute. */
363 if (!(args = PySequence_GetSlice(args, 1, PySequence_Length(args))))
364 return NULL;
365
366 status = PyObject_SetAttrString(self, "args", args);
367 if (status < 0) {
368 Py_DECREF(args);
369 return NULL;
370 }
371
372 /* set code attribute */
373 switch (PySequence_Length(args)) {
374 case 0:
375 Py_INCREF(Py_None);
376 code = Py_None;
377 break;
378 case 1:
379 code = PySequence_GetItem(args, 0);
380 break;
381 default:
382 Py_INCREF(args);
383 code = args;
384 break;
385 }
386
387 status = PyObject_SetAttrString(self, "code", code);
388 Py_DECREF(code);
389 Py_DECREF(args);
390 if (status < 0)
391 return NULL;
392
393 Py_INCREF(Py_None);
394 return Py_None;
395}
396
397
398PyMethodDef SystemExit_methods[] = {
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000399 { "__init__", SystemExit__init__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000400 {NULL, NULL}
401};
402
403
404
405static char
406KeyboardInterrupt__doc__[] = "Program interrupted by user.";
407
408static char
409ImportError__doc__[] =
410"Import can't find module, or can't find name in module.";
411
412
413
414static char
415EnvironmentError__doc__[] = "Base class for I/O related errors.";
416
417
418static PyObject*
419EnvironmentError__init__(PyObject* self, PyObject* args)
420{
421 PyObject* item0 = NULL;
422 PyObject* item1 = NULL;
423 PyObject* item2 = NULL;
424 PyObject* subslice = NULL;
425 PyObject* rtnval = NULL;
426
427 if (!(self = get_self(args)))
428 return NULL;
429
430 if (!(args = PySequence_GetSlice(args, 1, PySequence_Length(args))))
431 return NULL;
432
433 if (PyObject_SetAttrString(self, "args", args) ||
434 PyObject_SetAttrString(self, "errno", Py_None) ||
435 PyObject_SetAttrString(self, "strerror", Py_None) ||
436 PyObject_SetAttrString(self, "filename", Py_None))
437 {
438 goto finally;
439 }
440
441 switch (PySequence_Length(args)) {
442 case 3:
443 /* open() errors give third argument which is the filename. But so
444 * common in-place unpacking doesn't break, e.g.:
445 *
446 * except IOError, (errno, strerror):
447 *
448 * we hack args so that it only contains two items. This also
449 * means we need our own __str__() which prints out the filename
450 * when it was supplied.
451 */
452 item0 = PySequence_GetItem(args, 0);
453 item1 = PySequence_GetItem(args, 1);
454 item2 = PySequence_GetItem(args, 2);
455 if (!item0 || !item1 || !item2)
456 goto finally;
457
458 if (PyObject_SetAttrString(self, "errno", item0) ||
459 PyObject_SetAttrString(self, "strerror", item1) ||
460 PyObject_SetAttrString(self, "filename", item2))
461 {
462 goto finally;
463 }
464
465 subslice = PySequence_GetSlice(args, 0, 2);
466 if (!subslice || PyObject_SetAttrString(self, "args", subslice))
467 goto finally;
468
469 case 2:
470 /* common case: PyErr_SetFromErrno() */
471 item0 = PySequence_GetItem(args, 0);
472 item1 = PySequence_GetItem(args, 1);
473 if (!item0 || !item1)
474 goto finally;
475
476 if (PyObject_SetAttrString(self, "errno", item0) ||
477 PyObject_SetAttrString(self, "strerror", item1))
478 {
479 goto finally;
480 }
481 }
482
483 Py_INCREF(Py_None);
484 rtnval = Py_None;
485
486 finally:
487 Py_DECREF(args);
488 Py_XDECREF(item0);
489 Py_XDECREF(item1);
490 Py_XDECREF(item2);
491 Py_XDECREF(subslice);
492 return rtnval;
493}
494
495
496static PyObject*
497EnvironmentError__str__(PyObject* self, PyObject* args)
498{
499 PyObject* originalself = self;
500 PyObject* filename;
501 PyObject* serrno;
502 PyObject* strerror;
503 PyObject* rtnval = NULL;
504
505 if (!PyArg_ParseTuple(args, "O", &self))
506 return NULL;
507
508 filename = PyObject_GetAttrString(self, "filename");
509 serrno = PyObject_GetAttrString(self, "errno");
510 strerror = PyObject_GetAttrString(self, "strerror");
511 if (!filename || !serrno || !strerror)
512 goto finally;
513
514 if (filename != Py_None) {
515 PyObject* fmt = PyString_FromString("[Errno %s] %s: %s");
516 PyObject* repr = PyObject_Repr(filename);
517 PyObject* tuple = PyTuple_New(3);
518
519 if (!fmt || !repr || !tuple) {
520 Py_XDECREF(fmt);
521 Py_XDECREF(repr);
522 Py_XDECREF(tuple);
523 goto finally;
524 }
525
526 PyTuple_SET_ITEM(tuple, 0, serrno);
527 PyTuple_SET_ITEM(tuple, 1, strerror);
528 PyTuple_SET_ITEM(tuple, 2, repr);
529
530 rtnval = PyString_Format(fmt, tuple);
531
532 Py_DECREF(fmt);
533 Py_DECREF(tuple);
534 /* already freed because tuple owned only reference */
535 serrno = NULL;
536 strerror = NULL;
537 }
538 else if (PyObject_IsTrue(serrno) && PyObject_IsTrue(strerror)) {
539 PyObject* fmt = PyString_FromString("[Errno %s] %s");
540 PyObject* tuple = PyTuple_New(2);
541
542 if (!fmt || !tuple) {
543 Py_XDECREF(fmt);
544 Py_XDECREF(tuple);
545 goto finally;
546 }
547
548 PyTuple_SET_ITEM(tuple, 0, serrno);
549 PyTuple_SET_ITEM(tuple, 1, strerror);
550
551 rtnval = PyString_Format(fmt, tuple);
552
553 Py_DECREF(fmt);
554 Py_DECREF(tuple);
555 /* already freed because tuple owned only reference */
556 serrno = NULL;
557 strerror = NULL;
558 }
559 else
560 /* The original Python code said:
561 *
562 * return StandardError.__str__(self)
563 *
564 * but there is no StandardError__str__() function; we happen to
565 * know that's just a pass through to Exception__str__().
566 */
567 rtnval = Exception__str__(originalself, args);
568
569 finally:
570 Py_XDECREF(filename);
571 Py_XDECREF(serrno);
572 Py_XDECREF(strerror);
573 return rtnval;
574}
575
576
577static
578PyMethodDef EnvironmentError_methods[] = {
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000579 {"__init__", EnvironmentError__init__, METH_VARARGS},
580 {"__str__", EnvironmentError__str__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000581 {NULL, NULL}
582};
583
584
585
586
587static char
588IOError__doc__[] = "I/O operation failed.";
589
590static char
591OSError__doc__[] = "OS system call failed.";
592
593#ifdef MS_WINDOWS
594static char
595WindowsError__doc__[] = "MS-Windows OS system call failed.";
596#endif /* MS_WINDOWS */
597
598static char
599EOFError__doc__[] = "Read beyond end of file.";
600
601static char
602RuntimeError__doc__[] = "Unspecified run-time error.";
603
604static char
605NotImplementedError__doc__[] =
606"Method or function hasn't been implemented yet.";
607
608static char
609NameError__doc__[] = "Name not found globally.";
610
611static char
612UnboundLocalError__doc__[] =
613"Local name referenced but not bound to a value.";
614
615static char
616AttributeError__doc__[] = "Attribute not found.";
617
618
619
620static char
621SyntaxError__doc__[] = "Invalid syntax.";
622
623
624static int
625SyntaxError__classinit__(PyObject* klass)
626{
627 PyObject* emptystring = PyString_FromString("");
628
629 /* Additional class-creation time initializations */
630 if (!emptystring ||
631 PyObject_SetAttrString(klass, "msg", emptystring) ||
632 PyObject_SetAttrString(klass, "filename", Py_None) ||
633 PyObject_SetAttrString(klass, "lineno", Py_None) ||
634 PyObject_SetAttrString(klass, "offset", Py_None) ||
635 PyObject_SetAttrString(klass, "text", Py_None))
636 {
637 Py_XDECREF(emptystring);
638 return -1;
639 }
640 Py_DECREF(emptystring);
641 return 0;
642}
643
644
645static PyObject*
646SyntaxError__init__(PyObject* self, PyObject* args)
647{
648 PyObject* rtnval = NULL;
649 int lenargs;
650
651 if (!(self = get_self(args)))
652 return NULL;
653
654 if (!(args = PySequence_GetSlice(args, 1, PySequence_Length(args))))
655 return NULL;
656
657 if (PyObject_SetAttrString(self, "args", args))
658 goto finally;
659
660 lenargs = PySequence_Length(args);
661 if (lenargs >= 1) {
662 PyObject* item0 = PySequence_GetItem(args, 0);
663 int status;
664
665 if (!item0)
666 goto finally;
667 status = PyObject_SetAttrString(self, "msg", item0);
668 Py_DECREF(item0);
669 if (status)
670 goto finally;
671 }
672 if (lenargs == 2) {
673 PyObject* info = PySequence_GetItem(args, 1);
674 PyObject *filename, *lineno, *offset, *text;
675 int status = 1;
676
677 if (!info)
678 goto finally;
679
680 filename = PySequence_GetItem(info, 0);
681 lineno = PySequence_GetItem(info, 1);
682 offset = PySequence_GetItem(info, 2);
683 text = PySequence_GetItem(info, 3);
684
685 Py_DECREF(info);
686
687 if (filename && lineno && offset && text) {
688 status = PyObject_SetAttrString(self, "filename", filename) ||
689 PyObject_SetAttrString(self, "lineno", lineno) ||
690 PyObject_SetAttrString(self, "offset", offset) ||
691 PyObject_SetAttrString(self, "text", text);
692 }
693 Py_XDECREF(filename);
694 Py_XDECREF(lineno);
695 Py_XDECREF(offset);
696 Py_XDECREF(text);
697
698 if (status)
699 goto finally;
700 }
701 Py_INCREF(Py_None);
702 rtnval = Py_None;
703
704 finally:
705 Py_DECREF(args);
706 return rtnval;
707}
708
709
710static PyObject*
711SyntaxError__str__(PyObject* self, PyObject* args)
712{
713 PyObject* msg;
714 PyObject* str;
715
716 if (!PyArg_ParseTuple(args, "O", &self))
717 return NULL;
718
719 if (!(msg = PyObject_GetAttrString(self, "msg")))
720 return NULL;
721
722 str = PyObject_Str(msg);
723 Py_DECREF(msg);
724 return str;
725}
726
727
728PyMethodDef SyntaxError_methods[] = {
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000729 {"__init__", SyntaxError__init__, METH_VARARGS},
730 {"__str__", SyntaxError__str__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000731 {NULL, NULL}
732};
733
734
735
736static char
737AssertionError__doc__[] = "Assertion failed.";
738
739static char
740LookupError__doc__[] = "Base class for lookup errors.";
741
742static char
743IndexError__doc__[] = "Sequence index out of range.";
744
745static char
746KeyError__doc__[] = "Mapping key not found.";
747
748static char
749ArithmeticError__doc__[] = "Base class for arithmetic errors.";
750
751static char
752OverflowError__doc__[] = "Result too large to be represented.";
753
754static char
755ZeroDivisionError__doc__[] =
756"Second argument to a division or modulo operation was zero.";
757
758static char
759FloatingPointError__doc__[] = "Floating point operation failed.";
760
761static char
762ValueError__doc__[] = "Inappropriate argument value (of correct type).";
763
764static char
765UnicodeError__doc__[] = "Unicode related error.";
766
767static char
768SystemError__doc__[] = "Internal error in the Python interpreter.\n\
769\n\
770Please report this to the Python maintainer, along with the traceback,\n\
771the Python version, and the hardware/OS platform and version.";
772
773static char
774MemoryError__doc__[] = "Out of memory.";
775
776
777
778/* module global functions */
779static PyMethodDef functions[] = {
780 /* Sentinel */
781 {NULL, NULL}
782};
783
784
785
786/* Global C API defined exceptions */
787
788PyObject *PyExc_Exception;
789PyObject *PyExc_StandardError;
790PyObject *PyExc_ArithmeticError;
791PyObject *PyExc_LookupError;
792
793PyObject *PyExc_AssertionError;
794PyObject *PyExc_AttributeError;
795PyObject *PyExc_EOFError;
796PyObject *PyExc_FloatingPointError;
797PyObject *PyExc_EnvironmentError;
798PyObject *PyExc_IOError;
799PyObject *PyExc_OSError;
800PyObject *PyExc_ImportError;
801PyObject *PyExc_IndexError;
802PyObject *PyExc_KeyError;
803PyObject *PyExc_KeyboardInterrupt;
804PyObject *PyExc_MemoryError;
805PyObject *PyExc_NameError;
806PyObject *PyExc_OverflowError;
807PyObject *PyExc_RuntimeError;
808PyObject *PyExc_NotImplementedError;
809PyObject *PyExc_SyntaxError;
810PyObject *PyExc_SystemError;
811PyObject *PyExc_SystemExit;
812PyObject *PyExc_UnboundLocalError;
813PyObject *PyExc_UnicodeError;
814PyObject *PyExc_TypeError;
815PyObject *PyExc_ValueError;
816PyObject *PyExc_ZeroDivisionError;
817#ifdef MS_WINDOWS
818PyObject *PyExc_WindowsError;
819#endif
820
821/* Pre-computed MemoryError instance. Best to create this as early as
822 * possibly and not wait until a MemoryError is actually raised!
823 */
824PyObject *PyExc_MemoryErrorInst;
825
826
827
828/* mapping between exception names and their PyObject** */
829static struct
830{
831 char* name;
832 PyObject** exc;
833 PyObject** base; /* NULL == PyExc_StandardError */
834 char* docstr;
835 PyMethodDef* methods;
836 int (*classinit)(PyObject*);
837}
838exctable[] = {
839 /*
840 * The first three classes MUST appear in exactly this order
841 */
842 {"Exception", &PyExc_Exception},
843 {"StandardError", &PyExc_StandardError, &PyExc_Exception,
844 StandardError__doc__},
845 {"TypeError", &PyExc_TypeError, 0, TypeError__doc__},
846 /*
847 * The rest appear in depth-first order of the hierarchy
848 */
849 {"SystemExit", &PyExc_SystemExit, &PyExc_Exception, SystemExit__doc__,
850 SystemExit_methods},
851 {"KeyboardInterrupt", &PyExc_KeyboardInterrupt, 0, KeyboardInterrupt__doc__},
852 {"ImportError", &PyExc_ImportError, 0, ImportError__doc__},
853 {"EnvironmentError", &PyExc_EnvironmentError, 0, EnvironmentError__doc__,
854 EnvironmentError_methods},
855 {"IOError", &PyExc_IOError, &PyExc_EnvironmentError, IOError__doc__},
856 {"OSError", &PyExc_OSError, &PyExc_EnvironmentError, OSError__doc__},
857#ifdef MS_WINDOWS
858 {"WindowsError", &PyExc_WindowsError, &PyExc_EnvironmentError,
859 WindowsError__doc__},
860#endif /* MS_WINDOWS */
861 {"EOFError", &PyExc_EOFError, 0, EOFError__doc__},
862 {"RuntimeError", &PyExc_RuntimeError, 0, RuntimeError__doc__},
863 {"NotImplementedError", &PyExc_NotImplementedError,
864 &PyExc_RuntimeError, NotImplementedError__doc__},
865 {"NameError", &PyExc_NameError, 0, NameError__doc__},
866 {"UnboundLocalError", &PyExc_UnboundLocalError, &PyExc_NameError,
867 UnboundLocalError__doc__},
868 {"AttributeError", &PyExc_AttributeError, 0, AttributeError__doc__},
869 {"SyntaxError", &PyExc_SyntaxError, 0, SyntaxError__doc__,
870 SyntaxError_methods, SyntaxError__classinit__},
871 {"AssertionError", &PyExc_AssertionError, 0, AssertionError__doc__},
872 {"LookupError", &PyExc_LookupError, 0, LookupError__doc__},
873 {"IndexError", &PyExc_IndexError, &PyExc_LookupError,
874 IndexError__doc__},
875 {"KeyError", &PyExc_KeyError, &PyExc_LookupError,
876 KeyError__doc__},
877 {"ArithmeticError", &PyExc_ArithmeticError, 0, ArithmeticError__doc__},
878 {"OverflowError", &PyExc_OverflowError, &PyExc_ArithmeticError,
879 OverflowError__doc__},
880 {"ZeroDivisionError", &PyExc_ZeroDivisionError, &PyExc_ArithmeticError,
881 ZeroDivisionError__doc__},
882 {"FloatingPointError", &PyExc_FloatingPointError, &PyExc_ArithmeticError,
883 FloatingPointError__doc__},
884 {"ValueError", &PyExc_ValueError, 0, ValueError__doc__},
885 {"UnicodeError", &PyExc_UnicodeError, &PyExc_ValueError, UnicodeError__doc__},
886 {"SystemError", &PyExc_SystemError, 0, SystemError__doc__},
887 {"MemoryError", &PyExc_MemoryError, 0, MemoryError__doc__},
888 /* Sentinel */
889 {NULL}
890};
891
892
893
894void
895#ifdef WIN32
896__declspec(dllexport)
897#endif /* WIN32 */
898init_exceptions()
899{
900 char* modulename = "exceptions";
901 int modnamesz = strlen(modulename);
902 int i;
903
904 PyObject* me = Py_InitModule(modulename, functions);
905 PyObject* mydict = PyModule_GetDict(me);
906 PyObject* bltinmod = PyImport_ImportModule("__builtin__");
907 PyObject* bdict = PyModule_GetDict(bltinmod);
908 PyObject* doc = PyString_FromString(module__doc__);
909 PyObject* args;
910
911 PyDict_SetItemString(mydict, "__doc__", doc);
Barry Warsaw8fcaa922000-07-01 04:45:52 +0000912 Py_DECREF(doc);
Barry Warsaw675ac282000-05-26 19:05:16 +0000913 if (PyErr_Occurred())
914 Py_FatalError("exceptions bootstrapping error.");
915
916 /* This is the base class of all exceptions, so make it first. */
917 if (make_Exception(modulename) ||
918 PyDict_SetItemString(mydict, "Exception", PyExc_Exception) ||
919 PyDict_SetItemString(bdict, "Exception", PyExc_Exception))
920 {
921 Py_FatalError("Base class `Exception' could not be created.");
922 }
923
924 /* Now we can programmatically create all the remaining exceptions.
925 * Remember to start the loop at 1 to skip Exceptions.
926 */
927 for (i=1; exctable[i].name; i++) {
928 int status;
929 char* cname = PyMem_NEW(char, modnamesz+strlen(exctable[i].name)+2);
930 PyObject* base;
931
932 (void)strcpy(cname, modulename);
933 (void)strcat(cname, ".");
934 (void)strcat(cname, exctable[i].name);
935
936 if (exctable[i].base == 0)
937 base = PyExc_StandardError;
938 else
939 base = *exctable[i].base;
940
941 status = make_class(exctable[i].exc, base, cname,
942 exctable[i].methods,
943 exctable[i].docstr);
944
945 PyMem_DEL(cname);
946
947 if (status)
948 Py_FatalError("Standard exception classes could not be created.");
949
950 if (exctable[i].classinit) {
951 status = (*exctable[i].classinit)(*exctable[i].exc);
952 if (status)
953 Py_FatalError("An exception class could not be initialized.");
954 }
955
956 /* Now insert the class into both this module and the __builtin__
957 * module.
958 */
959 if (PyDict_SetItemString(mydict, exctable[i].name, *exctable[i].exc) ||
960 PyDict_SetItemString(bdict, exctable[i].name, *exctable[i].exc))
961 {
962 Py_FatalError("Module dictionary insertion problem.");
963 }
964 }
965
966 /* Now we need to pre-allocate a MemoryError instance */
967 args = Py_BuildValue("()");
968 if (!args ||
969 !(PyExc_MemoryErrorInst = PyEval_CallObject(PyExc_MemoryError, args)))
970 {
971 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
972 }
973 Py_DECREF(args);
974
975 /* We're done with __builtin__ */
976 Py_DECREF(bltinmod);
977}
978
979
980void
981#ifdef WIN32
982__declspec(dllexport)
983#endif /* WIN32 */
984fini_exceptions()
985{
986 int i;
987
988 Py_XDECREF(PyExc_MemoryErrorInst);
989 PyExc_MemoryErrorInst = NULL;
990
991 for (i=0; exctable[i].name; i++) {
992 Py_XDECREF(*exctable[i].exc);
993 *exctable[i].exc = NULL;
994 }
995}