blob: 36e37955dc376028ec20c08d3d4cd52137e8695b [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 PyObject *repr_suffix;
102 PyObject *repr;
103 char *name;
104 char *dot;
105
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000106 repr_suffix = PyObject_Repr(self->args);
107 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000108 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000109
110 name = (char *)self->ob_type->tp_name;
111 dot = strrchr(name, '.');
112 if (dot != NULL) name = dot+1;
113
114 repr = PyString_FromString(name);
115 if (!repr) {
116 Py_DECREF(repr_suffix);
117 return NULL;
118 }
119
120 PyString_ConcatAndDel(&repr, repr_suffix);
121 return repr;
122}
123
124/* Pickling support */
125static PyObject *
126BaseException_reduce(PyBaseExceptionObject *self)
127{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000128 if (self->args && self->dict)
129 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
130 else
131 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132}
133
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000134/*
135 * Needed for backward compatibility, since exceptions used to store
136 * all their attributes in the __dict__. Code is taken from cPickle's
137 * load_build function.
138 */
139static PyObject *
140BaseException_setstate(PyObject *self, PyObject *state)
141{
142 PyObject *d_key, *d_value;
143 Py_ssize_t i = 0;
144
145 if (state != Py_None) {
146 if (!PyDict_Check(state)) {
147 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
148 return NULL;
149 }
150 while (PyDict_Next(state, &i, &d_key, &d_value)) {
151 if (PyObject_SetAttr(self, d_key, d_value) < 0)
152 return NULL;
153 }
154 }
155 Py_RETURN_NONE;
156}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000157
Thomas Wouters477c8d52006-05-27 19:21:47 +0000158
159static PyMethodDef BaseException_methods[] = {
160 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000161 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000162 {NULL, NULL, 0, NULL},
163};
164
165
Thomas Wouters477c8d52006-05-27 19:21:47 +0000166static PyObject *
167BaseException_get_dict(PyBaseExceptionObject *self)
168{
169 if (self->dict == NULL) {
170 self->dict = PyDict_New();
171 if (!self->dict)
172 return NULL;
173 }
174 Py_INCREF(self->dict);
175 return self->dict;
176}
177
178static int
179BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
180{
181 if (val == NULL) {
182 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
183 return -1;
184 }
185 if (!PyDict_Check(val)) {
186 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
187 return -1;
188 }
189 Py_CLEAR(self->dict);
190 Py_INCREF(val);
191 self->dict = val;
192 return 0;
193}
194
195static PyObject *
196BaseException_get_args(PyBaseExceptionObject *self)
197{
198 if (self->args == NULL) {
199 Py_INCREF(Py_None);
200 return Py_None;
201 }
202 Py_INCREF(self->args);
203 return self->args;
204}
205
206static int
207BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
208{
209 PyObject *seq;
210 if (val == NULL) {
211 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
212 return -1;
213 }
214 seq = PySequence_Tuple(val);
215 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000216 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000217 self->args = seq;
218 return 0;
219}
220
Guido van Rossum360e4b82007-05-14 22:51:27 +0000221
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222static PyGetSetDef BaseException_getset[] = {
223 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
224 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
225 {NULL},
226};
227
228
229static PyTypeObject _PyExc_BaseException = {
230 PyObject_HEAD_INIT(NULL)
231 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000232 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000233 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
234 0, /*tp_itemsize*/
235 (destructor)BaseException_dealloc, /*tp_dealloc*/
236 0, /*tp_print*/
237 0, /*tp_getattr*/
238 0, /*tp_setattr*/
239 0, /* tp_compare; */
240 (reprfunc)BaseException_repr, /*tp_repr*/
241 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000242 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000243 0, /*tp_as_mapping*/
244 0, /*tp_hash */
245 0, /*tp_call*/
246 (reprfunc)BaseException_str, /*tp_str*/
247 PyObject_GenericGetAttr, /*tp_getattro*/
248 PyObject_GenericSetAttr, /*tp_setattro*/
249 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000250 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
251 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000252 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
253 (traverseproc)BaseException_traverse, /* tp_traverse */
254 (inquiry)BaseException_clear, /* tp_clear */
255 0, /* tp_richcompare */
256 0, /* tp_weaklistoffset */
257 0, /* tp_iter */
258 0, /* tp_iternext */
259 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000260 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000261 BaseException_getset, /* tp_getset */
262 0, /* tp_base */
263 0, /* tp_dict */
264 0, /* tp_descr_get */
265 0, /* tp_descr_set */
266 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
267 (initproc)BaseException_init, /* tp_init */
268 0, /* tp_alloc */
269 BaseException_new, /* tp_new */
270};
271/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
272from the previous implmentation and also allowing Python objects to be used
273in the API */
274PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
275
276/* note these macros omit the last semicolon so the macro invocation may
277 * include it and not look strange.
278 */
279#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
280static PyTypeObject _PyExc_ ## EXCNAME = { \
281 PyObject_HEAD_INIT(NULL) \
282 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000283 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000284 sizeof(PyBaseExceptionObject), \
285 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
286 0, 0, 0, 0, 0, 0, 0, \
287 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
288 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
289 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
290 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
291 (initproc)BaseException_init, 0, BaseException_new,\
292}; \
293PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
294
295#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
296static PyTypeObject _PyExc_ ## EXCNAME = { \
297 PyObject_HEAD_INIT(NULL) \
298 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000299 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000300 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000301 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000302 0, 0, 0, 0, 0, \
303 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000304 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
305 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000306 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000307 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000308}; \
309PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
310
311#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
312static PyTypeObject _PyExc_ ## EXCNAME = { \
313 PyObject_HEAD_INIT(NULL) \
314 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000315 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316 sizeof(Py ## EXCSTORE ## Object), 0, \
317 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
318 (reprfunc)EXCSTR, 0, 0, 0, \
319 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
320 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
321 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
322 EXCMEMBERS, 0, &_ ## EXCBASE, \
323 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000324 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325}; \
326PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
327
328
329/*
330 * Exception extends BaseException
331 */
332SimpleExtendsException(PyExc_BaseException, Exception,
333 "Common base class for all non-exit exceptions.");
334
335
336/*
337 * StandardError extends Exception
338 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000339SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340 "Base class for all standard Python exceptions that do not represent\n"
341 "interpreter exiting.");
342
343
344/*
345 * TypeError extends StandardError
346 */
347SimpleExtendsException(PyExc_StandardError, TypeError,
348 "Inappropriate argument type.");
349
350
351/*
352 * StopIteration extends Exception
353 */
354SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000355 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000356
357
358/*
359 * GeneratorExit extends Exception
360 */
361SimpleExtendsException(PyExc_Exception, GeneratorExit,
362 "Request that a generator exit.");
363
364
365/*
366 * SystemExit extends BaseException
367 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000368
369static int
370SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
371{
372 Py_ssize_t size = PyTuple_GET_SIZE(args);
373
374 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
375 return -1;
376
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000377 if (size == 0)
378 return 0;
379 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000380 if (size == 1)
381 self->code = PyTuple_GET_ITEM(args, 0);
382 else if (size > 1)
383 self->code = args;
384 Py_INCREF(self->code);
385 return 0;
386}
387
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000388static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389SystemExit_clear(PySystemExitObject *self)
390{
391 Py_CLEAR(self->code);
392 return BaseException_clear((PyBaseExceptionObject *)self);
393}
394
395static void
396SystemExit_dealloc(PySystemExitObject *self)
397{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000398 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399 SystemExit_clear(self);
400 self->ob_type->tp_free((PyObject *)self);
401}
402
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000403static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
405{
406 Py_VISIT(self->code);
407 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
408}
409
410static PyMemberDef SystemExit_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
412 PyDoc_STR("exception code")},
413 {NULL} /* Sentinel */
414};
415
416ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
417 SystemExit_dealloc, 0, SystemExit_members, 0,
418 "Request to exit from the interpreter.");
419
420/*
421 * KeyboardInterrupt extends BaseException
422 */
423SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
424 "Program interrupted by user.");
425
426
427/*
428 * ImportError extends StandardError
429 */
430SimpleExtendsException(PyExc_StandardError, ImportError,
431 "Import can't find module, or can't find name in module.");
432
433
434/*
435 * EnvironmentError extends StandardError
436 */
437
Thomas Wouters477c8d52006-05-27 19:21:47 +0000438/* Where a function has a single filename, such as open() or some
439 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
440 * called, giving a third argument which is the filename. But, so
441 * that old code using in-place unpacking doesn't break, e.g.:
442 *
443 * except IOError, (errno, strerror):
444 *
445 * we hack args so that it only contains two items. This also
446 * means we need our own __str__() which prints out the filename
447 * when it was supplied.
448 */
449static int
450EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
451 PyObject *kwds)
452{
453 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
454 PyObject *subslice = NULL;
455
456 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
457 return -1;
458
Thomas Wouters89f507f2006-12-13 04:49:30 +0000459 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460 return 0;
461 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000462
463 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464 &myerrno, &strerror, &filename)) {
465 return -1;
466 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000467 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000468 self->myerrno = myerrno;
469 Py_INCREF(self->myerrno);
470
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000471 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472 self->strerror = strerror;
473 Py_INCREF(self->strerror);
474
475 /* self->filename will remain Py_None otherwise */
476 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000477 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478 self->filename = filename;
479 Py_INCREF(self->filename);
480
481 subslice = PyTuple_GetSlice(args, 0, 2);
482 if (!subslice)
483 return -1;
484
485 Py_DECREF(self->args); /* replacing args */
486 self->args = subslice;
487 }
488 return 0;
489}
490
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000491static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492EnvironmentError_clear(PyEnvironmentErrorObject *self)
493{
494 Py_CLEAR(self->myerrno);
495 Py_CLEAR(self->strerror);
496 Py_CLEAR(self->filename);
497 return BaseException_clear((PyBaseExceptionObject *)self);
498}
499
500static void
501EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
502{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000503 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504 EnvironmentError_clear(self);
505 self->ob_type->tp_free((PyObject *)self);
506}
507
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000508static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000509EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
510 void *arg)
511{
512 Py_VISIT(self->myerrno);
513 Py_VISIT(self->strerror);
514 Py_VISIT(self->filename);
515 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
516}
517
518static PyObject *
519EnvironmentError_str(PyEnvironmentErrorObject *self)
520{
521 PyObject *rtnval = NULL;
522
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000523 if (self->filename) {
524 PyObject *fmt;
525 PyObject *repr;
526 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000528 fmt = PyString_FromString("[Errno %s] %s: %s");
529 if (!fmt)
530 return NULL;
531
532 repr = PyObject_Repr(self->filename);
533 if (!repr) {
534 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000535 return NULL;
536 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000537 tuple = PyTuple_New(3);
538 if (!tuple) {
539 Py_DECREF(repr);
540 Py_DECREF(fmt);
541 return NULL;
542 }
543
544 if (self->myerrno) {
545 Py_INCREF(self->myerrno);
546 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
547 }
548 else {
549 Py_INCREF(Py_None);
550 PyTuple_SET_ITEM(tuple, 0, Py_None);
551 }
552 if (self->strerror) {
553 Py_INCREF(self->strerror);
554 PyTuple_SET_ITEM(tuple, 1, self->strerror);
555 }
556 else {
557 Py_INCREF(Py_None);
558 PyTuple_SET_ITEM(tuple, 1, Py_None);
559 }
560
Thomas Wouters477c8d52006-05-27 19:21:47 +0000561 PyTuple_SET_ITEM(tuple, 2, repr);
562
563 rtnval = PyString_Format(fmt, tuple);
564
565 Py_DECREF(fmt);
566 Py_DECREF(tuple);
567 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000568 else if (self->myerrno && self->strerror) {
569 PyObject *fmt;
570 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000571
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000572 fmt = PyString_FromString("[Errno %s] %s");
573 if (!fmt)
574 return NULL;
575
576 tuple = PyTuple_New(2);
577 if (!tuple) {
578 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000579 return NULL;
580 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000581
582 if (self->myerrno) {
583 Py_INCREF(self->myerrno);
584 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
585 }
586 else {
587 Py_INCREF(Py_None);
588 PyTuple_SET_ITEM(tuple, 0, Py_None);
589 }
590 if (self->strerror) {
591 Py_INCREF(self->strerror);
592 PyTuple_SET_ITEM(tuple, 1, self->strerror);
593 }
594 else {
595 Py_INCREF(Py_None);
596 PyTuple_SET_ITEM(tuple, 1, Py_None);
597 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000598
599 rtnval = PyString_Format(fmt, tuple);
600
601 Py_DECREF(fmt);
602 Py_DECREF(tuple);
603 }
604 else
605 rtnval = BaseException_str((PyBaseExceptionObject *)self);
606
607 return rtnval;
608}
609
610static PyMemberDef EnvironmentError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
612 PyDoc_STR("exception errno")},
613 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
614 PyDoc_STR("exception strerror")},
615 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
616 PyDoc_STR("exception filename")},
617 {NULL} /* Sentinel */
618};
619
620
621static PyObject *
622EnvironmentError_reduce(PyEnvironmentErrorObject *self)
623{
624 PyObject *args = self->args;
625 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000626
Thomas Wouters477c8d52006-05-27 19:21:47 +0000627 /* self->args is only the first two real arguments if there was a
628 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000629 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630 args = PyTuple_New(3);
631 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000632
633 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000634 Py_INCREF(tmp);
635 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000636
637 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638 Py_INCREF(tmp);
639 PyTuple_SET_ITEM(args, 1, tmp);
640
641 Py_INCREF(self->filename);
642 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000643 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000644 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000645
646 if (self->dict)
647 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
648 else
649 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000650 Py_DECREF(args);
651 return res;
652}
653
654
655static PyMethodDef EnvironmentError_methods[] = {
656 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
657 {NULL}
658};
659
660ComplexExtendsException(PyExc_StandardError, EnvironmentError,
661 EnvironmentError, EnvironmentError_dealloc,
662 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000663 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664 "Base class for I/O related errors.");
665
666
667/*
668 * IOError extends EnvironmentError
669 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000670MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671 EnvironmentError, "I/O operation failed.");
672
673
674/*
675 * OSError extends EnvironmentError
676 */
677MiddlingExtendsException(PyExc_EnvironmentError, OSError,
678 EnvironmentError, "OS system call failed.");
679
680
681/*
682 * WindowsError extends OSError
683 */
684#ifdef MS_WINDOWS
685#include "errmap.h"
686
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000687static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688WindowsError_clear(PyWindowsErrorObject *self)
689{
690 Py_CLEAR(self->myerrno);
691 Py_CLEAR(self->strerror);
692 Py_CLEAR(self->filename);
693 Py_CLEAR(self->winerror);
694 return BaseException_clear((PyBaseExceptionObject *)self);
695}
696
697static void
698WindowsError_dealloc(PyWindowsErrorObject *self)
699{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000700 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000701 WindowsError_clear(self);
702 self->ob_type->tp_free((PyObject *)self);
703}
704
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000705static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000706WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
707{
708 Py_VISIT(self->myerrno);
709 Py_VISIT(self->strerror);
710 Py_VISIT(self->filename);
711 Py_VISIT(self->winerror);
712 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
713}
714
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715static int
716WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
717{
718 PyObject *o_errcode = NULL;
719 long errcode;
720 long posix_errno;
721
722 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
723 == -1)
724 return -1;
725
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000726 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000728
729 /* Set errno to the POSIX errno, and winerror to the Win32
730 error code. */
731 errcode = PyInt_AsLong(self->myerrno);
732 if (errcode == -1 && PyErr_Occurred())
733 return -1;
734 posix_errno = winerror_to_errno(errcode);
735
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000736 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000737 self->winerror = self->myerrno;
738
739 o_errcode = PyInt_FromLong(posix_errno);
740 if (!o_errcode)
741 return -1;
742
743 self->myerrno = o_errcode;
744
745 return 0;
746}
747
748
749static PyObject *
750WindowsError_str(PyWindowsErrorObject *self)
751{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000752 PyObject *rtnval = NULL;
753
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000754 if (self->filename) {
755 PyObject *fmt;
756 PyObject *repr;
757 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000759 fmt = PyString_FromString("[Error %s] %s: %s");
760 if (!fmt)
761 return NULL;
762
763 repr = PyObject_Repr(self->filename);
764 if (!repr) {
765 Py_DECREF(fmt);
766 return NULL;
767 }
768 tuple = PyTuple_New(3);
769 if (!tuple) {
770 Py_DECREF(repr);
771 Py_DECREF(fmt);
772 return NULL;
773 }
774
Thomas Wouters89f507f2006-12-13 04:49:30 +0000775 if (self->winerror) {
776 Py_INCREF(self->winerror);
777 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000778 }
779 else {
780 Py_INCREF(Py_None);
781 PyTuple_SET_ITEM(tuple, 0, Py_None);
782 }
783 if (self->strerror) {
784 Py_INCREF(self->strerror);
785 PyTuple_SET_ITEM(tuple, 1, self->strerror);
786 }
787 else {
788 Py_INCREF(Py_None);
789 PyTuple_SET_ITEM(tuple, 1, Py_None);
790 }
791
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000792 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793
794 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000795
796 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797 Py_DECREF(tuple);
798 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000799 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000800 PyObject *fmt;
801 PyObject *tuple;
802
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 fmt = PyString_FromString("[Error %s] %s");
804 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000805 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000806
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000807 tuple = PyTuple_New(2);
808 if (!tuple) {
809 Py_DECREF(fmt);
810 return NULL;
811 }
812
Thomas Wouters89f507f2006-12-13 04:49:30 +0000813 if (self->winerror) {
814 Py_INCREF(self->winerror);
815 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 }
817 else {
818 Py_INCREF(Py_None);
819 PyTuple_SET_ITEM(tuple, 0, Py_None);
820 }
821 if (self->strerror) {
822 Py_INCREF(self->strerror);
823 PyTuple_SET_ITEM(tuple, 1, self->strerror);
824 }
825 else {
826 Py_INCREF(Py_None);
827 PyTuple_SET_ITEM(tuple, 1, Py_None);
828 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829
830 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000831
832 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000833 Py_DECREF(tuple);
834 }
835 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000836 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837
Thomas Wouters477c8d52006-05-27 19:21:47 +0000838 return rtnval;
839}
840
841static PyMemberDef WindowsError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
843 PyDoc_STR("POSIX exception code")},
844 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
845 PyDoc_STR("exception strerror")},
846 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
847 PyDoc_STR("exception filename")},
848 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
849 PyDoc_STR("Win32 exception code")},
850 {NULL} /* Sentinel */
851};
852
853ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
854 WindowsError_dealloc, 0, WindowsError_members,
855 WindowsError_str, "MS-Windows OS system call failed.");
856
857#endif /* MS_WINDOWS */
858
859
860/*
861 * VMSError extends OSError (I think)
862 */
863#ifdef __VMS
864MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
865 "OpenVMS OS system call failed.");
866#endif
867
868
869/*
870 * EOFError extends StandardError
871 */
872SimpleExtendsException(PyExc_StandardError, EOFError,
873 "Read beyond end of file.");
874
875
876/*
877 * RuntimeError extends StandardError
878 */
879SimpleExtendsException(PyExc_StandardError, RuntimeError,
880 "Unspecified run-time error.");
881
882
883/*
884 * NotImplementedError extends RuntimeError
885 */
886SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
887 "Method or function hasn't been implemented yet.");
888
889/*
890 * NameError extends StandardError
891 */
892SimpleExtendsException(PyExc_StandardError, NameError,
893 "Name not found globally.");
894
895/*
896 * UnboundLocalError extends NameError
897 */
898SimpleExtendsException(PyExc_NameError, UnboundLocalError,
899 "Local name referenced but not bound to a value.");
900
901/*
902 * AttributeError extends StandardError
903 */
904SimpleExtendsException(PyExc_StandardError, AttributeError,
905 "Attribute not found.");
906
907
908/*
909 * SyntaxError extends StandardError
910 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911
912static int
913SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
914{
915 PyObject *info = NULL;
916 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
917
918 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
919 return -1;
920
921 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000922 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923 self->msg = PyTuple_GET_ITEM(args, 0);
924 Py_INCREF(self->msg);
925 }
926 if (lenargs == 2) {
927 info = PyTuple_GET_ITEM(args, 1);
928 info = PySequence_Tuple(info);
929 if (!info) return -1;
930
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000931 if (PyTuple_GET_SIZE(info) != 4) {
932 /* not a very good error message, but it's what Python 2.4 gives */
933 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
934 Py_DECREF(info);
935 return -1;
936 }
937
938 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 self->filename = PyTuple_GET_ITEM(info, 0);
940 Py_INCREF(self->filename);
941
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000942 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943 self->lineno = PyTuple_GET_ITEM(info, 1);
944 Py_INCREF(self->lineno);
945
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000946 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947 self->offset = PyTuple_GET_ITEM(info, 2);
948 Py_INCREF(self->offset);
949
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000950 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951 self->text = PyTuple_GET_ITEM(info, 3);
952 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000953
954 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000955 }
956 return 0;
957}
958
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000959static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000960SyntaxError_clear(PySyntaxErrorObject *self)
961{
962 Py_CLEAR(self->msg);
963 Py_CLEAR(self->filename);
964 Py_CLEAR(self->lineno);
965 Py_CLEAR(self->offset);
966 Py_CLEAR(self->text);
967 Py_CLEAR(self->print_file_and_line);
968 return BaseException_clear((PyBaseExceptionObject *)self);
969}
970
971static void
972SyntaxError_dealloc(PySyntaxErrorObject *self)
973{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000974 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000975 SyntaxError_clear(self);
976 self->ob_type->tp_free((PyObject *)self);
977}
978
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000979static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000980SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
981{
982 Py_VISIT(self->msg);
983 Py_VISIT(self->filename);
984 Py_VISIT(self->lineno);
985 Py_VISIT(self->offset);
986 Py_VISIT(self->text);
987 Py_VISIT(self->print_file_and_line);
988 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
989}
990
991/* This is called "my_basename" instead of just "basename" to avoid name
992 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
993 defined, and Python does define that. */
994static char *
995my_basename(char *name)
996{
997 char *cp = name;
998 char *result = name;
999
1000 if (name == NULL)
1001 return "???";
1002 while (*cp != '\0') {
1003 if (*cp == SEP)
1004 result = cp + 1;
1005 ++cp;
1006 }
1007 return result;
1008}
1009
1010
1011static PyObject *
1012SyntaxError_str(PySyntaxErrorObject *self)
1013{
1014 PyObject *str;
1015 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001016 int have_filename = 0;
1017 int have_lineno = 0;
1018 char *buffer = NULL;
1019 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001020
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001021 if (self->msg)
1022 str = PyObject_Str(self->msg);
1023 else
1024 str = PyObject_Str(Py_None);
1025 if (!str) return NULL;
1026 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1027 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001028
1029 /* XXX -- do all the additional formatting with filename and
1030 lineno here */
1031
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001032 have_filename = (self->filename != NULL) &&
1033 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001034 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001035
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001036 if (!have_filename && !have_lineno)
1037 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001039 bufsize = PyString_GET_SIZE(str) + 64;
1040 if (have_filename)
1041 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001042
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001043 buffer = PyMem_MALLOC(bufsize);
1044 if (buffer == NULL)
1045 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001046
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001047 if (have_filename && have_lineno)
1048 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1049 PyString_AS_STRING(str),
1050 my_basename(PyString_AS_STRING(self->filename)),
1051 PyInt_AsLong(self->lineno));
1052 else if (have_filename)
1053 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1054 PyString_AS_STRING(str),
1055 my_basename(PyString_AS_STRING(self->filename)));
1056 else /* only have_lineno */
1057 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1058 PyString_AS_STRING(str),
1059 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001061 result = PyString_FromString(buffer);
1062 PyMem_FREE(buffer);
1063
1064 if (result == NULL)
1065 result = str;
1066 else
1067 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068 return result;
1069}
1070
1071static PyMemberDef SyntaxError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001072 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1073 PyDoc_STR("exception msg")},
1074 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1075 PyDoc_STR("exception filename")},
1076 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1077 PyDoc_STR("exception lineno")},
1078 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1079 PyDoc_STR("exception offset")},
1080 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1081 PyDoc_STR("exception text")},
1082 {"print_file_and_line", T_OBJECT,
1083 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1084 PyDoc_STR("exception print_file_and_line")},
1085 {NULL} /* Sentinel */
1086};
1087
1088ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1089 SyntaxError_dealloc, 0, SyntaxError_members,
1090 SyntaxError_str, "Invalid syntax.");
1091
1092
1093/*
1094 * IndentationError extends SyntaxError
1095 */
1096MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1097 "Improper indentation.");
1098
1099
1100/*
1101 * TabError extends IndentationError
1102 */
1103MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1104 "Improper mixture of spaces and tabs.");
1105
1106
1107/*
1108 * LookupError extends StandardError
1109 */
1110SimpleExtendsException(PyExc_StandardError, LookupError,
1111 "Base class for lookup errors.");
1112
1113
1114/*
1115 * IndexError extends LookupError
1116 */
1117SimpleExtendsException(PyExc_LookupError, IndexError,
1118 "Sequence index out of range.");
1119
1120
1121/*
1122 * KeyError extends LookupError
1123 */
1124static PyObject *
1125KeyError_str(PyBaseExceptionObject *self)
1126{
1127 /* If args is a tuple of exactly one item, apply repr to args[0].
1128 This is done so that e.g. the exception raised by {}[''] prints
1129 KeyError: ''
1130 rather than the confusing
1131 KeyError
1132 alone. The downside is that if KeyError is raised with an explanatory
1133 string, that string will be displayed in quotes. Too bad.
1134 If args is anything else, use the default BaseException__str__().
1135 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001136 if (PyTuple_GET_SIZE(self->args) == 1) {
1137 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138 }
1139 return BaseException_str(self);
1140}
1141
1142ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1143 0, 0, 0, KeyError_str, "Mapping key not found.");
1144
1145
1146/*
1147 * ValueError extends StandardError
1148 */
1149SimpleExtendsException(PyExc_StandardError, ValueError,
1150 "Inappropriate argument value (of correct type).");
1151
1152/*
1153 * UnicodeError extends ValueError
1154 */
1155
1156SimpleExtendsException(PyExc_ValueError, UnicodeError,
1157 "Unicode related error.");
1158
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159static int
1160get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1161{
1162 if (!attr) {
1163 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1164 return -1;
1165 }
1166
Guido van Rossumddefaf32007-01-14 03:31:43 +00001167 if (PyLong_Check(attr)) {
1168 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169 if (*value == -1 && PyErr_Occurred())
1170 return -1;
1171 } else {
1172 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1173 return -1;
1174 }
1175 return 0;
1176}
1177
1178static int
1179set_ssize_t(PyObject **attr, Py_ssize_t value)
1180{
1181 PyObject *obj = PyInt_FromSsize_t(value);
1182 if (!obj)
1183 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001184 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185 *attr = obj;
1186 return 0;
1187}
1188
1189static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +00001190get_bytes(PyObject *attr, const char *name)
1191{
1192 if (!attr) {
1193 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1194 return NULL;
1195 }
1196
1197 if (!PyBytes_Check(attr)) {
1198 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1199 return NULL;
1200 }
1201 Py_INCREF(attr);
1202 return attr;
1203}
1204
1205static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001206get_unicode(PyObject *attr, const char *name)
1207{
1208 if (!attr) {
1209 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1210 return NULL;
1211 }
1212
1213 if (!PyUnicode_Check(attr)) {
1214 PyErr_Format(PyExc_TypeError,
1215 "%.200s attribute must be unicode", name);
1216 return NULL;
1217 }
1218 Py_INCREF(attr);
1219 return attr;
1220}
1221
Walter Dörwaldd2034312007-05-18 16:29:38 +00001222static int
1223set_unicodefromstring(PyObject **attr, const char *value)
1224{
1225 PyObject *obj = PyUnicode_FromString(value);
1226 if (!obj)
1227 return -1;
1228 Py_CLEAR(*attr);
1229 *attr = obj;
1230 return 0;
1231}
1232
Thomas Wouters477c8d52006-05-27 19:21:47 +00001233PyObject *
1234PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1235{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001236 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001237}
1238
1239PyObject *
1240PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1241{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001242 return get_unicode(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001243}
1244
1245PyObject *
1246PyUnicodeEncodeError_GetObject(PyObject *exc)
1247{
1248 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1249}
1250
1251PyObject *
1252PyUnicodeDecodeError_GetObject(PyObject *exc)
1253{
Walter Dörwald612344f2007-05-04 19:28:21 +00001254 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001255}
1256
1257PyObject *
1258PyUnicodeTranslateError_GetObject(PyObject *exc)
1259{
1260 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1261}
1262
1263int
1264PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1265{
1266 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1267 Py_ssize_t size;
1268 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1269 "object");
1270 if (!obj) return -1;
1271 size = PyUnicode_GET_SIZE(obj);
1272 if (*start<0)
1273 *start = 0; /*XXX check for values <0*/
1274 if (*start>=size)
1275 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001276 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277 return 0;
1278 }
1279 return -1;
1280}
1281
1282
1283int
1284PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1285{
1286 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1287 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001288 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001289 "object");
1290 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001291 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292 if (*start<0)
1293 *start = 0;
1294 if (*start>=size)
1295 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001296 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001297 return 0;
1298 }
1299 return -1;
1300}
1301
1302
1303int
1304PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1305{
1306 return PyUnicodeEncodeError_GetStart(exc, start);
1307}
1308
1309
1310int
1311PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1312{
1313 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1314}
1315
1316
1317int
1318PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1319{
1320 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1321}
1322
1323
1324int
1325PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1326{
1327 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1328}
1329
1330
1331int
1332PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1333{
1334 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1335 Py_ssize_t size;
1336 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1337 "object");
1338 if (!obj) return -1;
1339 size = PyUnicode_GET_SIZE(obj);
1340 if (*end<1)
1341 *end = 1;
1342 if (*end>size)
1343 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001344 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345 return 0;
1346 }
1347 return -1;
1348}
1349
1350
1351int
1352PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1353{
1354 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1355 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001356 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357 "object");
1358 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001359 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360 if (*end<1)
1361 *end = 1;
1362 if (*end>size)
1363 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001364 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001365 return 0;
1366 }
1367 return -1;
1368}
1369
1370
1371int
1372PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1373{
1374 return PyUnicodeEncodeError_GetEnd(exc, start);
1375}
1376
1377
1378int
1379PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1380{
1381 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1382}
1383
1384
1385int
1386PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1387{
1388 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1389}
1390
1391
1392int
1393PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1394{
1395 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1396}
1397
1398PyObject *
1399PyUnicodeEncodeError_GetReason(PyObject *exc)
1400{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001401 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402}
1403
1404
1405PyObject *
1406PyUnicodeDecodeError_GetReason(PyObject *exc)
1407{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001408 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409}
1410
1411
1412PyObject *
1413PyUnicodeTranslateError_GetReason(PyObject *exc)
1414{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001415 return get_unicode(((PyUnicodeErrorObject *)exc)->reason, "reason");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416}
1417
1418
1419int
1420PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1421{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001422 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1423 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001424}
1425
1426
1427int
1428PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1429{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001430 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1431 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001432}
1433
1434
1435int
1436PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1437{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001438 return set_unicodefromstring(&((PyUnicodeErrorObject *)exc)->reason,
1439 reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440}
1441
1442
Thomas Wouters477c8d52006-05-27 19:21:47 +00001443static int
1444UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1445 PyTypeObject *objecttype)
1446{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001447 Py_CLEAR(self->encoding);
1448 Py_CLEAR(self->object);
1449 Py_CLEAR(self->start);
1450 Py_CLEAR(self->end);
1451 Py_CLEAR(self->reason);
1452
Thomas Wouters477c8d52006-05-27 19:21:47 +00001453 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
Walter Dörwaldd2034312007-05-18 16:29:38 +00001454 &PyUnicode_Type, &self->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001456 &PyLong_Type, &self->start,
1457 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001458 &PyUnicode_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001459 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460 self->reason = NULL;
1461 return -1;
1462 }
1463
1464 Py_INCREF(self->encoding);
1465 Py_INCREF(self->object);
1466 Py_INCREF(self->start);
1467 Py_INCREF(self->end);
1468 Py_INCREF(self->reason);
1469
1470 return 0;
1471}
1472
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001473static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001474UnicodeError_clear(PyUnicodeErrorObject *self)
1475{
1476 Py_CLEAR(self->encoding);
1477 Py_CLEAR(self->object);
1478 Py_CLEAR(self->start);
1479 Py_CLEAR(self->end);
1480 Py_CLEAR(self->reason);
1481 return BaseException_clear((PyBaseExceptionObject *)self);
1482}
1483
1484static void
1485UnicodeError_dealloc(PyUnicodeErrorObject *self)
1486{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001487 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001488 UnicodeError_clear(self);
1489 self->ob_type->tp_free((PyObject *)self);
1490}
1491
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001492static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001493UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1494{
1495 Py_VISIT(self->encoding);
1496 Py_VISIT(self->object);
1497 Py_VISIT(self->start);
1498 Py_VISIT(self->end);
1499 Py_VISIT(self->reason);
1500 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1501}
1502
1503static PyMemberDef UnicodeError_members[] = {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001504 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1505 PyDoc_STR("exception encoding")},
1506 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1507 PyDoc_STR("exception object")},
1508 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1509 PyDoc_STR("exception start")},
1510 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1511 PyDoc_STR("exception end")},
1512 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1513 PyDoc_STR("exception reason")},
1514 {NULL} /* Sentinel */
1515};
1516
1517
1518/*
1519 * UnicodeEncodeError extends UnicodeError
1520 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521
1522static int
1523UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1524{
1525 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1526 return -1;
1527 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1528 kwds, &PyUnicode_Type);
1529}
1530
1531static PyObject *
1532UnicodeEncodeError_str(PyObject *self)
1533{
1534 Py_ssize_t start;
1535 Py_ssize_t end;
1536
1537 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001538 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539
1540 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001541 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542
1543 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001544 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1545 char badchar_str[20];
1546 if (badchar <= 0xff)
1547 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1548 else if (badchar <= 0xffff)
1549 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1550 else
1551 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001552 return PyUnicode_FromFormat(
1553 "'%U' codec can't encode character u'\\%s' in position %zd: %U",
1554 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001555 badchar_str,
1556 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001557 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001558 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001560 return PyUnicode_FromFormat(
1561 "'%U' codec can't encode characters in position %zd-%zd: %U",
1562 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001563 start,
1564 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001565 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001566 );
1567}
1568
1569static PyTypeObject _PyExc_UnicodeEncodeError = {
1570 PyObject_HEAD_INIT(NULL)
1571 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001572 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001573 sizeof(PyUnicodeErrorObject), 0,
1574 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1575 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1576 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001577 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1578 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001579 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001580 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001581};
1582PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1583
1584PyObject *
1585PyUnicodeEncodeError_Create(
1586 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1587 Py_ssize_t start, Py_ssize_t end, const char *reason)
1588{
Walter Dörwaldd2034312007-05-18 16:29:38 +00001589 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001590 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001591}
1592
1593
1594/*
1595 * UnicodeDecodeError extends UnicodeError
1596 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001597
1598static int
1599UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1600{
1601 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1602 return -1;
1603 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001604 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605}
1606
1607static PyObject *
1608UnicodeDecodeError_str(PyObject *self)
1609{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001610 Py_ssize_t start = 0;
1611 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001612
1613 if (PyUnicodeDecodeError_GetStart(self, &start))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001614 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001615
1616 if (PyUnicodeDecodeError_GetEnd(self, &end))
Walter Dörwaldd2034312007-05-18 16:29:38 +00001617 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618
1619 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001620 /* FromFormat does not support %02x, so format that separately */
1621 char byte[4];
1622 PyOS_snprintf(byte, sizeof(byte), "%02x",
Walter Dörwald612344f2007-05-04 19:28:21 +00001623 ((int)PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001624 return PyUnicode_FromFormat(
1625 "'%U' codec can't decode byte 0x%s in position %zd: %U",
1626 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001627 byte,
1628 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001629 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001630 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001631 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001632 return PyUnicode_FromFormat(
1633 "'%U' codec can't decode bytes in position %zd-%zd: %U",
1634 ((PyUnicodeErrorObject *)self)->encoding,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635 start,
1636 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001637 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001638 );
1639}
1640
1641static PyTypeObject _PyExc_UnicodeDecodeError = {
1642 PyObject_HEAD_INIT(NULL)
1643 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001644 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645 sizeof(PyUnicodeErrorObject), 0,
1646 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1647 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1648 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001649 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1650 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001652 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653};
1654PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1655
1656PyObject *
1657PyUnicodeDecodeError_Create(
1658 const char *encoding, const char *object, Py_ssize_t length,
1659 Py_ssize_t start, Py_ssize_t end, const char *reason)
1660{
1661 assert(length < INT_MAX);
1662 assert(start < INT_MAX);
1663 assert(end < INT_MAX);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001664 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001665 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001666}
1667
1668
1669/*
1670 * UnicodeTranslateError extends UnicodeError
1671 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672
1673static int
1674UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1675 PyObject *kwds)
1676{
1677 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1678 return -1;
1679
1680 Py_CLEAR(self->object);
1681 Py_CLEAR(self->start);
1682 Py_CLEAR(self->end);
1683 Py_CLEAR(self->reason);
1684
1685 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1686 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001687 &PyLong_Type, &self->start,
1688 &PyLong_Type, &self->end,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001689 &PyUnicode_Type, &self->reason)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001690 self->object = self->start = self->end = self->reason = NULL;
1691 return -1;
1692 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001693
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 Py_INCREF(self->object);
1695 Py_INCREF(self->start);
1696 Py_INCREF(self->end);
1697 Py_INCREF(self->reason);
1698
1699 return 0;
1700}
1701
1702
1703static PyObject *
1704UnicodeTranslateError_str(PyObject *self)
1705{
1706 Py_ssize_t start;
1707 Py_ssize_t end;
1708
1709 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001710 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001711
1712 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001713 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001714
1715 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001716 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1717 char badchar_str[20];
1718 if (badchar <= 0xff)
1719 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1720 else if (badchar <= 0xffff)
1721 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1722 else
1723 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
Walter Dörwaldd2034312007-05-18 16:29:38 +00001724 return PyUnicode_FromFormat(
1725 "can't translate character u'\\%s' in position %zd: %U",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001726 badchar_str,
1727 start,
Walter Dörwaldd2034312007-05-18 16:29:38 +00001728 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001729 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730 }
Walter Dörwaldd2034312007-05-18 16:29:38 +00001731 return PyUnicode_FromFormat(
1732 "can't translate characters in position %zd-%zd: %U",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001733 start,
1734 (end-1),
Walter Dörwaldd2034312007-05-18 16:29:38 +00001735 ((PyUnicodeErrorObject *)self)->reason
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736 );
1737}
1738
1739static PyTypeObject _PyExc_UnicodeTranslateError = {
1740 PyObject_HEAD_INIT(NULL)
1741 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001742 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001743 sizeof(PyUnicodeErrorObject), 0,
1744 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1745 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1746 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001747 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1749 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001750 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751};
1752PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1753
1754PyObject *
1755PyUnicodeTranslateError_Create(
1756 const Py_UNICODE *object, Py_ssize_t length,
1757 Py_ssize_t start, Py_ssize_t end, const char *reason)
1758{
1759 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001760 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001761}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001762
1763
1764/*
1765 * AssertionError extends StandardError
1766 */
1767SimpleExtendsException(PyExc_StandardError, AssertionError,
1768 "Assertion failed.");
1769
1770
1771/*
1772 * ArithmeticError extends StandardError
1773 */
1774SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1775 "Base class for arithmetic errors.");
1776
1777
1778/*
1779 * FloatingPointError extends ArithmeticError
1780 */
1781SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1782 "Floating point operation failed.");
1783
1784
1785/*
1786 * OverflowError extends ArithmeticError
1787 */
1788SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1789 "Result too large to be represented.");
1790
1791
1792/*
1793 * ZeroDivisionError extends ArithmeticError
1794 */
1795SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1796 "Second argument to a division or modulo operation was zero.");
1797
1798
1799/*
1800 * SystemError extends StandardError
1801 */
1802SimpleExtendsException(PyExc_StandardError, SystemError,
1803 "Internal error in the Python interpreter.\n"
1804 "\n"
1805 "Please report this to the Python maintainer, along with the traceback,\n"
1806 "the Python version, and the hardware/OS platform and version.");
1807
1808
1809/*
1810 * ReferenceError extends StandardError
1811 */
1812SimpleExtendsException(PyExc_StandardError, ReferenceError,
1813 "Weak ref proxy used after referent went away.");
1814
1815
1816/*
1817 * MemoryError extends StandardError
1818 */
1819SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1820
1821
1822/* Warning category docstrings */
1823
1824/*
1825 * Warning extends Exception
1826 */
1827SimpleExtendsException(PyExc_Exception, Warning,
1828 "Base class for warning categories.");
1829
1830
1831/*
1832 * UserWarning extends Warning
1833 */
1834SimpleExtendsException(PyExc_Warning, UserWarning,
1835 "Base class for warnings generated by user code.");
1836
1837
1838/*
1839 * DeprecationWarning extends Warning
1840 */
1841SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1842 "Base class for warnings about deprecated features.");
1843
1844
1845/*
1846 * PendingDeprecationWarning extends Warning
1847 */
1848SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1849 "Base class for warnings about features which will be deprecated\n"
1850 "in the future.");
1851
1852
1853/*
1854 * SyntaxWarning extends Warning
1855 */
1856SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1857 "Base class for warnings about dubious syntax.");
1858
1859
1860/*
1861 * RuntimeWarning extends Warning
1862 */
1863SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1864 "Base class for warnings about dubious runtime behavior.");
1865
1866
1867/*
1868 * FutureWarning extends Warning
1869 */
1870SimpleExtendsException(PyExc_Warning, FutureWarning,
1871 "Base class for warnings about constructs that will change semantically\n"
1872 "in the future.");
1873
1874
1875/*
1876 * ImportWarning extends Warning
1877 */
1878SimpleExtendsException(PyExc_Warning, ImportWarning,
1879 "Base class for warnings about probable mistakes in module imports");
1880
1881
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001882/*
1883 * UnicodeWarning extends Warning
1884 */
1885SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1886 "Base class for warnings about Unicode related problems, mostly\n"
1887 "related to conversion problems.");
1888
1889
Thomas Wouters477c8d52006-05-27 19:21:47 +00001890/* Pre-computed MemoryError instance. Best to create this as early as
1891 * possible and not wait until a MemoryError is actually raised!
1892 */
1893PyObject *PyExc_MemoryErrorInst=NULL;
1894
Thomas Wouters477c8d52006-05-27 19:21:47 +00001895#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1896 Py_FatalError("exceptions bootstrapping error.");
1897
1898#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001899 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1900 Py_FatalError("Module dictionary insertion problem.");
1901
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001902#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1903/* crt variable checking in VisualStudio .NET 2005 */
1904#include <crtdbg.h>
1905
1906static int prevCrtReportMode;
1907static _invalid_parameter_handler prevCrtHandler;
1908
1909/* Invalid parameter handler. Sets a ValueError exception */
1910static void
1911InvalidParameterHandler(
1912 const wchar_t * expression,
1913 const wchar_t * function,
1914 const wchar_t * file,
1915 unsigned int line,
1916 uintptr_t pReserved)
1917{
1918 /* Do nothing, allow execution to continue. Usually this
1919 * means that the CRT will set errno to EINVAL
1920 */
1921}
1922#endif
1923
1924
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001926_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001927{
Neal Norwitz2633c692007-02-26 22:22:47 +00001928 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001929
1930 PRE_INIT(BaseException)
1931 PRE_INIT(Exception)
1932 PRE_INIT(StandardError)
1933 PRE_INIT(TypeError)
1934 PRE_INIT(StopIteration)
1935 PRE_INIT(GeneratorExit)
1936 PRE_INIT(SystemExit)
1937 PRE_INIT(KeyboardInterrupt)
1938 PRE_INIT(ImportError)
1939 PRE_INIT(EnvironmentError)
1940 PRE_INIT(IOError)
1941 PRE_INIT(OSError)
1942#ifdef MS_WINDOWS
1943 PRE_INIT(WindowsError)
1944#endif
1945#ifdef __VMS
1946 PRE_INIT(VMSError)
1947#endif
1948 PRE_INIT(EOFError)
1949 PRE_INIT(RuntimeError)
1950 PRE_INIT(NotImplementedError)
1951 PRE_INIT(NameError)
1952 PRE_INIT(UnboundLocalError)
1953 PRE_INIT(AttributeError)
1954 PRE_INIT(SyntaxError)
1955 PRE_INIT(IndentationError)
1956 PRE_INIT(TabError)
1957 PRE_INIT(LookupError)
1958 PRE_INIT(IndexError)
1959 PRE_INIT(KeyError)
1960 PRE_INIT(ValueError)
1961 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001962 PRE_INIT(UnicodeEncodeError)
1963 PRE_INIT(UnicodeDecodeError)
1964 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965 PRE_INIT(AssertionError)
1966 PRE_INIT(ArithmeticError)
1967 PRE_INIT(FloatingPointError)
1968 PRE_INIT(OverflowError)
1969 PRE_INIT(ZeroDivisionError)
1970 PRE_INIT(SystemError)
1971 PRE_INIT(ReferenceError)
1972 PRE_INIT(MemoryError)
1973 PRE_INIT(Warning)
1974 PRE_INIT(UserWarning)
1975 PRE_INIT(DeprecationWarning)
1976 PRE_INIT(PendingDeprecationWarning)
1977 PRE_INIT(SyntaxWarning)
1978 PRE_INIT(RuntimeWarning)
1979 PRE_INIT(FutureWarning)
1980 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001981 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001982
Thomas Wouters477c8d52006-05-27 19:21:47 +00001983 bltinmod = PyImport_ImportModule("__builtin__");
1984 if (bltinmod == NULL)
1985 Py_FatalError("exceptions bootstrapping error.");
1986 bdict = PyModule_GetDict(bltinmod);
1987 if (bdict == NULL)
1988 Py_FatalError("exceptions bootstrapping error.");
1989
1990 POST_INIT(BaseException)
1991 POST_INIT(Exception)
1992 POST_INIT(StandardError)
1993 POST_INIT(TypeError)
1994 POST_INIT(StopIteration)
1995 POST_INIT(GeneratorExit)
1996 POST_INIT(SystemExit)
1997 POST_INIT(KeyboardInterrupt)
1998 POST_INIT(ImportError)
1999 POST_INIT(EnvironmentError)
2000 POST_INIT(IOError)
2001 POST_INIT(OSError)
2002#ifdef MS_WINDOWS
2003 POST_INIT(WindowsError)
2004#endif
2005#ifdef __VMS
2006 POST_INIT(VMSError)
2007#endif
2008 POST_INIT(EOFError)
2009 POST_INIT(RuntimeError)
2010 POST_INIT(NotImplementedError)
2011 POST_INIT(NameError)
2012 POST_INIT(UnboundLocalError)
2013 POST_INIT(AttributeError)
2014 POST_INIT(SyntaxError)
2015 POST_INIT(IndentationError)
2016 POST_INIT(TabError)
2017 POST_INIT(LookupError)
2018 POST_INIT(IndexError)
2019 POST_INIT(KeyError)
2020 POST_INIT(ValueError)
2021 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002022 POST_INIT(UnicodeEncodeError)
2023 POST_INIT(UnicodeDecodeError)
2024 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002025 POST_INIT(AssertionError)
2026 POST_INIT(ArithmeticError)
2027 POST_INIT(FloatingPointError)
2028 POST_INIT(OverflowError)
2029 POST_INIT(ZeroDivisionError)
2030 POST_INIT(SystemError)
2031 POST_INIT(ReferenceError)
2032 POST_INIT(MemoryError)
2033 POST_INIT(Warning)
2034 POST_INIT(UserWarning)
2035 POST_INIT(DeprecationWarning)
2036 POST_INIT(PendingDeprecationWarning)
2037 POST_INIT(SyntaxWarning)
2038 POST_INIT(RuntimeWarning)
2039 POST_INIT(FutureWarning)
2040 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002041 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002042
2043 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2044 if (!PyExc_MemoryErrorInst)
2045 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2046
2047 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002048
2049#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2050 /* Set CRT argument error handler */
2051 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2052 /* turn off assertions in debug mode */
2053 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2054#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002055}
2056
2057void
2058_PyExc_Fini(void)
2059{
2060 Py_XDECREF(PyExc_MemoryErrorInst);
2061 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002062#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2063 /* reset CRT error handling */
2064 _set_invalid_parameter_handler(prevCrtHandler);
2065 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2066#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002067}