blob: 2fb58e253794a88874c5d832ef92cb623e0ca362 [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/*
317 * StandardError extends Exception
318 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000319SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320 "Base class for all standard Python exceptions that do not represent\n"
321 "interpreter exiting.");
322
323
324/*
325 * TypeError extends StandardError
326 */
327SimpleExtendsException(PyExc_StandardError, TypeError,
328 "Inappropriate argument type.");
329
330
331/*
332 * StopIteration extends Exception
333 */
334SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000335 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000336
337
338/*
339 * GeneratorExit extends Exception
340 */
341SimpleExtendsException(PyExc_Exception, GeneratorExit,
342 "Request that a generator exit.");
343
344
345/*
346 * SystemExit extends BaseException
347 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000348
349static int
350SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
351{
352 Py_ssize_t size = PyTuple_GET_SIZE(args);
353
354 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
355 return -1;
356
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000357 if (size == 0)
358 return 0;
359 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000360 if (size == 1)
361 self->code = PyTuple_GET_ITEM(args, 0);
362 else if (size > 1)
363 self->code = args;
364 Py_INCREF(self->code);
365 return 0;
366}
367
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000368static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369SystemExit_clear(PySystemExitObject *self)
370{
371 Py_CLEAR(self->code);
372 return BaseException_clear((PyBaseExceptionObject *)self);
373}
374
375static void
376SystemExit_dealloc(PySystemExitObject *self)
377{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000378 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000379 SystemExit_clear(self);
380 self->ob_type->tp_free((PyObject *)self);
381}
382
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000383static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000384SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
385{
386 Py_VISIT(self->code);
387 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
388}
389
390static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000391 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
392 PyDoc_STR("exception code")},
393 {NULL} /* Sentinel */
394};
395
396ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
397 SystemExit_dealloc, 0, SystemExit_members, 0,
398 "Request to exit from the interpreter.");
399
400/*
401 * KeyboardInterrupt extends BaseException
402 */
403SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
404 "Program interrupted by user.");
405
406
407/*
408 * ImportError extends StandardError
409 */
410SimpleExtendsException(PyExc_StandardError, ImportError,
411 "Import can't find module, or can't find name in module.");
412
413
414/*
415 * EnvironmentError extends StandardError
416 */
417
Thomas Wouters477c8d52006-05-27 19:21:47 +0000418/* Where a function has a single filename, such as open() or some
419 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
420 * called, giving a third argument which is the filename. But, so
421 * that old code using in-place unpacking doesn't break, e.g.:
422 *
423 * except IOError, (errno, strerror):
424 *
425 * we hack args so that it only contains two items. This also
426 * means we need our own __str__() which prints out the filename
427 * when it was supplied.
428 */
429static int
430EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
431 PyObject *kwds)
432{
433 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
434 PyObject *subslice = NULL;
435
436 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
437 return -1;
438
Thomas Wouters89f507f2006-12-13 04:49:30 +0000439 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440 return 0;
441 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000442
443 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000444 &myerrno, &strerror, &filename)) {
445 return -1;
446 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000447 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000448 self->myerrno = myerrno;
449 Py_INCREF(self->myerrno);
450
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000451 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000452 self->strerror = strerror;
453 Py_INCREF(self->strerror);
454
455 /* self->filename will remain Py_None otherwise */
456 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000457 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000458 self->filename = filename;
459 Py_INCREF(self->filename);
460
461 subslice = PyTuple_GetSlice(args, 0, 2);
462 if (!subslice)
463 return -1;
464
465 Py_DECREF(self->args); /* replacing args */
466 self->args = subslice;
467 }
468 return 0;
469}
470
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000471static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472EnvironmentError_clear(PyEnvironmentErrorObject *self)
473{
474 Py_CLEAR(self->myerrno);
475 Py_CLEAR(self->strerror);
476 Py_CLEAR(self->filename);
477 return BaseException_clear((PyBaseExceptionObject *)self);
478}
479
480static void
481EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
482{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000483 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000484 EnvironmentError_clear(self);
485 self->ob_type->tp_free((PyObject *)self);
486}
487
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000488static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
490 void *arg)
491{
492 Py_VISIT(self->myerrno);
493 Py_VISIT(self->strerror);
494 Py_VISIT(self->filename);
495 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
496}
497
498static PyObject *
499EnvironmentError_str(PyEnvironmentErrorObject *self)
500{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000501 if (self->filename)
502 return PyUnicode_FromFormat("[Errno %S] %S: %R",
503 self->myerrno ? self->myerrno: Py_None,
504 self->strerror ? self->strerror: Py_None,
505 self->filename);
506 else if (self->myerrno && self->strerror)
507 return PyUnicode_FromFormat("[Errno %S] %S",
508 self->myerrno ? self->myerrno: Py_None,
509 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000511 return BaseException_str((PyBaseExceptionObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000512}
513
514static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000515 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
516 PyDoc_STR("exception errno")},
517 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
518 PyDoc_STR("exception strerror")},
519 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
520 PyDoc_STR("exception filename")},
521 {NULL} /* Sentinel */
522};
523
524
525static PyObject *
526EnvironmentError_reduce(PyEnvironmentErrorObject *self)
527{
528 PyObject *args = self->args;
529 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000530
Thomas Wouters477c8d52006-05-27 19:21:47 +0000531 /* self->args is only the first two real arguments if there was a
532 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000533 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000534 args = PyTuple_New(3);
535 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000536
537 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000538 Py_INCREF(tmp);
539 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000540
541 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000542 Py_INCREF(tmp);
543 PyTuple_SET_ITEM(args, 1, tmp);
544
545 Py_INCREF(self->filename);
546 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000547 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000548 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000549
550 if (self->dict)
551 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
552 else
553 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000554 Py_DECREF(args);
555 return res;
556}
557
558
559static PyMethodDef EnvironmentError_methods[] = {
560 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
561 {NULL}
562};
563
564ComplexExtendsException(PyExc_StandardError, EnvironmentError,
565 EnvironmentError, EnvironmentError_dealloc,
566 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000567 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000568 "Base class for I/O related errors.");
569
570
571/*
572 * IOError extends EnvironmentError
573 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000574MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000575 EnvironmentError, "I/O operation failed.");
576
577
578/*
579 * OSError extends EnvironmentError
580 */
581MiddlingExtendsException(PyExc_EnvironmentError, OSError,
582 EnvironmentError, "OS system call failed.");
583
584
585/*
586 * WindowsError extends OSError
587 */
588#ifdef MS_WINDOWS
589#include "errmap.h"
590
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000591static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000592WindowsError_clear(PyWindowsErrorObject *self)
593{
594 Py_CLEAR(self->myerrno);
595 Py_CLEAR(self->strerror);
596 Py_CLEAR(self->filename);
597 Py_CLEAR(self->winerror);
598 return BaseException_clear((PyBaseExceptionObject *)self);
599}
600
601static void
602WindowsError_dealloc(PyWindowsErrorObject *self)
603{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000604 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000605 WindowsError_clear(self);
606 self->ob_type->tp_free((PyObject *)self);
607}
608
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000609static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000610WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
611{
612 Py_VISIT(self->myerrno);
613 Py_VISIT(self->strerror);
614 Py_VISIT(self->filename);
615 Py_VISIT(self->winerror);
616 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
617}
618
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619static int
620WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
621{
622 PyObject *o_errcode = NULL;
623 long errcode;
624 long posix_errno;
625
626 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
627 == -1)
628 return -1;
629
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000630 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000631 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000632
633 /* Set errno to the POSIX errno, and winerror to the Win32
634 error code. */
635 errcode = PyInt_AsLong(self->myerrno);
636 if (errcode == -1 && PyErr_Occurred())
637 return -1;
638 posix_errno = winerror_to_errno(errcode);
639
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000640 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000641 self->winerror = self->myerrno;
642
643 o_errcode = PyInt_FromLong(posix_errno);
644 if (!o_errcode)
645 return -1;
646
647 self->myerrno = o_errcode;
648
649 return 0;
650}
651
652
653static PyObject *
654WindowsError_str(PyWindowsErrorObject *self)
655{
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000656 if (self->filename)
657 return PyUnicode_FromFormat("[Error %S] %S: %R",
658 self->winerror ? self->winerror: Py_None,
659 self->strerror ? self->strerror: Py_None,
660 self->filename);
661 else if (self->winerror && self->strerror)
662 return PyUnicode_FromFormat("[Error %S] %S",
663 self->winerror ? self->winerror: Py_None,
664 self->strerror ? self->strerror: Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665 else
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000666 return EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000667}
668
669static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
671 PyDoc_STR("POSIX exception code")},
672 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
673 PyDoc_STR("exception strerror")},
674 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
675 PyDoc_STR("exception filename")},
676 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
677 PyDoc_STR("Win32 exception code")},
678 {NULL} /* Sentinel */
679};
680
681ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
682 WindowsError_dealloc, 0, WindowsError_members,
683 WindowsError_str, "MS-Windows OS system call failed.");
684
685#endif /* MS_WINDOWS */
686
687
688/*
689 * VMSError extends OSError (I think)
690 */
691#ifdef __VMS
692MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
693 "OpenVMS OS system call failed.");
694#endif
695
696
697/*
698 * EOFError extends StandardError
699 */
700SimpleExtendsException(PyExc_StandardError, EOFError,
701 "Read beyond end of file.");
702
703
704/*
705 * RuntimeError extends StandardError
706 */
707SimpleExtendsException(PyExc_StandardError, RuntimeError,
708 "Unspecified run-time error.");
709
710
711/*
712 * NotImplementedError extends RuntimeError
713 */
714SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
715 "Method or function hasn't been implemented yet.");
716
717/*
718 * NameError extends StandardError
719 */
720SimpleExtendsException(PyExc_StandardError, NameError,
721 "Name not found globally.");
722
723/*
724 * UnboundLocalError extends NameError
725 */
726SimpleExtendsException(PyExc_NameError, UnboundLocalError,
727 "Local name referenced but not bound to a value.");
728
729/*
730 * AttributeError extends StandardError
731 */
732SimpleExtendsException(PyExc_StandardError, AttributeError,
733 "Attribute not found.");
734
735
736/*
737 * SyntaxError extends StandardError
738 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739
740static int
741SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
742{
743 PyObject *info = NULL;
744 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
745
746 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
747 return -1;
748
749 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000750 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000751 self->msg = PyTuple_GET_ITEM(args, 0);
752 Py_INCREF(self->msg);
753 }
754 if (lenargs == 2) {
755 info = PyTuple_GET_ITEM(args, 1);
756 info = PySequence_Tuple(info);
757 if (!info) return -1;
758
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000759 if (PyTuple_GET_SIZE(info) != 4) {
760 /* not a very good error message, but it's what Python 2.4 gives */
761 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
762 Py_DECREF(info);
763 return -1;
764 }
765
766 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000767 self->filename = PyTuple_GET_ITEM(info, 0);
768 Py_INCREF(self->filename);
769
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000770 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771 self->lineno = PyTuple_GET_ITEM(info, 1);
772 Py_INCREF(self->lineno);
773
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000774 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000775 self->offset = PyTuple_GET_ITEM(info, 2);
776 Py_INCREF(self->offset);
777
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000778 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000779 self->text = PyTuple_GET_ITEM(info, 3);
780 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000781
782 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000783 }
784 return 0;
785}
786
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000787static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000788SyntaxError_clear(PySyntaxErrorObject *self)
789{
790 Py_CLEAR(self->msg);
791 Py_CLEAR(self->filename);
792 Py_CLEAR(self->lineno);
793 Py_CLEAR(self->offset);
794 Py_CLEAR(self->text);
795 Py_CLEAR(self->print_file_and_line);
796 return BaseException_clear((PyBaseExceptionObject *)self);
797}
798
799static void
800SyntaxError_dealloc(PySyntaxErrorObject *self)
801{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000802 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 SyntaxError_clear(self);
804 self->ob_type->tp_free((PyObject *)self);
805}
806
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000807static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
809{
810 Py_VISIT(self->msg);
811 Py_VISIT(self->filename);
812 Py_VISIT(self->lineno);
813 Py_VISIT(self->offset);
814 Py_VISIT(self->text);
815 Py_VISIT(self->print_file_and_line);
816 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
817}
818
819/* This is called "my_basename" instead of just "basename" to avoid name
820 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
821 defined, and Python does define that. */
822static char *
823my_basename(char *name)
824{
825 char *cp = name;
826 char *result = name;
827
828 if (name == NULL)
829 return "???";
830 while (*cp != '\0') {
831 if (*cp == SEP)
832 result = cp + 1;
833 ++cp;
834 }
835 return result;
836}
837
838
839static PyObject *
840SyntaxError_str(PySyntaxErrorObject *self)
841{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000842 int have_filename = 0;
843 int have_lineno = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000844
845 /* XXX -- do all the additional formatting with filename and
846 lineno here */
847
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000848 have_filename = (self->filename != NULL) &&
849 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +0000850 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000851
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000852 if (!have_filename && !have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000853 return PyObject_Unicode(self->msg ? self->msg : Py_None);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000855 if (have_filename && have_lineno)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000856 return PyUnicode_FromFormat("%S (%s, line %ld)",
857 self->msg ? self->msg : Py_None,
858 my_basename(PyString_AS_STRING(self->filename)),
859 PyInt_AsLong(self->lineno));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000860 else if (have_filename)
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000861 return PyUnicode_FromFormat("%S (%s)",
862 self->msg ? self->msg : Py_None,
863 my_basename(PyString_AS_STRING(self->filename)));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000864 else /* only have_lineno */
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000865 return PyUnicode_FromFormat("%S (line %ld)",
866 self->msg ? self->msg : Py_None,
867 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000868}
869
870static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
872 PyDoc_STR("exception msg")},
873 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
874 PyDoc_STR("exception filename")},
875 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
876 PyDoc_STR("exception lineno")},
877 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
878 PyDoc_STR("exception offset")},
879 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
880 PyDoc_STR("exception text")},
881 {"print_file_and_line", T_OBJECT,
882 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
883 PyDoc_STR("exception print_file_and_line")},
884 {NULL} /* Sentinel */
885};
886
887ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
888 SyntaxError_dealloc, 0, SyntaxError_members,
889 SyntaxError_str, "Invalid syntax.");
890
891
892/*
893 * IndentationError extends SyntaxError
894 */
895MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
896 "Improper indentation.");
897
898
899/*
900 * TabError extends IndentationError
901 */
902MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
903 "Improper mixture of spaces and tabs.");
904
905
906/*
907 * LookupError extends StandardError
908 */
909SimpleExtendsException(PyExc_StandardError, LookupError,
910 "Base class for lookup errors.");
911
912
913/*
914 * IndexError extends LookupError
915 */
916SimpleExtendsException(PyExc_LookupError, IndexError,
917 "Sequence index out of range.");
918
919
920/*
921 * KeyError extends LookupError
922 */
923static PyObject *
924KeyError_str(PyBaseExceptionObject *self)
925{
926 /* If args is a tuple of exactly one item, apply repr to args[0].
927 This is done so that e.g. the exception raised by {}[''] prints
928 KeyError: ''
929 rather than the confusing
930 KeyError
931 alone. The downside is that if KeyError is raised with an explanatory
932 string, that string will be displayed in quotes. Too bad.
933 If args is anything else, use the default BaseException__str__().
934 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000935 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwaldf5bec7c2007-05-26 15:03:32 +0000936 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000937 }
938 return BaseException_str(self);
939}
940
941ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
942 0, 0, 0, KeyError_str, "Mapping key not found.");
943
944
945/*
946 * ValueError extends StandardError
947 */
948SimpleExtendsException(PyExc_StandardError, ValueError,
949 "Inappropriate argument value (of correct type).");
950
951/*
952 * UnicodeError extends ValueError
953 */
954
955SimpleExtendsException(PyExc_ValueError, UnicodeError,
956 "Unicode related error.");
957
Thomas Wouters477c8d52006-05-27 19:21:47 +0000958static int
959get_int(PyObject *attr, Py_ssize_t *value, const char *name)
960{
961 if (!attr) {
962 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
963 return -1;
964 }
965
Guido van Rossumddefaf32007-01-14 03:31:43 +0000966 if (PyLong_Check(attr)) {
967 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968 if (*value == -1 && PyErr_Occurred())
969 return -1;
970 } else {
971 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
972 return -1;
973 }
974 return 0;
975}
976
977static int
978set_ssize_t(PyObject **attr, Py_ssize_t value)
979{
980 PyObject *obj = PyInt_FromSsize_t(value);
981 if (!obj)
982 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000983 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000984 *attr = obj;
985 return 0;
986}
987
988static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +0000989get_bytes(PyObject *attr, const char *name)
990{
991 if (!attr) {
992 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
993 return NULL;
994 }
995
996 if (!PyBytes_Check(attr)) {
997 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
998 return NULL;
999 }
1000 Py_INCREF(attr);
1001 return attr;
1002}
1003
1004static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005get_unicode(PyObject *attr, const char *name)
1006{
1007 if (!attr) {
1008 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1009 return NULL;
1010 }
1011
1012 if (!PyUnicode_Check(attr)) {
1013 PyErr_Format(PyExc_TypeError,
1014 "%.200s attribute must be unicode", name);
1015 return NULL;
1016 }
1017 Py_INCREF(attr);
1018 return attr;
1019}
1020
Walter Dörwaldd2034312007-05-18 16:29:38 +00001021static int
1022set_unicodefromstring(PyObject **attr, const char *value)
1023{
1024 PyObject *obj = PyUnicode_FromString(value);
1025 if (!obj)
1026 return -1;
1027 Py_CLEAR(*attr);
1028 *attr = obj;
1029 return 0;
1030}
1031
Thomas Wouters477c8d52006-05-27 19:21:47 +00001032PyObject *
1033PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1034{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001035 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001036}
1037
1038PyObject *
1039PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1040{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001041 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042}
1043
1044PyObject *
1045PyUnicodeEncodeError_GetObject(PyObject *exc)
1046{
1047 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1048}
1049
1050PyObject *
1051PyUnicodeDecodeError_GetObject(PyObject *exc)
1052{
Walter Dörwald612344f2007-05-04 19:28:21 +00001053 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001054}
1055
1056PyObject *
1057PyUnicodeTranslateError_GetObject(PyObject *exc)
1058{
1059 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1060}
1061
1062int
1063PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1064{
1065 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1066 Py_ssize_t size;
1067 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1068 "object");
1069 if (!obj) return -1;
1070 size = PyUnicode_GET_SIZE(obj);
1071 if (*start<0)
1072 *start = 0; /*XXX check for values <0*/
1073 if (*start>=size)
1074 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001075 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001076 return 0;
1077 }
1078 return -1;
1079}
1080
1081
1082int
1083PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1084{
1085 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1086 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001087 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001088 "object");
1089 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001090 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001091 if (*start<0)
1092 *start = 0;
1093 if (*start>=size)
1094 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001095 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001096 return 0;
1097 }
1098 return -1;
1099}
1100
1101
1102int
1103PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1104{
1105 return PyUnicodeEncodeError_GetStart(exc, start);
1106}
1107
1108
1109int
1110PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1111{
1112 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1113}
1114
1115
1116int
1117PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1118{
1119 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1120}
1121
1122
1123int
1124PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1125{
1126 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1127}
1128
1129
1130int
1131PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1132{
1133 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1134 Py_ssize_t size;
1135 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1136 "object");
1137 if (!obj) return -1;
1138 size = PyUnicode_GET_SIZE(obj);
1139 if (*end<1)
1140 *end = 1;
1141 if (*end>size)
1142 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001143 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001144 return 0;
1145 }
1146 return -1;
1147}
1148
1149
1150int
1151PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1152{
1153 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1154 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001155 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156 "object");
1157 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001158 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159 if (*end<1)
1160 *end = 1;
1161 if (*end>size)
1162 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001163 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164 return 0;
1165 }
1166 return -1;
1167}
1168
1169
1170int
1171PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1172{
1173 return PyUnicodeEncodeError_GetEnd(exc, start);
1174}
1175
1176
1177int
1178PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1179{
1180 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1181}
1182
1183
1184int
1185PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1186{
1187 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1188}
1189
1190
1191int
1192PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1193{
1194 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1195}
1196
1197PyObject *
1198PyUnicodeEncodeError_GetReason(PyObject *exc)
1199{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001200 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001201}
1202
1203
1204PyObject *
1205PyUnicodeDecodeError_GetReason(PyObject *exc)
1206{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001207 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208}
1209
1210
1211PyObject *
1212PyUnicodeTranslateError_GetReason(PyObject *exc)
1213{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001214 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001215}
1216
1217
1218int
1219PyUnicodeEncodeError_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
1227PyUnicodeDecodeError_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
1234int
1235PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1236{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001237 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1238 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001239}
1240
1241
Thomas Wouters477c8d52006-05-27 19:21:47 +00001242static int
1243UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1244 PyTypeObject *objecttype)
1245{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001246 Py_CLEAR(self->encoding);
1247 Py_CLEAR(self->object);
1248 Py_CLEAR(self->start);
1249 Py_CLEAR(self->end);
1250 Py_CLEAR(self->reason);
1251
Thomas Wouters477c8d52006-05-27 19:21:47 +00001252 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001253 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001254 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001255 &PyLong_Type, &self->start,
1256 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001257 &PyUnicode_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001258 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001259 self->reason = NULL;
1260 return -1;
1261 }
1262
1263 Py_INCREF(self->encoding);
1264 Py_INCREF(self->object);
1265 Py_INCREF(self->start);
1266 Py_INCREF(self->end);
1267 Py_INCREF(self->reason);
1268
1269 return 0;
1270}
1271
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001272static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273UnicodeError_clear(PyUnicodeErrorObject *self)
1274{
1275 Py_CLEAR(self->encoding);
1276 Py_CLEAR(self->object);
1277 Py_CLEAR(self->start);
1278 Py_CLEAR(self->end);
1279 Py_CLEAR(self->reason);
1280 return BaseException_clear((PyBaseExceptionObject *)self);
1281}
1282
1283static void
1284UnicodeError_dealloc(PyUnicodeErrorObject *self)
1285{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001286 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001287 UnicodeError_clear(self);
1288 self->ob_type->tp_free((PyObject *)self);
1289}
1290
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001291static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1293{
1294 Py_VISIT(self->encoding);
1295 Py_VISIT(self->object);
1296 Py_VISIT(self->start);
1297 Py_VISIT(self->end);
1298 Py_VISIT(self->reason);
1299 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1300}
1301
1302static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001303 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1304 PyDoc_STR("exception encoding")},
1305 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1306 PyDoc_STR("exception object")},
1307 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1308 PyDoc_STR("exception start")},
1309 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1310 PyDoc_STR("exception end")},
1311 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1312 PyDoc_STR("exception reason")},
1313 {NULL} /* Sentinel */
1314};
1315
1316
1317/*
1318 * UnicodeEncodeError extends UnicodeError
1319 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
1321static int
1322UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1323{
1324 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1325 return -1;
1326 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1327 kwds, &PyUnicode_Type);
1328}
1329
1330static PyObject *
1331UnicodeEncodeError_str(PyObject *self)
1332{
1333 Py_ssize_t start;
1334 Py_ssize_t end;
1335
1336 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001337 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001338
1339 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001340 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341
1342 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001343 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001344 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001345 if (badchar <= 0xff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001346 fmt = "'%U' codec can't encode character u'\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347 else if (badchar <= 0xffff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001348 fmt = "'%U' codec can't encode character u'\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001349 else
Walter Dörwald787b03b2007-06-05 13:29:29 +00001350 fmt = "'%U' codec can't encode character u'\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001351 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001352 fmt,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001353 ((PyUnicodeErrorObject *)self)->encoding,
Walter Dörwald787b03b2007-06-05 13:29:29 +00001354 badchar,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001355 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001356 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001357 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001358 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001359 return PyUnicode_FromFormat(
1360 "'%U' codec can't encode characters in position %zd-%zd: %U",
1361 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362 start,
1363 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001364 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001365 );
1366}
1367
1368static PyTypeObject _PyExc_UnicodeEncodeError = {
1369 PyObject_HEAD_INIT(NULL)
1370 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001371 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372 sizeof(PyUnicodeErrorObject), 0,
1373 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1374 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1375 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001376 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1377 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001379 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380};
1381PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1382
1383PyObject *
1384PyUnicodeEncodeError_Create(
1385 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1386 Py_ssize_t start, Py_ssize_t end, const char *reason)
1387{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001388 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001389 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390}
1391
1392
1393/*
1394 * UnicodeDecodeError extends UnicodeError
1395 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001396
1397static int
1398UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1399{
1400 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1401 return -1;
1402 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001403 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404}
1405
1406static PyObject *
1407UnicodeDecodeError_str(PyObject *self)
1408{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001409 Py_ssize_t start = 0;
1410 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411
1412 if (PyUnicodeDecodeError_GetStart(self, &start))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001413 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414
1415 if (PyUnicodeDecodeError_GetEnd(self, &end))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001416 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417
1418 if (end==start+1) {
Walter Dörwald787b03b2007-06-05 13:29:29 +00001419 int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start]&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001420 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001421 "'%U' codec can't decode byte 0x%02x in position %zd: %U",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001422 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001423 byte,
1424 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001425 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001426 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001428 return PyUnicode_FromFormat(
1429 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1430 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431 start,
1432 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001433 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001434 );
1435}
1436
1437static PyTypeObject _PyExc_UnicodeDecodeError = {
1438 PyObject_HEAD_INIT(NULL)
1439 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001440 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001441 sizeof(PyUnicodeErrorObject), 0,
1442 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1443 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1444 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001445 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1446 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001448 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449};
1450PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1451
1452PyObject *
1453PyUnicodeDecodeError_Create(
1454 const char *encoding, const char *object, Py_ssize_t length,
1455 Py_ssize_t start, Py_ssize_t end, const char *reason)
1456{
1457 assert(length < INT_MAX);
1458 assert(start < INT_MAX);
1459 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001460 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001461 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462}
1463
1464
1465/*
1466 * UnicodeTranslateError extends UnicodeError
1467 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468
1469static int
1470UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1471 PyObject *kwds)
1472{
1473 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1474 return -1;
1475
1476 Py_CLEAR(self->object);
1477 Py_CLEAR(self->start);
1478 Py_CLEAR(self->end);
1479 Py_CLEAR(self->reason);
1480
1481 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1482 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001483 &PyLong_Type, &self->start,
1484 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001485 &PyUnicode_Type, &self->reason)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001486 self->object = self->start = self->end = self->reason = NULL;
1487 return -1;
1488 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001489
Thomas Wouters477c8d52006-05-27 19:21:47 +00001490 Py_INCREF(self->object);
1491 Py_INCREF(self->start);
1492 Py_INCREF(self->end);
1493 Py_INCREF(self->reason);
1494
1495 return 0;
1496}
1497
1498
1499static PyObject *
1500UnicodeTranslateError_str(PyObject *self)
1501{
1502 Py_ssize_t start;
1503 Py_ssize_t end;
1504
1505 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001506 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001507
1508 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001509 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510
1511 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001512 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
Walter Dörwald787b03b2007-06-05 13:29:29 +00001513 const char *fmt;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001514 if (badchar <= 0xff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001515 fmt = "can't translate character u'\\x%02x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001516 else if (badchar <= 0xffff)
Walter Dörwald787b03b2007-06-05 13:29:29 +00001517 fmt = "can't translate character u'\\u%04x' in position %zd: %U";
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001518 else
Walter Dörwald787b03b2007-06-05 13:29:29 +00001519 fmt = "can't translate character u'\\U%08x' in position %zd: %U";
Walter Dörwaldd2034312007-05-18 16:29:38 +00001520 return PyUnicode_FromFormat(
Walter Dörwald787b03b2007-06-05 13:29:29 +00001521 fmt,
1522 badchar,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001523 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001524 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001525 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001527 return PyUnicode_FromFormat(
1528 "can't translate characters in position %zd-%zd: %U",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529 start,
1530 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001531 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001532 );
1533}
1534
1535static PyTypeObject _PyExc_UnicodeTranslateError = {
1536 PyObject_HEAD_INIT(NULL)
1537 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001538 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539 sizeof(PyUnicodeErrorObject), 0,
1540 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1541 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1542 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001543 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1545 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001546 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547};
1548PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1549
1550PyObject *
1551PyUnicodeTranslateError_Create(
1552 const Py_UNICODE *object, Py_ssize_t length,
1553 Py_ssize_t start, Py_ssize_t end, const char *reason)
1554{
1555 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001556 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001558
1559
1560/*
1561 * AssertionError extends StandardError
1562 */
1563SimpleExtendsException(PyExc_StandardError, AssertionError,
1564 "Assertion failed.");
1565
1566
1567/*
1568 * ArithmeticError extends StandardError
1569 */
1570SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1571 "Base class for arithmetic errors.");
1572
1573
1574/*
1575 * FloatingPointError extends ArithmeticError
1576 */
1577SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1578 "Floating point operation failed.");
1579
1580
1581/*
1582 * OverflowError extends ArithmeticError
1583 */
1584SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1585 "Result too large to be represented.");
1586
1587
1588/*
1589 * ZeroDivisionError extends ArithmeticError
1590 */
1591SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1592 "Second argument to a division or modulo operation was zero.");
1593
1594
1595/*
1596 * SystemError extends StandardError
1597 */
1598SimpleExtendsException(PyExc_StandardError, SystemError,
1599 "Internal error in the Python interpreter.\n"
1600 "\n"
1601 "Please report this to the Python maintainer, along with the traceback,\n"
1602 "the Python version, and the hardware/OS platform and version.");
1603
1604
1605/*
1606 * ReferenceError extends StandardError
1607 */
1608SimpleExtendsException(PyExc_StandardError, ReferenceError,
1609 "Weak ref proxy used after referent went away.");
1610
1611
1612/*
1613 * MemoryError extends StandardError
1614 */
1615SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1616
1617
1618/* Warning category docstrings */
1619
1620/*
1621 * Warning extends Exception
1622 */
1623SimpleExtendsException(PyExc_Exception, Warning,
1624 "Base class for warning categories.");
1625
1626
1627/*
1628 * UserWarning extends Warning
1629 */
1630SimpleExtendsException(PyExc_Warning, UserWarning,
1631 "Base class for warnings generated by user code.");
1632
1633
1634/*
1635 * DeprecationWarning extends Warning
1636 */
1637SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1638 "Base class for warnings about deprecated features.");
1639
1640
1641/*
1642 * PendingDeprecationWarning extends Warning
1643 */
1644SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1645 "Base class for warnings about features which will be deprecated\n"
1646 "in the future.");
1647
1648
1649/*
1650 * SyntaxWarning extends Warning
1651 */
1652SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1653 "Base class for warnings about dubious syntax.");
1654
1655
1656/*
1657 * RuntimeWarning extends Warning
1658 */
1659SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1660 "Base class for warnings about dubious runtime behavior.");
1661
1662
1663/*
1664 * FutureWarning extends Warning
1665 */
1666SimpleExtendsException(PyExc_Warning, FutureWarning,
1667 "Base class for warnings about constructs that will change semantically\n"
1668 "in the future.");
1669
1670
1671/*
1672 * ImportWarning extends Warning
1673 */
1674SimpleExtendsException(PyExc_Warning, ImportWarning,
1675 "Base class for warnings about probable mistakes in module imports");
1676
1677
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001678/*
1679 * UnicodeWarning extends Warning
1680 */
1681SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1682 "Base class for warnings about Unicode related problems, mostly\n"
1683 "related to conversion problems.");
1684
1685
Thomas Wouters477c8d52006-05-27 19:21:47 +00001686/* Pre-computed MemoryError instance. Best to create this as early as
1687 * possible and not wait until a MemoryError is actually raised!
1688 */
1689PyObject *PyExc_MemoryErrorInst=NULL;
1690
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1692 Py_FatalError("exceptions bootstrapping error.");
1693
1694#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1696 Py_FatalError("Module dictionary insertion problem.");
1697
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001698#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1699/* crt variable checking in VisualStudio .NET 2005 */
1700#include <crtdbg.h>
1701
1702static int prevCrtReportMode;
1703static _invalid_parameter_handler prevCrtHandler;
1704
1705/* Invalid parameter handler. Sets a ValueError exception */
1706static void
1707InvalidParameterHandler(
1708 const wchar_t * expression,
1709 const wchar_t * function,
1710 const wchar_t * file,
1711 unsigned int line,
1712 uintptr_t pReserved)
1713{
1714 /* Do nothing, allow execution to continue. Usually this
1715 * means that the CRT will set errno to EINVAL
1716 */
1717}
1718#endif
1719
1720
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001722_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001723{
Neal Norwitz2633c692007-02-26 22:22:47 +00001724 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001725
1726 PRE_INIT(BaseException)
1727 PRE_INIT(Exception)
1728 PRE_INIT(StandardError)
1729 PRE_INIT(TypeError)
1730 PRE_INIT(StopIteration)
1731 PRE_INIT(GeneratorExit)
1732 PRE_INIT(SystemExit)
1733 PRE_INIT(KeyboardInterrupt)
1734 PRE_INIT(ImportError)
1735 PRE_INIT(EnvironmentError)
1736 PRE_INIT(IOError)
1737 PRE_INIT(OSError)
1738#ifdef MS_WINDOWS
1739 PRE_INIT(WindowsError)
1740#endif
1741#ifdef __VMS
1742 PRE_INIT(VMSError)
1743#endif
1744 PRE_INIT(EOFError)
1745 PRE_INIT(RuntimeError)
1746 PRE_INIT(NotImplementedError)
1747 PRE_INIT(NameError)
1748 PRE_INIT(UnboundLocalError)
1749 PRE_INIT(AttributeError)
1750 PRE_INIT(SyntaxError)
1751 PRE_INIT(IndentationError)
1752 PRE_INIT(TabError)
1753 PRE_INIT(LookupError)
1754 PRE_INIT(IndexError)
1755 PRE_INIT(KeyError)
1756 PRE_INIT(ValueError)
1757 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758 PRE_INIT(UnicodeEncodeError)
1759 PRE_INIT(UnicodeDecodeError)
1760 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001761 PRE_INIT(AssertionError)
1762 PRE_INIT(ArithmeticError)
1763 PRE_INIT(FloatingPointError)
1764 PRE_INIT(OverflowError)
1765 PRE_INIT(ZeroDivisionError)
1766 PRE_INIT(SystemError)
1767 PRE_INIT(ReferenceError)
1768 PRE_INIT(MemoryError)
1769 PRE_INIT(Warning)
1770 PRE_INIT(UserWarning)
1771 PRE_INIT(DeprecationWarning)
1772 PRE_INIT(PendingDeprecationWarning)
1773 PRE_INIT(SyntaxWarning)
1774 PRE_INIT(RuntimeWarning)
1775 PRE_INIT(FutureWarning)
1776 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001777 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779 bltinmod = PyImport_ImportModule("__builtin__");
1780 if (bltinmod == NULL)
1781 Py_FatalError("exceptions bootstrapping error.");
1782 bdict = PyModule_GetDict(bltinmod);
1783 if (bdict == NULL)
1784 Py_FatalError("exceptions bootstrapping error.");
1785
1786 POST_INIT(BaseException)
1787 POST_INIT(Exception)
1788 POST_INIT(StandardError)
1789 POST_INIT(TypeError)
1790 POST_INIT(StopIteration)
1791 POST_INIT(GeneratorExit)
1792 POST_INIT(SystemExit)
1793 POST_INIT(KeyboardInterrupt)
1794 POST_INIT(ImportError)
1795 POST_INIT(EnvironmentError)
1796 POST_INIT(IOError)
1797 POST_INIT(OSError)
1798#ifdef MS_WINDOWS
1799 POST_INIT(WindowsError)
1800#endif
1801#ifdef __VMS
1802 POST_INIT(VMSError)
1803#endif
1804 POST_INIT(EOFError)
1805 POST_INIT(RuntimeError)
1806 POST_INIT(NotImplementedError)
1807 POST_INIT(NameError)
1808 POST_INIT(UnboundLocalError)
1809 POST_INIT(AttributeError)
1810 POST_INIT(SyntaxError)
1811 POST_INIT(IndentationError)
1812 POST_INIT(TabError)
1813 POST_INIT(LookupError)
1814 POST_INIT(IndexError)
1815 POST_INIT(KeyError)
1816 POST_INIT(ValueError)
1817 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001818 POST_INIT(UnicodeEncodeError)
1819 POST_INIT(UnicodeDecodeError)
1820 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821 POST_INIT(AssertionError)
1822 POST_INIT(ArithmeticError)
1823 POST_INIT(FloatingPointError)
1824 POST_INIT(OverflowError)
1825 POST_INIT(ZeroDivisionError)
1826 POST_INIT(SystemError)
1827 POST_INIT(ReferenceError)
1828 POST_INIT(MemoryError)
1829 POST_INIT(Warning)
1830 POST_INIT(UserWarning)
1831 POST_INIT(DeprecationWarning)
1832 POST_INIT(PendingDeprecationWarning)
1833 POST_INIT(SyntaxWarning)
1834 POST_INIT(RuntimeWarning)
1835 POST_INIT(FutureWarning)
1836 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001837 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001838
1839 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
1840 if (!PyExc_MemoryErrorInst)
1841 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
1842
1843 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001844
1845#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1846 /* Set CRT argument error handler */
1847 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
1848 /* turn off assertions in debug mode */
1849 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
1850#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001851}
1852
1853void
1854_PyExc_Fini(void)
1855{
1856 Py_XDECREF(PyExc_MemoryErrorInst);
1857 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001858#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1859 /* reset CRT error handling */
1860 _set_invalid_parameter_handler(prevCrtHandler);
1861 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
1862#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001863}