blob: 1df0ea0852db27622efad8c2533edc1fbbec8ce4 [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{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000081 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000082 case 0:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000083 return PyUnicode_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 case 1:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000085 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +000086 default:
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +000087 return PyObject_Unicode(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +000088 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000089}
90
91static PyObject *
92BaseException_repr(PyBaseExceptionObject *self)
93{
Thomas Wouters477c8d52006-05-27 19:21:47 +000094 char *name;
95 char *dot;
96
Thomas Wouters477c8d52006-05-27 19:21:47 +000097 name = (char *)self->ob_type->tp_name;
98 dot = strrchr(name, '.');
99 if (dot != NULL) name = dot+1;
100
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000101 return PyUnicode_FromFormat("%s%R", name, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000102}
103
104/* Pickling support */
105static PyObject *
106BaseException_reduce(PyBaseExceptionObject *self)
107{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000108 if (self->args && self->dict)
109 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
110 else
111 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000112}
113
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000114/*
115 * Needed for backward compatibility, since exceptions used to store
116 * all their attributes in the __dict__. Code is taken from cPickle's
117 * load_build function.
118 */
119static PyObject *
120BaseException_setstate(PyObject *self, PyObject *state)
121{
122 PyObject *d_key, *d_value;
123 Py_ssize_t i = 0;
124
125 if (state != Py_None) {
126 if (!PyDict_Check(state)) {
127 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
128 return NULL;
129 }
130 while (PyDict_Next(state, &i, &d_key, &d_value)) {
131 if (PyObject_SetAttr(self, d_key, d_value) < 0)
132 return NULL;
133 }
134 }
135 Py_RETURN_NONE;
136}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000137
Thomas Wouters477c8d52006-05-27 19:21:47 +0000138
139static PyMethodDef BaseException_methods[] = {
140 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000141 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000142 {NULL, NULL, 0, NULL},
143};
144
145
Thomas Wouters477c8d52006-05-27 19:21:47 +0000146static PyObject *
147BaseException_get_dict(PyBaseExceptionObject *self)
148{
149 if (self->dict == NULL) {
150 self->dict = PyDict_New();
151 if (!self->dict)
152 return NULL;
153 }
154 Py_INCREF(self->dict);
155 return self->dict;
156}
157
158static int
159BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
160{
161 if (val == NULL) {
162 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
163 return -1;
164 }
165 if (!PyDict_Check(val)) {
166 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
167 return -1;
168 }
169 Py_CLEAR(self->dict);
170 Py_INCREF(val);
171 self->dict = val;
172 return 0;
173}
174
175static PyObject *
176BaseException_get_args(PyBaseExceptionObject *self)
177{
178 if (self->args == NULL) {
179 Py_INCREF(Py_None);
180 return Py_None;
181 }
182 Py_INCREF(self->args);
183 return self->args;
184}
185
186static int
187BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
188{
189 PyObject *seq;
190 if (val == NULL) {
191 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
192 return -1;
193 }
194 seq = PySequence_Tuple(val);
195 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000196 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000197 self->args = seq;
198 return 0;
199}
200
Guido van Rossum360e4b82007-05-14 22:51:27 +0000201
Thomas Wouters477c8d52006-05-27 19:21:47 +0000202static PyGetSetDef BaseException_getset[] = {
203 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
204 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
205 {NULL},
206};
207
208
209static PyTypeObject _PyExc_BaseException = {
210 PyObject_HEAD_INIT(NULL)
211 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000212 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000213 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
214 0, /*tp_itemsize*/
215 (destructor)BaseException_dealloc, /*tp_dealloc*/
216 0, /*tp_print*/
217 0, /*tp_getattr*/
218 0, /*tp_setattr*/
219 0, /* tp_compare; */
220 (reprfunc)BaseException_repr, /*tp_repr*/
221 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000222 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000223 0, /*tp_as_mapping*/
224 0, /*tp_hash */
225 0, /*tp_call*/
226 (reprfunc)BaseException_str, /*tp_str*/
227 PyObject_GenericGetAttr, /*tp_getattro*/
228 PyObject_GenericSetAttr, /*tp_setattro*/
229 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000230 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
231 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000232 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
233 (traverseproc)BaseException_traverse, /* tp_traverse */
234 (inquiry)BaseException_clear, /* tp_clear */
235 0, /* tp_richcompare */
236 0, /* tp_weaklistoffset */
237 0, /* tp_iter */
238 0, /* tp_iternext */
239 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000240 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000241 BaseException_getset, /* tp_getset */
242 0, /* tp_base */
243 0, /* tp_dict */
244 0, /* tp_descr_get */
245 0, /* tp_descr_set */
246 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
247 (initproc)BaseException_init, /* tp_init */
248 0, /* tp_alloc */
249 BaseException_new, /* tp_new */
250};
251/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
252from the previous implmentation and also allowing Python objects to be used
253in the API */
254PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
255
256/* note these macros omit the last semicolon so the macro invocation may
257 * include it and not look strange.
258 */
259#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
260static PyTypeObject _PyExc_ ## EXCNAME = { \
261 PyObject_HEAD_INIT(NULL) \
262 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000263 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000264 sizeof(PyBaseExceptionObject), \
265 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
266 0, 0, 0, 0, 0, 0, 0, \
267 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
268 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
269 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
270 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
271 (initproc)BaseException_init, 0, BaseException_new,\
272}; \
273PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
274
275#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
276static PyTypeObject _PyExc_ ## EXCNAME = { \
277 PyObject_HEAD_INIT(NULL) \
278 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000279 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000281 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000282 0, 0, 0, 0, 0, \
283 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
285 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000286 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000287 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000288}; \
289PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
290
291#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
292static PyTypeObject _PyExc_ ## EXCNAME = { \
293 PyObject_HEAD_INIT(NULL) \
294 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000295 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000296 sizeof(Py ## EXCSTORE ## Object), 0, \
297 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
298 (reprfunc)EXCSTR, 0, 0, 0, \
299 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
300 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
301 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
302 EXCMEMBERS, 0, &_ ## EXCBASE, \
303 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000304 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000305}; \
306PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
307
308
309/*
310 * Exception extends BaseException
311 */
312SimpleExtendsException(PyExc_BaseException, Exception,
313 "Common base class for all non-exit exceptions.");
314
315
316/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000317 * TypeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000318 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000319SimpleExtendsException(PyExc_Exception, TypeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320 "Inappropriate argument type.");
321
322
323/*
324 * StopIteration extends Exception
325 */
326SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000327 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328
329
330/*
331 * GeneratorExit extends Exception
332 */
333SimpleExtendsException(PyExc_Exception, GeneratorExit,
334 "Request that a generator exit.");
335
336
337/*
338 * SystemExit extends BaseException
339 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340
341static int
342SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
343{
344 Py_ssize_t size = PyTuple_GET_SIZE(args);
345
346 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
347 return -1;
348
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000349 if (size == 0)
350 return 0;
351 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000352 if (size == 1)
353 self->code = PyTuple_GET_ITEM(args, 0);
354 else if (size > 1)
355 self->code = args;
356 Py_INCREF(self->code);
357 return 0;
358}
359
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000360static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000361SystemExit_clear(PySystemExitObject *self)
362{
363 Py_CLEAR(self->code);
364 return BaseException_clear((PyBaseExceptionObject *)self);
365}
366
367static void
368SystemExit_dealloc(PySystemExitObject *self)
369{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000370 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000371 SystemExit_clear(self);
372 self->ob_type->tp_free((PyObject *)self);
373}
374
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000375static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000376SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
377{
378 Py_VISIT(self->code);
379 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
380}
381
382static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000383 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
384 PyDoc_STR("exception code")},
385 {NULL} /* Sentinel */
386};
387
388ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
389 SystemExit_dealloc, 0, SystemExit_members, 0,
390 "Request to exit from the interpreter.");
391
392/*
393 * KeyboardInterrupt extends BaseException
394 */
395SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
396 "Program interrupted by user.");
397
398
399/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000400 * ImportError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000401 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000402SimpleExtendsException(PyExc_Exception, ImportError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000403 "Import can't find module, or can't find name in module.");
404
405
406/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000407 * EnvironmentError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408 */
409
Thomas Wouters477c8d52006-05-27 19:21:47 +0000410/* Where a function has a single filename, such as open() or some
411 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
412 * called, giving a third argument which is the filename. But, so
413 * that old code using in-place unpacking doesn't break, e.g.:
414 *
415 * except IOError, (errno, strerror):
416 *
417 * we hack args so that it only contains two items. This also
418 * means we need our own __str__() which prints out the filename
419 * when it was supplied.
420 */
421static int
422EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
423 PyObject *kwds)
424{
425 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
426 PyObject *subslice = NULL;
427
428 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
429 return -1;
430
Thomas Wouters89f507f2006-12-13 04:49:30 +0000431 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432 return 0;
433 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000434
435 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000436 &myerrno, &strerror, &filename)) {
437 return -1;
438 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000439 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440 self->myerrno = myerrno;
441 Py_INCREF(self->myerrno);
442
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000443 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000444 self->strerror = strerror;
445 Py_INCREF(self->strerror);
446
447 /* self->filename will remain Py_None otherwise */
448 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000449 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000450 self->filename = filename;
451 Py_INCREF(self->filename);
452
453 subslice = PyTuple_GetSlice(args, 0, 2);
454 if (!subslice)
455 return -1;
456
457 Py_DECREF(self->args); /* replacing args */
458 self->args = subslice;
459 }
460 return 0;
461}
462
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000463static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464EnvironmentError_clear(PyEnvironmentErrorObject *self)
465{
466 Py_CLEAR(self->myerrno);
467 Py_CLEAR(self->strerror);
468 Py_CLEAR(self->filename);
469 return BaseException_clear((PyBaseExceptionObject *)self);
470}
471
472static void
473EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
474{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000475 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000476 EnvironmentError_clear(self);
477 self->ob_type->tp_free((PyObject *)self);
478}
479
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000480static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000481EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
482 void *arg)
483{
484 Py_VISIT(self->myerrno);
485 Py_VISIT(self->strerror);
486 Py_VISIT(self->filename);
487 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
488}
489
490static PyObject *
491EnvironmentError_str(PyEnvironmentErrorObject *self)
492{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000493 if (self->filename)
494 return PyUnicode_FromFormat("[Errno %S] %S: %R",
495 self->myerrno ? self->myerrno: Py_None,
496 self->strerror ? self->strerror: Py_None,
497 self->filename);
498 else if (self->myerrno && self->strerror)
499 return PyUnicode_FromFormat("[Errno %S] %S",
500 self->myerrno ? self->myerrno: Py_None,
501 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000503 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504}
505
506static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000507 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
508 PyDoc_STR("exception errno")},
509 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
510 PyDoc_STR("exception strerror")},
511 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
512 PyDoc_STR("exception filename")},
513 {NULL} /* Sentinel */
514};
515
516
517static PyObject *
518EnvironmentError_reduce(PyEnvironmentErrorObject *self)
519{
520 PyObject *args = self->args;
521 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000522
Thomas Wouters477c8d52006-05-27 19:21:47 +0000523 /* self->args is only the first two real arguments if there was a
524 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000525 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 args = PyTuple_New(3);
527 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000528
529 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000530 Py_INCREF(tmp);
531 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000532
533 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000534 Py_INCREF(tmp);
535 PyTuple_SET_ITEM(args, 1, tmp);
536
537 Py_INCREF(self->filename);
538 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000539 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000540 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000541
542 if (self->dict)
543 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
544 else
545 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000546 Py_DECREF(args);
547 return res;
548}
549
550
551static PyMethodDef EnvironmentError_methods[] = {
552 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
553 {NULL}
554};
555
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000556ComplexExtendsException(PyExc_Exception, EnvironmentError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000557 EnvironmentError, EnvironmentError_dealloc,
558 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000559 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000560 "Base class for I/O related errors.");
561
562
563/*
564 * IOError extends EnvironmentError
565 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000566MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000567 EnvironmentError, "I/O operation failed.");
568
569
570/*
571 * OSError extends EnvironmentError
572 */
573MiddlingExtendsException(PyExc_EnvironmentError, OSError,
574 EnvironmentError, "OS system call failed.");
575
576
577/*
578 * WindowsError extends OSError
579 */
580#ifdef MS_WINDOWS
581#include "errmap.h"
582
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000583static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000584WindowsError_clear(PyWindowsErrorObject *self)
585{
586 Py_CLEAR(self->myerrno);
587 Py_CLEAR(self->strerror);
588 Py_CLEAR(self->filename);
589 Py_CLEAR(self->winerror);
590 return BaseException_clear((PyBaseExceptionObject *)self);
591}
592
593static void
594WindowsError_dealloc(PyWindowsErrorObject *self)
595{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000596 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000597 WindowsError_clear(self);
598 self->ob_type->tp_free((PyObject *)self);
599}
600
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000601static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000602WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
603{
604 Py_VISIT(self->myerrno);
605 Py_VISIT(self->strerror);
606 Py_VISIT(self->filename);
607 Py_VISIT(self->winerror);
608 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
609}
610
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611static int
612WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
613{
614 PyObject *o_errcode = NULL;
615 long errcode;
616 long posix_errno;
617
618 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
619 == -1)
620 return -1;
621
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000622 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000623 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000624
625 /* Set errno to the POSIX errno, and winerror to the Win32
626 error code. */
627 errcode = PyInt_AsLong(self->myerrno);
628 if (errcode == -1 && PyErr_Occurred())
629 return -1;
630 posix_errno = winerror_to_errno(errcode);
631
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000632 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633 self->winerror = self->myerrno;
634
635 o_errcode = PyInt_FromLong(posix_errno);
636 if (!o_errcode)
637 return -1;
638
639 self->myerrno = o_errcode;
640
641 return 0;
642}
643
644
645static PyObject *
646WindowsError_str(PyWindowsErrorObject *self)
647{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000648 if (self->filename)
649 return PyUnicode_FromFormat("[Error %S] %S: %R",
650 self->winerror ? self->winerror: Py_None,
651 self->strerror ? self->strerror: Py_None,
652 self->filename);
653 else if (self->winerror && self->strerror)
654 return PyUnicode_FromFormat("[Error %S] %S",
655 self->winerror ? self->winerror: Py_None,
656 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000658 return EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659}
660
661static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000662 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
663 PyDoc_STR("POSIX exception code")},
664 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
665 PyDoc_STR("exception strerror")},
666 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
667 PyDoc_STR("exception filename")},
668 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
669 PyDoc_STR("Win32 exception code")},
670 {NULL} /* Sentinel */
671};
672
673ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
674 WindowsError_dealloc, 0, WindowsError_members,
675 WindowsError_str, "MS-Windows OS system call failed.");
676
677#endif /* MS_WINDOWS */
678
679
680/*
681 * VMSError extends OSError (I think)
682 */
683#ifdef __VMS
684MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
685 "OpenVMS OS system call failed.");
686#endif
687
688
689/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000690 * EOFError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000691 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000692SimpleExtendsException(PyExc_Exception, EOFError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693 "Read beyond end of file.");
694
695
696/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000697 * RuntimeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000698 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000699SimpleExtendsException(PyExc_Exception, RuntimeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700 "Unspecified run-time error.");
701
702
703/*
704 * NotImplementedError extends RuntimeError
705 */
706SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
707 "Method or function hasn't been implemented yet.");
708
709/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000710 * NameError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000711 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000712SimpleExtendsException(PyExc_Exception, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000713 "Name not found globally.");
714
715/*
716 * UnboundLocalError extends NameError
717 */
718SimpleExtendsException(PyExc_NameError, UnboundLocalError,
719 "Local name referenced but not bound to a value.");
720
721/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000722 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000723 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000724SimpleExtendsException(PyExc_Exception, AttributeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000725 "Attribute not found.");
726
727
728/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000729 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000730 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000731
732static int
733SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
734{
735 PyObject *info = NULL;
736 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
737
738 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
739 return -1;
740
741 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000742 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000743 self->msg = PyTuple_GET_ITEM(args, 0);
744 Py_INCREF(self->msg);
745 }
746 if (lenargs == 2) {
747 info = PyTuple_GET_ITEM(args, 1);
748 info = PySequence_Tuple(info);
749 if (!info) return -1;
750
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000751 if (PyTuple_GET_SIZE(info) != 4) {
752 /* not a very good error message, but it's what Python 2.4 gives */
753 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
754 Py_DECREF(info);
755 return -1;
756 }
757
758 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759 self->filename = PyTuple_GET_ITEM(info, 0);
760 Py_INCREF(self->filename);
761
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000762 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763 self->lineno = PyTuple_GET_ITEM(info, 1);
764 Py_INCREF(self->lineno);
765
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000766 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000767 self->offset = PyTuple_GET_ITEM(info, 2);
768 Py_INCREF(self->offset);
769
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000770 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771 self->text = PyTuple_GET_ITEM(info, 3);
772 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000773
774 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000775 }
776 return 0;
777}
778
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000779static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780SyntaxError_clear(PySyntaxErrorObject *self)
781{
782 Py_CLEAR(self->msg);
783 Py_CLEAR(self->filename);
784 Py_CLEAR(self->lineno);
785 Py_CLEAR(self->offset);
786 Py_CLEAR(self->text);
787 Py_CLEAR(self->print_file_and_line);
788 return BaseException_clear((PyBaseExceptionObject *)self);
789}
790
791static void
792SyntaxError_dealloc(PySyntaxErrorObject *self)
793{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000794 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000795 SyntaxError_clear(self);
796 self->ob_type->tp_free((PyObject *)self);
797}
798
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000799static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000800SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
801{
802 Py_VISIT(self->msg);
803 Py_VISIT(self->filename);
804 Py_VISIT(self->lineno);
805 Py_VISIT(self->offset);
806 Py_VISIT(self->text);
807 Py_VISIT(self->print_file_and_line);
808 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
809}
810
811/* This is called "my_basename" instead of just "basename" to avoid name
812 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
813 defined, and Python does define that. */
814static char *
815my_basename(char *name)
816{
817 char *cp = name;
818 char *result = name;
819
820 if (name == NULL)
821 return "???";
822 while (*cp != '\0') {
823 if (*cp == SEP)
824 result = cp + 1;
825 ++cp;
826 }
827 return result;
828}
829
830
831static PyObject *
832SyntaxError_str(PySyntaxErrorObject *self)
833{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000834 int have_filename = 0;
835 int have_lineno = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000836
837 /* XXX -- do all the additional formatting with filename and
838 lineno here */
839
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000840 have_filename = (self->filename != NULL) &&
841 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +0000842 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000843
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000844 if (!have_filename && !have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000845 return PyObject_Unicode(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000846
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000847 if (have_filename && have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000848 return PyUnicode_FromFormat("%S (%s, line %ld)",
849 self->msg ? self->msg : Py_None,
850 my_basename(PyString_AS_STRING(self->filename)),
851 PyInt_AsLong(self->lineno));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000852 else if (have_filename)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000853 return PyUnicode_FromFormat("%S (%s)",
854 self->msg ? self->msg : Py_None,
855 my_basename(PyString_AS_STRING(self->filename)));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000856 else /* only have_lineno */
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000857 return PyUnicode_FromFormat("%S (line %ld)",
858 self->msg ? self->msg : Py_None,
859 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860}
861
862static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000863 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
864 PyDoc_STR("exception msg")},
865 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
866 PyDoc_STR("exception filename")},
867 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
868 PyDoc_STR("exception lineno")},
869 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
870 PyDoc_STR("exception offset")},
871 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
872 PyDoc_STR("exception text")},
873 {"print_file_and_line", T_OBJECT,
874 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
875 PyDoc_STR("exception print_file_and_line")},
876 {NULL} /* Sentinel */
877};
878
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000879ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000880 SyntaxError_dealloc, 0, SyntaxError_members,
881 SyntaxError_str, "Invalid syntax.");
882
883
884/*
885 * IndentationError extends SyntaxError
886 */
887MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
888 "Improper indentation.");
889
890
891/*
892 * TabError extends IndentationError
893 */
894MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
895 "Improper mixture of spaces and tabs.");
896
897
898/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000899 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000900 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000901SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000902 "Base class for lookup errors.");
903
904
905/*
906 * IndexError extends LookupError
907 */
908SimpleExtendsException(PyExc_LookupError, IndexError,
909 "Sequence index out of range.");
910
911
912/*
913 * KeyError extends LookupError
914 */
915static PyObject *
916KeyError_str(PyBaseExceptionObject *self)
917{
918 /* If args is a tuple of exactly one item, apply repr to args[0].
919 This is done so that e.g. the exception raised by {}[''] prints
920 KeyError: ''
921 rather than the confusing
922 KeyError
923 alone. The downside is that if KeyError is raised with an explanatory
924 string, that string will be displayed in quotes. Too bad.
925 If args is anything else, use the default BaseException__str__().
926 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000927 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000928 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000929 }
930 return BaseException_str(self);
931}
932
933ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
934 0, 0, 0, KeyError_str, "Mapping key not found.");
935
936
937/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000938 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000940SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000941 "Inappropriate argument value (of correct type).");
942
943/*
944 * UnicodeError extends ValueError
945 */
946
947SimpleExtendsException(PyExc_ValueError, UnicodeError,
948 "Unicode related error.");
949
Thomas Wouters477c8d52006-05-27 19:21:47 +0000950static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +0000951get_bytes(PyObject *attr, const char *name)
952{
953 if (!attr) {
954 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
955 return NULL;
956 }
957
958 if (!PyBytes_Check(attr)) {
959 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
960 return NULL;
961 }
962 Py_INCREF(attr);
963 return attr;
964}
965
966static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967get_unicode(PyObject *attr, const char *name)
968{
969 if (!attr) {
970 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
971 return NULL;
972 }
973
974 if (!PyUnicode_Check(attr)) {
975 PyErr_Format(PyExc_TypeError,
976 "%.200s attribute must be unicode", name);
977 return NULL;
978 }
979 Py_INCREF(attr);
980 return attr;
981}
982
Walter Dörwaldd2034312007-05-18 16:29:38 +0000983static int
984set_unicodefromstring(PyObject **attr, const char *value)
985{
986 PyObject *obj = PyUnicode_FromString(value);
987 if (!obj)
988 return -1;
989 Py_CLEAR(*attr);
990 *attr = obj;
991 return 0;
992}
993
Thomas Wouters477c8d52006-05-27 19:21:47 +0000994PyObject *
995PyUnicodeEncodeError_GetEncoding(PyObject *exc)
996{
Walter Dörwaldd2034312007-05-18 16:29:38 +0000997 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998}
999
1000PyObject *
1001PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1002{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001003 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001004}
1005
1006PyObject *
1007PyUnicodeEncodeError_GetObject(PyObject *exc)
1008{
1009 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1010}
1011
1012PyObject *
1013PyUnicodeDecodeError_GetObject(PyObject *exc)
1014{
Walter Dörwald612344f2007-05-04 19:28:21 +00001015 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001016}
1017
1018PyObject *
1019PyUnicodeTranslateError_GetObject(PyObject *exc)
1020{
1021 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1022}
1023
1024int
1025PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1026{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001027 Py_ssize_t size;
1028 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1029 "object");
1030 if (!obj)
1031 return -1;
1032 *start = ((PyUnicodeErrorObject *)exc)->start;
1033 size = PyUnicode_GET_SIZE(obj);
1034 if (*start<0)
1035 *start = 0; /*XXX check for values <0*/
1036 if (*start>=size)
1037 *start = size-1;
1038 Py_DECREF(obj);
1039 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001040}
1041
1042
1043int
1044PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1045{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001046 Py_ssize_t size;
1047 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1048 if (!obj)
1049 return -1;
1050 size = PyBytes_GET_SIZE(obj);
1051 *start = ((PyUnicodeErrorObject *)exc)->start;
1052 if (*start<0)
1053 *start = 0;
1054 if (*start>=size)
1055 *start = size-1;
1056 Py_DECREF(obj);
1057 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058}
1059
1060
1061int
1062PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1063{
1064 return PyUnicodeEncodeError_GetStart(exc, start);
1065}
1066
1067
1068int
1069PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1070{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001071 ((PyUnicodeErrorObject *)exc)->start = start;
1072 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001073}
1074
1075
1076int
1077PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1078{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001079 ((PyUnicodeErrorObject *)exc)->start = start;
1080 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001081}
1082
1083
1084int
1085PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1086{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001087 ((PyUnicodeErrorObject *)exc)->start = start;
1088 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089}
1090
1091
1092int
1093PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1094{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001095 Py_ssize_t size;
1096 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1097 "object");
1098 if (!obj)
1099 return -1;
1100 *end = ((PyUnicodeErrorObject *)exc)->end;
1101 size = PyUnicode_GET_SIZE(obj);
1102 if (*end<1)
1103 *end = 1;
1104 if (*end>size)
1105 *end = size;
1106 Py_DECREF(obj);
1107 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001108}
1109
1110
1111int
1112PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1113{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001114 Py_ssize_t size;
1115 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1116 if (!obj)
1117 return -1;
1118 size = PyBytes_GET_SIZE(obj);
1119 *end = ((PyUnicodeErrorObject *)exc)->end;
1120 if (*end<1)
1121 *end = 1;
1122 if (*end>size)
1123 *end = size;
1124 Py_DECREF(obj);
1125 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126}
1127
1128
1129int
1130PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1131{
1132 return PyUnicodeEncodeError_GetEnd(exc, start);
1133}
1134
1135
1136int
1137PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1138{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001139 ((PyUnicodeErrorObject *)exc)->end = end;
1140 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001141}
1142
1143
1144int
1145PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1146{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001147 ((PyUnicodeErrorObject *)exc)->end = end;
1148 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001149}
1150
1151
1152int
1153PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1154{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001155 ((PyUnicodeErrorObject *)exc)->end = end;
1156 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001157}
1158
1159PyObject *
1160PyUnicodeEncodeError_GetReason(PyObject *exc)
1161{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001162 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163}
1164
1165
1166PyObject *
1167PyUnicodeDecodeError_GetReason(PyObject *exc)
1168{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001169 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001170}
1171
1172
1173PyObject *
1174PyUnicodeTranslateError_GetReason(PyObject *exc)
1175{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001176 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001177}
1178
1179
1180int
1181PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1182{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001183 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1184 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185}
1186
1187
1188int
1189PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1190{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001191 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1192 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193}
1194
1195
1196int
1197PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1198{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001199 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1200 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201}
1202
1203
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204static int
1205UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1206 PyTypeObject *objecttype)
1207{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001208 Py_CLEAR(self->encoding);
1209 Py_CLEAR(self->object);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001210 Py_CLEAR(self->reason);
1211
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001212 if (!PyArg_ParseTuple(args, "O!O!nnO!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001213 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001214 objecttype, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001215 &self->start,
1216 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001217 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001218 self->encoding = self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219 return -1;
1220 }
1221
1222 Py_INCREF(self->encoding);
1223 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001224 Py_INCREF(self->reason);
1225
1226 return 0;
1227}
1228
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001229static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001230UnicodeError_clear(PyUnicodeErrorObject *self)
1231{
1232 Py_CLEAR(self->encoding);
1233 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001234 Py_CLEAR(self->reason);
1235 return BaseException_clear((PyBaseExceptionObject *)self);
1236}
1237
1238static void
1239UnicodeError_dealloc(PyUnicodeErrorObject *self)
1240{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001241 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001242 UnicodeError_clear(self);
1243 self->ob_type->tp_free((PyObject *)self);
1244}
1245
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001246static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1248{
1249 Py_VISIT(self->encoding);
1250 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001251 Py_VISIT(self->reason);
1252 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1253}
1254
1255static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001256 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1257 PyDoc_STR("exception encoding")},
1258 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1259 PyDoc_STR("exception object")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001260 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001261 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001262 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001263 PyDoc_STR("exception end")},
1264 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1265 PyDoc_STR("exception reason")},
1266 {NULL} /* Sentinel */
1267};
1268
1269
1270/*
1271 * UnicodeEncodeError extends UnicodeError
1272 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273
1274static int
1275UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1276{
1277 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1278 return -1;
1279 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1280 kwds, &PyUnicode_Type);
1281}
1282
1283static PyObject *
1284UnicodeEncodeError_str(PyObject *self)
1285{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001286 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001287
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001288 if (uself->end==uself->start+1) {
1289 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001290 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001291 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001292 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001293 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001294 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001295 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001296 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001297 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001298 fmt,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001299 ((PyUnicodeErrorObject *)self)->encoding,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001300 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001301 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001302 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001303 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001304 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001305 return PyUnicode_FromFormat(
1306 "'%U' codec can't encode characters in position %zd-%zd: %U",
1307 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001308 uself->start,
1309 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001310 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001311 );
1312}
1313
1314static PyTypeObject _PyExc_UnicodeEncodeError = {
1315 PyObject_HEAD_INIT(NULL)
1316 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001317 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001318 sizeof(PyUnicodeErrorObject), 0,
1319 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1320 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1321 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001322 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1323 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001324 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001325 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326};
1327PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1328
1329PyObject *
1330PyUnicodeEncodeError_Create(
1331 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1332 Py_ssize_t start, Py_ssize_t end, const char *reason)
1333{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001334 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001335 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001336}
1337
1338
1339/*
1340 * UnicodeDecodeError extends UnicodeError
1341 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001342
1343static int
1344UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1345{
1346 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1347 return -1;
1348 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001349 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350}
1351
1352static PyObject *
1353UnicodeDecodeError_str(PyObject *self)
1354{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001355 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001356
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001357 if (uself->end==uself->start+1) {
1358 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001359 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001360 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001361 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001362 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001363 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001364 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001365 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001366 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001367 return PyUnicode_FromFormat(
1368 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1369 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001370 uself->start,
1371 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001372 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373 );
1374}
1375
1376static PyTypeObject _PyExc_UnicodeDecodeError = {
1377 PyObject_HEAD_INIT(NULL)
1378 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001379 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380 sizeof(PyUnicodeErrorObject), 0,
1381 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1382 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1383 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001384 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1385 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001387 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001388};
1389PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1390
1391PyObject *
1392PyUnicodeDecodeError_Create(
1393 const char *encoding, const char *object, Py_ssize_t length,
1394 Py_ssize_t start, Py_ssize_t end, const char *reason)
1395{
1396 assert(length < INT_MAX);
1397 assert(start < INT_MAX);
1398 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001399 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001401}
1402
1403
1404/*
1405 * UnicodeTranslateError extends UnicodeError
1406 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407
1408static int
1409UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1410 PyObject *kwds)
1411{
1412 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1413 return -1;
1414
1415 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416 Py_CLEAR(self->reason);
1417
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001418 if (!PyArg_ParseTuple(args, "O!nnO!",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419 &PyUnicode_Type, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001420 &self->start,
1421 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001422 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001423 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001424 return -1;
1425 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001426
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428 Py_INCREF(self->reason);
1429
1430 return 0;
1431}
1432
1433
1434static PyObject *
1435UnicodeTranslateError_str(PyObject *self)
1436{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001437 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001438
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001439 if (uself->end==uself->start+1) {
1440 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001441 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001442 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001443 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001444 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001445 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001446 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001447 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001448 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001449 fmt,
1450 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001451 uself->start,
1452 uself->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001453 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001454 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001455 return PyUnicode_FromFormat(
1456 "can't translate characters in position %zd-%zd: %U",
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001457 uself->start,
1458 uself->end-1,
1459 uself->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460 );
1461}
1462
1463static PyTypeObject _PyExc_UnicodeTranslateError = {
1464 PyObject_HEAD_INIT(NULL)
1465 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001466 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467 sizeof(PyUnicodeErrorObject), 0,
1468 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1469 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1470 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001471 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001472 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1473 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001474 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475};
1476PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1477
1478PyObject *
1479PyUnicodeTranslateError_Create(
1480 const Py_UNICODE *object, Py_ssize_t length,
1481 Py_ssize_t start, Py_ssize_t end, const char *reason)
1482{
1483 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001484 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001485}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001486
1487
1488/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001489 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001491SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001492 "Assertion failed.");
1493
1494
1495/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001496 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001498SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499 "Base class for arithmetic errors.");
1500
1501
1502/*
1503 * FloatingPointError extends ArithmeticError
1504 */
1505SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1506 "Floating point operation failed.");
1507
1508
1509/*
1510 * OverflowError extends ArithmeticError
1511 */
1512SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1513 "Result too large to be represented.");
1514
1515
1516/*
1517 * ZeroDivisionError extends ArithmeticError
1518 */
1519SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1520 "Second argument to a division or modulo operation was zero.");
1521
1522
1523/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001524 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001525 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001526SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527 "Internal error in the Python interpreter.\n"
1528 "\n"
1529 "Please report this to the Python maintainer, along with the traceback,\n"
1530 "the Python version, and the hardware/OS platform and version.");
1531
1532
1533/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001534 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001536SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537 "Weak ref proxy used after referent went away.");
1538
1539
1540/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001541 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001543SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544
1545
1546/* Warning category docstrings */
1547
1548/*
1549 * Warning extends Exception
1550 */
1551SimpleExtendsException(PyExc_Exception, Warning,
1552 "Base class for warning categories.");
1553
1554
1555/*
1556 * UserWarning extends Warning
1557 */
1558SimpleExtendsException(PyExc_Warning, UserWarning,
1559 "Base class for warnings generated by user code.");
1560
1561
1562/*
1563 * DeprecationWarning extends Warning
1564 */
1565SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1566 "Base class for warnings about deprecated features.");
1567
1568
1569/*
1570 * PendingDeprecationWarning extends Warning
1571 */
1572SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1573 "Base class for warnings about features which will be deprecated\n"
1574 "in the future.");
1575
1576
1577/*
1578 * SyntaxWarning extends Warning
1579 */
1580SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1581 "Base class for warnings about dubious syntax.");
1582
1583
1584/*
1585 * RuntimeWarning extends Warning
1586 */
1587SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1588 "Base class for warnings about dubious runtime behavior.");
1589
1590
1591/*
1592 * FutureWarning extends Warning
1593 */
1594SimpleExtendsException(PyExc_Warning, FutureWarning,
1595 "Base class for warnings about constructs that will change semantically\n"
1596 "in the future.");
1597
1598
1599/*
1600 * ImportWarning extends Warning
1601 */
1602SimpleExtendsException(PyExc_Warning, ImportWarning,
1603 "Base class for warnings about probable mistakes in module imports");
1604
1605
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001606/*
1607 * UnicodeWarning extends Warning
1608 */
1609SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1610 "Base class for warnings about Unicode related problems, mostly\n"
1611 "related to conversion problems.");
1612
1613
Thomas Wouters477c8d52006-05-27 19:21:47 +00001614/* Pre-computed MemoryError instance. Best to create this as early as
1615 * possible and not wait until a MemoryError is actually raised!
1616 */
1617PyObject *PyExc_MemoryErrorInst=NULL;
1618
Thomas Wouters477c8d52006-05-27 19:21:47 +00001619#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1620 Py_FatalError("exceptions bootstrapping error.");
1621
1622#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001623 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1624 Py_FatalError("Module dictionary insertion problem.");
1625
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001626#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1627/* crt variable checking in VisualStudio .NET 2005 */
1628#include <crtdbg.h>
1629
1630static int prevCrtReportMode;
1631static _invalid_parameter_handler prevCrtHandler;
1632
1633/* Invalid parameter handler. Sets a ValueError exception */
1634static void
1635InvalidParameterHandler(
1636 const wchar_t * expression,
1637 const wchar_t * function,
1638 const wchar_t * file,
1639 unsigned int line,
1640 uintptr_t pReserved)
1641{
1642 /* Do nothing, allow execution to continue. Usually this
1643 * means that the CRT will set errno to EINVAL
1644 */
1645}
1646#endif
1647
1648
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001650_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651{
Neal Norwitz2633c692007-02-26 22:22:47 +00001652 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653
1654 PRE_INIT(BaseException)
1655 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 PRE_INIT(TypeError)
1657 PRE_INIT(StopIteration)
1658 PRE_INIT(GeneratorExit)
1659 PRE_INIT(SystemExit)
1660 PRE_INIT(KeyboardInterrupt)
1661 PRE_INIT(ImportError)
1662 PRE_INIT(EnvironmentError)
1663 PRE_INIT(IOError)
1664 PRE_INIT(OSError)
1665#ifdef MS_WINDOWS
1666 PRE_INIT(WindowsError)
1667#endif
1668#ifdef __VMS
1669 PRE_INIT(VMSError)
1670#endif
1671 PRE_INIT(EOFError)
1672 PRE_INIT(RuntimeError)
1673 PRE_INIT(NotImplementedError)
1674 PRE_INIT(NameError)
1675 PRE_INIT(UnboundLocalError)
1676 PRE_INIT(AttributeError)
1677 PRE_INIT(SyntaxError)
1678 PRE_INIT(IndentationError)
1679 PRE_INIT(TabError)
1680 PRE_INIT(LookupError)
1681 PRE_INIT(IndexError)
1682 PRE_INIT(KeyError)
1683 PRE_INIT(ValueError)
1684 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685 PRE_INIT(UnicodeEncodeError)
1686 PRE_INIT(UnicodeDecodeError)
1687 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001688 PRE_INIT(AssertionError)
1689 PRE_INIT(ArithmeticError)
1690 PRE_INIT(FloatingPointError)
1691 PRE_INIT(OverflowError)
1692 PRE_INIT(ZeroDivisionError)
1693 PRE_INIT(SystemError)
1694 PRE_INIT(ReferenceError)
1695 PRE_INIT(MemoryError)
1696 PRE_INIT(Warning)
1697 PRE_INIT(UserWarning)
1698 PRE_INIT(DeprecationWarning)
1699 PRE_INIT(PendingDeprecationWarning)
1700 PRE_INIT(SyntaxWarning)
1701 PRE_INIT(RuntimeWarning)
1702 PRE_INIT(FutureWarning)
1703 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001704 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705
Thomas Wouters477c8d52006-05-27 19:21:47 +00001706 bltinmod = PyImport_ImportModule("__builtin__");
1707 if (bltinmod == NULL)
1708 Py_FatalError("exceptions bootstrapping error.");
1709 bdict = PyModule_GetDict(bltinmod);
1710 if (bdict == NULL)
1711 Py_FatalError("exceptions bootstrapping error.");
1712
1713 POST_INIT(BaseException)
1714 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 POST_INIT(TypeError)
1716 POST_INIT(StopIteration)
1717 POST_INIT(GeneratorExit)
1718 POST_INIT(SystemExit)
1719 POST_INIT(KeyboardInterrupt)
1720 POST_INIT(ImportError)
1721 POST_INIT(EnvironmentError)
1722 POST_INIT(IOError)
1723 POST_INIT(OSError)
1724#ifdef MS_WINDOWS
1725 POST_INIT(WindowsError)
1726#endif
1727#ifdef __VMS
1728 POST_INIT(VMSError)
1729#endif
1730 POST_INIT(EOFError)
1731 POST_INIT(RuntimeError)
1732 POST_INIT(NotImplementedError)
1733 POST_INIT(NameError)
1734 POST_INIT(UnboundLocalError)
1735 POST_INIT(AttributeError)
1736 POST_INIT(SyntaxError)
1737 POST_INIT(IndentationError)
1738 POST_INIT(TabError)
1739 POST_INIT(LookupError)
1740 POST_INIT(IndexError)
1741 POST_INIT(KeyError)
1742 POST_INIT(ValueError)
1743 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001744 POST_INIT(UnicodeEncodeError)
1745 POST_INIT(UnicodeDecodeError)
1746 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001747 POST_INIT(AssertionError)
1748 POST_INIT(ArithmeticError)
1749 POST_INIT(FloatingPointError)
1750 POST_INIT(OverflowError)
1751 POST_INIT(ZeroDivisionError)
1752 POST_INIT(SystemError)
1753 POST_INIT(ReferenceError)
1754 POST_INIT(MemoryError)
1755 POST_INIT(Warning)
1756 POST_INIT(UserWarning)
1757 POST_INIT(DeprecationWarning)
1758 POST_INIT(PendingDeprecationWarning)
1759 POST_INIT(SyntaxWarning)
1760 POST_INIT(RuntimeWarning)
1761 POST_INIT(FutureWarning)
1762 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001763 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001764
1765 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1766 if (!PyExc_MemoryErrorInst)
1767 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1768
1769 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001770
1771#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1772 /* Set CRT argument error handler */
1773 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1774 /* turn off assertions in debug mode */
1775 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1776#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001777}
1778
1779void
1780_PyExc_Fini(void)
1781{
1782 Py_XDECREF(PyExc_MemoryErrorInst);
1783 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001784#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1785 /* reset CRT error handling */
1786 _set_invalid_parameter_handler(prevCrtHandler);
1787 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1788#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789}