source: python/trunk/Python/errors.c@ 383

Last change on this file since 383 was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 17.8 KB
Line 
1
2/* Error handling */
3
4#include "Python.h"
5
6#ifndef __STDC__
7#ifndef MS_WINDOWS
8extern char *strerror(int);
9#endif
10#endif
11
12#ifdef MS_WINDOWS
13#include "windows.h"
14#include "winbase.h"
15#endif
16
17#include <ctype.h>
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23
24void
25PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
26{
27 PyThreadState *tstate = PyThreadState_GET();
28 PyObject *oldtype, *oldvalue, *oldtraceback;
29
30 if (traceback != NULL && !PyTraceBack_Check(traceback)) {
31 /* XXX Should never happen -- fatal error instead? */
32 /* Well, it could be None. */
33 Py_DECREF(traceback);
34 traceback = NULL;
35 }
36
37 /* Save these in locals to safeguard against recursive
38 invocation through Py_XDECREF */
39 oldtype = tstate->curexc_type;
40 oldvalue = tstate->curexc_value;
41 oldtraceback = tstate->curexc_traceback;
42
43 tstate->curexc_type = type;
44 tstate->curexc_value = value;
45 tstate->curexc_traceback = traceback;
46
47 Py_XDECREF(oldtype);
48 Py_XDECREF(oldvalue);
49 Py_XDECREF(oldtraceback);
50}
51
52void
53PyErr_SetObject(PyObject *exception, PyObject *value)
54{
55 Py_XINCREF(exception);
56 Py_XINCREF(value);
57 PyErr_Restore(exception, value, (PyObject *)NULL);
58}
59
60void
61PyErr_SetNone(PyObject *exception)
62{
63 PyErr_SetObject(exception, (PyObject *)NULL);
64}
65
66void
67PyErr_SetString(PyObject *exception, const char *string)
68{
69 PyObject *value = PyString_FromString(string);
70 PyErr_SetObject(exception, value);
71 Py_XDECREF(value);
72}
73
74
75PyObject *
76PyErr_Occurred(void)
77{
78 PyThreadState *tstate = PyThreadState_GET();
79
80 return tstate->curexc_type;
81}
82
83
84int
85PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
86{
87 if (err == NULL || exc == NULL) {
88 /* maybe caused by "import exceptions" that failed early on */
89 return 0;
90 }
91 if (PyTuple_Check(exc)) {
92 Py_ssize_t i, n;
93 n = PyTuple_Size(exc);
94 for (i = 0; i < n; i++) {
95 /* Test recursively */
96 if (PyErr_GivenExceptionMatches(
97 err, PyTuple_GET_ITEM(exc, i)))
98 {
99 return 1;
100 }
101 }
102 return 0;
103 }
104 /* err might be an instance, so check its class. */
105 if (PyExceptionInstance_Check(err))
106 err = PyExceptionInstance_Class(err);
107
108 if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
109 int res = 0;
110 PyObject *exception, *value, *tb;
111 PyErr_Fetch(&exception, &value, &tb);
112 res = PyObject_IsSubclass(err, exc);
113 /* This function must not fail, so print the error here */
114 if (res == -1) {
115 PyErr_WriteUnraisable(err);
116 res = 0;
117 }
118 PyErr_Restore(exception, value, tb);
119 return res;
120 }
121
122 return err == exc;
123}
124
125
126int
127PyErr_ExceptionMatches(PyObject *exc)
128{
129 return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
130}
131
132
133/* Used in many places to normalize a raised exception, including in
134 eval_code2(), do_raise(), and PyErr_Print()
135*/
136void
137PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
138{
139 PyObject *type = *exc;
140 PyObject *value = *val;
141 PyObject *inclass = NULL;
142 PyObject *initial_tb = NULL;
143 PyThreadState *tstate = NULL;
144
145 if (type == NULL) {
146 /* There was no exception, so nothing to do. */
147 return;
148 }
149
150 /* If PyErr_SetNone() was used, the value will have been actually
151 set to NULL.
152 */
153 if (!value) {
154 value = Py_None;
155 Py_INCREF(value);
156 }
157
158 if (PyExceptionInstance_Check(value))
159 inclass = PyExceptionInstance_Class(value);
160
161 /* Normalize the exception so that if the type is a class, the
162 value will be an instance.
163 */
164 if (PyExceptionClass_Check(type)) {
165 /* if the value was not an instance, or is not an instance
166 whose class is (or is derived from) type, then use the
167 value as an argument to instantiation of the type
168 class.
169 */
170 if (!inclass || !PyObject_IsSubclass(inclass, type)) {
171 PyObject *args, *res;
172
173 if (value == Py_None)
174 args = PyTuple_New(0);
175 else if (PyTuple_Check(value)) {
176 Py_INCREF(value);
177 args = value;
178 }
179 else
180 args = PyTuple_Pack(1, value);
181
182 if (args == NULL)
183 goto finally;
184 res = PyEval_CallObject(type, args);
185 Py_DECREF(args);
186 if (res == NULL)
187 goto finally;
188 Py_DECREF(value);
189 value = res;
190 }
191 /* if the class of the instance doesn't exactly match the
192 class of the type, believe the instance
193 */
194 else if (inclass != type) {
195 Py_DECREF(type);
196 type = inclass;
197 Py_INCREF(type);
198 }
199 }
200 *exc = type;
201 *val = value;
202 return;
203finally:
204 Py_DECREF(type);
205 Py_DECREF(value);
206 /* If the new exception doesn't set a traceback and the old
207 exception had a traceback, use the old traceback for the
208 new exception. It's better than nothing.
209 */
210 initial_tb = *tb;
211 PyErr_Fetch(exc, val, tb);
212 if (initial_tb != NULL) {
213 if (*tb == NULL)
214 *tb = initial_tb;
215 else
216 Py_DECREF(initial_tb);
217 }
218 /* normalize recursively */
219 tstate = PyThreadState_GET();
220 if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
221 --tstate->recursion_depth;
222 /* throw away the old exception... */
223 Py_DECREF(*exc);
224 Py_DECREF(*val);
225 /* ... and use the recursion error instead */
226 *exc = PyExc_RuntimeError;
227 *val = PyExc_RecursionErrorInst;
228 Py_INCREF(*exc);
229 Py_INCREF(*val);
230 /* just keeping the old traceback */
231 return;
232 }
233 PyErr_NormalizeException(exc, val, tb);
234 --tstate->recursion_depth;
235}
236
237
238void
239PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
240{
241 PyThreadState *tstate = PyThreadState_GET();
242
243 *p_type = tstate->curexc_type;
244 *p_value = tstate->curexc_value;
245 *p_traceback = tstate->curexc_traceback;
246
247 tstate->curexc_type = NULL;
248 tstate->curexc_value = NULL;
249 tstate->curexc_traceback = NULL;
250}
251
252void
253PyErr_Clear(void)
254{
255 PyErr_Restore(NULL, NULL, NULL);
256}
257
258/* Convenience functions to set a type error exception and return 0 */
259
260int
261PyErr_BadArgument(void)
262{
263 PyErr_SetString(PyExc_TypeError,
264 "bad argument type for built-in operation");
265 return 0;
266}
267
268PyObject *
269PyErr_NoMemory(void)
270{
271 if (PyErr_ExceptionMatches(PyExc_MemoryError))
272 /* already current */
273 return NULL;
274
275 /* raise the pre-allocated instance if it still exists */
276 if (PyExc_MemoryErrorInst)
277 PyErr_SetObject(PyExc_MemoryError, PyExc_MemoryErrorInst);
278 else
279 /* this will probably fail since there's no memory and hee,
280 hee, we have to instantiate this class
281 */
282 PyErr_SetNone(PyExc_MemoryError);
283
284 return NULL;
285}
286
287PyObject *
288PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
289{
290 PyObject *v;
291 char *s;
292 int i = errno;
293#ifdef PLAN9
294 char errbuf[ERRMAX];
295#endif
296#ifdef MS_WINDOWS
297 char *s_buf = NULL;
298 char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
299#endif
300#ifdef EINTR
301 if (i == EINTR && PyErr_CheckSignals())
302 return NULL;
303#endif
304#ifdef PLAN9
305 rerrstr(errbuf, sizeof errbuf);
306 s = errbuf;
307#else
308 if (i == 0)
309 s = "Error"; /* Sometimes errno didn't get set */
310 else
311#ifndef MS_WINDOWS
312 s = strerror(i);
313#else
314 {
315 /* Note that the Win32 errors do not lineup with the
316 errno error. So if the error is in the MSVC error
317 table, we use it, otherwise we assume it really _is_
318 a Win32 error code
319 */
320 if (i > 0 && i < _sys_nerr) {
321 s = _sys_errlist[i];
322 }
323 else {
324 int len = FormatMessage(
325 FORMAT_MESSAGE_ALLOCATE_BUFFER |
326 FORMAT_MESSAGE_FROM_SYSTEM |
327 FORMAT_MESSAGE_IGNORE_INSERTS,
328 NULL, /* no message source */
329 i,
330 MAKELANGID(LANG_NEUTRAL,
331 SUBLANG_DEFAULT),
332 /* Default language */
333 (LPTSTR) &s_buf,
334 0, /* size not used */
335 NULL); /* no args */
336 if (len==0) {
337 /* Only ever seen this in out-of-mem
338 situations */
339 sprintf(s_small_buf, "Windows Error 0x%X", i);
340 s = s_small_buf;
341 s_buf = NULL;
342 } else {
343 s = s_buf;
344 /* remove trailing cr/lf and dots */
345 while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
346 s[--len] = '\0';
347 }
348 }
349 }
350#endif /* Unix/Windows */
351#endif /* PLAN 9*/
352 if (filenameObject != NULL)
353 v = Py_BuildValue("(isO)", i, s, filenameObject);
354 else
355 v = Py_BuildValue("(is)", i, s);
356 if (v != NULL) {
357 PyErr_SetObject(exc, v);
358 Py_DECREF(v);
359 }
360#ifdef MS_WINDOWS
361 LocalFree(s_buf);
362#endif
363 return NULL;
364}
365
366
367PyObject *
368PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
369{
370 PyObject *name = filename ? PyString_FromString(filename) : NULL;
371 PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
372 Py_XDECREF(name);
373 return result;
374}
375
376#ifdef Py_WIN_WIDE_FILENAMES
377PyObject *
378PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
379{
380 PyObject *name = filename ?
381 PyUnicode_FromUnicode(filename, wcslen(filename)) :
382 NULL;
383 PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
384 Py_XDECREF(name);
385 return result;
386}
387#endif /* Py_WIN_WIDE_FILENAMES */
388
389PyObject *
390PyErr_SetFromErrno(PyObject *exc)
391{
392 return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
393}
394
395#ifdef MS_WINDOWS
396/* Windows specific error code handling */
397PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
398 PyObject *exc,
399 int ierr,
400 PyObject *filenameObject)
401{
402 int len;
403 char *s;
404 char *s_buf = NULL; /* Free via LocalFree */
405 char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
406 PyObject *v;
407 DWORD err = (DWORD)ierr;
408 if (err==0) err = GetLastError();
409 len = FormatMessage(
410 /* Error API error */
411 FORMAT_MESSAGE_ALLOCATE_BUFFER |
412 FORMAT_MESSAGE_FROM_SYSTEM |
413 FORMAT_MESSAGE_IGNORE_INSERTS,
414 NULL, /* no message source */
415 err,
416 MAKELANGID(LANG_NEUTRAL,
417 SUBLANG_DEFAULT), /* Default language */
418 (LPTSTR) &s_buf,
419 0, /* size not used */
420 NULL); /* no args */
421 if (len==0) {
422 /* Only seen this in out of mem situations */
423 sprintf(s_small_buf, "Windows Error 0x%X", err);
424 s = s_small_buf;
425 s_buf = NULL;
426 } else {
427 s = s_buf;
428 /* remove trailing cr/lf and dots */
429 while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
430 s[--len] = '\0';
431 }
432 if (filenameObject != NULL)
433 v = Py_BuildValue("(isO)", err, s, filenameObject);
434 else
435 v = Py_BuildValue("(is)", err, s);
436 if (v != NULL) {
437 PyErr_SetObject(exc, v);
438 Py_DECREF(v);
439 }
440 LocalFree(s_buf);
441 return NULL;
442}
443
444PyObject *PyErr_SetExcFromWindowsErrWithFilename(
445 PyObject *exc,
446 int ierr,
447 const char *filename)
448{
449 PyObject *name = filename ? PyString_FromString(filename) : NULL;
450 PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
451 ierr,
452 name);
453 Py_XDECREF(name);
454 return ret;
455}
456
457#ifdef Py_WIN_WIDE_FILENAMES
458PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
459 PyObject *exc,
460 int ierr,
461 const Py_UNICODE *filename)
462{
463 PyObject *name = filename ?
464 PyUnicode_FromUnicode(filename, wcslen(filename)) :
465 NULL;
466 PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
467 ierr,
468 name);
469 Py_XDECREF(name);
470 return ret;
471}
472#endif /* Py_WIN_WIDE_FILENAMES */
473
474PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
475{
476 return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
477}
478
479PyObject *PyErr_SetFromWindowsErr(int ierr)
480{
481 return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
482 ierr, NULL);
483}
484PyObject *PyErr_SetFromWindowsErrWithFilename(
485 int ierr,
486 const char *filename)
487{
488 PyObject *name = filename ? PyString_FromString(filename) : NULL;
489 PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
490 PyExc_WindowsError,
491 ierr, name);
492 Py_XDECREF(name);
493 return result;
494}
495
496#ifdef Py_WIN_WIDE_FILENAMES
497PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
498 int ierr,
499 const Py_UNICODE *filename)
500{
501 PyObject *name = filename ?
502 PyUnicode_FromUnicode(filename, wcslen(filename)) :
503 NULL;
504 PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
505 PyExc_WindowsError,
506 ierr, name);
507 Py_XDECREF(name);
508 return result;
509}
510#endif /* Py_WIN_WIDE_FILENAMES */
511#endif /* MS_WINDOWS */
512
513void
514_PyErr_BadInternalCall(char *filename, int lineno)
515{
516 PyErr_Format(PyExc_SystemError,
517 "%s:%d: bad argument to internal function",
518 filename, lineno);
519}
520
521/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
522 export the entry point for existing object code: */
523#undef PyErr_BadInternalCall
524void
525PyErr_BadInternalCall(void)
526{
527 PyErr_Format(PyExc_SystemError,
528 "bad argument to internal function");
529}
530#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
531
532
533
534PyObject *
535PyErr_Format(PyObject *exception, const char *format, ...)
536{
537 va_list vargs;
538 PyObject* string;
539
540#ifdef HAVE_STDARG_PROTOTYPES
541 va_start(vargs, format);
542#else
543 va_start(vargs);
544#endif
545
546 string = PyString_FromFormatV(format, vargs);
547 PyErr_SetObject(exception, string);
548 Py_XDECREF(string);
549 va_end(vargs);
550 return NULL;
551}
552
553
554
555PyObject *
556PyErr_NewException(char *name, PyObject *base, PyObject *dict)
557{
558 char *dot;
559 PyObject *modulename = NULL;
560 PyObject *classname = NULL;
561 PyObject *mydict = NULL;
562 PyObject *bases = NULL;
563 PyObject *result = NULL;
564 dot = strrchr(name, '.');
565 if (dot == NULL) {
566 PyErr_SetString(PyExc_SystemError,
567 "PyErr_NewException: name must be module.class");
568 return NULL;
569 }
570 if (base == NULL)
571 base = PyExc_Exception;
572 if (dict == NULL) {
573 dict = mydict = PyDict_New();
574 if (dict == NULL)
575 goto failure;
576 }
577 if (PyDict_GetItemString(dict, "__module__") == NULL) {
578 modulename = PyString_FromStringAndSize(name,
579 (Py_ssize_t)(dot-name));
580 if (modulename == NULL)
581 goto failure;
582 if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
583 goto failure;
584 }
585 if (PyTuple_Check(base)) {
586 bases = base;
587 /* INCREF as we create a new ref in the else branch */
588 Py_INCREF(bases);
589 } else {
590 bases = PyTuple_Pack(1, base);
591 if (bases == NULL)
592 goto failure;
593 }
594 /* Create a real new-style class. */
595 result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
596 dot+1, bases, dict);
597 failure:
598 Py_XDECREF(bases);
599 Py_XDECREF(mydict);
600 Py_XDECREF(classname);
601 Py_XDECREF(modulename);
602 return result;
603}
604
605/* Call when an exception has occurred but there is no way for Python
606 to handle it. Examples: exception in __del__ or during GC. */
607void
608PyErr_WriteUnraisable(PyObject *obj)
609{
610 PyObject *f, *t, *v, *tb;
611 PyErr_Fetch(&t, &v, &tb);
612 f = PySys_GetObject("stderr");
613 if (f != NULL) {
614 PyFile_WriteString("Exception ", f);
615 if (t) {
616 PyObject* moduleName;
617 char* className;
618 assert(PyExceptionClass_Check(t));
619 className = PyExceptionClass_Name(t);
620 if (className != NULL) {
621 char *dot = strrchr(className, '.');
622 if (dot != NULL)
623 className = dot+1;
624 }
625
626 moduleName = PyObject_GetAttrString(t, "__module__");
627 if (moduleName == NULL)
628 PyFile_WriteString("<unknown>", f);
629 else {
630 char* modstr = PyString_AsString(moduleName);
631 if (modstr &&
632 strcmp(modstr, "exceptions") != 0)
633 {
634 PyFile_WriteString(modstr, f);
635 PyFile_WriteString(".", f);
636 }
637 }
638 if (className == NULL)
639 PyFile_WriteString("<unknown>", f);
640 else
641 PyFile_WriteString(className, f);
642 if (v && v != Py_None) {
643 PyFile_WriteString(": ", f);
644 PyFile_WriteObject(v, f, 0);
645 }
646 Py_XDECREF(moduleName);
647 }
648 PyFile_WriteString(" in ", f);
649 PyFile_WriteObject(obj, f, 0);
650 PyFile_WriteString(" ignored\n", f);
651 PyErr_Clear(); /* Just in case */
652 }
653 Py_XDECREF(t);
654 Py_XDECREF(v);
655 Py_XDECREF(tb);
656}
657
658extern PyObject *PyModule_GetWarningsModule(void);
659
660
661/* Set file and line information for the current exception.
662 If the exception is not a SyntaxError, also sets additional attributes
663 to make printing of exceptions believe it is a syntax error. */
664
665void
666PyErr_SyntaxLocation(const char *filename, int lineno)
667{
668 PyObject *exc, *v, *tb, *tmp;
669
670 /* add attributes for the line number and filename for the error */
671 PyErr_Fetch(&exc, &v, &tb);
672 PyErr_NormalizeException(&exc, &v, &tb);
673 /* XXX check that it is, indeed, a syntax error. It might not
674 * be, though. */
675 tmp = PyInt_FromLong(lineno);
676 if (tmp == NULL)
677 PyErr_Clear();
678 else {
679 if (PyObject_SetAttrString(v, "lineno", tmp))
680 PyErr_Clear();
681 Py_DECREF(tmp);
682 }
683 if (filename != NULL) {
684 tmp = PyString_FromString(filename);
685 if (tmp == NULL)
686 PyErr_Clear();
687 else {
688 if (PyObject_SetAttrString(v, "filename", tmp))
689 PyErr_Clear();
690 Py_DECREF(tmp);
691 }
692
693 tmp = PyErr_ProgramText(filename, lineno);
694 if (tmp) {
695 if (PyObject_SetAttrString(v, "text", tmp))
696 PyErr_Clear();
697 Py_DECREF(tmp);
698 }
699 }
700 if (PyObject_SetAttrString(v, "offset", Py_None)) {
701 PyErr_Clear();
702 }
703 if (exc != PyExc_SyntaxError) {
704 if (!PyObject_HasAttrString(v, "msg")) {
705 tmp = PyObject_Str(v);
706 if (tmp) {
707 if (PyObject_SetAttrString(v, "msg", tmp))
708 PyErr_Clear();
709 Py_DECREF(tmp);
710 } else {
711 PyErr_Clear();
712 }
713 }
714 if (!PyObject_HasAttrString(v, "print_file_and_line")) {
715 if (PyObject_SetAttrString(v, "print_file_and_line",
716 Py_None))
717 PyErr_Clear();
718 }
719 }
720 PyErr_Restore(exc, v, tb);
721}
722
723/* com_fetch_program_text will attempt to load the line of text that
724 the exception refers to. If it fails, it will return NULL but will
725 not set an exception.
726
727 XXX The functionality of this function is quite similar to the
728 functionality in tb_displayline() in traceback.c.
729*/
730
731PyObject *
732PyErr_ProgramText(const char *filename, int lineno)
733{
734 FILE *fp;
735 int i;
736 char linebuf[1000];
737
738 if (filename == NULL || *filename == '\0' || lineno <= 0)
739 return NULL;
740 fp = fopen(filename, "r" PY_STDIOTEXTMODE);
741 if (fp == NULL)
742 return NULL;
743 for (i = 0; i < lineno; i++) {
744 char *pLastChar = &linebuf[sizeof(linebuf) - 2];
745 do {
746 *pLastChar = '\0';
747 if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, fp, NULL) == NULL)
748 break;
749 /* fgets read *something*; if it didn't get as
750 far as pLastChar, it must have found a newline
751 or hit the end of the file; if pLastChar is \n,
752 it obviously found a newline; else we haven't
753 yet seen a newline, so must continue */
754 } while (*pLastChar != '\0' && *pLastChar != '\n');
755 }
756 fclose(fp);
757 if (i == lineno) {
758 char *p = linebuf;
759 while (*p == ' ' || *p == '\t' || *p == '\014')
760 p++;
761 return PyString_FromString(p);
762 }
763 return NULL;
764}
765
766#ifdef __cplusplus
767}
768#endif
769
Note: See TracBrowser for help on using the repository browser.