summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>1997-08-29 22:13:51 (GMT)
committerBarry Warsaw <barry@python.org>1997-08-29 22:13:51 (GMT)
commit757af0e7bb7c7d56670fbc84f1f5b0182a54e3d5 (patch)
tree3e498ed3ff9aa2e2c38f4d50238d7f1488d59e6b
parent035574d755bfc306704e9975dc10e4e05a47b3bb (diff)
downloadcpython-757af0e7bb7c7d56670fbc84f1f5b0182a54e3d5.zip
cpython-757af0e7bb7c7d56670fbc84f1f5b0182a54e3d5.tar.gz
cpython-757af0e7bb7c7d56670fbc84f1f5b0182a54e3d5.tar.bz2
Removed obsolete exception PyExc_AccessError.
Added PyErr_MemoryErrorInst to hold the pre-instantiated instance when using class based exceptions. Simplified the creation of all built-in exceptions, both class based and string based. Actually, for class based exceptions, the string ones are still created just in case there's a problem creating the class based ones (so you still get *some* exception handling!). Now the init and fini functions run through a list of structure elements, creating the strings (and optionally classes) for every entry. initerrors(): the new base class exceptions StandardError, LookupError, and NumberError are initialized when using string exceptions, to tuples containing the list of derived string exceptions. This GvR trick enables forward compatibility! One bit of nastiness is that the C code has to know the inheritance tree embodied in exceptions.py. Added the two phase init and fini functions.
-rw-r--r--Python/bltinmodule.c214
1 files changed, 171 insertions, 43 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index a89b3fc..358b6f1 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1724,7 +1724,10 @@ static PyMethodDef builtin_methods[] = {
/* Predefined exceptions */
-PyObject *PyExc_AccessError;
+PyObject *PyExc_StandardError;
+PyObject *PyExc_NumberError;
+PyObject *PyExc_LookupError;
+
PyObject *PyExc_AssertionError;
PyObject *PyExc_AttributeError;
PyObject *PyExc_EOFError;
@@ -1745,6 +1748,108 @@ PyObject *PyExc_TypeError;
PyObject *PyExc_ValueError;
PyObject *PyExc_ZeroDivisionError;
+PyObject *PyExc_MemoryErrorInst;
+
+static struct
+{
+ char* name;
+ PyObject** exc;
+ int leaf_exc;
+}
+bltin_exc[] = {
+ {"StandardError", &PyExc_StandardError, 0},
+ {"NumberError", &PyExc_NumberError, 0},
+ {"LookupError", &PyExc_LookupError, 0},
+ {"AssertionError", &PyExc_AssertionError, 1},
+ {"AttributeError", &PyExc_AttributeError, 1},
+ {"EOFError", &PyExc_EOFError, 1},
+ {"FloatingPointError", &PyExc_FloatingPointError, 1},
+ {"IOError", &PyExc_IOError, 1},
+ {"ImportError", &PyExc_ImportError, 1},
+ {"IndexError", &PyExc_IndexError, 1},
+ {"KeyError", &PyExc_KeyError, 1},
+ {"KeyboardInterrupt", &PyExc_KeyboardInterrupt, 1},
+ {"MemoryError", &PyExc_MemoryError, 1},
+ {"NameError", &PyExc_NameError, 1},
+ {"OverflowError", &PyExc_OverflowError, 1},
+ {"RuntimeError", &PyExc_RuntimeError, 1},
+ {"SyntaxError", &PyExc_SyntaxError, 1},
+ {"SystemError", &PyExc_SystemError, 1},
+ {"SystemExit", &PyExc_SystemExit, 1},
+ {"TypeError", &PyExc_TypeError, 1},
+ {"ValueError", &PyExc_ValueError, 1},
+ {"ZeroDivisionError", &PyExc_ZeroDivisionError, 1},
+ {NULL, NULL}
+};
+
+
+/* import exceptions module to extract class exceptions */
+static void
+init_class_exc(dict)
+ PyObject *dict;
+{
+ int i;
+ PyObject *m = PyImport_ImportModule("exceptions");
+ PyObject *d;
+ PyObject *args;
+
+ if (m == NULL ||
+ (d = PyModule_GetDict(m)) == NULL)
+ {
+ PyObject *f = PySys_GetObject("stderr");
+ if (Py_VerboseFlag) {
+ PyFile_WriteString(
+ "'import exceptions' failed; traceback:\n", f);
+ PyErr_Print();
+ }
+ else {
+ PyFile_WriteString(
+ "'import exceptions' failed; use -v for traceback\n", f);
+ PyErr_Clear();
+ }
+ PyFile_WriteString("defaulting to old style exceptions\n", f);
+ return;
+ }
+ for (i = 0; bltin_exc[i].name; i++) {
+ /* dig the exception out of the module */
+ PyObject *exc = PyDict_GetItemString(d, bltin_exc[i].name);
+ if (!exc)
+ Py_FatalError("built-in exception cannot be initialized");
+
+ Py_XDECREF(*bltin_exc[i].exc);
+
+ /* squirrel away a pointer to the exception */
+ Py_INCREF(exc);
+ *bltin_exc[i].exc = exc;
+
+ /* and insert the name in the __builtin__ module */
+ PyDict_SetItemString(dict, bltin_exc[i].name, exc);
+ }
+
+ /* we need one pre-allocated instance */
+ args = Py_BuildValue("()");
+ if (args) {
+ PyExc_MemoryErrorInst =
+ PyEval_CallObject(PyExc_MemoryError, args);
+ Py_DECREF(args);
+ }
+
+ /* we're done with the exceptions module */
+ Py_DECREF(m);
+
+ if (PyErr_Occurred())
+ Py_FatalError("can't instantiate standard exceptions");
+}
+
+
+static void
+fini_instances()
+{
+ Py_XDECREF(PyExc_MemoryErrorInst);
+ PyExc_MemoryErrorInst = NULL;
+}
+
+
static PyObject *
newstdexception(dict, name)
PyObject *dict;
@@ -1760,55 +1865,60 @@ static void
initerrors(dict)
PyObject *dict;
{
- PyExc_AccessError = newstdexception(dict, "AccessError");
- PyExc_AssertionError = newstdexception(dict, "AssertionError");
- PyExc_AttributeError = newstdexception(dict, "AttributeError");
- PyExc_EOFError = newstdexception(dict, "EOFError");
- PyExc_FloatingPointError = newstdexception(dict, "FloatingPointError");
- PyExc_IOError = newstdexception(dict, "IOError");
- PyExc_ImportError = newstdexception(dict, "ImportError");
- PyExc_IndexError = newstdexception(dict, "IndexError");
- PyExc_KeyError = newstdexception(dict, "KeyError");
- PyExc_KeyboardInterrupt = newstdexception(dict, "KeyboardInterrupt");
- PyExc_MemoryError = newstdexception(dict, "MemoryError");
- PyExc_NameError = newstdexception(dict, "NameError");
- PyExc_OverflowError = newstdexception(dict, "OverflowError");
- PyExc_RuntimeError = newstdexception(dict, "RuntimeError");
- PyExc_SyntaxError = newstdexception(dict, "SyntaxError");
- PyExc_SystemError = newstdexception(dict, "SystemError");
- PyExc_SystemExit = newstdexception(dict, "SystemExit");
- PyExc_TypeError = newstdexception(dict, "TypeError");
- PyExc_ValueError = newstdexception(dict, "ValueError");
- PyExc_ZeroDivisionError = newstdexception(dict, "ZeroDivisionError");
+ int i;
+ int exccnt = 0;
+ for (i = 0; bltin_exc[i].name; i++, exccnt++) {
+ if (bltin_exc[i].leaf_exc)
+ *bltin_exc[i].exc =
+ newstdexception(dict, bltin_exc[i].name);
+ }
+
+ /* This is kind of bogus because we special case the three new
+ exceptions to be nearly forward compatible. But this means we
+ hard code knowledge about exceptions.py into C here. I don't
+ have a better solution, though
+ */
+ PyExc_LookupError = PyTuple_New(2);
+ Py_INCREF(PyExc_IndexError);
+ PyTuple_SET_ITEM(PyExc_LookupError, 0, PyExc_IndexError);
+ Py_INCREF(PyExc_KeyError);
+ PyTuple_SET_ITEM(PyExc_LookupError, 1, PyExc_KeyError);
+ PyDict_SetItemString(dict, "LookupError", PyExc_LookupError);
+
+ PyExc_NumberError = PyTuple_New(3);
+ Py_INCREF(PyExc_OverflowError);
+ PyTuple_SET_ITEM(PyExc_NumberError, 0, PyExc_OverflowError);
+ Py_INCREF(PyExc_ZeroDivisionError);
+ PyTuple_SET_ITEM(PyExc_NumberError, 1, PyExc_ZeroDivisionError);
+ Py_INCREF(PyExc_FloatingPointError);
+ PyTuple_SET_ITEM(PyExc_NumberError, 2, PyExc_FloatingPointError);
+ PyDict_SetItemString(dict, "NumberError", PyExc_NumberError);
+
+ PyExc_StandardError = PyTuple_New(exccnt-1);
+ for (i = 1; bltin_exc[i].name; i++) {
+ PyObject *exc = *bltin_exc[i].exc;
+ Py_INCREF(exc);
+ PyTuple_SET_ITEM(PyExc_StandardError, i-1, exc);
+ }
+ PyDict_SetItemString(dict, "StandardError", PyExc_StandardError);
+
+ if (PyErr_Occurred())
+ Py_FatalError("Could not initialize built-in string exceptions");
}
static void
finierrors()
{
- Py_XDECREF(PyExc_AccessError); PyExc_AccessError = NULL;
- Py_XDECREF(PyExc_AssertionError); PyExc_AssertionError = NULL;
- Py_XDECREF(PyExc_AttributeError); PyExc_AttributeError = NULL;
- Py_XDECREF(PyExc_EOFError); PyExc_EOFError = NULL;
- Py_XDECREF(PyExc_FloatingPointError); PyExc_FloatingPointError = NULL;
- Py_XDECREF(PyExc_IOError); PyExc_IOError = NULL;
- Py_XDECREF(PyExc_ImportError); PyExc_ImportError = NULL;
- Py_XDECREF(PyExc_IndexError); PyExc_IndexError = NULL;
- Py_XDECREF(PyExc_KeyError); PyExc_KeyError = NULL;
- Py_XDECREF(PyExc_KeyboardInterrupt); PyExc_KeyboardInterrupt = NULL;
- Py_XDECREF(PyExc_MemoryError); PyExc_MemoryError = NULL;
- Py_XDECREF(PyExc_NameError); PyExc_NameError = NULL;
- Py_XDECREF(PyExc_OverflowError); PyExc_OverflowError = NULL;
- Py_XDECREF(PyExc_RuntimeError); PyExc_RuntimeError = NULL;
- Py_XDECREF(PyExc_SyntaxError); PyExc_SyntaxError = NULL;
- Py_XDECREF(PyExc_SystemError); PyExc_SystemError = NULL;
- Py_XDECREF(PyExc_SystemExit); PyExc_SystemExit = NULL;
- Py_XDECREF(PyExc_TypeError); PyExc_TypeError = NULL;
- Py_XDECREF(PyExc_ValueError); PyExc_ValueError = NULL;
- Py_XDECREF(PyExc_ZeroDivisionError); PyExc_ZeroDivisionError = NULL;
+ int i;
+ for (i = 0; bltin_exc[i].name; i++) {
+ PyObject *exc = *bltin_exc[i].exc;
+ Py_XDECREF(exc);
+ *bltin_exc[i].exc = NULL;
+ }
}
PyObject *
-_PyBuiltin_Init()
+_PyBuiltin_Init_1()
{
PyObject *mod, *dict;
mod = Py_InitModule("__builtin__", builtin_methods);
@@ -1823,11 +1933,29 @@ _PyBuiltin_Init()
if (PyDict_SetItemString(dict, "__debug__",
PyInt_FromLong(Py_OptimizeFlag == 0)) < 0)
return NULL;
+
return mod;
}
void
-_PyBuiltin_Fini()
+_PyBuiltin_Init_2(dict)
+ PyObject *dict;
+{
+ /* if Python was started with -X, initialize the class exceptions */
+ if (Py_UseClassExceptionsFlag)
+ init_class_exc(dict);
+}
+
+
+void
+_PyBuiltin_Fini_1()
+{
+ fini_instances();
+}
+
+
+void
+_PyBuiltin_Fini_2()
{
finierrors();
}