blob: f7189e21a6b2ac928475de0d17fd469501a00bc4 [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{
81 PyObject *out;
82
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000083 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000084 case 0:
85 out = PyString_FromString("");
86 break;
87 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000088 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +000089 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +000090 default:
91 out = PyObject_Str(self->args);
92 break;
93 }
94
95 return out;
96}
97
98static PyObject *
99BaseException_repr(PyBaseExceptionObject *self)
100{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000101 char *name;
102 char *dot;
103
Thomas Wouters477c8d52006-05-27 19:21:47 +0000104 name = (char *)self->ob_type->tp_name;
105 dot = strrchr(name, '.');
106 if (dot != NULL) name = dot+1;
107
Walter Dörwald7569dfe2007-05-19 21:49:49 +0000108 return PyUnicode_FromFormat("%s%R", name, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109}
110
111/* Pickling support */
112static PyObject *
113BaseException_reduce(PyBaseExceptionObject *self)
114{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000115 if (self->args && self->dict)
116 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
117 else
118 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000119}
120
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000121/*
122 * Needed for backward compatibility, since exceptions used to store
123 * all their attributes in the __dict__. Code is taken from cPickle's
124 * load_build function.
125 */
126static PyObject *
127BaseException_setstate(PyObject *self, PyObject *state)
128{
129 PyObject *d_key, *d_value;
130 Py_ssize_t i = 0;
131
132 if (state != Py_None) {
133 if (!PyDict_Check(state)) {
134 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
135 return NULL;
136 }
137 while (PyDict_Next(state, &i, &d_key, &d_value)) {
138 if (PyObject_SetAttr(self, d_key, d_value) < 0)
139 return NULL;
140 }
141 }
142 Py_RETURN_NONE;
143}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000144
Thomas Wouters477c8d52006-05-27 19:21:47 +0000145
146static PyMethodDef BaseException_methods[] = {
147 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000148 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000149 {NULL, NULL, 0, NULL},
150};
151
152
Thomas Wouters477c8d52006-05-27 19:21:47 +0000153static PyObject *
154BaseException_get_dict(PyBaseExceptionObject *self)
155{
156 if (self->dict == NULL) {
157 self->dict = PyDict_New();
158 if (!self->dict)
159 return NULL;
160 }
161 Py_INCREF(self->dict);
162 return self->dict;
163}
164
165static int
166BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
167{
168 if (val == NULL) {
169 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
170 return -1;
171 }
172 if (!PyDict_Check(val)) {
173 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
174 return -1;
175 }
176 Py_CLEAR(self->dict);
177 Py_INCREF(val);
178 self->dict = val;
179 return 0;
180}
181
182static PyObject *
183BaseException_get_args(PyBaseExceptionObject *self)
184{
185 if (self->args == NULL) {
186 Py_INCREF(Py_None);
187 return Py_None;
188 }
189 Py_INCREF(self->args);
190 return self->args;
191}
192
193static int
194BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
195{
196 PyObject *seq;
197 if (val == NULL) {
198 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
199 return -1;
200 }
201 seq = PySequence_Tuple(val);
202 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000203 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000204 self->args = seq;
205 return 0;
206}
207
Guido van Rossum360e4b82007-05-14 22:51:27 +0000208
Thomas Wouters477c8d52006-05-27 19:21:47 +0000209static PyGetSetDef BaseException_getset[] = {
210 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
211 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
212 {NULL},
213};
214
215
216static PyTypeObject _PyExc_BaseException = {
217 PyObject_HEAD_INIT(NULL)
218 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000219 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000220 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
221 0, /*tp_itemsize*/
222 (destructor)BaseException_dealloc, /*tp_dealloc*/
223 0, /*tp_print*/
224 0, /*tp_getattr*/
225 0, /*tp_setattr*/
226 0, /* tp_compare; */
227 (reprfunc)BaseException_repr, /*tp_repr*/
228 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000229 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000230 0, /*tp_as_mapping*/
231 0, /*tp_hash */
232 0, /*tp_call*/
233 (reprfunc)BaseException_str, /*tp_str*/
234 PyObject_GenericGetAttr, /*tp_getattro*/
235 PyObject_GenericSetAttr, /*tp_setattro*/
236 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000237 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
238 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000239 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
240 (traverseproc)BaseException_traverse, /* tp_traverse */
241 (inquiry)BaseException_clear, /* tp_clear */
242 0, /* tp_richcompare */
243 0, /* tp_weaklistoffset */
244 0, /* tp_iter */
245 0, /* tp_iternext */
246 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000247 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000248 BaseException_getset, /* tp_getset */
249 0, /* tp_base */
250 0, /* tp_dict */
251 0, /* tp_descr_get */
252 0, /* tp_descr_set */
253 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
254 (initproc)BaseException_init, /* tp_init */
255 0, /* tp_alloc */
256 BaseException_new, /* tp_new */
257};
258/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
259from the previous implmentation and also allowing Python objects to be used
260in the API */
261PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
262
263/* note these macros omit the last semicolon so the macro invocation may
264 * include it and not look strange.
265 */
266#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
267static PyTypeObject _PyExc_ ## EXCNAME = { \
268 PyObject_HEAD_INIT(NULL) \
269 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000270 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000271 sizeof(PyBaseExceptionObject), \
272 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
273 0, 0, 0, 0, 0, 0, 0, \
274 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
275 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
276 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
277 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
278 (initproc)BaseException_init, 0, BaseException_new,\
279}; \
280PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
281
282#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
283static PyTypeObject _PyExc_ ## EXCNAME = { \
284 PyObject_HEAD_INIT(NULL) \
285 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000286 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000287 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000288 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000289 0, 0, 0, 0, 0, \
290 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000291 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
292 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000293 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000294 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295}; \
296PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
297
298#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
299static PyTypeObject _PyExc_ ## EXCNAME = { \
300 PyObject_HEAD_INIT(NULL) \
301 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000302 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000303 sizeof(Py ## EXCSTORE ## Object), 0, \
304 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
305 (reprfunc)EXCSTR, 0, 0, 0, \
306 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
307 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
308 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
309 EXCMEMBERS, 0, &_ ## EXCBASE, \
310 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000311 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000312}; \
313PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
314
315
316/*
317 * Exception extends BaseException
318 */
319SimpleExtendsException(PyExc_BaseException, Exception,
320 "Common base class for all non-exit exceptions.");
321
322
323/*
324 * StandardError extends Exception
325 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000326SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000327 "Base class for all standard Python exceptions that do not represent\n"
328 "interpreter exiting.");
329
330
331/*
332 * TypeError extends StandardError
333 */
334SimpleExtendsException(PyExc_StandardError, TypeError,
335 "Inappropriate argument type.");
336
337
338/*
339 * StopIteration extends Exception
340 */
341SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000342 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000343
344
345/*
346 * GeneratorExit extends Exception
347 */
348SimpleExtendsException(PyExc_Exception, GeneratorExit,
349 "Request that a generator exit.");
350
351
352/*
353 * SystemExit extends BaseException
354 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000355
356static int
357SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
358{
359 Py_ssize_t size = PyTuple_GET_SIZE(args);
360
361 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
362 return -1;
363
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000364 if (size == 0)
365 return 0;
366 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367 if (size == 1)
368 self->code = PyTuple_GET_ITEM(args, 0);
369 else if (size > 1)
370 self->code = args;
371 Py_INCREF(self->code);
372 return 0;
373}
374
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000375static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000376SystemExit_clear(PySystemExitObject *self)
377{
378 Py_CLEAR(self->code);
379 return BaseException_clear((PyBaseExceptionObject *)self);
380}
381
382static void
383SystemExit_dealloc(PySystemExitObject *self)
384{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000385 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000386 SystemExit_clear(self);
387 self->ob_type->tp_free((PyObject *)self);
388}
389
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000390static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000391SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
392{
393 Py_VISIT(self->code);
394 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
395}
396
397static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000398 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
399 PyDoc_STR("exception code")},
400 {NULL} /* Sentinel */
401};
402
403ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
404 SystemExit_dealloc, 0, SystemExit_members, 0,
405 "Request to exit from the interpreter.");
406
407/*
408 * KeyboardInterrupt extends BaseException
409 */
410SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
411 "Program interrupted by user.");
412
413
414/*
415 * ImportError extends StandardError
416 */
417SimpleExtendsException(PyExc_StandardError, ImportError,
418 "Import can't find module, or can't find name in module.");
419
420
421/*
422 * EnvironmentError extends StandardError
423 */
424
Thomas Wouters477c8d52006-05-27 19:21:47 +0000425/* Where a function has a single filename, such as open() or some
426 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
427 * called, giving a third argument which is the filename. But, so
428 * that old code using in-place unpacking doesn't break, e.g.:
429 *
430 * except IOError, (errno, strerror):
431 *
432 * we hack args so that it only contains two items. This also
433 * means we need our own __str__() which prints out the filename
434 * when it was supplied.
435 */
436static int
437EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
438 PyObject *kwds)
439{
440 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
441 PyObject *subslice = NULL;
442
443 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
444 return -1;
445
Thomas Wouters89f507f2006-12-13 04:49:30 +0000446 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000447 return 0;
448 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000449
450 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000451 &myerrno, &strerror, &filename)) {
452 return -1;
453 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000454 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000455 self->myerrno = myerrno;
456 Py_INCREF(self->myerrno);
457
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000458 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000459 self->strerror = strerror;
460 Py_INCREF(self->strerror);
461
462 /* self->filename will remain Py_None otherwise */
463 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000464 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000465 self->filename = filename;
466 Py_INCREF(self->filename);
467
468 subslice = PyTuple_GetSlice(args, 0, 2);
469 if (!subslice)
470 return -1;
471
472 Py_DECREF(self->args); /* replacing args */
473 self->args = subslice;
474 }
475 return 0;
476}
477
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000478static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479EnvironmentError_clear(PyEnvironmentErrorObject *self)
480{
481 Py_CLEAR(self->myerrno);
482 Py_CLEAR(self->strerror);
483 Py_CLEAR(self->filename);
484 return BaseException_clear((PyBaseExceptionObject *)self);
485}
486
487static void
488EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
489{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000490 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491 EnvironmentError_clear(self);
492 self->ob_type->tp_free((PyObject *)self);
493}
494
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000495static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
497 void *arg)
498{
499 Py_VISIT(self->myerrno);
500 Py_VISIT(self->strerror);
501 Py_VISIT(self->filename);
502 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
503}
504
505static PyObject *
506EnvironmentError_str(PyEnvironmentErrorObject *self)
507{
508 PyObject *rtnval = NULL;
509
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000510 if (self->filename) {
511 PyObject *fmt;
512 PyObject *repr;
513 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000514
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000515 fmt = PyString_FromString("[Errno %s] %s: %s");
516 if (!fmt)
517 return NULL;
518
Walter Dörwald1ab83302007-05-18 17:15:44 +0000519 repr = PyObject_ReprStr8(self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000520 if (!repr) {
521 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522 return NULL;
523 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524 tuple = PyTuple_New(3);
525 if (!tuple) {
526 Py_DECREF(repr);
527 Py_DECREF(fmt);
528 return NULL;
529 }
530
531 if (self->myerrno) {
532 Py_INCREF(self->myerrno);
533 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
534 }
535 else {
536 Py_INCREF(Py_None);
537 PyTuple_SET_ITEM(tuple, 0, Py_None);
538 }
539 if (self->strerror) {
540 Py_INCREF(self->strerror);
541 PyTuple_SET_ITEM(tuple, 1, self->strerror);
542 }
543 else {
544 Py_INCREF(Py_None);
545 PyTuple_SET_ITEM(tuple, 1, Py_None);
546 }
547
Thomas Wouters477c8d52006-05-27 19:21:47 +0000548 PyTuple_SET_ITEM(tuple, 2, repr);
549
550 rtnval = PyString_Format(fmt, tuple);
551
552 Py_DECREF(fmt);
553 Py_DECREF(tuple);
554 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000555 else if (self->myerrno && self->strerror) {
556 PyObject *fmt;
557 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000558
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000559 fmt = PyString_FromString("[Errno %s] %s");
560 if (!fmt)
561 return NULL;
562
563 tuple = PyTuple_New(2);
564 if (!tuple) {
565 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000566 return NULL;
567 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000568
569 if (self->myerrno) {
570 Py_INCREF(self->myerrno);
571 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
572 }
573 else {
574 Py_INCREF(Py_None);
575 PyTuple_SET_ITEM(tuple, 0, Py_None);
576 }
577 if (self->strerror) {
578 Py_INCREF(self->strerror);
579 PyTuple_SET_ITEM(tuple, 1, self->strerror);
580 }
581 else {
582 Py_INCREF(Py_None);
583 PyTuple_SET_ITEM(tuple, 1, Py_None);
584 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000585
586 rtnval = PyString_Format(fmt, tuple);
587
588 Py_DECREF(fmt);
589 Py_DECREF(tuple);
590 }
591 else
592 rtnval = BaseException_str((PyBaseExceptionObject *)self);
593
594 return rtnval;
595}
596
597static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
599 PyDoc_STR("exception errno")},
600 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
601 PyDoc_STR("exception strerror")},
602 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
603 PyDoc_STR("exception filename")},
604 {NULL} /* Sentinel */
605};
606
607
608static PyObject *
609EnvironmentError_reduce(PyEnvironmentErrorObject *self)
610{
611 PyObject *args = self->args;
612 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000613
Thomas Wouters477c8d52006-05-27 19:21:47 +0000614 /* self->args is only the first two real arguments if there was a
615 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000616 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617 args = PyTuple_New(3);
618 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000619
620 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000621 Py_INCREF(tmp);
622 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000623
624 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625 Py_INCREF(tmp);
626 PyTuple_SET_ITEM(args, 1, tmp);
627
628 Py_INCREF(self->filename);
629 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000630 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000631 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000632
633 if (self->dict)
634 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
635 else
636 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637 Py_DECREF(args);
638 return res;
639}
640
641
642static PyMethodDef EnvironmentError_methods[] = {
643 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
644 {NULL}
645};
646
647ComplexExtendsException(PyExc_StandardError, EnvironmentError,
648 EnvironmentError, EnvironmentError_dealloc,
649 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000650 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000651 "Base class for I/O related errors.");
652
653
654/*
655 * IOError extends EnvironmentError
656 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000657MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000658 EnvironmentError, "I/O operation failed.");
659
660
661/*
662 * OSError extends EnvironmentError
663 */
664MiddlingExtendsException(PyExc_EnvironmentError, OSError,
665 EnvironmentError, "OS system call failed.");
666
667
668/*
669 * WindowsError extends OSError
670 */
671#ifdef MS_WINDOWS
672#include "errmap.h"
673
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000674static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675WindowsError_clear(PyWindowsErrorObject *self)
676{
677 Py_CLEAR(self->myerrno);
678 Py_CLEAR(self->strerror);
679 Py_CLEAR(self->filename);
680 Py_CLEAR(self->winerror);
681 return BaseException_clear((PyBaseExceptionObject *)self);
682}
683
684static void
685WindowsError_dealloc(PyWindowsErrorObject *self)
686{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000687 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688 WindowsError_clear(self);
689 self->ob_type->tp_free((PyObject *)self);
690}
691
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000692static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
694{
695 Py_VISIT(self->myerrno);
696 Py_VISIT(self->strerror);
697 Py_VISIT(self->filename);
698 Py_VISIT(self->winerror);
699 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
700}
701
Thomas Wouters477c8d52006-05-27 19:21:47 +0000702static int
703WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
704{
705 PyObject *o_errcode = NULL;
706 long errcode;
707 long posix_errno;
708
709 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
710 == -1)
711 return -1;
712
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000713 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000714 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715
716 /* Set errno to the POSIX errno, and winerror to the Win32
717 error code. */
718 errcode = PyInt_AsLong(self->myerrno);
719 if (errcode == -1 && PyErr_Occurred())
720 return -1;
721 posix_errno = winerror_to_errno(errcode);
722
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000723 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000724 self->winerror = self->myerrno;
725
726 o_errcode = PyInt_FromLong(posix_errno);
727 if (!o_errcode)
728 return -1;
729
730 self->myerrno = o_errcode;
731
732 return 0;
733}
734
735
736static PyObject *
737WindowsError_str(PyWindowsErrorObject *self)
738{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000739 PyObject *rtnval = NULL;
740
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000741 if (self->filename) {
742 PyObject *fmt;
743 PyObject *repr;
744 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000745
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000746 fmt = PyString_FromString("[Error %s] %s: %s");
747 if (!fmt)
748 return NULL;
749
Walter Dörwald1ab83302007-05-18 17:15:44 +0000750 repr = PyObject_ReprStr8(self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000751 if (!repr) {
752 Py_DECREF(fmt);
753 return NULL;
754 }
755 tuple = PyTuple_New(3);
756 if (!tuple) {
757 Py_DECREF(repr);
758 Py_DECREF(fmt);
759 return NULL;
760 }
761
Thomas Wouters89f507f2006-12-13 04:49:30 +0000762 if (self->winerror) {
763 Py_INCREF(self->winerror);
764 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000765 }
766 else {
767 Py_INCREF(Py_None);
768 PyTuple_SET_ITEM(tuple, 0, Py_None);
769 }
770 if (self->strerror) {
771 Py_INCREF(self->strerror);
772 PyTuple_SET_ITEM(tuple, 1, self->strerror);
773 }
774 else {
775 Py_INCREF(Py_None);
776 PyTuple_SET_ITEM(tuple, 1, Py_None);
777 }
778
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000779 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780
781 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000782
783 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784 Py_DECREF(tuple);
785 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000786 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000787 PyObject *fmt;
788 PyObject *tuple;
789
Thomas Wouters477c8d52006-05-27 19:21:47 +0000790 fmt = PyString_FromString("[Error %s] %s");
791 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000792 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000794 tuple = PyTuple_New(2);
795 if (!tuple) {
796 Py_DECREF(fmt);
797 return NULL;
798 }
799
Thomas Wouters89f507f2006-12-13 04:49:30 +0000800 if (self->winerror) {
801 Py_INCREF(self->winerror);
802 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000803 }
804 else {
805 Py_INCREF(Py_None);
806 PyTuple_SET_ITEM(tuple, 0, Py_None);
807 }
808 if (self->strerror) {
809 Py_INCREF(self->strerror);
810 PyTuple_SET_ITEM(tuple, 1, self->strerror);
811 }
812 else {
813 Py_INCREF(Py_None);
814 PyTuple_SET_ITEM(tuple, 1, Py_None);
815 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000816
817 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000818
819 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 Py_DECREF(tuple);
821 }
822 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000823 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824
Thomas Wouters477c8d52006-05-27 19:21:47 +0000825 return rtnval;
826}
827
828static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
830 PyDoc_STR("POSIX exception code")},
831 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
832 PyDoc_STR("exception strerror")},
833 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
834 PyDoc_STR("exception filename")},
835 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
836 PyDoc_STR("Win32 exception code")},
837 {NULL} /* Sentinel */
838};
839
840ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
841 WindowsError_dealloc, 0, WindowsError_members,
842 WindowsError_str, "MS-Windows OS system call failed.");
843
844#endif /* MS_WINDOWS */
845
846
847/*
848 * VMSError extends OSError (I think)
849 */
850#ifdef __VMS
851MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
852 "OpenVMS OS system call failed.");
853#endif
854
855
856/*
857 * EOFError extends StandardError
858 */
859SimpleExtendsException(PyExc_StandardError, EOFError,
860 "Read beyond end of file.");
861
862
863/*
864 * RuntimeError extends StandardError
865 */
866SimpleExtendsException(PyExc_StandardError, RuntimeError,
867 "Unspecified run-time error.");
868
869
870/*
871 * NotImplementedError extends RuntimeError
872 */
873SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
874 "Method or function hasn't been implemented yet.");
875
876/*
877 * NameError extends StandardError
878 */
879SimpleExtendsException(PyExc_StandardError, NameError,
880 "Name not found globally.");
881
882/*
883 * UnboundLocalError extends NameError
884 */
885SimpleExtendsException(PyExc_NameError, UnboundLocalError,
886 "Local name referenced but not bound to a value.");
887
888/*
889 * AttributeError extends StandardError
890 */
891SimpleExtendsException(PyExc_StandardError, AttributeError,
892 "Attribute not found.");
893
894
895/*
896 * SyntaxError extends StandardError
897 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000898
899static int
900SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
901{
902 PyObject *info = NULL;
903 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
904
905 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
906 return -1;
907
908 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000909 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000910 self->msg = PyTuple_GET_ITEM(args, 0);
911 Py_INCREF(self->msg);
912 }
913 if (lenargs == 2) {
914 info = PyTuple_GET_ITEM(args, 1);
915 info = PySequence_Tuple(info);
916 if (!info) return -1;
917
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000918 if (PyTuple_GET_SIZE(info) != 4) {
919 /* not a very good error message, but it's what Python 2.4 gives */
920 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
921 Py_DECREF(info);
922 return -1;
923 }
924
925 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926 self->filename = PyTuple_GET_ITEM(info, 0);
927 Py_INCREF(self->filename);
928
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000929 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000930 self->lineno = PyTuple_GET_ITEM(info, 1);
931 Py_INCREF(self->lineno);
932
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000933 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000934 self->offset = PyTuple_GET_ITEM(info, 2);
935 Py_INCREF(self->offset);
936
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000937 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000938 self->text = PyTuple_GET_ITEM(info, 3);
939 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000940
941 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000942 }
943 return 0;
944}
945
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000946static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947SyntaxError_clear(PySyntaxErrorObject *self)
948{
949 Py_CLEAR(self->msg);
950 Py_CLEAR(self->filename);
951 Py_CLEAR(self->lineno);
952 Py_CLEAR(self->offset);
953 Py_CLEAR(self->text);
954 Py_CLEAR(self->print_file_and_line);
955 return BaseException_clear((PyBaseExceptionObject *)self);
956}
957
958static void
959SyntaxError_dealloc(PySyntaxErrorObject *self)
960{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000961 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000962 SyntaxError_clear(self);
963 self->ob_type->tp_free((PyObject *)self);
964}
965
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000966static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
968{
969 Py_VISIT(self->msg);
970 Py_VISIT(self->filename);
971 Py_VISIT(self->lineno);
972 Py_VISIT(self->offset);
973 Py_VISIT(self->text);
974 Py_VISIT(self->print_file_and_line);
975 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
976}
977
978/* This is called "my_basename" instead of just "basename" to avoid name
979 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
980 defined, and Python does define that. */
981static char *
982my_basename(char *name)
983{
984 char *cp = name;
985 char *result = name;
986
987 if (name == NULL)
988 return "???";
989 while (*cp != '\0') {
990 if (*cp == SEP)
991 result = cp + 1;
992 ++cp;
993 }
994 return result;
995}
996
997
998static PyObject *
999SyntaxError_str(PySyntaxErrorObject *self)
1000{
1001 PyObject *str;
1002 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001003 int have_filename = 0;
1004 int have_lineno = 0;
1005 char *buffer = NULL;
1006 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001007
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001008 if (self->msg)
1009 str = PyObject_Str(self->msg);
1010 else
1011 str = PyObject_Str(Py_None);
1012 if (!str) return NULL;
1013 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1014 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001015
1016 /* XXX -- do all the additional formatting with filename and
1017 lineno here */
1018
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001019 have_filename = (self->filename != NULL) &&
1020 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001021 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001023 if (!have_filename && !have_lineno)
1024 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001025
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001026 bufsize = PyString_GET_SIZE(str) + 64;
1027 if (have_filename)
1028 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001030 buffer = PyMem_MALLOC(bufsize);
1031 if (buffer == NULL)
1032 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001033
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001034 if (have_filename && have_lineno)
1035 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1036 PyString_AS_STRING(str),
1037 my_basename(PyString_AS_STRING(self->filename)),
1038 PyInt_AsLong(self->lineno));
1039 else if (have_filename)
1040 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1041 PyString_AS_STRING(str),
1042 my_basename(PyString_AS_STRING(self->filename)));
1043 else /* only have_lineno */
1044 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1045 PyString_AS_STRING(str),
1046 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001047
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001048 result = PyString_FromString(buffer);
1049 PyMem_FREE(buffer);
1050
1051 if (result == NULL)
1052 result = str;
1053 else
1054 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001055 return result;
1056}
1057
1058static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001059 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1060 PyDoc_STR("exception msg")},
1061 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1062 PyDoc_STR("exception filename")},
1063 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1064 PyDoc_STR("exception lineno")},
1065 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1066 PyDoc_STR("exception offset")},
1067 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1068 PyDoc_STR("exception text")},
1069 {"print_file_and_line", T_OBJECT,
1070 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1071 PyDoc_STR("exception print_file_and_line")},
1072 {NULL} /* Sentinel */
1073};
1074
1075ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1076 SyntaxError_dealloc, 0, SyntaxError_members,
1077 SyntaxError_str, "Invalid syntax.");
1078
1079
1080/*
1081 * IndentationError extends SyntaxError
1082 */
1083MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1084 "Improper indentation.");
1085
1086
1087/*
1088 * TabError extends IndentationError
1089 */
1090MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1091 "Improper mixture of spaces and tabs.");
1092
1093
1094/*
1095 * LookupError extends StandardError
1096 */
1097SimpleExtendsException(PyExc_StandardError, LookupError,
1098 "Base class for lookup errors.");
1099
1100
1101/*
1102 * IndexError extends LookupError
1103 */
1104SimpleExtendsException(PyExc_LookupError, IndexError,
1105 "Sequence index out of range.");
1106
1107
1108/*
1109 * KeyError extends LookupError
1110 */
1111static PyObject *
1112KeyError_str(PyBaseExceptionObject *self)
1113{
1114 /* If args is a tuple of exactly one item, apply repr to args[0].
1115 This is done so that e.g. the exception raised by {}[''] prints
1116 KeyError: ''
1117 rather than the confusing
1118 KeyError
1119 alone. The downside is that if KeyError is raised with an explanatory
1120 string, that string will be displayed in quotes. Too bad.
1121 If args is anything else, use the default BaseException__str__().
1122 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001123 if (PyTuple_GET_SIZE(self->args) == 1) {
Walter Dörwald1ab83302007-05-18 17:15:44 +00001124 return PyObject_ReprStr8(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001125 }
1126 return BaseException_str(self);
1127}
1128
1129ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1130 0, 0, 0, KeyError_str, "Mapping key not found.");
1131
1132
1133/*
1134 * ValueError extends StandardError
1135 */
1136SimpleExtendsException(PyExc_StandardError, ValueError,
1137 "Inappropriate argument value (of correct type).");
1138
1139/*
1140 * UnicodeError extends ValueError
1141 */
1142
1143SimpleExtendsException(PyExc_ValueError, UnicodeError,
1144 "Unicode related error.");
1145
Thomas Wouters477c8d52006-05-27 19:21:47 +00001146static int
1147get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1148{
1149 if (!attr) {
1150 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1151 return -1;
1152 }
1153
Guido van Rossumddefaf32007-01-14 03:31:43 +00001154 if (PyLong_Check(attr)) {
1155 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001156 if (*value == -1 && PyErr_Occurred())
1157 return -1;
1158 } else {
1159 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1160 return -1;
1161 }
1162 return 0;
1163}
1164
1165static int
1166set_ssize_t(PyObject **attr, Py_ssize_t value)
1167{
1168 PyObject *obj = PyInt_FromSsize_t(value);
1169 if (!obj)
1170 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001171 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001172 *attr = obj;
1173 return 0;
1174}
1175
1176static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +00001177get_bytes(PyObject *attr, const char *name)
1178{
1179 if (!attr) {
1180 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1181 return NULL;
1182 }
1183
1184 if (!PyBytes_Check(attr)) {
1185 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1186 return NULL;
1187 }
1188 Py_INCREF(attr);
1189 return attr;
1190}
1191
1192static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193get_unicode(PyObject *attr, const char *name)
1194{
1195 if (!attr) {
1196 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1197 return NULL;
1198 }
1199
1200 if (!PyUnicode_Check(attr)) {
1201 PyErr_Format(PyExc_TypeError,
1202 "%.200s attribute must be unicode", name);
1203 return NULL;
1204 }
1205 Py_INCREF(attr);
1206 return attr;
1207}
1208
Walter Dörwaldd2034312007-05-18 16:29:38 +00001209static int
1210set_unicodefromstring(PyObject **attr, const char *value)
1211{
1212 PyObject *obj = PyUnicode_FromString(value);
1213 if (!obj)
1214 return -1;
1215 Py_CLEAR(*attr);
1216 *attr = obj;
1217 return 0;
1218}
1219
Thomas Wouters477c8d52006-05-27 19:21:47 +00001220PyObject *
1221PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1222{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001223 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001224}
1225
1226PyObject *
1227PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1228{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001229 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001230}
1231
1232PyObject *
1233PyUnicodeEncodeError_GetObject(PyObject *exc)
1234{
1235 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1236}
1237
1238PyObject *
1239PyUnicodeDecodeError_GetObject(PyObject *exc)
1240{
Walter Dörwald612344f2007-05-04 19:28:21 +00001241 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001242}
1243
1244PyObject *
1245PyUnicodeTranslateError_GetObject(PyObject *exc)
1246{
1247 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1248}
1249
1250int
1251PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1252{
1253 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1254 Py_ssize_t size;
1255 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1256 "object");
1257 if (!obj) return -1;
1258 size = PyUnicode_GET_SIZE(obj);
1259 if (*start<0)
1260 *start = 0; /*XXX check for values <0*/
1261 if (*start>=size)
1262 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001263 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001264 return 0;
1265 }
1266 return -1;
1267}
1268
1269
1270int
1271PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1272{
1273 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1274 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001275 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001276 "object");
1277 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001278 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001279 if (*start<0)
1280 *start = 0;
1281 if (*start>=size)
1282 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001283 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001284 return 0;
1285 }
1286 return -1;
1287}
1288
1289
1290int
1291PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1292{
1293 return PyUnicodeEncodeError_GetStart(exc, start);
1294}
1295
1296
1297int
1298PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1299{
1300 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1301}
1302
1303
1304int
1305PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1306{
1307 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1308}
1309
1310
1311int
1312PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1313{
1314 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1315}
1316
1317
1318int
1319PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1320{
1321 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1322 Py_ssize_t size;
1323 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1324 "object");
1325 if (!obj) return -1;
1326 size = PyUnicode_GET_SIZE(obj);
1327 if (*end<1)
1328 *end = 1;
1329 if (*end>size)
1330 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001331 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332 return 0;
1333 }
1334 return -1;
1335}
1336
1337
1338int
1339PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1340{
1341 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1342 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001343 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001344 "object");
1345 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001346 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001347 if (*end<1)
1348 *end = 1;
1349 if (*end>size)
1350 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001351 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352 return 0;
1353 }
1354 return -1;
1355}
1356
1357
1358int
1359PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1360{
1361 return PyUnicodeEncodeError_GetEnd(exc, start);
1362}
1363
1364
1365int
1366PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1367{
1368 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1369}
1370
1371
1372int
1373PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1374{
1375 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1376}
1377
1378
1379int
1380PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1381{
1382 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1383}
1384
1385PyObject *
1386PyUnicodeEncodeError_GetReason(PyObject *exc)
1387{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001388 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001389}
1390
1391
1392PyObject *
1393PyUnicodeDecodeError_GetReason(PyObject *exc)
1394{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001395 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001396}
1397
1398
1399PyObject *
1400PyUnicodeTranslateError_GetReason(PyObject *exc)
1401{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001402 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403}
1404
1405
1406int
1407PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1408{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001409 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1410 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411}
1412
1413
1414int
1415PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1416{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001417 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1418 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419}
1420
1421
1422int
1423PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1424{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001425 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1426 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427}
1428
1429
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430static int
1431UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1432 PyTypeObject *objecttype)
1433{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001434 Py_CLEAR(self->encoding);
1435 Py_CLEAR(self->object);
1436 Py_CLEAR(self->start);
1437 Py_CLEAR(self->end);
1438 Py_CLEAR(self->reason);
1439
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001441 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001442 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001443 &PyLong_Type, &self->start,
1444 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001445 &PyUnicode_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001446 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447 self->reason = NULL;
1448 return -1;
1449 }
1450
1451 Py_INCREF(self->encoding);
1452 Py_INCREF(self->object);
1453 Py_INCREF(self->start);
1454 Py_INCREF(self->end);
1455 Py_INCREF(self->reason);
1456
1457 return 0;
1458}
1459
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001460static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001461UnicodeError_clear(PyUnicodeErrorObject *self)
1462{
1463 Py_CLEAR(self->encoding);
1464 Py_CLEAR(self->object);
1465 Py_CLEAR(self->start);
1466 Py_CLEAR(self->end);
1467 Py_CLEAR(self->reason);
1468 return BaseException_clear((PyBaseExceptionObject *)self);
1469}
1470
1471static void
1472UnicodeError_dealloc(PyUnicodeErrorObject *self)
1473{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001474 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475 UnicodeError_clear(self);
1476 self->ob_type->tp_free((PyObject *)self);
1477}
1478
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001479static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001480UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1481{
1482 Py_VISIT(self->encoding);
1483 Py_VISIT(self->object);
1484 Py_VISIT(self->start);
1485 Py_VISIT(self->end);
1486 Py_VISIT(self->reason);
1487 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1488}
1489
1490static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001491 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1492 PyDoc_STR("exception encoding")},
1493 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1494 PyDoc_STR("exception object")},
1495 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1496 PyDoc_STR("exception start")},
1497 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1498 PyDoc_STR("exception end")},
1499 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1500 PyDoc_STR("exception reason")},
1501 {NULL} /* Sentinel */
1502};
1503
1504
1505/*
1506 * UnicodeEncodeError extends UnicodeError
1507 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001508
1509static int
1510UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1511{
1512 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1513 return -1;
1514 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1515 kwds, &PyUnicode_Type);
1516}
1517
1518static PyObject *
1519UnicodeEncodeError_str(PyObject *self)
1520{
1521 Py_ssize_t start;
1522 Py_ssize_t end;
1523
1524 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001525 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526
1527 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001528 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001529
1530 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001531 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1532 char badchar_str[20];
1533 if (badchar <= 0xff)
1534 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1535 else if (badchar <= 0xffff)
1536 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1537 else
1538 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001539 return PyUnicode_FromFormat(
1540 "'%U' codec can't encode character u'\\%s' in position %zd: %U",
1541 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001542 badchar_str,
1543 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001544 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001545 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001547 return PyUnicode_FromFormat(
1548 "'%U' codec can't encode characters in position %zd-%zd: %U",
1549 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 start,
1551 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001552 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001553 );
1554}
1555
1556static PyTypeObject _PyExc_UnicodeEncodeError = {
1557 PyObject_HEAD_INIT(NULL)
1558 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001559 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560 sizeof(PyUnicodeErrorObject), 0,
1561 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1562 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1563 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001564 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1565 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001566 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001567 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568};
1569PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1570
1571PyObject *
1572PyUnicodeEncodeError_Create(
1573 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1574 Py_ssize_t start, Py_ssize_t end, const char *reason)
1575{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001576 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001577 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001578}
1579
1580
1581/*
1582 * UnicodeDecodeError extends UnicodeError
1583 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001584
1585static int
1586UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1587{
1588 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1589 return -1;
1590 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001591 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001592}
1593
1594static PyObject *
1595UnicodeDecodeError_str(PyObject *self)
1596{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001597 Py_ssize_t start = 0;
1598 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599
1600 if (PyUnicodeDecodeError_GetStart(self, &start))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001601 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001602
1603 if (PyUnicodeDecodeError_GetEnd(self, &end))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001604 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605
1606 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001607 /* FromFormat does not support %02x, so format that separately */
1608 char byte[4];
1609 PyOS_snprintf(byte, sizeof(byte), "%02x",
Walter Dörwald612344f2007-05-04 19:28:21 +00001610 ((int)PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001611 return PyUnicode_FromFormat(
1612 "'%U' codec can't decode byte 0x%s in position %zd: %U",
1613 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001614 byte,
1615 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001616 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001617 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001619 return PyUnicode_FromFormat(
1620 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1621 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001622 start,
1623 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001624 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001625 );
1626}
1627
1628static PyTypeObject _PyExc_UnicodeDecodeError = {
1629 PyObject_HEAD_INIT(NULL)
1630 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001631 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001632 sizeof(PyUnicodeErrorObject), 0,
1633 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1634 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1635 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001636 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1637 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001638 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001639 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001640};
1641PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1642
1643PyObject *
1644PyUnicodeDecodeError_Create(
1645 const char *encoding, const char *object, Py_ssize_t length,
1646 Py_ssize_t start, Py_ssize_t end, const char *reason)
1647{
1648 assert(length < INT_MAX);
1649 assert(start < INT_MAX);
1650 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001651 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001652 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653}
1654
1655
1656/*
1657 * UnicodeTranslateError extends UnicodeError
1658 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659
1660static int
1661UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1662 PyObject *kwds)
1663{
1664 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1665 return -1;
1666
1667 Py_CLEAR(self->object);
1668 Py_CLEAR(self->start);
1669 Py_CLEAR(self->end);
1670 Py_CLEAR(self->reason);
1671
1672 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1673 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001674 &PyLong_Type, &self->start,
1675 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001676 &PyUnicode_Type, &self->reason)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001677 self->object = self->start = self->end = self->reason = NULL;
1678 return -1;
1679 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001680
Thomas Wouters477c8d52006-05-27 19:21:47 +00001681 Py_INCREF(self->object);
1682 Py_INCREF(self->start);
1683 Py_INCREF(self->end);
1684 Py_INCREF(self->reason);
1685
1686 return 0;
1687}
1688
1689
1690static PyObject *
1691UnicodeTranslateError_str(PyObject *self)
1692{
1693 Py_ssize_t start;
1694 Py_ssize_t end;
1695
1696 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001697 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001698
1699 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001700 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001701
1702 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001703 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1704 char badchar_str[20];
1705 if (badchar <= 0xff)
1706 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1707 else if (badchar <= 0xffff)
1708 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1709 else
1710 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001711 return PyUnicode_FromFormat(
1712 "can't translate character u'\\%s' in position %zd: %U",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001713 badchar_str,
1714 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001715 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001716 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001718 return PyUnicode_FromFormat(
1719 "can't translate characters in position %zd-%zd: %U",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720 start,
1721 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001722 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001723 );
1724}
1725
1726static PyTypeObject _PyExc_UnicodeTranslateError = {
1727 PyObject_HEAD_INIT(NULL)
1728 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001729 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730 sizeof(PyUnicodeErrorObject), 0,
1731 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1732 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1733 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001734 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001735 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1736 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001737 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001738};
1739PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1740
1741PyObject *
1742PyUnicodeTranslateError_Create(
1743 const Py_UNICODE *object, Py_ssize_t length,
1744 Py_ssize_t start, Py_ssize_t end, const char *reason)
1745{
1746 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001747 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001749
1750
1751/*
1752 * AssertionError extends StandardError
1753 */
1754SimpleExtendsException(PyExc_StandardError, AssertionError,
1755 "Assertion failed.");
1756
1757
1758/*
1759 * ArithmeticError extends StandardError
1760 */
1761SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1762 "Base class for arithmetic errors.");
1763
1764
1765/*
1766 * FloatingPointError extends ArithmeticError
1767 */
1768SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1769 "Floating point operation failed.");
1770
1771
1772/*
1773 * OverflowError extends ArithmeticError
1774 */
1775SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1776 "Result too large to be represented.");
1777
1778
1779/*
1780 * ZeroDivisionError extends ArithmeticError
1781 */
1782SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1783 "Second argument to a division or modulo operation was zero.");
1784
1785
1786/*
1787 * SystemError extends StandardError
1788 */
1789SimpleExtendsException(PyExc_StandardError, SystemError,
1790 "Internal error in the Python interpreter.\n"
1791 "\n"
1792 "Please report this to the Python maintainer, along with the traceback,\n"
1793 "the Python version, and the hardware/OS platform and version.");
1794
1795
1796/*
1797 * ReferenceError extends StandardError
1798 */
1799SimpleExtendsException(PyExc_StandardError, ReferenceError,
1800 "Weak ref proxy used after referent went away.");
1801
1802
1803/*
1804 * MemoryError extends StandardError
1805 */
1806SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1807
1808
1809/* Warning category docstrings */
1810
1811/*
1812 * Warning extends Exception
1813 */
1814SimpleExtendsException(PyExc_Exception, Warning,
1815 "Base class for warning categories.");
1816
1817
1818/*
1819 * UserWarning extends Warning
1820 */
1821SimpleExtendsException(PyExc_Warning, UserWarning,
1822 "Base class for warnings generated by user code.");
1823
1824
1825/*
1826 * DeprecationWarning extends Warning
1827 */
1828SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1829 "Base class for warnings about deprecated features.");
1830
1831
1832/*
1833 * PendingDeprecationWarning extends Warning
1834 */
1835SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1836 "Base class for warnings about features which will be deprecated\n"
1837 "in the future.");
1838
1839
1840/*
1841 * SyntaxWarning extends Warning
1842 */
1843SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1844 "Base class for warnings about dubious syntax.");
1845
1846
1847/*
1848 * RuntimeWarning extends Warning
1849 */
1850SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1851 "Base class for warnings about dubious runtime behavior.");
1852
1853
1854/*
1855 * FutureWarning extends Warning
1856 */
1857SimpleExtendsException(PyExc_Warning, FutureWarning,
1858 "Base class for warnings about constructs that will change semantically\n"
1859 "in the future.");
1860
1861
1862/*
1863 * ImportWarning extends Warning
1864 */
1865SimpleExtendsException(PyExc_Warning, ImportWarning,
1866 "Base class for warnings about probable mistakes in module imports");
1867
1868
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001869/*
1870 * UnicodeWarning extends Warning
1871 */
1872SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1873 "Base class for warnings about Unicode related problems, mostly\n"
1874 "related to conversion problems.");
1875
1876
Thomas Wouters477c8d52006-05-27 19:21:47 +00001877/* Pre-computed MemoryError instance. Best to create this as early as
1878 * possible and not wait until a MemoryError is actually raised!
1879 */
1880PyObject *PyExc_MemoryErrorInst=NULL;
1881
Thomas Wouters477c8d52006-05-27 19:21:47 +00001882#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1883 Py_FatalError("exceptions bootstrapping error.");
1884
1885#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001886 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1887 Py_FatalError("Module dictionary insertion problem.");
1888
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001889#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1890/* crt variable checking in VisualStudio .NET 2005 */
1891#include <crtdbg.h>
1892
1893static int prevCrtReportMode;
1894static _invalid_parameter_handler prevCrtHandler;
1895
1896/* Invalid parameter handler. Sets a ValueError exception */
1897static void
1898InvalidParameterHandler(
1899 const wchar_t * expression,
1900 const wchar_t * function,
1901 const wchar_t * file,
1902 unsigned int line,
1903 uintptr_t pReserved)
1904{
1905 /* Do nothing, allow execution to continue. Usually this
1906 * means that the CRT will set errno to EINVAL
1907 */
1908}
1909#endif
1910
1911
Thomas Wouters477c8d52006-05-27 19:21:47 +00001912PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001913_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001914{
Neal Norwitz2633c692007-02-26 22:22:47 +00001915 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001916
1917 PRE_INIT(BaseException)
1918 PRE_INIT(Exception)
1919 PRE_INIT(StandardError)
1920 PRE_INIT(TypeError)
1921 PRE_INIT(StopIteration)
1922 PRE_INIT(GeneratorExit)
1923 PRE_INIT(SystemExit)
1924 PRE_INIT(KeyboardInterrupt)
1925 PRE_INIT(ImportError)
1926 PRE_INIT(EnvironmentError)
1927 PRE_INIT(IOError)
1928 PRE_INIT(OSError)
1929#ifdef MS_WINDOWS
1930 PRE_INIT(WindowsError)
1931#endif
1932#ifdef __VMS
1933 PRE_INIT(VMSError)
1934#endif
1935 PRE_INIT(EOFError)
1936 PRE_INIT(RuntimeError)
1937 PRE_INIT(NotImplementedError)
1938 PRE_INIT(NameError)
1939 PRE_INIT(UnboundLocalError)
1940 PRE_INIT(AttributeError)
1941 PRE_INIT(SyntaxError)
1942 PRE_INIT(IndentationError)
1943 PRE_INIT(TabError)
1944 PRE_INIT(LookupError)
1945 PRE_INIT(IndexError)
1946 PRE_INIT(KeyError)
1947 PRE_INIT(ValueError)
1948 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001949 PRE_INIT(UnicodeEncodeError)
1950 PRE_INIT(UnicodeDecodeError)
1951 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001952 PRE_INIT(AssertionError)
1953 PRE_INIT(ArithmeticError)
1954 PRE_INIT(FloatingPointError)
1955 PRE_INIT(OverflowError)
1956 PRE_INIT(ZeroDivisionError)
1957 PRE_INIT(SystemError)
1958 PRE_INIT(ReferenceError)
1959 PRE_INIT(MemoryError)
1960 PRE_INIT(Warning)
1961 PRE_INIT(UserWarning)
1962 PRE_INIT(DeprecationWarning)
1963 PRE_INIT(PendingDeprecationWarning)
1964 PRE_INIT(SyntaxWarning)
1965 PRE_INIT(RuntimeWarning)
1966 PRE_INIT(FutureWarning)
1967 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001968 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001969
Thomas Wouters477c8d52006-05-27 19:21:47 +00001970 bltinmod = PyImport_ImportModule("__builtin__");
1971 if (bltinmod == NULL)
1972 Py_FatalError("exceptions bootstrapping error.");
1973 bdict = PyModule_GetDict(bltinmod);
1974 if (bdict == NULL)
1975 Py_FatalError("exceptions bootstrapping error.");
1976
1977 POST_INIT(BaseException)
1978 POST_INIT(Exception)
1979 POST_INIT(StandardError)
1980 POST_INIT(TypeError)
1981 POST_INIT(StopIteration)
1982 POST_INIT(GeneratorExit)
1983 POST_INIT(SystemExit)
1984 POST_INIT(KeyboardInterrupt)
1985 POST_INIT(ImportError)
1986 POST_INIT(EnvironmentError)
1987 POST_INIT(IOError)
1988 POST_INIT(OSError)
1989#ifdef MS_WINDOWS
1990 POST_INIT(WindowsError)
1991#endif
1992#ifdef __VMS
1993 POST_INIT(VMSError)
1994#endif
1995 POST_INIT(EOFError)
1996 POST_INIT(RuntimeError)
1997 POST_INIT(NotImplementedError)
1998 POST_INIT(NameError)
1999 POST_INIT(UnboundLocalError)
2000 POST_INIT(AttributeError)
2001 POST_INIT(SyntaxError)
2002 POST_INIT(IndentationError)
2003 POST_INIT(TabError)
2004 POST_INIT(LookupError)
2005 POST_INIT(IndexError)
2006 POST_INIT(KeyError)
2007 POST_INIT(ValueError)
2008 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002009 POST_INIT(UnicodeEncodeError)
2010 POST_INIT(UnicodeDecodeError)
2011 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002012 POST_INIT(AssertionError)
2013 POST_INIT(ArithmeticError)
2014 POST_INIT(FloatingPointError)
2015 POST_INIT(OverflowError)
2016 POST_INIT(ZeroDivisionError)
2017 POST_INIT(SystemError)
2018 POST_INIT(ReferenceError)
2019 POST_INIT(MemoryError)
2020 POST_INIT(Warning)
2021 POST_INIT(UserWarning)
2022 POST_INIT(DeprecationWarning)
2023 POST_INIT(PendingDeprecationWarning)
2024 POST_INIT(SyntaxWarning)
2025 POST_INIT(RuntimeWarning)
2026 POST_INIT(FutureWarning)
2027 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002028 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029
2030 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2031 if (!PyExc_MemoryErrorInst)
2032 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2033
2034 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002035
2036#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2037 /* Set CRT argument error handler */
2038 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2039 /* turn off assertions in debug mode */
2040 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2041#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002042}
2043
2044void
2045_PyExc_Fini(void)
2046{
2047 Py_XDECREF(PyExc_MemoryErrorInst);
2048 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002049#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2050 /* reset CRT error handling */
2051 _set_invalid_parameter_handler(prevCrtHandler);
2052 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2053#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002054}