blob: acc7da50c16119e52df393efe6d443cef3d55700 [file] [log] [blame]
Georg Brandl43ab1002006-05-28 20:57:09 +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
Richard Jones7b9558d2006-05-27 12:29:24 +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);
13#define EXC_MODULE_NAME "exceptions."
14
Richard Jonesc5b2a2e2006-05-27 16:07:28 +000015/* NOTE: If the exception class hierarchy changes, don't forget to update
16 * Lib/test/exception_hierarchy.txt
17 */
18
19PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
20\n\
21Exceptions found here are defined both in the exceptions module and the\n\
22built-in namespace. It is recommended that user-defined exceptions\n\
23inherit from Exception. See the documentation for the exception\n\
24inheritance hierarchy.\n\
25");
26
Richard Jones7b9558d2006-05-27 12:29:24 +000027/*
28 * BaseException
29 */
30static PyObject *
31BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
32{
33 PyBaseExceptionObject *self;
34
35 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
36 /* the dict is created on the fly in PyObject_GenericSetAttr */
37 self->message = self->dict = NULL;
38
39 self->args = PyTuple_New(0);
40 if (!self->args) {
41 Py_DECREF(self);
42 return NULL;
43 }
44
Michael W. Hudson22a80e72006-05-28 15:51:40 +000045 self->message = PyString_FromString("");
Richard Jones7b9558d2006-05-27 12:29:24 +000046 if (!self->message) {
47 Py_DECREF(self);
48 return NULL;
49 }
50
51 return (PyObject *)self;
52}
53
54static int
55BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
56{
Georg Brandlb0432bc2006-05-30 08:17:00 +000057 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
58 return -1;
59
Richard Jones7b9558d2006-05-27 12:29:24 +000060 Py_DECREF(self->args);
61 self->args = args;
62 Py_INCREF(self->args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +000065 Py_CLEAR(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000066 self->message = PyTuple_GET_ITEM(self->args, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +000067 Py_INCREF(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000068 }
69 return 0;
70}
71
Michael W. Hudson96495ee2006-05-28 17:40:29 +000072static int
Richard Jones7b9558d2006-05-27 12:29:24 +000073BaseException_clear(PyBaseExceptionObject *self)
74{
75 Py_CLEAR(self->dict);
76 Py_CLEAR(self->args);
77 Py_CLEAR(self->message);
78 return 0;
79}
80
81static void
82BaseException_dealloc(PyBaseExceptionObject *self)
83{
84 BaseException_clear(self);
85 self->ob_type->tp_free((PyObject *)self);
86}
87
Michael W. Hudson96495ee2006-05-28 17:40:29 +000088static int
Richard Jones7b9558d2006-05-27 12:29:24 +000089BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
90{
Michael W. Hudson22a80e72006-05-28 15:51:40 +000091 Py_VISIT(self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +000092 Py_VISIT(self->args);
93 Py_VISIT(self->message);
94 return 0;
95}
96
97static PyObject *
98BaseException_str(PyBaseExceptionObject *self)
99{
100 PyObject *out;
101
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000102 switch (PyTuple_GET_SIZE(self->args)) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000103 case 0:
104 out = PyString_FromString("");
105 break;
106 case 1:
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000107 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000108 break;
Richard Jones7b9558d2006-05-27 12:29:24 +0000109 default:
110 out = PyObject_Str(self->args);
111 break;
112 }
113
114 return out;
115}
116
117static PyObject *
118BaseException_repr(PyBaseExceptionObject *self)
119{
Richard Jones7b9558d2006-05-27 12:29:24 +0000120 PyObject *repr_suffix;
121 PyObject *repr;
122 char *name;
123 char *dot;
124
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000125 repr_suffix = PyObject_Repr(self->args);
126 if (!repr_suffix)
Richard Jones7b9558d2006-05-27 12:29:24 +0000127 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000128
129 name = (char *)self->ob_type->tp_name;
130 dot = strrchr(name, '.');
131 if (dot != NULL) name = dot+1;
132
133 repr = PyString_FromString(name);
134 if (!repr) {
135 Py_DECREF(repr_suffix);
136 return NULL;
137 }
138
139 PyString_ConcatAndDel(&repr, repr_suffix);
140 return repr;
141}
142
143/* Pickling support */
144static PyObject *
145BaseException_reduce(PyBaseExceptionObject *self)
146{
Georg Brandlddba4732006-05-30 07:04:55 +0000147 if (self->args && self->dict)
148 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000149 else
Georg Brandlddba4732006-05-30 07:04:55 +0000150 return PyTuple_Pack(2, self->ob_type, self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000151}
152
Georg Brandl85ac8502006-06-01 06:39:19 +0000153/*
154 * Needed for backward compatibility, since exceptions used to store
155 * all their attributes in the __dict__. Code is taken from cPickle's
156 * load_build function.
157 */
158static PyObject *
159BaseException_setstate(PyObject *self, PyObject *state)
160{
161 PyObject *d_key, *d_value;
162 Py_ssize_t i = 0;
163
164 if (state != Py_None) {
165 if (!PyDict_Check(state)) {
166 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
167 return NULL;
168 }
169 while (PyDict_Next(state, &i, &d_key, &d_value)) {
170 if (PyObject_SetAttr(self, d_key, d_value) < 0)
171 return NULL;
172 }
173 }
174 Py_RETURN_NONE;
175}
Richard Jones7b9558d2006-05-27 12:29:24 +0000176
177#ifdef Py_USING_UNICODE
178/* while this method generates fairly uninspired output, it a least
179 * guarantees that we can display exceptions that have unicode attributes
180 */
181static PyObject *
182BaseException_unicode(PyBaseExceptionObject *self)
183{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000184 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000185 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000186 if (PyTuple_GET_SIZE(self->args) == 1)
187 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000188 return PyObject_Unicode(self->args);
189}
190#endif /* Py_USING_UNICODE */
191
192static PyMethodDef BaseException_methods[] = {
193 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Georg Brandl85ac8502006-06-01 06:39:19 +0000194 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Richard Jones7b9558d2006-05-27 12:29:24 +0000195#ifdef Py_USING_UNICODE
196 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
197#endif
198 {NULL, NULL, 0, NULL},
199};
200
201
202
203static PyObject *
204BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
205{
206 return PySequence_GetItem(self->args, index);
207}
208
209static PySequenceMethods BaseException_as_sequence = {
210 0, /* sq_length; */
211 0, /* sq_concat; */
212 0, /* sq_repeat; */
213 (ssizeargfunc)BaseException_getitem, /* sq_item; */
214 0, /* sq_slice; */
215 0, /* sq_ass_item; */
216 0, /* sq_ass_slice; */
217 0, /* sq_contains; */
218 0, /* sq_inplace_concat; */
219 0 /* sq_inplace_repeat; */
220};
221
222static PyMemberDef BaseException_members[] = {
223 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
224 PyDoc_STR("exception message")},
225 {NULL} /* Sentinel */
226};
227
228
229static PyObject *
230BaseException_get_dict(PyBaseExceptionObject *self)
231{
232 if (self->dict == NULL) {
233 self->dict = PyDict_New();
234 if (!self->dict)
235 return NULL;
236 }
237 Py_INCREF(self->dict);
238 return self->dict;
239}
240
241static int
242BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
243{
244 if (val == NULL) {
245 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
246 return -1;
247 }
248 if (!PyDict_Check(val)) {
249 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
250 return -1;
251 }
252 Py_CLEAR(self->dict);
253 Py_INCREF(val);
254 self->dict = val;
255 return 0;
256}
257
258static PyObject *
259BaseException_get_args(PyBaseExceptionObject *self)
260{
261 if (self->args == NULL) {
262 Py_INCREF(Py_None);
263 return Py_None;
264 }
265 Py_INCREF(self->args);
266 return self->args;
267}
268
269static int
270BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
271{
272 PyObject *seq;
273 if (val == NULL) {
274 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
275 return -1;
276 }
277 seq = PySequence_Tuple(val);
278 if (!seq) return -1;
Georg Brandlc7c51142006-05-29 09:46:51 +0000279 Py_CLEAR(self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000280 self->args = seq;
281 return 0;
282}
283
284static PyGetSetDef BaseException_getset[] = {
285 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
286 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
287 {NULL},
288};
289
290
291static PyTypeObject _PyExc_BaseException = {
292 PyObject_HEAD_INIT(NULL)
293 0, /*ob_size*/
294 EXC_MODULE_NAME "BaseException", /*tp_name*/
295 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
296 0, /*tp_itemsize*/
297 (destructor)BaseException_dealloc, /*tp_dealloc*/
298 0, /*tp_print*/
299 0, /*tp_getattr*/
300 0, /*tp_setattr*/
301 0, /* tp_compare; */
302 (reprfunc)BaseException_repr, /*tp_repr*/
303 0, /*tp_as_number*/
304 &BaseException_as_sequence, /*tp_as_sequence*/
305 0, /*tp_as_mapping*/
306 0, /*tp_hash */
307 0, /*tp_call*/
308 (reprfunc)BaseException_str, /*tp_str*/
309 PyObject_GenericGetAttr, /*tp_getattro*/
310 PyObject_GenericSetAttr, /*tp_setattro*/
311 0, /*tp_as_buffer*/
312 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
313 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
314 (traverseproc)BaseException_traverse, /* tp_traverse */
315 (inquiry)BaseException_clear, /* tp_clear */
316 0, /* tp_richcompare */
317 0, /* tp_weaklistoffset */
318 0, /* tp_iter */
319 0, /* tp_iternext */
320 BaseException_methods, /* tp_methods */
321 BaseException_members, /* tp_members */
322 BaseException_getset, /* tp_getset */
323 0, /* tp_base */
324 0, /* tp_dict */
325 0, /* tp_descr_get */
326 0, /* tp_descr_set */
327 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
328 (initproc)BaseException_init, /* tp_init */
329 0, /* tp_alloc */
330 BaseException_new, /* tp_new */
331};
332/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
333from the previous implmentation and also allowing Python objects to be used
334in the API */
335PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
336
Richard Jones2d555b32006-05-27 16:15:11 +0000337/* note these macros omit the last semicolon so the macro invocation may
338 * include it and not look strange.
339 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000340#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
341static PyTypeObject _PyExc_ ## EXCNAME = { \
342 PyObject_HEAD_INIT(NULL) \
343 0, \
344 EXC_MODULE_NAME # EXCNAME, \
345 sizeof(PyBaseExceptionObject), \
346 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
347 0, 0, 0, 0, 0, 0, 0, \
348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
349 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
350 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
351 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
352 (initproc)BaseException_init, 0, BaseException_new,\
353}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000354PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000355
356#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
357static PyTypeObject _PyExc_ ## EXCNAME = { \
358 PyObject_HEAD_INIT(NULL) \
359 0, \
360 EXC_MODULE_NAME # EXCNAME, \
361 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000362 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000363 0, 0, 0, 0, 0, \
364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000365 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
366 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000367 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000368 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000369}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000370PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000371
372#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
373static PyTypeObject _PyExc_ ## EXCNAME = { \
374 PyObject_HEAD_INIT(NULL) \
375 0, \
376 EXC_MODULE_NAME # EXCNAME, \
377 sizeof(Py ## EXCSTORE ## Object), 0, \
378 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
379 (reprfunc)EXCSTR, 0, 0, 0, \
380 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
381 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
382 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
383 EXCMEMBERS, 0, &_ ## EXCBASE, \
384 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000385 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000386}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000387PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000388
389
390/*
391 * Exception extends BaseException
392 */
393SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000394 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000395
396
397/*
398 * StandardError extends Exception
399 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000400SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000401 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000402 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000403
404
405/*
406 * TypeError extends StandardError
407 */
408SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000409 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000410
411
412/*
413 * StopIteration extends Exception
414 */
415SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000416 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000417
418
419/*
420 * GeneratorExit extends Exception
421 */
422SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000423 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000424
425
426/*
427 * SystemExit extends BaseException
428 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000429
430static int
431SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
432{
433 Py_ssize_t size = PyTuple_GET_SIZE(args);
434
435 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
436 return -1;
437
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000438 if (size == 0)
439 return 0;
440 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000441 if (size == 1)
442 self->code = PyTuple_GET_ITEM(args, 0);
443 else if (size > 1)
444 self->code = args;
445 Py_INCREF(self->code);
446 return 0;
447}
448
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000449static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000450SystemExit_clear(PySystemExitObject *self)
451{
452 Py_CLEAR(self->code);
453 return BaseException_clear((PyBaseExceptionObject *)self);
454}
455
456static void
457SystemExit_dealloc(PySystemExitObject *self)
458{
459 SystemExit_clear(self);
460 self->ob_type->tp_free((PyObject *)self);
461}
462
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000463static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000464SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
465{
466 Py_VISIT(self->code);
467 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
468}
469
470static PyMemberDef SystemExit_members[] = {
471 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
472 PyDoc_STR("exception message")},
473 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
474 PyDoc_STR("exception code")},
475 {NULL} /* Sentinel */
476};
477
478ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
479 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000480 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000481
482/*
483 * KeyboardInterrupt extends BaseException
484 */
485SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000486 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000487
488
489/*
490 * ImportError extends StandardError
491 */
492SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000493 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000494
495
496/*
497 * EnvironmentError extends StandardError
498 */
499
Richard Jones7b9558d2006-05-27 12:29:24 +0000500/* Where a function has a single filename, such as open() or some
501 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
502 * called, giving a third argument which is the filename. But, so
503 * that old code using in-place unpacking doesn't break, e.g.:
504 *
505 * except IOError, (errno, strerror):
506 *
507 * we hack args so that it only contains two items. This also
508 * means we need our own __str__() which prints out the filename
509 * when it was supplied.
510 */
511static int
512EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
513 PyObject *kwds)
514{
515 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
516 PyObject *subslice = NULL;
517
518 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
519 return -1;
520
521 if (PyTuple_GET_SIZE(args) <= 1) {
522 return 0;
523 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000524
525 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000526 &myerrno, &strerror, &filename)) {
527 return -1;
528 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000529 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000530 self->myerrno = myerrno;
531 Py_INCREF(self->myerrno);
532
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000533 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000534 self->strerror = strerror;
535 Py_INCREF(self->strerror);
536
537 /* self->filename will remain Py_None otherwise */
538 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000539 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000540 self->filename = filename;
541 Py_INCREF(self->filename);
542
543 subslice = PyTuple_GetSlice(args, 0, 2);
544 if (!subslice)
545 return -1;
546
547 Py_DECREF(self->args); /* replacing args */
548 self->args = subslice;
549 }
550 return 0;
551}
552
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000553static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000554EnvironmentError_clear(PyEnvironmentErrorObject *self)
555{
556 Py_CLEAR(self->myerrno);
557 Py_CLEAR(self->strerror);
558 Py_CLEAR(self->filename);
559 return BaseException_clear((PyBaseExceptionObject *)self);
560}
561
562static void
563EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
564{
565 EnvironmentError_clear(self);
566 self->ob_type->tp_free((PyObject *)self);
567}
568
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000569static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000570EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
571 void *arg)
572{
573 Py_VISIT(self->myerrno);
574 Py_VISIT(self->strerror);
575 Py_VISIT(self->filename);
576 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
577}
578
579static PyObject *
580EnvironmentError_str(PyEnvironmentErrorObject *self)
581{
582 PyObject *rtnval = NULL;
583
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000584 if (self->filename) {
585 PyObject *fmt;
586 PyObject *repr;
587 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000588
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000589 fmt = PyString_FromString("[Errno %s] %s: %s");
590 if (!fmt)
591 return NULL;
592
593 repr = PyObject_Repr(self->filename);
594 if (!repr) {
595 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000596 return NULL;
597 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000598 tuple = PyTuple_New(3);
599 if (!tuple) {
600 Py_DECREF(repr);
601 Py_DECREF(fmt);
602 return NULL;
603 }
604
605 if (self->myerrno) {
606 Py_INCREF(self->myerrno);
607 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
608 }
609 else {
610 Py_INCREF(Py_None);
611 PyTuple_SET_ITEM(tuple, 0, Py_None);
612 }
613 if (self->strerror) {
614 Py_INCREF(self->strerror);
615 PyTuple_SET_ITEM(tuple, 1, self->strerror);
616 }
617 else {
618 Py_INCREF(Py_None);
619 PyTuple_SET_ITEM(tuple, 1, Py_None);
620 }
621
Richard Jones7b9558d2006-05-27 12:29:24 +0000622 Py_INCREF(repr);
623 PyTuple_SET_ITEM(tuple, 2, repr);
624
625 rtnval = PyString_Format(fmt, tuple);
626
627 Py_DECREF(fmt);
628 Py_DECREF(tuple);
629 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000630 else if (self->myerrno && self->strerror) {
631 PyObject *fmt;
632 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000633
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000634 fmt = PyString_FromString("[Errno %s] %s");
635 if (!fmt)
636 return NULL;
637
638 tuple = PyTuple_New(2);
639 if (!tuple) {
640 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000641 return NULL;
642 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000643
644 if (self->myerrno) {
645 Py_INCREF(self->myerrno);
646 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
647 }
648 else {
649 Py_INCREF(Py_None);
650 PyTuple_SET_ITEM(tuple, 0, Py_None);
651 }
652 if (self->strerror) {
653 Py_INCREF(self->strerror);
654 PyTuple_SET_ITEM(tuple, 1, self->strerror);
655 }
656 else {
657 Py_INCREF(Py_None);
658 PyTuple_SET_ITEM(tuple, 1, Py_None);
659 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000660
661 rtnval = PyString_Format(fmt, tuple);
662
663 Py_DECREF(fmt);
664 Py_DECREF(tuple);
665 }
666 else
667 rtnval = BaseException_str((PyBaseExceptionObject *)self);
668
669 return rtnval;
670}
671
672static PyMemberDef EnvironmentError_members[] = {
673 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
674 PyDoc_STR("exception message")},
675 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000676 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000677 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000678 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000679 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000680 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000681 {NULL} /* Sentinel */
682};
683
684
685static PyObject *
686EnvironmentError_reduce(PyEnvironmentErrorObject *self)
687{
688 PyObject *args = self->args;
689 PyObject *res = NULL, *tmp;
Georg Brandl05f97bf2006-05-30 07:13:29 +0000690
Richard Jones7b9558d2006-05-27 12:29:24 +0000691 /* self->args is only the first two real arguments if there was a
692 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000693 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000694 args = PyTuple_New(3);
695 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000696
697 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000698 Py_INCREF(tmp);
699 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000700
701 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000702 Py_INCREF(tmp);
703 PyTuple_SET_ITEM(args, 1, tmp);
704
705 Py_INCREF(self->filename);
706 PyTuple_SET_ITEM(args, 2, self->filename);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000707 } else
Richard Jones7b9558d2006-05-27 12:29:24 +0000708 Py_INCREF(args);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000709
710 if (self->dict)
711 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
712 else
713 res = PyTuple_Pack(2, self->ob_type, args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000714 Py_DECREF(args);
715 return res;
716}
717
718
719static PyMethodDef EnvironmentError_methods[] = {
720 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
721 {NULL}
722};
723
724ComplexExtendsException(PyExc_StandardError, EnvironmentError,
725 EnvironmentError, EnvironmentError_dealloc,
726 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000727 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000728 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000729
730
731/*
732 * IOError extends EnvironmentError
733 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000734MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000735 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000736
737
738/*
739 * OSError extends EnvironmentError
740 */
741MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000742 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000743
744
745/*
746 * WindowsError extends OSError
747 */
748#ifdef MS_WINDOWS
749#include "errmap.h"
750
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000751static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000752WindowsError_clear(PyWindowsErrorObject *self)
753{
754 Py_CLEAR(self->myerrno);
755 Py_CLEAR(self->strerror);
756 Py_CLEAR(self->filename);
757 Py_CLEAR(self->winerror);
758 return BaseException_clear((PyBaseExceptionObject *)self);
759}
760
761static void
762WindowsError_dealloc(PyWindowsErrorObject *self)
763{
764 WindowsError_clear(self);
765 self->ob_type->tp_free((PyObject *)self);
766}
767
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000768static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000769WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
770{
771 Py_VISIT(self->myerrno);
772 Py_VISIT(self->strerror);
773 Py_VISIT(self->filename);
774 Py_VISIT(self->winerror);
775 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
776}
777
Richard Jones7b9558d2006-05-27 12:29:24 +0000778static int
779WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
780{
781 PyObject *o_errcode = NULL;
782 long errcode;
783 long posix_errno;
784
785 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
786 == -1)
787 return -1;
788
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000789 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000790 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000791
792 /* Set errno to the POSIX errno, and winerror to the Win32
793 error code. */
794 errcode = PyInt_AsLong(self->myerrno);
795 if (errcode == -1 && PyErr_Occurred())
796 return -1;
797 posix_errno = winerror_to_errno(errcode);
798
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000799 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000800 self->winerror = self->myerrno;
801
802 o_errcode = PyInt_FromLong(posix_errno);
803 if (!o_errcode)
804 return -1;
805
806 self->myerrno = o_errcode;
807
808 return 0;
809}
810
811
812static PyObject *
813WindowsError_str(PyWindowsErrorObject *self)
814{
Richard Jones7b9558d2006-05-27 12:29:24 +0000815 PyObject *rtnval = NULL;
816
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000817 if (self->filename) {
818 PyObject *fmt;
819 PyObject *repr;
820 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000821
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000822 fmt = PyString_FromString("[Error %s] %s: %s");
823 if (!fmt)
824 return NULL;
825
826 repr = PyObject_Repr(self->filename);
827 if (!repr) {
828 Py_DECREF(fmt);
829 return NULL;
830 }
831 tuple = PyTuple_New(3);
832 if (!tuple) {
833 Py_DECREF(repr);
834 Py_DECREF(fmt);
835 return NULL;
836 }
837
838 if (self->myerrno) {
839 Py_INCREF(self->myerrno);
840 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
841 }
842 else {
843 Py_INCREF(Py_None);
844 PyTuple_SET_ITEM(tuple, 0, Py_None);
845 }
846 if (self->strerror) {
847 Py_INCREF(self->strerror);
848 PyTuple_SET_ITEM(tuple, 1, self->strerror);
849 }
850 else {
851 Py_INCREF(Py_None);
852 PyTuple_SET_ITEM(tuple, 1, Py_None);
853 }
854
855 Py_INCREF(repr);
856 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000857
858 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000859
860 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000861 Py_DECREF(tuple);
862 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000863 else if (self->myerrno && self->strerror) {
864 PyObject *fmt;
865 PyObject *tuple;
866
Richard Jones7b9558d2006-05-27 12:29:24 +0000867 fmt = PyString_FromString("[Error %s] %s");
868 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000869 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000870
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000871 tuple = PyTuple_New(2);
872 if (!tuple) {
873 Py_DECREF(fmt);
874 return NULL;
875 }
876
877 if (self->myerrno) {
878 Py_INCREF(self->myerrno);
879 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
880 }
881 else {
882 Py_INCREF(Py_None);
883 PyTuple_SET_ITEM(tuple, 0, Py_None);
884 }
885 if (self->strerror) {
886 Py_INCREF(self->strerror);
887 PyTuple_SET_ITEM(tuple, 1, self->strerror);
888 }
889 else {
890 Py_INCREF(Py_None);
891 PyTuple_SET_ITEM(tuple, 1, Py_None);
892 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000893
894 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000895
896 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000897 Py_DECREF(tuple);
898 }
899 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000900 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000901
Richard Jones7b9558d2006-05-27 12:29:24 +0000902 return rtnval;
903}
904
905static PyMemberDef WindowsError_members[] = {
906 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
907 PyDoc_STR("exception message")},
908 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000909 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000910 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000911 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000912 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000913 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000914 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000915 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000916 {NULL} /* Sentinel */
917};
918
Richard Jones2d555b32006-05-27 16:15:11 +0000919ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
920 WindowsError_dealloc, 0, WindowsError_members,
921 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000922
923#endif /* MS_WINDOWS */
924
925
926/*
927 * VMSError extends OSError (I think)
928 */
929#ifdef __VMS
930MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000931 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000932#endif
933
934
935/*
936 * EOFError extends StandardError
937 */
938SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000939 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000940
941
942/*
943 * RuntimeError extends StandardError
944 */
945SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000946 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000947
948
949/*
950 * NotImplementedError extends RuntimeError
951 */
952SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000953 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000954
955/*
956 * NameError extends StandardError
957 */
958SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000959 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000960
961/*
962 * UnboundLocalError extends NameError
963 */
964SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000965 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000966
967/*
968 * AttributeError extends StandardError
969 */
970SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000971 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000972
973
974/*
975 * SyntaxError extends StandardError
976 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000977
978static int
979SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
980{
981 PyObject *info = NULL;
982 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
983
984 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
985 return -1;
986
987 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000988 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000989 self->msg = PyTuple_GET_ITEM(args, 0);
990 Py_INCREF(self->msg);
991 }
992 if (lenargs == 2) {
993 info = PyTuple_GET_ITEM(args, 1);
994 info = PySequence_Tuple(info);
995 if (!info) return -1;
996
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000997 if (PyTuple_GET_SIZE(info) != 4) {
998 /* not a very good error message, but it's what Python 2.4 gives */
999 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
1000 Py_DECREF(info);
1001 return -1;
1002 }
1003
1004 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001005 self->filename = PyTuple_GET_ITEM(info, 0);
1006 Py_INCREF(self->filename);
1007
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001008 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001009 self->lineno = PyTuple_GET_ITEM(info, 1);
1010 Py_INCREF(self->lineno);
1011
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001012 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +00001013 self->offset = PyTuple_GET_ITEM(info, 2);
1014 Py_INCREF(self->offset);
1015
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001016 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +00001017 self->text = PyTuple_GET_ITEM(info, 3);
1018 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001019
1020 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +00001021 }
1022 return 0;
1023}
1024
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001025static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001026SyntaxError_clear(PySyntaxErrorObject *self)
1027{
1028 Py_CLEAR(self->msg);
1029 Py_CLEAR(self->filename);
1030 Py_CLEAR(self->lineno);
1031 Py_CLEAR(self->offset);
1032 Py_CLEAR(self->text);
1033 Py_CLEAR(self->print_file_and_line);
1034 return BaseException_clear((PyBaseExceptionObject *)self);
1035}
1036
1037static void
1038SyntaxError_dealloc(PySyntaxErrorObject *self)
1039{
1040 SyntaxError_clear(self);
1041 self->ob_type->tp_free((PyObject *)self);
1042}
1043
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001044static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001045SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1046{
1047 Py_VISIT(self->msg);
1048 Py_VISIT(self->filename);
1049 Py_VISIT(self->lineno);
1050 Py_VISIT(self->offset);
1051 Py_VISIT(self->text);
1052 Py_VISIT(self->print_file_and_line);
1053 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1054}
1055
1056/* This is called "my_basename" instead of just "basename" to avoid name
1057 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1058 defined, and Python does define that. */
1059static char *
1060my_basename(char *name)
1061{
1062 char *cp = name;
1063 char *result = name;
1064
1065 if (name == NULL)
1066 return "???";
1067 while (*cp != '\0') {
1068 if (*cp == SEP)
1069 result = cp + 1;
1070 ++cp;
1071 }
1072 return result;
1073}
1074
1075
1076static PyObject *
1077SyntaxError_str(PySyntaxErrorObject *self)
1078{
1079 PyObject *str;
1080 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001081 int have_filename = 0;
1082 int have_lineno = 0;
1083 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001084 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001085
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001086 if (self->msg)
1087 str = PyObject_Str(self->msg);
1088 else
1089 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001090 if (!str) return NULL;
1091 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1092 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001093
1094 /* XXX -- do all the additional formatting with filename and
1095 lineno here */
1096
Georg Brandl43ab1002006-05-28 20:57:09 +00001097 have_filename = (self->filename != NULL) &&
1098 PyString_Check(self->filename);
1099 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001100
Georg Brandl43ab1002006-05-28 20:57:09 +00001101 if (!have_filename && !have_lineno)
1102 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001103
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001104 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001105 if (have_filename)
1106 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001107
Georg Brandl43ab1002006-05-28 20:57:09 +00001108 buffer = PyMem_MALLOC(bufsize);
1109 if (buffer == NULL)
1110 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001111
Georg Brandl43ab1002006-05-28 20:57:09 +00001112 if (have_filename && have_lineno)
1113 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1114 PyString_AS_STRING(str),
1115 my_basename(PyString_AS_STRING(self->filename)),
1116 PyInt_AsLong(self->lineno));
1117 else if (have_filename)
1118 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1119 PyString_AS_STRING(str),
1120 my_basename(PyString_AS_STRING(self->filename)));
1121 else /* only have_lineno */
1122 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1123 PyString_AS_STRING(str),
1124 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001125
Georg Brandl43ab1002006-05-28 20:57:09 +00001126 result = PyString_FromString(buffer);
1127 PyMem_FREE(buffer);
1128
1129 if (result == NULL)
1130 result = str;
1131 else
1132 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001133 return result;
1134}
1135
1136static PyMemberDef SyntaxError_members[] = {
1137 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1138 PyDoc_STR("exception message")},
1139 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1140 PyDoc_STR("exception msg")},
1141 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1142 PyDoc_STR("exception filename")},
1143 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1144 PyDoc_STR("exception lineno")},
1145 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1146 PyDoc_STR("exception offset")},
1147 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1148 PyDoc_STR("exception text")},
1149 {"print_file_and_line", T_OBJECT,
1150 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1151 PyDoc_STR("exception print_file_and_line")},
1152 {NULL} /* Sentinel */
1153};
1154
1155ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1156 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001157 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001158
1159
1160/*
1161 * IndentationError extends SyntaxError
1162 */
1163MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001164 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001165
1166
1167/*
1168 * TabError extends IndentationError
1169 */
1170MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001171 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001172
1173
1174/*
1175 * LookupError extends StandardError
1176 */
1177SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001178 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001179
1180
1181/*
1182 * IndexError extends LookupError
1183 */
1184SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001185 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001186
1187
1188/*
1189 * KeyError extends LookupError
1190 */
1191static PyObject *
1192KeyError_str(PyBaseExceptionObject *self)
1193{
1194 /* If args is a tuple of exactly one item, apply repr to args[0].
1195 This is done so that e.g. the exception raised by {}[''] prints
1196 KeyError: ''
1197 rather than the confusing
1198 KeyError
1199 alone. The downside is that if KeyError is raised with an explanatory
1200 string, that string will be displayed in quotes. Too bad.
1201 If args is anything else, use the default BaseException__str__().
1202 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001203 if (PyTuple_GET_SIZE(self->args) == 1) {
1204 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001205 }
1206 return BaseException_str(self);
1207}
1208
1209ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001210 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001211
1212
1213/*
1214 * ValueError extends StandardError
1215 */
1216SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001217 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001218
1219/*
1220 * UnicodeError extends ValueError
1221 */
1222
1223SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001224 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001225
1226#ifdef Py_USING_UNICODE
1227static int
1228get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1229{
1230 if (!attr) {
1231 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1232 return -1;
1233 }
1234
1235 if (PyInt_Check(attr)) {
1236 *value = PyInt_AS_LONG(attr);
1237 } else if (PyLong_Check(attr)) {
1238 *value = _PyLong_AsSsize_t(attr);
1239 if (*value == -1 && PyErr_Occurred())
1240 return -1;
1241 } else {
1242 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1243 return -1;
1244 }
1245 return 0;
1246}
1247
1248static int
1249set_ssize_t(PyObject **attr, Py_ssize_t value)
1250{
1251 PyObject *obj = PyInt_FromSsize_t(value);
1252 if (!obj)
1253 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001254 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001255 *attr = obj;
1256 return 0;
1257}
1258
1259static PyObject *
1260get_string(PyObject *attr, const char *name)
1261{
1262 if (!attr) {
1263 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1264 return NULL;
1265 }
1266
1267 if (!PyString_Check(attr)) {
1268 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1269 return NULL;
1270 }
1271 Py_INCREF(attr);
1272 return attr;
1273}
1274
1275
1276static int
1277set_string(PyObject **attr, const char *value)
1278{
1279 PyObject *obj = PyString_FromString(value);
1280 if (!obj)
1281 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001282 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001283 *attr = obj;
1284 return 0;
1285}
1286
1287
1288static PyObject *
1289get_unicode(PyObject *attr, const char *name)
1290{
1291 if (!attr) {
1292 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1293 return NULL;
1294 }
1295
1296 if (!PyUnicode_Check(attr)) {
1297 PyErr_Format(PyExc_TypeError,
1298 "%.200s attribute must be unicode", name);
1299 return NULL;
1300 }
1301 Py_INCREF(attr);
1302 return attr;
1303}
1304
1305PyObject *
1306PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1307{
1308 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1309}
1310
1311PyObject *
1312PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1313{
1314 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1315}
1316
1317PyObject *
1318PyUnicodeEncodeError_GetObject(PyObject *exc)
1319{
1320 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1321}
1322
1323PyObject *
1324PyUnicodeDecodeError_GetObject(PyObject *exc)
1325{
1326 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1327}
1328
1329PyObject *
1330PyUnicodeTranslateError_GetObject(PyObject *exc)
1331{
1332 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1333}
1334
1335int
1336PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1337{
1338 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1339 Py_ssize_t size;
1340 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1341 "object");
1342 if (!obj) return -1;
1343 size = PyUnicode_GET_SIZE(obj);
1344 if (*start<0)
1345 *start = 0; /*XXX check for values <0*/
1346 if (*start>=size)
1347 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001348 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001349 return 0;
1350 }
1351 return -1;
1352}
1353
1354
1355int
1356PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1357{
1358 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1359 Py_ssize_t size;
1360 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1361 "object");
1362 if (!obj) return -1;
1363 size = PyString_GET_SIZE(obj);
1364 if (*start<0)
1365 *start = 0;
1366 if (*start>=size)
1367 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001368 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001369 return 0;
1370 }
1371 return -1;
1372}
1373
1374
1375int
1376PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1377{
1378 return PyUnicodeEncodeError_GetStart(exc, start);
1379}
1380
1381
1382int
1383PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1384{
1385 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1386}
1387
1388
1389int
1390PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1391{
1392 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1393}
1394
1395
1396int
1397PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1398{
1399 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1400}
1401
1402
1403int
1404PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1405{
1406 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1407 Py_ssize_t size;
1408 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1409 "object");
1410 if (!obj) return -1;
1411 size = PyUnicode_GET_SIZE(obj);
1412 if (*end<1)
1413 *end = 1;
1414 if (*end>size)
1415 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001416 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001417 return 0;
1418 }
1419 return -1;
1420}
1421
1422
1423int
1424PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1425{
1426 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1427 Py_ssize_t size;
1428 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1429 "object");
1430 if (!obj) return -1;
1431 size = PyString_GET_SIZE(obj);
1432 if (*end<1)
1433 *end = 1;
1434 if (*end>size)
1435 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001436 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001437 return 0;
1438 }
1439 return -1;
1440}
1441
1442
1443int
1444PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1445{
1446 return PyUnicodeEncodeError_GetEnd(exc, start);
1447}
1448
1449
1450int
1451PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1452{
1453 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1454}
1455
1456
1457int
1458PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1459{
1460 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1461}
1462
1463
1464int
1465PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1466{
1467 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1468}
1469
1470PyObject *
1471PyUnicodeEncodeError_GetReason(PyObject *exc)
1472{
1473 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1474}
1475
1476
1477PyObject *
1478PyUnicodeDecodeError_GetReason(PyObject *exc)
1479{
1480 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1481}
1482
1483
1484PyObject *
1485PyUnicodeTranslateError_GetReason(PyObject *exc)
1486{
1487 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1488}
1489
1490
1491int
1492PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1493{
1494 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1495}
1496
1497
1498int
1499PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1500{
1501 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1502}
1503
1504
1505int
1506PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1507{
1508 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1509}
1510
1511
Richard Jones7b9558d2006-05-27 12:29:24 +00001512static int
1513UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1514 PyTypeObject *objecttype)
1515{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001516 Py_CLEAR(self->encoding);
1517 Py_CLEAR(self->object);
1518 Py_CLEAR(self->start);
1519 Py_CLEAR(self->end);
1520 Py_CLEAR(self->reason);
1521
Richard Jones7b9558d2006-05-27 12:29:24 +00001522 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1523 &PyString_Type, &self->encoding,
1524 objecttype, &self->object,
1525 &PyInt_Type, &self->start,
1526 &PyInt_Type, &self->end,
1527 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001528 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001529 self->reason = NULL;
1530 return -1;
1531 }
1532
1533 Py_INCREF(self->encoding);
1534 Py_INCREF(self->object);
1535 Py_INCREF(self->start);
1536 Py_INCREF(self->end);
1537 Py_INCREF(self->reason);
1538
1539 return 0;
1540}
1541
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001542static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001543UnicodeError_clear(PyUnicodeErrorObject *self)
1544{
1545 Py_CLEAR(self->encoding);
1546 Py_CLEAR(self->object);
1547 Py_CLEAR(self->start);
1548 Py_CLEAR(self->end);
1549 Py_CLEAR(self->reason);
1550 return BaseException_clear((PyBaseExceptionObject *)self);
1551}
1552
1553static void
1554UnicodeError_dealloc(PyUnicodeErrorObject *self)
1555{
1556 UnicodeError_clear(self);
1557 self->ob_type->tp_free((PyObject *)self);
1558}
1559
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001560static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001561UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1562{
1563 Py_VISIT(self->encoding);
1564 Py_VISIT(self->object);
1565 Py_VISIT(self->start);
1566 Py_VISIT(self->end);
1567 Py_VISIT(self->reason);
1568 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1569}
1570
1571static PyMemberDef UnicodeError_members[] = {
1572 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1573 PyDoc_STR("exception message")},
1574 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1575 PyDoc_STR("exception encoding")},
1576 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1577 PyDoc_STR("exception object")},
1578 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1579 PyDoc_STR("exception start")},
1580 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1581 PyDoc_STR("exception end")},
1582 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1583 PyDoc_STR("exception reason")},
1584 {NULL} /* Sentinel */
1585};
1586
1587
1588/*
1589 * UnicodeEncodeError extends UnicodeError
1590 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001591
1592static int
1593UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1594{
1595 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1596 return -1;
1597 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1598 kwds, &PyUnicode_Type);
1599}
1600
1601static PyObject *
1602UnicodeEncodeError_str(PyObject *self)
1603{
1604 Py_ssize_t start;
1605 Py_ssize_t end;
1606
1607 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001608 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001609
1610 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001611 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001612
1613 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001614 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1615 char badchar_str[20];
1616 if (badchar <= 0xff)
1617 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1618 else if (badchar <= 0xffff)
1619 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1620 else
1621 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1622 return PyString_FromFormat(
1623 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1624 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1625 badchar_str,
1626 start,
1627 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1628 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001629 }
1630 return PyString_FromFormat(
1631 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1632 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1633 start,
1634 (end-1),
1635 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1636 );
1637}
1638
1639static PyTypeObject _PyExc_UnicodeEncodeError = {
1640 PyObject_HEAD_INIT(NULL)
1641 0,
1642 "UnicodeEncodeError",
1643 sizeof(PyUnicodeErrorObject), 0,
1644 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1645 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1646 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001647 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1648 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001649 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001650 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001651};
1652PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1653
1654PyObject *
1655PyUnicodeEncodeError_Create(
1656 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1657 Py_ssize_t start, Py_ssize_t end, const char *reason)
1658{
1659 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001660 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001661}
1662
1663
1664/*
1665 * UnicodeDecodeError extends UnicodeError
1666 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001667
1668static int
1669UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1670{
1671 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1672 return -1;
1673 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1674 kwds, &PyString_Type);
1675}
1676
1677static PyObject *
1678UnicodeDecodeError_str(PyObject *self)
1679{
Georg Brandl43ab1002006-05-28 20:57:09 +00001680 Py_ssize_t start = 0;
1681 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001682
1683 if (PyUnicodeDecodeError_GetStart(self, &start))
1684 return NULL;
1685
1686 if (PyUnicodeDecodeError_GetEnd(self, &end))
1687 return NULL;
1688
1689 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001690 /* FromFormat does not support %02x, so format that separately */
1691 char byte[4];
1692 PyOS_snprintf(byte, sizeof(byte), "%02x",
1693 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1694 return PyString_FromFormat(
1695 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1696 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1697 byte,
1698 start,
1699 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1700 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001701 }
1702 return PyString_FromFormat(
1703 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1704 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1705 start,
1706 (end-1),
1707 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1708 );
1709}
1710
1711static PyTypeObject _PyExc_UnicodeDecodeError = {
1712 PyObject_HEAD_INIT(NULL)
1713 0,
1714 EXC_MODULE_NAME "UnicodeDecodeError",
1715 sizeof(PyUnicodeErrorObject), 0,
1716 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1717 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1718 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001719 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1720 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001721 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001722 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001723};
1724PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1725
1726PyObject *
1727PyUnicodeDecodeError_Create(
1728 const char *encoding, const char *object, Py_ssize_t length,
1729 Py_ssize_t start, Py_ssize_t end, const char *reason)
1730{
1731 assert(length < INT_MAX);
1732 assert(start < INT_MAX);
1733 assert(end < INT_MAX);
1734 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001735 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001736}
1737
1738
1739/*
1740 * UnicodeTranslateError extends UnicodeError
1741 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001742
1743static int
1744UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1745 PyObject *kwds)
1746{
1747 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1748 return -1;
1749
1750 Py_CLEAR(self->object);
1751 Py_CLEAR(self->start);
1752 Py_CLEAR(self->end);
1753 Py_CLEAR(self->reason);
1754
1755 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1756 &PyUnicode_Type, &self->object,
1757 &PyInt_Type, &self->start,
1758 &PyInt_Type, &self->end,
1759 &PyString_Type, &self->reason)) {
1760 self->object = self->start = self->end = self->reason = NULL;
1761 return -1;
1762 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001763
Richard Jones7b9558d2006-05-27 12:29:24 +00001764 Py_INCREF(self->object);
1765 Py_INCREF(self->start);
1766 Py_INCREF(self->end);
1767 Py_INCREF(self->reason);
1768
1769 return 0;
1770}
1771
1772
1773static PyObject *
1774UnicodeTranslateError_str(PyObject *self)
1775{
1776 Py_ssize_t start;
1777 Py_ssize_t end;
1778
1779 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001780 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001781
1782 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001783 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001784
1785 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001786 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1787 char badchar_str[20];
1788 if (badchar <= 0xff)
1789 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1790 else if (badchar <= 0xffff)
1791 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1792 else
1793 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1794 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001795 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001796 badchar_str,
1797 start,
1798 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1799 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001800 }
1801 return PyString_FromFormat(
1802 "can't translate characters in position %zd-%zd: %.400s",
1803 start,
1804 (end-1),
1805 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1806 );
1807}
1808
1809static PyTypeObject _PyExc_UnicodeTranslateError = {
1810 PyObject_HEAD_INIT(NULL)
1811 0,
1812 EXC_MODULE_NAME "UnicodeTranslateError",
1813 sizeof(PyUnicodeErrorObject), 0,
1814 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1815 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1816 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1817 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1818 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1819 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001820 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001821};
1822PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1823
1824PyObject *
1825PyUnicodeTranslateError_Create(
1826 const Py_UNICODE *object, Py_ssize_t length,
1827 Py_ssize_t start, Py_ssize_t end, const char *reason)
1828{
1829 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001830 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001831}
1832#endif
1833
1834
1835/*
1836 * AssertionError extends StandardError
1837 */
1838SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001839 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001840
1841
1842/*
1843 * ArithmeticError extends StandardError
1844 */
1845SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001846 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001847
1848
1849/*
1850 * FloatingPointError extends ArithmeticError
1851 */
1852SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001853 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001854
1855
1856/*
1857 * OverflowError extends ArithmeticError
1858 */
1859SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001860 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001861
1862
1863/*
1864 * ZeroDivisionError extends ArithmeticError
1865 */
1866SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001867 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001868
1869
1870/*
1871 * SystemError extends StandardError
1872 */
1873SimpleExtendsException(PyExc_StandardError, SystemError,
1874 "Internal error in the Python interpreter.\n"
1875 "\n"
1876 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001877 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001878
1879
1880/*
1881 * ReferenceError extends StandardError
1882 */
1883SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001884 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001885
1886
1887/*
1888 * MemoryError extends StandardError
1889 */
Richard Jones2d555b32006-05-27 16:15:11 +00001890SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001891
1892
1893/* Warning category docstrings */
1894
1895/*
1896 * Warning extends Exception
1897 */
1898SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001899 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001900
1901
1902/*
1903 * UserWarning extends Warning
1904 */
1905SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001906 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001907
1908
1909/*
1910 * DeprecationWarning extends Warning
1911 */
1912SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001913 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001914
1915
1916/*
1917 * PendingDeprecationWarning extends Warning
1918 */
1919SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1920 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001921 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001922
1923
1924/*
1925 * SyntaxWarning extends Warning
1926 */
1927SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001928 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001929
1930
1931/*
1932 * RuntimeWarning extends Warning
1933 */
1934SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001935 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001936
1937
1938/*
1939 * FutureWarning extends Warning
1940 */
1941SimpleExtendsException(PyExc_Warning, FutureWarning,
1942 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001943 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001944
1945
1946/*
1947 * ImportWarning extends Warning
1948 */
1949SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001950 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001951
1952
1953/* Pre-computed MemoryError instance. Best to create this as early as
1954 * possible and not wait until a MemoryError is actually raised!
1955 */
1956PyObject *PyExc_MemoryErrorInst=NULL;
1957
1958/* module global functions */
1959static PyMethodDef functions[] = {
1960 /* Sentinel */
1961 {NULL, NULL}
1962};
1963
1964#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1965 Py_FatalError("exceptions bootstrapping error.");
1966
1967#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1968 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1969 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1970 Py_FatalError("Module dictionary insertion problem.");
1971
1972PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001973_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001974{
1975 PyObject *m, *bltinmod, *bdict;
1976
1977 PRE_INIT(BaseException)
1978 PRE_INIT(Exception)
1979 PRE_INIT(StandardError)
1980 PRE_INIT(TypeError)
1981 PRE_INIT(StopIteration)
1982 PRE_INIT(GeneratorExit)
1983 PRE_INIT(SystemExit)
1984 PRE_INIT(KeyboardInterrupt)
1985 PRE_INIT(ImportError)
1986 PRE_INIT(EnvironmentError)
1987 PRE_INIT(IOError)
1988 PRE_INIT(OSError)
1989#ifdef MS_WINDOWS
1990 PRE_INIT(WindowsError)
1991#endif
1992#ifdef __VMS
1993 PRE_INIT(VMSError)
1994#endif
1995 PRE_INIT(EOFError)
1996 PRE_INIT(RuntimeError)
1997 PRE_INIT(NotImplementedError)
1998 PRE_INIT(NameError)
1999 PRE_INIT(UnboundLocalError)
2000 PRE_INIT(AttributeError)
2001 PRE_INIT(SyntaxError)
2002 PRE_INIT(IndentationError)
2003 PRE_INIT(TabError)
2004 PRE_INIT(LookupError)
2005 PRE_INIT(IndexError)
2006 PRE_INIT(KeyError)
2007 PRE_INIT(ValueError)
2008 PRE_INIT(UnicodeError)
2009#ifdef Py_USING_UNICODE
2010 PRE_INIT(UnicodeEncodeError)
2011 PRE_INIT(UnicodeDecodeError)
2012 PRE_INIT(UnicodeTranslateError)
2013#endif
2014 PRE_INIT(AssertionError)
2015 PRE_INIT(ArithmeticError)
2016 PRE_INIT(FloatingPointError)
2017 PRE_INIT(OverflowError)
2018 PRE_INIT(ZeroDivisionError)
2019 PRE_INIT(SystemError)
2020 PRE_INIT(ReferenceError)
2021 PRE_INIT(MemoryError)
2022 PRE_INIT(Warning)
2023 PRE_INIT(UserWarning)
2024 PRE_INIT(DeprecationWarning)
2025 PRE_INIT(PendingDeprecationWarning)
2026 PRE_INIT(SyntaxWarning)
2027 PRE_INIT(RuntimeWarning)
2028 PRE_INIT(FutureWarning)
2029 PRE_INIT(ImportWarning)
2030
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00002031 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2032 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00002033 if (m == NULL) return;
2034
2035 bltinmod = PyImport_ImportModule("__builtin__");
2036 if (bltinmod == NULL)
2037 Py_FatalError("exceptions bootstrapping error.");
2038 bdict = PyModule_GetDict(bltinmod);
2039 if (bdict == NULL)
2040 Py_FatalError("exceptions bootstrapping error.");
2041
2042 POST_INIT(BaseException)
2043 POST_INIT(Exception)
2044 POST_INIT(StandardError)
2045 POST_INIT(TypeError)
2046 POST_INIT(StopIteration)
2047 POST_INIT(GeneratorExit)
2048 POST_INIT(SystemExit)
2049 POST_INIT(KeyboardInterrupt)
2050 POST_INIT(ImportError)
2051 POST_INIT(EnvironmentError)
2052 POST_INIT(IOError)
2053 POST_INIT(OSError)
2054#ifdef MS_WINDOWS
2055 POST_INIT(WindowsError)
2056#endif
2057#ifdef __VMS
2058 POST_INIT(VMSError)
2059#endif
2060 POST_INIT(EOFError)
2061 POST_INIT(RuntimeError)
2062 POST_INIT(NotImplementedError)
2063 POST_INIT(NameError)
2064 POST_INIT(UnboundLocalError)
2065 POST_INIT(AttributeError)
2066 POST_INIT(SyntaxError)
2067 POST_INIT(IndentationError)
2068 POST_INIT(TabError)
2069 POST_INIT(LookupError)
2070 POST_INIT(IndexError)
2071 POST_INIT(KeyError)
2072 POST_INIT(ValueError)
2073 POST_INIT(UnicodeError)
2074#ifdef Py_USING_UNICODE
2075 POST_INIT(UnicodeEncodeError)
2076 POST_INIT(UnicodeDecodeError)
2077 POST_INIT(UnicodeTranslateError)
2078#endif
2079 POST_INIT(AssertionError)
2080 POST_INIT(ArithmeticError)
2081 POST_INIT(FloatingPointError)
2082 POST_INIT(OverflowError)
2083 POST_INIT(ZeroDivisionError)
2084 POST_INIT(SystemError)
2085 POST_INIT(ReferenceError)
2086 POST_INIT(MemoryError)
2087 POST_INIT(Warning)
2088 POST_INIT(UserWarning)
2089 POST_INIT(DeprecationWarning)
2090 POST_INIT(PendingDeprecationWarning)
2091 POST_INIT(SyntaxWarning)
2092 POST_INIT(RuntimeWarning)
2093 POST_INIT(FutureWarning)
2094 POST_INIT(ImportWarning)
2095
2096 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2097 if (!PyExc_MemoryErrorInst)
2098 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2099
2100 Py_DECREF(bltinmod);
2101}
2102
2103void
2104_PyExc_Fini(void)
2105{
2106 Py_XDECREF(PyExc_MemoryErrorInst);
2107 PyExc_MemoryErrorInst = NULL;
2108}