blob: a4018068ab59a43724e62a92ee740841eb00a5c9 [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_lineno = 0;
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000835 char *filename = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000836
837 /* XXX -- do all the additional formatting with filename and
838 lineno here */
839
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000840 if (self->filename) {
841 if (PyString_Check(self->filename))
842 filename = PyString_AsString(self->filename);
843 else if (PyUnicode_Check(self->filename))
844 filename = PyUnicode_AsString(self->filename);
845 }
Guido van Rossumddefaf32007-01-14 03:31:43 +0000846 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000847
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000848 if (!filename && !have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000849 return PyObject_Unicode(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000851 if (filename && have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000852 return PyUnicode_FromFormat("%S (%s, line %ld)",
853 self->msg ? self->msg : Py_None,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000854 my_basename(filename),
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000855 PyInt_AsLong(self->lineno));
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000856 else if (filename)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000857 return PyUnicode_FromFormat("%S (%s)",
858 self->msg ? self->msg : Py_None,
Martin v. Löwis10a60b32007-07-18 02:28:27 +0000859 my_basename(filename));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000860 else /* only have_lineno */
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000861 return PyUnicode_FromFormat("%S (line %ld)",
862 self->msg ? self->msg : Py_None,
863 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000864}
865
866static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000867 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
868 PyDoc_STR("exception msg")},
869 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
870 PyDoc_STR("exception filename")},
871 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
872 PyDoc_STR("exception lineno")},
873 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
874 PyDoc_STR("exception offset")},
875 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
876 PyDoc_STR("exception text")},
877 {"print_file_and_line", T_OBJECT,
878 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
879 PyDoc_STR("exception print_file_and_line")},
880 {NULL} /* Sentinel */
881};
882
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000883ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884 SyntaxError_dealloc, 0, SyntaxError_members,
885 SyntaxError_str, "Invalid syntax.");
886
887
888/*
889 * IndentationError extends SyntaxError
890 */
891MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
892 "Improper indentation.");
893
894
895/*
896 * TabError extends IndentationError
897 */
898MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
899 "Improper mixture of spaces and tabs.");
900
901
902/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000903 * LookupError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000904 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000905SimpleExtendsException(PyExc_Exception, LookupError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000906 "Base class for lookup errors.");
907
908
909/*
910 * IndexError extends LookupError
911 */
912SimpleExtendsException(PyExc_LookupError, IndexError,
913 "Sequence index out of range.");
914
915
916/*
917 * KeyError extends LookupError
918 */
919static PyObject *
920KeyError_str(PyBaseExceptionObject *self)
921{
922 /* If args is a tuple of exactly one item, apply repr to args[0].
923 This is done so that e.g. the exception raised by {}[''] prints
924 KeyError: ''
925 rather than the confusing
926 KeyError
927 alone. The downside is that if KeyError is raised with an explanatory
928 string, that string will be displayed in quotes. Too bad.
929 If args is anything else, use the default BaseException__str__().
930 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000931 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000932 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000933 }
934 return BaseException_str(self);
935}
936
937ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
938 0, 0, 0, KeyError_str, "Mapping key not found.");
939
940
941/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000942 * ValueError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000944SimpleExtendsException(PyExc_Exception, ValueError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000945 "Inappropriate argument value (of correct type).");
946
947/*
948 * UnicodeError extends ValueError
949 */
950
951SimpleExtendsException(PyExc_ValueError, UnicodeError,
952 "Unicode related error.");
953
Thomas Wouters477c8d52006-05-27 19:21:47 +0000954static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +0000955get_bytes(PyObject *attr, const char *name)
956{
957 if (!attr) {
958 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
959 return NULL;
960 }
961
962 if (!PyBytes_Check(attr)) {
963 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
964 return NULL;
965 }
966 Py_INCREF(attr);
967 return attr;
968}
969
970static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000971get_unicode(PyObject *attr, const char *name)
972{
973 if (!attr) {
974 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
975 return NULL;
976 }
977
978 if (!PyUnicode_Check(attr)) {
979 PyErr_Format(PyExc_TypeError,
980 "%.200s attribute must be unicode", name);
981 return NULL;
982 }
983 Py_INCREF(attr);
984 return attr;
985}
986
Walter Dörwaldd2034312007-05-18 16:29:38 +0000987static int
988set_unicodefromstring(PyObject **attr, const char *value)
989{
990 PyObject *obj = PyUnicode_FromString(value);
991 if (!obj)
992 return -1;
993 Py_CLEAR(*attr);
994 *attr = obj;
995 return 0;
996}
997
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998PyObject *
999PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1000{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001001 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002}
1003
1004PyObject *
1005PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1006{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001007 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008}
1009
1010PyObject *
1011PyUnicodeEncodeError_GetObject(PyObject *exc)
1012{
1013 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1014}
1015
1016PyObject *
1017PyUnicodeDecodeError_GetObject(PyObject *exc)
1018{
Walter Dörwald612344f2007-05-04 19:28:21 +00001019 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001020}
1021
1022PyObject *
1023PyUnicodeTranslateError_GetObject(PyObject *exc)
1024{
1025 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1026}
1027
1028int
1029PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1030{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001031 Py_ssize_t size;
1032 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1033 "object");
1034 if (!obj)
1035 return -1;
1036 *start = ((PyUnicodeErrorObject *)exc)->start;
1037 size = PyUnicode_GET_SIZE(obj);
1038 if (*start<0)
1039 *start = 0; /*XXX check for values <0*/
1040 if (*start>=size)
1041 *start = size-1;
1042 Py_DECREF(obj);
1043 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001044}
1045
1046
1047int
1048PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1049{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001050 Py_ssize_t size;
1051 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1052 if (!obj)
1053 return -1;
1054 size = PyBytes_GET_SIZE(obj);
1055 *start = ((PyUnicodeErrorObject *)exc)->start;
1056 if (*start<0)
1057 *start = 0;
1058 if (*start>=size)
1059 *start = size-1;
1060 Py_DECREF(obj);
1061 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001062}
1063
1064
1065int
1066PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1067{
1068 return PyUnicodeEncodeError_GetStart(exc, start);
1069}
1070
1071
1072int
1073PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1074{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001075 ((PyUnicodeErrorObject *)exc)->start = start;
1076 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001077}
1078
1079
1080int
1081PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1082{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001083 ((PyUnicodeErrorObject *)exc)->start = start;
1084 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001085}
1086
1087
1088int
1089PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1090{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001091 ((PyUnicodeErrorObject *)exc)->start = start;
1092 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001093}
1094
1095
1096int
1097PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1098{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001099 Py_ssize_t size;
1100 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1101 "object");
1102 if (!obj)
1103 return -1;
1104 *end = ((PyUnicodeErrorObject *)exc)->end;
1105 size = PyUnicode_GET_SIZE(obj);
1106 if (*end<1)
1107 *end = 1;
1108 if (*end>size)
1109 *end = size;
1110 Py_DECREF(obj);
1111 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001112}
1113
1114
1115int
1116PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1117{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001118 Py_ssize_t size;
1119 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
1120 if (!obj)
1121 return -1;
1122 size = PyBytes_GET_SIZE(obj);
1123 *end = ((PyUnicodeErrorObject *)exc)->end;
1124 if (*end<1)
1125 *end = 1;
1126 if (*end>size)
1127 *end = size;
1128 Py_DECREF(obj);
1129 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001130}
1131
1132
1133int
1134PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1135{
1136 return PyUnicodeEncodeError_GetEnd(exc, start);
1137}
1138
1139
1140int
1141PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1142{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001143 ((PyUnicodeErrorObject *)exc)->end = end;
1144 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001145}
1146
1147
1148int
1149PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1150{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001151 ((PyUnicodeErrorObject *)exc)->end = end;
1152 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001153}
1154
1155
1156int
1157PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1158{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001159 ((PyUnicodeErrorObject *)exc)->end = end;
1160 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001161}
1162
1163PyObject *
1164PyUnicodeEncodeError_GetReason(PyObject *exc)
1165{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001166 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001167}
1168
1169
1170PyObject *
1171PyUnicodeDecodeError_GetReason(PyObject *exc)
1172{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001173 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174}
1175
1176
1177PyObject *
1178PyUnicodeTranslateError_GetReason(PyObject *exc)
1179{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001180 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001181}
1182
1183
1184int
1185PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1186{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001187 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1188 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001189}
1190
1191
1192int
1193PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1194{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001195 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1196 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001197}
1198
1199
1200int
1201PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1202{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001203 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1204 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001205}
1206
1207
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208static int
1209UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1210 PyTypeObject *objecttype)
1211{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001212 Py_CLEAR(self->encoding);
1213 Py_CLEAR(self->object);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001214 Py_CLEAR(self->reason);
1215
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001216 if (!PyArg_ParseTuple(args, "O!O!nnO!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001217 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001218 objecttype, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001219 &self->start,
1220 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001221 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001222 self->encoding = self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001223 return -1;
1224 }
1225
1226 Py_INCREF(self->encoding);
1227 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001228 Py_INCREF(self->reason);
1229
1230 return 0;
1231}
1232
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001233static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001234UnicodeError_clear(PyUnicodeErrorObject *self)
1235{
1236 Py_CLEAR(self->encoding);
1237 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001238 Py_CLEAR(self->reason);
1239 return BaseException_clear((PyBaseExceptionObject *)self);
1240}
1241
1242static void
1243UnicodeError_dealloc(PyUnicodeErrorObject *self)
1244{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001245 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001246 UnicodeError_clear(self);
1247 self->ob_type->tp_free((PyObject *)self);
1248}
1249
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001250static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001251UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1252{
1253 Py_VISIT(self->encoding);
1254 Py_VISIT(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001255 Py_VISIT(self->reason);
1256 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1257}
1258
1259static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1261 PyDoc_STR("exception encoding")},
1262 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1263 PyDoc_STR("exception object")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001264 {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001265 PyDoc_STR("exception start")},
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001266 {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001267 PyDoc_STR("exception end")},
1268 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1269 PyDoc_STR("exception reason")},
1270 {NULL} /* Sentinel */
1271};
1272
1273
1274/*
1275 * UnicodeEncodeError extends UnicodeError
1276 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277
1278static int
1279UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1280{
1281 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1282 return -1;
1283 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1284 kwds, &PyUnicode_Type);
1285}
1286
1287static PyObject *
1288UnicodeEncodeError_str(PyObject *self)
1289{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001290 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001291
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001292 if (uself->end==uself->start+1) {
1293 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001294 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001295 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001296 fmt = "'%U' codec can't encode character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001297 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001298 fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001299 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001300 fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001301 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001302 fmt,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001303 ((PyUnicodeErrorObject *)self)->encoding,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001304 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001305 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001306 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001307 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001308 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001309 return PyUnicode_FromFormat(
1310 "'%U' codec can't encode characters in position %zd-%zd: %U",
1311 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001312 uself->start,
1313 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001314 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315 );
1316}
1317
1318static PyTypeObject _PyExc_UnicodeEncodeError = {
1319 PyObject_HEAD_INIT(NULL)
1320 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001321 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322 sizeof(PyUnicodeErrorObject), 0,
1323 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1324 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1325 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001326 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1327 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001329 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001330};
1331PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1332
1333PyObject *
1334PyUnicodeEncodeError_Create(
1335 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1336 Py_ssize_t start, Py_ssize_t end, const char *reason)
1337{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001338 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001339 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340}
1341
1342
1343/*
1344 * UnicodeDecodeError extends UnicodeError
1345 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346
1347static int
1348UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1349{
1350 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1351 return -1;
1352 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001353 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354}
1355
1356static PyObject *
1357UnicodeDecodeError_str(PyObject *self)
1358{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001359 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001361 if (uself->end==uself->start+1) {
1362 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001363 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001364 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001365 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001366 byte,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001367 uself->start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001368 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001369 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001371 return PyUnicode_FromFormat(
1372 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1373 ((PyUnicodeErrorObject *)self)->encoding,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001374 uself->start,
1375 uself->end-1,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001376 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377 );
1378}
1379
1380static PyTypeObject _PyExc_UnicodeDecodeError = {
1381 PyObject_HEAD_INIT(NULL)
1382 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001383 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384 sizeof(PyUnicodeErrorObject), 0,
1385 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1386 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1387 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001388 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1389 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001391 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392};
1393PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1394
1395PyObject *
1396PyUnicodeDecodeError_Create(
1397 const char *encoding, const char *object, Py_ssize_t length,
1398 Py_ssize_t start, Py_ssize_t end, const char *reason)
1399{
1400 assert(length < INT_MAX);
1401 assert(start < INT_MAX);
1402 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001403 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001404 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405}
1406
1407
1408/*
1409 * UnicodeTranslateError extends UnicodeError
1410 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411
1412static int
1413UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1414 PyObject *kwds)
1415{
1416 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1417 return -1;
1418
1419 Py_CLEAR(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001420 Py_CLEAR(self->reason);
1421
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001422 if (!PyArg_ParseTuple(args, "O!nnO!",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423 &PyUnicode_Type, &self->object,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001424 &self->start,
1425 &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001426 &PyUnicode_Type, &self->reason)) {
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001427 self->object = self->reason = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428 return -1;
1429 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001430
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431 Py_INCREF(self->object);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001432 Py_INCREF(self->reason);
1433
1434 return 0;
1435}
1436
1437
1438static PyObject *
1439UnicodeTranslateError_str(PyObject *self)
1440{
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001441 PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001442
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001443 if (uself->end==uself->start+1) {
1444 int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001445 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001446 if (badchar <= 0xff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001447 fmt = "can't translate character '\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001448 else if (badchar <= 0xffff)
Walter Dörwald32a4c712007-06-20 09:25:34 +00001449 fmt = "can't translate character '\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001450 else
Walter Dörwald32a4c712007-06-20 09:25:34 +00001451 fmt = "can't translate character '\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001452 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001453 fmt,
1454 badchar,
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001455 uself->start,
1456 uself->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001457 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001459 return PyUnicode_FromFormat(
1460 "can't translate characters in position %zd-%zd: %U",
Guido van Rossum7eaf8222007-06-18 17:58:50 +00001461 uself->start,
1462 uself->end-1,
1463 uself->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001464 );
1465}
1466
1467static PyTypeObject _PyExc_UnicodeTranslateError = {
1468 PyObject_HEAD_INIT(NULL)
1469 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001470 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001471 sizeof(PyUnicodeErrorObject), 0,
1472 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1473 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1474 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001475 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001476 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1477 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001478 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479};
1480PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1481
1482PyObject *
1483PyUnicodeTranslateError_Create(
1484 const Py_UNICODE *object, Py_ssize_t length,
1485 Py_ssize_t start, Py_ssize_t end, const char *reason)
1486{
1487 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001488 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001489}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490
1491
1492/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001493 * AssertionError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001495SimpleExtendsException(PyExc_Exception, AssertionError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496 "Assertion failed.");
1497
1498
1499/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001500 * ArithmeticError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001501 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001502SimpleExtendsException(PyExc_Exception, ArithmeticError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001503 "Base class for arithmetic errors.");
1504
1505
1506/*
1507 * FloatingPointError extends ArithmeticError
1508 */
1509SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1510 "Floating point operation failed.");
1511
1512
1513/*
1514 * OverflowError extends ArithmeticError
1515 */
1516SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1517 "Result too large to be represented.");
1518
1519
1520/*
1521 * ZeroDivisionError extends ArithmeticError
1522 */
1523SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1524 "Second argument to a division or modulo operation was zero.");
1525
1526
1527/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001528 * SystemError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001530SimpleExtendsException(PyExc_Exception, SystemError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531 "Internal error in the Python interpreter.\n"
1532 "\n"
1533 "Please report this to the Python maintainer, along with the traceback,\n"
1534 "the Python version, and the hardware/OS platform and version.");
1535
1536
1537/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001538 * ReferenceError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001540SimpleExtendsException(PyExc_Exception, ReferenceError,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001541 "Weak ref proxy used after referent went away.");
1542
1543
1544/*
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001545 * MemoryError extends Exception
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546 */
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001547SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548
1549
1550/* Warning category docstrings */
1551
1552/*
1553 * Warning extends Exception
1554 */
1555SimpleExtendsException(PyExc_Exception, Warning,
1556 "Base class for warning categories.");
1557
1558
1559/*
1560 * UserWarning extends Warning
1561 */
1562SimpleExtendsException(PyExc_Warning, UserWarning,
1563 "Base class for warnings generated by user code.");
1564
1565
1566/*
1567 * DeprecationWarning extends Warning
1568 */
1569SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1570 "Base class for warnings about deprecated features.");
1571
1572
1573/*
1574 * PendingDeprecationWarning extends Warning
1575 */
1576SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1577 "Base class for warnings about features which will be deprecated\n"
1578 "in the future.");
1579
1580
1581/*
1582 * SyntaxWarning extends Warning
1583 */
1584SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1585 "Base class for warnings about dubious syntax.");
1586
1587
1588/*
1589 * RuntimeWarning extends Warning
1590 */
1591SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1592 "Base class for warnings about dubious runtime behavior.");
1593
1594
1595/*
1596 * FutureWarning extends Warning
1597 */
1598SimpleExtendsException(PyExc_Warning, FutureWarning,
1599 "Base class for warnings about constructs that will change semantically\n"
1600 "in the future.");
1601
1602
1603/*
1604 * ImportWarning extends Warning
1605 */
1606SimpleExtendsException(PyExc_Warning, ImportWarning,
1607 "Base class for warnings about probable mistakes in module imports");
1608
1609
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001610/*
1611 * UnicodeWarning extends Warning
1612 */
1613SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1614 "Base class for warnings about Unicode related problems, mostly\n"
1615 "related to conversion problems.");
1616
1617
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618/* Pre-computed MemoryError instance. Best to create this as early as
1619 * possible and not wait until a MemoryError is actually raised!
1620 */
1621PyObject *PyExc_MemoryErrorInst=NULL;
1622
Thomas Wouters477c8d52006-05-27 19:21:47 +00001623#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1624 Py_FatalError("exceptions bootstrapping error.");
1625
1626#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1628 Py_FatalError("Module dictionary insertion problem.");
1629
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001630#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1631/* crt variable checking in VisualStudio .NET 2005 */
1632#include <crtdbg.h>
1633
1634static int prevCrtReportMode;
1635static _invalid_parameter_handler prevCrtHandler;
1636
1637/* Invalid parameter handler. Sets a ValueError exception */
1638static void
1639InvalidParameterHandler(
1640 const wchar_t * expression,
1641 const wchar_t * function,
1642 const wchar_t * file,
1643 unsigned int line,
1644 uintptr_t pReserved)
1645{
1646 /* Do nothing, allow execution to continue. Usually this
1647 * means that the CRT will set errno to EINVAL
1648 */
1649}
1650#endif
1651
1652
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001654_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655{
Neal Norwitz2633c692007-02-26 22:22:47 +00001656 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657
1658 PRE_INIT(BaseException)
1659 PRE_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660 PRE_INIT(TypeError)
1661 PRE_INIT(StopIteration)
1662 PRE_INIT(GeneratorExit)
1663 PRE_INIT(SystemExit)
1664 PRE_INIT(KeyboardInterrupt)
1665 PRE_INIT(ImportError)
1666 PRE_INIT(EnvironmentError)
1667 PRE_INIT(IOError)
1668 PRE_INIT(OSError)
1669#ifdef MS_WINDOWS
1670 PRE_INIT(WindowsError)
1671#endif
1672#ifdef __VMS
1673 PRE_INIT(VMSError)
1674#endif
1675 PRE_INIT(EOFError)
1676 PRE_INIT(RuntimeError)
1677 PRE_INIT(NotImplementedError)
1678 PRE_INIT(NameError)
1679 PRE_INIT(UnboundLocalError)
1680 PRE_INIT(AttributeError)
1681 PRE_INIT(SyntaxError)
1682 PRE_INIT(IndentationError)
1683 PRE_INIT(TabError)
1684 PRE_INIT(LookupError)
1685 PRE_INIT(IndexError)
1686 PRE_INIT(KeyError)
1687 PRE_INIT(ValueError)
1688 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001689 PRE_INIT(UnicodeEncodeError)
1690 PRE_INIT(UnicodeDecodeError)
1691 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001692 PRE_INIT(AssertionError)
1693 PRE_INIT(ArithmeticError)
1694 PRE_INIT(FloatingPointError)
1695 PRE_INIT(OverflowError)
1696 PRE_INIT(ZeroDivisionError)
1697 PRE_INIT(SystemError)
1698 PRE_INIT(ReferenceError)
1699 PRE_INIT(MemoryError)
1700 PRE_INIT(Warning)
1701 PRE_INIT(UserWarning)
1702 PRE_INIT(DeprecationWarning)
1703 PRE_INIT(PendingDeprecationWarning)
1704 PRE_INIT(SyntaxWarning)
1705 PRE_INIT(RuntimeWarning)
1706 PRE_INIT(FutureWarning)
1707 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001708 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001709
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710 bltinmod = PyImport_ImportModule("__builtin__");
1711 if (bltinmod == NULL)
1712 Py_FatalError("exceptions bootstrapping error.");
1713 bdict = PyModule_GetDict(bltinmod);
1714 if (bdict == NULL)
1715 Py_FatalError("exceptions bootstrapping error.");
1716
1717 POST_INIT(BaseException)
1718 POST_INIT(Exception)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001719 POST_INIT(TypeError)
1720 POST_INIT(StopIteration)
1721 POST_INIT(GeneratorExit)
1722 POST_INIT(SystemExit)
1723 POST_INIT(KeyboardInterrupt)
1724 POST_INIT(ImportError)
1725 POST_INIT(EnvironmentError)
1726 POST_INIT(IOError)
1727 POST_INIT(OSError)
1728#ifdef MS_WINDOWS
1729 POST_INIT(WindowsError)
1730#endif
1731#ifdef __VMS
1732 POST_INIT(VMSError)
1733#endif
1734 POST_INIT(EOFError)
1735 POST_INIT(RuntimeError)
1736 POST_INIT(NotImplementedError)
1737 POST_INIT(NameError)
1738 POST_INIT(UnboundLocalError)
1739 POST_INIT(AttributeError)
1740 POST_INIT(SyntaxError)
1741 POST_INIT(IndentationError)
1742 POST_INIT(TabError)
1743 POST_INIT(LookupError)
1744 POST_INIT(IndexError)
1745 POST_INIT(KeyError)
1746 POST_INIT(ValueError)
1747 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748 POST_INIT(UnicodeEncodeError)
1749 POST_INIT(UnicodeDecodeError)
1750 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751 POST_INIT(AssertionError)
1752 POST_INIT(ArithmeticError)
1753 POST_INIT(FloatingPointError)
1754 POST_INIT(OverflowError)
1755 POST_INIT(ZeroDivisionError)
1756 POST_INIT(SystemError)
1757 POST_INIT(ReferenceError)
1758 POST_INIT(MemoryError)
1759 POST_INIT(Warning)
1760 POST_INIT(UserWarning)
1761 POST_INIT(DeprecationWarning)
1762 POST_INIT(PendingDeprecationWarning)
1763 POST_INIT(SyntaxWarning)
1764 POST_INIT(RuntimeWarning)
1765 POST_INIT(FutureWarning)
1766 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001767 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001768
1769 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1770 if (!PyExc_MemoryErrorInst)
1771 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1772
1773 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001774
1775#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1776 /* Set CRT argument error handler */
1777 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1778 /* turn off assertions in debug mode */
1779 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1780#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001781}
1782
1783void
1784_PyExc_Fini(void)
1785{
1786 Py_XDECREF(PyExc_MemoryErrorInst);
1787 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001788#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1789 /* reset CRT error handling */
1790 _set_invalid_parameter_handler(prevCrtHandler);
1791 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1792#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001793}