blob: c32e15ccbc5d6a661d8193f85e0946bf15e4bf2c [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:
Barry Warsaw7dfeb422000-07-09 04:56:25 +0000443 /* Where a function has a single filename, such as open() or some
444 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
445 * called, giving a third argument which is the filename. But, so
446 * that old code using in-place unpacking doesn't break, e.g.:
Barry Warsaw675ac282000-05-26 19:05:16 +0000447 *
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;
Barry Warsaw7dfeb422000-07-09 04:56:25 +0000470 break;
Barry Warsaw675ac282000-05-26 19:05:16 +0000471
472 case 2:
Barry Warsaw7dfeb422000-07-09 04:56:25 +0000473 /* Used when PyErr_SetFromErrno() is called and no filename
474 * argument is given.
475 */
Barry Warsaw675ac282000-05-26 19:05:16 +0000476 item0 = PySequence_GetItem(args, 0);
477 item1 = PySequence_GetItem(args, 1);
478 if (!item0 || !item1)
479 goto finally;
480
481 if (PyObject_SetAttrString(self, "errno", item0) ||
482 PyObject_SetAttrString(self, "strerror", item1))
483 {
484 goto finally;
485 }
Barry Warsaw7dfeb422000-07-09 04:56:25 +0000486 break;
Barry Warsaw675ac282000-05-26 19:05:16 +0000487 }
488
489 Py_INCREF(Py_None);
490 rtnval = Py_None;
491
492 finally:
493 Py_DECREF(args);
494 Py_XDECREF(item0);
495 Py_XDECREF(item1);
496 Py_XDECREF(item2);
497 Py_XDECREF(subslice);
498 return rtnval;
499}
500
501
502static PyObject*
503EnvironmentError__str__(PyObject* self, PyObject* args)
504{
505 PyObject* originalself = self;
506 PyObject* filename;
507 PyObject* serrno;
508 PyObject* strerror;
509 PyObject* rtnval = NULL;
510
511 if (!PyArg_ParseTuple(args, "O", &self))
512 return NULL;
513
514 filename = PyObject_GetAttrString(self, "filename");
515 serrno = PyObject_GetAttrString(self, "errno");
516 strerror = PyObject_GetAttrString(self, "strerror");
517 if (!filename || !serrno || !strerror)
518 goto finally;
519
520 if (filename != Py_None) {
521 PyObject* fmt = PyString_FromString("[Errno %s] %s: %s");
522 PyObject* repr = PyObject_Repr(filename);
523 PyObject* tuple = PyTuple_New(3);
524
525 if (!fmt || !repr || !tuple) {
526 Py_XDECREF(fmt);
527 Py_XDECREF(repr);
528 Py_XDECREF(tuple);
529 goto finally;
530 }
531
532 PyTuple_SET_ITEM(tuple, 0, serrno);
533 PyTuple_SET_ITEM(tuple, 1, strerror);
534 PyTuple_SET_ITEM(tuple, 2, repr);
535
536 rtnval = PyString_Format(fmt, tuple);
537
538 Py_DECREF(fmt);
539 Py_DECREF(tuple);
540 /* already freed because tuple owned only reference */
541 serrno = NULL;
542 strerror = NULL;
543 }
544 else if (PyObject_IsTrue(serrno) && PyObject_IsTrue(strerror)) {
545 PyObject* fmt = PyString_FromString("[Errno %s] %s");
546 PyObject* tuple = PyTuple_New(2);
547
548 if (!fmt || !tuple) {
549 Py_XDECREF(fmt);
550 Py_XDECREF(tuple);
551 goto finally;
552 }
553
554 PyTuple_SET_ITEM(tuple, 0, serrno);
555 PyTuple_SET_ITEM(tuple, 1, strerror);
556
557 rtnval = PyString_Format(fmt, tuple);
558
559 Py_DECREF(fmt);
560 Py_DECREF(tuple);
561 /* already freed because tuple owned only reference */
562 serrno = NULL;
563 strerror = NULL;
564 }
565 else
566 /* The original Python code said:
567 *
568 * return StandardError.__str__(self)
569 *
570 * but there is no StandardError__str__() function; we happen to
571 * know that's just a pass through to Exception__str__().
572 */
573 rtnval = Exception__str__(originalself, args);
574
575 finally:
576 Py_XDECREF(filename);
577 Py_XDECREF(serrno);
578 Py_XDECREF(strerror);
579 return rtnval;
580}
581
582
583static
584PyMethodDef EnvironmentError_methods[] = {
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000585 {"__init__", EnvironmentError__init__, METH_VARARGS},
586 {"__str__", EnvironmentError__str__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000587 {NULL, NULL}
588};
589
590
591
592
593static char
594IOError__doc__[] = "I/O operation failed.";
595
596static char
597OSError__doc__[] = "OS system call failed.";
598
599#ifdef MS_WINDOWS
600static char
601WindowsError__doc__[] = "MS-Windows OS system call failed.";
602#endif /* MS_WINDOWS */
603
604static char
605EOFError__doc__[] = "Read beyond end of file.";
606
607static char
608RuntimeError__doc__[] = "Unspecified run-time error.";
609
610static char
611NotImplementedError__doc__[] =
612"Method or function hasn't been implemented yet.";
613
614static char
615NameError__doc__[] = "Name not found globally.";
616
617static char
618UnboundLocalError__doc__[] =
619"Local name referenced but not bound to a value.";
620
621static char
622AttributeError__doc__[] = "Attribute not found.";
623
624
625
626static char
627SyntaxError__doc__[] = "Invalid syntax.";
628
629
630static int
631SyntaxError__classinit__(PyObject* klass)
632{
633 PyObject* emptystring = PyString_FromString("");
634
635 /* Additional class-creation time initializations */
636 if (!emptystring ||
637 PyObject_SetAttrString(klass, "msg", emptystring) ||
638 PyObject_SetAttrString(klass, "filename", Py_None) ||
639 PyObject_SetAttrString(klass, "lineno", Py_None) ||
640 PyObject_SetAttrString(klass, "offset", Py_None) ||
641 PyObject_SetAttrString(klass, "text", Py_None))
642 {
643 Py_XDECREF(emptystring);
644 return -1;
645 }
646 Py_DECREF(emptystring);
647 return 0;
648}
649
650
651static PyObject*
652SyntaxError__init__(PyObject* self, PyObject* args)
653{
654 PyObject* rtnval = NULL;
655 int lenargs;
656
657 if (!(self = get_self(args)))
658 return NULL;
659
660 if (!(args = PySequence_GetSlice(args, 1, PySequence_Length(args))))
661 return NULL;
662
663 if (PyObject_SetAttrString(self, "args", args))
664 goto finally;
665
666 lenargs = PySequence_Length(args);
667 if (lenargs >= 1) {
668 PyObject* item0 = PySequence_GetItem(args, 0);
669 int status;
670
671 if (!item0)
672 goto finally;
673 status = PyObject_SetAttrString(self, "msg", item0);
674 Py_DECREF(item0);
675 if (status)
676 goto finally;
677 }
678 if (lenargs == 2) {
679 PyObject* info = PySequence_GetItem(args, 1);
680 PyObject *filename, *lineno, *offset, *text;
681 int status = 1;
682
683 if (!info)
684 goto finally;
685
686 filename = PySequence_GetItem(info, 0);
687 lineno = PySequence_GetItem(info, 1);
688 offset = PySequence_GetItem(info, 2);
689 text = PySequence_GetItem(info, 3);
690
691 Py_DECREF(info);
692
693 if (filename && lineno && offset && text) {
694 status = PyObject_SetAttrString(self, "filename", filename) ||
695 PyObject_SetAttrString(self, "lineno", lineno) ||
696 PyObject_SetAttrString(self, "offset", offset) ||
697 PyObject_SetAttrString(self, "text", text);
698 }
699 Py_XDECREF(filename);
700 Py_XDECREF(lineno);
701 Py_XDECREF(offset);
702 Py_XDECREF(text);
703
704 if (status)
705 goto finally;
706 }
707 Py_INCREF(Py_None);
708 rtnval = Py_None;
709
710 finally:
711 Py_DECREF(args);
712 return rtnval;
713}
714
715
716static PyObject*
717SyntaxError__str__(PyObject* self, PyObject* args)
718{
719 PyObject* msg;
720 PyObject* str;
721
722 if (!PyArg_ParseTuple(args, "O", &self))
723 return NULL;
724
725 if (!(msg = PyObject_GetAttrString(self, "msg")))
726 return NULL;
727
728 str = PyObject_Str(msg);
729 Py_DECREF(msg);
730 return str;
731}
732
733
734PyMethodDef SyntaxError_methods[] = {
Jeremy Hylton4e542a32000-06-30 04:59:59 +0000735 {"__init__", SyntaxError__init__, METH_VARARGS},
736 {"__str__", SyntaxError__str__, METH_VARARGS},
Barry Warsaw675ac282000-05-26 19:05:16 +0000737 {NULL, NULL}
738};
739
740
741
742static char
743AssertionError__doc__[] = "Assertion failed.";
744
745static char
746LookupError__doc__[] = "Base class for lookup errors.";
747
748static char
749IndexError__doc__[] = "Sequence index out of range.";
750
751static char
752KeyError__doc__[] = "Mapping key not found.";
753
754static char
755ArithmeticError__doc__[] = "Base class for arithmetic errors.";
756
757static char
758OverflowError__doc__[] = "Result too large to be represented.";
759
760static char
761ZeroDivisionError__doc__[] =
762"Second argument to a division or modulo operation was zero.";
763
764static char
765FloatingPointError__doc__[] = "Floating point operation failed.";
766
767static char
768ValueError__doc__[] = "Inappropriate argument value (of correct type).";
769
770static char
771UnicodeError__doc__[] = "Unicode related error.";
772
773static char
774SystemError__doc__[] = "Internal error in the Python interpreter.\n\
775\n\
776Please report this to the Python maintainer, along with the traceback,\n\
777the Python version, and the hardware/OS platform and version.";
778
779static char
780MemoryError__doc__[] = "Out of memory.";
781
782
783
784/* module global functions */
785static PyMethodDef functions[] = {
786 /* Sentinel */
787 {NULL, NULL}
788};
789
790
791
792/* Global C API defined exceptions */
793
794PyObject *PyExc_Exception;
795PyObject *PyExc_StandardError;
796PyObject *PyExc_ArithmeticError;
797PyObject *PyExc_LookupError;
798
799PyObject *PyExc_AssertionError;
800PyObject *PyExc_AttributeError;
801PyObject *PyExc_EOFError;
802PyObject *PyExc_FloatingPointError;
803PyObject *PyExc_EnvironmentError;
804PyObject *PyExc_IOError;
805PyObject *PyExc_OSError;
806PyObject *PyExc_ImportError;
807PyObject *PyExc_IndexError;
808PyObject *PyExc_KeyError;
809PyObject *PyExc_KeyboardInterrupt;
810PyObject *PyExc_MemoryError;
811PyObject *PyExc_NameError;
812PyObject *PyExc_OverflowError;
813PyObject *PyExc_RuntimeError;
814PyObject *PyExc_NotImplementedError;
815PyObject *PyExc_SyntaxError;
816PyObject *PyExc_SystemError;
817PyObject *PyExc_SystemExit;
818PyObject *PyExc_UnboundLocalError;
819PyObject *PyExc_UnicodeError;
820PyObject *PyExc_TypeError;
821PyObject *PyExc_ValueError;
822PyObject *PyExc_ZeroDivisionError;
823#ifdef MS_WINDOWS
824PyObject *PyExc_WindowsError;
825#endif
826
827/* Pre-computed MemoryError instance. Best to create this as early as
828 * possibly and not wait until a MemoryError is actually raised!
829 */
830PyObject *PyExc_MemoryErrorInst;
831
832
833
834/* mapping between exception names and their PyObject** */
835static struct
836{
837 char* name;
838 PyObject** exc;
839 PyObject** base; /* NULL == PyExc_StandardError */
840 char* docstr;
841 PyMethodDef* methods;
842 int (*classinit)(PyObject*);
843}
844exctable[] = {
845 /*
846 * The first three classes MUST appear in exactly this order
847 */
848 {"Exception", &PyExc_Exception},
849 {"StandardError", &PyExc_StandardError, &PyExc_Exception,
850 StandardError__doc__},
851 {"TypeError", &PyExc_TypeError, 0, TypeError__doc__},
852 /*
853 * The rest appear in depth-first order of the hierarchy
854 */
855 {"SystemExit", &PyExc_SystemExit, &PyExc_Exception, SystemExit__doc__,
856 SystemExit_methods},
857 {"KeyboardInterrupt", &PyExc_KeyboardInterrupt, 0, KeyboardInterrupt__doc__},
858 {"ImportError", &PyExc_ImportError, 0, ImportError__doc__},
859 {"EnvironmentError", &PyExc_EnvironmentError, 0, EnvironmentError__doc__,
860 EnvironmentError_methods},
861 {"IOError", &PyExc_IOError, &PyExc_EnvironmentError, IOError__doc__},
862 {"OSError", &PyExc_OSError, &PyExc_EnvironmentError, OSError__doc__},
863#ifdef MS_WINDOWS
864 {"WindowsError", &PyExc_WindowsError, &PyExc_EnvironmentError,
865 WindowsError__doc__},
866#endif /* MS_WINDOWS */
867 {"EOFError", &PyExc_EOFError, 0, EOFError__doc__},
868 {"RuntimeError", &PyExc_RuntimeError, 0, RuntimeError__doc__},
869 {"NotImplementedError", &PyExc_NotImplementedError,
870 &PyExc_RuntimeError, NotImplementedError__doc__},
871 {"NameError", &PyExc_NameError, 0, NameError__doc__},
872 {"UnboundLocalError", &PyExc_UnboundLocalError, &PyExc_NameError,
873 UnboundLocalError__doc__},
874 {"AttributeError", &PyExc_AttributeError, 0, AttributeError__doc__},
875 {"SyntaxError", &PyExc_SyntaxError, 0, SyntaxError__doc__,
876 SyntaxError_methods, SyntaxError__classinit__},
877 {"AssertionError", &PyExc_AssertionError, 0, AssertionError__doc__},
878 {"LookupError", &PyExc_LookupError, 0, LookupError__doc__},
879 {"IndexError", &PyExc_IndexError, &PyExc_LookupError,
880 IndexError__doc__},
881 {"KeyError", &PyExc_KeyError, &PyExc_LookupError,
882 KeyError__doc__},
883 {"ArithmeticError", &PyExc_ArithmeticError, 0, ArithmeticError__doc__},
884 {"OverflowError", &PyExc_OverflowError, &PyExc_ArithmeticError,
885 OverflowError__doc__},
886 {"ZeroDivisionError", &PyExc_ZeroDivisionError, &PyExc_ArithmeticError,
887 ZeroDivisionError__doc__},
888 {"FloatingPointError", &PyExc_FloatingPointError, &PyExc_ArithmeticError,
889 FloatingPointError__doc__},
890 {"ValueError", &PyExc_ValueError, 0, ValueError__doc__},
891 {"UnicodeError", &PyExc_UnicodeError, &PyExc_ValueError, UnicodeError__doc__},
892 {"SystemError", &PyExc_SystemError, 0, SystemError__doc__},
893 {"MemoryError", &PyExc_MemoryError, 0, MemoryError__doc__},
894 /* Sentinel */
895 {NULL}
896};
897
898
899
900void
901#ifdef WIN32
902__declspec(dllexport)
903#endif /* WIN32 */
904init_exceptions()
905{
906 char* modulename = "exceptions";
907 int modnamesz = strlen(modulename);
908 int i;
909
910 PyObject* me = Py_InitModule(modulename, functions);
911 PyObject* mydict = PyModule_GetDict(me);
912 PyObject* bltinmod = PyImport_ImportModule("__builtin__");
913 PyObject* bdict = PyModule_GetDict(bltinmod);
914 PyObject* doc = PyString_FromString(module__doc__);
915 PyObject* args;
916
917 PyDict_SetItemString(mydict, "__doc__", doc);
Barry Warsaw8fcaa922000-07-01 04:45:52 +0000918 Py_DECREF(doc);
Barry Warsaw675ac282000-05-26 19:05:16 +0000919 if (PyErr_Occurred())
920 Py_FatalError("exceptions bootstrapping error.");
921
922 /* This is the base class of all exceptions, so make it first. */
923 if (make_Exception(modulename) ||
924 PyDict_SetItemString(mydict, "Exception", PyExc_Exception) ||
925 PyDict_SetItemString(bdict, "Exception", PyExc_Exception))
926 {
927 Py_FatalError("Base class `Exception' could not be created.");
928 }
929
930 /* Now we can programmatically create all the remaining exceptions.
931 * Remember to start the loop at 1 to skip Exceptions.
932 */
933 for (i=1; exctable[i].name; i++) {
934 int status;
935 char* cname = PyMem_NEW(char, modnamesz+strlen(exctable[i].name)+2);
936 PyObject* base;
937
938 (void)strcpy(cname, modulename);
939 (void)strcat(cname, ".");
940 (void)strcat(cname, exctable[i].name);
941
942 if (exctable[i].base == 0)
943 base = PyExc_StandardError;
944 else
945 base = *exctable[i].base;
946
947 status = make_class(exctable[i].exc, base, cname,
948 exctable[i].methods,
949 exctable[i].docstr);
950
951 PyMem_DEL(cname);
952
953 if (status)
954 Py_FatalError("Standard exception classes could not be created.");
955
956 if (exctable[i].classinit) {
957 status = (*exctable[i].classinit)(*exctable[i].exc);
958 if (status)
959 Py_FatalError("An exception class could not be initialized.");
960 }
961
962 /* Now insert the class into both this module and the __builtin__
963 * module.
964 */
965 if (PyDict_SetItemString(mydict, exctable[i].name, *exctable[i].exc) ||
966 PyDict_SetItemString(bdict, exctable[i].name, *exctable[i].exc))
967 {
968 Py_FatalError("Module dictionary insertion problem.");
969 }
970 }
971
972 /* Now we need to pre-allocate a MemoryError instance */
973 args = Py_BuildValue("()");
974 if (!args ||
975 !(PyExc_MemoryErrorInst = PyEval_CallObject(PyExc_MemoryError, args)))
976 {
977 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
978 }
979 Py_DECREF(args);
980
981 /* We're done with __builtin__ */
982 Py_DECREF(bltinmod);
983}
984
985
986void
987#ifdef WIN32
988__declspec(dllexport)
989#endif /* WIN32 */
990fini_exceptions()
991{
992 int i;
993
994 Py_XDECREF(PyExc_MemoryErrorInst);
995 PyExc_MemoryErrorInst = NULL;
996
997 for (i=0; exctable[i].name; i++) {
998 Py_XDECREF(*exctable[i].exc);
999 *exctable[i].exc = NULL;
1000 }
1001}