blob: 710495f6105fa6d8f181f242ad29b8de37f5e8ed [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{
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000044 if (!_PyArg_NoKeywords(Py_Type(self)->tp_name, kwds))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000045 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);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000067 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000068}
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
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000097 name = (char *)Py_Type(self)->tp_name;
Thomas Wouters477c8d52006-05-27 19:21:47 +000098 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)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000109 return PyTuple_Pack(3, Py_Type(self), self->args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000110 else
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000111 return PyTuple_Pack(2, Py_Type(self), 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 = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000210 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +0000211 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000212 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
213 0, /*tp_itemsize*/
214 (destructor)BaseException_dealloc, /*tp_dealloc*/
215 0, /*tp_print*/
216 0, /*tp_getattr*/
217 0, /*tp_setattr*/
218 0, /* tp_compare; */
219 (reprfunc)BaseException_repr, /*tp_repr*/
220 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000221 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222 0, /*tp_as_mapping*/
223 0, /*tp_hash */
224 0, /*tp_call*/
225 (reprfunc)BaseException_str, /*tp_str*/
226 PyObject_GenericGetAttr, /*tp_getattro*/
227 PyObject_GenericSetAttr, /*tp_setattro*/
228 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000229 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
230 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000231 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
232 (traverseproc)BaseException_traverse, /* tp_traverse */
233 (inquiry)BaseException_clear, /* tp_clear */
234 0, /* tp_richcompare */
235 0, /* tp_weaklistoffset */
236 0, /* tp_iter */
237 0, /* tp_iternext */
238 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000239 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000240 BaseException_getset, /* tp_getset */
241 0, /* tp_base */
242 0, /* tp_dict */
243 0, /* tp_descr_get */
244 0, /* tp_descr_set */
245 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
246 (initproc)BaseException_init, /* tp_init */
247 0, /* tp_alloc */
248 BaseException_new, /* tp_new */
249};
250/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
251from the previous implmentation and also allowing Python objects to be used
252in the API */
253PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
254
255/* note these macros omit the last semicolon so the macro invocation may
256 * include it and not look strange.
257 */
258#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
259static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000260 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000261 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000262 sizeof(PyBaseExceptionObject), \
263 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
264 0, 0, 0, 0, 0, 0, 0, \
265 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
266 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
267 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
268 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
269 (initproc)BaseException_init, 0, BaseException_new,\
270}; \
271PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
272
273#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
274static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000275 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000276 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000278 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000279 0, 0, 0, 0, 0, \
280 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000281 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
282 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000283 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000285}; \
286PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
287
288#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
289static PyTypeObject _PyExc_ ## EXCNAME = { \
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000290 PyVarObject_HEAD_INIT(NULL, 0) \
Neal Norwitz2633c692007-02-26 22:22:47 +0000291 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000292 sizeof(Py ## EXCSTORE ## Object), 0, \
293 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
294 (reprfunc)EXCSTR, 0, 0, 0, \
295 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
296 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
297 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
298 EXCMEMBERS, 0, &_ ## EXCBASE, \
299 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000300 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000301}; \
302PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
303
304
305/*
306 * Exception extends BaseException
307 */
308SimpleExtendsException(PyExc_BaseException, Exception,
309 "Common base class for all non-exit exceptions.");
310
311
312/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000313 * TypeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000314 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000315SimpleExtendsException(PyExc_Exception, TypeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316 "Inappropriate argument type.");
317
318
319/*
320 * StopIteration extends Exception
321 */
322SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000323 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324
325
326/*
327 * GeneratorExit extends Exception
328 */
329SimpleExtendsException(PyExc_Exception, GeneratorExit,
330 "Request that a generator exit.");
331
332
333/*
334 * SystemExit extends BaseException
335 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000336
337static int
338SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
339{
340 Py_ssize_t size = PyTuple_GET_SIZE(args);
341
342 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
343 return -1;
344
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000345 if (size == 0)
346 return 0;
347 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000348 if (size == 1)
349 self->code = PyTuple_GET_ITEM(args, 0);
350 else if (size > 1)
351 self->code = args;
352 Py_INCREF(self->code);
353 return 0;
354}
355
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000356static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000357SystemExit_clear(PySystemExitObject *self)
358{
359 Py_CLEAR(self->code);
360 return BaseException_clear((PyBaseExceptionObject *)self);
361}
362
363static void
364SystemExit_dealloc(PySystemExitObject *self)
365{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000366 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367 SystemExit_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000368 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369}
370
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000371static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000372SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
373{
374 Py_VISIT(self->code);
375 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
376}
377
378static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000379 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
380 PyDoc_STR("exception code")},
381 {NULL} /* Sentinel */
382};
383
384ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
385 SystemExit_dealloc, 0, SystemExit_members, 0,
386 "Request to exit from the interpreter.");
387
388/*
389 * KeyboardInterrupt extends BaseException
390 */
391SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
392 "Program interrupted by user.");
393
394
395/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000396 * ImportError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000397 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000398SimpleExtendsException(PyExc_Exception, ImportError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399 "Import can't find module, or can't find name in module.");
400
401
402/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000403 * EnvironmentError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404 */
405
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406/* Where a function has a single filename, such as open() or some
407 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
408 * called, giving a third argument which is the filename. But, so
409 * that old code using in-place unpacking doesn't break, e.g.:
410 *
411 * except IOError, (errno, strerror):
412 *
413 * we hack args so that it only contains two items. This also
414 * means we need our own __str__() which prints out the filename
415 * when it was supplied.
416 */
417static int
418EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
419 PyObject *kwds)
420{
421 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
422 PyObject *subslice = NULL;
423
424 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
425 return -1;
426
Thomas Wouters89f507f2006-12-13 04:49:30 +0000427 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000428 return 0;
429 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000430
431 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432 &myerrno, &strerror, &filename)) {
433 return -1;
434 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000435 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000436 self->myerrno = myerrno;
437 Py_INCREF(self->myerrno);
438
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000439 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440 self->strerror = strerror;
441 Py_INCREF(self->strerror);
442
443 /* self->filename will remain Py_None otherwise */
444 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000445 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446 self->filename = filename;
447 Py_INCREF(self->filename);
448
449 subslice = PyTuple_GetSlice(args, 0, 2);
450 if (!subslice)
451 return -1;
452
453 Py_DECREF(self->args); /* replacing args */
454 self->args = subslice;
455 }
456 return 0;
457}
458
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000459static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460EnvironmentError_clear(PyEnvironmentErrorObject *self)
461{
462 Py_CLEAR(self->myerrno);
463 Py_CLEAR(self->strerror);
464 Py_CLEAR(self->filename);
465 return BaseException_clear((PyBaseExceptionObject *)self);
466}
467
468static void
469EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
470{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000471 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472 EnvironmentError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000473 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474}
475
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000476static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000477EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
478 void *arg)
479{
480 Py_VISIT(self->myerrno);
481 Py_VISIT(self->strerror);
482 Py_VISIT(self->filename);
483 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
484}
485
486static PyObject *
487EnvironmentError_str(PyEnvironmentErrorObject *self)
488{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000489 if (self->filename)
490 return PyUnicode_FromFormat("[Errno %S] %S: %R",
491 self->myerrno ? self->myerrno: Py_None,
492 self->strerror ? self->strerror: Py_None,
493 self->filename);
494 else if (self->myerrno && self->strerror)
495 return PyUnicode_FromFormat("[Errno %S] %S",
496 self->myerrno ? self->myerrno: Py_None,
497 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000499 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500}
501
502static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000503 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
504 PyDoc_STR("exception errno")},
505 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
506 PyDoc_STR("exception strerror")},
507 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
508 PyDoc_STR("exception filename")},
509 {NULL} /* Sentinel */
510};
511
512
513static PyObject *
514EnvironmentError_reduce(PyEnvironmentErrorObject *self)
515{
516 PyObject *args = self->args;
517 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000518
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519 /* self->args is only the first two real arguments if there was a
520 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000521 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522 args = PyTuple_New(3);
523 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524
525 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 Py_INCREF(tmp);
527 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000528
529 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000530 Py_INCREF(tmp);
531 PyTuple_SET_ITEM(args, 1, tmp);
532
533 Py_INCREF(self->filename);
534 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000535 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000536 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000537
538 if (self->dict)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000539 res = PyTuple_Pack(3, Py_Type(self), args, self->dict);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000540 else
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000541 res = PyTuple_Pack(2, Py_Type(self), args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000542 Py_DECREF(args);
543 return res;
544}
545
546
547static PyMethodDef EnvironmentError_methods[] = {
548 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
549 {NULL}
550};
551
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000552ComplexExtendsException(PyExc_Exception, EnvironmentError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000553 EnvironmentError, EnvironmentError_dealloc,
554 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000555 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000556 "Base class for I/O related errors.");
557
558
559/*
560 * IOError extends EnvironmentError
561 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000562MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000563 EnvironmentError, "I/O operation failed.");
564
565
566/*
567 * OSError extends EnvironmentError
568 */
569MiddlingExtendsException(PyExc_EnvironmentError, OSError,
570 EnvironmentError, "OS system call failed.");
571
572
573/*
574 * WindowsError extends OSError
575 */
576#ifdef MS_WINDOWS
577#include "errmap.h"
578
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000579static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000580WindowsError_clear(PyWindowsErrorObject *self)
581{
582 Py_CLEAR(self->myerrno);
583 Py_CLEAR(self->strerror);
584 Py_CLEAR(self->filename);
585 Py_CLEAR(self->winerror);
586 return BaseException_clear((PyBaseExceptionObject *)self);
587}
588
589static void
590WindowsError_dealloc(PyWindowsErrorObject *self)
591{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000592 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000593 WindowsError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000594 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000595}
596
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000597static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
599{
600 Py_VISIT(self->myerrno);
601 Py_VISIT(self->strerror);
602 Py_VISIT(self->filename);
603 Py_VISIT(self->winerror);
604 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
605}
606
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607static int
608WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
609{
610 PyObject *o_errcode = NULL;
611 long errcode;
612 long posix_errno;
613
614 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
615 == -1)
616 return -1;
617
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000618 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000620
621 /* Set errno to the POSIX errno, and winerror to the Win32
622 error code. */
623 errcode = PyInt_AsLong(self->myerrno);
624 if (errcode == -1 && PyErr_Occurred())
625 return -1;
626 posix_errno = winerror_to_errno(errcode);
627
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000628 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000629 self->winerror = self->myerrno;
630
631 o_errcode = PyInt_FromLong(posix_errno);
632 if (!o_errcode)
633 return -1;
634
635 self->myerrno = o_errcode;
636
637 return 0;
638}
639
640
641static PyObject *
642WindowsError_str(PyWindowsErrorObject *self)
643{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000644 if (self->filename)
645 return PyUnicode_FromFormat("[Error %S] %S: %R",
646 self->winerror ? self->winerror: Py_None,
647 self->strerror ? self->strerror: Py_None,
648 self->filename);
649 else if (self->winerror && self->strerror)
650 return PyUnicode_FromFormat("[Error %S] %S",
651 self->winerror ? self->winerror: Py_None,
652 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000654 return EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000655}
656
657static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000658 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
659 PyDoc_STR("POSIX exception code")},
660 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
661 PyDoc_STR("exception strerror")},
662 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
663 PyDoc_STR("exception filename")},
664 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
665 PyDoc_STR("Win32 exception code")},
666 {NULL} /* Sentinel */
667};
668
669ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
670 WindowsError_dealloc, 0, WindowsError_members,
671 WindowsError_str, "MS-Windows OS system call failed.");
672
673#endif /* MS_WINDOWS */
674
675
676/*
677 * VMSError extends OSError (I think)
678 */
679#ifdef __VMS
680MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
681 "OpenVMS OS system call failed.");
682#endif
683
684
685/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000686 * EOFError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000688SimpleExtendsException(PyExc_Exception, EOFError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689 "Read beyond end of file.");
690
691
692/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693 * RuntimeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000695SimpleExtendsException(PyExc_Exception, RuntimeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000696 "Unspecified run-time error.");
697
698
699/*
700 * NotImplementedError extends RuntimeError
701 */
702SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
703 "Method or function hasn't been implemented yet.");
704
705/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000706 * NameError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000708SimpleExtendsException(PyExc_Exception, NameError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709 "Name not found globally.");
710
711/*
712 * UnboundLocalError extends NameError
713 */
714SimpleExtendsException(PyExc_NameError, UnboundLocalError,
715 "Local name referenced but not bound to a value.");
716
717/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000718 * AttributeError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000720SimpleExtendsException(PyExc_Exception, AttributeError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000721 "Attribute not found.");
722
723
724/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000725 * SyntaxError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727
728static int
729SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
730{
731 PyObject *info = NULL;
732 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
733
734 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
735 return -1;
736
737 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000738 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739 self->msg = PyTuple_GET_ITEM(args, 0);
740 Py_INCREF(self->msg);
741 }
742 if (lenargs == 2) {
743 info = PyTuple_GET_ITEM(args, 1);
744 info = PySequence_Tuple(info);
745 if (!info) return -1;
746
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000747 if (PyTuple_GET_SIZE(info) != 4) {
748 /* not a very good error message, but it's what Python 2.4 gives */
749 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
750 Py_DECREF(info);
751 return -1;
752 }
753
754 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755 self->filename = PyTuple_GET_ITEM(info, 0);
756 Py_INCREF(self->filename);
757
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000758 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759 self->lineno = PyTuple_GET_ITEM(info, 1);
760 Py_INCREF(self->lineno);
761
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000762 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763 self->offset = PyTuple_GET_ITEM(info, 2);
764 Py_INCREF(self->offset);
765
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000766 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000767 self->text = PyTuple_GET_ITEM(info, 3);
768 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000769
770 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771 }
772 return 0;
773}
774
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000775static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776SyntaxError_clear(PySyntaxErrorObject *self)
777{
778 Py_CLEAR(self->msg);
779 Py_CLEAR(self->filename);
780 Py_CLEAR(self->lineno);
781 Py_CLEAR(self->offset);
782 Py_CLEAR(self->text);
783 Py_CLEAR(self->print_file_and_line);
784 return BaseException_clear((PyBaseExceptionObject *)self);
785}
786
787static void
788SyntaxError_dealloc(PySyntaxErrorObject *self)
789{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000790 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791 SyntaxError_clear(self);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000792 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793}
794
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000795static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000796SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
797{
798 Py_VISIT(self->msg);
799 Py_VISIT(self->filename);
800 Py_VISIT(self->lineno);
801 Py_VISIT(self->offset);
802 Py_VISIT(self->text);
803 Py_VISIT(self->print_file_and_line);
804 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
805}
806
807/* This is called "my_basename" instead of just "basename" to avoid name
808 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
809 defined, and Python does define that. */
810static char *
811my_basename(char *name)
812{
813 char *cp = name;
814 char *result = name;
815
816 if (name == NULL)
817 return "???";
818 while (*cp != '\0') {
819 if (*cp == SEP)
820 result = cp + 1;
821 ++cp;
822 }
823 return result;
824}
825
826
827static PyObject *
828SyntaxError_str(PySyntaxErrorObject *self)
829{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000830 int have_lineno = 0;
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000831 char *filename = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832
833 /* XXX -- do all the additional formatting with filename and
834 lineno here */
835
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000836 if (self->filename) {
837 if (PyString_Check(self->filename))
838 filename = PyString_AsString(self->filename);
839 else if (PyUnicode_Check(self->filename))
840 filename = PyUnicode_AsString(self->filename);
841 }
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
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000844 if (!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
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000847 if (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,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000850 my_basename(filename),
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000851 PyInt_AsLong(self->lineno));
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000852 else if (filename)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000853 return PyUnicode_FromFormat("%S (%s)",
854 self->msg ? self->msg : Py_None,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000855 my_basename(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);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001243 Py_Type(self)->tp_free((PyObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001244}
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 = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001315 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001316 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317 sizeof(PyUnicodeErrorObject), 0,
1318 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1319 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001321 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1322 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001323 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001324 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001325};
1326PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1327
1328PyObject *
1329PyUnicodeEncodeError_Create(
1330 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1331 Py_ssize_t start, Py_ssize_t end, const char *reason)
1332{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001333 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001334 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337
1338/*
1339 * UnicodeDecodeError extends UnicodeError
1340 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341
1342static int
1343UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1344{
1345 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1346 return -1;
1347 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001348 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001349}
1350
1351static PyObject *
1352UnicodeDecodeError_str(PyObject *self)
1353{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001354 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001355
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001356 if (uself->end==uself->start+1) {
1357 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001358 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001359 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001360 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001361 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001362 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001363 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001364 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001365 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001366 return PyUnicode_FromFormat(
1367 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1368 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001369 uself->start,
1370 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001371 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372 );
1373}
1374
1375static PyTypeObject _PyExc_UnicodeDecodeError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001376 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001377 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378 sizeof(PyUnicodeErrorObject), 0,
1379 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1380 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1381 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001382 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1383 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001385 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386};
1387PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1388
1389PyObject *
1390PyUnicodeDecodeError_Create(
1391 const char *encoding, const char *object, Py_ssize_t length,
1392 Py_ssize_t start, Py_ssize_t end, const char *reason)
1393{
1394 assert(length < INT_MAX);
1395 assert(start < INT_MAX);
1396 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001397 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001398 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399}
1400
1401
1402/*
1403 * UnicodeTranslateError extends UnicodeError
1404 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405
1406static int
1407UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1408 PyObject *kwds)
1409{
1410 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1411 return -1;
1412
1413 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414 Py_CLEAR(self->reason);
1415
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001416 if (!PyArg_ParseTuple(args, "O!nnO!",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417 &PyUnicode_Type, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001418 &self->start,
1419 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001420 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001421 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422 return -1;
1423 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001424
Thomas Wouters477c8d52006-05-27 19:21:47 +00001425 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426 Py_INCREF(self->reason);
1427
1428 return 0;
1429}
1430
1431
1432static PyObject *
1433UnicodeTranslateError_str(PyObject *self)
1434{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001435 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001437 if (uself->end==uself->start+1) {
1438 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001439 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001440 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001441 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001442 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001443 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001444 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001445 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001446 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001447 fmt,
1448 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001449 uself->start,
1450 uself->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001451 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001452 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001453 return PyUnicode_FromFormat(
1454 "can't translate characters in position %zd-%zd: %U",
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001455 uself->start,
1456 uself->end-1,
1457 uself->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458 );
1459}
1460
1461static PyTypeObject _PyExc_UnicodeTranslateError = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001462 PyVarObject_HEAD_INIT(NULL, 0)
Neal Norwitz2633c692007-02-26 22:22:47 +00001463 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001464 sizeof(PyUnicodeErrorObject), 0,
1465 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1466 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1467 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001468 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1470 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001471 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001472};
1473PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1474
1475PyObject *
1476PyUnicodeTranslateError_Create(
1477 const Py_UNICODE *object, Py_ssize_t length,
1478 Py_ssize_t start, Py_ssize_t end, const char *reason)
1479{
1480 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001481 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001483
1484
1485/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001486 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001488SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001489 "Assertion failed.");
1490
1491
1492/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001493 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001495SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496 "Base class for arithmetic errors.");
1497
1498
1499/*
1500 * FloatingPointError extends ArithmeticError
1501 */
1502SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1503 "Floating point operation failed.");
1504
1505
1506/*
1507 * OverflowError extends ArithmeticError
1508 */
1509SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1510 "Result too large to be represented.");
1511
1512
1513/*
1514 * ZeroDivisionError extends ArithmeticError
1515 */
1516SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1517 "Second argument to a division or modulo operation was zero.");
1518
1519
1520/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001521 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001522 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001523SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001524 "Internal error in the Python interpreter.\n"
1525 "\n"
1526 "Please report this to the Python maintainer, along with the traceback,\n"
1527 "the Python version, and the hardware/OS platform and version.");
1528
1529
1530/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001531 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001532 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001533SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001534 "Weak ref proxy used after referent went away.");
1535
1536
1537/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001538 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001540SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001541
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001542/*
1543 * BufferError extends Exception
1544 */
1545SimpleExtendsException(PyExc_Exception, BufferError, "Buffer error.");
1546
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547
1548/* Warning category docstrings */
1549
1550/*
1551 * Warning extends Exception
1552 */
1553SimpleExtendsException(PyExc_Exception, Warning,
1554 "Base class for warning categories.");
1555
1556
1557/*
1558 * UserWarning extends Warning
1559 */
1560SimpleExtendsException(PyExc_Warning, UserWarning,
1561 "Base class for warnings generated by user code.");
1562
1563
1564/*
1565 * DeprecationWarning extends Warning
1566 */
1567SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1568 "Base class for warnings about deprecated features.");
1569
1570
1571/*
1572 * PendingDeprecationWarning extends Warning
1573 */
1574SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1575 "Base class for warnings about features which will be deprecated\n"
1576 "in the future.");
1577
1578
1579/*
1580 * SyntaxWarning extends Warning
1581 */
1582SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1583 "Base class for warnings about dubious syntax.");
1584
1585
1586/*
1587 * RuntimeWarning extends Warning
1588 */
1589SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1590 "Base class for warnings about dubious runtime behavior.");
1591
1592
1593/*
1594 * FutureWarning extends Warning
1595 */
1596SimpleExtendsException(PyExc_Warning, FutureWarning,
1597 "Base class for warnings about constructs that will change semantically\n"
1598 "in the future.");
1599
1600
1601/*
1602 * ImportWarning extends Warning
1603 */
1604SimpleExtendsException(PyExc_Warning, ImportWarning,
1605 "Base class for warnings about probable mistakes in module imports");
1606
1607
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001608/*
1609 * UnicodeWarning extends Warning
1610 */
1611SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1612 "Base class for warnings about Unicode related problems, mostly\n"
1613 "related to conversion problems.");
1614
1615
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616/* Pre-computed MemoryError instance. Best to create this as early as
1617 * possible and not wait until a MemoryError is actually raised!
1618 */
1619PyObject *PyExc_MemoryErrorInst=NULL;
1620
Thomas Wouters477c8d52006-05-27 19:21:47 +00001621#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1622 Py_FatalError("exceptions bootstrapping error.");
1623
1624#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001625 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1626 Py_FatalError("Module dictionary insertion problem.");
1627
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001628#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1629/* crt variable checking in VisualStudio .NET 2005 */
1630#include <crtdbg.h>
1631
1632static int prevCrtReportMode;
1633static _invalid_parameter_handler prevCrtHandler;
1634
1635/* Invalid parameter handler. Sets a ValueError exception */
1636static void
1637InvalidParameterHandler(
1638 const wchar_t * expression,
1639 const wchar_t * function,
1640 const wchar_t * file,
1641 unsigned int line,
1642 uintptr_t pReserved)
1643{
1644 /* Do nothing, allow execution to continue. Usually this
1645 * means that the CRT will set errno to EINVAL
1646 */
1647}
1648#endif
1649
1650
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001652_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653{
Neal Norwitz2633c692007-02-26 22:22:47 +00001654 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655
1656 PRE_INIT(BaseException)
1657 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658 PRE_INIT(TypeError)
1659 PRE_INIT(StopIteration)
1660 PRE_INIT(GeneratorExit)
1661 PRE_INIT(SystemExit)
1662 PRE_INIT(KeyboardInterrupt)
1663 PRE_INIT(ImportError)
1664 PRE_INIT(EnvironmentError)
1665 PRE_INIT(IOError)
1666 PRE_INIT(OSError)
1667#ifdef MS_WINDOWS
1668 PRE_INIT(WindowsError)
1669#endif
1670#ifdef __VMS
1671 PRE_INIT(VMSError)
1672#endif
1673 PRE_INIT(EOFError)
1674 PRE_INIT(RuntimeError)
1675 PRE_INIT(NotImplementedError)
1676 PRE_INIT(NameError)
1677 PRE_INIT(UnboundLocalError)
1678 PRE_INIT(AttributeError)
1679 PRE_INIT(SyntaxError)
1680 PRE_INIT(IndentationError)
1681 PRE_INIT(TabError)
1682 PRE_INIT(LookupError)
1683 PRE_INIT(IndexError)
1684 PRE_INIT(KeyError)
1685 PRE_INIT(ValueError)
1686 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001687 PRE_INIT(UnicodeEncodeError)
1688 PRE_INIT(UnicodeDecodeError)
1689 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001690 PRE_INIT(AssertionError)
1691 PRE_INIT(ArithmeticError)
1692 PRE_INIT(FloatingPointError)
1693 PRE_INIT(OverflowError)
1694 PRE_INIT(ZeroDivisionError)
1695 PRE_INIT(SystemError)
1696 PRE_INIT(ReferenceError)
1697 PRE_INIT(MemoryError)
1698 PRE_INIT(Warning)
1699 PRE_INIT(UserWarning)
1700 PRE_INIT(DeprecationWarning)
1701 PRE_INIT(PendingDeprecationWarning)
1702 PRE_INIT(SyntaxWarning)
1703 PRE_INIT(RuntimeWarning)
1704 PRE_INIT(FutureWarning)
1705 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001706 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707
Thomas Wouters477c8d52006-05-27 19:21:47 +00001708 bltinmod = PyImport_ImportModule("__builtin__");
1709 if (bltinmod == NULL)
1710 Py_FatalError("exceptions bootstrapping error.");
1711 bdict = PyModule_GetDict(bltinmod);
1712 if (bdict == NULL)
1713 Py_FatalError("exceptions bootstrapping error.");
1714
1715 POST_INIT(BaseException)
1716 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717 POST_INIT(TypeError)
1718 POST_INIT(StopIteration)
1719 POST_INIT(GeneratorExit)
1720 POST_INIT(SystemExit)
1721 POST_INIT(KeyboardInterrupt)
1722 POST_INIT(ImportError)
1723 POST_INIT(EnvironmentError)
1724 POST_INIT(IOError)
1725 POST_INIT(OSError)
1726#ifdef MS_WINDOWS
1727 POST_INIT(WindowsError)
1728#endif
1729#ifdef __VMS
1730 POST_INIT(VMSError)
1731#endif
1732 POST_INIT(EOFError)
1733 POST_INIT(RuntimeError)
1734 POST_INIT(NotImplementedError)
1735 POST_INIT(NameError)
1736 POST_INIT(UnboundLocalError)
1737 POST_INIT(AttributeError)
1738 POST_INIT(SyntaxError)
1739 POST_INIT(IndentationError)
1740 POST_INIT(TabError)
1741 POST_INIT(LookupError)
1742 POST_INIT(IndexError)
1743 POST_INIT(KeyError)
1744 POST_INIT(ValueError)
1745 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746 POST_INIT(UnicodeEncodeError)
1747 POST_INIT(UnicodeDecodeError)
1748 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001749 POST_INIT(AssertionError)
1750 POST_INIT(ArithmeticError)
1751 POST_INIT(FloatingPointError)
1752 POST_INIT(OverflowError)
1753 POST_INIT(ZeroDivisionError)
1754 POST_INIT(SystemError)
1755 POST_INIT(ReferenceError)
1756 POST_INIT(MemoryError)
1757 POST_INIT(Warning)
1758 POST_INIT(UserWarning)
1759 POST_INIT(DeprecationWarning)
1760 POST_INIT(PendingDeprecationWarning)
1761 POST_INIT(SyntaxWarning)
1762 POST_INIT(RuntimeWarning)
1763 POST_INIT(FutureWarning)
1764 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001765 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766
1767 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1768 if (!PyExc_MemoryErrorInst)
1769 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1770
1771 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001772
1773#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1774 /* Set CRT argument error handler */
1775 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1776 /* turn off assertions in debug mode */
1777 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1778#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779}
1780
1781void
1782_PyExc_Fini(void)
1783{
1784 Py_XDECREF(PyExc_MemoryErrorInst);
1785 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001786#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1787 /* reset CRT error handling */
1788 _set_invalid_parameter_handler(prevCrtHandler);
1789 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1790#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001791}