Beispiel #1
0
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
{
  PyObject *exception, *value;
  PyTracebackObject *tb;

  *lineno = -1;
  *offset = 0;

  PyErr_Fetch(&exception, &value, (PyObject **)&tb);

  if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
    /* no traceback available when SyntaxError.
     * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
    PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
    PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */

    if (value) { /* should always be true */
      PyObject *message;
      PyObject *filename_py, *text_py;

      if (parse_syntax_error(value, &message, &filename_py, lineno, offset, &text_py)) {
        const char *filename = _PyUnicode_AsString(filename_py);
        /* python adds a '/', prefix, so check for both */
        if ((BLI_path_cmp(filename, filepath) == 0) ||
            ((filename[0] == '\\' || filename[0] == '/') &&
             BLI_path_cmp(filename + 1, filepath) == 0)) {
          /* good */
        }
        else {
          *lineno = -1;
        }
      }
      else {
        *lineno = -1;
      }
    }
  }
  else {
    PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
    PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
    PyErr_Print();

    for (tb = (PyTracebackObject *)PySys_GetObject("last_traceback");
         tb && (PyObject *)tb != Py_None;
         tb = tb->tb_next) {
      PyObject *coerce;
      const char *tb_filepath = traceback_filepath(tb, &coerce);
      const int match = ((BLI_path_cmp(tb_filepath, filepath) == 0) ||
                         ((tb_filepath[0] == '\\' || tb_filepath[0] == '/') &&
                          BLI_path_cmp(tb_filepath + 1, filepath) == 0));
      Py_DECREF(coerce);

      if (match) {
        *lineno = tb->tb_lineno;
        /* used to break here, but better find the inner most line */
      }
    }
  }
}
Beispiel #2
0
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
{
	PyObject *exception, *value;
	PyTracebackObject *tb;

	*lineno= -1;
	*offset= 0;

	PyErr_Fetch(&exception, &value, (PyObject **)&tb);

	if(exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
		/* no traceback available when SyntaxError.
		 * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */

		if(value) { /* should always be true */
			PyObject *message;
			const char *filename, *text;

			if(parse_syntax_error(value, &message, &filename, lineno, offset, &text)) {
				/* python adds a '/', prefix, so check for both */
				if(	(strcmp(filename, filepath) == 0) || 
					((filename[0] == '\\' || filename[0] == '/') && strcmp(filename + 1, filepath) == 0)
				) {
					/* good */
				}
				else {
					*lineno= -1;
				}
			}
			else {
				*lineno= -1;
			}
		}
	}
	else {
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */
		PyErr_Print();

		for(tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; tb= tb->tb_next) {
			if(strcmp(traceback_filepath(tb), filepath) != 0) {
				*lineno= tb->tb_lineno;
				break;
			}
		}
	}
}
Beispiel #3
0
void
PyErr_PrintEx(int set_sys_last_vars)
{
	int err = 0;
	PyObject *exception, *v, *tb, *f;
	PyErr_Fetch(&exception, &v, &tb);
	PyErr_NormalizeException(&exception, &v, &tb);

	if (exception == NULL)
		return;

	if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
		if (Py_FlushLine())
			PyErr_Clear();
		fflush(stdout);
		if (v == NULL || v == Py_None)
			Py_Exit(0);
		if (PyInstance_Check(v)) {
			/* we expect the error code to be store in the
			   `code' attribute
			*/
			PyObject *code = PyObject_GetAttrString(v, "code");
			if (code) {
				Py_DECREF(v);
				v = code;
				if (v == Py_None)
					Py_Exit(0);
			}
			/* if we failed to dig out the "code" attribute,
			   then just let the else clause below print the
			   error
			*/
		}
		if (PyInt_Check(v))
			Py_Exit((int)PyInt_AsLong(v));
		else {
			/* OK to use real stderr here */
			PyObject_Print(v, stderr, Py_PRINT_RAW);
			fprintf(stderr, "\n");
			Py_Exit(1);
		}
	}
	if (set_sys_last_vars) {
		PySys_SetObject("last_type", exception);
		PySys_SetObject("last_value", v);
		PySys_SetObject("last_traceback", tb);
	}
	f = PySys_GetObject("stderr");
	if (f == NULL)
		fprintf(stderr, "lost sys.stderr\n");
	else {
		if (Py_FlushLine())
			PyErr_Clear();
		fflush(stdout);
		err = PyTraceBack_Print(tb, f);
		if (err == 0 &&
		    PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
		{
			PyObject *message;
			char *filename, *text;
			int lineno, offset;
			if (!parse_syntax_error(v, &message, &filename,
						&lineno, &offset, &text))
				PyErr_Clear();
			else {
				char buf[10];
				PyFile_WriteString("  File \"", f);
				if (filename == NULL)
					PyFile_WriteString("<string>", f);
				else
					PyFile_WriteString(filename, f);
				PyFile_WriteString("\", line ", f);
				sprintf(buf, "%d", lineno);
				PyFile_WriteString(buf, f);
				PyFile_WriteString("\n", f);
				if (text != NULL) {
					char *nl;
					if (offset > 0 &&
					    offset == (int)strlen(text))
						offset--;
					for (;;) {
						nl = strchr(text, '\n');
						if (nl == NULL ||
						    nl-text >= offset)
							break;
						offset -= (nl+1-text);
						text = nl+1;
					}
					while (*text == ' ' || *text == '\t') {
						text++;
						offset--;
					}
					PyFile_WriteString("    ", f);
					PyFile_WriteString(text, f);
					if (*text == '\0' ||
					    text[strlen(text)-1] != '\n')
						PyFile_WriteString("\n", f);
					PyFile_WriteString("    ", f);
					offset--;
					while (offset > 0) {
						PyFile_WriteString(" ", f);
						offset--;
					}
					PyFile_WriteString("^\n", f);
				}
				Py_INCREF(message);
				Py_DECREF(v);
				v = message;
				/* Can't be bothered to check all those
				   PyFile_WriteString() calls */
				if (PyErr_Occurred())
					err = -1;
			}
		}
		if (err) {
			/* Don't do anything else */
		}
		else if (PyClass_Check(exception)) {
			PyClassObject* exc = (PyClassObject*)exception;
			PyObject* className = exc->cl_name;
			PyObject* moduleName =
			      PyDict_GetItemString(exc->cl_dict, "__module__");

			if (moduleName == NULL)
				err = PyFile_WriteString("<unknown>", f);
			else {
				char* modstr = PyString_AsString(moduleName);
				if (modstr && strcmp(modstr, "exceptions")) 
				{
					err = PyFile_WriteString(modstr, f);
					err += PyFile_WriteString(".", f);
				}
			}
			if (err == 0) {
				if (className == NULL)
				      err = PyFile_WriteString("<unknown>", f);
				else
				      err = PyFile_WriteObject(className, f,
							       Py_PRINT_RAW);
			}
		}
		else
			err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
		if (err == 0) {
			if (v != NULL && v != Py_None) {
				PyObject *s = PyObject_Str(v);
				/* only print colon if the str() of the
				   object is not the empty string
				*/
				if (s == NULL)
					err = -1;
				else if (!PyString_Check(s) ||
					 PyString_GET_SIZE(s) != 0)
					err = PyFile_WriteString(": ", f);
				if (err == 0)
				  err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
				Py_XDECREF(s);
			}
		}
		if (err == 0)
			err = PyFile_WriteString("\n", f);
	}
	Py_XDECREF(exception);
	Py_XDECREF(v);
	Py_XDECREF(tb);
	/* If an error happened here, don't show it.
	   XXX This is wrong, but too many callers rely on this behavior. */
	if (err != 0)
		PyErr_Clear();
}
Beispiel #4
0
static void
print_exception(PyObject *f, PyObject *value)
{
    int err = 0;
    PyObject *type, *tb;
    _Py_IDENTIFIER(print_file_and_line);

    if (!PyExceptionInstance_Check(value)) {
        err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f);
        err += PyFile_WriteString(Py_TYPE(value)->tp_name, f);
        err += PyFile_WriteString(" found\n", f);
        if (err)
            PyErr_Clear();
        return;
    }

    Py_INCREF(value);
    fflush(stdout);
    type = (PyObject *) Py_TYPE(value);
    tb = PyException_GetTraceback(value);
    if (tb && tb != Py_None)
        err = PyTraceBack_Print(tb, f);
    if (err == 0 &&
        _PyObject_HasAttrId(value, &PyId_print_file_and_line))
    {
        PyObject *message, *filename, *text;
        int lineno, offset;
        if (!parse_syntax_error(value, &message, &filename,
                                &lineno, &offset, &text))
            PyErr_Clear();
        else {
            PyObject *line;

            Py_DECREF(value);
            value = message;

            line = PyUnicode_FromFormat("  File \"%U\", line %d\n",
                                          filename, lineno);
            Py_DECREF(filename);
            if (line != NULL) {
                PyFile_WriteObject(line, f, Py_PRINT_RAW);
                Py_DECREF(line);
            }

            if (text != NULL) {
                print_error_text(f, offset, text);
                Py_DECREF(text);
            }

            /* Can't be bothered to check all those
               PyFile_WriteString() calls */
            if (PyErr_Occurred())
                err = -1;
        }
    }
    if (err) {
        /* Don't do anything else */
    }
    else {
        PyObject* moduleName;
        const char *className;
        _Py_IDENTIFIER(__module__);
        assert(PyExceptionClass_Check(type));
        className = PyExceptionClass_Name(type);
        if (className != NULL) {
            const char *dot = strrchr(className, '.');
            if (dot != NULL)
                className = dot+1;
        }

        moduleName = _PyObject_GetAttrId(type, &PyId___module__);
        if (moduleName == NULL || !PyUnicode_Check(moduleName))
        {
            Py_XDECREF(moduleName);
            err = PyFile_WriteString("<unknown>", f);
        }
        else {
            if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins))
            {
                err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW);
                err += PyFile_WriteString(".", f);
            }
            Py_DECREF(moduleName);
        }
        if (err == 0) {
            if (className == NULL)
                      err = PyFile_WriteString("<unknown>", f);
            else
                      err = PyFile_WriteString(className, f);
        }
    }
    if (err == 0 && (value != Py_None)) {
        PyObject *s = PyObject_Str(value);
        /* only print colon if the str() of the
           object is not the empty string
        */
        if (s == NULL) {
            PyErr_Clear();
            err = -1;
            PyFile_WriteString(": <exception str() failed>", f);
        }
        else if (!PyUnicode_Check(s) ||
            PyUnicode_GetLength(s) != 0)
            err = PyFile_WriteString(": ", f);
        if (err == 0)
          err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
        Py_XDECREF(s);
    }
    /* try to write a newline in any case */
    if (err < 0) {
        PyErr_Clear();
    }
    err += PyFile_WriteString("\n", f);
    Py_XDECREF(tb);
    Py_DECREF(value);
    /* If an error happened here, don't show it.
       XXX This is wrong, but too many callers rely on this behavior. */
    if (err != 0)
        PyErr_Clear();
}
Beispiel #5
0
void
PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
{
	int err = 0;
	PyObject *f = PySys_GetObject("stderr");
	Py_INCREF(value);
	if (f == NULL)
		fprintf(stderr, "lost sys.stderr\n");
	else {
		if (Py_FlushLine())
			PyErr_Clear();
		fflush(stdout);
		if (tb && tb != Py_None)
			err = PyTraceBack_Print(tb, f);
		if (err == 0 &&
		    PyObject_HasAttrString(value, "print_file_and_line"))
		{
			PyObject *message;
			const char *filename, *text;
			int lineno, offset;
			if (!parse_syntax_error(value, &message, &filename,
						&lineno, &offset, &text))
				PyErr_Clear();
			else {
				char buf[10];
				PyFile_WriteString("  File \"", f);
				if (filename == NULL)
					PyFile_WriteString("<string>", f);
				else
					PyFile_WriteString(filename, f);
				PyFile_WriteString("\", line ", f);
				PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
				PyFile_WriteString(buf, f);
				PyFile_WriteString("\n", f);
				if (text != NULL)
					print_error_text(f, offset, text);
				Py_DECREF(value);
				value = message;
				/* Can't be bothered to check all those
				   PyFile_WriteString() calls */
				if (PyErr_Occurred())
					err = -1;
			}
		}
		if (err) {
			/* Don't do anything else */
		}
		else if (PyExceptionClass_Check(exception)) {
			PyObject* moduleName;
			char* className = PyExceptionClass_Name(exception);
			if (className != NULL) {
				char *dot = strrchr(className, '.');
				if (dot != NULL)
					className = dot+1;
			}

			moduleName = PyObject_GetAttrString(exception, "__module__");
			if (moduleName == NULL)
				err = PyFile_WriteString("<unknown>", f);
			else {
				char* modstr = PyString_AsString(moduleName);
				if (modstr && strcmp(modstr, "exceptions"))
				{
					err = PyFile_WriteString(modstr, f);
					err += PyFile_WriteString(".", f);
				}
				Py_DECREF(moduleName);
			}
			if (err == 0) {
				if (className == NULL)
				      err = PyFile_WriteString("<unknown>", f);
				else
				      err = PyFile_WriteString(className, f);
			}
		}
		else
			err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
		if (err == 0 && (value != Py_None)) {
			PyObject *s = PyObject_Str(value);
			/* only print colon if the str() of the
			   object is not the empty string
			*/
			if (s == NULL)
				err = -1;
			else if (!PyString_Check(s) ||
				 PyString_GET_SIZE(s) != 0)
				err = PyFile_WriteString(": ", f);
			if (err == 0)
			  err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
			Py_XDECREF(s);
		}
		if (err == 0)
			err = PyFile_WriteString("\n", f);
	}
	Py_DECREF(value);
	/* If an error happened here, don't show it.
	   XXX This is wrong, but too many callers rely on this behavior. */
	if (err != 0)
		PyErr_Clear();
}