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