blob: c9335ad8380d506fdba042a90084a6990147a205 [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 int
951get_int(PyObject *attr, Py_ssize_t *value, const char *name)
952{
953 if (!attr) {
954 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
955 return -1;
956 }
957
Guido van Rossumddefaf32007-01-14 03:31:43 +0000958 if (PyLong_Check(attr)) {
959 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000960 if (*value == -1 && PyErr_Occurred())
961 return -1;
962 } else {
963 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
964 return -1;
965 }
966 return 0;
967}
968
969static int
970set_ssize_t(PyObject **attr, Py_ssize_t value)
971{
972 PyObject *obj = PyInt_FromSsize_t(value);
973 if (!obj)
974 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000975 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000976 *attr = obj;
977 return 0;
978}
979
980static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +0000981get_bytes(PyObject *attr, const char *name)
982{
983 if (!attr) {
984 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
985 return NULL;
986 }
987
988 if (!PyBytes_Check(attr)) {
989 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
990 return NULL;
991 }
992 Py_INCREF(attr);
993 return attr;
994}
995
996static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997get_unicode(PyObject *attr, const char *name)
998{
999 if (!attr) {
1000 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1001 return NULL;
1002 }
1003
1004 if (!PyUnicode_Check(attr)) {
1005 PyErr_Format(PyExc_TypeError,
1006 "%.200s attribute must be unicode", name);
1007 return NULL;
1008 }
1009 Py_INCREF(attr);
1010 return attr;
1011}
1012
Walter Dörwaldd2034312007-05-18 16:29:38 +00001013static int
1014set_unicodefromstring(PyObject **attr, const char *value)
1015{
1016 PyObject *obj = PyUnicode_FromString(value);
1017 if (!obj)
1018 return -1;
1019 Py_CLEAR(*attr);
1020 *attr = obj;
1021 return 0;
1022}
1023
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024PyObject *
1025PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1026{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001027 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001028}
1029
1030PyObject *
1031PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1032{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001033 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034}
1035
1036PyObject *
1037PyUnicodeEncodeError_GetObject(PyObject *exc)
1038{
1039 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1040}
1041
1042PyObject *
1043PyUnicodeDecodeError_GetObject(PyObject *exc)
1044{
Walter Dörwald612344f2007-05-04 19:28:21 +00001045 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001046}
1047
1048PyObject *
1049PyUnicodeTranslateError_GetObject(PyObject *exc)
1050{
1051 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1052}
1053
1054int
1055PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1056{
1057 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1058 Py_ssize_t size;
1059 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1060 "object");
1061 if (!obj) return -1;
1062 size = PyUnicode_GET_SIZE(obj);
1063 if (*start<0)
1064 *start = 0; /*XXX check for values <0*/
1065 if (*start>=size)
1066 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001067 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068 return 0;
1069 }
1070 return -1;
1071}
1072
1073
1074int
1075PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1076{
1077 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1078 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001079 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001080 "object");
1081 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001082 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001083 if (*start<0)
1084 *start = 0;
1085 if (*start>=size)
1086 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001087 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001088 return 0;
1089 }
1090 return -1;
1091}
1092
1093
1094int
1095PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1096{
1097 return PyUnicodeEncodeError_GetStart(exc, start);
1098}
1099
1100
1101int
1102PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1103{
1104 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1105}
1106
1107
1108int
1109PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1110{
1111 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1112}
1113
1114
1115int
1116PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1117{
1118 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1119}
1120
1121
1122int
1123PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1124{
1125 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1126 Py_ssize_t size;
1127 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1128 "object");
1129 if (!obj) return -1;
1130 size = PyUnicode_GET_SIZE(obj);
1131 if (*end<1)
1132 *end = 1;
1133 if (*end>size)
1134 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001135 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001136 return 0;
1137 }
1138 return -1;
1139}
1140
1141
1142int
1143PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1144{
1145 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1146 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001147 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001148 "object");
1149 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001150 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001151 if (*end<1)
1152 *end = 1;
1153 if (*end>size)
1154 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001155 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156 return 0;
1157 }
1158 return -1;
1159}
1160
1161
1162int
1163PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1164{
1165 return PyUnicodeEncodeError_GetEnd(exc, start);
1166}
1167
1168
1169int
1170PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1171{
1172 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1173}
1174
1175
1176int
1177PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1178{
1179 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1180}
1181
1182
1183int
1184PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1185{
1186 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1187}
1188
1189PyObject *
1190PyUnicodeEncodeError_GetReason(PyObject *exc)
1191{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001192 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193}
1194
1195
1196PyObject *
1197PyUnicodeDecodeError_GetReason(PyObject *exc)
1198{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001199 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001200}
1201
1202
1203PyObject *
1204PyUnicodeTranslateError_GetReason(PyObject *exc)
1205{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001206 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001207}
1208
1209
1210int
1211PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1212{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001213 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1214 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001215}
1216
1217
1218int
1219PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1220{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001221 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1222 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001223}
1224
1225
1226int
1227PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1228{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001229 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1230 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001231}
1232
1233
Thomas Wouters477c8d52006-05-27 19:21:47 +00001234static int
1235UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1236 PyTypeObject *objecttype)
1237{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001238 Py_CLEAR(self->encoding);
1239 Py_CLEAR(self->object);
1240 Py_CLEAR(self->start);
1241 Py_CLEAR(self->end);
1242 Py_CLEAR(self->reason);
1243
Thomas Wouters477c8d52006-05-27 19:21:47 +00001244 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001245 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001246 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001247 &PyLong_Type, &self->start,
1248 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001249 &PyUnicode_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001250 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001251 self->reason = NULL;
1252 return -1;
1253 }
1254
1255 Py_INCREF(self->encoding);
1256 Py_INCREF(self->object);
1257 Py_INCREF(self->start);
1258 Py_INCREF(self->end);
1259 Py_INCREF(self->reason);
1260
1261 return 0;
1262}
1263
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001264static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001265UnicodeError_clear(PyUnicodeErrorObject *self)
1266{
1267 Py_CLEAR(self->encoding);
1268 Py_CLEAR(self->object);
1269 Py_CLEAR(self->start);
1270 Py_CLEAR(self->end);
1271 Py_CLEAR(self->reason);
1272 return BaseException_clear((PyBaseExceptionObject *)self);
1273}
1274
1275static void
1276UnicodeError_dealloc(PyUnicodeErrorObject *self)
1277{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001278 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001279 UnicodeError_clear(self);
1280 self->ob_type->tp_free((PyObject *)self);
1281}
1282
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001283static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001284UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1285{
1286 Py_VISIT(self->encoding);
1287 Py_VISIT(self->object);
1288 Py_VISIT(self->start);
1289 Py_VISIT(self->end);
1290 Py_VISIT(self->reason);
1291 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1292}
1293
1294static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001295 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1296 PyDoc_STR("exception encoding")},
1297 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1298 PyDoc_STR("exception object")},
1299 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1300 PyDoc_STR("exception start")},
1301 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1302 PyDoc_STR("exception end")},
1303 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1304 PyDoc_STR("exception reason")},
1305 {NULL} /* Sentinel */
1306};
1307
1308
1309/*
1310 * UnicodeEncodeError extends UnicodeError
1311 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001312
1313static int
1314UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1315{
1316 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1317 return -1;
1318 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1319 kwds, &PyUnicode_Type);
1320}
1321
1322static PyObject *
1323UnicodeEncodeError_str(PyObject *self)
1324{
1325 Py_ssize_t start;
1326 Py_ssize_t end;
1327
1328 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001329 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001330
1331 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001332 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001333
1334 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001335 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001336 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001337 if (badchar <= 0xff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001338 fmt = "'%U' codec can't encode character u'\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001339 else if (badchar <= 0xffff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001340 fmt = "'%U' codec can't encode character u'\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001341 else
Walter Dörwald787b03b2007-06-05 13:29:29 +00001342 fmt = "'%U' codec can't encode character u'\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001343 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001344 fmt,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001345 ((PyUnicodeErrorObject *)self)->encoding,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001346 badchar,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001348 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001349 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001351 return PyUnicode_FromFormat(
1352 "'%U' codec can't encode characters in position %zd-%zd: %U",
1353 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354 start,
1355 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001356 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357 );
1358}
1359
1360static PyTypeObject _PyExc_UnicodeEncodeError = {
1361 PyObject_HEAD_INIT(NULL)
1362 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001363 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001364 sizeof(PyUnicodeErrorObject), 0,
1365 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1366 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1367 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001368 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1369 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001371 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372};
1373PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1374
1375PyObject *
1376PyUnicodeEncodeError_Create(
1377 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1378 Py_ssize_t start, Py_ssize_t end, const char *reason)
1379{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001380 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001381 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001382}
1383
1384
1385/*
1386 * UnicodeDecodeError extends UnicodeError
1387 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001388
1389static int
1390UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1391{
1392 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1393 return -1;
1394 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001395 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001396}
1397
1398static PyObject *
1399UnicodeDecodeError_str(PyObject *self)
1400{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001401 Py_ssize_t start = 0;
1402 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403
1404 if (PyUnicodeDecodeError_GetStart(self, &start))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001405 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001406
1407 if (PyUnicodeDecodeError_GetEnd(self, &end))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001408 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
1410 if (end==start+1) {
Walter Dörwald787b03b2007-06-05 13:29:29 +00001411 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001412 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001413 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001414 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001415 byte,
1416 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001417 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001418 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001420 return PyUnicode_FromFormat(
1421 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1422 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423 start,
1424 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001425 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426 );
1427}
1428
1429static PyTypeObject _PyExc_UnicodeDecodeError = {
1430 PyObject_HEAD_INIT(NULL)
1431 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001432 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001433 sizeof(PyUnicodeErrorObject), 0,
1434 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1435 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1436 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001437 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1438 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001439 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001440 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001441};
1442PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1443
1444PyObject *
1445PyUnicodeDecodeError_Create(
1446 const char *encoding, const char *object, Py_ssize_t length,
1447 Py_ssize_t start, Py_ssize_t end, const char *reason)
1448{
1449 assert(length < INT_MAX);
1450 assert(start < INT_MAX);
1451 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001452 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001453 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001454}
1455
1456
1457/*
1458 * UnicodeTranslateError extends UnicodeError
1459 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460
1461static int
1462UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1463 PyObject *kwds)
1464{
1465 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1466 return -1;
1467
1468 Py_CLEAR(self->object);
1469 Py_CLEAR(self->start);
1470 Py_CLEAR(self->end);
1471 Py_CLEAR(self->reason);
1472
1473 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1474 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001475 &PyLong_Type, &self->start,
1476 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001477 &PyUnicode_Type, &self->reason)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001478 self->object = self->start = self->end = self->reason = NULL;
1479 return -1;
1480 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001481
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482 Py_INCREF(self->object);
1483 Py_INCREF(self->start);
1484 Py_INCREF(self->end);
1485 Py_INCREF(self->reason);
1486
1487 return 0;
1488}
1489
1490
1491static PyObject *
1492UnicodeTranslateError_str(PyObject *self)
1493{
1494 Py_ssize_t start;
1495 Py_ssize_t end;
1496
1497 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001498 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499
1500 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001501 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001502
1503 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001504 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001505 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001506 if (badchar <= 0xff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001507 fmt = "can't translate character u'\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001508 else if (badchar <= 0xffff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001509 fmt = "can't translate character u'\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001510 else
Walter Dörwald787b03b2007-06-05 13:29:29 +00001511 fmt = "can't translate character u'\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001512 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001513 fmt,
1514 badchar,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001515 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001516 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001517 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001518 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001519 return PyUnicode_FromFormat(
1520 "can't translate characters in position %zd-%zd: %U",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 start,
1522 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001523 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001524 );
1525}
1526
1527static PyTypeObject _PyExc_UnicodeTranslateError = {
1528 PyObject_HEAD_INIT(NULL)
1529 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001530 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531 sizeof(PyUnicodeErrorObject), 0,
1532 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1533 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1534 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001535 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1537 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001538 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539};
1540PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1541
1542PyObject *
1543PyUnicodeTranslateError_Create(
1544 const Py_UNICODE *object, Py_ssize_t length,
1545 Py_ssize_t start, Py_ssize_t end, const char *reason)
1546{
1547 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001548 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550
1551
1552/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001553 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001555SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556 "Assertion failed.");
1557
1558
1559/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001560 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001561 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001562SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001563 "Base class for arithmetic errors.");
1564
1565
1566/*
1567 * FloatingPointError extends ArithmeticError
1568 */
1569SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1570 "Floating point operation failed.");
1571
1572
1573/*
1574 * OverflowError extends ArithmeticError
1575 */
1576SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1577 "Result too large to be represented.");
1578
1579
1580/*
1581 * ZeroDivisionError extends ArithmeticError
1582 */
1583SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1584 "Second argument to a division or modulo operation was zero.");
1585
1586
1587/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001588 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001589 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001590SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001591 "Internal error in the Python interpreter.\n"
1592 "\n"
1593 "Please report this to the Python maintainer, along with the traceback,\n"
1594 "the Python version, and the hardware/OS platform and version.");
1595
1596
1597/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001598 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001600SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601 "Weak ref proxy used after referent went away.");
1602
1603
1604/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001605 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001607SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001608
1609
1610/* Warning category docstrings */
1611
1612/*
1613 * Warning extends Exception
1614 */
1615SimpleExtendsException(PyExc_Exception, Warning,
1616 "Base class for warning categories.");
1617
1618
1619/*
1620 * UserWarning extends Warning
1621 */
1622SimpleExtendsException(PyExc_Warning, UserWarning,
1623 "Base class for warnings generated by user code.");
1624
1625
1626/*
1627 * DeprecationWarning extends Warning
1628 */
1629SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1630 "Base class for warnings about deprecated features.");
1631
1632
1633/*
1634 * PendingDeprecationWarning extends Warning
1635 */
1636SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1637 "Base class for warnings about features which will be deprecated\n"
1638 "in the future.");
1639
1640
1641/*
1642 * SyntaxWarning extends Warning
1643 */
1644SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1645 "Base class for warnings about dubious syntax.");
1646
1647
1648/*
1649 * RuntimeWarning extends Warning
1650 */
1651SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1652 "Base class for warnings about dubious runtime behavior.");
1653
1654
1655/*
1656 * FutureWarning extends Warning
1657 */
1658SimpleExtendsException(PyExc_Warning, FutureWarning,
1659 "Base class for warnings about constructs that will change semantically\n"
1660 "in the future.");
1661
1662
1663/*
1664 * ImportWarning extends Warning
1665 */
1666SimpleExtendsException(PyExc_Warning, ImportWarning,
1667 "Base class for warnings about probable mistakes in module imports");
1668
1669
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001670/*
1671 * UnicodeWarning extends Warning
1672 */
1673SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1674 "Base class for warnings about Unicode related problems, mostly\n"
1675 "related to conversion problems.");
1676
1677
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678/* Pre-computed MemoryError instance. Best to create this as early as
1679 * possible and not wait until a MemoryError is actually raised!
1680 */
1681PyObject *PyExc_MemoryErrorInst=NULL;
1682
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1684 Py_FatalError("exceptions bootstrapping error.");
1685
1686#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001687 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1688 Py_FatalError("Module dictionary insertion problem.");
1689
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001690#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1691/* crt variable checking in VisualStudio .NET 2005 */
1692#include <crtdbg.h>
1693
1694static int prevCrtReportMode;
1695static _invalid_parameter_handler prevCrtHandler;
1696
1697/* Invalid parameter handler. Sets a ValueError exception */
1698static void
1699InvalidParameterHandler(
1700 const wchar_t * expression,
1701 const wchar_t * function,
1702 const wchar_t * file,
1703 unsigned int line,
1704 uintptr_t pReserved)
1705{
1706 /* Do nothing, allow execution to continue. Usually this
1707 * means that the CRT will set errno to EINVAL
1708 */
1709}
1710#endif
1711
1712
Thomas Wouters477c8d52006-05-27 19:21:47 +00001713PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001714_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715{
Neal Norwitz2633c692007-02-26 22:22:47 +00001716 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717
1718 PRE_INIT(BaseException)
1719 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720 PRE_INIT(TypeError)
1721 PRE_INIT(StopIteration)
1722 PRE_INIT(GeneratorExit)
1723 PRE_INIT(SystemExit)
1724 PRE_INIT(KeyboardInterrupt)
1725 PRE_INIT(ImportError)
1726 PRE_INIT(EnvironmentError)
1727 PRE_INIT(IOError)
1728 PRE_INIT(OSError)
1729#ifdef MS_WINDOWS
1730 PRE_INIT(WindowsError)
1731#endif
1732#ifdef __VMS
1733 PRE_INIT(VMSError)
1734#endif
1735 PRE_INIT(EOFError)
1736 PRE_INIT(RuntimeError)
1737 PRE_INIT(NotImplementedError)
1738 PRE_INIT(NameError)
1739 PRE_INIT(UnboundLocalError)
1740 PRE_INIT(AttributeError)
1741 PRE_INIT(SyntaxError)
1742 PRE_INIT(IndentationError)
1743 PRE_INIT(TabError)
1744 PRE_INIT(LookupError)
1745 PRE_INIT(IndexError)
1746 PRE_INIT(KeyError)
1747 PRE_INIT(ValueError)
1748 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001749 PRE_INIT(UnicodeEncodeError)
1750 PRE_INIT(UnicodeDecodeError)
1751 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001752 PRE_INIT(AssertionError)
1753 PRE_INIT(ArithmeticError)
1754 PRE_INIT(FloatingPointError)
1755 PRE_INIT(OverflowError)
1756 PRE_INIT(ZeroDivisionError)
1757 PRE_INIT(SystemError)
1758 PRE_INIT(ReferenceError)
1759 PRE_INIT(MemoryError)
1760 PRE_INIT(Warning)
1761 PRE_INIT(UserWarning)
1762 PRE_INIT(DeprecationWarning)
1763 PRE_INIT(PendingDeprecationWarning)
1764 PRE_INIT(SyntaxWarning)
1765 PRE_INIT(RuntimeWarning)
1766 PRE_INIT(FutureWarning)
1767 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001768 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769
Thomas Wouters477c8d52006-05-27 19:21:47 +00001770 bltinmod = PyImport_ImportModule("__builtin__");
1771 if (bltinmod == NULL)
1772 Py_FatalError("exceptions bootstrapping error.");
1773 bdict = PyModule_GetDict(bltinmod);
1774 if (bdict == NULL)
1775 Py_FatalError("exceptions bootstrapping error.");
1776
1777 POST_INIT(BaseException)
1778 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779 POST_INIT(TypeError)
1780 POST_INIT(StopIteration)
1781 POST_INIT(GeneratorExit)
1782 POST_INIT(SystemExit)
1783 POST_INIT(KeyboardInterrupt)
1784 POST_INIT(ImportError)
1785 POST_INIT(EnvironmentError)
1786 POST_INIT(IOError)
1787 POST_INIT(OSError)
1788#ifdef MS_WINDOWS
1789 POST_INIT(WindowsError)
1790#endif
1791#ifdef __VMS
1792 POST_INIT(VMSError)
1793#endif
1794 POST_INIT(EOFError)
1795 POST_INIT(RuntimeError)
1796 POST_INIT(NotImplementedError)
1797 POST_INIT(NameError)
1798 POST_INIT(UnboundLocalError)
1799 POST_INIT(AttributeError)
1800 POST_INIT(SyntaxError)
1801 POST_INIT(IndentationError)
1802 POST_INIT(TabError)
1803 POST_INIT(LookupError)
1804 POST_INIT(IndexError)
1805 POST_INIT(KeyError)
1806 POST_INIT(ValueError)
1807 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001808 POST_INIT(UnicodeEncodeError)
1809 POST_INIT(UnicodeDecodeError)
1810 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811 POST_INIT(AssertionError)
1812 POST_INIT(ArithmeticError)
1813 POST_INIT(FloatingPointError)
1814 POST_INIT(OverflowError)
1815 POST_INIT(ZeroDivisionError)
1816 POST_INIT(SystemError)
1817 POST_INIT(ReferenceError)
1818 POST_INIT(MemoryError)
1819 POST_INIT(Warning)
1820 POST_INIT(UserWarning)
1821 POST_INIT(DeprecationWarning)
1822 POST_INIT(PendingDeprecationWarning)
1823 POST_INIT(SyntaxWarning)
1824 POST_INIT(RuntimeWarning)
1825 POST_INIT(FutureWarning)
1826 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001827 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001828
1829 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1830 if (!PyExc_MemoryErrorInst)
1831 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1832
1833 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001834
1835#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1836 /* Set CRT argument error handler */
1837 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1838 /* turn off assertions in debug mode */
1839 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1840#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001841}
1842
1843void
1844_PyExc_Fini(void)
1845{
1846 Py_XDECREF(PyExc_MemoryErrorInst);
1847 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001848#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1849 /* reset CRT error handling */
1850 _set_invalid_parameter_handler(prevCrtHandler);
1851 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1852#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001853}