blob: ad618ff06b16e4022d73f71fa7ae6424713ab8a2 [file] [log] [blame]
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001/*
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
Thomas Wouters477c8d52006-05-27 19:21:47 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
9#include "structmember.h"
10#include "osdefs.h"
11
Thomas Wouters477c8d52006-05-27 19:21:47 +000012
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020013/* Compatibility aliases */
14PyObject *PyExc_EnvironmentError = NULL;
15PyObject *PyExc_IOError = NULL;
16#ifdef MS_WINDOWS
17PyObject *PyExc_WindowsError = NULL;
18#endif
19#ifdef __VMS
20PyObject *PyExc_VMSError = NULL;
21#endif
22
23/* The dict map from errno codes to OSError subclasses */
24static PyObject *errnomap = NULL;
25
26
Thomas Wouters477c8d52006-05-27 19:21:47 +000027/* NOTE: If the exception class hierarchy changes, don't forget to update
28 * Lib/test/exception_hierarchy.txt
29 */
30
Thomas Wouters477c8d52006-05-27 19:21:47 +000031/*
32 * BaseException
33 */
34static PyObject *
35BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
36{
37 PyBaseExceptionObject *self;
38
39 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
Guido van Rossumd8faa362007-04-27 19:54:29 +000040 if (!self)
41 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000042 /* the dict is created on the fly in PyObject_GenericSetAttr */
Guido van Rossumebe3e162007-05-17 18:20:34 +000043 self->dict = NULL;
Collin Winter1966f1c2007-09-01 20:26:44 +000044 self->traceback = self->cause = self->context = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000045
46 self->args = PyTuple_New(0);
47 if (!self->args) {
48 Py_DECREF(self);
49 return NULL;
50 }
51
Thomas Wouters477c8d52006-05-27 19:21:47 +000052 return (PyObject *)self;
53}
54
55static int
56BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
57{
Christian Heimes90aa7642007-12-19 02:45:37 +000058 if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000059 return -1;
60
Thomas Wouters477c8d52006-05-27 19:21:47 +000061 Py_DECREF(self->args);
62 self->args = args;
63 Py_INCREF(self->args);
64
Thomas Wouters477c8d52006-05-27 19:21:47 +000065 return 0;
66}
67
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000068static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000069BaseException_clear(PyBaseExceptionObject *self)
70{
71 Py_CLEAR(self->dict);
72 Py_CLEAR(self->args);
Collin Winter828f04a2007-08-31 00:04:24 +000073 Py_CLEAR(self->traceback);
Collin Winter1966f1c2007-09-01 20:26:44 +000074 Py_CLEAR(self->cause);
75 Py_CLEAR(self->context);
Thomas Wouters477c8d52006-05-27 19:21:47 +000076 return 0;
77}
78
79static void
80BaseException_dealloc(PyBaseExceptionObject *self)
81{
Thomas Wouters89f507f2006-12-13 04:49:30 +000082 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000083 BaseException_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +000084 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000085}
86
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000087static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000088BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
89{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000090 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000091 Py_VISIT(self->args);
Collin Winter828f04a2007-08-31 00:04:24 +000092 Py_VISIT(self->traceback);
Collin Winter1966f1c2007-09-01 20:26:44 +000093 Py_VISIT(self->cause);
94 Py_VISIT(self->context);
Thomas Wouters477c8d52006-05-27 19:21:47 +000095 return 0;
96}
97
98static PyObject *
99BaseException_str(PyBaseExceptionObject *self)
100{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000101 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000102 case 0:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000103 return PyUnicode_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000104 case 1:
Thomas Heller519a0422007-11-15 20:48:54 +0000105 return PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000106 default:
Thomas Heller519a0422007-11-15 20:48:54 +0000107 return PyObject_Str(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000108 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109}
110
111static PyObject *
112BaseException_repr(PyBaseExceptionObject *self)
113{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 char *name;
115 char *dot;
116
Christian Heimes90aa7642007-12-19 02:45:37 +0000117 name = (char *)Py_TYPE(self)->tp_name;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000118 dot = strrchr(name, '.');
119 if (dot != NULL) name = dot+1;
120
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000121 return PyUnicode_FromFormat("%s%R", name, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000122}
123
124/* Pickling support */
125static PyObject *
126BaseException_reduce(PyBaseExceptionObject *self)
127{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000128 if (self->args && self->dict)
Christian Heimes90aa7642007-12-19 02:45:37 +0000129 return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000130 else
Christian Heimes90aa7642007-12-19 02:45:37 +0000131 return PyTuple_Pack(2, Py_TYPE(self), self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132}
133
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000134/*
135 * Needed for backward compatibility, since exceptions used to store
136 * all their attributes in the __dict__. Code is taken from cPickle's
137 * load_build function.
138 */
139static PyObject *
140BaseException_setstate(PyObject *self, PyObject *state)
141{
142 PyObject *d_key, *d_value;
143 Py_ssize_t i = 0;
144
145 if (state != Py_None) {
146 if (!PyDict_Check(state)) {
147 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
148 return NULL;
149 }
150 while (PyDict_Next(state, &i, &d_key, &d_value)) {
151 if (PyObject_SetAttr(self, d_key, d_value) < 0)
152 return NULL;
153 }
154 }
155 Py_RETURN_NONE;
156}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000157
Collin Winter828f04a2007-08-31 00:04:24 +0000158static PyObject *
159BaseException_with_traceback(PyObject *self, PyObject *tb) {
160 if (PyException_SetTraceback(self, tb))
161 return NULL;
162
163 Py_INCREF(self);
164 return self;
165}
166
Georg Brandl76941002008-05-05 21:38:47 +0000167PyDoc_STRVAR(with_traceback_doc,
168"Exception.with_traceback(tb) --\n\
169 set self.__traceback__ to tb and return self.");
170
Thomas Wouters477c8d52006-05-27 19:21:47 +0000171
172static PyMethodDef BaseException_methods[] = {
173 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000174 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Georg Brandl76941002008-05-05 21:38:47 +0000175 {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
176 with_traceback_doc},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000177 {NULL, NULL, 0, NULL},
178};
179
180
Thomas Wouters477c8d52006-05-27 19:21:47 +0000181static PyObject *
182BaseException_get_dict(PyBaseExceptionObject *self)
183{
184 if (self->dict == NULL) {
185 self->dict = PyDict_New();
186 if (!self->dict)
187 return NULL;
188 }
189 Py_INCREF(self->dict);
190 return self->dict;
191}
192
193static int
194BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
195{
196 if (val == NULL) {
197 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
198 return -1;
199 }
200 if (!PyDict_Check(val)) {
201 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
202 return -1;
203 }
204 Py_CLEAR(self->dict);
205 Py_INCREF(val);
206 self->dict = val;
207 return 0;
208}
209
210static PyObject *
211BaseException_get_args(PyBaseExceptionObject *self)
212{
213 if (self->args == NULL) {
214 Py_INCREF(Py_None);
215 return Py_None;
216 }
217 Py_INCREF(self->args);
218 return self->args;
219}
220
221static int
222BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
223{
224 PyObject *seq;
225 if (val == NULL) {
226 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
227 return -1;
228 }
229 seq = PySequence_Tuple(val);
230 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000231 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000232 self->args = seq;
233 return 0;
234}
235
Collin Winter828f04a2007-08-31 00:04:24 +0000236static PyObject *
237BaseException_get_tb(PyBaseExceptionObject *self)
238{
239 if (self->traceback == NULL) {
240 Py_INCREF(Py_None);
241 return Py_None;
242 }
243 Py_INCREF(self->traceback);
244 return self->traceback;
245}
246
247static int
248BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb)
249{
250 if (tb == NULL) {
251 PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
252 return -1;
253 }
254 else if (!(tb == Py_None || PyTraceBack_Check(tb))) {
255 PyErr_SetString(PyExc_TypeError,
256 "__traceback__ must be a traceback or None");
257 return -1;
258 }
259
260 Py_XINCREF(tb);
261 Py_XDECREF(self->traceback);
262 self->traceback = tb;
263 return 0;
264}
265
Georg Brandlab6f2f62009-03-31 04:16:10 +0000266static PyObject *
267BaseException_get_context(PyObject *self) {
268 PyObject *res = PyException_GetContext(self);
269 if (res) return res; /* new reference already returned above */
270 Py_RETURN_NONE;
271}
272
273static int
274BaseException_set_context(PyObject *self, PyObject *arg) {
275 if (arg == NULL) {
276 PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted");
277 return -1;
278 } else if (arg == Py_None) {
279 arg = NULL;
280 } else if (!PyExceptionInstance_Check(arg)) {
281 PyErr_SetString(PyExc_TypeError, "exception context must be None "
282 "or derive from BaseException");
283 return -1;
284 } else {
285 /* PyException_SetContext steals this reference */
286 Py_INCREF(arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 }
Georg Brandlab6f2f62009-03-31 04:16:10 +0000288 PyException_SetContext(self, arg);
289 return 0;
290}
291
292static PyObject *
293BaseException_get_cause(PyObject *self) {
294 PyObject *res = PyException_GetCause(self);
295 if (res) return res; /* new reference already returned above */
296 Py_RETURN_NONE;
297}
298
299static int
300BaseException_set_cause(PyObject *self, PyObject *arg) {
301 if (arg == NULL) {
302 PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted");
303 return -1;
304 } else if (arg == Py_None) {
305 arg = NULL;
306 } else if (!PyExceptionInstance_Check(arg)) {
307 PyErr_SetString(PyExc_TypeError, "exception cause must be None "
308 "or derive from BaseException");
309 return -1;
310 } else {
311 /* PyException_SetCause steals this reference */
312 Py_INCREF(arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 }
Georg Brandlab6f2f62009-03-31 04:16:10 +0000314 PyException_SetCause(self, arg);
315 return 0;
316}
317
Guido van Rossum360e4b82007-05-14 22:51:27 +0000318
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319static PyGetSetDef BaseException_getset[] = {
320 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
321 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
Collin Winter828f04a2007-08-31 00:04:24 +0000322 {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
Georg Brandlab6f2f62009-03-31 04:16:10 +0000323 {"__context__", (getter)BaseException_get_context,
324 (setter)BaseException_set_context, PyDoc_STR("exception context")},
325 {"__cause__", (getter)BaseException_get_cause,
326 (setter)BaseException_set_cause, PyDoc_STR("exception cause")},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000327 {NULL},
328};
329
330
Collin Winter828f04a2007-08-31 00:04:24 +0000331PyObject *
332PyException_GetTraceback(PyObject *self) {
333 PyBaseExceptionObject *base_self = (PyBaseExceptionObject *)self;
334 Py_XINCREF(base_self->traceback);
335 return base_self->traceback;
336}
337
338
339int
340PyException_SetTraceback(PyObject *self, PyObject *tb) {
341 return BaseException_set_tb((PyBaseExceptionObject *)self, tb);
342}
343
344PyObject *
345PyException_GetCause(PyObject *self) {
346 PyObject *cause = ((PyBaseExceptionObject *)self)->cause;
347 Py_XINCREF(cause);
348 return cause;
349}
350
351/* Steals a reference to cause */
352void
353PyException_SetCause(PyObject *self, PyObject *cause) {
354 PyObject *old_cause = ((PyBaseExceptionObject *)self)->cause;
355 ((PyBaseExceptionObject *)self)->cause = cause;
356 Py_XDECREF(old_cause);
357}
358
359PyObject *
360PyException_GetContext(PyObject *self) {
361 PyObject *context = ((PyBaseExceptionObject *)self)->context;
362 Py_XINCREF(context);
363 return context;
364}
365
366/* Steals a reference to context */
367void
368PyException_SetContext(PyObject *self, PyObject *context) {
369 PyObject *old_context = ((PyBaseExceptionObject *)self)->context;
370 ((PyBaseExceptionObject *)self)->context = context;
371 Py_XDECREF(old_context);
372}
373
374
Thomas Wouters477c8d52006-05-27 19:21:47 +0000375static PyTypeObject _PyExc_BaseException = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000376 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +0000377 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000378 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
379 0, /*tp_itemsize*/
380 (destructor)BaseException_dealloc, /*tp_dealloc*/
381 0, /*tp_print*/
382 0, /*tp_getattr*/
383 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000384 0, /* tp_reserved; */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000385 (reprfunc)BaseException_repr, /*tp_repr*/
386 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000387 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388 0, /*tp_as_mapping*/
389 0, /*tp_hash */
390 0, /*tp_call*/
391 (reprfunc)BaseException_str, /*tp_str*/
392 PyObject_GenericGetAttr, /*tp_getattro*/
393 PyObject_GenericSetAttr, /*tp_setattro*/
394 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000395 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000397 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
398 (traverseproc)BaseException_traverse, /* tp_traverse */
399 (inquiry)BaseException_clear, /* tp_clear */
400 0, /* tp_richcompare */
401 0, /* tp_weaklistoffset */
402 0, /* tp_iter */
403 0, /* tp_iternext */
404 BaseException_methods, /* tp_methods */
Georg Brandlab6f2f62009-03-31 04:16:10 +0000405 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406 BaseException_getset, /* tp_getset */
407 0, /* tp_base */
408 0, /* tp_dict */
409 0, /* tp_descr_get */
410 0, /* tp_descr_set */
411 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
412 (initproc)BaseException_init, /* tp_init */
413 0, /* tp_alloc */
414 BaseException_new, /* tp_new */
415};
416/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
417from the previous implmentation and also allowing Python objects to be used
418in the API */
419PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
420
421/* note these macros omit the last semicolon so the macro invocation may
422 * include it and not look strange.
423 */
424#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
425static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000426 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000427 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000428 sizeof(PyBaseExceptionObject), \
429 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
430 0, 0, 0, 0, 0, 0, 0, \
431 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
432 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
433 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
434 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
435 (initproc)BaseException_init, 0, BaseException_new,\
436}; \
437PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
438
439#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
440static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000441 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000442 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000444 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000445 0, 0, 0, 0, 0, \
446 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000447 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
448 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200450 (initproc)EXCSTORE ## _init, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000451}; \
452PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
453
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200454#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCNEW, \
455 EXCMETHODS, EXCMEMBERS, EXCGETSET, \
456 EXCSTR, EXCDOC) \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000458 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000459 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460 sizeof(Py ## EXCSTORE ## Object), 0, \
461 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
462 (reprfunc)EXCSTR, 0, 0, 0, \
463 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
464 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
465 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200466 EXCMEMBERS, EXCGETSET, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000467 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200468 (initproc)EXCSTORE ## _init, 0, EXCNEW,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000469}; \
470PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
471
472
473/*
474 * Exception extends BaseException
475 */
476SimpleExtendsException(PyExc_BaseException, Exception,
477 "Common base class for all non-exit exceptions.");
478
479
480/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000481 * TypeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000482 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000483SimpleExtendsException(PyExc_Exception, TypeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000484 "Inappropriate argument type.");
485
486
487/*
488 * StopIteration extends Exception
489 */
490SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000491 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492
493
494/*
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000495 * GeneratorExit extends BaseException
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496 */
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000497SimpleExtendsException(PyExc_BaseException, GeneratorExit,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498 "Request that a generator exit.");
499
500
501/*
502 * SystemExit extends BaseException
503 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504
505static int
506SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
507{
508 Py_ssize_t size = PyTuple_GET_SIZE(args);
509
510 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
511 return -1;
512
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000513 if (size == 0)
514 return 0;
515 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000516 if (size == 1)
517 self->code = PyTuple_GET_ITEM(args, 0);
Victor Stinner92236e52011-05-26 14:25:54 +0200518 else /* size > 1 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519 self->code = args;
520 Py_INCREF(self->code);
521 return 0;
522}
523
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525SystemExit_clear(PySystemExitObject *self)
526{
527 Py_CLEAR(self->code);
528 return BaseException_clear((PyBaseExceptionObject *)self);
529}
530
531static void
532SystemExit_dealloc(PySystemExitObject *self)
533{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000534 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000535 SystemExit_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000536 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000537}
538
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000539static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000540SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
541{
542 Py_VISIT(self->code);
543 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
544}
545
546static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000547 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
548 PyDoc_STR("exception code")},
549 {NULL} /* Sentinel */
550};
551
552ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200553 0, 0, SystemExit_members, 0, 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000554 "Request to exit from the interpreter.");
555
556/*
557 * KeyboardInterrupt extends BaseException
558 */
559SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
560 "Program interrupted by user.");
561
562
563/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000564 * ImportError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000565 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000566SimpleExtendsException(PyExc_Exception, ImportError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000567 "Import can't find module, or can't find name in module.");
568
569
570/*
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200571 * OSError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000572 */
573
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200574#ifdef MS_WINDOWS
575#include "errmap.h"
576#endif
577
Thomas Wouters477c8d52006-05-27 19:21:47 +0000578/* Where a function has a single filename, such as open() or some
579 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
580 * called, giving a third argument which is the filename. But, so
581 * that old code using in-place unpacking doesn't break, e.g.:
582 *
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200583 * except OSError, (errno, strerror):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000584 *
585 * we hack args so that it only contains two items. This also
586 * means we need our own __str__() which prints out the filename
587 * when it was supplied.
588 */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200589
590static PyObject *
591OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000592{
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200593 PyOSErrorObject *self = NULL;
594 Py_ssize_t nargs;
595
Thomas Wouters477c8d52006-05-27 19:21:47 +0000596 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
597 PyObject *subslice = NULL;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200598#ifdef MS_WINDOWS
599 PyObject *winerror = NULL;
600 long winerrcode = 0;
601#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000602
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200603 if (!_PyArg_NoKeywords(type->tp_name, kwds))
604 return NULL;
605 Py_INCREF(args);
606 nargs = PyTuple_GET_SIZE(args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200608#ifdef MS_WINDOWS
609 if (nargs >= 2 && nargs <= 4) {
610 if (!PyArg_UnpackTuple(args, "OSError", 2, 4,
611 &myerrno, &strerror, &filename, &winerror))
612 goto error;
613 if (winerror && PyLong_Check(winerror)) {
614 long errcode;
615 PyObject *newargs;
616 Py_ssize_t i;
617
618 winerrcode = PyLong_AsLong(winerror);
619 if (winerrcode == -1 && PyErr_Occurred())
620 goto error;
621 /* Set errno to the corresponding POSIX errno (overriding
622 first argument). Windows Socket error codes (>= 10000)
623 have the same value as their POSIX counterparts.
624 */
625 if (winerrcode < 10000)
626 errcode = winerror_to_errno(winerrcode);
627 else
628 errcode = winerrcode;
629 myerrno = PyLong_FromLong(errcode);
630 if (!myerrno)
631 goto error;
632 newargs = PyTuple_New(nargs);
633 if (!newargs)
634 goto error;
635 PyTuple_SET_ITEM(newargs, 0, myerrno);
636 for (i = 1; i < nargs; i++) {
637 PyObject *val = PyTuple_GET_ITEM(args, i);
638 Py_INCREF(val);
639 PyTuple_SET_ITEM(newargs, i, val);
640 }
641 Py_DECREF(args);
642 args = newargs;
643 }
644 }
645#else
646 if (nargs >= 2 && nargs <= 3) {
647 if (!PyArg_UnpackTuple(args, "OSError", 2, 3,
648 &myerrno, &strerror, &filename))
649 goto error;
650 }
651#endif
652 if (myerrno && PyLong_Check(myerrno) &&
653 errnomap && (PyObject *) type == PyExc_OSError) {
654 PyObject *newtype;
655 newtype = PyDict_GetItem(errnomap, myerrno);
656 if (newtype) {
657 assert(PyType_Check(newtype));
658 type = (PyTypeObject *) newtype;
659 }
660 else if (PyErr_Occurred())
661 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000662 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000663
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200664 self = (PyOSErrorObject *) type->tp_alloc(type, 0);
665 if (!self)
666 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000667
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200668 self->dict = NULL;
669 self->traceback = self->cause = self->context = NULL;
670 self->written = -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671
672 /* self->filename will remain Py_None otherwise */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200673 if (filename && filename != Py_None) {
674 if ((PyObject *) type == PyExc_BlockingIOError &&
675 PyNumber_Check(filename)) {
676 /* BlockingIOError's 3rd argument can be the number of
677 * characters written.
678 */
679 self->written = PyNumber_AsSsize_t(filename, PyExc_ValueError);
680 if (self->written == -1 && PyErr_Occurred())
681 goto error;
682 }
683 else {
684 Py_INCREF(filename);
685 self->filename = filename;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200687 if (nargs >= 2 && nargs <= 3) {
688 /* filename is removed from the args tuple (for compatibility
689 purposes, see test_exceptions.py) */
690 subslice = PyTuple_GetSlice(args, 0, 2);
691 if (!subslice)
692 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200694 Py_DECREF(args); /* replacing args */
695 args = subslice;
696 }
697 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000698 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200699
700 /* Steals the reference to args */
701 self->args = args;
702 args = NULL;
703
704 Py_XINCREF(myerrno);
705 self->myerrno = myerrno;
706
707 Py_XINCREF(strerror);
708 self->strerror = strerror;
709
710#ifdef MS_WINDOWS
711 Py_XINCREF(winerror);
712 self->winerror = winerror;
713#endif
714
715 return (PyObject *) self;
716
717error:
718 Py_XDECREF(args);
719 Py_XDECREF(self);
720 return NULL;
721}
722
723static int
724OSError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
725{
726 /* Everything already done in OSError_new */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727 return 0;
728}
729
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000730static int
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200731OSError_clear(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000732{
733 Py_CLEAR(self->myerrno);
734 Py_CLEAR(self->strerror);
735 Py_CLEAR(self->filename);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200736#ifdef MS_WINDOWS
737 Py_CLEAR(self->winerror);
738#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739 return BaseException_clear((PyBaseExceptionObject *)self);
740}
741
742static void
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200743OSError_dealloc(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000745 _PyObject_GC_UNTRACK(self);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200746 OSError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +0000747 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000748}
749
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000750static int
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200751OSError_traverse(PyOSErrorObject *self, visitproc visit,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000752 void *arg)
753{
754 Py_VISIT(self->myerrno);
755 Py_VISIT(self->strerror);
756 Py_VISIT(self->filename);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200757#ifdef MS_WINDOWS
758 Py_VISIT(self->winerror);
759#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
761}
762
763static PyObject *
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200764OSError_str(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000765{
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200766#ifdef MS_WINDOWS
767 /* If available, winerror has the priority over myerrno */
768 if (self->winerror && self->filename)
769 return PyUnicode_FromFormat("[Error %S] %S: %R",
770 self->winerror ? self->winerror: Py_None,
771 self->strerror ? self->strerror: Py_None,
772 self->filename);
773 if (self->winerror && self->strerror)
774 return PyUnicode_FromFormat("[Error %S] %S",
775 self->winerror ? self->winerror: Py_None,
776 self->strerror ? self->strerror: Py_None);
777#endif
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000778 if (self->filename)
779 return PyUnicode_FromFormat("[Errno %S] %S: %R",
780 self->myerrno ? self->myerrno: Py_None,
781 self->strerror ? self->strerror: Py_None,
782 self->filename);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200783 if (self->myerrno && self->strerror)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000784 return PyUnicode_FromFormat("[Errno %S] %S",
785 self->myerrno ? self->myerrno: Py_None,
786 self->strerror ? self->strerror: Py_None);
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200787 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000788}
789
Thomas Wouters477c8d52006-05-27 19:21:47 +0000790static PyObject *
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200791OSError_reduce(PyOSErrorObject *self)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000792{
793 PyObject *args = self->args;
794 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000795
Thomas Wouters477c8d52006-05-27 19:21:47 +0000796 /* self->args is only the first two real arguments if there was a
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200797 * file name given to OSError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000798 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000799 args = PyTuple_New(3);
800 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000801
802 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 Py_INCREF(tmp);
804 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000805
806 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000807 Py_INCREF(tmp);
808 PyTuple_SET_ITEM(args, 1, tmp);
809
810 Py_INCREF(self->filename);
811 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000812 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000814
815 if (self->dict)
Christian Heimes90aa7642007-12-19 02:45:37 +0000816 res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000817 else
Christian Heimes90aa7642007-12-19 02:45:37 +0000818 res = PyTuple_Pack(2, Py_TYPE(self), args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000819 Py_DECREF(args);
820 return res;
821}
822
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200823static PyObject *
824OSError_written_get(PyOSErrorObject *self, void *context)
825{
826 if (self->written == -1) {
827 PyErr_SetString(PyExc_AttributeError, "characters_written");
828 return NULL;
829 }
830 return PyLong_FromSsize_t(self->written);
831}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200833static int
834OSError_written_set(PyOSErrorObject *self, PyObject *arg, void *context)
835{
836 Py_ssize_t n;
837 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
838 if (n == -1 && PyErr_Occurred())
839 return -1;
840 self->written = n;
841 return 0;
842}
843
844static PyMemberDef OSError_members[] = {
845 {"errno", T_OBJECT, offsetof(PyOSErrorObject, myerrno), 0,
846 PyDoc_STR("POSIX exception code")},
847 {"strerror", T_OBJECT, offsetof(PyOSErrorObject, strerror), 0,
848 PyDoc_STR("exception strerror")},
849 {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0,
850 PyDoc_STR("exception filename")},
851#ifdef MS_WINDOWS
852 {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0,
853 PyDoc_STR("Win32 exception code")},
854#endif
855 {NULL} /* Sentinel */
856};
857
858static PyMethodDef OSError_methods[] = {
859 {"__reduce__", (PyCFunction)OSError_reduce, METH_NOARGS},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860 {NULL}
861};
862
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200863static PyGetSetDef OSError_getset[] = {
864 {"characters_written", (getter) OSError_written_get,
865 (setter) OSError_written_set, NULL},
866 {NULL}
867};
868
869
870ComplexExtendsException(PyExc_Exception, OSError,
871 OSError, OSError_new,
872 OSError_methods, OSError_members, OSError_getset,
873 OSError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874 "Base class for I/O related errors.");
875
876
877/*
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200878 * Various OSError subclasses
Thomas Wouters477c8d52006-05-27 19:21:47 +0000879 */
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200880MiddlingExtendsException(PyExc_OSError, BlockingIOError, OSError,
881 "I/O operation would block.");
882MiddlingExtendsException(PyExc_OSError, ConnectionError, OSError,
883 "Connection error.");
884MiddlingExtendsException(PyExc_OSError, ChildProcessError, OSError,
885 "Child process error.");
886MiddlingExtendsException(PyExc_ConnectionError, BrokenPipeError, OSError,
887 "Broken pipe.");
888MiddlingExtendsException(PyExc_ConnectionError, ConnectionAbortedError, OSError,
889 "Connection aborted.");
890MiddlingExtendsException(PyExc_ConnectionError, ConnectionRefusedError, OSError,
891 "Connection refused.");
892MiddlingExtendsException(PyExc_ConnectionError, ConnectionResetError, OSError,
893 "Connection reset.");
894MiddlingExtendsException(PyExc_OSError, FileExistsError, OSError,
895 "File already exists.");
896MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError,
897 "File not found.");
898MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError,
899 "Operation doesn't work on directories.");
900MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError,
901 "Operation only works on directories.");
902MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError,
903 "Interrupted by signal.");
904MiddlingExtendsException(PyExc_OSError, PermissionError, OSError,
905 "Not enough permissions.");
906MiddlingExtendsException(PyExc_OSError, ProcessLookupError, OSError,
907 "Process not found.");
908MiddlingExtendsException(PyExc_OSError, TimeoutError, OSError,
909 "Timeout expired.");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000910
911/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000912 * EOFError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000913 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000914SimpleExtendsException(PyExc_Exception, EOFError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000915 "Read beyond end of file.");
916
917
918/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000919 * RuntimeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000920 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000921SimpleExtendsException(PyExc_Exception, RuntimeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922 "Unspecified run-time error.");
923
924
925/*
926 * NotImplementedError extends RuntimeError
927 */
928SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
929 "Method or function hasn't been implemented yet.");
930
931/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000932 * NameError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000933 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000934SimpleExtendsException(PyExc_Exception, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000935 "Name not found globally.");
936
937/*
938 * UnboundLocalError extends NameError
939 */
940SimpleExtendsException(PyExc_NameError, UnboundLocalError,
941 "Local name referenced but not bound to a value.");
942
943/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000944 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000945 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000946SimpleExtendsException(PyExc_Exception, AttributeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947 "Attribute not found.");
948
949
950/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000951 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000952 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000953
954static int
955SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
956{
957 PyObject *info = NULL;
958 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
959
960 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
961 return -1;
962
963 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000964 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000965 self->msg = PyTuple_GET_ITEM(args, 0);
966 Py_INCREF(self->msg);
967 }
968 if (lenargs == 2) {
969 info = PyTuple_GET_ITEM(args, 1);
970 info = PySequence_Tuple(info);
971 if (!info) return -1;
972
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000973 if (PyTuple_GET_SIZE(info) != 4) {
974 /* not a very good error message, but it's what Python 2.4 gives */
975 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
976 Py_DECREF(info);
977 return -1;
978 }
979
980 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981 self->filename = PyTuple_GET_ITEM(info, 0);
982 Py_INCREF(self->filename);
983
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000984 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000985 self->lineno = PyTuple_GET_ITEM(info, 1);
986 Py_INCREF(self->lineno);
987
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000988 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000989 self->offset = PyTuple_GET_ITEM(info, 2);
990 Py_INCREF(self->offset);
991
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000992 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000993 self->text = PyTuple_GET_ITEM(info, 3);
994 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000995
996 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997 }
998 return 0;
999}
1000
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001001static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002SyntaxError_clear(PySyntaxErrorObject *self)
1003{
1004 Py_CLEAR(self->msg);
1005 Py_CLEAR(self->filename);
1006 Py_CLEAR(self->lineno);
1007 Py_CLEAR(self->offset);
1008 Py_CLEAR(self->text);
1009 Py_CLEAR(self->print_file_and_line);
1010 return BaseException_clear((PyBaseExceptionObject *)self);
1011}
1012
1013static void
1014SyntaxError_dealloc(PySyntaxErrorObject *self)
1015{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001016 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001017 SyntaxError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001018 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019}
1020
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001021static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1023{
1024 Py_VISIT(self->msg);
1025 Py_VISIT(self->filename);
1026 Py_VISIT(self->lineno);
1027 Py_VISIT(self->offset);
1028 Py_VISIT(self->text);
1029 Py_VISIT(self->print_file_and_line);
1030 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1031}
1032
1033/* This is called "my_basename" instead of just "basename" to avoid name
1034 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1035 defined, and Python does define that. */
Victor Stinner6237daf2010-04-28 17:26:19 +00001036static PyObject*
1037my_basename(PyObject *name)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038{
Victor Stinner6237daf2010-04-28 17:26:19 +00001039 Py_ssize_t i, size, offset;
Victor Stinner31392e72011-10-05 20:14:23 +02001040 int kind;
1041 void *data;
1042
1043 if (PyUnicode_READY(name))
1044 return NULL;
1045 kind = PyUnicode_KIND(name);
1046 data = PyUnicode_DATA(name);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001047 size = PyUnicode_GET_LENGTH(name);
Victor Stinner6237daf2010-04-28 17:26:19 +00001048 offset = 0;
1049 for(i=0; i < size; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001050 if (PyUnicode_READ(kind, data, i) == SEP)
Victor Stinner6237daf2010-04-28 17:26:19 +00001051 offset = i + 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001052 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001053 if (offset != 0)
1054 return PyUnicode_Substring(name, offset, size);
1055 else {
Victor Stinner6237daf2010-04-28 17:26:19 +00001056 Py_INCREF(name);
1057 return name;
1058 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001059}
1060
1061
1062static PyObject *
1063SyntaxError_str(PySyntaxErrorObject *self)
1064{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001065 int have_lineno = 0;
Victor Stinner6237daf2010-04-28 17:26:19 +00001066 PyObject *filename;
1067 PyObject *result;
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001068 /* Below, we always ignore overflow errors, just printing -1.
1069 Still, we cannot allow an OverflowError to be raised, so
1070 we need to call PyLong_AsLongAndOverflow. */
1071 int overflow;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001072
1073 /* XXX -- do all the additional formatting with filename and
1074 lineno here */
1075
Neal Norwitzed2b7392007-08-26 04:51:10 +00001076 if (self->filename && PyUnicode_Check(self->filename)) {
Victor Stinner6237daf2010-04-28 17:26:19 +00001077 filename = my_basename(self->filename);
1078 if (filename == NULL)
1079 return NULL;
1080 } else {
1081 filename = NULL;
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001082 }
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001083 have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001084
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001085 if (!filename && !have_lineno)
Thomas Heller519a0422007-11-15 20:48:54 +00001086 return PyObject_Str(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001087
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001088 if (filename && have_lineno)
Victor Stinner6237daf2010-04-28 17:26:19 +00001089 result = PyUnicode_FromFormat("%S (%U, line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001090 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001091 filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Martin v. Löwis10a60b32007-07-18 02:28:27 +00001093 else if (filename)
Victor Stinner6237daf2010-04-28 17:26:19 +00001094 result = PyUnicode_FromFormat("%S (%U)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001095 self->msg ? self->msg : Py_None,
Victor Stinner6237daf2010-04-28 17:26:19 +00001096 filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097 else /* only have_lineno */
Victor Stinner6237daf2010-04-28 17:26:19 +00001098 result = PyUnicode_FromFormat("%S (line %ld)",
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001099 self->msg ? self->msg : Py_None,
Martin v. Löwisd1a1d1e2007-12-04 22:10:37 +00001100 PyLong_AsLongAndOverflow(self->lineno, &overflow));
Victor Stinner6237daf2010-04-28 17:26:19 +00001101 Py_XDECREF(filename);
1102 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001103}
1104
1105static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001106 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1107 PyDoc_STR("exception msg")},
1108 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1109 PyDoc_STR("exception filename")},
1110 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1111 PyDoc_STR("exception lineno")},
1112 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1113 PyDoc_STR("exception offset")},
1114 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1115 PyDoc_STR("exception text")},
1116 {"print_file_and_line", T_OBJECT,
1117 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1118 PyDoc_STR("exception print_file_and_line")},
1119 {NULL} /* Sentinel */
1120};
1121
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001122ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001123 0, 0, SyntaxError_members, 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001124 SyntaxError_str, "Invalid syntax.");
1125
1126
1127/*
1128 * IndentationError extends SyntaxError
1129 */
1130MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1131 "Improper indentation.");
1132
1133
1134/*
1135 * TabError extends IndentationError
1136 */
1137MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1138 "Improper mixture of spaces and tabs.");
1139
1140
1141/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001142 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001143 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001144SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001145 "Base class for lookup errors.");
1146
1147
1148/*
1149 * IndexError extends LookupError
1150 */
1151SimpleExtendsException(PyExc_LookupError, IndexError,
1152 "Sequence index out of range.");
1153
1154
1155/*
1156 * KeyError extends LookupError
1157 */
1158static PyObject *
1159KeyError_str(PyBaseExceptionObject *self)
1160{
1161 /* If args is a tuple of exactly one item, apply repr to args[0].
1162 This is done so that e.g. the exception raised by {}[''] prints
1163 KeyError: ''
1164 rather than the confusing
1165 KeyError
1166 alone. The downside is that if KeyError is raised with an explanatory
1167 string, that string will be displayed in quotes. Too bad.
1168 If args is anything else, use the default BaseException__str__().
1169 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001170 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +00001171 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001172 }
1173 return BaseException_str(self);
1174}
1175
1176ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001177 0, 0, 0, 0, KeyError_str, "Mapping key not found.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001178
1179
1180/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001181 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001183SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184 "Inappropriate argument value (of correct type).");
1185
1186/*
1187 * UnicodeError extends ValueError
1188 */
1189
1190SimpleExtendsException(PyExc_ValueError, UnicodeError,
1191 "Unicode related error.");
1192
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001194get_string(PyObject *attr, const char *name)
Walter Dörwald612344f2007-05-04 19:28:21 +00001195{
1196 if (!attr) {
1197 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1198 return NULL;
1199 }
1200
Christian Heimes72b710a2008-05-26 13:28:38 +00001201 if (!PyBytes_Check(attr)) {
Walter Dörwald612344f2007-05-04 19:28:21 +00001202 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1203 return NULL;
1204 }
1205 Py_INCREF(attr);
1206 return attr;
1207}
1208
1209static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001210get_unicode(PyObject *attr, const char *name)
1211{
1212 if (!attr) {
1213 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1214 return NULL;
1215 }
1216
1217 if (!PyUnicode_Check(attr)) {
1218 PyErr_Format(PyExc_TypeError,
1219 "%.200s attribute must be unicode", name);
1220 return NULL;
1221 }
1222 Py_INCREF(attr);
1223 return attr;
1224}
1225
Walter Dörwaldd2034312007-05-18 16:29:38 +00001226static int
1227set_unicodefromstring(PyObject **attr, const char *value)
1228{
1229 PyObject *obj = PyUnicode_FromString(value);
1230 if (!obj)
1231 return -1;
1232 Py_CLEAR(*attr);
1233 *attr = obj;
1234 return 0;
1235}
1236
Thomas Wouters477c8d52006-05-27 19:21:47 +00001237PyObject *
1238PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1239{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001240 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001241}
1242
1243PyObject *
1244PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1245{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001246 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247}
1248
1249PyObject *
1250PyUnicodeEncodeError_GetObject(PyObject *exc)
1251{
1252 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1253}
1254
1255PyObject *
1256PyUnicodeDecodeError_GetObject(PyObject *exc)
1257{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001258 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001259}
1260
1261PyObject *
1262PyUnicodeTranslateError_GetObject(PyObject *exc)
1263{
1264 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1265}
1266
1267int
1268PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1269{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001270 Py_ssize_t size;
1271 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1272 "object");
1273 if (!obj)
1274 return -1;
1275 *start = ((PyUnicodeErrorObject *)exc)->start;
1276 size = PyUnicode_GET_SIZE(obj);
1277 if (*start<0)
1278 *start = 0; /*XXX check for values <0*/
1279 if (*start>=size)
1280 *start = size-1;
1281 Py_DECREF(obj);
1282 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001283}
1284
1285
1286int
1287PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1288{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001289 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001290 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001291 if (!obj)
1292 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001293 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001294 *start = ((PyUnicodeErrorObject *)exc)->start;
1295 if (*start<0)
1296 *start = 0;
1297 if (*start>=size)
1298 *start = size-1;
1299 Py_DECREF(obj);
1300 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001301}
1302
1303
1304int
1305PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1306{
1307 return PyUnicodeEncodeError_GetStart(exc, start);
1308}
1309
1310
1311int
1312PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1313{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001314 ((PyUnicodeErrorObject *)exc)->start = start;
1315 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001316}
1317
1318
1319int
1320PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1321{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001322 ((PyUnicodeErrorObject *)exc)->start = start;
1323 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001324}
1325
1326
1327int
1328PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1329{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001330 ((PyUnicodeErrorObject *)exc)->start = start;
1331 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332}
1333
1334
1335int
1336PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1337{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001338 Py_ssize_t size;
1339 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1340 "object");
1341 if (!obj)
1342 return -1;
1343 *end = ((PyUnicodeErrorObject *)exc)->end;
1344 size = PyUnicode_GET_SIZE(obj);
1345 if (*end<1)
1346 *end = 1;
1347 if (*end>size)
1348 *end = size;
1349 Py_DECREF(obj);
1350 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001351}
1352
1353
1354int
1355PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1356{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001357 Py_ssize_t size;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001358 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object, "object");
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001359 if (!obj)
1360 return -1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001361 size = PyBytes_GET_SIZE(obj);
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001362 *end = ((PyUnicodeErrorObject *)exc)->end;
1363 if (*end<1)
1364 *end = 1;
1365 if (*end>size)
1366 *end = size;
1367 Py_DECREF(obj);
1368 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369}
1370
1371
1372int
1373PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1374{
1375 return PyUnicodeEncodeError_GetEnd(exc, start);
1376}
1377
1378
1379int
1380PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1381{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001382 ((PyUnicodeErrorObject *)exc)->end = end;
1383 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384}
1385
1386
1387int
1388PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1389{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001390 ((PyUnicodeErrorObject *)exc)->end = end;
1391 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392}
1393
1394
1395int
1396PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1397{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001398 ((PyUnicodeErrorObject *)exc)->end = end;
1399 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400}
1401
1402PyObject *
1403PyUnicodeEncodeError_GetReason(PyObject *exc)
1404{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001405 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001406}
1407
1408
1409PyObject *
1410PyUnicodeDecodeError_GetReason(PyObject *exc)
1411{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001412 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001413}
1414
1415
1416PyObject *
1417PyUnicodeTranslateError_GetReason(PyObject *exc)
1418{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001419 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001420}
1421
1422
1423int
1424PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1425{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001426 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1427 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428}
1429
1430
1431int
1432PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1433{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001434 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1435 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436}
1437
1438
1439int
1440PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1441{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001442 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1443 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001444}
1445
1446
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001448UnicodeError_clear(PyUnicodeErrorObject *self)
1449{
1450 Py_CLEAR(self->encoding);
1451 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001452 Py_CLEAR(self->reason);
1453 return BaseException_clear((PyBaseExceptionObject *)self);
1454}
1455
1456static void
1457UnicodeError_dealloc(PyUnicodeErrorObject *self)
1458{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001459 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460 UnicodeError_clear(self);
Christian Heimes90aa7642007-12-19 02:45:37 +00001461 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462}
1463
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001464static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001465UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1466{
1467 Py_VISIT(self->encoding);
1468 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469 Py_VISIT(self->reason);
1470 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1471}
1472
1473static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001474 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1475 PyDoc_STR("exception encoding")},
1476 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1477 PyDoc_STR("exception object")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001478 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001480 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001481 PyDoc_STR("exception end")},
1482 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1483 PyDoc_STR("exception reason")},
1484 {NULL} /* Sentinel */
1485};
1486
1487
1488/*
1489 * UnicodeEncodeError extends UnicodeError
1490 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001491
1492static int
1493UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1494{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001495 PyUnicodeErrorObject *err;
1496
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1498 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001499
1500 err = (PyUnicodeErrorObject *)self;
1501
1502 Py_CLEAR(err->encoding);
1503 Py_CLEAR(err->object);
1504 Py_CLEAR(err->reason);
1505
1506 if (!PyArg_ParseTuple(args, "O!O!nnO!",
1507 &PyUnicode_Type, &err->encoding,
1508 &PyUnicode_Type, &err->object,
1509 &err->start,
1510 &err->end,
1511 &PyUnicode_Type, &err->reason)) {
1512 err->encoding = err->object = err->reason = NULL;
1513 return -1;
1514 }
1515
1516 Py_INCREF(err->encoding);
1517 Py_INCREF(err->object);
1518 Py_INCREF(err->reason);
1519
1520 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521}
1522
1523static PyObject *
1524UnicodeEncodeError_str(PyObject *self)
1525{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001526 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00001527 PyObject *result = NULL;
1528 PyObject *reason_str = NULL;
1529 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530
Eric Smith0facd772010-02-24 15:42:29 +00001531 /* Get reason and encoding as strings, which they might not be if
1532 they've been modified after we were contructed. */
1533 reason_str = PyObject_Str(uself->reason);
1534 if (reason_str == NULL)
1535 goto done;
1536 encoding_str = PyObject_Str(uself->encoding);
1537 if (encoding_str == NULL)
1538 goto done;
1539
1540 if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001541 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001542 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001543 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001544 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001545 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001546 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001547 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001548 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Eric Smith0facd772010-02-24 15:42:29 +00001549 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001550 fmt,
Eric Smith0facd772010-02-24 15:42:29 +00001551 encoding_str,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001552 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001553 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00001554 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555 }
Eric Smith0facd772010-02-24 15:42:29 +00001556 else {
1557 result = PyUnicode_FromFormat(
1558 "'%U' codec can't encode characters in position %zd-%zd: %U",
1559 encoding_str,
1560 uself->start,
1561 uself->end-1,
1562 reason_str);
1563 }
1564done:
1565 Py_XDECREF(reason_str);
1566 Py_XDECREF(encoding_str);
1567 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568}
1569
1570static PyTypeObject _PyExc_UnicodeEncodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001571 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001572 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001573 sizeof(PyUnicodeErrorObject), 0,
1574 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1575 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1576 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001577 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1578 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001579 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001580 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001581};
1582PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1583
1584PyObject *
1585PyUnicodeEncodeError_Create(
1586 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1587 Py_ssize_t start, Py_ssize_t end, const char *reason)
1588{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00001589 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001590 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001591}
1592
1593
1594/*
1595 * UnicodeDecodeError extends UnicodeError
1596 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001597
1598static int
1599UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1600{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001601 PyUnicodeErrorObject *ude;
1602 const char *data;
1603 Py_ssize_t size;
1604
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1606 return -1;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001607
1608 ude = (PyUnicodeErrorObject *)self;
1609
1610 Py_CLEAR(ude->encoding);
1611 Py_CLEAR(ude->object);
1612 Py_CLEAR(ude->reason);
1613
1614 if (!PyArg_ParseTuple(args, "O!OnnO!",
1615 &PyUnicode_Type, &ude->encoding,
1616 &ude->object,
1617 &ude->start,
1618 &ude->end,
1619 &PyUnicode_Type, &ude->reason)) {
1620 ude->encoding = ude->object = ude->reason = NULL;
1621 return -1;
1622 }
1623
Christian Heimes72b710a2008-05-26 13:28:38 +00001624 if (!PyBytes_Check(ude->object)) {
Guido van Rossum98297ee2007-11-06 21:34:58 +00001625 if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) {
1626 ude->encoding = ude->object = ude->reason = NULL;
1627 return -1;
1628 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001629 ude->object = PyBytes_FromStringAndSize(data, size);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001630 }
1631 else {
1632 Py_INCREF(ude->object);
1633 }
1634
1635 Py_INCREF(ude->encoding);
1636 Py_INCREF(ude->reason);
1637
1638 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001639}
1640
1641static PyObject *
1642UnicodeDecodeError_str(PyObject *self)
1643{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001644 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00001645 PyObject *result = NULL;
1646 PyObject *reason_str = NULL;
1647 PyObject *encoding_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001648
Eric Smith0facd772010-02-24 15:42:29 +00001649 /* Get reason and encoding as strings, which they might not be if
1650 they've been modified after we were contructed. */
1651 reason_str = PyObject_Str(uself->reason);
1652 if (reason_str == NULL)
1653 goto done;
1654 encoding_str = PyObject_Str(uself->encoding);
1655 if (encoding_str == NULL)
1656 goto done;
1657
1658 if (uself->start < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) {
Christian Heimes72b710a2008-05-26 13:28:38 +00001659 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Eric Smith0facd772010-02-24 15:42:29 +00001660 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001661 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Eric Smith0facd772010-02-24 15:42:29 +00001662 encoding_str,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001663 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001664 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00001665 reason_str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001666 }
Eric Smith0facd772010-02-24 15:42:29 +00001667 else {
1668 result = PyUnicode_FromFormat(
1669 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1670 encoding_str,
1671 uself->start,
1672 uself->end-1,
1673 reason_str
1674 );
1675 }
1676done:
1677 Py_XDECREF(reason_str);
1678 Py_XDECREF(encoding_str);
1679 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001680}
1681
1682static PyTypeObject _PyExc_UnicodeDecodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001683 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001684 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685 sizeof(PyUnicodeErrorObject), 0,
1686 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1687 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1688 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001689 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1690 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001692 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001693};
1694PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1695
1696PyObject *
1697PyUnicodeDecodeError_Create(
1698 const char *encoding, const char *object, Py_ssize_t length,
1699 Py_ssize_t start, Py_ssize_t end, const char *reason)
1700{
Victor Stinner7eeb5b52010-06-07 19:57:46 +00001701 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001702 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001703}
1704
1705
1706/*
1707 * UnicodeTranslateError extends UnicodeError
1708 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001709
1710static int
1711UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1712 PyObject *kwds)
1713{
1714 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1715 return -1;
1716
1717 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001718 Py_CLEAR(self->reason);
1719
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001720 if (!PyArg_ParseTuple(args, "O!nnO!",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721 &PyUnicode_Type, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001722 &self->start,
1723 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001724 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001725 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726 return -1;
1727 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001728
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730 Py_INCREF(self->reason);
1731
1732 return 0;
1733}
1734
1735
1736static PyObject *
1737UnicodeTranslateError_str(PyObject *self)
1738{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001739 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Eric Smith0facd772010-02-24 15:42:29 +00001740 PyObject *result = NULL;
1741 PyObject *reason_str = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001742
Eric Smith0facd772010-02-24 15:42:29 +00001743 /* Get reason as a string, which it might not be if it's been
1744 modified after we were contructed. */
1745 reason_str = PyObject_Str(uself->reason);
1746 if (reason_str == NULL)
1747 goto done;
1748
1749 if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001750 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001751 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001752 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001753 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001754 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001755 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001756 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001757 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Benjamin Petersonc5f4e1e2010-02-25 01:22:28 +00001758 result = PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001759 fmt,
1760 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001761 uself->start,
Eric Smith0facd772010-02-24 15:42:29 +00001762 reason_str
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001763 );
Eric Smith0facd772010-02-24 15:42:29 +00001764 } else {
1765 result = PyUnicode_FromFormat(
1766 "can't translate characters in position %zd-%zd: %U",
1767 uself->start,
1768 uself->end-1,
1769 reason_str
1770 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001771 }
Eric Smith0facd772010-02-24 15:42:29 +00001772done:
1773 Py_XDECREF(reason_str);
1774 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775}
1776
1777static PyTypeObject _PyExc_UnicodeTranslateError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001778 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001779 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001780 sizeof(PyUnicodeErrorObject), 0,
1781 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1782 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1783 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001784 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001785 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1786 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001787 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001788};
1789PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1790
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001791/* Deprecated. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001792PyObject *
1793PyUnicodeTranslateError_Create(
1794 const Py_UNICODE *object, Py_ssize_t length,
1795 Py_ssize_t start, Py_ssize_t end, const char *reason)
1796{
1797 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001798 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001799}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001801PyObject *
1802_PyUnicodeTranslateError_Create(
1803 PyObject *object,
1804 Py_ssize_t start, Py_ssize_t end, const char *reason)
1805{
1806 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Ons",
1807 object, start, end, reason);
1808}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001809
1810/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001811 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001812 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001813SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001814 "Assertion failed.");
1815
1816
1817/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001818 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001819 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001820SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821 "Base class for arithmetic errors.");
1822
1823
1824/*
1825 * FloatingPointError extends ArithmeticError
1826 */
1827SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1828 "Floating point operation failed.");
1829
1830
1831/*
1832 * OverflowError extends ArithmeticError
1833 */
1834SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1835 "Result too large to be represented.");
1836
1837
1838/*
1839 * ZeroDivisionError extends ArithmeticError
1840 */
1841SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1842 "Second argument to a division or modulo operation was zero.");
1843
1844
1845/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001846 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001847 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001848SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849 "Internal error in the Python interpreter.\n"
1850 "\n"
1851 "Please report this to the Python maintainer, along with the traceback,\n"
1852 "the Python version, and the hardware/OS platform and version.");
1853
1854
1855/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001856 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001857 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001858SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001859 "Weak ref proxy used after referent went away.");
1860
1861
1862/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001863 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001864 */
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00001865
1866#define MEMERRORS_SAVE 16
1867static PyBaseExceptionObject *memerrors_freelist = NULL;
1868static int memerrors_numfree = 0;
1869
1870static PyObject *
1871MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1872{
1873 PyBaseExceptionObject *self;
1874
1875 if (type != (PyTypeObject *) PyExc_MemoryError)
1876 return BaseException_new(type, args, kwds);
1877 if (memerrors_freelist == NULL)
1878 return BaseException_new(type, args, kwds);
1879 /* Fetch object from freelist and revive it */
1880 self = memerrors_freelist;
1881 self->args = PyTuple_New(0);
1882 /* This shouldn't happen since the empty tuple is persistent */
1883 if (self->args == NULL)
1884 return NULL;
1885 memerrors_freelist = (PyBaseExceptionObject *) self->dict;
1886 memerrors_numfree--;
1887 self->dict = NULL;
1888 _Py_NewReference((PyObject *)self);
1889 _PyObject_GC_TRACK(self);
1890 return (PyObject *)self;
1891}
1892
1893static void
1894MemoryError_dealloc(PyBaseExceptionObject *self)
1895{
1896 _PyObject_GC_UNTRACK(self);
1897 BaseException_clear(self);
1898 if (memerrors_numfree >= MEMERRORS_SAVE)
1899 Py_TYPE(self)->tp_free((PyObject *)self);
1900 else {
1901 self->dict = (PyObject *) memerrors_freelist;
1902 memerrors_freelist = self;
1903 memerrors_numfree++;
1904 }
1905}
1906
1907static void
1908preallocate_memerrors(void)
1909{
1910 /* We create enough MemoryErrors and then decref them, which will fill
1911 up the freelist. */
1912 int i;
1913 PyObject *errors[MEMERRORS_SAVE];
1914 for (i = 0; i < MEMERRORS_SAVE; i++) {
1915 errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError,
1916 NULL, NULL);
1917 if (!errors[i])
1918 Py_FatalError("Could not preallocate MemoryError object");
1919 }
1920 for (i = 0; i < MEMERRORS_SAVE; i++) {
1921 Py_DECREF(errors[i]);
1922 }
1923}
1924
1925static void
1926free_preallocated_memerrors(void)
1927{
1928 while (memerrors_freelist != NULL) {
1929 PyObject *self = (PyObject *) memerrors_freelist;
1930 memerrors_freelist = (PyBaseExceptionObject *) memerrors_freelist->dict;
1931 Py_TYPE(self)->tp_free((PyObject *)self);
1932 }
1933}
1934
1935
1936static PyTypeObject _PyExc_MemoryError = {
1937 PyVarObject_HEAD_INIT(NULL, 0)
1938 "MemoryError",
1939 sizeof(PyBaseExceptionObject),
1940 0, (destructor)MemoryError_dealloc, 0, 0, 0, 0, 0, 0, 0,
1941 0, 0, 0, 0, 0, 0, 0,
1942 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1943 PyDoc_STR("Out of memory."), (traverseproc)BaseException_traverse,
1944 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception,
1945 0, 0, 0, offsetof(PyBaseExceptionObject, dict),
1946 (initproc)BaseException_init, 0, MemoryError_new
1947};
1948PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError;
1949
Thomas Wouters477c8d52006-05-27 19:21:47 +00001950
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001951/*
1952 * BufferError extends Exception
1953 */
1954SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
1955
Thomas Wouters477c8d52006-05-27 19:21:47 +00001956
1957/* Warning category docstrings */
1958
1959/*
1960 * Warning extends Exception
1961 */
1962SimpleExtendsException(PyExc_Exception, Warning,
1963 "Base class for warning categories.");
1964
1965
1966/*
1967 * UserWarning extends Warning
1968 */
1969SimpleExtendsException(PyExc_Warning, UserWarning,
1970 "Base class for warnings generated by user code.");
1971
1972
1973/*
1974 * DeprecationWarning extends Warning
1975 */
1976SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1977 "Base class for warnings about deprecated features.");
1978
1979
1980/*
1981 * PendingDeprecationWarning extends Warning
1982 */
1983SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1984 "Base class for warnings about features which will be deprecated\n"
1985 "in the future.");
1986
1987
1988/*
1989 * SyntaxWarning extends Warning
1990 */
1991SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1992 "Base class for warnings about dubious syntax.");
1993
1994
1995/*
1996 * RuntimeWarning extends Warning
1997 */
1998SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1999 "Base class for warnings about dubious runtime behavior.");
2000
2001
2002/*
2003 * FutureWarning extends Warning
2004 */
2005SimpleExtendsException(PyExc_Warning, FutureWarning,
2006 "Base class for warnings about constructs that will change semantically\n"
2007 "in the future.");
2008
2009
2010/*
2011 * ImportWarning extends Warning
2012 */
2013SimpleExtendsException(PyExc_Warning, ImportWarning,
2014 "Base class for warnings about probable mistakes in module imports");
2015
2016
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002017/*
2018 * UnicodeWarning extends Warning
2019 */
2020SimpleExtendsException(PyExc_Warning, UnicodeWarning,
2021 "Base class for warnings about Unicode related problems, mostly\n"
2022 "related to conversion problems.");
2023
Georg Brandl08be72d2010-10-24 15:11:22 +00002024
Guido van Rossum98297ee2007-11-06 21:34:58 +00002025/*
2026 * BytesWarning extends Warning
2027 */
2028SimpleExtendsException(PyExc_Warning, BytesWarning,
2029 "Base class for warnings about bytes and buffer related problems, mostly\n"
2030 "related to conversion from str or comparing to str.");
2031
2032
Georg Brandl08be72d2010-10-24 15:11:22 +00002033/*
2034 * ResourceWarning extends Warning
2035 */
2036SimpleExtendsException(PyExc_Warning, ResourceWarning,
2037 "Base class for warnings about resource usage.");
2038
2039
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002040
Thomas Wouters89d996e2007-09-08 17:39:28 +00002041/* Pre-computed RuntimeError instance for when recursion depth is reached.
2042 Meant to be used when normalizing the exception for exceeding the recursion
2043 depth will cause its own infinite recursion.
2044*/
2045PyObject *PyExc_RecursionErrorInst = NULL;
2046
Thomas Wouters477c8d52006-05-27 19:21:47 +00002047#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
2048 Py_FatalError("exceptions bootstrapping error.");
2049
2050#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00002051 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
2052 Py_FatalError("Module dictionary insertion problem.");
2053
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002054#define INIT_ALIAS(NAME, TYPE) Py_INCREF(PyExc_ ## TYPE); \
2055 PyExc_ ## NAME = PyExc_ ## TYPE; \
2056 if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) \
2057 Py_FatalError("Module dictionary insertion problem.");
2058
2059#define ADD_ERRNO(TYPE, CODE) { \
2060 PyObject *_code = PyLong_FromLong(CODE); \
2061 assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
2062 if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \
2063 Py_FatalError("errmap insertion problem."); \
2064 }
2065
2066#ifdef MS_WINDOWS
2067#include <Winsock2.h>
2068#if defined(WSAEALREADY) && !defined(EALREADY)
2069#define EALREADY WSAEALREADY
2070#endif
2071#if defined(WSAECONNABORTED) && !defined(ECONNABORTED)
2072#define ECONNABORTED WSAECONNABORTED
2073#endif
2074#if defined(WSAECONNREFUSED) && !defined(ECONNREFUSED)
2075#define ECONNREFUSED WSAECONNREFUSED
2076#endif
2077#if defined(WSAECONNRESET) && !defined(ECONNRESET)
2078#define ECONNRESET WSAECONNRESET
2079#endif
2080#if defined(WSAEINPROGRESS) && !defined(EINPROGRESS)
2081#define EINPROGRESS WSAEINPROGRESS
2082#endif
2083#if defined(WSAESHUTDOWN) && !defined(ESHUTDOWN)
2084#define ESHUTDOWN WSAESHUTDOWN
2085#endif
2086#if defined(WSAETIMEDOUT) && !defined(ETIMEDOUT)
2087#define ETIMEDOUT WSAETIMEDOUT
2088#endif
2089#if defined(WSAEWOULDBLOCK) && !defined(EWOULDBLOCK)
2090#define EWOULDBLOCK WSAEWOULDBLOCK
2091#endif
2092#endif /* MS_WINDOWS */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002093
Martin v. Löwis1a214512008-06-11 05:26:20 +00002094void
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002095_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002096{
Neal Norwitz2633c692007-02-26 22:22:47 +00002097 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002098
2099 PRE_INIT(BaseException)
2100 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101 PRE_INIT(TypeError)
2102 PRE_INIT(StopIteration)
2103 PRE_INIT(GeneratorExit)
2104 PRE_INIT(SystemExit)
2105 PRE_INIT(KeyboardInterrupt)
2106 PRE_INIT(ImportError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002107 PRE_INIT(OSError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002108 PRE_INIT(EOFError)
2109 PRE_INIT(RuntimeError)
2110 PRE_INIT(NotImplementedError)
2111 PRE_INIT(NameError)
2112 PRE_INIT(UnboundLocalError)
2113 PRE_INIT(AttributeError)
2114 PRE_INIT(SyntaxError)
2115 PRE_INIT(IndentationError)
2116 PRE_INIT(TabError)
2117 PRE_INIT(LookupError)
2118 PRE_INIT(IndexError)
2119 PRE_INIT(KeyError)
2120 PRE_INIT(ValueError)
2121 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002122 PRE_INIT(UnicodeEncodeError)
2123 PRE_INIT(UnicodeDecodeError)
2124 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002125 PRE_INIT(AssertionError)
2126 PRE_INIT(ArithmeticError)
2127 PRE_INIT(FloatingPointError)
2128 PRE_INIT(OverflowError)
2129 PRE_INIT(ZeroDivisionError)
2130 PRE_INIT(SystemError)
2131 PRE_INIT(ReferenceError)
Neal Norwitzfaa54a32007-08-19 04:23:20 +00002132 PRE_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002133 PRE_INIT(MemoryError)
Benjamin Peterson2b968d62008-07-05 23:38:30 +00002134 PRE_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002135 PRE_INIT(Warning)
2136 PRE_INIT(UserWarning)
2137 PRE_INIT(DeprecationWarning)
2138 PRE_INIT(PendingDeprecationWarning)
2139 PRE_INIT(SyntaxWarning)
2140 PRE_INIT(RuntimeWarning)
2141 PRE_INIT(FutureWarning)
2142 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002143 PRE_INIT(UnicodeWarning)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002144 PRE_INIT(BytesWarning)
Georg Brandl08be72d2010-10-24 15:11:22 +00002145 PRE_INIT(ResourceWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002146
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002147 /* OSError subclasses */
2148 PRE_INIT(ConnectionError);
2149
2150 PRE_INIT(BlockingIOError);
2151 PRE_INIT(BrokenPipeError);
2152 PRE_INIT(ChildProcessError);
2153 PRE_INIT(ConnectionAbortedError);
2154 PRE_INIT(ConnectionRefusedError);
2155 PRE_INIT(ConnectionResetError);
2156 PRE_INIT(FileExistsError);
2157 PRE_INIT(FileNotFoundError);
2158 PRE_INIT(IsADirectoryError);
2159 PRE_INIT(NotADirectoryError);
2160 PRE_INIT(InterruptedError);
2161 PRE_INIT(PermissionError);
2162 PRE_INIT(ProcessLookupError);
2163 PRE_INIT(TimeoutError);
2164
Georg Brandl1a3284e2007-12-02 09:40:06 +00002165 bltinmod = PyImport_ImportModule("builtins");
Thomas Wouters477c8d52006-05-27 19:21:47 +00002166 if (bltinmod == NULL)
2167 Py_FatalError("exceptions bootstrapping error.");
2168 bdict = PyModule_GetDict(bltinmod);
2169 if (bdict == NULL)
2170 Py_FatalError("exceptions bootstrapping error.");
2171
2172 POST_INIT(BaseException)
2173 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002174 POST_INIT(TypeError)
2175 POST_INIT(StopIteration)
2176 POST_INIT(GeneratorExit)
2177 POST_INIT(SystemExit)
2178 POST_INIT(KeyboardInterrupt)
2179 POST_INIT(ImportError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002180 POST_INIT(OSError)
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002181 INIT_ALIAS(EnvironmentError, OSError)
2182 INIT_ALIAS(IOError, OSError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002183#ifdef MS_WINDOWS
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002184 INIT_ALIAS(WindowsError, OSError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002185#endif
2186#ifdef __VMS
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002187 INIT_ALIAS(VMSError, OSError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002188#endif
2189 POST_INIT(EOFError)
2190 POST_INIT(RuntimeError)
2191 POST_INIT(NotImplementedError)
2192 POST_INIT(NameError)
2193 POST_INIT(UnboundLocalError)
2194 POST_INIT(AttributeError)
2195 POST_INIT(SyntaxError)
2196 POST_INIT(IndentationError)
2197 POST_INIT(TabError)
2198 POST_INIT(LookupError)
2199 POST_INIT(IndexError)
2200 POST_INIT(KeyError)
2201 POST_INIT(ValueError)
2202 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002203 POST_INIT(UnicodeEncodeError)
2204 POST_INIT(UnicodeDecodeError)
2205 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002206 POST_INIT(AssertionError)
2207 POST_INIT(ArithmeticError)
2208 POST_INIT(FloatingPointError)
2209 POST_INIT(OverflowError)
2210 POST_INIT(ZeroDivisionError)
2211 POST_INIT(SystemError)
2212 POST_INIT(ReferenceError)
Neal Norwitzfaa54a32007-08-19 04:23:20 +00002213 POST_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002214 POST_INIT(MemoryError)
Benjamin Peterson2b968d62008-07-05 23:38:30 +00002215 POST_INIT(BufferError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002216 POST_INIT(Warning)
2217 POST_INIT(UserWarning)
2218 POST_INIT(DeprecationWarning)
2219 POST_INIT(PendingDeprecationWarning)
2220 POST_INIT(SyntaxWarning)
2221 POST_INIT(RuntimeWarning)
2222 POST_INIT(FutureWarning)
2223 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002224 POST_INIT(UnicodeWarning)
Guido van Rossum98297ee2007-11-06 21:34:58 +00002225 POST_INIT(BytesWarning)
Georg Brandl08be72d2010-10-24 15:11:22 +00002226 POST_INIT(ResourceWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002227
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002228 errnomap = PyDict_New();
2229 if (!errnomap)
2230 Py_FatalError("Cannot allocate map from errnos to OSError subclasses");
2231
2232 /* OSError subclasses */
2233 POST_INIT(ConnectionError);
2234
2235 POST_INIT(BlockingIOError);
2236 ADD_ERRNO(BlockingIOError, EAGAIN);
2237 ADD_ERRNO(BlockingIOError, EALREADY);
2238 ADD_ERRNO(BlockingIOError, EINPROGRESS);
2239 ADD_ERRNO(BlockingIOError, EWOULDBLOCK);
2240 POST_INIT(BrokenPipeError);
2241 ADD_ERRNO(BrokenPipeError, EPIPE);
2242 ADD_ERRNO(BrokenPipeError, ESHUTDOWN);
2243 POST_INIT(ChildProcessError);
2244 ADD_ERRNO(ChildProcessError, ECHILD);
2245 POST_INIT(ConnectionAbortedError);
2246 ADD_ERRNO(ConnectionAbortedError, ECONNABORTED);
2247 POST_INIT(ConnectionRefusedError);
2248 ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED);
2249 POST_INIT(ConnectionResetError);
2250 ADD_ERRNO(ConnectionResetError, ECONNRESET);
2251 POST_INIT(FileExistsError);
2252 ADD_ERRNO(FileExistsError, EEXIST);
2253 POST_INIT(FileNotFoundError);
2254 ADD_ERRNO(FileNotFoundError, ENOENT);
2255 POST_INIT(IsADirectoryError);
2256 ADD_ERRNO(IsADirectoryError, EISDIR);
2257 POST_INIT(NotADirectoryError);
2258 ADD_ERRNO(NotADirectoryError, ENOTDIR);
2259 POST_INIT(InterruptedError);
2260 ADD_ERRNO(InterruptedError, EINTR);
2261 POST_INIT(PermissionError);
2262 ADD_ERRNO(PermissionError, EACCES);
2263 ADD_ERRNO(PermissionError, EPERM);
2264 POST_INIT(ProcessLookupError);
2265 ADD_ERRNO(ProcessLookupError, ESRCH);
2266 POST_INIT(TimeoutError);
2267 ADD_ERRNO(TimeoutError, ETIMEDOUT);
2268
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002269 preallocate_memerrors();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002270
Thomas Wouters89d996e2007-09-08 17:39:28 +00002271 PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
2272 if (!PyExc_RecursionErrorInst)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 Py_FatalError("Cannot pre-allocate RuntimeError instance for "
2274 "recursion errors");
Thomas Wouters89d996e2007-09-08 17:39:28 +00002275 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 PyBaseExceptionObject *err_inst =
2277 (PyBaseExceptionObject *)PyExc_RecursionErrorInst;
2278 PyObject *args_tuple;
2279 PyObject *exc_message;
2280 exc_message = PyUnicode_FromString("maximum recursion depth exceeded");
2281 if (!exc_message)
2282 Py_FatalError("cannot allocate argument for RuntimeError "
2283 "pre-allocation");
2284 args_tuple = PyTuple_Pack(1, exc_message);
2285 if (!args_tuple)
2286 Py_FatalError("cannot allocate tuple for RuntimeError "
2287 "pre-allocation");
2288 Py_DECREF(exc_message);
2289 if (BaseException_init(err_inst, args_tuple, NULL))
2290 Py_FatalError("init of pre-allocated RuntimeError failed");
2291 Py_DECREF(args_tuple);
Thomas Wouters89d996e2007-09-08 17:39:28 +00002292 }
2293
Thomas Wouters477c8d52006-05-27 19:21:47 +00002294 Py_DECREF(bltinmod);
2295}
2296
2297void
2298_PyExc_Fini(void)
2299{
Benjamin Peterson78565b22009-06-28 19:19:51 +00002300 Py_CLEAR(PyExc_RecursionErrorInst);
Antoine Pitrou07e20ef2010-10-28 22:56:58 +00002301 free_preallocated_memerrors();
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02002302 Py_CLEAR(errnomap);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002303}