blob: 1096bace5a67801b9cb4d0b9e0015f9388823f89 [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 */
30 self->message = self->dict = NULL;
31
32 self->args = PyTuple_New(0);
33 if (!self->args) {
34 Py_DECREF(self);
35 return NULL;
36 }
37
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000038 self->message = PyString_FromString("");
Thomas Wouters477c8d52006-05-27 19:21:47 +000039 if (!self->message) {
40 Py_DECREF(self);
41 return NULL;
42 }
43
44 return (PyObject *)self;
45}
46
47static int
48BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
49{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000050 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
51 return -1;
52
Thomas Wouters477c8d52006-05-27 19:21:47 +000053 Py_DECREF(self->args);
54 self->args = args;
55 Py_INCREF(self->args);
56
57 if (PyTuple_GET_SIZE(self->args) == 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000058 Py_CLEAR(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000059 self->message = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000060 Py_INCREF(self->message);
Thomas Wouters477c8d52006-05-27 19:21:47 +000061 }
62 return 0;
63}
64
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000065static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000066BaseException_clear(PyBaseExceptionObject *self)
67{
68 Py_CLEAR(self->dict);
69 Py_CLEAR(self->args);
70 Py_CLEAR(self->message);
71 return 0;
72}
73
74static void
75BaseException_dealloc(PyBaseExceptionObject *self)
76{
Thomas Wouters89f507f2006-12-13 04:49:30 +000077 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +000078 BaseException_clear(self);
79 self->ob_type->tp_free((PyObject *)self);
80}
81
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000082static int
Thomas Wouters477c8d52006-05-27 19:21:47 +000083BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
84{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000085 Py_VISIT(self->dict);
Thomas Wouters477c8d52006-05-27 19:21:47 +000086 Py_VISIT(self->args);
87 Py_VISIT(self->message);
88 return 0;
89}
90
91static PyObject *
92BaseException_str(PyBaseExceptionObject *self)
93{
94 PyObject *out;
95
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000096 switch (PyTuple_GET_SIZE(self->args)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +000097 case 0:
98 out = PyString_FromString("");
99 break;
100 case 1:
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000101 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000102 break;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000103 default:
104 out = PyObject_Str(self->args);
105 break;
106 }
107
108 return out;
109}
110
111static PyObject *
112BaseException_repr(PyBaseExceptionObject *self)
113{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000114 PyObject *repr_suffix;
115 PyObject *repr;
116 char *name;
117 char *dot;
118
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000119 repr_suffix = PyObject_Repr(self->args);
120 if (!repr_suffix)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000121 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000122
123 name = (char *)self->ob_type->tp_name;
124 dot = strrchr(name, '.');
125 if (dot != NULL) name = dot+1;
126
127 repr = PyString_FromString(name);
128 if (!repr) {
129 Py_DECREF(repr_suffix);
130 return NULL;
131 }
132
133 PyString_ConcatAndDel(&repr, repr_suffix);
134 return repr;
135}
136
137/* Pickling support */
138static PyObject *
139BaseException_reduce(PyBaseExceptionObject *self)
140{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000141 if (self->args && self->dict)
142 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
143 else
144 return PyTuple_Pack(2, self->ob_type, self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000145}
146
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000147/*
148 * Needed for backward compatibility, since exceptions used to store
149 * all their attributes in the __dict__. Code is taken from cPickle's
150 * load_build function.
151 */
152static PyObject *
153BaseException_setstate(PyObject *self, PyObject *state)
154{
155 PyObject *d_key, *d_value;
156 Py_ssize_t i = 0;
157
158 if (state != Py_None) {
159 if (!PyDict_Check(state)) {
160 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
161 return NULL;
162 }
163 while (PyDict_Next(state, &i, &d_key, &d_value)) {
164 if (PyObject_SetAttr(self, d_key, d_value) < 0)
165 return NULL;
166 }
167 }
168 Py_RETURN_NONE;
169}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000170
Thomas Wouters477c8d52006-05-27 19:21:47 +0000171
172static PyMethodDef BaseException_methods[] = {
173 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000174 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Thomas Wouters477c8d52006-05-27 19:21:47 +0000175 {NULL, NULL, 0, NULL},
176};
177
178
Thomas Wouters477c8d52006-05-27 19:21:47 +0000179static PyMemberDef BaseException_members[] = {
180 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
181 PyDoc_STR("exception message")},
182 {NULL} /* Sentinel */
183};
184
185
186static PyObject *
187BaseException_get_dict(PyBaseExceptionObject *self)
188{
189 if (self->dict == NULL) {
190 self->dict = PyDict_New();
191 if (!self->dict)
192 return NULL;
193 }
194 Py_INCREF(self->dict);
195 return self->dict;
196}
197
198static int
199BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
200{
201 if (val == NULL) {
202 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
203 return -1;
204 }
205 if (!PyDict_Check(val)) {
206 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
207 return -1;
208 }
209 Py_CLEAR(self->dict);
210 Py_INCREF(val);
211 self->dict = val;
212 return 0;
213}
214
215static PyObject *
216BaseException_get_args(PyBaseExceptionObject *self)
217{
218 if (self->args == NULL) {
219 Py_INCREF(Py_None);
220 return Py_None;
221 }
222 Py_INCREF(self->args);
223 return self->args;
224}
225
226static int
227BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
228{
229 PyObject *seq;
230 if (val == NULL) {
231 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
232 return -1;
233 }
234 seq = PySequence_Tuple(val);
235 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000236 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000237 self->args = seq;
238 return 0;
239}
240
241static PyGetSetDef BaseException_getset[] = {
242 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
243 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
244 {NULL},
245};
246
247
248static PyTypeObject _PyExc_BaseException = {
249 PyObject_HEAD_INIT(NULL)
250 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000251 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000252 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
253 0, /*tp_itemsize*/
254 (destructor)BaseException_dealloc, /*tp_dealloc*/
255 0, /*tp_print*/
256 0, /*tp_getattr*/
257 0, /*tp_setattr*/
258 0, /* tp_compare; */
259 (reprfunc)BaseException_repr, /*tp_repr*/
260 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000261 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000262 0, /*tp_as_mapping*/
263 0, /*tp_hash */
264 0, /*tp_call*/
265 (reprfunc)BaseException_str, /*tp_str*/
266 PyObject_GenericGetAttr, /*tp_getattro*/
267 PyObject_GenericSetAttr, /*tp_setattro*/
268 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000269 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
270 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000271 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
272 (traverseproc)BaseException_traverse, /* tp_traverse */
273 (inquiry)BaseException_clear, /* tp_clear */
274 0, /* tp_richcompare */
275 0, /* tp_weaklistoffset */
276 0, /* tp_iter */
277 0, /* tp_iternext */
278 BaseException_methods, /* tp_methods */
279 BaseException_members, /* tp_members */
280 BaseException_getset, /* tp_getset */
281 0, /* tp_base */
282 0, /* tp_dict */
283 0, /* tp_descr_get */
284 0, /* tp_descr_set */
285 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
286 (initproc)BaseException_init, /* tp_init */
287 0, /* tp_alloc */
288 BaseException_new, /* tp_new */
289};
290/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
291from the previous implmentation and also allowing Python objects to be used
292in the API */
293PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
294
295/* note these macros omit the last semicolon so the macro invocation may
296 * include it and not look strange.
297 */
298#define SimpleExtendsException(EXCBASE, EXCNAME, 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(PyBaseExceptionObject), \
304 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
305 0, 0, 0, 0, 0, 0, 0, \
306 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
307 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
308 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
309 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
310 (initproc)BaseException_init, 0, BaseException_new,\
311}; \
312PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
313
314#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
315static PyTypeObject _PyExc_ ## EXCNAME = { \
316 PyObject_HEAD_INIT(NULL) \
317 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000318 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000320 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321 0, 0, 0, 0, 0, \
322 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000323 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
324 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000326 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000327}; \
328PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
329
330#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
331static PyTypeObject _PyExc_ ## EXCNAME = { \
332 PyObject_HEAD_INIT(NULL) \
333 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000334 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000335 sizeof(Py ## EXCSTORE ## Object), 0, \
336 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
337 (reprfunc)EXCSTR, 0, 0, 0, \
338 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
339 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
340 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
341 EXCMEMBERS, 0, &_ ## EXCBASE, \
342 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000343 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344}; \
345PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
346
347
348/*
349 * Exception extends BaseException
350 */
351SimpleExtendsException(PyExc_BaseException, Exception,
352 "Common base class for all non-exit exceptions.");
353
354
355/*
356 * StandardError extends Exception
357 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000358SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000359 "Base class for all standard Python exceptions that do not represent\n"
360 "interpreter exiting.");
361
362
363/*
364 * TypeError extends StandardError
365 */
366SimpleExtendsException(PyExc_StandardError, TypeError,
367 "Inappropriate argument type.");
368
369
370/*
371 * StopIteration extends Exception
372 */
373SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000374 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000375
376
377/*
378 * GeneratorExit extends Exception
379 */
380SimpleExtendsException(PyExc_Exception, GeneratorExit,
381 "Request that a generator exit.");
382
383
384/*
385 * SystemExit extends BaseException
386 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000387
388static int
389SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
390{
391 Py_ssize_t size = PyTuple_GET_SIZE(args);
392
393 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
394 return -1;
395
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000396 if (size == 0)
397 return 0;
398 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000399 if (size == 1)
400 self->code = PyTuple_GET_ITEM(args, 0);
401 else if (size > 1)
402 self->code = args;
403 Py_INCREF(self->code);
404 return 0;
405}
406
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000407static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408SystemExit_clear(PySystemExitObject *self)
409{
410 Py_CLEAR(self->code);
411 return BaseException_clear((PyBaseExceptionObject *)self);
412}
413
414static void
415SystemExit_dealloc(PySystemExitObject *self)
416{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000417 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000418 SystemExit_clear(self);
419 self->ob_type->tp_free((PyObject *)self);
420}
421
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000422static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000423SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
424{
425 Py_VISIT(self->code);
426 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
427}
428
429static PyMemberDef SystemExit_members[] = {
430 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
431 PyDoc_STR("exception message")},
432 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
433 PyDoc_STR("exception code")},
434 {NULL} /* Sentinel */
435};
436
437ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
438 SystemExit_dealloc, 0, SystemExit_members, 0,
439 "Request to exit from the interpreter.");
440
441/*
442 * KeyboardInterrupt extends BaseException
443 */
444SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
445 "Program interrupted by user.");
446
447
448/*
449 * ImportError extends StandardError
450 */
451SimpleExtendsException(PyExc_StandardError, ImportError,
452 "Import can't find module, or can't find name in module.");
453
454
455/*
456 * EnvironmentError extends StandardError
457 */
458
Thomas Wouters477c8d52006-05-27 19:21:47 +0000459/* Where a function has a single filename, such as open() or some
460 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
461 * called, giving a third argument which is the filename. But, so
462 * that old code using in-place unpacking doesn't break, e.g.:
463 *
464 * except IOError, (errno, strerror):
465 *
466 * we hack args so that it only contains two items. This also
467 * means we need our own __str__() which prints out the filename
468 * when it was supplied.
469 */
470static int
471EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
472 PyObject *kwds)
473{
474 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
475 PyObject *subslice = NULL;
476
477 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
478 return -1;
479
Thomas Wouters89f507f2006-12-13 04:49:30 +0000480 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000481 return 0;
482 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000483
484 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485 &myerrno, &strerror, &filename)) {
486 return -1;
487 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000488 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489 self->myerrno = myerrno;
490 Py_INCREF(self->myerrno);
491
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000492 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493 self->strerror = strerror;
494 Py_INCREF(self->strerror);
495
496 /* self->filename will remain Py_None otherwise */
497 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000498 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000499 self->filename = filename;
500 Py_INCREF(self->filename);
501
502 subslice = PyTuple_GetSlice(args, 0, 2);
503 if (!subslice)
504 return -1;
505
506 Py_DECREF(self->args); /* replacing args */
507 self->args = subslice;
508 }
509 return 0;
510}
511
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000512static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513EnvironmentError_clear(PyEnvironmentErrorObject *self)
514{
515 Py_CLEAR(self->myerrno);
516 Py_CLEAR(self->strerror);
517 Py_CLEAR(self->filename);
518 return BaseException_clear((PyBaseExceptionObject *)self);
519}
520
521static void
522EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
523{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000524 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525 EnvironmentError_clear(self);
526 self->ob_type->tp_free((PyObject *)self);
527}
528
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000529static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000530EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
531 void *arg)
532{
533 Py_VISIT(self->myerrno);
534 Py_VISIT(self->strerror);
535 Py_VISIT(self->filename);
536 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
537}
538
539static PyObject *
540EnvironmentError_str(PyEnvironmentErrorObject *self)
541{
542 PyObject *rtnval = NULL;
543
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000544 if (self->filename) {
545 PyObject *fmt;
546 PyObject *repr;
547 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000548
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000549 fmt = PyString_FromString("[Errno %s] %s: %s");
550 if (!fmt)
551 return NULL;
552
553 repr = PyObject_Repr(self->filename);
554 if (!repr) {
555 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000556 return NULL;
557 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000558 tuple = PyTuple_New(3);
559 if (!tuple) {
560 Py_DECREF(repr);
561 Py_DECREF(fmt);
562 return NULL;
563 }
564
565 if (self->myerrno) {
566 Py_INCREF(self->myerrno);
567 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
568 }
569 else {
570 Py_INCREF(Py_None);
571 PyTuple_SET_ITEM(tuple, 0, Py_None);
572 }
573 if (self->strerror) {
574 Py_INCREF(self->strerror);
575 PyTuple_SET_ITEM(tuple, 1, self->strerror);
576 }
577 else {
578 Py_INCREF(Py_None);
579 PyTuple_SET_ITEM(tuple, 1, Py_None);
580 }
581
Thomas Wouters477c8d52006-05-27 19:21:47 +0000582 PyTuple_SET_ITEM(tuple, 2, repr);
583
584 rtnval = PyString_Format(fmt, tuple);
585
586 Py_DECREF(fmt);
587 Py_DECREF(tuple);
588 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000589 else if (self->myerrno && self->strerror) {
590 PyObject *fmt;
591 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000592
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000593 fmt = PyString_FromString("[Errno %s] %s");
594 if (!fmt)
595 return NULL;
596
597 tuple = PyTuple_New(2);
598 if (!tuple) {
599 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000600 return NULL;
601 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000602
603 if (self->myerrno) {
604 Py_INCREF(self->myerrno);
605 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
606 }
607 else {
608 Py_INCREF(Py_None);
609 PyTuple_SET_ITEM(tuple, 0, Py_None);
610 }
611 if (self->strerror) {
612 Py_INCREF(self->strerror);
613 PyTuple_SET_ITEM(tuple, 1, self->strerror);
614 }
615 else {
616 Py_INCREF(Py_None);
617 PyTuple_SET_ITEM(tuple, 1, Py_None);
618 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619
620 rtnval = PyString_Format(fmt, tuple);
621
622 Py_DECREF(fmt);
623 Py_DECREF(tuple);
624 }
625 else
626 rtnval = BaseException_str((PyBaseExceptionObject *)self);
627
628 return rtnval;
629}
630
631static PyMemberDef EnvironmentError_members[] = {
632 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
633 PyDoc_STR("exception message")},
634 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
635 PyDoc_STR("exception errno")},
636 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
637 PyDoc_STR("exception strerror")},
638 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
639 PyDoc_STR("exception filename")},
640 {NULL} /* Sentinel */
641};
642
643
644static PyObject *
645EnvironmentError_reduce(PyEnvironmentErrorObject *self)
646{
647 PyObject *args = self->args;
648 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000649
Thomas Wouters477c8d52006-05-27 19:21:47 +0000650 /* self->args is only the first two real arguments if there was a
651 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000652 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653 args = PyTuple_New(3);
654 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000655
656 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657 Py_INCREF(tmp);
658 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000659
660 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000661 Py_INCREF(tmp);
662 PyTuple_SET_ITEM(args, 1, tmp);
663
664 Py_INCREF(self->filename);
665 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000666 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000667 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000668
669 if (self->dict)
670 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
671 else
672 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000673 Py_DECREF(args);
674 return res;
675}
676
677
678static PyMethodDef EnvironmentError_methods[] = {
679 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
680 {NULL}
681};
682
683ComplexExtendsException(PyExc_StandardError, EnvironmentError,
684 EnvironmentError, EnvironmentError_dealloc,
685 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000686 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 "Base class for I/O related errors.");
688
689
690/*
691 * IOError extends EnvironmentError
692 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000693MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694 EnvironmentError, "I/O operation failed.");
695
696
697/*
698 * OSError extends EnvironmentError
699 */
700MiddlingExtendsException(PyExc_EnvironmentError, OSError,
701 EnvironmentError, "OS system call failed.");
702
703
704/*
705 * WindowsError extends OSError
706 */
707#ifdef MS_WINDOWS
708#include "errmap.h"
709
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000710static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000711WindowsError_clear(PyWindowsErrorObject *self)
712{
713 Py_CLEAR(self->myerrno);
714 Py_CLEAR(self->strerror);
715 Py_CLEAR(self->filename);
716 Py_CLEAR(self->winerror);
717 return BaseException_clear((PyBaseExceptionObject *)self);
718}
719
720static void
721WindowsError_dealloc(PyWindowsErrorObject *self)
722{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000723 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000724 WindowsError_clear(self);
725 self->ob_type->tp_free((PyObject *)self);
726}
727
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000728static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000729WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
730{
731 Py_VISIT(self->myerrno);
732 Py_VISIT(self->strerror);
733 Py_VISIT(self->filename);
734 Py_VISIT(self->winerror);
735 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
736}
737
Thomas Wouters477c8d52006-05-27 19:21:47 +0000738static int
739WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
740{
741 PyObject *o_errcode = NULL;
742 long errcode;
743 long posix_errno;
744
745 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
746 == -1)
747 return -1;
748
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000749 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000750 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000751
752 /* Set errno to the POSIX errno, and winerror to the Win32
753 error code. */
754 errcode = PyInt_AsLong(self->myerrno);
755 if (errcode == -1 && PyErr_Occurred())
756 return -1;
757 posix_errno = winerror_to_errno(errcode);
758
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000759 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760 self->winerror = self->myerrno;
761
762 o_errcode = PyInt_FromLong(posix_errno);
763 if (!o_errcode)
764 return -1;
765
766 self->myerrno = o_errcode;
767
768 return 0;
769}
770
771
772static PyObject *
773WindowsError_str(PyWindowsErrorObject *self)
774{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000775 PyObject *rtnval = NULL;
776
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000777 if (self->filename) {
778 PyObject *fmt;
779 PyObject *repr;
780 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000781
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000782 fmt = PyString_FromString("[Error %s] %s: %s");
783 if (!fmt)
784 return NULL;
785
786 repr = PyObject_Repr(self->filename);
787 if (!repr) {
788 Py_DECREF(fmt);
789 return NULL;
790 }
791 tuple = PyTuple_New(3);
792 if (!tuple) {
793 Py_DECREF(repr);
794 Py_DECREF(fmt);
795 return NULL;
796 }
797
Thomas Wouters89f507f2006-12-13 04:49:30 +0000798 if (self->winerror) {
799 Py_INCREF(self->winerror);
800 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000801 }
802 else {
803 Py_INCREF(Py_None);
804 PyTuple_SET_ITEM(tuple, 0, Py_None);
805 }
806 if (self->strerror) {
807 Py_INCREF(self->strerror);
808 PyTuple_SET_ITEM(tuple, 1, self->strerror);
809 }
810 else {
811 Py_INCREF(Py_None);
812 PyTuple_SET_ITEM(tuple, 1, Py_None);
813 }
814
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000815 PyTuple_SET_ITEM(tuple, 2, repr);
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 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000822 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000823 PyObject *fmt;
824 PyObject *tuple;
825
Thomas Wouters477c8d52006-05-27 19:21:47 +0000826 fmt = PyString_FromString("[Error %s] %s");
827 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000828 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000830 tuple = PyTuple_New(2);
831 if (!tuple) {
832 Py_DECREF(fmt);
833 return NULL;
834 }
835
Thomas Wouters89f507f2006-12-13 04:49:30 +0000836 if (self->winerror) {
837 Py_INCREF(self->winerror);
838 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000839 }
840 else {
841 Py_INCREF(Py_None);
842 PyTuple_SET_ITEM(tuple, 0, Py_None);
843 }
844 if (self->strerror) {
845 Py_INCREF(self->strerror);
846 PyTuple_SET_ITEM(tuple, 1, self->strerror);
847 }
848 else {
849 Py_INCREF(Py_None);
850 PyTuple_SET_ITEM(tuple, 1, Py_None);
851 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000852
853 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000854
855 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856 Py_DECREF(tuple);
857 }
858 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000859 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860
Thomas Wouters477c8d52006-05-27 19:21:47 +0000861 return rtnval;
862}
863
864static PyMemberDef WindowsError_members[] = {
865 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
866 PyDoc_STR("exception message")},
867 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
868 PyDoc_STR("POSIX exception code")},
869 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
870 PyDoc_STR("exception strerror")},
871 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
872 PyDoc_STR("exception filename")},
873 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
874 PyDoc_STR("Win32 exception code")},
875 {NULL} /* Sentinel */
876};
877
878ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
879 WindowsError_dealloc, 0, WindowsError_members,
880 WindowsError_str, "MS-Windows OS system call failed.");
881
882#endif /* MS_WINDOWS */
883
884
885/*
886 * VMSError extends OSError (I think)
887 */
888#ifdef __VMS
889MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
890 "OpenVMS OS system call failed.");
891#endif
892
893
894/*
895 * EOFError extends StandardError
896 */
897SimpleExtendsException(PyExc_StandardError, EOFError,
898 "Read beyond end of file.");
899
900
901/*
902 * RuntimeError extends StandardError
903 */
904SimpleExtendsException(PyExc_StandardError, RuntimeError,
905 "Unspecified run-time error.");
906
907
908/*
909 * NotImplementedError extends RuntimeError
910 */
911SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
912 "Method or function hasn't been implemented yet.");
913
914/*
915 * NameError extends StandardError
916 */
917SimpleExtendsException(PyExc_StandardError, NameError,
918 "Name not found globally.");
919
920/*
921 * UnboundLocalError extends NameError
922 */
923SimpleExtendsException(PyExc_NameError, UnboundLocalError,
924 "Local name referenced but not bound to a value.");
925
926/*
927 * AttributeError extends StandardError
928 */
929SimpleExtendsException(PyExc_StandardError, AttributeError,
930 "Attribute not found.");
931
932
933/*
934 * SyntaxError extends StandardError
935 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000936
937static int
938SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
939{
940 PyObject *info = NULL;
941 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
942
943 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
944 return -1;
945
946 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000947 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000948 self->msg = PyTuple_GET_ITEM(args, 0);
949 Py_INCREF(self->msg);
950 }
951 if (lenargs == 2) {
952 info = PyTuple_GET_ITEM(args, 1);
953 info = PySequence_Tuple(info);
954 if (!info) return -1;
955
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000956 if (PyTuple_GET_SIZE(info) != 4) {
957 /* not a very good error message, but it's what Python 2.4 gives */
958 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
959 Py_DECREF(info);
960 return -1;
961 }
962
963 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964 self->filename = PyTuple_GET_ITEM(info, 0);
965 Py_INCREF(self->filename);
966
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000967 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968 self->lineno = PyTuple_GET_ITEM(info, 1);
969 Py_INCREF(self->lineno);
970
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000971 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000972 self->offset = PyTuple_GET_ITEM(info, 2);
973 Py_INCREF(self->offset);
974
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000975 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000976 self->text = PyTuple_GET_ITEM(info, 3);
977 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000978
979 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000980 }
981 return 0;
982}
983
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000984static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000985SyntaxError_clear(PySyntaxErrorObject *self)
986{
987 Py_CLEAR(self->msg);
988 Py_CLEAR(self->filename);
989 Py_CLEAR(self->lineno);
990 Py_CLEAR(self->offset);
991 Py_CLEAR(self->text);
992 Py_CLEAR(self->print_file_and_line);
993 return BaseException_clear((PyBaseExceptionObject *)self);
994}
995
996static void
997SyntaxError_dealloc(PySyntaxErrorObject *self)
998{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000999 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001000 SyntaxError_clear(self);
1001 self->ob_type->tp_free((PyObject *)self);
1002}
1003
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001004static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1006{
1007 Py_VISIT(self->msg);
1008 Py_VISIT(self->filename);
1009 Py_VISIT(self->lineno);
1010 Py_VISIT(self->offset);
1011 Py_VISIT(self->text);
1012 Py_VISIT(self->print_file_and_line);
1013 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1014}
1015
1016/* This is called "my_basename" instead of just "basename" to avoid name
1017 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1018 defined, and Python does define that. */
1019static char *
1020my_basename(char *name)
1021{
1022 char *cp = name;
1023 char *result = name;
1024
1025 if (name == NULL)
1026 return "???";
1027 while (*cp != '\0') {
1028 if (*cp == SEP)
1029 result = cp + 1;
1030 ++cp;
1031 }
1032 return result;
1033}
1034
1035
1036static PyObject *
1037SyntaxError_str(PySyntaxErrorObject *self)
1038{
1039 PyObject *str;
1040 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001041 int have_filename = 0;
1042 int have_lineno = 0;
1043 char *buffer = NULL;
1044 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001045
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001046 if (self->msg)
1047 str = PyObject_Str(self->msg);
1048 else
1049 str = PyObject_Str(Py_None);
1050 if (!str) return NULL;
1051 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1052 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001053
1054 /* XXX -- do all the additional formatting with filename and
1055 lineno here */
1056
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001057 have_filename = (self->filename != NULL) &&
1058 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001059 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001061 if (!have_filename && !have_lineno)
1062 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001063
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001064 bufsize = PyString_GET_SIZE(str) + 64;
1065 if (have_filename)
1066 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001068 buffer = PyMem_MALLOC(bufsize);
1069 if (buffer == NULL)
1070 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001072 if (have_filename && have_lineno)
1073 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1074 PyString_AS_STRING(str),
1075 my_basename(PyString_AS_STRING(self->filename)),
1076 PyInt_AsLong(self->lineno));
1077 else if (have_filename)
1078 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1079 PyString_AS_STRING(str),
1080 my_basename(PyString_AS_STRING(self->filename)));
1081 else /* only have_lineno */
1082 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1083 PyString_AS_STRING(str),
1084 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001085
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001086 result = PyString_FromString(buffer);
1087 PyMem_FREE(buffer);
1088
1089 if (result == NULL)
1090 result = str;
1091 else
1092 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001093 return result;
1094}
1095
1096static PyMemberDef SyntaxError_members[] = {
1097 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1098 PyDoc_STR("exception message")},
1099 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1100 PyDoc_STR("exception msg")},
1101 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1102 PyDoc_STR("exception filename")},
1103 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1104 PyDoc_STR("exception lineno")},
1105 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1106 PyDoc_STR("exception offset")},
1107 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1108 PyDoc_STR("exception text")},
1109 {"print_file_and_line", T_OBJECT,
1110 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1111 PyDoc_STR("exception print_file_and_line")},
1112 {NULL} /* Sentinel */
1113};
1114
1115ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1116 SyntaxError_dealloc, 0, SyntaxError_members,
1117 SyntaxError_str, "Invalid syntax.");
1118
1119
1120/*
1121 * IndentationError extends SyntaxError
1122 */
1123MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1124 "Improper indentation.");
1125
1126
1127/*
1128 * TabError extends IndentationError
1129 */
1130MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1131 "Improper mixture of spaces and tabs.");
1132
1133
1134/*
1135 * LookupError extends StandardError
1136 */
1137SimpleExtendsException(PyExc_StandardError, LookupError,
1138 "Base class for lookup errors.");
1139
1140
1141/*
1142 * IndexError extends LookupError
1143 */
1144SimpleExtendsException(PyExc_LookupError, IndexError,
1145 "Sequence index out of range.");
1146
1147
1148/*
1149 * KeyError extends LookupError
1150 */
1151static PyObject *
1152KeyError_str(PyBaseExceptionObject *self)
1153{
1154 /* If args is a tuple of exactly one item, apply repr to args[0].
1155 This is done so that e.g. the exception raised by {}[''] prints
1156 KeyError: ''
1157 rather than the confusing
1158 KeyError
1159 alone. The downside is that if KeyError is raised with an explanatory
1160 string, that string will be displayed in quotes. Too bad.
1161 If args is anything else, use the default BaseException__str__().
1162 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001163 if (PyTuple_GET_SIZE(self->args) == 1) {
1164 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001165 }
1166 return BaseException_str(self);
1167}
1168
1169ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1170 0, 0, 0, KeyError_str, "Mapping key not found.");
1171
1172
1173/*
1174 * ValueError extends StandardError
1175 */
1176SimpleExtendsException(PyExc_StandardError, ValueError,
1177 "Inappropriate argument value (of correct type).");
1178
1179/*
1180 * UnicodeError extends ValueError
1181 */
1182
1183SimpleExtendsException(PyExc_ValueError, UnicodeError,
1184 "Unicode related error.");
1185
Thomas Wouters477c8d52006-05-27 19:21:47 +00001186static int
1187get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1188{
1189 if (!attr) {
1190 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1191 return -1;
1192 }
1193
Guido van Rossumddefaf32007-01-14 03:31:43 +00001194 if (PyLong_Check(attr)) {
1195 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001196 if (*value == -1 && PyErr_Occurred())
1197 return -1;
1198 } else {
1199 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1200 return -1;
1201 }
1202 return 0;
1203}
1204
1205static int
1206set_ssize_t(PyObject **attr, Py_ssize_t value)
1207{
1208 PyObject *obj = PyInt_FromSsize_t(value);
1209 if (!obj)
1210 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001211 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001212 *attr = obj;
1213 return 0;
1214}
1215
1216static PyObject *
1217get_string(PyObject *attr, const char *name)
1218{
1219 if (!attr) {
1220 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1221 return NULL;
1222 }
1223
1224 if (!PyString_Check(attr)) {
1225 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1226 return NULL;
1227 }
1228 Py_INCREF(attr);
1229 return attr;
1230}
1231
1232
1233static int
1234set_string(PyObject **attr, const char *value)
1235{
1236 PyObject *obj = PyString_FromString(value);
1237 if (!obj)
1238 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001239 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001240 *attr = obj;
1241 return 0;
1242}
1243
1244
1245static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +00001246get_bytes(PyObject *attr, const char *name)
1247{
1248 if (!attr) {
1249 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1250 return NULL;
1251 }
1252
1253 if (!PyBytes_Check(attr)) {
1254 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1255 return NULL;
1256 }
1257 Py_INCREF(attr);
1258 return attr;
1259}
1260
1261static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001262get_unicode(PyObject *attr, const char *name)
1263{
1264 if (!attr) {
1265 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1266 return NULL;
1267 }
1268
1269 if (!PyUnicode_Check(attr)) {
1270 PyErr_Format(PyExc_TypeError,
1271 "%.200s attribute must be unicode", name);
1272 return NULL;
1273 }
1274 Py_INCREF(attr);
1275 return attr;
1276}
1277
1278PyObject *
1279PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1280{
1281 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1282}
1283
1284PyObject *
1285PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1286{
1287 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1288}
1289
1290PyObject *
1291PyUnicodeEncodeError_GetObject(PyObject *exc)
1292{
1293 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1294}
1295
1296PyObject *
1297PyUnicodeDecodeError_GetObject(PyObject *exc)
1298{
Walter Dörwald612344f2007-05-04 19:28:21 +00001299 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001300}
1301
1302PyObject *
1303PyUnicodeTranslateError_GetObject(PyObject *exc)
1304{
1305 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1306}
1307
1308int
1309PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1310{
1311 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1312 Py_ssize_t size;
1313 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1314 "object");
1315 if (!obj) return -1;
1316 size = PyUnicode_GET_SIZE(obj);
1317 if (*start<0)
1318 *start = 0; /*XXX check for values <0*/
1319 if (*start>=size)
1320 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001321 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322 return 0;
1323 }
1324 return -1;
1325}
1326
1327
1328int
1329PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1330{
1331 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1332 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001333 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001334 "object");
1335 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001336 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001337 if (*start<0)
1338 *start = 0;
1339 if (*start>=size)
1340 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001341 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001342 return 0;
1343 }
1344 return -1;
1345}
1346
1347
1348int
1349PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1350{
1351 return PyUnicodeEncodeError_GetStart(exc, start);
1352}
1353
1354
1355int
1356PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1357{
1358 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1359}
1360
1361
1362int
1363PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1364{
1365 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1366}
1367
1368
1369int
1370PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1371{
1372 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1373}
1374
1375
1376int
1377PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1378{
1379 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1380 Py_ssize_t size;
1381 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1382 "object");
1383 if (!obj) return -1;
1384 size = PyUnicode_GET_SIZE(obj);
1385 if (*end<1)
1386 *end = 1;
1387 if (*end>size)
1388 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001389 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390 return 0;
1391 }
1392 return -1;
1393}
1394
1395
1396int
1397PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1398{
1399 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1400 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001401 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402 "object");
1403 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001404 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405 if (*end<1)
1406 *end = 1;
1407 if (*end>size)
1408 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001409 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001410 return 0;
1411 }
1412 return -1;
1413}
1414
1415
1416int
1417PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1418{
1419 return PyUnicodeEncodeError_GetEnd(exc, start);
1420}
1421
1422
1423int
1424PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1425{
1426 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1427}
1428
1429
1430int
1431PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1432{
1433 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1434}
1435
1436
1437int
1438PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1439{
1440 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1441}
1442
1443PyObject *
1444PyUnicodeEncodeError_GetReason(PyObject *exc)
1445{
1446 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1447}
1448
1449
1450PyObject *
1451PyUnicodeDecodeError_GetReason(PyObject *exc)
1452{
1453 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1454}
1455
1456
1457PyObject *
1458PyUnicodeTranslateError_GetReason(PyObject *exc)
1459{
1460 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1461}
1462
1463
1464int
1465PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1466{
1467 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1468}
1469
1470
1471int
1472PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1473{
1474 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1475}
1476
1477
1478int
1479PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1480{
1481 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1482}
1483
1484
Thomas Wouters477c8d52006-05-27 19:21:47 +00001485static int
1486UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1487 PyTypeObject *objecttype)
1488{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001489 Py_CLEAR(self->encoding);
1490 Py_CLEAR(self->object);
1491 Py_CLEAR(self->start);
1492 Py_CLEAR(self->end);
1493 Py_CLEAR(self->reason);
1494
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1496 &PyString_Type, &self->encoding,
1497 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001498 &PyLong_Type, &self->start,
1499 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001500 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001501 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001502 self->reason = NULL;
1503 return -1;
1504 }
1505
1506 Py_INCREF(self->encoding);
1507 Py_INCREF(self->object);
1508 Py_INCREF(self->start);
1509 Py_INCREF(self->end);
1510 Py_INCREF(self->reason);
1511
1512 return 0;
1513}
1514
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001515static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516UnicodeError_clear(PyUnicodeErrorObject *self)
1517{
1518 Py_CLEAR(self->encoding);
1519 Py_CLEAR(self->object);
1520 Py_CLEAR(self->start);
1521 Py_CLEAR(self->end);
1522 Py_CLEAR(self->reason);
1523 return BaseException_clear((PyBaseExceptionObject *)self);
1524}
1525
1526static void
1527UnicodeError_dealloc(PyUnicodeErrorObject *self)
1528{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001529 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530 UnicodeError_clear(self);
1531 self->ob_type->tp_free((PyObject *)self);
1532}
1533
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001534static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1536{
1537 Py_VISIT(self->encoding);
1538 Py_VISIT(self->object);
1539 Py_VISIT(self->start);
1540 Py_VISIT(self->end);
1541 Py_VISIT(self->reason);
1542 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1543}
1544
1545static PyMemberDef UnicodeError_members[] = {
1546 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1547 PyDoc_STR("exception message")},
1548 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1549 PyDoc_STR("exception encoding")},
1550 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1551 PyDoc_STR("exception object")},
1552 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1553 PyDoc_STR("exception start")},
1554 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1555 PyDoc_STR("exception end")},
1556 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1557 PyDoc_STR("exception reason")},
1558 {NULL} /* Sentinel */
1559};
1560
1561
1562/*
1563 * UnicodeEncodeError extends UnicodeError
1564 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565
1566static int
1567UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1568{
1569 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1570 return -1;
1571 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1572 kwds, &PyUnicode_Type);
1573}
1574
1575static PyObject *
1576UnicodeEncodeError_str(PyObject *self)
1577{
1578 Py_ssize_t start;
1579 Py_ssize_t end;
1580
1581 if (PyUnicodeEncodeError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001582 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001583
1584 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001585 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001586
1587 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001588 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1589 char badchar_str[20];
1590 if (badchar <= 0xff)
1591 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1592 else if (badchar <= 0xffff)
1593 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1594 else
1595 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1596 return PyString_FromFormat(
1597 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1598 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1599 badchar_str,
1600 start,
1601 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1602 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001603 }
1604 return PyString_FromFormat(
1605 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1606 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1607 start,
1608 (end-1),
1609 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1610 );
1611}
1612
1613static PyTypeObject _PyExc_UnicodeEncodeError = {
1614 PyObject_HEAD_INIT(NULL)
1615 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001616 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001617 sizeof(PyUnicodeErrorObject), 0,
1618 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1619 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1620 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001621 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1622 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001623 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001624 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001625};
1626PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1627
1628PyObject *
1629PyUnicodeEncodeError_Create(
1630 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1631 Py_ssize_t start, Py_ssize_t end, const char *reason)
1632{
1633 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001634 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635}
1636
1637
1638/*
1639 * UnicodeDecodeError extends UnicodeError
1640 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001641
1642static int
1643UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1644{
1645 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1646 return -1;
1647 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
Walter Dörwald612344f2007-05-04 19:28:21 +00001648 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649}
1650
1651static PyObject *
1652UnicodeDecodeError_str(PyObject *self)
1653{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001654 Py_ssize_t start = 0;
1655 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656
1657 if (PyUnicodeDecodeError_GetStart(self, &start))
1658 return NULL;
1659
1660 if (PyUnicodeDecodeError_GetEnd(self, &end))
1661 return NULL;
1662
1663 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001664 /* FromFormat does not support %02x, so format that separately */
1665 char byte[4];
1666 PyOS_snprintf(byte, sizeof(byte), "%02x",
Walter Dörwald612344f2007-05-04 19:28:21 +00001667 ((int)PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001668 return PyString_FromFormat(
1669 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1670 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1671 byte,
1672 start,
1673 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1674 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675 }
1676 return PyString_FromFormat(
1677 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1678 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1679 start,
1680 (end-1),
1681 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1682 );
1683}
1684
1685static PyTypeObject _PyExc_UnicodeDecodeError = {
1686 PyObject_HEAD_INIT(NULL)
1687 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001688 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001689 sizeof(PyUnicodeErrorObject), 0,
1690 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1691 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1692 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001693 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1694 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001695 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001696 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001697};
1698PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1699
1700PyObject *
1701PyUnicodeDecodeError_Create(
1702 const char *encoding, const char *object, Py_ssize_t length,
1703 Py_ssize_t start, Py_ssize_t end, const char *reason)
1704{
1705 assert(length < INT_MAX);
1706 assert(start < INT_MAX);
1707 assert(end < INT_MAX);
Walter Dörwald612344f2007-05-04 19:28:21 +00001708 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001709 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710}
1711
1712
1713/*
1714 * UnicodeTranslateError extends UnicodeError
1715 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001716
1717static int
1718UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1719 PyObject *kwds)
1720{
1721 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1722 return -1;
1723
1724 Py_CLEAR(self->object);
1725 Py_CLEAR(self->start);
1726 Py_CLEAR(self->end);
1727 Py_CLEAR(self->reason);
1728
1729 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1730 &PyUnicode_Type, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001731 &PyLong_Type, &self->start,
1732 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001733 &PyString_Type, &self->reason)) {
1734 self->object = self->start = self->end = self->reason = NULL;
1735 return -1;
1736 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001737
Thomas Wouters477c8d52006-05-27 19:21:47 +00001738 Py_INCREF(self->object);
1739 Py_INCREF(self->start);
1740 Py_INCREF(self->end);
1741 Py_INCREF(self->reason);
1742
1743 return 0;
1744}
1745
1746
1747static PyObject *
1748UnicodeTranslateError_str(PyObject *self)
1749{
1750 Py_ssize_t start;
1751 Py_ssize_t end;
1752
1753 if (PyUnicodeTranslateError_GetStart(self, &start))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001754 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755
1756 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001757 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758
1759 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001760 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1761 char badchar_str[20];
1762 if (badchar <= 0xff)
1763 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1764 else if (badchar <= 0xffff)
1765 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1766 else
1767 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1768 return PyString_FromFormat(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001770 badchar_str,
1771 start,
1772 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1773 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001774 }
1775 return PyString_FromFormat(
1776 "can't translate characters in position %zd-%zd: %.400s",
1777 start,
1778 (end-1),
1779 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1780 );
1781}
1782
1783static PyTypeObject _PyExc_UnicodeTranslateError = {
1784 PyObject_HEAD_INIT(NULL)
1785 0,
Neal Norwitz2633c692007-02-26 22:22:47 +00001786 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001787 sizeof(PyUnicodeErrorObject), 0,
1788 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1789 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1790 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001791 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001792 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1793 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001794 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001795};
1796PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1797
1798PyObject *
1799PyUnicodeTranslateError_Create(
1800 const Py_UNICODE *object, Py_ssize_t length,
1801 Py_ssize_t start, Py_ssize_t end, const char *reason)
1802{
1803 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001804 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001805}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001806
1807
1808/*
1809 * AssertionError extends StandardError
1810 */
1811SimpleExtendsException(PyExc_StandardError, AssertionError,
1812 "Assertion failed.");
1813
1814
1815/*
1816 * ArithmeticError extends StandardError
1817 */
1818SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1819 "Base class for arithmetic errors.");
1820
1821
1822/*
1823 * FloatingPointError extends ArithmeticError
1824 */
1825SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1826 "Floating point operation failed.");
1827
1828
1829/*
1830 * OverflowError extends ArithmeticError
1831 */
1832SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1833 "Result too large to be represented.");
1834
1835
1836/*
1837 * ZeroDivisionError extends ArithmeticError
1838 */
1839SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1840 "Second argument to a division or modulo operation was zero.");
1841
1842
1843/*
1844 * SystemError extends StandardError
1845 */
1846SimpleExtendsException(PyExc_StandardError, SystemError,
1847 "Internal error in the Python interpreter.\n"
1848 "\n"
1849 "Please report this to the Python maintainer, along with the traceback,\n"
1850 "the Python version, and the hardware/OS platform and version.");
1851
1852
1853/*
1854 * ReferenceError extends StandardError
1855 */
1856SimpleExtendsException(PyExc_StandardError, ReferenceError,
1857 "Weak ref proxy used after referent went away.");
1858
1859
1860/*
1861 * MemoryError extends StandardError
1862 */
1863SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1864
1865
1866/* Warning category docstrings */
1867
1868/*
1869 * Warning extends Exception
1870 */
1871SimpleExtendsException(PyExc_Exception, Warning,
1872 "Base class for warning categories.");
1873
1874
1875/*
1876 * UserWarning extends Warning
1877 */
1878SimpleExtendsException(PyExc_Warning, UserWarning,
1879 "Base class for warnings generated by user code.");
1880
1881
1882/*
1883 * DeprecationWarning extends Warning
1884 */
1885SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1886 "Base class for warnings about deprecated features.");
1887
1888
1889/*
1890 * PendingDeprecationWarning extends Warning
1891 */
1892SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1893 "Base class for warnings about features which will be deprecated\n"
1894 "in the future.");
1895
1896
1897/*
1898 * SyntaxWarning extends Warning
1899 */
1900SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1901 "Base class for warnings about dubious syntax.");
1902
1903
1904/*
1905 * RuntimeWarning extends Warning
1906 */
1907SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1908 "Base class for warnings about dubious runtime behavior.");
1909
1910
1911/*
1912 * FutureWarning extends Warning
1913 */
1914SimpleExtendsException(PyExc_Warning, FutureWarning,
1915 "Base class for warnings about constructs that will change semantically\n"
1916 "in the future.");
1917
1918
1919/*
1920 * ImportWarning extends Warning
1921 */
1922SimpleExtendsException(PyExc_Warning, ImportWarning,
1923 "Base class for warnings about probable mistakes in module imports");
1924
1925
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001926/*
1927 * UnicodeWarning extends Warning
1928 */
1929SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1930 "Base class for warnings about Unicode related problems, mostly\n"
1931 "related to conversion problems.");
1932
1933
Thomas Wouters477c8d52006-05-27 19:21:47 +00001934/* Pre-computed MemoryError instance. Best to create this as early as
1935 * possible and not wait until a MemoryError is actually raised!
1936 */
1937PyObject *PyExc_MemoryErrorInst=NULL;
1938
Thomas Wouters477c8d52006-05-27 19:21:47 +00001939#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1940 Py_FatalError("exceptions bootstrapping error.");
1941
1942#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001943 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1944 Py_FatalError("Module dictionary insertion problem.");
1945
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001946#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1947/* crt variable checking in VisualStudio .NET 2005 */
1948#include <crtdbg.h>
1949
1950static int prevCrtReportMode;
1951static _invalid_parameter_handler prevCrtHandler;
1952
1953/* Invalid parameter handler. Sets a ValueError exception */
1954static void
1955InvalidParameterHandler(
1956 const wchar_t * expression,
1957 const wchar_t * function,
1958 const wchar_t * file,
1959 unsigned int line,
1960 uintptr_t pReserved)
1961{
1962 /* Do nothing, allow execution to continue. Usually this
1963 * means that the CRT will set errno to EINVAL
1964 */
1965}
1966#endif
1967
1968
Thomas Wouters477c8d52006-05-27 19:21:47 +00001969PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001970_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971{
Neal Norwitz2633c692007-02-26 22:22:47 +00001972 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001973
1974 PRE_INIT(BaseException)
1975 PRE_INIT(Exception)
1976 PRE_INIT(StandardError)
1977 PRE_INIT(TypeError)
1978 PRE_INIT(StopIteration)
1979 PRE_INIT(GeneratorExit)
1980 PRE_INIT(SystemExit)
1981 PRE_INIT(KeyboardInterrupt)
1982 PRE_INIT(ImportError)
1983 PRE_INIT(EnvironmentError)
1984 PRE_INIT(IOError)
1985 PRE_INIT(OSError)
1986#ifdef MS_WINDOWS
1987 PRE_INIT(WindowsError)
1988#endif
1989#ifdef __VMS
1990 PRE_INIT(VMSError)
1991#endif
1992 PRE_INIT(EOFError)
1993 PRE_INIT(RuntimeError)
1994 PRE_INIT(NotImplementedError)
1995 PRE_INIT(NameError)
1996 PRE_INIT(UnboundLocalError)
1997 PRE_INIT(AttributeError)
1998 PRE_INIT(SyntaxError)
1999 PRE_INIT(IndentationError)
2000 PRE_INIT(TabError)
2001 PRE_INIT(LookupError)
2002 PRE_INIT(IndexError)
2003 PRE_INIT(KeyError)
2004 PRE_INIT(ValueError)
2005 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002006 PRE_INIT(UnicodeEncodeError)
2007 PRE_INIT(UnicodeDecodeError)
2008 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002009 PRE_INIT(AssertionError)
2010 PRE_INIT(ArithmeticError)
2011 PRE_INIT(FloatingPointError)
2012 PRE_INIT(OverflowError)
2013 PRE_INIT(ZeroDivisionError)
2014 PRE_INIT(SystemError)
2015 PRE_INIT(ReferenceError)
2016 PRE_INIT(MemoryError)
2017 PRE_INIT(Warning)
2018 PRE_INIT(UserWarning)
2019 PRE_INIT(DeprecationWarning)
2020 PRE_INIT(PendingDeprecationWarning)
2021 PRE_INIT(SyntaxWarning)
2022 PRE_INIT(RuntimeWarning)
2023 PRE_INIT(FutureWarning)
2024 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002025 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002026
Thomas Wouters477c8d52006-05-27 19:21:47 +00002027 bltinmod = PyImport_ImportModule("__builtin__");
2028 if (bltinmod == NULL)
2029 Py_FatalError("exceptions bootstrapping error.");
2030 bdict = PyModule_GetDict(bltinmod);
2031 if (bdict == NULL)
2032 Py_FatalError("exceptions bootstrapping error.");
2033
2034 POST_INIT(BaseException)
2035 POST_INIT(Exception)
2036 POST_INIT(StandardError)
2037 POST_INIT(TypeError)
2038 POST_INIT(StopIteration)
2039 POST_INIT(GeneratorExit)
2040 POST_INIT(SystemExit)
2041 POST_INIT(KeyboardInterrupt)
2042 POST_INIT(ImportError)
2043 POST_INIT(EnvironmentError)
2044 POST_INIT(IOError)
2045 POST_INIT(OSError)
2046#ifdef MS_WINDOWS
2047 POST_INIT(WindowsError)
2048#endif
2049#ifdef __VMS
2050 POST_INIT(VMSError)
2051#endif
2052 POST_INIT(EOFError)
2053 POST_INIT(RuntimeError)
2054 POST_INIT(NotImplementedError)
2055 POST_INIT(NameError)
2056 POST_INIT(UnboundLocalError)
2057 POST_INIT(AttributeError)
2058 POST_INIT(SyntaxError)
2059 POST_INIT(IndentationError)
2060 POST_INIT(TabError)
2061 POST_INIT(LookupError)
2062 POST_INIT(IndexError)
2063 POST_INIT(KeyError)
2064 POST_INIT(ValueError)
2065 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002066 POST_INIT(UnicodeEncodeError)
2067 POST_INIT(UnicodeDecodeError)
2068 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002069 POST_INIT(AssertionError)
2070 POST_INIT(ArithmeticError)
2071 POST_INIT(FloatingPointError)
2072 POST_INIT(OverflowError)
2073 POST_INIT(ZeroDivisionError)
2074 POST_INIT(SystemError)
2075 POST_INIT(ReferenceError)
2076 POST_INIT(MemoryError)
2077 POST_INIT(Warning)
2078 POST_INIT(UserWarning)
2079 POST_INIT(DeprecationWarning)
2080 POST_INIT(PendingDeprecationWarning)
2081 POST_INIT(SyntaxWarning)
2082 POST_INIT(RuntimeWarning)
2083 POST_INIT(FutureWarning)
2084 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002085 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002086
2087 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2088 if (!PyExc_MemoryErrorInst)
2089 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2090
2091 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002092
2093#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2094 /* Set CRT argument error handler */
2095 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2096 /* turn off assertions in debug mode */
2097 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2098#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002099}
2100
2101void
2102_PyExc_Fini(void)
2103{
2104 Py_XDECREF(PyExc_MemoryErrorInst);
2105 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002106#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2107 /* reset CRT error handling */
2108 _set_invalid_parameter_handler(prevCrtHandler);
2109 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2110#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002111}