blob: c15c4aded1e975cd529dd6fb504afed57594b1c3 [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 PyObject *
180BaseException_get_dict(PyBaseExceptionObject *self)
181{
182 if (self->dict == NULL) {
183 self->dict = PyDict_New();
184 if (!self->dict)
185 return NULL;
186 }
187 Py_INCREF(self->dict);
188 return self->dict;
189}
190
191static int
192BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
193{
194 if (val == NULL) {
195 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
196 return -1;
197 }
198 if (!PyDict_Check(val)) {
199 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
200 return -1;
201 }
202 Py_CLEAR(self->dict);
203 Py_INCREF(val);
204 self->dict = val;
205 return 0;
206}
207
208static PyObject *
209BaseException_get_args(PyBaseExceptionObject *self)
210{
211 if (self->args == NULL) {
212 Py_INCREF(Py_None);
213 return Py_None;
214 }
215 Py_INCREF(self->args);
216 return self->args;
217}
218
219static int
220BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
221{
222 PyObject *seq;
223 if (val == NULL) {
224 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
225 return -1;
226 }
227 seq = PySequence_Tuple(val);
228 if (!seq) return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000229 Py_CLEAR(self->args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000230 self->args = seq;
231 return 0;
232}
233
Guido van Rossum360e4b82007-05-14 22:51:27 +0000234static PyObject *
235BaseException_get_message(PyBaseExceptionObject *self)
236{
237 int ret;
238 ret = PyErr_WarnEx(PyExc_DeprecationWarning,
239 "BaseException.message has been deprecated as "
240 "of Python 2.6",
241 1);
242 if (ret == -1)
243 return NULL;
244
245 Py_INCREF(self->message);
246 return self->message;
247}
248
249static int
250BaseException_set_message(PyBaseExceptionObject *self, PyObject *val)
251{
252 int ret;
253 ret = PyErr_WarnEx(PyExc_DeprecationWarning,
254 "BaseException.message has been deprecated as "
255 "of Python 2.6",
256 1);
257 if (ret == -1)
258 return -1;
259 Py_INCREF(val);
260 Py_DECREF(self->message);
261 self->message = val;
262 return 0;
263}
264
Thomas Wouters477c8d52006-05-27 19:21:47 +0000265static PyGetSetDef BaseException_getset[] = {
266 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
267 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
Guido van Rossum360e4b82007-05-14 22:51:27 +0000268 {"message", (getter)BaseException_get_message,
269 (setter)BaseException_set_message},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000270 {NULL},
271};
272
273
274static PyTypeObject _PyExc_BaseException = {
275 PyObject_HEAD_INIT(NULL)
276 0, /*ob_size*/
Neal Norwitz2633c692007-02-26 22:22:47 +0000277 "BaseException", /*tp_name*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000278 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
279 0, /*tp_itemsize*/
280 (destructor)BaseException_dealloc, /*tp_dealloc*/
281 0, /*tp_print*/
282 0, /*tp_getattr*/
283 0, /*tp_setattr*/
284 0, /* tp_compare; */
285 (reprfunc)BaseException_repr, /*tp_repr*/
286 0, /*tp_as_number*/
Brett Cannonba7bf492007-02-27 00:15:55 +0000287 0, /*tp_as_sequence*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000288 0, /*tp_as_mapping*/
289 0, /*tp_hash */
290 0, /*tp_call*/
291 (reprfunc)BaseException_str, /*tp_str*/
292 PyObject_GenericGetAttr, /*tp_getattro*/
293 PyObject_GenericSetAttr, /*tp_setattro*/
294 0, /*tp_as_buffer*/
Thomas Wouters27d517b2007-02-25 20:39:11 +0000295 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
296 Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
Thomas Wouters477c8d52006-05-27 19:21:47 +0000297 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
298 (traverseproc)BaseException_traverse, /* tp_traverse */
299 (inquiry)BaseException_clear, /* tp_clear */
300 0, /* tp_richcompare */
301 0, /* tp_weaklistoffset */
302 0, /* tp_iter */
303 0, /* tp_iternext */
304 BaseException_methods, /* tp_methods */
Guido van Rossum360e4b82007-05-14 22:51:27 +0000305 0, /* tp_members */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000306 BaseException_getset, /* tp_getset */
307 0, /* tp_base */
308 0, /* tp_dict */
309 0, /* tp_descr_get */
310 0, /* tp_descr_set */
311 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
312 (initproc)BaseException_init, /* tp_init */
313 0, /* tp_alloc */
314 BaseException_new, /* tp_new */
315};
316/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
317from the previous implmentation and also allowing Python objects to be used
318in the API */
319PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
320
321/* note these macros omit the last semicolon so the macro invocation may
322 * include it and not look strange.
323 */
324#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
325static PyTypeObject _PyExc_ ## EXCNAME = { \
326 PyObject_HEAD_INIT(NULL) \
327 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000328 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329 sizeof(PyBaseExceptionObject), \
330 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
331 0, 0, 0, 0, 0, 0, 0, \
332 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
333 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
334 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
335 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
336 (initproc)BaseException_init, 0, BaseException_new,\
337}; \
338PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
339
340#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
341static PyTypeObject _PyExc_ ## EXCNAME = { \
342 PyObject_HEAD_INIT(NULL) \
343 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000344 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000345 sizeof(Py ## EXCSTORE ## Object), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000346 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000347 0, 0, 0, 0, 0, \
348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000349 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
350 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000351 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000352 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000353}; \
354PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
355
356#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
357static PyTypeObject _PyExc_ ## EXCNAME = { \
358 PyObject_HEAD_INIT(NULL) \
359 0, \
Neal Norwitz2633c692007-02-26 22:22:47 +0000360 # EXCNAME, \
Thomas Wouters477c8d52006-05-27 19:21:47 +0000361 sizeof(Py ## EXCSTORE ## Object), 0, \
362 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
363 (reprfunc)EXCSTR, 0, 0, 0, \
364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
365 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
366 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
367 EXCMEMBERS, 0, &_ ## EXCBASE, \
368 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000369 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Thomas Wouters477c8d52006-05-27 19:21:47 +0000370}; \
371PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
372
373
374/*
375 * Exception extends BaseException
376 */
377SimpleExtendsException(PyExc_BaseException, Exception,
378 "Common base class for all non-exit exceptions.");
379
380
381/*
382 * StandardError extends Exception
383 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000384SimpleExtendsException(PyExc_Exception, StandardError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000385 "Base class for all standard Python exceptions that do not represent\n"
386 "interpreter exiting.");
387
388
389/*
390 * TypeError extends StandardError
391 */
392SimpleExtendsException(PyExc_StandardError, TypeError,
393 "Inappropriate argument type.");
394
395
396/*
397 * StopIteration extends Exception
398 */
399SimpleExtendsException(PyExc_Exception, StopIteration,
Georg Brandla18af4e2007-04-21 15:47:16 +0000400 "Signal the end from iterator.__next__().");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000401
402
403/*
404 * GeneratorExit extends Exception
405 */
406SimpleExtendsException(PyExc_Exception, GeneratorExit,
407 "Request that a generator exit.");
408
409
410/*
411 * SystemExit extends BaseException
412 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000413
414static int
415SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
416{
417 Py_ssize_t size = PyTuple_GET_SIZE(args);
418
419 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
420 return -1;
421
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000422 if (size == 0)
423 return 0;
424 Py_CLEAR(self->code);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000425 if (size == 1)
426 self->code = PyTuple_GET_ITEM(args, 0);
427 else if (size > 1)
428 self->code = args;
429 Py_INCREF(self->code);
430 return 0;
431}
432
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000433static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434SystemExit_clear(PySystemExitObject *self)
435{
436 Py_CLEAR(self->code);
437 return BaseException_clear((PyBaseExceptionObject *)self);
438}
439
440static void
441SystemExit_dealloc(PySystemExitObject *self)
442{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000443 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000444 SystemExit_clear(self);
445 self->ob_type->tp_free((PyObject *)self);
446}
447
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000448static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
450{
451 Py_VISIT(self->code);
452 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
453}
454
455static PyMemberDef SystemExit_members[] = {
456 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
457 PyDoc_STR("exception message")},
458 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
459 PyDoc_STR("exception code")},
460 {NULL} /* Sentinel */
461};
462
463ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
464 SystemExit_dealloc, 0, SystemExit_members, 0,
465 "Request to exit from the interpreter.");
466
467/*
468 * KeyboardInterrupt extends BaseException
469 */
470SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
471 "Program interrupted by user.");
472
473
474/*
475 * ImportError extends StandardError
476 */
477SimpleExtendsException(PyExc_StandardError, ImportError,
478 "Import can't find module, or can't find name in module.");
479
480
481/*
482 * EnvironmentError extends StandardError
483 */
484
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485/* Where a function has a single filename, such as open() or some
486 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
487 * called, giving a third argument which is the filename. But, so
488 * that old code using in-place unpacking doesn't break, e.g.:
489 *
490 * except IOError, (errno, strerror):
491 *
492 * we hack args so that it only contains two items. This also
493 * means we need our own __str__() which prints out the filename
494 * when it was supplied.
495 */
496static int
497EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
498 PyObject *kwds)
499{
500 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
501 PyObject *subslice = NULL;
502
503 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
504 return -1;
505
Thomas Wouters89f507f2006-12-13 04:49:30 +0000506 if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000507 return 0;
508 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000509
510 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000511 &myerrno, &strerror, &filename)) {
512 return -1;
513 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000514 Py_CLEAR(self->myerrno); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000515 self->myerrno = myerrno;
516 Py_INCREF(self->myerrno);
517
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000518 Py_CLEAR(self->strerror); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519 self->strerror = strerror;
520 Py_INCREF(self->strerror);
521
522 /* self->filename will remain Py_None otherwise */
523 if (filename != NULL) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000524 Py_CLEAR(self->filename); /* replacing */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525 self->filename = filename;
526 Py_INCREF(self->filename);
527
528 subslice = PyTuple_GetSlice(args, 0, 2);
529 if (!subslice)
530 return -1;
531
532 Py_DECREF(self->args); /* replacing args */
533 self->args = subslice;
534 }
535 return 0;
536}
537
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000538static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000539EnvironmentError_clear(PyEnvironmentErrorObject *self)
540{
541 Py_CLEAR(self->myerrno);
542 Py_CLEAR(self->strerror);
543 Py_CLEAR(self->filename);
544 return BaseException_clear((PyBaseExceptionObject *)self);
545}
546
547static void
548EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
549{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000550 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000551 EnvironmentError_clear(self);
552 self->ob_type->tp_free((PyObject *)self);
553}
554
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000555static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000556EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
557 void *arg)
558{
559 Py_VISIT(self->myerrno);
560 Py_VISIT(self->strerror);
561 Py_VISIT(self->filename);
562 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
563}
564
565static PyObject *
566EnvironmentError_str(PyEnvironmentErrorObject *self)
567{
568 PyObject *rtnval = NULL;
569
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000570 if (self->filename) {
571 PyObject *fmt;
572 PyObject *repr;
573 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000574
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000575 fmt = PyString_FromString("[Errno %s] %s: %s");
576 if (!fmt)
577 return NULL;
578
579 repr = PyObject_Repr(self->filename);
580 if (!repr) {
581 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000582 return NULL;
583 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000584 tuple = PyTuple_New(3);
585 if (!tuple) {
586 Py_DECREF(repr);
587 Py_DECREF(fmt);
588 return NULL;
589 }
590
591 if (self->myerrno) {
592 Py_INCREF(self->myerrno);
593 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
594 }
595 else {
596 Py_INCREF(Py_None);
597 PyTuple_SET_ITEM(tuple, 0, Py_None);
598 }
599 if (self->strerror) {
600 Py_INCREF(self->strerror);
601 PyTuple_SET_ITEM(tuple, 1, self->strerror);
602 }
603 else {
604 Py_INCREF(Py_None);
605 PyTuple_SET_ITEM(tuple, 1, Py_None);
606 }
607
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608 PyTuple_SET_ITEM(tuple, 2, repr);
609
610 rtnval = PyString_Format(fmt, tuple);
611
612 Py_DECREF(fmt);
613 Py_DECREF(tuple);
614 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000615 else if (self->myerrno && self->strerror) {
616 PyObject *fmt;
617 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000618
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000619 fmt = PyString_FromString("[Errno %s] %s");
620 if (!fmt)
621 return NULL;
622
623 tuple = PyTuple_New(2);
624 if (!tuple) {
625 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000626 return NULL;
627 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000628
629 if (self->myerrno) {
630 Py_INCREF(self->myerrno);
631 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
632 }
633 else {
634 Py_INCREF(Py_None);
635 PyTuple_SET_ITEM(tuple, 0, Py_None);
636 }
637 if (self->strerror) {
638 Py_INCREF(self->strerror);
639 PyTuple_SET_ITEM(tuple, 1, self->strerror);
640 }
641 else {
642 Py_INCREF(Py_None);
643 PyTuple_SET_ITEM(tuple, 1, Py_None);
644 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000645
646 rtnval = PyString_Format(fmt, tuple);
647
648 Py_DECREF(fmt);
649 Py_DECREF(tuple);
650 }
651 else
652 rtnval = BaseException_str((PyBaseExceptionObject *)self);
653
654 return rtnval;
655}
656
657static PyMemberDef EnvironmentError_members[] = {
658 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
659 PyDoc_STR("exception message")},
660 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
661 PyDoc_STR("exception errno")},
662 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
663 PyDoc_STR("exception strerror")},
664 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
665 PyDoc_STR("exception filename")},
666 {NULL} /* Sentinel */
667};
668
669
670static PyObject *
671EnvironmentError_reduce(PyEnvironmentErrorObject *self)
672{
673 PyObject *args = self->args;
674 PyObject *res = NULL, *tmp;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000675
Thomas Wouters477c8d52006-05-27 19:21:47 +0000676 /* self->args is only the first two real arguments if there was a
677 * file name given to EnvironmentError. */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000678 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000679 args = PyTuple_New(3);
680 if (!args) return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000681
682 tmp = PyTuple_GET_ITEM(self->args, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683 Py_INCREF(tmp);
684 PyTuple_SET_ITEM(args, 0, tmp);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000685
686 tmp = PyTuple_GET_ITEM(self->args, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 Py_INCREF(tmp);
688 PyTuple_SET_ITEM(args, 1, tmp);
689
690 Py_INCREF(self->filename);
691 PyTuple_SET_ITEM(args, 2, self->filename);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000692 } else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693 Py_INCREF(args);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000694
695 if (self->dict)
696 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
697 else
698 res = PyTuple_Pack(2, self->ob_type, args);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000699 Py_DECREF(args);
700 return res;
701}
702
703
704static PyMethodDef EnvironmentError_methods[] = {
705 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
706 {NULL}
707};
708
709ComplexExtendsException(PyExc_StandardError, EnvironmentError,
710 EnvironmentError, EnvironmentError_dealloc,
711 EnvironmentError_methods, EnvironmentError_members,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000712 EnvironmentError_str,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000713 "Base class for I/O related errors.");
714
715
716/*
717 * IOError extends EnvironmentError
718 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000719MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000720 EnvironmentError, "I/O operation failed.");
721
722
723/*
724 * OSError extends EnvironmentError
725 */
726MiddlingExtendsException(PyExc_EnvironmentError, OSError,
727 EnvironmentError, "OS system call failed.");
728
729
730/*
731 * WindowsError extends OSError
732 */
733#ifdef MS_WINDOWS
734#include "errmap.h"
735
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000736static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000737WindowsError_clear(PyWindowsErrorObject *self)
738{
739 Py_CLEAR(self->myerrno);
740 Py_CLEAR(self->strerror);
741 Py_CLEAR(self->filename);
742 Py_CLEAR(self->winerror);
743 return BaseException_clear((PyBaseExceptionObject *)self);
744}
745
746static void
747WindowsError_dealloc(PyWindowsErrorObject *self)
748{
Thomas Wouters89f507f2006-12-13 04:49:30 +0000749 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000750 WindowsError_clear(self);
751 self->ob_type->tp_free((PyObject *)self);
752}
753
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000754static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
756{
757 Py_VISIT(self->myerrno);
758 Py_VISIT(self->strerror);
759 Py_VISIT(self->filename);
760 Py_VISIT(self->winerror);
761 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
762}
763
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764static int
765WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
766{
767 PyObject *o_errcode = NULL;
768 long errcode;
769 long posix_errno;
770
771 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
772 == -1)
773 return -1;
774
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000775 if (self->myerrno == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777
778 /* Set errno to the POSIX errno, and winerror to the Win32
779 error code. */
780 errcode = PyInt_AsLong(self->myerrno);
781 if (errcode == -1 && PyErr_Occurred())
782 return -1;
783 posix_errno = winerror_to_errno(errcode);
784
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000785 Py_CLEAR(self->winerror);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000786 self->winerror = self->myerrno;
787
788 o_errcode = PyInt_FromLong(posix_errno);
789 if (!o_errcode)
790 return -1;
791
792 self->myerrno = o_errcode;
793
794 return 0;
795}
796
797
798static PyObject *
799WindowsError_str(PyWindowsErrorObject *self)
800{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801 PyObject *rtnval = NULL;
802
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000803 if (self->filename) {
804 PyObject *fmt;
805 PyObject *repr;
806 PyObject *tuple;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000807
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000808 fmt = PyString_FromString("[Error %s] %s: %s");
809 if (!fmt)
810 return NULL;
811
812 repr = PyObject_Repr(self->filename);
813 if (!repr) {
814 Py_DECREF(fmt);
815 return NULL;
816 }
817 tuple = PyTuple_New(3);
818 if (!tuple) {
819 Py_DECREF(repr);
820 Py_DECREF(fmt);
821 return NULL;
822 }
823
Thomas Wouters89f507f2006-12-13 04:49:30 +0000824 if (self->winerror) {
825 Py_INCREF(self->winerror);
826 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000827 }
828 else {
829 Py_INCREF(Py_None);
830 PyTuple_SET_ITEM(tuple, 0, Py_None);
831 }
832 if (self->strerror) {
833 Py_INCREF(self->strerror);
834 PyTuple_SET_ITEM(tuple, 1, self->strerror);
835 }
836 else {
837 Py_INCREF(Py_None);
838 PyTuple_SET_ITEM(tuple, 1, Py_None);
839 }
840
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000841 PyTuple_SET_ITEM(tuple, 2, repr);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842
843 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000844
845 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000846 Py_DECREF(tuple);
847 }
Thomas Wouters89f507f2006-12-13 04:49:30 +0000848 else if (self->winerror && self->strerror) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000849 PyObject *fmt;
850 PyObject *tuple;
851
Thomas Wouters477c8d52006-05-27 19:21:47 +0000852 fmt = PyString_FromString("[Error %s] %s");
853 if (!fmt)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000854 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000855
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000856 tuple = PyTuple_New(2);
857 if (!tuple) {
858 Py_DECREF(fmt);
859 return NULL;
860 }
861
Thomas Wouters89f507f2006-12-13 04:49:30 +0000862 if (self->winerror) {
863 Py_INCREF(self->winerror);
864 PyTuple_SET_ITEM(tuple, 0, self->winerror);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000865 }
866 else {
867 Py_INCREF(Py_None);
868 PyTuple_SET_ITEM(tuple, 0, Py_None);
869 }
870 if (self->strerror) {
871 Py_INCREF(self->strerror);
872 PyTuple_SET_ITEM(tuple, 1, self->strerror);
873 }
874 else {
875 Py_INCREF(Py_None);
876 PyTuple_SET_ITEM(tuple, 1, Py_None);
877 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000878
879 rtnval = PyString_Format(fmt, tuple);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000880
881 Py_DECREF(fmt);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000882 Py_DECREF(tuple);
883 }
884 else
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000885 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886
Thomas Wouters477c8d52006-05-27 19:21:47 +0000887 return rtnval;
888}
889
890static PyMemberDef WindowsError_members[] = {
891 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
892 PyDoc_STR("exception message")},
893 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
894 PyDoc_STR("POSIX exception code")},
895 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
896 PyDoc_STR("exception strerror")},
897 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
898 PyDoc_STR("exception filename")},
899 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
900 PyDoc_STR("Win32 exception code")},
901 {NULL} /* Sentinel */
902};
903
904ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
905 WindowsError_dealloc, 0, WindowsError_members,
906 WindowsError_str, "MS-Windows OS system call failed.");
907
908#endif /* MS_WINDOWS */
909
910
911/*
912 * VMSError extends OSError (I think)
913 */
914#ifdef __VMS
915MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
916 "OpenVMS OS system call failed.");
917#endif
918
919
920/*
921 * EOFError extends StandardError
922 */
923SimpleExtendsException(PyExc_StandardError, EOFError,
924 "Read beyond end of file.");
925
926
927/*
928 * RuntimeError extends StandardError
929 */
930SimpleExtendsException(PyExc_StandardError, RuntimeError,
931 "Unspecified run-time error.");
932
933
934/*
935 * NotImplementedError extends RuntimeError
936 */
937SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
938 "Method or function hasn't been implemented yet.");
939
940/*
941 * NameError extends StandardError
942 */
943SimpleExtendsException(PyExc_StandardError, NameError,
944 "Name not found globally.");
945
946/*
947 * UnboundLocalError extends NameError
948 */
949SimpleExtendsException(PyExc_NameError, UnboundLocalError,
950 "Local name referenced but not bound to a value.");
951
952/*
953 * AttributeError extends StandardError
954 */
955SimpleExtendsException(PyExc_StandardError, AttributeError,
956 "Attribute not found.");
957
958
959/*
960 * SyntaxError extends StandardError
961 */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000962
963static int
964SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
965{
966 PyObject *info = NULL;
967 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
968
969 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
970 return -1;
971
972 if (lenargs >= 1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000973 Py_CLEAR(self->msg);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000974 self->msg = PyTuple_GET_ITEM(args, 0);
975 Py_INCREF(self->msg);
976 }
977 if (lenargs == 2) {
978 info = PyTuple_GET_ITEM(args, 1);
979 info = PySequence_Tuple(info);
980 if (!info) return -1;
981
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000982 if (PyTuple_GET_SIZE(info) != 4) {
983 /* not a very good error message, but it's what Python 2.4 gives */
984 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
985 Py_DECREF(info);
986 return -1;
987 }
988
989 Py_CLEAR(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000990 self->filename = PyTuple_GET_ITEM(info, 0);
991 Py_INCREF(self->filename);
992
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000993 Py_CLEAR(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000994 self->lineno = PyTuple_GET_ITEM(info, 1);
995 Py_INCREF(self->lineno);
996
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000997 Py_CLEAR(self->offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998 self->offset = PyTuple_GET_ITEM(info, 2);
999 Py_INCREF(self->offset);
1000
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001001 Py_CLEAR(self->text);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002 self->text = PyTuple_GET_ITEM(info, 3);
1003 Py_INCREF(self->text);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001004
1005 Py_DECREF(info);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006 }
1007 return 0;
1008}
1009
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001010static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001011SyntaxError_clear(PySyntaxErrorObject *self)
1012{
1013 Py_CLEAR(self->msg);
1014 Py_CLEAR(self->filename);
1015 Py_CLEAR(self->lineno);
1016 Py_CLEAR(self->offset);
1017 Py_CLEAR(self->text);
1018 Py_CLEAR(self->print_file_and_line);
1019 return BaseException_clear((PyBaseExceptionObject *)self);
1020}
1021
1022static void
1023SyntaxError_dealloc(PySyntaxErrorObject *self)
1024{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001025 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001026 SyntaxError_clear(self);
1027 self->ob_type->tp_free((PyObject *)self);
1028}
1029
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001030static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1032{
1033 Py_VISIT(self->msg);
1034 Py_VISIT(self->filename);
1035 Py_VISIT(self->lineno);
1036 Py_VISIT(self->offset);
1037 Py_VISIT(self->text);
1038 Py_VISIT(self->print_file_and_line);
1039 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1040}
1041
1042/* This is called "my_basename" instead of just "basename" to avoid name
1043 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1044 defined, and Python does define that. */
1045static char *
1046my_basename(char *name)
1047{
1048 char *cp = name;
1049 char *result = name;
1050
1051 if (name == NULL)
1052 return "???";
1053 while (*cp != '\0') {
1054 if (*cp == SEP)
1055 result = cp + 1;
1056 ++cp;
1057 }
1058 return result;
1059}
1060
1061
1062static PyObject *
1063SyntaxError_str(PySyntaxErrorObject *self)
1064{
1065 PyObject *str;
1066 PyObject *result;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001067 int have_filename = 0;
1068 int have_lineno = 0;
1069 char *buffer = NULL;
1070 Py_ssize_t bufsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001072 if (self->msg)
1073 str = PyObject_Str(self->msg);
1074 else
1075 str = PyObject_Str(Py_None);
1076 if (!str) return NULL;
1077 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1078 if (!PyString_Check(str)) return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001079
1080 /* XXX -- do all the additional formatting with filename and
1081 lineno here */
1082
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001083 have_filename = (self->filename != NULL) &&
1084 PyString_Check(self->filename);
Guido van Rossumddefaf32007-01-14 03:31:43 +00001085 have_lineno = (self->lineno != NULL) && PyInt_CheckExact(self->lineno);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001087 if (!have_filename && !have_lineno)
1088 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001090 bufsize = PyString_GET_SIZE(str) + 64;
1091 if (have_filename)
1092 bufsize += PyString_GET_SIZE(self->filename);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001093
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001094 buffer = PyMem_MALLOC(bufsize);
1095 if (buffer == NULL)
1096 return str;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001098 if (have_filename && have_lineno)
1099 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1100 PyString_AS_STRING(str),
1101 my_basename(PyString_AS_STRING(self->filename)),
1102 PyInt_AsLong(self->lineno));
1103 else if (have_filename)
1104 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1105 PyString_AS_STRING(str),
1106 my_basename(PyString_AS_STRING(self->filename)));
1107 else /* only have_lineno */
1108 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1109 PyString_AS_STRING(str),
1110 PyInt_AsLong(self->lineno));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001111
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001112 result = PyString_FromString(buffer);
1113 PyMem_FREE(buffer);
1114
1115 if (result == NULL)
1116 result = str;
1117 else
1118 Py_DECREF(str);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001119 return result;
1120}
1121
1122static PyMemberDef SyntaxError_members[] = {
1123 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1124 PyDoc_STR("exception message")},
1125 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1126 PyDoc_STR("exception msg")},
1127 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1128 PyDoc_STR("exception filename")},
1129 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1130 PyDoc_STR("exception lineno")},
1131 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1132 PyDoc_STR("exception offset")},
1133 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1134 PyDoc_STR("exception text")},
1135 {"print_file_and_line", T_OBJECT,
1136 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1137 PyDoc_STR("exception print_file_and_line")},
1138 {NULL} /* Sentinel */
1139};
1140
1141ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1142 SyntaxError_dealloc, 0, SyntaxError_members,
1143 SyntaxError_str, "Invalid syntax.");
1144
1145
1146/*
1147 * IndentationError extends SyntaxError
1148 */
1149MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
1150 "Improper indentation.");
1151
1152
1153/*
1154 * TabError extends IndentationError
1155 */
1156MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
1157 "Improper mixture of spaces and tabs.");
1158
1159
1160/*
1161 * LookupError extends StandardError
1162 */
1163SimpleExtendsException(PyExc_StandardError, LookupError,
1164 "Base class for lookup errors.");
1165
1166
1167/*
1168 * IndexError extends LookupError
1169 */
1170SimpleExtendsException(PyExc_LookupError, IndexError,
1171 "Sequence index out of range.");
1172
1173
1174/*
1175 * KeyError extends LookupError
1176 */
1177static PyObject *
1178KeyError_str(PyBaseExceptionObject *self)
1179{
1180 /* If args is a tuple of exactly one item, apply repr to args[0].
1181 This is done so that e.g. the exception raised by {}[''] prints
1182 KeyError: ''
1183 rather than the confusing
1184 KeyError
1185 alone. The downside is that if KeyError is raised with an explanatory
1186 string, that string will be displayed in quotes. Too bad.
1187 If args is anything else, use the default BaseException__str__().
1188 */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001189 if (PyTuple_GET_SIZE(self->args) == 1) {
1190 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001191 }
1192 return BaseException_str(self);
1193}
1194
1195ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
1196 0, 0, 0, KeyError_str, "Mapping key not found.");
1197
1198
1199/*
1200 * ValueError extends StandardError
1201 */
1202SimpleExtendsException(PyExc_StandardError, ValueError,
1203 "Inappropriate argument value (of correct type).");
1204
1205/*
1206 * UnicodeError extends ValueError
1207 */
1208
1209SimpleExtendsException(PyExc_ValueError, UnicodeError,
1210 "Unicode related error.");
1211
Thomas Wouters477c8d52006-05-27 19:21:47 +00001212static int
1213get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1214{
1215 if (!attr) {
1216 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1217 return -1;
1218 }
1219
Guido van Rossumddefaf32007-01-14 03:31:43 +00001220 if (PyLong_Check(attr)) {
1221 *value = PyLong_AsSsize_t(attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001222 if (*value == -1 && PyErr_Occurred())
1223 return -1;
1224 } else {
1225 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1226 return -1;
1227 }
1228 return 0;
1229}
1230
1231static int
1232set_ssize_t(PyObject **attr, Py_ssize_t value)
1233{
1234 PyObject *obj = PyInt_FromSsize_t(value);
1235 if (!obj)
1236 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001237 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001238 *attr = obj;
1239 return 0;
1240}
1241
1242static PyObject *
1243get_string(PyObject *attr, const char *name)
1244{
1245 if (!attr) {
1246 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1247 return NULL;
1248 }
1249
1250 if (!PyString_Check(attr)) {
1251 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1252 return NULL;
1253 }
1254 Py_INCREF(attr);
1255 return attr;
1256}
1257
1258
1259static int
1260set_string(PyObject **attr, const char *value)
1261{
1262 PyObject *obj = PyString_FromString(value);
1263 if (!obj)
1264 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001265 Py_CLEAR(*attr);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001266 *attr = obj;
1267 return 0;
1268}
1269
1270
1271static PyObject *
Walter Dörwald612344f2007-05-04 19:28:21 +00001272get_bytes(PyObject *attr, const char *name)
1273{
1274 if (!attr) {
1275 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1276 return NULL;
1277 }
1278
1279 if (!PyBytes_Check(attr)) {
1280 PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name);
1281 return NULL;
1282 }
1283 Py_INCREF(attr);
1284 return attr;
1285}
1286
1287static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001288get_unicode(PyObject *attr, const char *name)
1289{
1290 if (!attr) {
1291 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1292 return NULL;
1293 }
1294
1295 if (!PyUnicode_Check(attr)) {
1296 PyErr_Format(PyExc_TypeError,
1297 "%.200s attribute must be unicode", name);
1298 return NULL;
1299 }
1300 Py_INCREF(attr);
1301 return attr;
1302}
1303
1304PyObject *
1305PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1306{
1307 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1308}
1309
1310PyObject *
1311PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1312{
1313 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1314}
1315
1316PyObject *
1317PyUnicodeEncodeError_GetObject(PyObject *exc)
1318{
1319 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1320}
1321
1322PyObject *
1323PyUnicodeDecodeError_GetObject(PyObject *exc)
1324{
Walter Dörwald612344f2007-05-04 19:28:21 +00001325 return get_bytes(((PyUnicodeErrorObject *)exc)->object, "object");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326}
1327
1328PyObject *
1329PyUnicodeTranslateError_GetObject(PyObject *exc)
1330{
1331 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1332}
1333
1334int
1335PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1336{
1337 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1338 Py_ssize_t size;
1339 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1340 "object");
1341 if (!obj) return -1;
1342 size = PyUnicode_GET_SIZE(obj);
1343 if (*start<0)
1344 *start = 0; /*XXX check for values <0*/
1345 if (*start>=size)
1346 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348 return 0;
1349 }
1350 return -1;
1351}
1352
1353
1354int
1355PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1356{
1357 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1358 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001359 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360 "object");
1361 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001362 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001363 if (*start<0)
1364 *start = 0;
1365 if (*start>=size)
1366 *start = size-1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001367 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368 return 0;
1369 }
1370 return -1;
1371}
1372
1373
1374int
1375PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1376{
1377 return PyUnicodeEncodeError_GetStart(exc, start);
1378}
1379
1380
1381int
1382PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1383{
1384 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1385}
1386
1387
1388int
1389PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1390{
1391 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1392}
1393
1394
1395int
1396PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1397{
1398 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1399}
1400
1401
1402int
1403PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1404{
1405 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1406 Py_ssize_t size;
1407 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1408 "object");
1409 if (!obj) return -1;
1410 size = PyUnicode_GET_SIZE(obj);
1411 if (*end<1)
1412 *end = 1;
1413 if (*end>size)
1414 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001415 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416 return 0;
1417 }
1418 return -1;
1419}
1420
1421
1422int
1423PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1424{
1425 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1426 Py_ssize_t size;
Walter Dörwald612344f2007-05-04 19:28:21 +00001427 PyObject *obj = get_bytes(((PyUnicodeErrorObject *)exc)->object,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428 "object");
1429 if (!obj) return -1;
Walter Dörwald612344f2007-05-04 19:28:21 +00001430 size = PyBytes_GET_SIZE(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431 if (*end<1)
1432 *end = 1;
1433 if (*end>size)
1434 *end = size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001435 Py_DECREF(obj);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436 return 0;
1437 }
1438 return -1;
1439}
1440
1441
1442int
1443PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1444{
1445 return PyUnicodeEncodeError_GetEnd(exc, start);
1446}
1447
1448
1449int
1450PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1451{
1452 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1453}
1454
1455
1456int
1457PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1458{
1459 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1460}
1461
1462
1463int
1464PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1465{
1466 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1467}
1468
1469PyObject *
1470PyUnicodeEncodeError_GetReason(PyObject *exc)
1471{
1472 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1473}
1474
1475
1476PyObject *
1477PyUnicodeDecodeError_GetReason(PyObject *exc)
1478{
1479 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1480}
1481
1482
1483PyObject *
1484PyUnicodeTranslateError_GetReason(PyObject *exc)
1485{
1486 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1487}
1488
1489
1490int
1491PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1492{
1493 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1494}
1495
1496
1497int
1498PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1499{
1500 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1501}
1502
1503
1504int
1505PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1506{
1507 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1508}
1509
1510
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511static int
1512UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1513 PyTypeObject *objecttype)
1514{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001515 Py_CLEAR(self->encoding);
1516 Py_CLEAR(self->object);
1517 Py_CLEAR(self->start);
1518 Py_CLEAR(self->end);
1519 Py_CLEAR(self->reason);
1520
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1522 &PyString_Type, &self->encoding,
1523 objecttype, &self->object,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001524 &PyLong_Type, &self->start,
1525 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526 &PyString_Type, &self->reason)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001527 self->encoding = self->object = self->start = self->end =
Thomas Wouters477c8d52006-05-27 19:21:47 +00001528 self->reason = NULL;
1529 return -1;
1530 }
1531
1532 Py_INCREF(self->encoding);
1533 Py_INCREF(self->object);
1534 Py_INCREF(self->start);
1535 Py_INCREF(self->end);
1536 Py_INCREF(self->reason);
1537
1538 return 0;
1539}
1540
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001541static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542UnicodeError_clear(PyUnicodeErrorObject *self)
1543{
1544 Py_CLEAR(self->encoding);
1545 Py_CLEAR(self->object);
1546 Py_CLEAR(self->start);
1547 Py_CLEAR(self->end);
1548 Py_CLEAR(self->reason);
1549 return BaseException_clear((PyBaseExceptionObject *)self);
1550}
1551
1552static void
1553UnicodeError_dealloc(PyUnicodeErrorObject *self)
1554{
Thomas Wouters89f507f2006-12-13 04:49:30 +00001555 _PyObject_GC_UNTRACK(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556 UnicodeError_clear(self);
1557 self->ob_type->tp_free((PyObject *)self);
1558}
1559
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001560static int
Thomas Wouters477c8d52006-05-27 19:21:47 +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 */
Thomas Wouters477c8d52006-05-27 19:21:47 +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))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001608 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001609
1610 if (PyUnicodeEncodeError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001611 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001612
1613 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +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 );
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Neal Norwitz2633c692007-02-26 22:22:47 +00001642 "UnicodeEncodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001643 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,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001647 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1648 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001650 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +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",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001660 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001661}
1662
1663
1664/*
1665 * UnicodeDecodeError extends UnicodeError
1666 */
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Walter Dörwald612344f2007-05-04 19:28:21 +00001674 kwds, &PyBytes_Type);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675}
1676
1677static PyObject *
1678UnicodeDecodeError_str(PyObject *self)
1679{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001680 Py_ssize_t start = 0;
1681 Py_ssize_t end = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +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) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001690 /* FromFormat does not support %02x, so format that separately */
1691 char byte[4];
1692 PyOS_snprintf(byte, sizeof(byte), "%02x",
Walter Dörwald612344f2007-05-04 19:28:21 +00001693 ((int)PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001694 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 );
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Neal Norwitz2633c692007-02-26 22:22:47 +00001714 "UnicodeDecodeError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 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,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001719 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1720 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001722 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +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);
Walter Dörwald612344f2007-05-04 19:28:21 +00001734 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001735 encoding, object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736}
1737
1738
1739/*
1740 * UnicodeTranslateError extends UnicodeError
1741 */
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Guido van Rossumddefaf32007-01-14 03:31:43 +00001757 &PyLong_Type, &self->start,
1758 &PyLong_Type, &self->end,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001759 &PyString_Type, &self->reason)) {
1760 self->object = self->start = self->end = self->reason = NULL;
1761 return -1;
1762 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001763
Thomas Wouters477c8d52006-05-27 19:21:47 +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))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001780 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001781
1782 if (PyUnicodeTranslateError_GetEnd(self, &end))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001783 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001784
1785 if (end==start+1) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +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(
Thomas Wouters477c8d52006-05-27 19:21:47 +00001795 "can't translate character u'\\%s' in position %zd: %.400s",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001796 badchar_str,
1797 start,
1798 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1799 );
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Neal Norwitz2633c692007-02-26 22:22:47 +00001812 "UnicodeTranslateError",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001813 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,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001817 PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001818 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1819 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001820 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Thomas Wouters477c8d52006-05-27 19:21:47 +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",
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001830 object, length, start, end, reason);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001831}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001832
1833
1834/*
1835 * AssertionError extends StandardError
1836 */
1837SimpleExtendsException(PyExc_StandardError, AssertionError,
1838 "Assertion failed.");
1839
1840
1841/*
1842 * ArithmeticError extends StandardError
1843 */
1844SimpleExtendsException(PyExc_StandardError, ArithmeticError,
1845 "Base class for arithmetic errors.");
1846
1847
1848/*
1849 * FloatingPointError extends ArithmeticError
1850 */
1851SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
1852 "Floating point operation failed.");
1853
1854
1855/*
1856 * OverflowError extends ArithmeticError
1857 */
1858SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
1859 "Result too large to be represented.");
1860
1861
1862/*
1863 * ZeroDivisionError extends ArithmeticError
1864 */
1865SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
1866 "Second argument to a division or modulo operation was zero.");
1867
1868
1869/*
1870 * SystemError extends StandardError
1871 */
1872SimpleExtendsException(PyExc_StandardError, SystemError,
1873 "Internal error in the Python interpreter.\n"
1874 "\n"
1875 "Please report this to the Python maintainer, along with the traceback,\n"
1876 "the Python version, and the hardware/OS platform and version.");
1877
1878
1879/*
1880 * ReferenceError extends StandardError
1881 */
1882SimpleExtendsException(PyExc_StandardError, ReferenceError,
1883 "Weak ref proxy used after referent went away.");
1884
1885
1886/*
1887 * MemoryError extends StandardError
1888 */
1889SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
1890
1891
1892/* Warning category docstrings */
1893
1894/*
1895 * Warning extends Exception
1896 */
1897SimpleExtendsException(PyExc_Exception, Warning,
1898 "Base class for warning categories.");
1899
1900
1901/*
1902 * UserWarning extends Warning
1903 */
1904SimpleExtendsException(PyExc_Warning, UserWarning,
1905 "Base class for warnings generated by user code.");
1906
1907
1908/*
1909 * DeprecationWarning extends Warning
1910 */
1911SimpleExtendsException(PyExc_Warning, DeprecationWarning,
1912 "Base class for warnings about deprecated features.");
1913
1914
1915/*
1916 * PendingDeprecationWarning extends Warning
1917 */
1918SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1919 "Base class for warnings about features which will be deprecated\n"
1920 "in the future.");
1921
1922
1923/*
1924 * SyntaxWarning extends Warning
1925 */
1926SimpleExtendsException(PyExc_Warning, SyntaxWarning,
1927 "Base class for warnings about dubious syntax.");
1928
1929
1930/*
1931 * RuntimeWarning extends Warning
1932 */
1933SimpleExtendsException(PyExc_Warning, RuntimeWarning,
1934 "Base class for warnings about dubious runtime behavior.");
1935
1936
1937/*
1938 * FutureWarning extends Warning
1939 */
1940SimpleExtendsException(PyExc_Warning, FutureWarning,
1941 "Base class for warnings about constructs that will change semantically\n"
1942 "in the future.");
1943
1944
1945/*
1946 * ImportWarning extends Warning
1947 */
1948SimpleExtendsException(PyExc_Warning, ImportWarning,
1949 "Base class for warnings about probable mistakes in module imports");
1950
1951
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001952/*
1953 * UnicodeWarning extends Warning
1954 */
1955SimpleExtendsException(PyExc_Warning, UnicodeWarning,
1956 "Base class for warnings about Unicode related problems, mostly\n"
1957 "related to conversion problems.");
1958
1959
Thomas Wouters477c8d52006-05-27 19:21:47 +00001960/* Pre-computed MemoryError instance. Best to create this as early as
1961 * possible and not wait until a MemoryError is actually raised!
1962 */
1963PyObject *PyExc_MemoryErrorInst=NULL;
1964
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1966 Py_FatalError("exceptions bootstrapping error.");
1967
1968#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
Thomas Wouters477c8d52006-05-27 19:21:47 +00001969 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1970 Py_FatalError("Module dictionary insertion problem.");
1971
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001972#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
1973/* crt variable checking in VisualStudio .NET 2005 */
1974#include <crtdbg.h>
1975
1976static int prevCrtReportMode;
1977static _invalid_parameter_handler prevCrtHandler;
1978
1979/* Invalid parameter handler. Sets a ValueError exception */
1980static void
1981InvalidParameterHandler(
1982 const wchar_t * expression,
1983 const wchar_t * function,
1984 const wchar_t * file,
1985 unsigned int line,
1986 uintptr_t pReserved)
1987{
1988 /* Do nothing, allow execution to continue. Usually this
1989 * means that the CRT will set errno to EINVAL
1990 */
1991}
1992#endif
1993
1994
Thomas Wouters477c8d52006-05-27 19:21:47 +00001995PyMODINIT_FUNC
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001996_PyExc_Init(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997{
Neal Norwitz2633c692007-02-26 22:22:47 +00001998 PyObject *bltinmod, *bdict;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999
2000 PRE_INIT(BaseException)
2001 PRE_INIT(Exception)
2002 PRE_INIT(StandardError)
2003 PRE_INIT(TypeError)
2004 PRE_INIT(StopIteration)
2005 PRE_INIT(GeneratorExit)
2006 PRE_INIT(SystemExit)
2007 PRE_INIT(KeyboardInterrupt)
2008 PRE_INIT(ImportError)
2009 PRE_INIT(EnvironmentError)
2010 PRE_INIT(IOError)
2011 PRE_INIT(OSError)
2012#ifdef MS_WINDOWS
2013 PRE_INIT(WindowsError)
2014#endif
2015#ifdef __VMS
2016 PRE_INIT(VMSError)
2017#endif
2018 PRE_INIT(EOFError)
2019 PRE_INIT(RuntimeError)
2020 PRE_INIT(NotImplementedError)
2021 PRE_INIT(NameError)
2022 PRE_INIT(UnboundLocalError)
2023 PRE_INIT(AttributeError)
2024 PRE_INIT(SyntaxError)
2025 PRE_INIT(IndentationError)
2026 PRE_INIT(TabError)
2027 PRE_INIT(LookupError)
2028 PRE_INIT(IndexError)
2029 PRE_INIT(KeyError)
2030 PRE_INIT(ValueError)
2031 PRE_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002032 PRE_INIT(UnicodeEncodeError)
2033 PRE_INIT(UnicodeDecodeError)
2034 PRE_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002035 PRE_INIT(AssertionError)
2036 PRE_INIT(ArithmeticError)
2037 PRE_INIT(FloatingPointError)
2038 PRE_INIT(OverflowError)
2039 PRE_INIT(ZeroDivisionError)
2040 PRE_INIT(SystemError)
2041 PRE_INIT(ReferenceError)
2042 PRE_INIT(MemoryError)
2043 PRE_INIT(Warning)
2044 PRE_INIT(UserWarning)
2045 PRE_INIT(DeprecationWarning)
2046 PRE_INIT(PendingDeprecationWarning)
2047 PRE_INIT(SyntaxWarning)
2048 PRE_INIT(RuntimeWarning)
2049 PRE_INIT(FutureWarning)
2050 PRE_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002051 PRE_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002052
Thomas Wouters477c8d52006-05-27 19:21:47 +00002053 bltinmod = PyImport_ImportModule("__builtin__");
2054 if (bltinmod == NULL)
2055 Py_FatalError("exceptions bootstrapping error.");
2056 bdict = PyModule_GetDict(bltinmod);
2057 if (bdict == NULL)
2058 Py_FatalError("exceptions bootstrapping error.");
2059
2060 POST_INIT(BaseException)
2061 POST_INIT(Exception)
2062 POST_INIT(StandardError)
2063 POST_INIT(TypeError)
2064 POST_INIT(StopIteration)
2065 POST_INIT(GeneratorExit)
2066 POST_INIT(SystemExit)
2067 POST_INIT(KeyboardInterrupt)
2068 POST_INIT(ImportError)
2069 POST_INIT(EnvironmentError)
2070 POST_INIT(IOError)
2071 POST_INIT(OSError)
2072#ifdef MS_WINDOWS
2073 POST_INIT(WindowsError)
2074#endif
2075#ifdef __VMS
2076 POST_INIT(VMSError)
2077#endif
2078 POST_INIT(EOFError)
2079 POST_INIT(RuntimeError)
2080 POST_INIT(NotImplementedError)
2081 POST_INIT(NameError)
2082 POST_INIT(UnboundLocalError)
2083 POST_INIT(AttributeError)
2084 POST_INIT(SyntaxError)
2085 POST_INIT(IndentationError)
2086 POST_INIT(TabError)
2087 POST_INIT(LookupError)
2088 POST_INIT(IndexError)
2089 POST_INIT(KeyError)
2090 POST_INIT(ValueError)
2091 POST_INIT(UnicodeError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002092 POST_INIT(UnicodeEncodeError)
2093 POST_INIT(UnicodeDecodeError)
2094 POST_INIT(UnicodeTranslateError)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002095 POST_INIT(AssertionError)
2096 POST_INIT(ArithmeticError)
2097 POST_INIT(FloatingPointError)
2098 POST_INIT(OverflowError)
2099 POST_INIT(ZeroDivisionError)
2100 POST_INIT(SystemError)
2101 POST_INIT(ReferenceError)
2102 POST_INIT(MemoryError)
2103 POST_INIT(Warning)
2104 POST_INIT(UserWarning)
2105 POST_INIT(DeprecationWarning)
2106 POST_INIT(PendingDeprecationWarning)
2107 POST_INIT(SyntaxWarning)
2108 POST_INIT(RuntimeWarning)
2109 POST_INIT(FutureWarning)
2110 POST_INIT(ImportWarning)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002111 POST_INIT(UnicodeWarning)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002112
2113 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2114 if (!PyExc_MemoryErrorInst)
2115 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2116
2117 Py_DECREF(bltinmod);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002118
2119#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2120 /* Set CRT argument error handler */
2121 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2122 /* turn off assertions in debug mode */
2123 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2124#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002125}
2126
2127void
2128_PyExc_Fini(void)
2129{
2130 Py_XDECREF(PyExc_MemoryErrorInst);
2131 PyExc_MemoryErrorInst = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002132#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
2133 /* reset CRT error handling */
2134 _set_invalid_parameter_handler(prevCrtHandler);
2135 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2136#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00002137}