blob: fabf3590d5c44816d11d76484295733e492d326f [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);
Guido van Rossumd8faa362007-04-27 19:54:29 +000027 if (!self)
28 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000029 /* the dict is created on the fly in PyObject_GenericSetAttr */
Guido van Rossumebe3e162007-05-17 18:20:34 +000030 self->dict = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000031
32 self->args = PyTuple_New(0);
33 if (!self->args) {
34 Py_DECREF(self);
35 return NULL;
36 }
37
Thomas Wouters477c8d52006-05-27 19:21:47 +000038 return (PyObject *)self;
39}
40
41static int
42BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
43{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000044 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
45 return -1;
46
Thomas Wouters477c8d52006-05-27 19:21:47 +000047 Py_DECREF(self->args);
48 self->args = args;
49 Py_INCREF(self->args);
50
Thomas Wouters477c8d52006-05-27 19:21:47 +000051 return 0;
52}
53
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000054static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000055BaseException_clear(PyBaseExceptionObject *self)
56{
57 Py_CLEAR(self->dict);
58 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000059 return 0;
60}
61
62static void
63BaseException_dealloc(PyBaseExceptionObject *self)
64{
Thomas Wouters89f507f2006-12-13 04:49:30 +000065 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000066 BaseException_clear(self);
67 self->ob_type->tp_free((PyObject *)self);
68}
69
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000070static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000071BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
72{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000073 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000074 Py_VISIT(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000075 return 0;
76}
77
78static PyObject *
79BaseException_str(PyBaseExceptionObject *self)
80{
81 PyObject *out;
82
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000083 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 case 0:
85 out = PyString_FromString("");
86 break;
87 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000088 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +000089 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +000090 default:
91 out = PyObject_Str(self->args);
92 break;
93 }
94
95 return out;
96}
97
98static PyObject *
99BaseException_repr(PyBaseExceptionObject *self)
100{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000101 PyObject *repr_suffix;
102 PyObject *repr;
103 char *name;
104 char *dot;
105
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000106 repr_suffix = PyObject_Repr(self->args);
107 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000108 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109
110 name = (char *)self->ob_type->tp_name;
111 dot = strrchr(name, '.');
112 if (dot != NULL) name = dot+1;
113
114 repr = PyString_FromString(name);
115 if (!repr) {
116 Py_DECREF(repr_suffix);
117 return NULL;
118 }
119
120 PyString_ConcatAndDel(&repr, repr_suffix);
121 return repr;
122}
123
124/* Pickling support */
125static PyObject *
126BaseException_reduce(PyBaseExceptionObject *self)
127{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000128 if (self->args && self->dict)
129 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
130 else
131 return PyTuple_Pack(2, self->ob_type, 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
Thomas Wouters477c8d52006-05-27 19:21:47 +0000158
159static PyMethodDef BaseException_methods[] = {
160 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000161 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000162 {NULL, NULL, 0, NULL},
163};
164
165
Thomas Wouters477c8d52006-05-27 19:21:47 +0000166static PyObject *
167BaseException_get_dict(PyBaseExceptionObject *self)
168{
169 if (self->dict == NULL) {
170 self->dict = PyDict_New();
171 if (!self->dict)
172 return NULL;
173 }
174 Py_INCREF(self->dict);
175 return self->dict;
176}
177
178static int
179BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
180{
181 if (val == NULL) {
182 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
183 return -1;
184 }
185 if (!PyDict_Check(val)) {
186 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
187 return -1;
188 }
189 Py_CLEAR(self->dict);
190 Py_INCREF(val);
191 self->dict = val;
192 return 0;
193}
194
195static PyObject *
196BaseException_get_args(PyBaseExceptionObject *self)
197{
198 if (self->args == NULL) {
199 Py_INCREF(Py_None);
200 return Py_None;
201 }
202 Py_INCREF(self->args);
203 return self->args;
204}
205
206static int
207BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
208{
209 PyObject *seq;
210 if (val == NULL) {
211 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
212 return -1;
213 }
214 seq = PySequence_Tuple(val);
215 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000216 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000217 self->args = seq;
218 return 0;
219}
220
Guido van Rossum360e4b82007-05-14 22:51:27 +0000221
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222static PyGetSetDef BaseException_getset[] = {
223 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
224 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
225 {NULL},
226};
227
228
229static PyTypeObject _PyExc_BaseException = {
230 PyObject_HEAD_INIT(NULL)
231 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000232 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000233 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
234 0, /*tp_itemsize*/
235 (destructor)BaseException_dealloc, /*tp_dealloc*/
236 0, /*tp_print*/
237 0, /*tp_getattr*/
238 0, /*tp_setattr*/
239 0, /* tp_compare; */
240 (reprfunc)BaseException_repr, /*tp_repr*/
241 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000242 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000243 0, /*tp_as_mapping*/
244 0, /*tp_hash */
245 0, /*tp_call*/
246 (reprfunc)BaseException_str, /*tp_str*/
247 PyObject_GenericGetAttr, /*tp_getattro*/
248 PyObject_GenericSetAttr, /*tp_setattro*/
249 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000250 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
251 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000252 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
253 (traverseproc)BaseException_traverse, /* tp_traverse */
254 (inquiry)BaseException_clear, /* tp_clear */
255 0, /* tp_richcompare */
256 0, /* tp_weaklistoffset */
257 0, /* tp_iter */
258 0, /* tp_iternext */
259 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000260 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000261 BaseException_getset, /* tp_getset */
262 0, /* tp_base */
263 0, /* tp_dict */
264 0, /* tp_descr_get */
265 0, /* tp_descr_set */
266 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
267 (initproc)BaseException_init, /* tp_init */
268 0, /* tp_alloc */
269 BaseException_new, /* tp_new */
270};
271/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
272from the previous implmentation and also allowing Python objects to be used
273in the API */
274PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
275
276/* note these macros omit the last semicolon so the macro invocation may
277 * include it and not look strange.
278 */
279#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
280static PyTypeObject _PyExc_ ## EXCNAME = { \
281 PyObject_HEAD_INIT(NULL) \
282 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000283 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000284 sizeof(PyBaseExceptionObject), \
285 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
286 0, 0, 0, 0, 0, 0, 0, \
287 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
288 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
289 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
290 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
291 (initproc)BaseException_init, 0, BaseException_new,\
292}; \
293PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
294
295#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
296static PyTypeObject _PyExc_ ## EXCNAME = { \
297 PyObject_HEAD_INIT(NULL) \
298 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000299 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000300 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000301 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000302 0, 0, 0, 0, 0, \
303 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000304 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
305 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000306 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000307 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000308}; \
309PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
310
311#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
312static PyTypeObject _PyExc_ ## EXCNAME = { \
313 PyObject_HEAD_INIT(NULL) \
314 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000315 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316 sizeof(Py ## EXCSTORE ## Object), 0, \
317 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
318 (reprfunc)EXCSTR, 0, 0, 0, \
319 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
320 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
321 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
322 EXCMEMBERS, 0, &_ ## EXCBASE, \
323 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
329/*
330 * Exception extends BaseException
331 */
332SimpleExtendsException(PyExc_BaseException, Exception,
333 "Common base class for all non-exit exceptions.");
334
335
336/*
337 * StandardError extends Exception
338 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000339SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340 "Base class for all standard Python exceptions that do not represent\n"
341 "interpreter exiting.");
342
343
344/*
345 * TypeError extends StandardError
346 */
347SimpleExtendsException(PyExc_StandardError, TypeError,
348 "Inappropriate argument type.");
349
350
351/*
352 * StopIteration extends Exception
353 */
354SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000355 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000356
357
358/*
359 * GeneratorExit extends Exception
360 */
361SimpleExtendsException(PyExc_Exception, GeneratorExit,
362 "Request that a generator exit.");
363
364
365/*
366 * SystemExit extends BaseException
367 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000368
369static int
370SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
371{
372 Py_ssize_t size = PyTuple_GET_SIZE(args);
373
374 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
375 return -1;
376
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000377 if (size == 0)
378 return 0;
379 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000380 if (size == 1)
381 self->code = PyTuple_GET_ITEM(args, 0);
382 else if (size > 1)
383 self->code = args;
384 Py_INCREF(self->code);
385 return 0;
386}
387
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000388static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389SystemExit_clear(PySystemExitObject *self)
390{
391 Py_CLEAR(self->code);
392 return BaseException_clear((PyBaseExceptionObject *)self);
393}
394
395static void
396SystemExit_dealloc(PySystemExitObject *self)
397{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000398 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399 SystemExit_clear(self);
400 self->ob_type->tp_free((PyObject *)self);
401}
402
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000403static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
405{
406 Py_VISIT(self->code);
407 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
408}
409
410static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
412 PyDoc_STR("exception code")},
413 {NULL} /* Sentinel */
414};
415
416ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
417 SystemExit_dealloc, 0, SystemExit_members, 0,
418 "Request to exit from the interpreter.");
419
420/*
421 * KeyboardInterrupt extends BaseException
422 */
423SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
424 "Program interrupted by user.");
425
426
427/*
428 * ImportError extends StandardError
429 */
430SimpleExtendsException(PyExc_StandardError, ImportError,
431 "Import can't find module, or can't find name in module.");
432
433
434/*
435 * EnvironmentError extends StandardError
436 */
437
Thomas Wouters477c8d52006-05-27 19:21:47 +0000438/* Where a function has a single filename, such as open() or some
439 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
440 * called, giving a third argument which is the filename. But, so
441 * that old code using in-place unpacking doesn't break, e.g.:
442 *
443 * except IOError, (errno, strerror):
444 *
445 * we hack args so that it only contains two items. This also
446 * means we need our own __str__() which prints out the filename
447 * when it was supplied.
448 */
449static int
450EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
451 PyObject *kwds)
452{
453 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
454 PyObject *subslice = NULL;
455
456 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
457 return -1;
458
Thomas Wouters89f507f2006-12-13 04:49:30 +0000459 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460 return 0;
461 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000462
463 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464 &myerrno, &strerror, &filename)) {
465 return -1;
466 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000467 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000468 self->myerrno = myerrno;
469 Py_INCREF(self->myerrno);
470
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000471 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472 self->strerror = strerror;
473 Py_INCREF(self->strerror);
474
475 /* self->filename will remain Py_None otherwise */
476 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000477 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478 self->filename = filename;
479 Py_INCREF(self->filename);
480
481 subslice = PyTuple_GetSlice(args, 0, 2);
482 if (!subslice)
483 return -1;
484
485 Py_DECREF(self->args); /* replacing args */
486 self->args = subslice;
487 }
488 return 0;
489}
490
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000491static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492EnvironmentError_clear(PyEnvironmentErrorObject *self)
493{
494 Py_CLEAR(self->myerrno);
495 Py_CLEAR(self->strerror);
496 Py_CLEAR(self->filename);
497 return BaseException_clear((PyBaseExceptionObject *)self);
498}
499
500static void
501EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
502{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000503 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504 EnvironmentError_clear(self);
505 self->ob_type->tp_free((PyObject *)self);
506}
507
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000508static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000509EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
510 void *arg)
511{
512 Py_VISIT(self->myerrno);
513 Py_VISIT(self->strerror);
514 Py_VISIT(self->filename);
515 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
516}
517
518static PyObject *
519EnvironmentError_str(PyEnvironmentErrorObject *self)
520{
521 PyObject *rtnval = NULL;
522
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000523 if (self->filename) {
524 PyObject *fmt;
525 PyObject *repr;
526 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000528 fmt = PyString_FromString("[Errno %s] %s: %s");
529 if (!fmt)
530 return NULL;
531
532 repr = PyObject_Repr(self->filename);
533 if (!repr) {
534 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000535 return NULL;
536 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000537 tuple = PyTuple_New(3);
538 if (!tuple) {
539 Py_DECREF(repr);
540 Py_DECREF(fmt);
541 return NULL;
542 }
543
544 if (self->myerrno) {
545 Py_INCREF(self->myerrno);
546 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
547 }
548 else {
549 Py_INCREF(Py_None);
550 PyTuple_SET_ITEM(tuple, 0, Py_None);
551 }
552 if (self->strerror) {
553 Py_INCREF(self->strerror);
554 PyTuple_SET_ITEM(tuple, 1, self->strerror);
555 }
556 else {
557 Py_INCREF(Py_None);
558 PyTuple_SET_ITEM(tuple, 1, Py_None);
559 }
560
Thomas Wouters477c8d52006-05-27 19:21:47 +0000561 PyTuple_SET_ITEM(tuple, 2, repr);
562
563 rtnval = PyString_Format(fmt, tuple);
564
565 Py_DECREF(fmt);
566 Py_DECREF(tuple);
567 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000568 else if (self->myerrno && self->strerror) {
569 PyObject *fmt;
570 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000571
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000572 fmt = PyString_FromString("[Errno %s] %s");
573 if (!fmt)
574 return NULL;
575
576 tuple = PyTuple_New(2);
577 if (!tuple) {
578 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000579 return NULL;
580 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000581
582 if (self->myerrno) {
583 Py_INCREF(self->myerrno);
584 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
585 }
586 else {
587 Py_INCREF(Py_None);
588 PyTuple_SET_ITEM(tuple, 0, Py_None);
589 }
590 if (self->strerror) {
591 Py_INCREF(self->strerror);
592 PyTuple_SET_ITEM(tuple, 1, self->strerror);
593 }
594 else {
595 Py_INCREF(Py_None);
596 PyTuple_SET_ITEM(tuple, 1, Py_None);
597 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598
599 rtnval = PyString_Format(fmt, tuple);
600
601 Py_DECREF(fmt);
602 Py_DECREF(tuple);
603 }
604 else
605 rtnval = BaseException_str((PyBaseExceptionObject *)self);
606
607 return rtnval;
608}
609
610static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
612 PyDoc_STR("exception errno")},
613 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
614 PyDoc_STR("exception strerror")},
615 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
616 PyDoc_STR("exception filename")},
617 {NULL} /* Sentinel */
618};
619
620
621static PyObject *
622EnvironmentError_reduce(PyEnvironmentErrorObject *self)
623{
624 PyObject *args = self->args;
625 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000626
Thomas Wouters477c8d52006-05-27 19:21:47 +0000627 /* self->args is only the first two real arguments if there was a
628 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000629 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630 args = PyTuple_New(3);
631 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000632
633 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000634 Py_INCREF(tmp);
635 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000636
637 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638 Py_INCREF(tmp);
639 PyTuple_SET_ITEM(args, 1, tmp);
640
641 Py_INCREF(self->filename);
642 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000643 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000644 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000645
646 if (self->dict)
647 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
648 else
649 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000650 Py_DECREF(args);
651 return res;
652}
653
654
655static PyMethodDef EnvironmentError_methods[] = {
656 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
657 {NULL}
658};
659
660ComplexExtendsException(PyExc_StandardError, EnvironmentError,
661 EnvironmentError, EnvironmentError_dealloc,
662 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000663 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664 "Base class for I/O related errors.");
665
666
667/*
668 * IOError extends EnvironmentError
669 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000670MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671 EnvironmentError, "I/O operation failed.");
672
673
674/*
675 * OSError extends EnvironmentError
676 */
677MiddlingExtendsException(PyExc_EnvironmentError, OSError,
678 EnvironmentError, "OS system call failed.");
679
680
681/*
682 * WindowsError extends OSError
683 */
684#ifdef MS_WINDOWS
685#include "errmap.h"
686
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000687static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688WindowsError_clear(PyWindowsErrorObject *self)
689{
690 Py_CLEAR(self->myerrno);
691 Py_CLEAR(self->strerror);
692 Py_CLEAR(self->filename);
693 Py_CLEAR(self->winerror);
694 return BaseException_clear((PyBaseExceptionObject *)self);
695}
696
697static void
698WindowsError_dealloc(PyWindowsErrorObject *self)
699{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000700 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000701 WindowsError_clear(self);
702 self->ob_type->tp_free((PyObject *)self);
703}
704
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000705static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000706WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
707{
708 Py_VISIT(self->myerrno);
709 Py_VISIT(self->strerror);
710 Py_VISIT(self->filename);
711 Py_VISIT(self->winerror);
712 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
713}
714
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715static int
716WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
717{
718 PyObject *o_errcode = NULL;
719 long errcode;
720 long posix_errno;
721
722 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
723 == -1)
724 return -1;
725
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000726 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000728
729 /* Set errno to the POSIX errno, and winerror to the Win32
730 error code. */
731 errcode = PyInt_AsLong(self->myerrno);
732 if (errcode == -1 && PyErr_Occurred())
733 return -1;
734 posix_errno = winerror_to_errno(errcode);
735
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000736 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000737 self->winerror = self->myerrno;
738
739 o_errcode = PyInt_FromLong(posix_errno);
740 if (!o_errcode)
741 return -1;
742
743 self->myerrno = o_errcode;
744
745 return 0;
746}
747
748
749static PyObject *
750WindowsError_str(PyWindowsErrorObject *self)
751{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000752 PyObject *rtnval = NULL;
753
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000754 if (self->filename) {
755 PyObject *fmt;
756 PyObject *repr;
757 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000759 fmt = PyString_FromString("[Error %s] %s: %s");
760 if (!fmt)
761 return NULL;
762
763 repr = PyObject_Repr(self->filename);
764 if (!repr) {
765 Py_DECREF(fmt);
766 return NULL;
767 }
768 tuple = PyTuple_New(3);
769 if (!tuple) {
770 Py_DECREF(repr);
771 Py_DECREF(fmt);
772 return NULL;
773 }
774
Thomas Wouters89f507f2006-12-13 04:49:30 +0000775 if (self->winerror) {
776 Py_INCREF(self->winerror);
777 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000778 }
779 else {
780 Py_INCREF(Py_None);
781 PyTuple_SET_ITEM(tuple, 0, Py_None);
782 }
783 if (self->strerror) {
784 Py_INCREF(self->strerror);
785 PyTuple_SET_ITEM(tuple, 1, self->strerror);
786 }
787 else {
788 Py_INCREF(Py_None);
789 PyTuple_SET_ITEM(tuple, 1, Py_None);
790 }
791
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000792 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793
794 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000795
796 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797 Py_DECREF(tuple);
798 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000799 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000800 PyObject *fmt;
801 PyObject *tuple;
802
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 fmt = PyString_FromString("[Error %s] %s");
804 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000805 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000806
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000807 tuple = PyTuple_New(2);
808 if (!tuple) {
809 Py_DECREF(fmt);
810 return NULL;
811 }
812
Thomas Wouters89f507f2006-12-13 04:49:30 +0000813 if (self->winerror) {
814 Py_INCREF(self->winerror);
815 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 }
817 else {
818 Py_INCREF(Py_None);
819 PyTuple_SET_ITEM(tuple, 0, Py_None);
820 }
821 if (self->strerror) {
822 Py_INCREF(self->strerror);
823 PyTuple_SET_ITEM(tuple, 1, self->strerror);
824 }
825 else {
826 Py_INCREF(Py_None);
827 PyTuple_SET_ITEM(tuple, 1, Py_None);
828 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829
830 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000831
832 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000833 Py_DECREF(tuple);
834 }
835 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000836 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837
Thomas Wouters477c8d52006-05-27 19:21:47 +0000838 return rtnval;
839}
840
841static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
843 PyDoc_STR("POSIX exception code")},
844 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
845 PyDoc_STR("exception strerror")},
846 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
847 PyDoc_STR("exception filename")},
848 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
849 PyDoc_STR("Win32 exception code")},
850 {NULL} /* Sentinel */
851};
852
853ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
854 WindowsError_dealloc, 0, WindowsError_members,
855 WindowsError_str, "MS-Windows OS system call failed.");
856
857#endif /* MS_WINDOWS */
858
859
860/*
861 * VMSError extends OSError (I think)
862 */
863#ifdef __VMS
864MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
865 "OpenVMS OS system call failed.");
866#endif
867
868
869/*
870 * EOFError extends StandardError
871 */
872SimpleExtendsException(PyExc_StandardError, EOFError,
873 "Read beyond end of file.");
874
875
876/*
877 * RuntimeError extends StandardError
878 */
879SimpleExtendsException(PyExc_StandardError, RuntimeError,
880 "Unspecified run-time error.");
881
882
883/*
884 * NotImplementedError extends RuntimeError
885 */
886SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
887 "Method or function hasn't been implemented yet.");
888
889/*
890 * NameError extends StandardError
891 */
892SimpleExtendsException(PyExc_StandardError, NameError,
893 "Name not found globally.");
894
895/*
896 * UnboundLocalError extends NameError
897 */
898SimpleExtendsException(PyExc_NameError, UnboundLocalError,
899 "Local name referenced but not bound to a value.");
900
901/*
902 * AttributeError extends StandardError
903 */
904SimpleExtendsException(PyExc_StandardError, AttributeError,
905 "Attribute not found.");
906
907
908/*
909 * SyntaxError extends StandardError
910 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911
912static int
913SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
914{
915 PyObject *info = NULL;
916 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
917
918 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
919 return -1;
920
921 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000922 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923 self->msg = PyTuple_GET_ITEM(args, 0);
924 Py_INCREF(self->msg);
925 }
926 if (lenargs == 2) {
927 info = PyTuple_GET_ITEM(args, 1);
928 info = PySequence_Tuple(info);
929 if (!info) return -1;
930
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000931 if (PyTuple_GET_SIZE(info) != 4) {
932 /* not a very good error message, but it's what Python 2.4 gives */
933 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
934 Py_DECREF(info);
935 return -1;
936 }
937
938 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 self->filename = PyTuple_GET_ITEM(info, 0);
940 Py_INCREF(self->filename);
941
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000942 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943 self->lineno = PyTuple_GET_ITEM(info, 1);
944 Py_INCREF(self->lineno);
945
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000946 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947 self->offset = PyTuple_GET_ITEM(info, 2);
948 Py_INCREF(self->offset);
949
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000950 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951 self->text = PyTuple_GET_ITEM(info, 3);
952 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000953
954 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000955 }
956 return 0;
957}
958
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000959static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000960SyntaxError_clear(PySyntaxErrorObject *self)
961{
962 Py_CLEAR(self->msg);
963 Py_CLEAR(self->filename);
964 Py_CLEAR(self->lineno);
965 Py_CLEAR(self->offset);
966 Py_CLEAR(self->text);
967 Py_CLEAR(self->print_file_and_line);
968 return BaseException_clear((PyBaseExceptionObject *)self);
969}
970
971static void
972SyntaxError_dealloc(PySyntaxErrorObject *self)
973{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000974 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000975 SyntaxError_clear(self);
976 self->ob_type->tp_free((PyObject *)self);
977}
978
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000979static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000980SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
981{
982 Py_VISIT(self->msg);
983 Py_VISIT(self->filename);
984 Py_VISIT(self->lineno);
985 Py_VISIT(self->offset);
986 Py_VISIT(self->text);
987 Py_VISIT(self->print_file_and_line);
988 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
989}
990
991/* This is called "my_basename" instead of just "basename" to avoid name
992 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
993 defined, and Python does define that. */
994static char *
995my_basename(char *name)
996{
997 char *cp = name;
998 char *result = name;
999
1000 if (name == NULL)
1001 return "???";
1002 while (*cp != '\0') {
1003 if (*cp == SEP)
1004 result = cp + 1;
1005 ++cp;
1006 }
1007 return result;
1008}
1009
1010
1011static PyObject *
1012SyntaxError_str(PySyntaxErrorObject *self)
1013{
1014 PyObject *str;
1015 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001016 int have_filename = 0;
1017 int have_lineno = 0;
1018 char *buffer = NULL;
1019 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001020
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001021 if (self->msg)
1022 str = PyObject_Str(self->msg);
1023 else
1024 str = PyObject_Str(Py_None);
1025 if (!str) return NULL;
1026 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1027 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001028
1029 /* XXX -- do all the additional formatting with filename and
1030 lineno here */
1031
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001032 have_filename = (self->filename != NULL) &&
1033 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001034 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001035
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001036 if (!have_filename && !have_lineno)
1037 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001039 bufsize = PyString_GET_SIZE(str) + 64;
1040 if (have_filename)
1041 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001043 buffer = PyMem_MALLOC(bufsize);
1044 if (buffer == NULL)
1045 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001046
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001047 if (have_filename && have_lineno)
1048 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1049 PyString_AS_STRING(str),
1050 my_basename(PyString_AS_STRING(self->filename)),
1051 PyInt_AsLong(self->lineno));
1052 else if (have_filename)
1053 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1054 PyString_AS_STRING(str),
1055 my_basename(PyString_AS_STRING(self->filename)));
1056 else /* only have_lineno */
1057 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1058 PyString_AS_STRING(str),
1059 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001061 result = PyString_FromString(buffer);
1062 PyMem_FREE(buffer);
1063
1064 if (result == NULL)
1065 result = str;
1066 else
1067 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068 return result;
1069}
1070
1071static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001072 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1073 PyDoc_STR("exception msg")},
1074 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1075 PyDoc_STR("exception filename")},
1076 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1077 PyDoc_STR("exception lineno")},
1078 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1079 PyDoc_STR("exception offset")},
1080 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1081 PyDoc_STR("exception text")},
1082 {"print_file_and_line", T_OBJECT,
1083 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1084 PyDoc_STR("exception print_file_and_line")},
1085 {NULL} /* Sentinel */
1086};
1087
1088ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1089 SyntaxError_dealloc, 0, SyntaxError_members,
1090 SyntaxError_str, "Invalid syntax.");
1091
1092
1093/*
1094 * IndentationError extends SyntaxError
1095 */
1096MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1097 "Improper indentation.");
1098
1099
1100/*
1101 * TabError extends IndentationError
1102 */
1103MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1104 "Improper mixture of spaces and tabs.");
1105
1106
1107/*
1108 * LookupError extends StandardError
1109 */
1110SimpleExtendsException(PyExc_StandardError, LookupError,
1111 "Base class for lookup errors.");
1112
1113
1114/*
1115 * IndexError extends LookupError
1116 */
1117SimpleExtendsException(PyExc_LookupError, IndexError,
1118 "Sequence index out of range.");
1119
1120
1121/*
1122 * KeyError extends LookupError
1123 */
1124static PyObject *
1125KeyError_str(PyBaseExceptionObject *self)
1126{
1127 /* If args is a tuple of exactly one item, apply repr to args[0].
1128 This is done so that e.g. the exception raised by {}[''] prints
1129 KeyError: ''
1130 rather than the confusing
1131 KeyError
1132 alone. The downside is that if KeyError is raised with an explanatory
1133 string, that string will be displayed in quotes. Too bad.
1134 If args is anything else, use the default BaseException__str__().
1135 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001136 if (PyTuple_GET_SIZE(self->args) == 1) {
1137 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138 }
1139 return BaseException_str(self);
1140}
1141
1142ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1143 0, 0, 0, KeyError_str, "Mapping key not found.");
1144
1145
1146/*
1147 * ValueError extends StandardError
1148 */
1149SimpleExtendsException(PyExc_StandardError, ValueError,
1150 "Inappropriate argument value (of correct type).");
1151
1152/*
1153 * UnicodeError extends ValueError
1154 */
1155
1156SimpleExtendsException(PyExc_ValueError, UnicodeError,
1157 "Unicode related error.");
1158
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159static int
1160get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1161{
1162 if (!attr) {
1163 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1164 return -1;
1165 }
1166
Guido van Rossumddefaf32007-01-14 03:31:43 +00001167 if (PyLong_Check(attr)) {
1168 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169 if (*value == -1 && PyErr_Occurred())
1170 return -1;
1171 } else {
1172 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1173 return -1;
1174 }
1175 return 0;
1176}
1177
1178static int
1179set_ssize_t(PyObject **attr, Py_ssize_t value)
1180{
1181 PyObject *obj = PyInt_FromSsize_t(value);
1182 if (!obj)
1183 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001184 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185 *attr = obj;
1186 return 0;
1187}
1188
1189static PyObject *
1190get_string(PyObject *attr, const char *name)
1191{
1192 if (!attr) {
1193 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1194 return NULL;
1195 }
1196
1197 if (!PyString_Check(attr)) {
1198 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1199 return NULL;
1200 }
1201 Py_INCREF(attr);
1202 return attr;
1203}
1204
1205
1206static int
1207set_string(PyObject **attr, const char *value)
1208{
1209 PyObject *obj = PyString_FromString(value);
1210 if (!obj)
1211 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001212 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001213 *attr = obj;
1214 return 0;
1215}
1216
1217
1218static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +00001219get_bytes(PyObject *attr, const char *name)
1220{
1221 if (!attr) {
1222 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1223 return NULL;
1224 }
1225
1226 if (!PyBytes_Check(attr)) {
1227 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1228 return NULL;
1229 }
1230 Py_INCREF(attr);
1231 return attr;
1232}
1233
1234static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001235get_unicode(PyObject *attr, const char *name)
1236{
1237 if (!attr) {
1238 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1239 return NULL;
1240 }
1241
1242 if (!PyUnicode_Check(attr)) {
1243 PyErr_Format(PyExc_TypeError,
1244 "%.200s attribute must be unicode", name);
1245 return NULL;
1246 }
1247 Py_INCREF(attr);
1248 return attr;
1249}
1250
1251PyObject *
1252PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1253{
1254 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1255}
1256
1257PyObject *
1258PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1259{
1260 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1261}
1262
1263PyObject *
1264PyUnicodeEncodeError_GetObject(PyObject *exc)
1265{
1266 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1267}
1268
1269PyObject *
1270PyUnicodeDecodeError_GetObject(PyObject *exc)
1271{
Walter Dörwald612344f2007-05-04 19:28:21 +00001272 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273}
1274
1275PyObject *
1276PyUnicodeTranslateError_GetObject(PyObject *exc)
1277{
1278 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1279}
1280
1281int
1282PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1283{
1284 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1285 Py_ssize_t size;
1286 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1287 "object");
1288 if (!obj) return -1;
1289 size = PyUnicode_GET_SIZE(obj);
1290 if (*start<0)
1291 *start = 0; /*XXX check for values <0*/
1292 if (*start>=size)
1293 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001294 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001295 return 0;
1296 }
1297 return -1;
1298}
1299
1300
1301int
1302PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1303{
1304 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1305 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001306 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001307 "object");
1308 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001309 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001310 if (*start<0)
1311 *start = 0;
1312 if (*start>=size)
1313 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001314 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315 return 0;
1316 }
1317 return -1;
1318}
1319
1320
1321int
1322PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1323{
1324 return PyUnicodeEncodeError_GetStart(exc, start);
1325}
1326
1327
1328int
1329PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1330{
1331 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1332}
1333
1334
1335int
1336PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1337{
1338 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1339}
1340
1341
1342int
1343PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1344{
1345 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1346}
1347
1348
1349int
1350PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1351{
1352 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1353 Py_ssize_t size;
1354 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1355 "object");
1356 if (!obj) return -1;
1357 size = PyUnicode_GET_SIZE(obj);
1358 if (*end<1)
1359 *end = 1;
1360 if (*end>size)
1361 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001362 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001363 return 0;
1364 }
1365 return -1;
1366}
1367
1368
1369int
1370PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1371{
1372 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1373 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001374 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375 "object");
1376 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001377 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378 if (*end<1)
1379 *end = 1;
1380 if (*end>size)
1381 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001382 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001383 return 0;
1384 }
1385 return -1;
1386}
1387
1388
1389int
1390PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1391{
1392 return PyUnicodeEncodeError_GetEnd(exc, start);
1393}
1394
1395
1396int
1397PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1398{
1399 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1400}
1401
1402
1403int
1404PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1405{
1406 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1407}
1408
1409
1410int
1411PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1412{
1413 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1414}
1415
1416PyObject *
1417PyUnicodeEncodeError_GetReason(PyObject *exc)
1418{
1419 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1420}
1421
1422
1423PyObject *
1424PyUnicodeDecodeError_GetReason(PyObject *exc)
1425{
1426 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1427}
1428
1429
1430PyObject *
1431PyUnicodeTranslateError_GetReason(PyObject *exc)
1432{
1433 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1434}
1435
1436
1437int
1438PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1439{
1440 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1441}
1442
1443
1444int
1445PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1446{
1447 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1448}
1449
1450
1451int
1452PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1453{
1454 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1455}
1456
1457
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458static int
1459UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1460 PyTypeObject *objecttype)
1461{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001462 Py_CLEAR(self->encoding);
1463 Py_CLEAR(self->object);
1464 Py_CLEAR(self->start);
1465 Py_CLEAR(self->end);
1466 Py_CLEAR(self->reason);
1467
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1469 &PyString_Type, &self->encoding,
1470 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001471 &PyLong_Type, &self->start,
1472 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001473 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001474 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475 self->reason = NULL;
1476 return -1;
1477 }
1478
1479 Py_INCREF(self->encoding);
1480 Py_INCREF(self->object);
1481 Py_INCREF(self->start);
1482 Py_INCREF(self->end);
1483 Py_INCREF(self->reason);
1484
1485 return 0;
1486}
1487
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001488static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001489UnicodeError_clear(PyUnicodeErrorObject *self)
1490{
1491 Py_CLEAR(self->encoding);
1492 Py_CLEAR(self->object);
1493 Py_CLEAR(self->start);
1494 Py_CLEAR(self->end);
1495 Py_CLEAR(self->reason);
1496 return BaseException_clear((PyBaseExceptionObject *)self);
1497}
1498
1499static void
1500UnicodeError_dealloc(PyUnicodeErrorObject *self)
1501{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001502 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001503 UnicodeError_clear(self);
1504 self->ob_type->tp_free((PyObject *)self);
1505}
1506
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001507static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001508UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1509{
1510 Py_VISIT(self->encoding);
1511 Py_VISIT(self->object);
1512 Py_VISIT(self->start);
1513 Py_VISIT(self->end);
1514 Py_VISIT(self->reason);
1515 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1516}
1517
1518static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001519 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1520 PyDoc_STR("exception encoding")},
1521 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1522 PyDoc_STR("exception object")},
1523 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1524 PyDoc_STR("exception start")},
1525 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1526 PyDoc_STR("exception end")},
1527 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1528 PyDoc_STR("exception reason")},
1529 {NULL} /* Sentinel */
1530};
1531
1532
1533/*
1534 * UnicodeEncodeError extends UnicodeError
1535 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536
1537static int
1538UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1539{
1540 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1541 return -1;
1542 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1543 kwds, &PyUnicode_Type);
1544}
1545
1546static PyObject *
1547UnicodeEncodeError_str(PyObject *self)
1548{
1549 Py_ssize_t start;
1550 Py_ssize_t end;
1551
1552 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001553 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554
1555 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001556 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557
1558 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001559 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1560 char badchar_str[20];
1561 if (badchar <= 0xff)
1562 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1563 else if (badchar <= 0xffff)
1564 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1565 else
1566 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1567 return PyString_FromFormat(
1568 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1569 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1570 badchar_str,
1571 start,
1572 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1573 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001574 }
1575 return PyString_FromFormat(
1576 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1577 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1578 start,
1579 (end-1),
1580 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1581 );
1582}
1583
1584static PyTypeObject _PyExc_UnicodeEncodeError = {
1585 PyObject_HEAD_INIT(NULL)
1586 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001587 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001588 sizeof(PyUnicodeErrorObject), 0,
1589 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1590 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1591 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001592 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1593 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001594 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001595 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001596};
1597PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1598
1599PyObject *
1600PyUnicodeEncodeError_Create(
1601 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1602 Py_ssize_t start, Py_ssize_t end, const char *reason)
1603{
1604 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001605 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606}
1607
1608
1609/*
1610 * UnicodeDecodeError extends UnicodeError
1611 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001612
1613static int
1614UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1615{
1616 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1617 return -1;
1618 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001619 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001620}
1621
1622static PyObject *
1623UnicodeDecodeError_str(PyObject *self)
1624{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001625 Py_ssize_t start = 0;
1626 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627
1628 if (PyUnicodeDecodeError_GetStart(self, &start))
1629 return NULL;
1630
1631 if (PyUnicodeDecodeError_GetEnd(self, &end))
1632 return NULL;
1633
1634 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001635 /* FromFormat does not support %02x, so format that separately */
1636 char byte[4];
1637 PyOS_snprintf(byte, sizeof(byte), "%02x",
Walter Dörwald612344f2007-05-04 19:28:21 +00001638 ((int)PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001639 return PyString_FromFormat(
1640 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1641 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1642 byte,
1643 start,
1644 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1645 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001646 }
1647 return PyString_FromFormat(
1648 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1649 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1650 start,
1651 (end-1),
1652 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1653 );
1654}
1655
1656static PyTypeObject _PyExc_UnicodeDecodeError = {
1657 PyObject_HEAD_INIT(NULL)
1658 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001659 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660 sizeof(PyUnicodeErrorObject), 0,
1661 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1662 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1663 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001664 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1665 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001666 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001667 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001668};
1669PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1670
1671PyObject *
1672PyUnicodeDecodeError_Create(
1673 const char *encoding, const char *object, Py_ssize_t length,
1674 Py_ssize_t start, Py_ssize_t end, const char *reason)
1675{
1676 assert(length < INT_MAX);
1677 assert(start < INT_MAX);
1678 assert(end < INT_MAX);
Walter Dörwald612344f2007-05-04 19:28:21 +00001679 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001680 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001681}
1682
1683
1684/*
1685 * UnicodeTranslateError extends UnicodeError
1686 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001687
1688static int
1689UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1690 PyObject *kwds)
1691{
1692 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1693 return -1;
1694
1695 Py_CLEAR(self->object);
1696 Py_CLEAR(self->start);
1697 Py_CLEAR(self->end);
1698 Py_CLEAR(self->reason);
1699
1700 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1701 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001702 &PyLong_Type, &self->start,
1703 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001704 &PyString_Type, &self->reason)) {
1705 self->object = self->start = self->end = self->reason = NULL;
1706 return -1;
1707 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001708
Thomas Wouters477c8d52006-05-27 19:21:47 +00001709 Py_INCREF(self->object);
1710 Py_INCREF(self->start);
1711 Py_INCREF(self->end);
1712 Py_INCREF(self->reason);
1713
1714 return 0;
1715}
1716
1717
1718static PyObject *
1719UnicodeTranslateError_str(PyObject *self)
1720{
1721 Py_ssize_t start;
1722 Py_ssize_t end;
1723
1724 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001725 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726
1727 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001728 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729
1730 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001731 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1732 char badchar_str[20];
1733 if (badchar <= 0xff)
1734 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1735 else if (badchar <= 0xffff)
1736 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1737 else
1738 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1739 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001741 badchar_str,
1742 start,
1743 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1744 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745 }
1746 return PyString_FromFormat(
1747 "can't translate characters in position %zd-%zd: %.400s",
1748 start,
1749 (end-1),
1750 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1751 );
1752}
1753
1754static PyTypeObject _PyExc_UnicodeTranslateError = {
1755 PyObject_HEAD_INIT(NULL)
1756 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001757 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758 sizeof(PyUnicodeErrorObject), 0,
1759 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1760 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1761 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001762 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001763 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1764 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001765 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766};
1767PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1768
1769PyObject *
1770PyUnicodeTranslateError_Create(
1771 const Py_UNICODE *object, Py_ssize_t length,
1772 Py_ssize_t start, Py_ssize_t end, const char *reason)
1773{
1774 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001775 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001776}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001777
1778
1779/*
1780 * AssertionError extends StandardError
1781 */
1782SimpleExtendsException(PyExc_StandardError, AssertionError,
1783 "Assertion failed.");
1784
1785
1786/*
1787 * ArithmeticError extends StandardError
1788 */
1789SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1790 "Base class for arithmetic errors.");
1791
1792
1793/*
1794 * FloatingPointError extends ArithmeticError
1795 */
1796SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1797 "Floating point operation failed.");
1798
1799
1800/*
1801 * OverflowError extends ArithmeticError
1802 */
1803SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1804 "Result too large to be represented.");
1805
1806
1807/*
1808 * ZeroDivisionError extends ArithmeticError
1809 */
1810SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1811 "Second argument to a division or modulo operation was zero.");
1812
1813
1814/*
1815 * SystemError extends StandardError
1816 */
1817SimpleExtendsException(PyExc_StandardError, SystemError,
1818 "Internal error in the Python interpreter.\n"
1819 "\n"
1820 "Please report this to the Python maintainer, along with the traceback,\n"
1821 "the Python version, and the hardware/OS platform and version.");
1822
1823
1824/*
1825 * ReferenceError extends StandardError
1826 */
1827SimpleExtendsException(PyExc_StandardError, ReferenceError,
1828 "Weak ref proxy used after referent went away.");
1829
1830
1831/*
1832 * MemoryError extends StandardError
1833 */
1834SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1835
1836
1837/* Warning category docstrings */
1838
1839/*
1840 * Warning extends Exception
1841 */
1842SimpleExtendsException(PyExc_Exception, Warning,
1843 "Base class for warning categories.");
1844
1845
1846/*
1847 * UserWarning extends Warning
1848 */
1849SimpleExtendsException(PyExc_Warning, UserWarning,
1850 "Base class for warnings generated by user code.");
1851
1852
1853/*
1854 * DeprecationWarning extends Warning
1855 */
1856SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1857 "Base class for warnings about deprecated features.");
1858
1859
1860/*
1861 * PendingDeprecationWarning extends Warning
1862 */
1863SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1864 "Base class for warnings about features which will be deprecated\n"
1865 "in the future.");
1866
1867
1868/*
1869 * SyntaxWarning extends Warning
1870 */
1871SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1872 "Base class for warnings about dubious syntax.");
1873
1874
1875/*
1876 * RuntimeWarning extends Warning
1877 */
1878SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1879 "Base class for warnings about dubious runtime behavior.");
1880
1881
1882/*
1883 * FutureWarning extends Warning
1884 */
1885SimpleExtendsException(PyExc_Warning, FutureWarning,
1886 "Base class for warnings about constructs that will change semantically\n"
1887 "in the future.");
1888
1889
1890/*
1891 * ImportWarning extends Warning
1892 */
1893SimpleExtendsException(PyExc_Warning, ImportWarning,
1894 "Base class for warnings about probable mistakes in module imports");
1895
1896
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001897/*
1898 * UnicodeWarning extends Warning
1899 */
1900SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1901 "Base class for warnings about Unicode related problems, mostly\n"
1902 "related to conversion problems.");
1903
1904
Thomas Wouters477c8d52006-05-27 19:21:47 +00001905/* Pre-computed MemoryError instance. Best to create this as early as
1906 * possible and not wait until a MemoryError is actually raised!
1907 */
1908PyObject *PyExc_MemoryErrorInst=NULL;
1909
Thomas Wouters477c8d52006-05-27 19:21:47 +00001910#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1911 Py_FatalError("exceptions bootstrapping error.");
1912
1913#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001914 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1915 Py_FatalError("Module dictionary insertion problem.");
1916
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001917#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1918/* crt variable checking in VisualStudio .NET 2005 */
1919#include <crtdbg.h>
1920
1921static int prevCrtReportMode;
1922static _invalid_parameter_handler prevCrtHandler;
1923
1924/* Invalid parameter handler. Sets a ValueError exception */
1925static void
1926InvalidParameterHandler(
1927 const wchar_t * expression,
1928 const wchar_t * function,
1929 const wchar_t * file,
1930 unsigned int line,
1931 uintptr_t pReserved)
1932{
1933 /* Do nothing, allow execution to continue. Usually this
1934 * means that the CRT will set errno to EINVAL
1935 */
1936}
1937#endif
1938
1939
Thomas Wouters477c8d52006-05-27 19:21:47 +00001940PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001941_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001942{
Neal Norwitz2633c692007-02-26 22:22:47 +00001943 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001944
1945 PRE_INIT(BaseException)
1946 PRE_INIT(Exception)
1947 PRE_INIT(StandardError)
1948 PRE_INIT(TypeError)
1949 PRE_INIT(StopIteration)
1950 PRE_INIT(GeneratorExit)
1951 PRE_INIT(SystemExit)
1952 PRE_INIT(KeyboardInterrupt)
1953 PRE_INIT(ImportError)
1954 PRE_INIT(EnvironmentError)
1955 PRE_INIT(IOError)
1956 PRE_INIT(OSError)
1957#ifdef MS_WINDOWS
1958 PRE_INIT(WindowsError)
1959#endif
1960#ifdef __VMS
1961 PRE_INIT(VMSError)
1962#endif
1963 PRE_INIT(EOFError)
1964 PRE_INIT(RuntimeError)
1965 PRE_INIT(NotImplementedError)
1966 PRE_INIT(NameError)
1967 PRE_INIT(UnboundLocalError)
1968 PRE_INIT(AttributeError)
1969 PRE_INIT(SyntaxError)
1970 PRE_INIT(IndentationError)
1971 PRE_INIT(TabError)
1972 PRE_INIT(LookupError)
1973 PRE_INIT(IndexError)
1974 PRE_INIT(KeyError)
1975 PRE_INIT(ValueError)
1976 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001977 PRE_INIT(UnicodeEncodeError)
1978 PRE_INIT(UnicodeDecodeError)
1979 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001980 PRE_INIT(AssertionError)
1981 PRE_INIT(ArithmeticError)
1982 PRE_INIT(FloatingPointError)
1983 PRE_INIT(OverflowError)
1984 PRE_INIT(ZeroDivisionError)
1985 PRE_INIT(SystemError)
1986 PRE_INIT(ReferenceError)
1987 PRE_INIT(MemoryError)
1988 PRE_INIT(Warning)
1989 PRE_INIT(UserWarning)
1990 PRE_INIT(DeprecationWarning)
1991 PRE_INIT(PendingDeprecationWarning)
1992 PRE_INIT(SyntaxWarning)
1993 PRE_INIT(RuntimeWarning)
1994 PRE_INIT(FutureWarning)
1995 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001996 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997
Thomas Wouters477c8d52006-05-27 19:21:47 +00001998 bltinmod = PyImport_ImportModule("__builtin__");
1999 if (bltinmod == NULL)
2000 Py_FatalError("exceptions bootstrapping error.");
2001 bdict = PyModule_GetDict(bltinmod);
2002 if (bdict == NULL)
2003 Py_FatalError("exceptions bootstrapping error.");
2004
2005 POST_INIT(BaseException)
2006 POST_INIT(Exception)
2007 POST_INIT(StandardError)
2008 POST_INIT(TypeError)
2009 POST_INIT(StopIteration)
2010 POST_INIT(GeneratorExit)
2011 POST_INIT(SystemExit)
2012 POST_INIT(KeyboardInterrupt)
2013 POST_INIT(ImportError)
2014 POST_INIT(EnvironmentError)
2015 POST_INIT(IOError)
2016 POST_INIT(OSError)
2017#ifdef MS_WINDOWS
2018 POST_INIT(WindowsError)
2019#endif
2020#ifdef __VMS
2021 POST_INIT(VMSError)
2022#endif
2023 POST_INIT(EOFError)
2024 POST_INIT(RuntimeError)
2025 POST_INIT(NotImplementedError)
2026 POST_INIT(NameError)
2027 POST_INIT(UnboundLocalError)
2028 POST_INIT(AttributeError)
2029 POST_INIT(SyntaxError)
2030 POST_INIT(IndentationError)
2031 POST_INIT(TabError)
2032 POST_INIT(LookupError)
2033 POST_INIT(IndexError)
2034 POST_INIT(KeyError)
2035 POST_INIT(ValueError)
2036 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002037 POST_INIT(UnicodeEncodeError)
2038 POST_INIT(UnicodeDecodeError)
2039 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002040 POST_INIT(AssertionError)
2041 POST_INIT(ArithmeticError)
2042 POST_INIT(FloatingPointError)
2043 POST_INIT(OverflowError)
2044 POST_INIT(ZeroDivisionError)
2045 POST_INIT(SystemError)
2046 POST_INIT(ReferenceError)
2047 POST_INIT(MemoryError)
2048 POST_INIT(Warning)
2049 POST_INIT(UserWarning)
2050 POST_INIT(DeprecationWarning)
2051 POST_INIT(PendingDeprecationWarning)
2052 POST_INIT(SyntaxWarning)
2053 POST_INIT(RuntimeWarning)
2054 POST_INIT(FutureWarning)
2055 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002056 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002057
2058 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2059 if (!PyExc_MemoryErrorInst)
2060 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2061
2062 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002063
2064#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2065 /* Set CRT argument error handler */
2066 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2067 /* turn off assertions in debug mode */
2068 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2069#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002070}
2071
2072void
2073_PyExc_Fini(void)
2074{
2075 Py_XDECREF(PyExc_MemoryErrorInst);
2076 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002077#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2078 /* reset CRT error handling */
2079 _set_invalid_parameter_handler(prevCrtHandler);
2080 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2081#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002082}