blob: 6832fd96ab62528f49d6be13f2eba8064f2b36ec [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
12#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +000013
14/* NOTE: If the exception class hierarchy changes, don't forget to update
15 * Lib/test/exception_hierarchy.txt
16 */
17
Thomas Wouters477c8d52006-05-27 19:21:47 +000018/*
19 * BaseException
20 */
21static PyObject *
22BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyBaseExceptionObject *self;
25
26 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
27 /* the dict is created on the fly in PyObject_GenericSetAttr */
28 self->message = self->dict = NULL;
29
30 self->args = PyTuple_New(0);
31 if (!self->args) {
32 Py_DECREF(self);
33 return NULL;
34 }
35
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000036 self->message = PyString_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000037 if (!self->message) {
38 Py_DECREF(self);
39 return NULL;
40 }
41
42 return (PyObject *)self;
43}
44
45static int
46BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
47{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000048 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
49 return -1;
50
Thomas Wouters477c8d52006-05-27 19:21:47 +000051 Py_DECREF(self->args);
52 self->args = args;
53 Py_INCREF(self->args);
54
55 if (PyTuple_GET_SIZE(self->args) == 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000056 Py_CLEAR(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000057 self->message = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000058 Py_INCREF(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000059 }
60 return 0;
61}
62
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000063static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000064BaseException_clear(PyBaseExceptionObject *self)
65{
66 Py_CLEAR(self->dict);
67 Py_CLEAR(self->args);
68 Py_CLEAR(self->message);
69 return 0;
70}
71
72static void
73BaseException_dealloc(PyBaseExceptionObject *self)
74{
Thomas Wouters89f507f2006-12-13 04:49:30 +000075 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000076 BaseException_clear(self);
77 self->ob_type->tp_free((PyObject *)self);
78}
79
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000080static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000081BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
82{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000083 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 Py_VISIT(self->args);
85 Py_VISIT(self->message);
86 return 0;
87}
88
89static PyObject *
90BaseException_str(PyBaseExceptionObject *self)
91{
92 PyObject *out;
93
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000094 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000095 case 0:
96 out = PyString_FromString("");
97 break;
98 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000099 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000100 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000101 default:
102 out = PyObject_Str(self->args);
103 break;
104 }
105
106 return out;
107}
108
109static PyObject *
110BaseException_repr(PyBaseExceptionObject *self)
111{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112 PyObject *repr_suffix;
113 PyObject *repr;
114 char *name;
115 char *dot;
116
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000117 repr_suffix = PyObject_Repr(self->args);
118 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000119 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000120
121 name = (char *)self->ob_type->tp_name;
122 dot = strrchr(name, '.');
123 if (dot != NULL) name = dot+1;
124
125 repr = PyString_FromString(name);
126 if (!repr) {
127 Py_DECREF(repr_suffix);
128 return NULL;
129 }
130
131 PyString_ConcatAndDel(&repr, repr_suffix);
132 return repr;
133}
134
135/* Pickling support */
136static PyObject *
137BaseException_reduce(PyBaseExceptionObject *self)
138{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000139 if (self->args && self->dict)
140 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
141 else
142 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000143}
144
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000145/*
146 * Needed for backward compatibility, since exceptions used to store
147 * all their attributes in the __dict__. Code is taken from cPickle's
148 * load_build function.
149 */
150static PyObject *
151BaseException_setstate(PyObject *self, PyObject *state)
152{
153 PyObject *d_key, *d_value;
154 Py_ssize_t i = 0;
155
156 if (state != Py_None) {
157 if (!PyDict_Check(state)) {
158 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
159 return NULL;
160 }
161 while (PyDict_Next(state, &i, &d_key, &d_value)) {
162 if (PyObject_SetAttr(self, d_key, d_value) < 0)
163 return NULL;
164 }
165 }
166 Py_RETURN_NONE;
167}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000168
Thomas Wouters477c8d52006-05-27 19:21:47 +0000169
170static PyMethodDef BaseException_methods[] = {
171 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000172 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000173 {NULL, NULL, 0, NULL},
174};
175
176
Thomas Wouters477c8d52006-05-27 19:21:47 +0000177static PyMemberDef BaseException_members[] = {
178 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
179 PyDoc_STR("exception message")},
180 {NULL} /* Sentinel */
181};
182
183
184static PyObject *
185BaseException_get_dict(PyBaseExceptionObject *self)
186{
187 if (self->dict == NULL) {
188 self->dict = PyDict_New();
189 if (!self->dict)
190 return NULL;
191 }
192 Py_INCREF(self->dict);
193 return self->dict;
194}
195
196static int
197BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
198{
199 if (val == NULL) {
200 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
201 return -1;
202 }
203 if (!PyDict_Check(val)) {
204 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
205 return -1;
206 }
207 Py_CLEAR(self->dict);
208 Py_INCREF(val);
209 self->dict = val;
210 return 0;
211}
212
213static PyObject *
214BaseException_get_args(PyBaseExceptionObject *self)
215{
216 if (self->args == NULL) {
217 Py_INCREF(Py_None);
218 return Py_None;
219 }
220 Py_INCREF(self->args);
221 return self->args;
222}
223
224static int
225BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
226{
227 PyObject *seq;
228 if (val == NULL) {
229 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
230 return -1;
231 }
232 seq = PySequence_Tuple(val);
233 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000234 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000235 self->args = seq;
236 return 0;
237}
238
239static PyGetSetDef BaseException_getset[] = {
240 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
241 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
242 {NULL},
243};
244
245
246static PyTypeObject _PyExc_BaseException = {
247 PyObject_HEAD_INIT(NULL)
248 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000249 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000250 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
251 0, /*tp_itemsize*/
252 (destructor)BaseException_dealloc, /*tp_dealloc*/
253 0, /*tp_print*/
254 0, /*tp_getattr*/
255 0, /*tp_setattr*/
256 0, /* tp_compare; */
257 (reprfunc)BaseException_repr, /*tp_repr*/
258 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000259 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000260 0, /*tp_as_mapping*/
261 0, /*tp_hash */
262 0, /*tp_call*/
263 (reprfunc)BaseException_str, /*tp_str*/
264 PyObject_GenericGetAttr, /*tp_getattro*/
265 PyObject_GenericSetAttr, /*tp_setattro*/
266 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000267 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
268 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000269 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
270 (traverseproc)BaseException_traverse, /* tp_traverse */
271 (inquiry)BaseException_clear, /* tp_clear */
272 0, /* tp_richcompare */
273 0, /* tp_weaklistoffset */
274 0, /* tp_iter */
275 0, /* tp_iternext */
276 BaseException_methods, /* tp_methods */
277 BaseException_members, /* tp_members */
278 BaseException_getset, /* tp_getset */
279 0, /* tp_base */
280 0, /* tp_dict */
281 0, /* tp_descr_get */
282 0, /* tp_descr_set */
283 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
284 (initproc)BaseException_init, /* tp_init */
285 0, /* tp_alloc */
286 BaseException_new, /* tp_new */
287};
288/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
289from the previous implmentation and also allowing Python objects to be used
290in the API */
291PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
292
293/* note these macros omit the last semicolon so the macro invocation may
294 * include it and not look strange.
295 */
296#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
297static PyTypeObject _PyExc_ ## EXCNAME = { \
298 PyObject_HEAD_INIT(NULL) \
299 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000300 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000301 sizeof(PyBaseExceptionObject), \
302 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
303 0, 0, 0, 0, 0, 0, 0, \
304 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
305 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
306 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
307 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
308 (initproc)BaseException_init, 0, BaseException_new,\
309}; \
310PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
311
312#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
313static PyTypeObject _PyExc_ ## EXCNAME = { \
314 PyObject_HEAD_INIT(NULL) \
315 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000316 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000318 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319 0, 0, 0, 0, 0, \
320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000321 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
322 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000323 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000324 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325}; \
326PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
327
328#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
329static PyTypeObject _PyExc_ ## EXCNAME = { \
330 PyObject_HEAD_INIT(NULL) \
331 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000332 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000333 sizeof(Py ## EXCSTORE ## Object), 0, \
334 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
335 (reprfunc)EXCSTR, 0, 0, 0, \
336 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
337 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
338 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
339 EXCMEMBERS, 0, &_ ## EXCBASE, \
340 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000341 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000342}; \
343PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
344
345
346/*
347 * Exception extends BaseException
348 */
349SimpleExtendsException(PyExc_BaseException, Exception,
350 "Common base class for all non-exit exceptions.");
351
352
353/*
354 * StandardError extends Exception
355 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000356SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000357 "Base class for all standard Python exceptions that do not represent\n"
358 "interpreter exiting.");
359
360
361/*
362 * TypeError extends StandardError
363 */
364SimpleExtendsException(PyExc_StandardError, TypeError,
365 "Inappropriate argument type.");
366
367
368/*
369 * StopIteration extends Exception
370 */
371SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000372 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000373
374
375/*
376 * GeneratorExit extends Exception
377 */
378SimpleExtendsException(PyExc_Exception, GeneratorExit,
379 "Request that a generator exit.");
380
381
382/*
383 * SystemExit extends BaseException
384 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000385
386static int
387SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
388{
389 Py_ssize_t size = PyTuple_GET_SIZE(args);
390
391 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
392 return -1;
393
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000394 if (size == 0)
395 return 0;
396 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000397 if (size == 1)
398 self->code = PyTuple_GET_ITEM(args, 0);
399 else if (size > 1)
400 self->code = args;
401 Py_INCREF(self->code);
402 return 0;
403}
404
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000405static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406SystemExit_clear(PySystemExitObject *self)
407{
408 Py_CLEAR(self->code);
409 return BaseException_clear((PyBaseExceptionObject *)self);
410}
411
412static void
413SystemExit_dealloc(PySystemExitObject *self)
414{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000415 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416 SystemExit_clear(self);
417 self->ob_type->tp_free((PyObject *)self);
418}
419
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000420static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
422{
423 Py_VISIT(self->code);
424 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
425}
426
427static PyMemberDef SystemExit_members[] = {
428 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
429 PyDoc_STR("exception message")},
430 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
431 PyDoc_STR("exception code")},
432 {NULL} /* Sentinel */
433};
434
435ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
436 SystemExit_dealloc, 0, SystemExit_members, 0,
437 "Request to exit from the interpreter.");
438
439/*
440 * KeyboardInterrupt extends BaseException
441 */
442SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
443 "Program interrupted by user.");
444
445
446/*
447 * ImportError extends StandardError
448 */
449SimpleExtendsException(PyExc_StandardError, ImportError,
450 "Import can't find module, or can't find name in module.");
451
452
453/*
454 * EnvironmentError extends StandardError
455 */
456
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457/* Where a function has a single filename, such as open() or some
458 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
459 * called, giving a third argument which is the filename. But, so
460 * that old code using in-place unpacking doesn't break, e.g.:
461 *
462 * except IOError, (errno, strerror):
463 *
464 * we hack args so that it only contains two items. This also
465 * means we need our own __str__() which prints out the filename
466 * when it was supplied.
467 */
468static int
469EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
470 PyObject *kwds)
471{
472 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
473 PyObject *subslice = NULL;
474
475 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
476 return -1;
477
Thomas Wouters89f507f2006-12-13 04:49:30 +0000478 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479 return 0;
480 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000481
482 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000483 &myerrno, &strerror, &filename)) {
484 return -1;
485 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000486 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487 self->myerrno = myerrno;
488 Py_INCREF(self->myerrno);
489
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000490 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491 self->strerror = strerror;
492 Py_INCREF(self->strerror);
493
494 /* self->filename will remain Py_None otherwise */
495 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000496 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000497 self->filename = filename;
498 Py_INCREF(self->filename);
499
500 subslice = PyTuple_GetSlice(args, 0, 2);
501 if (!subslice)
502 return -1;
503
504 Py_DECREF(self->args); /* replacing args */
505 self->args = subslice;
506 }
507 return 0;
508}
509
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000510static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000511EnvironmentError_clear(PyEnvironmentErrorObject *self)
512{
513 Py_CLEAR(self->myerrno);
514 Py_CLEAR(self->strerror);
515 Py_CLEAR(self->filename);
516 return BaseException_clear((PyBaseExceptionObject *)self);
517}
518
519static void
520EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
521{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000522 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000523 EnvironmentError_clear(self);
524 self->ob_type->tp_free((PyObject *)self);
525}
526
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000527static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000528EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
529 void *arg)
530{
531 Py_VISIT(self->myerrno);
532 Py_VISIT(self->strerror);
533 Py_VISIT(self->filename);
534 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
535}
536
537static PyObject *
538EnvironmentError_str(PyEnvironmentErrorObject *self)
539{
540 PyObject *rtnval = NULL;
541
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000542 if (self->filename) {
543 PyObject *fmt;
544 PyObject *repr;
545 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000546
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000547 fmt = PyString_FromString("[Errno %s] %s: %s");
548 if (!fmt)
549 return NULL;
550
551 repr = PyObject_Repr(self->filename);
552 if (!repr) {
553 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000554 return NULL;
555 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000556 tuple = PyTuple_New(3);
557 if (!tuple) {
558 Py_DECREF(repr);
559 Py_DECREF(fmt);
560 return NULL;
561 }
562
563 if (self->myerrno) {
564 Py_INCREF(self->myerrno);
565 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
566 }
567 else {
568 Py_INCREF(Py_None);
569 PyTuple_SET_ITEM(tuple, 0, Py_None);
570 }
571 if (self->strerror) {
572 Py_INCREF(self->strerror);
573 PyTuple_SET_ITEM(tuple, 1, self->strerror);
574 }
575 else {
576 Py_INCREF(Py_None);
577 PyTuple_SET_ITEM(tuple, 1, Py_None);
578 }
579
Thomas Wouters477c8d52006-05-27 19:21:47 +0000580 PyTuple_SET_ITEM(tuple, 2, repr);
581
582 rtnval = PyString_Format(fmt, tuple);
583
584 Py_DECREF(fmt);
585 Py_DECREF(tuple);
586 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000587 else if (self->myerrno && self->strerror) {
588 PyObject *fmt;
589 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000590
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000591 fmt = PyString_FromString("[Errno %s] %s");
592 if (!fmt)
593 return NULL;
594
595 tuple = PyTuple_New(2);
596 if (!tuple) {
597 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598 return NULL;
599 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000600
601 if (self->myerrno) {
602 Py_INCREF(self->myerrno);
603 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
604 }
605 else {
606 Py_INCREF(Py_None);
607 PyTuple_SET_ITEM(tuple, 0, Py_None);
608 }
609 if (self->strerror) {
610 Py_INCREF(self->strerror);
611 PyTuple_SET_ITEM(tuple, 1, self->strerror);
612 }
613 else {
614 Py_INCREF(Py_None);
615 PyTuple_SET_ITEM(tuple, 1, Py_None);
616 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617
618 rtnval = PyString_Format(fmt, tuple);
619
620 Py_DECREF(fmt);
621 Py_DECREF(tuple);
622 }
623 else
624 rtnval = BaseException_str((PyBaseExceptionObject *)self);
625
626 return rtnval;
627}
628
629static PyMemberDef EnvironmentError_members[] = {
630 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
631 PyDoc_STR("exception message")},
632 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
633 PyDoc_STR("exception errno")},
634 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
635 PyDoc_STR("exception strerror")},
636 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
637 PyDoc_STR("exception filename")},
638 {NULL} /* Sentinel */
639};
640
641
642static PyObject *
643EnvironmentError_reduce(PyEnvironmentErrorObject *self)
644{
645 PyObject *args = self->args;
646 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000647
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648 /* self->args is only the first two real arguments if there was a
649 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000650 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000651 args = PyTuple_New(3);
652 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000653
654 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000655 Py_INCREF(tmp);
656 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000657
658 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659 Py_INCREF(tmp);
660 PyTuple_SET_ITEM(args, 1, tmp);
661
662 Py_INCREF(self->filename);
663 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000664 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000666
667 if (self->dict)
668 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
669 else
670 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671 Py_DECREF(args);
672 return res;
673}
674
675
676static PyMethodDef EnvironmentError_methods[] = {
677 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
678 {NULL}
679};
680
681ComplexExtendsException(PyExc_StandardError, EnvironmentError,
682 EnvironmentError, EnvironmentError_dealloc,
683 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000684 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000685 "Base class for I/O related errors.");
686
687
688/*
689 * IOError extends EnvironmentError
690 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000691MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692 EnvironmentError, "I/O operation failed.");
693
694
695/*
696 * OSError extends EnvironmentError
697 */
698MiddlingExtendsException(PyExc_EnvironmentError, OSError,
699 EnvironmentError, "OS system call failed.");
700
701
702/*
703 * WindowsError extends OSError
704 */
705#ifdef MS_WINDOWS
706#include "errmap.h"
707
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000708static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709WindowsError_clear(PyWindowsErrorObject *self)
710{
711 Py_CLEAR(self->myerrno);
712 Py_CLEAR(self->strerror);
713 Py_CLEAR(self->filename);
714 Py_CLEAR(self->winerror);
715 return BaseException_clear((PyBaseExceptionObject *)self);
716}
717
718static void
719WindowsError_dealloc(PyWindowsErrorObject *self)
720{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000721 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000722 WindowsError_clear(self);
723 self->ob_type->tp_free((PyObject *)self);
724}
725
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000726static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
728{
729 Py_VISIT(self->myerrno);
730 Py_VISIT(self->strerror);
731 Py_VISIT(self->filename);
732 Py_VISIT(self->winerror);
733 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
734}
735
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736static int
737WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
738{
739 PyObject *o_errcode = NULL;
740 long errcode;
741 long posix_errno;
742
743 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
744 == -1)
745 return -1;
746
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000747 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000748 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749
750 /* Set errno to the POSIX errno, and winerror to the Win32
751 error code. */
752 errcode = PyInt_AsLong(self->myerrno);
753 if (errcode == -1 && PyErr_Occurred())
754 return -1;
755 posix_errno = winerror_to_errno(errcode);
756
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000757 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758 self->winerror = self->myerrno;
759
760 o_errcode = PyInt_FromLong(posix_errno);
761 if (!o_errcode)
762 return -1;
763
764 self->myerrno = o_errcode;
765
766 return 0;
767}
768
769
770static PyObject *
771WindowsError_str(PyWindowsErrorObject *self)
772{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000773 PyObject *rtnval = NULL;
774
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000775 if (self->filename) {
776 PyObject *fmt;
777 PyObject *repr;
778 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000779
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000780 fmt = PyString_FromString("[Error %s] %s: %s");
781 if (!fmt)
782 return NULL;
783
784 repr = PyObject_Repr(self->filename);
785 if (!repr) {
786 Py_DECREF(fmt);
787 return NULL;
788 }
789 tuple = PyTuple_New(3);
790 if (!tuple) {
791 Py_DECREF(repr);
792 Py_DECREF(fmt);
793 return NULL;
794 }
795
Thomas Wouters89f507f2006-12-13 04:49:30 +0000796 if (self->winerror) {
797 Py_INCREF(self->winerror);
798 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000799 }
800 else {
801 Py_INCREF(Py_None);
802 PyTuple_SET_ITEM(tuple, 0, Py_None);
803 }
804 if (self->strerror) {
805 Py_INCREF(self->strerror);
806 PyTuple_SET_ITEM(tuple, 1, self->strerror);
807 }
808 else {
809 Py_INCREF(Py_None);
810 PyTuple_SET_ITEM(tuple, 1, Py_None);
811 }
812
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000813 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000814
815 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816
817 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818 Py_DECREF(tuple);
819 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000820 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000821 PyObject *fmt;
822 PyObject *tuple;
823
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824 fmt = PyString_FromString("[Error %s] %s");
825 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000826 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000827
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000828 tuple = PyTuple_New(2);
829 if (!tuple) {
830 Py_DECREF(fmt);
831 return NULL;
832 }
833
Thomas Wouters89f507f2006-12-13 04:49:30 +0000834 if (self->winerror) {
835 Py_INCREF(self->winerror);
836 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000837 }
838 else {
839 Py_INCREF(Py_None);
840 PyTuple_SET_ITEM(tuple, 0, Py_None);
841 }
842 if (self->strerror) {
843 Py_INCREF(self->strerror);
844 PyTuple_SET_ITEM(tuple, 1, self->strerror);
845 }
846 else {
847 Py_INCREF(Py_None);
848 PyTuple_SET_ITEM(tuple, 1, Py_None);
849 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850
851 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000852
853 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854 Py_DECREF(tuple);
855 }
856 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000857 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000858
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859 return rtnval;
860}
861
862static PyMemberDef WindowsError_members[] = {
863 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
864 PyDoc_STR("exception message")},
865 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
866 PyDoc_STR("POSIX exception code")},
867 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
868 PyDoc_STR("exception strerror")},
869 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
870 PyDoc_STR("exception filename")},
871 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
872 PyDoc_STR("Win32 exception code")},
873 {NULL} /* Sentinel */
874};
875
876ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
877 WindowsError_dealloc, 0, WindowsError_members,
878 WindowsError_str, "MS-Windows OS system call failed.");
879
880#endif /* MS_WINDOWS */
881
882
883/*
884 * VMSError extends OSError (I think)
885 */
886#ifdef __VMS
887MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
888 "OpenVMS OS system call failed.");
889#endif
890
891
892/*
893 * EOFError extends StandardError
894 */
895SimpleExtendsException(PyExc_StandardError, EOFError,
896 "Read beyond end of file.");
897
898
899/*
900 * RuntimeError extends StandardError
901 */
902SimpleExtendsException(PyExc_StandardError, RuntimeError,
903 "Unspecified run-time error.");
904
905
906/*
907 * NotImplementedError extends RuntimeError
908 */
909SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
910 "Method or function hasn't been implemented yet.");
911
912/*
913 * NameError extends StandardError
914 */
915SimpleExtendsException(PyExc_StandardError, NameError,
916 "Name not found globally.");
917
918/*
919 * UnboundLocalError extends NameError
920 */
921SimpleExtendsException(PyExc_NameError, UnboundLocalError,
922 "Local name referenced but not bound to a value.");
923
924/*
925 * AttributeError extends StandardError
926 */
927SimpleExtendsException(PyExc_StandardError, AttributeError,
928 "Attribute not found.");
929
930
931/*
932 * SyntaxError extends StandardError
933 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000934
935static int
936SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
937{
938 PyObject *info = NULL;
939 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
940
941 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
942 return -1;
943
944 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000945 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000946 self->msg = PyTuple_GET_ITEM(args, 0);
947 Py_INCREF(self->msg);
948 }
949 if (lenargs == 2) {
950 info = PyTuple_GET_ITEM(args, 1);
951 info = PySequence_Tuple(info);
952 if (!info) return -1;
953
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000954 if (PyTuple_GET_SIZE(info) != 4) {
955 /* not a very good error message, but it's what Python 2.4 gives */
956 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
957 Py_DECREF(info);
958 return -1;
959 }
960
961 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000962 self->filename = PyTuple_GET_ITEM(info, 0);
963 Py_INCREF(self->filename);
964
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000965 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000966 self->lineno = PyTuple_GET_ITEM(info, 1);
967 Py_INCREF(self->lineno);
968
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000969 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000970 self->offset = PyTuple_GET_ITEM(info, 2);
971 Py_INCREF(self->offset);
972
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000973 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000974 self->text = PyTuple_GET_ITEM(info, 3);
975 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000976
977 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000978 }
979 return 0;
980}
981
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000982static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000983SyntaxError_clear(PySyntaxErrorObject *self)
984{
985 Py_CLEAR(self->msg);
986 Py_CLEAR(self->filename);
987 Py_CLEAR(self->lineno);
988 Py_CLEAR(self->offset);
989 Py_CLEAR(self->text);
990 Py_CLEAR(self->print_file_and_line);
991 return BaseException_clear((PyBaseExceptionObject *)self);
992}
993
994static void
995SyntaxError_dealloc(PySyntaxErrorObject *self)
996{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000997 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998 SyntaxError_clear(self);
999 self->ob_type->tp_free((PyObject *)self);
1000}
1001
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001002static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1004{
1005 Py_VISIT(self->msg);
1006 Py_VISIT(self->filename);
1007 Py_VISIT(self->lineno);
1008 Py_VISIT(self->offset);
1009 Py_VISIT(self->text);
1010 Py_VISIT(self->print_file_and_line);
1011 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1012}
1013
1014/* This is called "my_basename" instead of just "basename" to avoid name
1015 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1016 defined, and Python does define that. */
1017static char *
1018my_basename(char *name)
1019{
1020 char *cp = name;
1021 char *result = name;
1022
1023 if (name == NULL)
1024 return "???";
1025 while (*cp != '\0') {
1026 if (*cp == SEP)
1027 result = cp + 1;
1028 ++cp;
1029 }
1030 return result;
1031}
1032
1033
1034static PyObject *
1035SyntaxError_str(PySyntaxErrorObject *self)
1036{
1037 PyObject *str;
1038 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001039 int have_filename = 0;
1040 int have_lineno = 0;
1041 char *buffer = NULL;
1042 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001043
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001044 if (self->msg)
1045 str = PyObject_Str(self->msg);
1046 else
1047 str = PyObject_Str(Py_None);
1048 if (!str) return NULL;
1049 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1050 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051
1052 /* XXX -- do all the additional formatting with filename and
1053 lineno here */
1054
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001055 have_filename = (self->filename != NULL) &&
1056 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001057 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001059 if (!have_filename && !have_lineno)
1060 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001061
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001062 bufsize = PyString_GET_SIZE(str) + 64;
1063 if (have_filename)
1064 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001065
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001066 buffer = PyMem_MALLOC(bufsize);
1067 if (buffer == NULL)
1068 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001070 if (have_filename && have_lineno)
1071 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1072 PyString_AS_STRING(str),
1073 my_basename(PyString_AS_STRING(self->filename)),
1074 PyInt_AsLong(self->lineno));
1075 else if (have_filename)
1076 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1077 PyString_AS_STRING(str),
1078 my_basename(PyString_AS_STRING(self->filename)));
1079 else /* only have_lineno */
1080 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1081 PyString_AS_STRING(str),
1082 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001083
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001084 result = PyString_FromString(buffer);
1085 PyMem_FREE(buffer);
1086
1087 if (result == NULL)
1088 result = str;
1089 else
1090 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001091 return result;
1092}
1093
1094static PyMemberDef SyntaxError_members[] = {
1095 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1096 PyDoc_STR("exception message")},
1097 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1098 PyDoc_STR("exception msg")},
1099 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1100 PyDoc_STR("exception filename")},
1101 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1102 PyDoc_STR("exception lineno")},
1103 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1104 PyDoc_STR("exception offset")},
1105 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1106 PyDoc_STR("exception text")},
1107 {"print_file_and_line", T_OBJECT,
1108 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1109 PyDoc_STR("exception print_file_and_line")},
1110 {NULL} /* Sentinel */
1111};
1112
1113ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1114 SyntaxError_dealloc, 0, SyntaxError_members,
1115 SyntaxError_str, "Invalid syntax.");
1116
1117
1118/*
1119 * IndentationError extends SyntaxError
1120 */
1121MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1122 "Improper indentation.");
1123
1124
1125/*
1126 * TabError extends IndentationError
1127 */
1128MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1129 "Improper mixture of spaces and tabs.");
1130
1131
1132/*
1133 * LookupError extends StandardError
1134 */
1135SimpleExtendsException(PyExc_StandardError, LookupError,
1136 "Base class for lookup errors.");
1137
1138
1139/*
1140 * IndexError extends LookupError
1141 */
1142SimpleExtendsException(PyExc_LookupError, IndexError,
1143 "Sequence index out of range.");
1144
1145
1146/*
1147 * KeyError extends LookupError
1148 */
1149static PyObject *
1150KeyError_str(PyBaseExceptionObject *self)
1151{
1152 /* If args is a tuple of exactly one item, apply repr to args[0].
1153 This is done so that e.g. the exception raised by {}[''] prints
1154 KeyError: ''
1155 rather than the confusing
1156 KeyError
1157 alone. The downside is that if KeyError is raised with an explanatory
1158 string, that string will be displayed in quotes. Too bad.
1159 If args is anything else, use the default BaseException__str__().
1160 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001161 if (PyTuple_GET_SIZE(self->args) == 1) {
1162 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163 }
1164 return BaseException_str(self);
1165}
1166
1167ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1168 0, 0, 0, KeyError_str, "Mapping key not found.");
1169
1170
1171/*
1172 * ValueError extends StandardError
1173 */
1174SimpleExtendsException(PyExc_StandardError, ValueError,
1175 "Inappropriate argument value (of correct type).");
1176
1177/*
1178 * UnicodeError extends ValueError
1179 */
1180
1181SimpleExtendsException(PyExc_ValueError, UnicodeError,
1182 "Unicode related error.");
1183
1184#ifdef Py_USING_UNICODE
1185static int
1186get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1187{
1188 if (!attr) {
1189 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1190 return -1;
1191 }
1192
Guido van Rossumddefaf32007-01-14 03:31:43 +00001193 if (PyLong_Check(attr)) {
1194 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001195 if (*value == -1 && PyErr_Occurred())
1196 return -1;
1197 } else {
1198 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1199 return -1;
1200 }
1201 return 0;
1202}
1203
1204static int
1205set_ssize_t(PyObject **attr, Py_ssize_t value)
1206{
1207 PyObject *obj = PyInt_FromSsize_t(value);
1208 if (!obj)
1209 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001210 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211 *attr = obj;
1212 return 0;
1213}
1214
1215static PyObject *
1216get_string(PyObject *attr, const char *name)
1217{
1218 if (!attr) {
1219 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1220 return NULL;
1221 }
1222
1223 if (!PyString_Check(attr)) {
1224 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1225 return NULL;
1226 }
1227 Py_INCREF(attr);
1228 return attr;
1229}
1230
1231
1232static int
1233set_string(PyObject **attr, const char *value)
1234{
1235 PyObject *obj = PyString_FromString(value);
1236 if (!obj)
1237 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001238 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001239 *attr = obj;
1240 return 0;
1241}
1242
1243
1244static PyObject *
1245get_unicode(PyObject *attr, const char *name)
1246{
1247 if (!attr) {
1248 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1249 return NULL;
1250 }
1251
1252 if (!PyUnicode_Check(attr)) {
1253 PyErr_Format(PyExc_TypeError,
1254 "%.200s attribute must be unicode", name);
1255 return NULL;
1256 }
1257 Py_INCREF(attr);
1258 return attr;
1259}
1260
1261PyObject *
1262PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1263{
1264 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1265}
1266
1267PyObject *
1268PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1269{
1270 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1271}
1272
1273PyObject *
1274PyUnicodeEncodeError_GetObject(PyObject *exc)
1275{
1276 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1277}
1278
1279PyObject *
1280PyUnicodeDecodeError_GetObject(PyObject *exc)
1281{
1282 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1283}
1284
1285PyObject *
1286PyUnicodeTranslateError_GetObject(PyObject *exc)
1287{
1288 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1289}
1290
1291int
1292PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1293{
1294 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1295 Py_ssize_t size;
1296 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1297 "object");
1298 if (!obj) return -1;
1299 size = PyUnicode_GET_SIZE(obj);
1300 if (*start<0)
1301 *start = 0; /*XXX check for values <0*/
1302 if (*start>=size)
1303 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001304 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001305 return 0;
1306 }
1307 return -1;
1308}
1309
1310
1311int
1312PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1313{
1314 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1315 Py_ssize_t size;
1316 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1317 "object");
1318 if (!obj) return -1;
1319 size = PyString_GET_SIZE(obj);
1320 if (*start<0)
1321 *start = 0;
1322 if (*start>=size)
1323 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001324 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001325 return 0;
1326 }
1327 return -1;
1328}
1329
1330
1331int
1332PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1333{
1334 return PyUnicodeEncodeError_GetStart(exc, start);
1335}
1336
1337
1338int
1339PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1340{
1341 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1342}
1343
1344
1345int
1346PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1347{
1348 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1349}
1350
1351
1352int
1353PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1354{
1355 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1356}
1357
1358
1359int
1360PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1361{
1362 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1363 Py_ssize_t size;
1364 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1365 "object");
1366 if (!obj) return -1;
1367 size = PyUnicode_GET_SIZE(obj);
1368 if (*end<1)
1369 *end = 1;
1370 if (*end>size)
1371 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001372 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373 return 0;
1374 }
1375 return -1;
1376}
1377
1378
1379int
1380PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1381{
1382 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1383 Py_ssize_t size;
1384 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1385 "object");
1386 if (!obj) return -1;
1387 size = PyString_GET_SIZE(obj);
1388 if (*end<1)
1389 *end = 1;
1390 if (*end>size)
1391 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001392 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001393 return 0;
1394 }
1395 return -1;
1396}
1397
1398
1399int
1400PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1401{
1402 return PyUnicodeEncodeError_GetEnd(exc, start);
1403}
1404
1405
1406int
1407PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1408{
1409 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1410}
1411
1412
1413int
1414PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1415{
1416 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1417}
1418
1419
1420int
1421PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1422{
1423 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1424}
1425
1426PyObject *
1427PyUnicodeEncodeError_GetReason(PyObject *exc)
1428{
1429 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1430}
1431
1432
1433PyObject *
1434PyUnicodeDecodeError_GetReason(PyObject *exc)
1435{
1436 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1437}
1438
1439
1440PyObject *
1441PyUnicodeTranslateError_GetReason(PyObject *exc)
1442{
1443 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1444}
1445
1446
1447int
1448PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1449{
1450 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1451}
1452
1453
1454int
1455PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1456{
1457 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1458}
1459
1460
1461int
1462PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1463{
1464 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1465}
1466
1467
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468static int
1469UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1470 PyTypeObject *objecttype)
1471{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001472 Py_CLEAR(self->encoding);
1473 Py_CLEAR(self->object);
1474 Py_CLEAR(self->start);
1475 Py_CLEAR(self->end);
1476 Py_CLEAR(self->reason);
1477
Thomas Wouters477c8d52006-05-27 19:21:47 +00001478 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1479 &PyString_Type, &self->encoding,
1480 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001481 &PyLong_Type, &self->start,
1482 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001483 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001484 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001485 self->reason = NULL;
1486 return -1;
1487 }
1488
1489 Py_INCREF(self->encoding);
1490 Py_INCREF(self->object);
1491 Py_INCREF(self->start);
1492 Py_INCREF(self->end);
1493 Py_INCREF(self->reason);
1494
1495 return 0;
1496}
1497
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001498static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499UnicodeError_clear(PyUnicodeErrorObject *self)
1500{
1501 Py_CLEAR(self->encoding);
1502 Py_CLEAR(self->object);
1503 Py_CLEAR(self->start);
1504 Py_CLEAR(self->end);
1505 Py_CLEAR(self->reason);
1506 return BaseException_clear((PyBaseExceptionObject *)self);
1507}
1508
1509static void
1510UnicodeError_dealloc(PyUnicodeErrorObject *self)
1511{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001512 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001513 UnicodeError_clear(self);
1514 self->ob_type->tp_free((PyObject *)self);
1515}
1516
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001517static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001518UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1519{
1520 Py_VISIT(self->encoding);
1521 Py_VISIT(self->object);
1522 Py_VISIT(self->start);
1523 Py_VISIT(self->end);
1524 Py_VISIT(self->reason);
1525 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1526}
1527
1528static PyMemberDef UnicodeError_members[] = {
1529 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1530 PyDoc_STR("exception message")},
1531 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1532 PyDoc_STR("exception encoding")},
1533 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1534 PyDoc_STR("exception object")},
1535 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1536 PyDoc_STR("exception start")},
1537 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1538 PyDoc_STR("exception end")},
1539 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1540 PyDoc_STR("exception reason")},
1541 {NULL} /* Sentinel */
1542};
1543
1544
1545/*
1546 * UnicodeEncodeError extends UnicodeError
1547 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548
1549static int
1550UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1551{
1552 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1553 return -1;
1554 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1555 kwds, &PyUnicode_Type);
1556}
1557
1558static PyObject *
1559UnicodeEncodeError_str(PyObject *self)
1560{
1561 Py_ssize_t start;
1562 Py_ssize_t end;
1563
1564 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001565 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001566
1567 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001568 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001569
1570 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001571 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1572 char badchar_str[20];
1573 if (badchar <= 0xff)
1574 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1575 else if (badchar <= 0xffff)
1576 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1577 else
1578 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1579 return PyString_FromFormat(
1580 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1581 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1582 badchar_str,
1583 start,
1584 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1585 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001586 }
1587 return PyString_FromFormat(
1588 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1589 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1590 start,
1591 (end-1),
1592 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1593 );
1594}
1595
1596static PyTypeObject _PyExc_UnicodeEncodeError = {
1597 PyObject_HEAD_INIT(NULL)
1598 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001599 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600 sizeof(PyUnicodeErrorObject), 0,
1601 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1602 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1603 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001604 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1605 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001607 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001608};
1609PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1610
1611PyObject *
1612PyUnicodeEncodeError_Create(
1613 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1614 Py_ssize_t start, Py_ssize_t end, const char *reason)
1615{
1616 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001617 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618}
1619
1620
1621/*
1622 * UnicodeDecodeError extends UnicodeError
1623 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001624
1625static int
1626UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1627{
1628 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1629 return -1;
1630 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1631 kwds, &PyString_Type);
1632}
1633
1634static PyObject *
1635UnicodeDecodeError_str(PyObject *self)
1636{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001637 Py_ssize_t start = 0;
1638 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001639
1640 if (PyUnicodeDecodeError_GetStart(self, &start))
1641 return NULL;
1642
1643 if (PyUnicodeDecodeError_GetEnd(self, &end))
1644 return NULL;
1645
1646 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001647 /* FromFormat does not support %02x, so format that separately */
1648 char byte[4];
1649 PyOS_snprintf(byte, sizeof(byte), "%02x",
1650 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1651 return PyString_FromFormat(
1652 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1653 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1654 byte,
1655 start,
1656 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1657 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658 }
1659 return PyString_FromFormat(
1660 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1661 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1662 start,
1663 (end-1),
1664 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1665 );
1666}
1667
1668static PyTypeObject _PyExc_UnicodeDecodeError = {
1669 PyObject_HEAD_INIT(NULL)
1670 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001671 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672 sizeof(PyUnicodeErrorObject), 0,
1673 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1674 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1675 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001676 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1677 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001679 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001680};
1681PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1682
1683PyObject *
1684PyUnicodeDecodeError_Create(
1685 const char *encoding, const char *object, Py_ssize_t length,
1686 Py_ssize_t start, Py_ssize_t end, const char *reason)
1687{
1688 assert(length < INT_MAX);
1689 assert(start < INT_MAX);
1690 assert(end < INT_MAX);
1691 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001692 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001693}
1694
1695
1696/*
1697 * UnicodeTranslateError extends UnicodeError
1698 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001699
1700static int
1701UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1702 PyObject *kwds)
1703{
1704 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1705 return -1;
1706
1707 Py_CLEAR(self->object);
1708 Py_CLEAR(self->start);
1709 Py_CLEAR(self->end);
1710 Py_CLEAR(self->reason);
1711
1712 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1713 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001714 &PyLong_Type, &self->start,
1715 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001716 &PyString_Type, &self->reason)) {
1717 self->object = self->start = self->end = self->reason = NULL;
1718 return -1;
1719 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001720
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721 Py_INCREF(self->object);
1722 Py_INCREF(self->start);
1723 Py_INCREF(self->end);
1724 Py_INCREF(self->reason);
1725
1726 return 0;
1727}
1728
1729
1730static PyObject *
1731UnicodeTranslateError_str(PyObject *self)
1732{
1733 Py_ssize_t start;
1734 Py_ssize_t end;
1735
1736 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001737 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001738
1739 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001740 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741
1742 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001743 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1744 char badchar_str[20];
1745 if (badchar <= 0xff)
1746 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1747 else if (badchar <= 0xffff)
1748 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1749 else
1750 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1751 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001752 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001753 badchar_str,
1754 start,
1755 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1756 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001757 }
1758 return PyString_FromFormat(
1759 "can't translate characters in position %zd-%zd: %.400s",
1760 start,
1761 (end-1),
1762 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1763 );
1764}
1765
1766static PyTypeObject _PyExc_UnicodeTranslateError = {
1767 PyObject_HEAD_INIT(NULL)
1768 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001769 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001770 sizeof(PyUnicodeErrorObject), 0,
1771 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1772 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1773 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001774 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1776 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001777 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778};
1779PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1780
1781PyObject *
1782PyUnicodeTranslateError_Create(
1783 const Py_UNICODE *object, Py_ssize_t length,
1784 Py_ssize_t start, Py_ssize_t end, const char *reason)
1785{
1786 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001787 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001788}
1789#endif
1790
1791
1792/*
1793 * AssertionError extends StandardError
1794 */
1795SimpleExtendsException(PyExc_StandardError, AssertionError,
1796 "Assertion failed.");
1797
1798
1799/*
1800 * ArithmeticError extends StandardError
1801 */
1802SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1803 "Base class for arithmetic errors.");
1804
1805
1806/*
1807 * FloatingPointError extends ArithmeticError
1808 */
1809SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1810 "Floating point operation failed.");
1811
1812
1813/*
1814 * OverflowError extends ArithmeticError
1815 */
1816SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1817 "Result too large to be represented.");
1818
1819
1820/*
1821 * ZeroDivisionError extends ArithmeticError
1822 */
1823SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1824 "Second argument to a division or modulo operation was zero.");
1825
1826
1827/*
1828 * SystemError extends StandardError
1829 */
1830SimpleExtendsException(PyExc_StandardError, SystemError,
1831 "Internal error in the Python interpreter.\n"
1832 "\n"
1833 "Please report this to the Python maintainer, along with the traceback,\n"
1834 "the Python version, and the hardware/OS platform and version.");
1835
1836
1837/*
1838 * ReferenceError extends StandardError
1839 */
1840SimpleExtendsException(PyExc_StandardError, ReferenceError,
1841 "Weak ref proxy used after referent went away.");
1842
1843
1844/*
1845 * MemoryError extends StandardError
1846 */
1847SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1848
1849
1850/* Warning category docstrings */
1851
1852/*
1853 * Warning extends Exception
1854 */
1855SimpleExtendsException(PyExc_Exception, Warning,
1856 "Base class for warning categories.");
1857
1858
1859/*
1860 * UserWarning extends Warning
1861 */
1862SimpleExtendsException(PyExc_Warning, UserWarning,
1863 "Base class for warnings generated by user code.");
1864
1865
1866/*
1867 * DeprecationWarning extends Warning
1868 */
1869SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1870 "Base class for warnings about deprecated features.");
1871
1872
1873/*
1874 * PendingDeprecationWarning extends Warning
1875 */
1876SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1877 "Base class for warnings about features which will be deprecated\n"
1878 "in the future.");
1879
1880
1881/*
1882 * SyntaxWarning extends Warning
1883 */
1884SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1885 "Base class for warnings about dubious syntax.");
1886
1887
1888/*
1889 * RuntimeWarning extends Warning
1890 */
1891SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1892 "Base class for warnings about dubious runtime behavior.");
1893
1894
1895/*
1896 * FutureWarning extends Warning
1897 */
1898SimpleExtendsException(PyExc_Warning, FutureWarning,
1899 "Base class for warnings about constructs that will change semantically\n"
1900 "in the future.");
1901
1902
1903/*
1904 * ImportWarning extends Warning
1905 */
1906SimpleExtendsException(PyExc_Warning, ImportWarning,
1907 "Base class for warnings about probable mistakes in module imports");
1908
1909
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001910/*
1911 * UnicodeWarning extends Warning
1912 */
1913SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1914 "Base class for warnings about Unicode related problems, mostly\n"
1915 "related to conversion problems.");
1916
1917
Thomas Wouters477c8d52006-05-27 19:21:47 +00001918/* Pre-computed MemoryError instance. Best to create this as early as
1919 * possible and not wait until a MemoryError is actually raised!
1920 */
1921PyObject *PyExc_MemoryErrorInst=NULL;
1922
Thomas Wouters477c8d52006-05-27 19:21:47 +00001923#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1924 Py_FatalError("exceptions bootstrapping error.");
1925
1926#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001927 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1928 Py_FatalError("Module dictionary insertion problem.");
1929
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001930#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1931/* crt variable checking in VisualStudio .NET 2005 */
1932#include <crtdbg.h>
1933
1934static int prevCrtReportMode;
1935static _invalid_parameter_handler prevCrtHandler;
1936
1937/* Invalid parameter handler. Sets a ValueError exception */
1938static void
1939InvalidParameterHandler(
1940 const wchar_t * expression,
1941 const wchar_t * function,
1942 const wchar_t * file,
1943 unsigned int line,
1944 uintptr_t pReserved)
1945{
1946 /* Do nothing, allow execution to continue. Usually this
1947 * means that the CRT will set errno to EINVAL
1948 */
1949}
1950#endif
1951
1952
Thomas Wouters477c8d52006-05-27 19:21:47 +00001953PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001954_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001955{
Neal Norwitz2633c692007-02-26 22:22:47 +00001956 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001957
1958 PRE_INIT(BaseException)
1959 PRE_INIT(Exception)
1960 PRE_INIT(StandardError)
1961 PRE_INIT(TypeError)
1962 PRE_INIT(StopIteration)
1963 PRE_INIT(GeneratorExit)
1964 PRE_INIT(SystemExit)
1965 PRE_INIT(KeyboardInterrupt)
1966 PRE_INIT(ImportError)
1967 PRE_INIT(EnvironmentError)
1968 PRE_INIT(IOError)
1969 PRE_INIT(OSError)
1970#ifdef MS_WINDOWS
1971 PRE_INIT(WindowsError)
1972#endif
1973#ifdef __VMS
1974 PRE_INIT(VMSError)
1975#endif
1976 PRE_INIT(EOFError)
1977 PRE_INIT(RuntimeError)
1978 PRE_INIT(NotImplementedError)
1979 PRE_INIT(NameError)
1980 PRE_INIT(UnboundLocalError)
1981 PRE_INIT(AttributeError)
1982 PRE_INIT(SyntaxError)
1983 PRE_INIT(IndentationError)
1984 PRE_INIT(TabError)
1985 PRE_INIT(LookupError)
1986 PRE_INIT(IndexError)
1987 PRE_INIT(KeyError)
1988 PRE_INIT(ValueError)
1989 PRE_INIT(UnicodeError)
1990#ifdef Py_USING_UNICODE
1991 PRE_INIT(UnicodeEncodeError)
1992 PRE_INIT(UnicodeDecodeError)
1993 PRE_INIT(UnicodeTranslateError)
1994#endif
1995 PRE_INIT(AssertionError)
1996 PRE_INIT(ArithmeticError)
1997 PRE_INIT(FloatingPointError)
1998 PRE_INIT(OverflowError)
1999 PRE_INIT(ZeroDivisionError)
2000 PRE_INIT(SystemError)
2001 PRE_INIT(ReferenceError)
2002 PRE_INIT(MemoryError)
2003 PRE_INIT(Warning)
2004 PRE_INIT(UserWarning)
2005 PRE_INIT(DeprecationWarning)
2006 PRE_INIT(PendingDeprecationWarning)
2007 PRE_INIT(SyntaxWarning)
2008 PRE_INIT(RuntimeWarning)
2009 PRE_INIT(FutureWarning)
2010 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002011 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002012
Thomas Wouters477c8d52006-05-27 19:21:47 +00002013 bltinmod = PyImport_ImportModule("__builtin__");
2014 if (bltinmod == NULL)
2015 Py_FatalError("exceptions bootstrapping error.");
2016 bdict = PyModule_GetDict(bltinmod);
2017 if (bdict == NULL)
2018 Py_FatalError("exceptions bootstrapping error.");
2019
2020 POST_INIT(BaseException)
2021 POST_INIT(Exception)
2022 POST_INIT(StandardError)
2023 POST_INIT(TypeError)
2024 POST_INIT(StopIteration)
2025 POST_INIT(GeneratorExit)
2026 POST_INIT(SystemExit)
2027 POST_INIT(KeyboardInterrupt)
2028 POST_INIT(ImportError)
2029 POST_INIT(EnvironmentError)
2030 POST_INIT(IOError)
2031 POST_INIT(OSError)
2032#ifdef MS_WINDOWS
2033 POST_INIT(WindowsError)
2034#endif
2035#ifdef __VMS
2036 POST_INIT(VMSError)
2037#endif
2038 POST_INIT(EOFError)
2039 POST_INIT(RuntimeError)
2040 POST_INIT(NotImplementedError)
2041 POST_INIT(NameError)
2042 POST_INIT(UnboundLocalError)
2043 POST_INIT(AttributeError)
2044 POST_INIT(SyntaxError)
2045 POST_INIT(IndentationError)
2046 POST_INIT(TabError)
2047 POST_INIT(LookupError)
2048 POST_INIT(IndexError)
2049 POST_INIT(KeyError)
2050 POST_INIT(ValueError)
2051 POST_INIT(UnicodeError)
2052#ifdef Py_USING_UNICODE
2053 POST_INIT(UnicodeEncodeError)
2054 POST_INIT(UnicodeDecodeError)
2055 POST_INIT(UnicodeTranslateError)
2056#endif
2057 POST_INIT(AssertionError)
2058 POST_INIT(ArithmeticError)
2059 POST_INIT(FloatingPointError)
2060 POST_INIT(OverflowError)
2061 POST_INIT(ZeroDivisionError)
2062 POST_INIT(SystemError)
2063 POST_INIT(ReferenceError)
2064 POST_INIT(MemoryError)
2065 POST_INIT(Warning)
2066 POST_INIT(UserWarning)
2067 POST_INIT(DeprecationWarning)
2068 POST_INIT(PendingDeprecationWarning)
2069 POST_INIT(SyntaxWarning)
2070 POST_INIT(RuntimeWarning)
2071 POST_INIT(FutureWarning)
2072 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002073 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002074
2075 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2076 if (!PyExc_MemoryErrorInst)
2077 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2078
2079 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002080
2081#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2082 /* Set CRT argument error handler */
2083 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2084 /* turn off assertions in debug mode */
2085 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2086#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002087}
2088
2089void
2090_PyExc_Fini(void)
2091{
2092 Py_XDECREF(PyExc_MemoryErrorInst);
2093 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002094#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2095 /* reset CRT error handling */
2096 _set_invalid_parameter_handler(prevCrtHandler);
2097 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2098#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002099}