Ejemplo n.º 1
0
static void
_Py_PrintFatalError(int fd)
{
    PyObject *ferr, *res;
    PyObject *exception, *v, *tb;
    int has_tb;
    PyThreadState *tstate;

    PyErr_Fetch(&exception, &v, &tb);
    if (exception == NULL) {
        /* No current exception */
        goto display_stack;
    }

    ferr = _PySys_GetObjectId(&PyId_stderr);
    if (ferr == NULL || ferr == Py_None) {
        /* sys.stderr is not set yet or set to None,
           no need to try to display the exception */
        goto display_stack;
    }

    PyErr_NormalizeException(&exception, &v, &tb);
    if (tb == NULL) {
        tb = Py_None;
        Py_INCREF(tb);
    }
    PyException_SetTraceback(v, tb);
    if (exception == NULL) {
        /* PyErr_NormalizeException() failed */
        goto display_stack;
    }

    has_tb = (tb != Py_None);
    PyErr_Display(exception, v, tb);
    Py_XDECREF(exception);
    Py_XDECREF(v);
    Py_XDECREF(tb);

    /* sys.stderr may be buffered: call sys.stderr.flush() */
    res = _PyObject_CallMethodId(ferr, &PyId_flush, "");
    if (res == NULL)
        PyErr_Clear();
    else
        Py_DECREF(res);

    if (has_tb)
        return;

display_stack:
#ifdef WITH_THREAD
    /* PyGILState_GetThisThreadState() works even if the GIL was released */
    tstate = PyGILState_GetThisThreadState();
#else
    tstate = PyThreadState_GET();
#endif
    if (tstate == NULL) {
        /* _Py_DumpTracebackThreads() requires the thread state to display
         * frames */
        return;
    }

    fputc('\n', stderr);
    fflush(stderr);

    /* display the current Python stack */
    _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
}
Ejemplo n.º 2
0
/**
 * pygi_gerror_exception_check:
 * @error: a standard GLib GError ** output parameter
 *
 * Checks to see if a GError exception has been raised, and if so
 * translates the python exception to a standard GLib GError.  If the
 * raised exception is not a GError then PyErr_Print() is called.
 *
 * Returns: 0 if no exception has been raised, -1 if it is a
 * valid glib.GError, -2 otherwise.
 */
gboolean
pygi_gerror_exception_check (GError **error)
{
    PyObject *type, *value, *traceback;
    PyObject *py_message, *py_domain, *py_code;
    const char *bad_gerror_message;

    PyErr_Fetch(&type, &value, &traceback);
    if (type == NULL)
        return 0;
    PyErr_NormalizeException(&type, &value, &traceback);
    if (value == NULL) {
        PyErr_Restore(type, value, traceback);
        PyErr_Print();
        return -2;
    }
    if (!value ||
        !PyErr_GivenExceptionMatches(type,
                                     (PyObject *) PyGError)) {
        PyErr_Restore(type, value, traceback);
        PyErr_Print();
        return -2;
    }
    Py_DECREF(type);
    Py_XDECREF(traceback);

    py_message = PyObject_GetAttrString(value, "message");
    if (!py_message || !PYGLIB_PyUnicode_Check(py_message)) {
        bad_gerror_message = "GLib.Error instances must have a 'message' string attribute";
        Py_XDECREF(py_message);
        goto bad_gerror;
    }

    py_domain = PyObject_GetAttrString(value, "domain");
    if (!py_domain || !PYGLIB_PyUnicode_Check(py_domain)) {
        bad_gerror_message = "GLib.Error instances must have a 'domain' string attribute";
        Py_DECREF(py_message);
        Py_XDECREF(py_domain);
        goto bad_gerror;
    }

    py_code = PyObject_GetAttrString(value, "code");
    if (!py_code || !PYGLIB_PyLong_Check(py_code)) {
        bad_gerror_message = "GLib.Error instances must have a 'code' int attribute";
        Py_DECREF(py_message);
        Py_DECREF(py_domain);
        Py_XDECREF(py_code);
        goto bad_gerror;
    }

    g_set_error(error, g_quark_from_string(PYGLIB_PyUnicode_AsString(py_domain)),
                PYGLIB_PyLong_AsLong(py_code), "%s", PYGLIB_PyUnicode_AsString(py_message));

    Py_DECREF(py_message);
    Py_DECREF(py_code);
    Py_DECREF(py_domain);
    return -1;

bad_gerror:
    Py_DECREF(value);
    g_set_error(error, g_quark_from_static_string("pygi"), 0, "%s", bad_gerror_message);
    PyErr_SetString(PyExc_ValueError, bad_gerror_message);
    PyErr_Print();
    return -2;
}
Ejemplo n.º 3
0
static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
    PyObject *et, *ev, *tb;
    PyObject *value = NULL;

    __Pyx_ErrFetch(&et, &ev, &tb);

    if (!et) {
        Py_XDECREF(tb);
        Py_XDECREF(ev);
        Py_INCREF(Py_None);
        *pvalue = Py_None;
        return 0;
    }

    if (unlikely(et != PyExc_StopIteration) &&
            unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
    }

    // most common case: plain StopIteration without or with separate argument
    if (likely(et == PyExc_StopIteration)) {
        if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
            // PyErr_SetObject() and friends put the value directly into ev
            if (!ev) {
                Py_INCREF(Py_None);
                ev = Py_None;
            }
            Py_XDECREF(tb);
            Py_DECREF(et);
            *pvalue = ev;
            return 0;
        }
    }
    // otherwise: normalise and check what that gives us
    PyErr_NormalizeException(&et, &ev, &tb);
    if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
        // looks like normalisation failed - raise the new exception
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
    }
    Py_XDECREF(tb);
    Py_DECREF(et);
#if PY_VERSION_HEX >= 0x030300A0
    value = ((PyStopIterationObject *)ev)->value;
    Py_INCREF(value);
    Py_DECREF(ev);
#else
    {
        PyObject* args = PyObject_GetAttr(ev, PYIDENT("args"));
        Py_DECREF(ev);
        if (likely(args)) {
            value = PyObject_GetItem(args, 0);
            Py_DECREF(args);
        }
        if (unlikely(!value)) {
            __Pyx_ErrRestore(NULL, NULL, NULL);
            Py_INCREF(Py_None);
            value = Py_None;
        }
    }
#endif
    *pvalue = value;
    return 0;
}
Ejemplo n.º 4
0
/* Used in many places to normalize a raised exception, including in
   eval_code2(), do_raise(), and PyErr_Print()
*/
void
PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
{
	PyObject *type = *exc;
	PyObject *value = *val;
	PyObject *inclass = NULL;
	PyObject *initial_tb = NULL;

	if (type == NULL) {
		/* There was no exception, so nothing to do. */
		return;
	}

	/* If PyErr_SetNone() was used, the value will have been actually
	   set to NULL.
	*/
	if (!value) {
		value = Py_None;
		Py_INCREF(value);
	}

	if (PyInstance_Check(value))
		inclass = (PyObject*)((PyInstanceObject*)value)->in_class;

	/* Normalize the exception so that if the type is a class, the
	   value will be an instance.
	*/
	if (PyClass_Check(type)) {
		/* if the value was not an instance, or is not an instance
		   whose class is (or is derived from) type, then use the
		   value as an argument to instantiation of the type
		   class.
		*/
		if (!inclass || !PyClass_IsSubclass(inclass, type)) {
			PyObject *args, *res;

			if (value == Py_None)
				args = Py_BuildValue("()");
			else if (PyTuple_Check(value)) {
				Py_INCREF(value);
				args = value;
			}
			else
				args = Py_BuildValue("(O)", value);

			if (args == NULL)
				goto finally;
			res = PyEval_CallObject(type, args);
			Py_DECREF(args);
			if (res == NULL)
				goto finally;
			Py_DECREF(value);
			value = res;
		}
		/* if the class of the instance doesn't exactly match the
		   class of the type, believe the instance
		*/
		else if (inclass != type) {
 			Py_DECREF(type);
			type = inclass;
			Py_INCREF(type);
		}
	}
	*exc = type;
	*val = value;
	return;
finally:
	Py_DECREF(type);
	Py_DECREF(value);
	/* If the new exception doesn't set a traceback and the old
	   exception had a traceback, use the old traceback for the
	   new exception.  It's better than nothing.
	*/
	initial_tb = *tb;
	PyErr_Fetch(exc, val, tb);
	if (initial_tb != NULL) {
		if (*tb == NULL)
			*tb = initial_tb;
		else
			Py_DECREF(initial_tb);
	}
	/* normalize recursively */
	PyErr_NormalizeException(exc, val, tb);
}
Ejemplo n.º 5
0
static PyObject *
gen_throw(PyGenObject *gen, PyObject *args)
{
    PyObject *typ;
    PyObject *tb = NULL;
    PyObject *val = NULL;
    PyObject *yf = _PyGen_yf(gen);
    _Py_IDENTIFIER(throw);

    if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
        return NULL;

    if (yf) {
        PyObject *ret;
        int err;
        if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
            gen->gi_running = 1;
            err = gen_close_iter(yf);
            gen->gi_running = 0;
            Py_DECREF(yf);
            if (err < 0)
                return gen_send_ex(gen, Py_None, 1, 0);
            goto throw_here;
        }
        if (PyGen_CheckExact(yf)) {
            gen->gi_running = 1;
            ret = gen_throw((PyGenObject *)yf, args);
            gen->gi_running = 0;
        } else {
            PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
            if (meth == NULL) {
                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
                    Py_DECREF(yf);
                    return NULL;
                }
                PyErr_Clear();
                Py_DECREF(yf);
                goto throw_here;
            }
            gen->gi_running = 1;
            ret = PyObject_CallObject(meth, args);
            gen->gi_running = 0;
            Py_DECREF(meth);
        }
        Py_DECREF(yf);
        if (!ret) {
            PyObject *val;
            /* Pop subiterator from stack */
            ret = *(--gen->gi_frame->f_stacktop);
            assert(ret == yf);
            Py_DECREF(ret);
            /* Termination repetition of YIELD_FROM */
            gen->gi_frame->f_lasti += 2;
            if (_PyGen_FetchStopIterationValue(&val) == 0) {
                ret = gen_send_ex(gen, val, 0, 0);
                Py_DECREF(val);
            } else {
                ret = gen_send_ex(gen, Py_None, 1, 0);
            }
        }
        return ret;
    }

throw_here:
    /* First, check the traceback argument, replacing None with
       NULL. */
    if (tb == Py_None) {
        tb = NULL;
    }
    else if (tb != NULL && !PyTraceBack_Check(tb)) {
        PyErr_SetString(PyExc_TypeError,
            "throw() third argument must be a traceback object");
        return NULL;
    }

    Py_INCREF(typ);
    Py_XINCREF(val);
    Py_XINCREF(tb);

    if (PyExceptionClass_Check(typ))
        PyErr_NormalizeException(&typ, &val, &tb);

    else if (PyExceptionInstance_Check(typ)) {
        /* Raising an instance.  The value should be a dummy. */
        if (val && val != Py_None) {
            PyErr_SetString(PyExc_TypeError,
              "instance exception may not have a separate value");
            goto failed_throw;
        }
        else {
            /* Normalize to raise <class>, <instance> */
            Py_XDECREF(val);
            val = typ;
            typ = PyExceptionInstance_Class(typ);
            Py_INCREF(typ);

            if (tb == NULL)
                /* Returns NULL if there's no traceback */
                tb = PyException_GetTraceback(val);
        }
    }
    else {
        /* Not something you can raise.  throw() fails. */
        PyErr_Format(PyExc_TypeError,
                     "exceptions must be classes or instances "
                     "deriving from BaseException, not %s",
                     Py_TYPE(typ)->tp_name);
            goto failed_throw;
    }

    PyErr_Restore(typ, val, tb);
    return gen_send_ex(gen, Py_None, 1, 0);

failed_throw:
    /* Didn't use our arguments, so restore their original refcounts */
    Py_DECREF(typ);
    Py_XDECREF(val);
    Py_XDECREF(tb);
    return NULL;
}
Ejemplo n.º 6
0
void python_handle_exception(const char *fmt, ...)
{
    PyObject *pResult;
    const char *msg;
    char *buf;
    size_t buflen, msglen;
    PyObject *exception, *v, *tb, *args;
    PyObject *line;
    int i;
    char *srcbuf;

    // We don't want to generate traceback when no errors occured
    if (!PyErr_Occurred())
	return;

    if (fmt == NULL)
	srcbuf = NULL;
    else
	srcbuf = make_message(fmt);

    PyErr_Fetch(&exception, &v, &tb);
    PyErr_Clear();
    if (exception == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyErr_Fetch() has failed.\n");
        return;
    }

    PyErr_NormalizeException(&exception, &v, &tb);
    if (exception == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyErr_NormalizeException() has failed.\n");
        return;
    }

    args = PyTuple_Pack(3, exception, v, tb ? tb : Py_None);
    Py_XDECREF(exception);
    Py_XDECREF(v);
    Py_XDECREF(tb);
    if (args == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyTuple_Pack() has failed.\n");
        return;
    }

    pResult = PyObject_CallObject(format_exc_obj, args);
    Py_DECREF(args);
    if (pResult == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, traceback.format_exception() has failed.\n");
        return;
    }

    buflen = 1;
    buf = (char *)pkg_realloc(NULL, buflen * sizeof(char *));
    if (!buf)
    {
	LM_ERR("python_handle_exception(): Can't allocate memory (%lu bytes), pkg_realloc() has failed. Not enough memory.\n", buflen * sizeof(char *));
	return;
    }
    memset(buf, 0, sizeof(char *));

    for (i = 0; i < PySequence_Size(pResult); i++) {
        line = PySequence_GetItem(pResult, i);
        if (line == NULL) {
            LM_ERR("python_handle_exception(): Can't get traceback, PySequence_GetItem() has failed.\n");
            Py_DECREF(pResult);
	    if (buf)
		pkg_free(buf);
            return;
        }

        msg = PyString_AsString(line);

        if (msg == NULL) {
            LM_ERR("python_handle_exception(): Can't get traceback, PyString_AsString() has failed.\n");
            Py_DECREF(line);
            Py_DECREF(pResult);
	    if (buf)
		pkg_free(buf);
            return;
        }

	msglen = strlen(msg);
	buflen += ++msglen;

	buf = (char *)pkg_realloc(buf, buflen * sizeof(char *));
	if (!buf)
	{
	    LM_ERR("python_handle_exception(): Can't allocate memory (%li bytes), pkg_realloc() has failed. Not enough memory.\n", buflen * sizeof(char *));
	    Py_DECREF(line);
	    Py_DECREF(pResult);
	    return;
	}

	strncat(buf, msg, msglen >= buflen ? buflen-1 : msglen);

        Py_DECREF(line);
    }

    if (srcbuf == NULL)
	LM_ERR("Unhandled exception in the Python code:\n%s", buf);
    else
	LM_ERR("%s: Unhandled exception in the Python code:\n%s", srcbuf, buf);

    if (buf)
	pkg_free(buf);

    if (srcbuf)
	pkg_free(srcbuf);

    Py_DECREF(pResult);
}
Ejemplo n.º 7
0
static PyObject *
green_throw(PyGreenlet *self, PyObject *args)
{
	PyObject *typ = PyExc_GreenletExit;
	PyObject *val = NULL;
	PyObject *tb = NULL;

	if (!PyArg_ParseTuple(args, "|OOO:throw", &typ, &val, &tb))
	{
		return NULL;
	}

	/* First, check the traceback argument, replacing None, with NULL */
	if (tb == Py_None)
	{
		tb = NULL;
	}
	else if (tb != NULL && !PyTraceBack_Check(tb))
	{
		PyErr_SetString(
			PyExc_TypeError,
			"throw() third argument must be a traceback object");
		return NULL;
	}

	Py_INCREF(typ);
	Py_XINCREF(val);
	Py_XINCREF(tb);

	if (PyExceptionClass_Check(typ))
	{
		PyErr_NormalizeException(&typ, &val, &tb);
	}
	else if (PyExceptionInstance_Check(typ))
	{
		/* Raising an instance. The value should be a dummy. */
		if (val && val != Py_None)
		{
			PyErr_SetString(
				PyExc_TypeError,
				"instance exception may not have a separate value");
			goto failed_throw;
		}
		else
		{
			/* Normalize to raise <class>, <instance> */
			Py_XDECREF(val);
			val = typ;
			typ = PyExceptionInstance_Class(typ);
			Py_INCREF(typ);
		}
	}
	else
	{
		/* Not something you can raise. throw() fails. */
		PyErr_Format(
			PyExc_TypeError,
			"exceptions must be classes, or instances, not %s",
			Py_TYPE(typ)->tp_name);
		goto failed_throw;
	}

	return throw_greenlet(self, typ, val, tb);

failed_throw:
	/* Didn't use our arguments, so restore their original refcounts */
	Py_DECREF(typ);
	Py_XDECREF(val);
	Py_XDECREF(tb);
	return NULL;
}
Ejemplo n.º 8
0
QString
QPythonPriv::formatExc()
{
    PyObject *type = NULL;
    PyObject *value = NULL;
    PyObject *traceback = NULL;

    PyObject *list = NULL;
    PyObject *n = NULL;
    PyObject *s = NULL;

    PyErr_Fetch(&type, &value, &traceback);
    PyErr_NormalizeException(&type, &value, &traceback);

    QString message;
    QVariant v;

    if (type == NULL && value == NULL && traceback == NULL) {
        // No exception thrown?
        goto cleanup;
    }

    if (value != NULL) {
        // We can at least format the exception as string
        message = convertPyObjectToQVariant(PyObject_Str(value)).toString();
    }

    if (type == NULL || traceback == NULL) {
        // Cannot get a traceback for this exception
        goto cleanup;
    }

    list = PyObject_CallMethod(traceback_mod,
            "format_exception", "OOO", type, value, traceback);

    if (list == NULL) {
        // Could not format exception, fall back to original message
        PyErr_Print();
        goto cleanup;
    }

    n = PyUnicode_FromString("\n");
    if (n == NULL) {
        PyErr_Print();
        goto cleanup;
    }

    s = PyUnicode_Join(n, list);
    if (s == NULL) {
        PyErr_Print();
        goto cleanup;
    }

    v = convertPyObjectToQVariant(s);
    if (v.isValid()) {
        message = v.toString();
    }

cleanup:
    Py_XDECREF(s);
    Py_XDECREF(n);
    Py_XDECREF(list);

    Py_XDECREF(type);
    Py_XDECREF(value);
    Py_XDECREF(traceback);

    qDebug() << QString("PyOtherSide error: %1").arg(message);
    return message;
}
Ejemplo n.º 9
0
PyObject* NS(ErrorSet)(
  PyObject  *self
)
{
  SETUP_context
  PyObject *typeO = NULL, *valueO=NULL, *tbO = NULL, *retO = Py_None;

  PyThreadState *tstate = PyThreadState_Get();

  if (tstate->curexc_type == NULL || tstate->curexc_type == Py_None) {
    typeO = tstate->exc_type;
    valueO = tstate->exc_value;
    tbO = tstate->exc_traceback;
  } else {
    typeO = tstate->curexc_type;
    valueO = tstate->curexc_value;
    tbO = tstate->curexc_traceback;
  }
  Py_XINCREF(typeO);
  Py_XINCREF(valueO);
  Py_XINCREF(tbO);
  PyErr_Clear();

  {
    PyObject *valO = NULL ;

    if (typeO == Py_None || typeO == NULL) {
      MqErrorC (context, __func__, -1, "No active exception to reraise");

    } else if (PyErr_GivenExceptionMatches(typeO,NS(MqSException))) {

      MqErrorSet (context, 
	(MQ_INT) PyLong_AsLong(PyObject_GetAttrString(typeO,"num")),
	(enum MqErrorE) PyLong_AsLong(PyObject_GetAttrString(typeO,"code")),
	(MQ_CST const) PyBytes_AsString(PyUnicode_AsUTF8String(PyObject_GetAttrString(typeO,"text"))),
	NULL
      );

    } else if (valueO) {
      PyObject *tmod = NULL, *strO = NULL, *lstO = NULL;
      PyErrorCheckNT(end1,  tmod = PyImport_ImportModule("traceback"));
      if (tbO) {
	PyErr_NormalizeException(&typeO, &valueO, &tbO);
	PyErrorCheckNT(end1,  lstO = PyObject_CallMethod(tmod, "format_exception", "OOO", typeO, valueO, tbO));
      } else {
	PyErrorCheckNT(end1,  lstO = PyObject_CallMethod(tmod, "format_exception_only", "OO", typeO, valueO));
      }
      PyErrorCheckNT(end1,  strO = PyC2O(""));
      PyErrorCheckNT(end1,  valO = PyObject_CallMethod(strO, "join", "O", lstO));
end1:
      Py_XDECREF(tmod);
      Py_XDECREF(lstO);
      Py_XDECREF(strO);
      if (valO != NULL) {
	PyObject *strO=NULL, *utf8=NULL;

	PyErrorCheckNT(end2, strO = PyObject_Str(valO));
	PyErrorCheckNT(end2, utf8 = PyUnicode_AsUTF8String(strO));
	MqErrorC(context, __func__, -1, PyBytes_AsString(utf8));
end2:
	Py_XDECREF(utf8);
	Py_XDECREF(strO);
      }
      if (MqErrorGetCodeI(context) != MQ_ERROR)
	MqErrorV(context, __func__, -1, "%s: python error", PyExceptionClass_Name(typeO));
    }
  }

  Py_XDECREF(typeO);
  Py_XDECREF(valueO);
  Py_XDECREF(tbO);
  Py_XINCREF(retO);

  return retO;
}
Ejemplo n.º 10
0
static PyObject *cdefer_Deferred__runCallbacks(cdefer_Deferred *self) {
    PyObject *cb;
    PyObject *item;
    PyObject *callbacktuple;
    PyObject *callback;
    PyObject *args;
    PyObject *newArgs;
    PyObject *newArgs2;
    PyObject *kwargs;
    PyObject *_continue;
    PyObject *type, *value, *traceback;
    PyObject *tmp;
    PyObject *result;
    int size;
    int offset;
    const char *callback_name;

    if (self->running_callbacks) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (!self->paused) {
        cb = self->callbacks;

        if (!PyList_Check(cb)) {
            PyErr_SetString(PyExc_TypeError, "callbacks must be a list");
            return NULL;
        }

        for (;;) {
            size = PyList_GET_SIZE(cb);
            if (size == -1) {
                return NULL;
            }
            if (self->callback_index >= size) {
                break;
            }

            item = PyList_GET_ITEM(cb, self->callback_index);
            if (!item) {
                return NULL;
            }
            if (cdefer_Deferred__verify_callbacks_item(item)) {
                return NULL;
            }

            if (PyObject_IsInstance(self->result, failure_class)) {
                offset = 1;
                callback_name = "errback";
            } else {
                offset = 0;
                callback_name = "callback";
            }

            callbacktuple = PyTuple_GET_ITEM(item, offset);
            if (!callbacktuple) {
                return NULL;
            }

            if (cdefer_Deferred__verify_callback_entry(callback_name, callbacktuple)) {
                return NULL;
            }

            callback = PyTuple_GET_ITEM(callbacktuple, 0);
            if(!callback) {
                return NULL;
            }

            if (callback == Py_None) {
                ++self->callback_index;
                continue;
            }

            args = PyTuple_GET_ITEM(callbacktuple, 1);
            if (!args) {
                return NULL;
            }

            kwargs = PyTuple_GET_ITEM(callbacktuple, 2);
            if (!kwargs) {
                return NULL;
            }

            newArgs = Py_BuildValue("(O)", self->result);
            if (!newArgs) {
                return NULL;
            }

            if (args != Py_None) {
                newArgs2 = PySequence_InPlaceConcat(newArgs, args);
                Py_CLEAR(newArgs);
                if (!newArgs2) {
                    return NULL;
                }
            } else {
                newArgs2 = newArgs;
                newArgs = NULL;
            }

            ++self->callback_index;
            if (kwargs == Py_None) {
                kwargs = NULL;
            }
            self->running_callbacks = 1;
            tmp = PyObject_Call(callback, newArgs2, kwargs);
            self->running_callbacks = 0;
            Py_DECREF(self->result);
            self->result = tmp;

            Py_CLEAR(newArgs2);

            if (!self->result) {
                PyErr_Fetch(&type, &value, &traceback);
                PyErr_NormalizeException(&type, &value, &traceback);
                if (!traceback) {
                    traceback = Py_None;
                    Py_INCREF(traceback);
                }

                self->result = PyObject_CallFunction(failure_class, "OOO", value, type, traceback);
                if (!self->result) {
                    PyErr_Restore(type, value, traceback);
                    return NULL;
                }
                Py_DECREF(type);
                Py_DECREF(value);
                Py_DECREF(traceback);
                continue;
            }
            if (PyObject_TypeCheck(self->result, &cdefer_DeferredType)) {
                PyObject *self_result;

                if (PyList_SetSlice(cb, 0, self->callback_index, NULL) == -1) {
                    return NULL;
                }
                self->callback_index = 0;

                result = PyObject_CallMethod((PyObject *)self, "pause", NULL);
                if (!result) {
                    return NULL;
                }
                Py_DECREF(result);

                _continue = PyObject_GetAttrString((PyObject *)self,
                                                   "_continue");
                if (!_continue) {
                    return NULL;
                }

                self_result = self->result;
                Py_INCREF(self_result);
                result = cdefer_Deferred__addCallbacks(
                    (cdefer_Deferred *)self->result, _continue,
                    _continue, Py_None, Py_None, Py_None, Py_None);
                Py_DECREF(self_result);
                /* The reference was either copied/incref'd or not
                 * (when errored) in addCallbacks, either way, we own
                 * one too, and don't need it anymore. */
                Py_DECREF(_continue);

                if (!result) {
                    return NULL;
                }
                Py_DECREF(result);

                goto endLabel;
            }
        }
        if (PyList_SetSlice(cb, 0, PyList_GET_SIZE(cb), NULL) == -1) {
            return NULL;
        }
        self->callback_index = 0;
    }
endLabel:
    if (PyObject_IsInstance(self->result, failure_class)) {
        result = PyObject_CallMethod((PyObject *)self->result,
                                     "cleanFailure", NULL);
        if (!result) {
            return NULL;
        }
        Py_DECREF(result);
        if (cdefer_Deferred__set_debuginfo_fail_result(self) == -1) {
            return NULL;
        }
    } else {
        if (cdefer_Deferred__clear_debuginfo(self) == -1) {
            return NULL;
        }
    }
    Py_INCREF(Py_None);
    return Py_None;
}
Ejemplo n.º 11
0
void
PyErr_PrintEx(int set_sys_last_vars)
{
    PyObject *exception, *v, *tb, *hook;

    if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
        handle_system_exit();
    }
    PyErr_Fetch(&exception, &v, &tb);
    if (exception == NULL)
        return;
    PyErr_NormalizeException(&exception, &v, &tb);
    if (tb == NULL) {
        tb = Py_None;
        Py_INCREF(tb);
    }
    PyException_SetTraceback(v, tb);
    if (exception == NULL)
        return;
    /* Now we know v != NULL too */
    if (set_sys_last_vars) {
        if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
            PyErr_Clear();
        }
        if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
            PyErr_Clear();
        }
        if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
            PyErr_Clear();
        }
    }
    hook = _PySys_GetObjectId(&PyId_excepthook);
    if (hook) {
        PyObject* stack[3];
        PyObject *result;

        stack[0] = exception;
        stack[1] = v;
        stack[2] = tb;
        result = _PyObject_FastCall(hook, stack, 3);
        if (result == NULL) {
            PyObject *exception2, *v2, *tb2;
            if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
                handle_system_exit();
            }
            PyErr_Fetch(&exception2, &v2, &tb2);
            PyErr_NormalizeException(&exception2, &v2, &tb2);
            /* It should not be possible for exception2 or v2
               to be NULL. However PyErr_Display() can't
               tolerate NULLs, so just be safe. */
            if (exception2 == NULL) {
                exception2 = Py_None;
                Py_INCREF(exception2);
            }
            if (v2 == NULL) {
                v2 = Py_None;
                Py_INCREF(v2);
            }
            fflush(stdout);
            PySys_WriteStderr("Error in sys.excepthook:\n");
            PyErr_Display(exception2, v2, tb2);
            PySys_WriteStderr("\nOriginal exception was:\n");
            PyErr_Display(exception, v, tb);
            Py_DECREF(exception2);
            Py_DECREF(v2);
            Py_XDECREF(tb2);
        }
        Py_XDECREF(result);
    } else {
        PySys_WriteStderr("sys.excepthook is missing\n");
        PyErr_Display(exception, v, tb);
    }
    Py_XDECREF(exception);
    Py_XDECREF(v);
    Py_XDECREF(tb);
}
Ejemplo n.º 12
0
static int _cffi_initialize_python(void)
{
    /* This initializes Python, imports _cffi_backend, and then the
       present .dll/.so is set up as a CPython C extension module.
    */
    int result;
    PyGILState_STATE state;
    PyObject *pycode=NULL, *global_dict=NULL, *x;

#if PY_MAJOR_VERSION >= 3
    /* see comments in _cffi_carefully_make_gil() about the
       Python2/Python3 difference 
    */
#else
    /* Acquire the GIL.  We have no threadstate here.  If Python is 
       already initialized, it is possible that there is already one
       existing for this thread, but it is not made current now.
    */
    PyEval_AcquireLock();

    _cffi_py_initialize();

    /* The Py_InitializeEx() sometimes made a threadstate for us, but
       not always.  Indeed Py_InitializeEx() could be called and do
       nothing.  So do we have a threadstate, or not?  We don't know,
       but we can replace it with NULL in all cases.
    */
    (void)PyThreadState_Swap(NULL);

    /* Now we can release the GIL and re-acquire immediately using the
       logic of PyGILState(), which handles making or installing the
       correct threadstate.
    */
    PyEval_ReleaseLock();
#endif
    state = PyGILState_Ensure();

    /* Call the initxxx() function from the present module.  It will
       create and initialize us as a CPython extension module, instead
       of letting the startup Python code do it---it might reimport
       the same .dll/.so and get maybe confused on some platforms.
       It might also have troubles locating the .dll/.so again for all
       I know.
    */
    (void)_CFFI_PYTHON_STARTUP_FUNC();
    if (PyErr_Occurred())
        goto error;

    /* Now run the Python code provided to ffi.embedding_init_code().
     */
    pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE,
                              "<init code for '" _CFFI_MODULE_NAME "'>",
                              Py_file_input);
    if (pycode == NULL)
        goto error;
    global_dict = PyDict_New();
    if (global_dict == NULL)
        goto error;
    if (PyDict_SetItemString(global_dict, "__builtins__",
                             PyThreadState_GET()->interp->builtins) < 0)
        goto error;
    x = PyEval_EvalCode(
#if PY_MAJOR_VERSION < 3
                        (PyCodeObject *)
#endif
                        pycode, global_dict, global_dict);
    if (x == NULL)
        goto error;
    Py_DECREF(x);

    /* Done!  Now if we've been called from
       _cffi_start_and_call_python() in an ``extern "Python"``, we can
       only hope that the Python code did correctly set up the
       corresponding @ffi.def_extern() function.  Otherwise, the
       general logic of ``extern "Python"`` functions (inside the
       _cffi_backend module) will find that the reference is still
       missing and print an error.
     */
    result = 0;
 done:
    Py_XDECREF(pycode);
    Py_XDECREF(global_dict);
    PyGILState_Release(state);
    return result;

 error:;
    {
        /* Print as much information as potentially useful.
           Debugging load-time failures with embedding is not fun
        */
        PyObject *exception, *v, *tb, *f, *modules, *mod;
        PyErr_Fetch(&exception, &v, &tb);
        if (exception != NULL) {
            PyErr_NormalizeException(&exception, &v, &tb);
            PyErr_Display(exception, v, tb);
        }
        Py_XDECREF(exception);
        Py_XDECREF(v);
        Py_XDECREF(tb);

        f = PySys_GetObject((char *)"stderr");
        if (f != NULL && f != Py_None) {
            PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
                               "\ncompiled with cffi version: 1.5.1"
                               "\n_cffi_backend module: ", f);
            modules = PyImport_GetModuleDict();
            mod = PyDict_GetItemString(modules, "_cffi_backend");
            if (mod == NULL) {
                PyFile_WriteString("not loaded", f);
            }
            else {
                v = PyObject_GetAttrString(mod, "__file__");
                PyFile_WriteObject(v, f, 0);
                Py_XDECREF(v);
            }
            PyFile_WriteString("\nsys.path: ", f);
            PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0);
            PyFile_WriteString("\n\n", f);
        }
    }
    result = -1;
    goto done;
}
Ejemplo n.º 13
0
std::string getPythonTraceback()
{

    // get exception info
    PyObject *type, *value, *traceback;
    PyErr_Fetch(&type, &value, &traceback);
    PyErr_NormalizeException(&type, &value, &traceback);

    std::ostringstream mssg;
    if (traceback)
    {

        PyObject* tracebackModule;
        PyObject* tracebackDictionary;
        PyObject* tracebackFunction;
    
        tracebackModule = PyImport_ImportModule("traceback");
        if (!tracebackModule)
        {
            throw python_error("unable to load traceback module while importing numpy inside PDAL");
        }

        tracebackDictionary = PyModule_GetDict(tracebackModule);

        tracebackFunction = PyDict_GetItemString(tracebackDictionary, "format_exception");
        if (!tracebackFunction)
        {
            throw python_error("unable to find traceback function while importing numpy inside PDAL");
        }

        if (!PyCallable_Check(tracebackFunction))
        {
            throw python_error("invalid traceback function while importing numpy inside PDAL");
        }

        
        // create an argument for "format exception"
        PyObject* args = PyTuple_New(3);
        PyTuple_SetItem(args, 0, type);
        PyTuple_SetItem(args, 1, value);
        PyTuple_SetItem(args, 2, traceback);

        // get a list of string describing what went wrong
        PyObject* output = PyObject_CallObject(tracebackFunction, args);

        // print error message
        int i, n = PyList_Size(output);

#if PY_MAJOR_VERSION >= 3
        for (i=0; i<n; i++) 
        {
            PyObject* u = PyUnicode_AsUTF8String(PyList_GetItem(output, i));
            const char* p = PyBytes_AsString(u);
            
            mssg << p;
        }
        
#else
        for (i=0; i<n; i++) mssg << PyString_AsString(PyList_GetItem(output, i));
#endif
        
        // clean up
        Py_XDECREF(args);
        Py_XDECREF(output);
    }
    else if (value != NULL)
    {
        PyObject *s = PyObject_Str(value);
#if PY_MAJOR_VERSION >= 3
        // const char* text = PyUnicode_AS_DATA(s);
        PyObject* u = PyUnicode_AsUTF8String(s);
        const char* text = PyBytes_AsString(u);        
#else
        const char* text = PyString_AS_STRING(s);
#endif
        Py_DECREF(s);
        mssg << text;
    }
    else
    {
        mssg << "unknown error that we are unable to get a traceback for. Was it already printed/taken?";
    }

    Py_XDECREF(value);
    Py_XDECREF(type);
    Py_XDECREF(traceback);

    return mssg.str();
}
Ejemplo n.º 14
0
/*
 * Emit a PG error or notice, together with any available info about
 * the current Python error, previously set by PLy_exception_set().
 * This should be used to propagate Python errors into PG.  If fmt is
 * NULL, the Python error becomes the primary error message, otherwise
 * it becomes the detail.  If there is a Python traceback, it is put
 * in the context.
 */
void
PLy_elog(int elevel, const char *fmt,...)
{
	char	   *xmsg;
	char	   *tbmsg;
	int			tb_depth;
	StringInfoData emsg;
	PyObject   *exc,
			   *val,
			   *tb;
	const char *primary = NULL;
	int			sqlerrcode = 0;
	char	   *detail = NULL;
	char	   *hint = NULL;
	char	   *query = NULL;
	int			position = 0;

	PyErr_Fetch(&exc, &val, &tb);

	if (exc != NULL)
	{
		PyErr_NormalizeException(&exc, &val, &tb);

		if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
			PLy_get_spi_error_data(val, &sqlerrcode, &detail, &hint, &query, &position);
		else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
			elevel = FATAL;
	}

	/* this releases our refcount on tb! */
	PLy_traceback(exc, val, tb,
				  &xmsg, &tbmsg, &tb_depth);

	if (fmt)
	{
		initStringInfo(&emsg);
		for (;;)
		{
			va_list		ap;
			int			needed;

			va_start(ap, fmt);
			needed = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap);
			va_end(ap);
			if (needed == 0)
				break;
			enlargeStringInfo(&emsg, needed);
		}
		primary = emsg.data;

		/* Since we have a format string, we cannot have a SPI detail. */
		Assert(detail == NULL);

		/* If there's an exception message, it goes in the detail. */
		if (xmsg)
			detail = xmsg;
	}
	else
	{
		if (xmsg)
			primary = xmsg;
	}

	PG_TRY();
	{
		ereport(elevel,
				(errcode(sqlerrcode ? sqlerrcode : ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
			  errmsg_internal("%s", primary ? primary : "no exception data"),
				 (detail) ? errdetail_internal("%s", detail) : 0,
				 (tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
				 (hint) ? errhint("%s", hint) : 0,
				 (query) ? internalerrquery(query) : 0,
				 (position) ? internalerrposition(position) : 0));
	}
	PG_CATCH();
	{
		if (fmt)
			pfree(emsg.data);
		if (xmsg)
			pfree(xmsg);
		if (tbmsg)
			pfree(tbmsg);
		Py_XDECREF(exc);
		Py_XDECREF(val);

		PG_RE_THROW();
	}
	PG_END_TRY();

	if (fmt)
		pfree(emsg.data);
	if (xmsg)
		pfree(xmsg);
	if (tbmsg)
		pfree(tbmsg);
	Py_XDECREF(exc);
	Py_XDECREF(val);
}
Ejemplo n.º 15
0
int py_plugin_open(struct plugin *plugin, char *dir)
{
	PyObject *handle, *info;
	PyObject *PyStr;
	PyObject *PyErrType, *PyErr, *PyTraceback;

	if (!(PyStr = PyString_FromString(dir))) {
		PyErr_Print();
		return -1;
	}

	if (PyList_Insert(PyPath, 0, PyStr)) {
		Py_DECREF(PyStr);
		return -1;
	}

	if (!(handle = PyImport_ImportModule(plugin->name))) {
		/* ignore "module not found" errors in top level module */
		PyErr_Fetch(&PyErrType, &PyErr, &PyTraceback);
		PyErr_NormalizeException(&PyErrType, &PyErr, &PyTraceback);
		if (PyErr_GivenExceptionMatches(PyErr, PyExc_ImportError) &&
		  !PyTraceback) {
			Py_XDECREF(PyErrType);
			Py_XDECREF(PyErr);
		}
		else {
			PyErr_Restore(PyErrType, PyErr, PyTraceback);
			PyErr_Print();
		}

		if (PySequence_DelItem(PyPath, 0)) {
			PyErr_Print();
		}
		Py_DECREF(PyStr);
		return -1;
	}

	if (PySequence_DelItem(PyPath, 0)) {
		PyErr_Print();
	}
	Py_DECREF(PyStr);

	if (!(plugin->p = malloc(sizeof(struct py_plugin)))) {
		wminput_err("Error allocating py_plugin");
		return -1;
	}

	plugin->type = PLUGIN_PYTHON;
	plugin->info = NULL;
	plugin->data = NULL;
	((struct py_plugin *) plugin->p)->init = NULL;
	((struct py_plugin *) plugin->p)->exec = NULL;

	if (!(plugin->info = malloc(sizeof *plugin->info))) {
		wminput_err("Error allocating plugin info");
		goto ERR_HND;
	}
	if (!(plugin->data = malloc(sizeof *plugin->data))) {
		wminput_err("Error allocating plugin data");
		goto ERR_HND;
	}
	if (!(((struct py_plugin *)plugin->p)->init =
	  PyObject_GetAttrString(handle, "wmplugin_init"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(((struct py_plugin *)plugin->p)->init)) {
		wminput_err("Unable to load plugin init function: not callable");
		goto ERR_HND;
	}
	if (!(((struct py_plugin *)plugin->p)->exec =
	  PyObject_GetAttrString(handle, "wmplugin_exec"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(((struct py_plugin *)plugin->p)->exec)) {
		wminput_err("Unable to load plugin exec function: not callable");
		goto ERR_HND;
	}
	if (!(info = PyObject_GetAttrString(handle, "wmplugin_info"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(info)) {
		wminput_err("Unable to load plugin info function: not callable");
		Py_DECREF((PyObject *)info);
		goto ERR_HND;
	}
	if (py_plugin_info(plugin, info)) {
		wminput_err("Error on python_info");
		Py_DECREF((PyObject *)info);
		goto ERR_HND;
	}
	Py_DECREF((PyObject *)info);

	((struct py_plugin *) plugin->p)->handle = handle;

	return 0;

ERR_HND:
	if (plugin->info) {
		free(plugin->info);
	}
	if (plugin->data) {
		free(plugin->data);
	}
	if (plugin->p) {
		if (((struct py_plugin *)plugin->p)->init) {
			Py_DECREF(((struct py_plugin *)plugin->p)->init);
		}
		if (((struct py_plugin *)plugin->p)->exec) {
			Py_DECREF(((struct py_plugin *)plugin->p)->exec);
		}
		free(plugin->p);
	}
	Py_DECREF(handle);
	return -1;
}
Ejemplo n.º 16
0
void
PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
{
    PyObject *exc, *v, *tb, *tmp;
    _Py_IDENTIFIER(filename);
    _Py_IDENTIFIER(lineno);
    _Py_IDENTIFIER(msg);
    _Py_IDENTIFIER(offset);
    _Py_IDENTIFIER(print_file_and_line);
    _Py_IDENTIFIER(text);

    /* add attributes for the line number and filename for the error */
    PyErr_Fetch(&exc, &v, &tb);
    PyErr_NormalizeException(&exc, &v, &tb);
    /* XXX check that it is, indeed, a syntax error. It might not
     * be, though. */
    tmp = PyLong_FromLong(lineno);
    if (tmp == NULL)
        PyErr_Clear();
    else {
        if (_PyObject_SetAttrId(v, &PyId_lineno, tmp))
            PyErr_Clear();
        Py_DECREF(tmp);
    }
    if (col_offset >= 0) {
        tmp = PyLong_FromLong(col_offset);
        if (tmp == NULL)
            PyErr_Clear();
        else {
            if (_PyObject_SetAttrId(v, &PyId_offset, tmp))
                PyErr_Clear();
            Py_DECREF(tmp);
        }
    }
    if (filename != NULL) {
        if (_PyObject_SetAttrId(v, &PyId_filename, filename))
            PyErr_Clear();

        tmp = PyErr_ProgramTextObject(filename, lineno);
        if (tmp) {
            if (_PyObject_SetAttrId(v, &PyId_text, tmp))
                PyErr_Clear();
            Py_DECREF(tmp);
        }
    }
    if (_PyObject_SetAttrId(v, &PyId_offset, Py_None)) {
        PyErr_Clear();
    }
    if (exc != PyExc_SyntaxError) {
        if (!_PyObject_HasAttrId(v, &PyId_msg)) {
            tmp = PyObject_Str(v);
            if (tmp) {
                if (_PyObject_SetAttrId(v, &PyId_msg, tmp))
                    PyErr_Clear();
                Py_DECREF(tmp);
            } else {
                PyErr_Clear();
            }
        }
        if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
            if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
                                    Py_None))
                PyErr_Clear();
        }
    }
    PyErr_Restore(exc, v, tb);
}
Ejemplo n.º 17
0
void reportPythonError( QString moduleName )
{
	// Print the Error
	if( PyErr_Occurred() )
	{
		PyObject *exception, *value, *traceback;

		PyErr_Fetch( &exception, &value, &traceback );
		PyErr_NormalizeException( &exception, &value, &traceback );

		// Set sys. variables for exception tracking
		PySys_SetObject( "last_type", exception );
		PySys_SetObject( "last_value", value );
		PySys_SetObject( "last_traceback", traceback );

		PyObject *exceptionName = PyObject_GetAttrString( exception, "__name__" );

		// Do we have a detailed description of the error ?
		PyObject *error = value != 0 ? PyObject_Str( value ) : 0;

		if( !error )
		{
			if( !moduleName.isNull() )
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured while compiling \"%1\": %2" ).arg( moduleName ).arg( PyString_AsString( exceptionName ) ) );
			}
			else
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured: %1" ).arg( PyString_AsString( exceptionName ) ) );
			}
		}
		else
		{
			if( !moduleName.isNull() )
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured in \"%1\": %2" ).arg( moduleName ).arg( PyString_AsString( exceptionName ) ) );
			}
			else
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured: %1" ).arg( PyString_AsString( exceptionName ) ) );
			}

			Console::instance()->log( LOG_PYTHON, QString( "%1: %2" ).arg( PyString_AsString( exceptionName ) ).arg( PyString_AsString( error ) ), false );
			Py_XDECREF( error );
		}

		// Don't print a traceback for syntax errors
		if( PyErr_GivenExceptionMatches( exception, PyExc_SyntaxError ) )
		{
			Py_XDECREF( traceback );
			traceback = 0;
		}

		// Dump a traceback
		while( traceback )
		{
			if( !PyObject_HasAttrString( traceback, "tb_frame" ) )
				break;

			PyObject *frame = PyObject_GetAttrString( traceback, "tb_frame" );

			if( !PyObject_HasAttrString( frame, "f_code" ) )
			{
				Py_XDECREF( frame );
				break;
			}

			PyObject *code = PyObject_GetAttrString( frame, "f_code" );

			if( !PyObject_HasAttrString( code, "co_filename" ) || !PyObject_HasAttrString( code, "co_name" ) )
			{
				Py_XDECREF( frame );
				Py_XDECREF( code );
				break;
			}

			PyObject *pyFilename = PyObject_GetAttrString( code, "co_filename" );
			PyObject *pyFunction = PyObject_GetAttrString( code, "co_name" );

			QString filename = PyString_AsString( pyFilename );
			QString function = PyString_AsString( pyFunction );

			Py_XDECREF( pyFilename );
			Py_XDECREF( pyFunction );

			Py_XDECREF( code );
			Py_XDECREF( frame );

			PyObject *pyLine = PyObject_GetAttrString( traceback, "tb_lineno" );
			unsigned int line = PyInt_AsLong( pyLine );
			Py_XDECREF( pyLine );

			// Print it 
			Console::instance()->log( LOG_PYTHON, QString( "File '%1',%2 in '%3'" ).arg( filename ).arg( line ).arg( function ), false );

			// Switch Frames
			PyObject *newtb = PyObject_GetAttrString( traceback, "tb_next" );
			Py_XDECREF( traceback );
			traceback = newtb;
		}

		Py_XDECREF( exceptionName );
		Py_XDECREF( exception );
		Py_XDECREF( value );
		Py_XDECREF( traceback );
	}
}
Ejemplo n.º 18
0
/* Used in many places to normalize a raised exception, including in
   eval_code2(), do_raise(), and PyErr_Print()

   XXX: should PyErr_NormalizeException() also call
            PyException_SetTraceback() with the resulting value and tb?
*/
void
PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
{
    PyObject *type = *exc;
    PyObject *value = *val;
    PyObject *inclass = NULL;
    PyObject *initial_tb = NULL;
    PyThreadState *tstate = NULL;

    if (type == NULL) {
        /* There was no exception, so nothing to do. */
        return;
    }

    /* If PyErr_SetNone() was used, the value will have been actually
       set to NULL.
    */
    if (!value) {
        value = Py_None;
        Py_INCREF(value);
    }

    if (PyExceptionInstance_Check(value))
        inclass = PyExceptionInstance_Class(value);

    /* Normalize the exception so that if the type is a class, the
       value will be an instance.
    */
    if (PyExceptionClass_Check(type)) {
        int is_subclass;
        if (inclass) {
            is_subclass = PyObject_IsSubclass(inclass, type);
            if (is_subclass < 0)
                goto finally;
        }
        else
            is_subclass = 0;

        /* if the value was not an instance, or is not an instance
           whose class is (or is derived from) type, then use the
           value as an argument to instantiation of the type
           class.
        */
        if (!inclass || !is_subclass) {
            PyObject *fixed_value;

            fixed_value = _PyErr_CreateException(type, value);
            if (fixed_value == NULL) {
                goto finally;
            }

            Py_DECREF(value);
            value = fixed_value;
        }
        /* if the class of the instance doesn't exactly match the
           class of the type, believe the instance
        */
        else if (inclass != type) {
            Py_DECREF(type);
            type = inclass;
            Py_INCREF(type);
        }
    }
    *exc = type;
    *val = value;
    return;
finally:
    Py_DECREF(type);
    Py_DECREF(value);
    /* If the new exception doesn't set a traceback and the old
       exception had a traceback, use the old traceback for the
       new exception.  It's better than nothing.
    */
    initial_tb = *tb;
    PyErr_Fetch(exc, val, tb);
    if (initial_tb != NULL) {
        if (*tb == NULL)
            *tb = initial_tb;
        else
            Py_DECREF(initial_tb);
    }
    /* normalize recursively */
    tstate = PyThreadState_GET();
    if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
        --tstate->recursion_depth;
        /* throw away the old exception and use the recursion error instead */
        Py_INCREF(PyExc_RecursionError);
        Py_SETREF(*exc, PyExc_RecursionError);
        Py_INCREF(PyExc_RecursionErrorInst);
        Py_SETREF(*val, PyExc_RecursionErrorInst);
        /* just keeping the old traceback */
        return;
    }
    PyErr_NormalizeException(exc, val, tb);
    --tstate->recursion_depth;
}
Ejemplo n.º 19
0
static PyObject *
Fiber_func_throw(Fiber *self, PyObject *args)
{
    Fiber *current;
    PyObject *typ, *val, *tb;

    val = tb = NULL;

    if (!PyArg_ParseTuple(args, "O|OO:throw", &typ, &val, &tb)) {
	return NULL;
    }

    /* First, check the traceback argument, replacing None, with NULL */
    if (tb == Py_None) {
        tb = NULL;
    } else if (tb != NULL && !PyTraceBack_Check(tb)) {
	PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback object");
	return NULL;
    }

    Py_INCREF(typ);
    Py_XINCREF(val);
    Py_XINCREF(tb);

    if (PyExceptionClass_Check(typ)) {
        PyErr_NormalizeException(&typ, &val, &tb);
    } else if (PyExceptionInstance_Check(typ)) {
        /* Raising an instance. The value should be a dummy. */
        if (val && val != Py_None) {
	    PyErr_SetString(PyExc_TypeError, "instance exceptions cannot have a separate value");
	    goto error;
	} else {
	    /* Normalize to raise <class>, <instance> */
	    Py_XDECREF(val);
            val = typ;
            typ = PyExceptionInstance_Class(typ);
	    Py_INCREF(typ);
	}
    } else {
	/* Not something you can raise. throw() fails. */
        PyErr_Format(PyExc_TypeError, "exceptions must be classes, or instances, not %s", Py_TYPE(typ)->tp_name);
	goto error;
    }

    if (!(current = get_current())) {
        goto error;
    }

    if (self == current) {
        PyErr_SetString(PyExc_FiberError, "cannot throw from a Fiber to itself");
        goto error;
    }

    if (self->stacklet_h == EMPTY_STACKLET_HANDLE) {
        PyErr_SetString(PyExc_FiberError, "Fiber has ended");
        goto error;
    }

    if (self->thread_h != current->thread_h) {
        PyErr_SetString(PyExc_FiberError, "cannot switch to a Fiber on a different thread");
        return NULL;
    }

    /* set error and do a switch with NULL as the value */
    PyErr_Restore(typ, val, tb);

    return do_switch(self, NULL);

error:
    /* Didn't use our arguments, so restore their original refcounts */
    Py_DECREF(typ);
    Py_XDECREF(val);
    Py_XDECREF(tb);
    return NULL;
}
Ejemplo n.º 20
0
/**
 * This emits the error signal and resets the error state
 * of the python interpreter.
 */
void PythonScript::emit_error() {
  // gil is necessary so other things don't continue
  ScopedPythonGIL lock;

  // return early if nothing happened
  if (!PyErr_Occurred()) {
    emit finished(MSG_FINISHED);
    return;
  }
  // get the error information out
  PyObject *exception(nullptr), *value(nullptr), *traceback(nullptr);
  PyErr_Fetch(&exception, &value, &traceback);

  // special check for system exceptions
  if (bool(exception) &&
      PyErr_GivenExceptionMatches(exception, PyExc_SystemExit) &&
      PyObject_HasAttrString(exception, "code")) {
    // value is the return code handed to sys.exit
    long code = 0;
    if (bool(value) && INT_CHECK(value)) {
      code = TO_LONG(value);
    }

    // if we are returning 0 then cleanup and return
    if (code == 0) {
      // maybe shouldn't clear the error, but for now this
      // is the agreed upon behavior
      PyErr_Clear();
      Py_XDECREF(traceback);
      Py_XDECREF(exception);
      Py_XDECREF(value);
      emit finished(MSG_FINISHED);
      return;
    }
  }

  // prework on the exception handling
  PyErr_NormalizeException(&exception, &value, &traceback);
  PyErr_Clear();

  // convert the traceback into something useful
  int lineNumber = 0;
  QString filename;
  if (traceback) {
    PyTracebackObject *tb = (PyTracebackObject *)traceback;
    lineNumber = tb->tb_lineno;
    filename = TO_CSTRING(tb->tb_frame->f_code->co_filename);
  }

  // the error message is the full (formated) traceback
  PyObject *str_repr = PyObject_Str(value);
  QString message;
  QTextStream msgStream(&message);
  if (value && str_repr) {
    if (exception == PyExc_SyntaxError) {
      msgStream << constructSyntaxErrorStr(value);
    } else {
      QString excTypeName(
          value->ob_type
              ->tp_name); // This is fully qualified with the module name
      excTypeName = excTypeName.section(".", -1);
      msgStream << excTypeName << ": " << TO_CSTRING(str_repr);
    }

  } else {
    msgStream << "Unknown exception has occurred.";
  }
  tracebackToMsg(msgStream, (PyTracebackObject *)(traceback));
  msgStream << "\n";

  Py_XDECREF(traceback);
  Py_XDECREF(exception);
  Py_XDECREF(value);

  emit error(msgStream.readAll(), filename, lineNumber);
}
Ejemplo n.º 21
0
void
PyErr_PrintEx(int set_sys_last_vars)
{
	PyObject *exception, *v, *tb, *hook;

	if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
		handle_system_exit();
	}
	PyErr_Fetch(&exception, &v, &tb);
	if (exception == NULL)
		return;
	PyErr_NormalizeException(&exception, &v, &tb);
	if (exception == NULL)
		return;
        /* Now we know v != NULL too */
	if (set_sys_last_vars) {
		PySys_SetObject("last_type", exception);
		PySys_SetObject("last_value", v);
		PySys_SetObject("last_traceback", tb);
	}
	hook = PySys_GetObject("excepthook");
	if (hook) {
		PyObject *args = PyTuple_Pack(3,
		    exception, v, tb ? tb : Py_None);
		PyObject *result = PyEval_CallObject(hook, args);
		if (result == NULL) {
			PyObject *exception2, *v2, *tb2;
			if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
				handle_system_exit();
			}
			PyErr_Fetch(&exception2, &v2, &tb2);
			PyErr_NormalizeException(&exception2, &v2, &tb2);
			/* It should not be possible for exception2 or v2
			   to be NULL. However PyErr_Display() can't
			   tolerate NULLs, so just be safe. */
			if (exception2 == NULL) {
				exception2 = Py_None;
				Py_INCREF(exception2);
			}
			if (v2 == NULL) {
				v2 = Py_None;
				Py_INCREF(v2);
			}
			if (Py_FlushLine())
				PyErr_Clear();
			fflush(stdout);
			PySys_WriteStderr("Error in sys.excepthook:\n");
			PyErr_Display(exception2, v2, tb2);
			PySys_WriteStderr("\nOriginal exception was:\n");
			PyErr_Display(exception, v, tb);
			Py_DECREF(exception2);
			Py_DECREF(v2);
			Py_XDECREF(tb2);
		}
		Py_XDECREF(result);
		Py_XDECREF(args);
	} else {
		PySys_WriteStderr("sys.excepthook is missing\n");
		PyErr_Display(exception, v, tb);
	}
	Py_XDECREF(exception);
	Py_XDECREF(v);
	Py_XDECREF(tb);
}
Ejemplo n.º 22
0
/*
 * Extract a Python traceback from the current exception.
 *
 * The exception error message is returned in xmsg, the traceback in
 * tbmsg (both as palloc'd strings) and the traceback depth in
 * tb_depth.
 */
static void
PLy_traceback(char **xmsg, char **tbmsg, int *tb_depth)
{
	PyObject   *e,
			   *v,
			   *tb;
	PyObject   *e_type_o;
	PyObject   *e_module_o;
	char	   *e_type_s = NULL;
	char	   *e_module_s = NULL;
	PyObject   *vob = NULL;
	char	   *vstr;
	StringInfoData xstr;
	StringInfoData tbstr;

	/*
	 * get the current exception
	 */
	PyErr_Fetch(&e, &v, &tb);

	/*
	 * oops, no exception, return
	 */
	if (e == NULL)
	{
		*xmsg = NULL;
		*tbmsg = NULL;
		*tb_depth = 0;

		return;
	}

	PyErr_NormalizeException(&e, &v, &tb);

	/*
	 * Format the exception and its value and put it in xmsg.
	 */

	e_type_o = PyObject_GetAttrString(e, "__name__");
	e_module_o = PyObject_GetAttrString(e, "__module__");
	if (e_type_o)
		e_type_s = PyString_AsString(e_type_o);
	if (e_type_s)
		e_module_s = PyString_AsString(e_module_o);

	if (v && ((vob = PyObject_Str(v)) != NULL))
		vstr = PyString_AsString(vob);
	else
		vstr = "unknown";

	initStringInfo(&xstr);
	if (!e_type_s || !e_module_s)
	{
		if (PyString_Check(e))
			/* deprecated string exceptions */
			appendStringInfoString(&xstr, PyString_AsString(e));
		else
			/* shouldn't happen */
			appendStringInfoString(&xstr, "unrecognized exception");
	}
	/* mimics behavior of traceback.format_exception_only */
	else if (strcmp(e_module_s, "builtins") == 0
			 || strcmp(e_module_s, "__main__") == 0
			 || strcmp(e_module_s, "exceptions") == 0)
		appendStringInfo(&xstr, "%s", e_type_s);
	else
		appendStringInfo(&xstr, "%s.%s", e_module_s, e_type_s);
	appendStringInfo(&xstr, ": %s", vstr);

	*xmsg = xstr.data;

	/*
	 * Now format the traceback and put it in tbmsg.
	 */

	*tb_depth = 0;
	initStringInfo(&tbstr);
	/* Mimick Python traceback reporting as close as possible. */
	appendStringInfoString(&tbstr, "Traceback (most recent call last):");
	while (tb != NULL && tb != Py_None)
	{
		PyObject   *volatile tb_prev = NULL;
		PyObject   *volatile frame = NULL;
		PyObject   *volatile code = NULL;
		PyObject   *volatile name = NULL;
		PyObject   *volatile lineno = NULL;
		PyObject   *volatile filename = NULL;

		PG_TRY();
		{
			lineno = PyObject_GetAttrString(tb, "tb_lineno");
			if (lineno == NULL)
				elog(ERROR, "could not get line number from Python traceback");

			frame = PyObject_GetAttrString(tb, "tb_frame");
			if (frame == NULL)
				elog(ERROR, "could not get frame from Python traceback");

			code = PyObject_GetAttrString(frame, "f_code");
			if (code == NULL)
				elog(ERROR, "could not get code object from Python frame");

			name = PyObject_GetAttrString(code, "co_name");
			if (name == NULL)
				elog(ERROR, "could not get function name from Python code object");

			filename = PyObject_GetAttrString(code, "co_filename");
			if (filename == NULL)
				elog(ERROR, "could not get file name from Python code object");
		}
		PG_CATCH();
		{
			Py_XDECREF(frame);
			Py_XDECREF(code);
			Py_XDECREF(name);
			Py_XDECREF(lineno);
			Py_XDECREF(filename);
			PG_RE_THROW();
		}
		PG_END_TRY();

		/* The first frame always points at <module>, skip it. */
		if (*tb_depth > 0)
		{
			PLyExecutionContext	*exec_ctx = PLy_current_execution_context();
			char	   *proname;
			char	   *fname;
			char	   *line;
			char	   *plain_filename;
			long		plain_lineno;

			/*
			 * The second frame points at the internal function, but to mimick
			 * Python error reporting we want to say <module>.
			 */
			if (*tb_depth == 1)
				fname = "<module>";
			else
				fname = PyString_AsString(name);

			proname = PLy_procedure_name(exec_ctx->curr_proc);
			plain_filename = PyString_AsString(filename);
			plain_lineno = PyInt_AsLong(lineno);

			if (proname == NULL)
				appendStringInfo(
				&tbstr, "\n  PL/Python anonymous code block, line %ld, in %s",
								 plain_lineno - 1, fname);
			else
				appendStringInfo(
					&tbstr, "\n  PL/Python function \"%s\", line %ld, in %s",
								 proname, plain_lineno - 1, fname);

			/*
			 * function code object was compiled with "<string>" as the
			 * filename
			 */
			if (exec_ctx->curr_proc && plain_filename != NULL &&
				strcmp(plain_filename, "<string>") == 0)
			{
				/*
				 * If we know the current procedure, append the exact line
				 * from the source, again mimicking Python's traceback.py
				 * module behavior.  We could store the already line-split
				 * source to avoid splitting it every time, but producing a
				 * traceback is not the most important scenario to optimize
				 * for.  But we do not go as far as traceback.py in reading
				 * the source of imported modules.
				 */
				line = get_source_line(exec_ctx->curr_proc->src, plain_lineno);
				if (line)
				{
					appendStringInfo(&tbstr, "\n    %s", line);
					pfree(line);
				}
			}
		}

		Py_DECREF(frame);
		Py_DECREF(code);
		Py_DECREF(name);
		Py_DECREF(lineno);
		Py_DECREF(filename);

		/* Release the current frame and go to the next one. */
		tb_prev = tb;
		tb = PyObject_GetAttrString(tb, "tb_next");
		Assert(tb_prev != Py_None);
		Py_DECREF(tb_prev);
		if (tb == NULL)
			elog(ERROR, "could not traverse Python traceback");
		(*tb_depth)++;
	}

	/* Return the traceback. */
	*tbmsg = tbstr.data;

	Py_XDECREF(e_type_o);
	Py_XDECREF(e_module_o);
	Py_XDECREF(vob);
	Py_XDECREF(v);
	Py_DECREF(e);
}
Ejemplo n.º 23
0
ErrorResult PythonEngine::parseError()
{
    QString traceback;
    QString text;
    int line = -1;

    PyErr_NormalizeException(&errorType, &errorValue, &errorTraceback);

    if (errorTraceback)
    {
        PyTracebackObject *tb = (PyTracebackObject *) errorTraceback;
        line = tb->tb_lineno;
        text.append(QString("Line %1: ").arg(tb->tb_lineno));

        while (tb)
        {
            PyFrameObject *frame = tb->tb_frame;

            if (frame && frame->f_code) {
                PyCodeObject* codeObject = frame->f_code;
                if (PyString_Check(codeObject->co_filename))
                    traceback.append(QString("File '%1'").arg(PyString_AsString(codeObject->co_filename)));

                int errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti);
                traceback.append(QString(", line %1").arg(errorLine));

                if (PyString_Check(codeObject->co_name))
                    traceback.append(QString(", in %1").arg(PyString_AsString(codeObject->co_name)));
            }
            traceback.append(QString("\n"));

            tb = tb->tb_next;
        }
    }
    traceback = traceback.trimmed();

    PyObject *errorString = NULL;
    if (errorType != NULL && (errorString = PyObject_Str(errorType)) != NULL && (PyString_Check(errorString)))
    {
        Py_INCREF(errorString);
        text.append(PyString_AsString(errorString));
        Py_XDECREF(errorString);
    }
    else
    {
        text.append("\n<unknown exception type>");
    }

    if (errorValue != NULL && (errorString = PyObject_Str(errorValue)) != NULL && (PyString_Check(errorString)))
    {
        Py_INCREF(errorString);
        text.append("\n");
        text.append(PyString_AsString(errorString));
        Py_XDECREF(errorString);
    }
    else
    {
        text.append("\n<unknown exception data>");
    }

    Py_XDECREF(errorType);
    errorType = NULL;
    Py_XDECREF(errorValue);
    errorValue = NULL;
    Py_XDECREF(errorTraceback);
    errorTraceback = NULL;

    PyErr_Clear();

    return ErrorResult(text, traceback, line);
}
Ejemplo n.º 24
0
QString QgsPythonUtilsImpl::getTraceback()
{
#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}

  // acquire global interpreter lock to ensure we are in a consistent state
  PyGILState_STATE gstate;
  gstate = PyGILState_Ensure();

  QString errMsg;
  QString result;

  PyObject *modStringIO = NULL;
  PyObject *modTB = NULL;
  PyObject *obStringIO = NULL;
  PyObject *obResult = NULL;

  PyObject *type, *value, *traceback;

  PyErr_Fetch( &type, &value, &traceback );
  PyErr_NormalizeException( &type, &value, &traceback );

  modStringIO = PyImport_ImportModule( "cStringIO" );
  if ( modStringIO == NULL )
    TRACEBACK_FETCH_ERROR( "can't import cStringIO" );

  obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", NULL );

  /* Construct a cStringIO object */
  if ( obStringIO == NULL )
    TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" );

  modTB = PyImport_ImportModule( "traceback" );
  if ( modTB == NULL )
    TRACEBACK_FETCH_ERROR( "can't import traceback" );

  obResult = PyObject_CallMethod( modTB, ( char* ) "print_exception",
                                  ( char* ) "OOOOO",
                                  type, value ? value : Py_None,
                                  traceback ? traceback : Py_None,
                                  Py_None,
                                  obStringIO );

  if ( obResult == NULL )
    TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" );
  Py_DECREF( obResult );

  obResult = PyObject_CallMethod( obStringIO, ( char* ) "getvalue", NULL );
  if ( obResult == NULL )
    TRACEBACK_FETCH_ERROR( "getvalue() failed." );

  /* And it should be a string all ready to go - duplicate it. */
  if ( !PyString_Check( obResult ) )
    TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" );

  result = PyString_AsString( obResult );

done:

  // All finished - first see if we encountered an error
  if ( result.isEmpty() && !errMsg.isEmpty() )
  {
    result = errMsg;
  }

  Py_XDECREF( modStringIO );
  Py_XDECREF( modTB );
  Py_XDECREF( obStringIO );
  Py_XDECREF( obResult );
  Py_XDECREF( value );
  Py_XDECREF( traceback );
  Py_XDECREF( type );

  // we are done calling python API, release global interpreter lock
  PyGILState_Release( gstate );

  return result;
}
Ejemplo n.º 25
0
static PyObject *
gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
{
    PyThreadState *tstate = PyThreadState_GET();
    PyFrameObject *f = gen->gi_frame;
    PyObject *result;

    if (gen->gi_running) {
        char *msg = "generator already executing";
        if (PyCoro_CheckExact(gen))
            msg = "coroutine already executing";
        PyErr_SetString(PyExc_ValueError, msg);
        return NULL;
    }
    if (f == NULL || f->f_stacktop == NULL) {
        if (PyCoro_CheckExact(gen) && !closing) {
            /* `gen` is an exhausted coroutine: raise an error,
               except when called from gen_close(), which should
               always be a silent method. */
            PyErr_SetString(
                PyExc_RuntimeError,
                "cannot reuse already awaited coroutine");
        } else if (arg && !exc) {
            /* `gen` is an exhausted generator:
               only set exception if called from send(). */
            PyErr_SetNone(PyExc_StopIteration);
        }
        return NULL;
    }

    if (f->f_lasti == -1) {
        if (arg && arg != Py_None) {
            char *msg = "can't send non-None value to a "
                        "just-started generator";
            if (PyCoro_CheckExact(gen))
                msg = "can't send non-None value to a "
                      "just-started coroutine";
            PyErr_SetString(PyExc_TypeError, msg);
            return NULL;
        }
    } else {
        /* Push arg onto the frame's value stack */
        result = arg ? arg : Py_None;
        Py_INCREF(result);
        *(f->f_stacktop++) = result;
    }

    /* Generators always return to their most recent caller, not
     * necessarily their creator. */
    Py_XINCREF(tstate->frame);
    assert(f->f_back == NULL);
    f->f_back = tstate->frame;

    gen->gi_running = 1;
    result = PyEval_EvalFrameEx(f, exc);
    gen->gi_running = 0;

    /* Don't keep the reference to f_back any longer than necessary.  It
     * may keep a chain of frames alive or it could create a reference
     * cycle. */
    assert(f->f_back == tstate->frame);
    Py_CLEAR(f->f_back);

    /* If the generator just returned (as opposed to yielding), signal
     * that the generator is exhausted. */
    if (result && f->f_stacktop == NULL) {
        if (result == Py_None) {
            /* Delay exception instantiation if we can */
            PyErr_SetNone(PyExc_StopIteration);
        } else {
            PyObject *e = PyObject_CallFunctionObjArgs(
                               PyExc_StopIteration, result, NULL);
            if (e != NULL) {
                PyErr_SetObject(PyExc_StopIteration, e);
                Py_DECREF(e);
            }
        }
        Py_CLEAR(result);
    }
    else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
        /* Check for __future__ generator_stop and conditionally turn
         * a leaking StopIteration into RuntimeError (with its cause
         * set appropriately). */
        if (((PyCodeObject *)gen->gi_code)->co_flags &
              (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
        {
            PyObject *exc, *val, *val2, *tb;
            char *msg = "generator raised StopIteration";
            if (PyCoro_CheckExact(gen))
                msg = "coroutine raised StopIteration";
            PyErr_Fetch(&exc, &val, &tb);
            PyErr_NormalizeException(&exc, &val, &tb);
            if (tb != NULL)
                PyException_SetTraceback(val, tb);
            Py_DECREF(exc);
            Py_XDECREF(tb);
            PyErr_SetString(PyExc_RuntimeError, msg);
            PyErr_Fetch(&exc, &val2, &tb);
            PyErr_NormalizeException(&exc, &val2, &tb);
            Py_INCREF(val);
            PyException_SetCause(val2, val);
            PyException_SetContext(val2, val);
            PyErr_Restore(exc, val2, tb);
        }
        else {
            PyObject *exc, *val, *tb;

            /* Pop the exception before issuing a warning. */
            PyErr_Fetch(&exc, &val, &tb);

            if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                                 "generator '%.50S' raised StopIteration",
                                 gen->gi_qualname)) {
                /* Warning was converted to an error. */
                Py_XDECREF(exc);
                Py_XDECREF(val);
                Py_XDECREF(tb);
            }
            else {
                PyErr_Restore(exc, val, tb);
            }
        }
    }

    if (!result || f->f_stacktop == NULL) {
        /* generator can't be rerun, so release the frame */
        /* first clean reference cycle through stored exception traceback */
        PyObject *t, *v, *tb;
        t = f->f_exc_type;
        v = f->f_exc_value;
        tb = f->f_exc_traceback;
        f->f_exc_type = NULL;
        f->f_exc_value = NULL;
        f->f_exc_traceback = NULL;
        Py_XDECREF(t);
        Py_XDECREF(v);
        Py_XDECREF(tb);
        gen->gi_frame->f_gen = NULL;
        gen->gi_frame = NULL;
        Py_DECREF(f);
    }

    return result;
}
Ejemplo n.º 26
0
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
    PyObject* owned_instance = NULL;
    if (tb == Py_None) {
        tb = 0;
    } else if (tb && !PyTraceBack_Check(tb)) {
        PyErr_SetString(PyExc_TypeError,
            "raise: arg 3 must be a traceback or None");
        goto bad;
    }
    if (value == Py_None)
        value = 0;

    if (PyExceptionInstance_Check(type)) {
        if (value) {
            PyErr_SetString(PyExc_TypeError,
                "instance exception may not have a separate value");
            goto bad;
        }
        value = type;
        type = (PyObject*) Py_TYPE(value);
    } else if (PyExceptionClass_Check(type)) {
        // make sure value is an exception instance of type
        PyObject *instance_class = NULL;
        if (value && PyExceptionInstance_Check(value)) {
            instance_class = (PyObject*) Py_TYPE(value);
            if (instance_class != type) {
                int is_subclass = PyObject_IsSubclass(instance_class, type);
                if (!is_subclass) {
                    instance_class = NULL;
                } else if (unlikely(is_subclass == -1)) {
                    // error on subclass test
                    goto bad;
                } else {
                    // believe the instance
                    type = instance_class;
                }
            }
        }
        if (!instance_class) {
            // instantiate the type now (we don't know when and how it will be caught)
            // assuming that 'value' is an argument to the type's constructor
            // not using PyErr_NormalizeException() to avoid ref-counting problems
            PyObject *args;
            if (!value)
                args = PyTuple_New(0);
            else if (PyTuple_Check(value)) {
                Py_INCREF(value);
                args = value;
            } else
                args = PyTuple_Pack(1, value);
            if (!args)
                goto bad;
            owned_instance = PyObject_Call(type, args, NULL);
            Py_DECREF(args);
            if (!owned_instance)
                goto bad;
            value = owned_instance;
            if (!PyExceptionInstance_Check(value)) {
                PyErr_Format(PyExc_TypeError,
                             "calling %R should have returned an instance of "
                             "BaseException, not %R",
                             type, Py_TYPE(value));
                goto bad;
            }
        }
    } else {
        PyErr_SetString(PyExc_TypeError,
            "raise: exception class must be a subclass of BaseException");
        goto bad;
    }

#if PY_VERSION_HEX >= 0x03030000
    if (cause) {
#else
    if (cause && cause != Py_None) {
#endif
        PyObject *fixed_cause;
        if (cause == Py_None) {
            // raise ... from None
            fixed_cause = NULL;
        } else if (PyExceptionClass_Check(cause)) {
            fixed_cause = PyObject_CallObject(cause, NULL);
            if (fixed_cause == NULL)
                goto bad;
        } else if (PyExceptionInstance_Check(cause)) {
            fixed_cause = cause;
            Py_INCREF(fixed_cause);
        } else {
            PyErr_SetString(PyExc_TypeError,
                            "exception causes must derive from "
                            "BaseException");
            goto bad;
        }
        PyException_SetCause(value, fixed_cause);
    }

    PyErr_SetObject(type, value);

    if (tb) {
#if CYTHON_COMPILING_IN_PYPY
        PyObject *tmp_type, *tmp_value, *tmp_tb;
        PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb);
        Py_INCREF(tb);
        PyErr_Restore(tmp_type, tmp_value, tb);
        Py_XDECREF(tmp_tb);
#else
        PyThreadState *tstate = PyThreadState_GET();
        PyObject* tmp_tb = tstate->curexc_traceback;
        if (tb != tmp_tb) {
            Py_INCREF(tb);
            tstate->curexc_traceback = tb;
            Py_XDECREF(tmp_tb);
        }
#endif
    }

bad:
    Py_XDECREF(owned_instance);
    return;
}
#endif

/////////////// GetException.proto ///////////////
//@substitute: naming
//@requires: PyThreadStateGet

#if CYTHON_FAST_THREAD_STATE
#define __Pyx_GetException(type, value, tb)  __Pyx__GetException($local_tstate_cname, type, value, tb)
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
#else
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
#endif

/////////////// GetException ///////////////

#if CYTHON_FAST_THREAD_STATE
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
#else
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
#endif
    PyObject *local_type, *local_value, *local_tb;
#if CYTHON_FAST_THREAD_STATE
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    local_type = tstate->curexc_type;
    local_value = tstate->curexc_value;
    local_tb = tstate->curexc_traceback;
    tstate->curexc_type = 0;
    tstate->curexc_value = 0;
    tstate->curexc_traceback = 0;
#else
    PyErr_Fetch(&local_type, &local_value, &local_tb);
#endif
    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
#if CYTHON_FAST_THREAD_STATE
    if (unlikely(tstate->curexc_type))
#else
    if (unlikely(PyErr_Occurred()))
#endif
        goto bad;
    #if PY_MAJOR_VERSION >= 3
    if (local_tb) {
        if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
            goto bad;
    }
    #endif
    // traceback may be NULL for freshly raised exceptions
    Py_XINCREF(local_tb);
    // exception state may be temporarily empty in parallel loops (race condition)
    Py_XINCREF(local_type);
    Py_XINCREF(local_value);
    *type = local_type;
    *value = local_value;
    *tb = local_tb;
#if CYTHON_FAST_THREAD_STATE
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = local_type;
    tstate->exc_value = local_value;
    tstate->exc_traceback = local_tb;
    // Make sure tstate is in a consistent state when we XDECREF
    // these objects (DECREF may run arbitrary code).
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
#else
    PyErr_SetExcInfo(local_type, local_value, local_tb);
#endif
    return 0;
bad:
    *type = 0;
    *value = 0;
    *tb = 0;
    Py_XDECREF(local_type);
    Py_XDECREF(local_value);
    Py_XDECREF(local_tb);
    return -1;
}

/////////////// ReRaiseException.proto ///////////////

static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/

/////////////// ReRaiseException.proto ///////////////

static CYTHON_INLINE void __Pyx_ReraiseException(void) {
    PyObject *type = NULL, *value = NULL, *tb = NULL;
#if CYTHON_FAST_THREAD_STATE
    PyThreadState *tstate = PyThreadState_GET();
    type = tstate->exc_type;
    value = tstate->exc_value;
    tb = tstate->exc_traceback;
#else
    PyErr_GetExcInfo(&type, &value, &tb);
#endif
    if (!type || type == Py_None) {
#if !CYTHON_FAST_THREAD_STATE
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(tb);
#endif
        // message copied from Py3
        PyErr_SetString(PyExc_RuntimeError,
            "No active exception to reraise");
    } else {
#if CYTHON_FAST_THREAD_STATE
        Py_INCREF(type);
        Py_XINCREF(value);
        Py_XINCREF(tb);

#endif
        PyErr_Restore(type, value, tb);
    }
}
Ejemplo n.º 27
0
static gboolean
glade_python_setup ()
{
  GString *command;
  const gchar *module_path;
  const GList *paths;

  Py_SetProgramName (PY_STRING (PACKAGE_NAME));

  /* Initialize the Python interpreter */
  python_init ();

  /* Check and init pygobject */

  PyErr_Clear ();
  glade_python_init_pygobject_check (PYGOBJECT_REQUIRED_MAJOR,
                                     PYGOBJECT_REQUIRED_MINOR,
                                     PYGOBJECT_REQUIRED_MICRO);
  if (PyErr_Occurred ())
    {
      PyObject *ptype, *pvalue, *ptraceback, *pstr;
      char *pvalue_char = "";

      PyErr_Fetch (&ptype, &pvalue, &ptraceback);
      PyErr_NormalizeException (&ptype, &pvalue, &ptraceback);

      if ((pstr = PyObject_Str (pvalue)))
        pvalue_char = STRING_FROM_PYSTR (pstr);

      g_warning ("Unable to load pygobject module >= %d.%d.%d, "
                 "please make sure it is in python's path (sys.path). "
                 "(use PYTHONPATH env variable to specify non default paths)\n%s",
                 PYGOBJECT_REQUIRED_MAJOR, PYGOBJECT_REQUIRED_MINOR,
                 PYGOBJECT_REQUIRED_MICRO, pvalue_char);

      Py_DecRef (ptype);
      Py_DecRef (pvalue);
      Py_DecRef (ptraceback);
      Py_DecRef (pstr);
      PyErr_Clear ();
      Py_Finalize ();

      return TRUE;
    }

  pyg_disable_warning_redirections ();

  /* Generate system path array */
  command = g_string_new ("import sys; sys.path+=[");

  /* GLADE_ENV_MODULE_PATH has priority */
  module_path = g_getenv (GLADE_ENV_MODULE_PATH);
  if (module_path)
    g_string_append_printf (command, "'%s', ", module_path);

  /* Append modules directory */
  g_string_append_printf (command, "'%s'", glade_app_get_modules_dir ());
  
  /* Append extra paths (declared in the Preferences) */
  for (paths = glade_catalog_get_extra_paths (); paths; paths = g_list_next (paths))
    g_string_append_printf (command, ", '%s'", (gchar *) paths->data);

  /* Close python statement */
  g_string_append (command, "];\n");

  /* Make sure we load Gtk 3 */
  g_string_append (command, "import gi; gi.require_version('Gtk', '3.0');\n");

  /* Finally run statement in vm */
  PyRun_SimpleString (command->str);

  g_string_free (command, TRUE);

  return FALSE;
}
Ejemplo n.º 28
0
// Format the current Python exception as a string.
// Let Python do the work for us; call traceback.format_exception()
std::string formatPythonException() {
    if (!PyErr_Occurred()) {
        return "<no error?>";
    }

    // Retrieve Python exception and "normalize" (the docs are unclear but
    // they say you should do it :) )
    PyObject* exceptionObj;
    PyObject* valueObj;
    PyObject* tracebackObj;
    PyErr_Fetch(&exceptionObj, &valueObj, &tracebackObj);
    DCHECK(exceptionObj);
    PyErr_NormalizeException(&exceptionObj, &valueObj, &tracebackObj);

    PyObjectHandle exception(exceptionObj);
    PyObjectHandle value(valueObj);
    PyObjectHandle traceback(tracebackObj);

    // value and traceback may be null
    if (!value) {
        value.reset(PyObjectHandle::INCREF, Py_None);
    }
    if (!traceback) {
        traceback.reset(PyObjectHandle::INCREF, Py_None);
    }

    PyObjectHandle tbModule(PyImport_ImportModule("traceback"));
    if (!tbModule) {
        return "<import traceback failed>";
    }

    PyObject* tbDict = PyModule_GetDict(tbModule.get());  // borrowed
    if (!tbDict) {
        return "<no dict in traceback module>";
    }

    // borrowed
    PyObject* formatFunc = PyDict_GetItemString(tbDict, "format_exception");
    if (!formatFunc) {
        return "<no format_exception in traceback module>";
    }

    PyObjectHandle formatted(PyObject_CallFunction(
                                 formatFunc, const_cast<char*>("OOO"), exception.get(), value.get(),
                                 traceback.get()));
    if (!formatted) {
        return "<traceback.format_exception error>";
    }

    // format_exception returns a list of strings that should be concatenated.
    // Well then, let's do that.

    if (!PyList_Check(formatted.get())) {
        return "<traceback.format_exception didn't return a list>";
    }

    std::string out;
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(formatted.get()); ++i) {
        PyObject* obj = PyList_GET_ITEM(formatted.get(), i);  // borrowed
        char* data;
        Py_ssize_t len;
        if (PyString_AsStringAndSize(obj, &data, &len) == -1) {
            return "<traceback.format_exception member not a string>";
        }
        out.append(data, len);
    }

    return out;
}
Ejemplo n.º 29
0
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
#else
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
#endif
    PyObject *local_type, *local_value, *local_tb;
#if CYTHON_FAST_THREAD_STATE
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    local_type = tstate->curexc_type;
    local_value = tstate->curexc_value;
    local_tb = tstate->curexc_traceback;
    tstate->curexc_type = 0;
    tstate->curexc_value = 0;
    tstate->curexc_traceback = 0;
#else
    PyErr_Fetch(&local_type, &local_value, &local_tb);
#endif
    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
#if CYTHON_FAST_THREAD_STATE
    if (unlikely(tstate->curexc_type))
#else
    if (unlikely(PyErr_Occurred()))
#endif
        goto bad;
    #if PY_MAJOR_VERSION >= 3
    if (local_tb) {
        if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
            goto bad;
    }
    #endif
    // traceback may be NULL for freshly raised exceptions
    Py_XINCREF(local_tb);
    // exception state may be temporarily empty in parallel loops (race condition)
    Py_XINCREF(local_type);
    Py_XINCREF(local_value);
    *type = local_type;
    *value = local_value;
    *tb = local_tb;
#if CYTHON_FAST_THREAD_STATE
    #if PY_VERSION_HEX >= 0x030700A2
    tmp_type = tstate->exc_state.exc_type;
    tmp_value = tstate->exc_state.exc_value;
    tmp_tb = tstate->exc_state.exc_traceback;
    tstate->exc_state.exc_type = local_type;
    tstate->exc_state.exc_value = local_value;
    tstate->exc_state.exc_traceback = local_tb;
    #else
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = local_type;
    tstate->exc_value = local_value;
    tstate->exc_traceback = local_tb;
    #endif
    // Make sure tstate is in a consistent state when we XDECREF
    // these objects (DECREF may run arbitrary code).
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
#else
    PyErr_SetExcInfo(local_type, local_value, local_tb);
#endif
    return 0;
bad:
    *type = 0;
    *value = 0;
    *tb = 0;
    Py_XDECREF(local_type);
    Py_XDECREF(local_value);
    Py_XDECREF(local_tb);
    return -1;
}
Ejemplo n.º 30
0
static char *
get_exc_trace()
{
    char *tbstr = NULL; 

    PyObject *iostrmod = NULL;
    PyObject *tbmod = NULL;
    PyObject *iostr = NULL;
    PyObject *obstr = NULL;
    PyObject *args = NULL;
    PyObject *newstr = NULL;
    PyObject *func = NULL;
    char* rv = NULL; 

    PyObject *type, *value, *traceback;
    TARGET_THREAD_BEGIN_BLOCK; 
    PyErr_Fetch(&type, &value, &traceback);
    debug("** type %p, value %p, traceback %p", type, value, traceback); 
    PyErr_Print(); 
    PyErr_Clear(); 
    PyErr_NormalizeException(&type, &value, &traceback);
    debug("** type %p, value %p, traceback %p", type, value, traceback); 

    iostrmod = PyImport_ImportModule("StringIO");
    if (iostrmod==NULL)
        TB_ERROR("can't import StringIO");

    iostr = PyObject_CallMethod(iostrmod, "StringIO", NULL);

    if (iostr==NULL)
        TB_ERROR("cStringIO.StringIO() failed");

    tbmod = PyImport_ImportModule("traceback");
    if (tbmod==NULL)
        TB_ERROR("can't import traceback");

    obstr = PyObject_CallMethod(tbmod, "print_exception",
        "(OOOOO)",
        type ? type : Py_None, 
        value ? value : Py_None,
        traceback ? traceback : Py_None,
        Py_None,
        iostr);

    if (obstr==NULL) 
    {
        PyErr_Print(); 
        TB_ERROR("traceback.print_exception() failed");
    }

    Py_DecRef(obstr);

    obstr = PyObject_CallMethod(iostr, "getvalue", NULL);
    if (obstr==NULL) 
        TB_ERROR("getvalue() failed.");

    if (!PyString_Check(obstr))
        TB_ERROR("getvalue() did not return a string");

    debug("%s", PyString_AsString(obstr)); 
    args = PyTuple_New(2);
    PyTuple_SetItem(args, 0, string2target("\n")); 
    PyTuple_SetItem(args, 1, string2target("<br>")); 
    
    func = PyObject_GetAttrString(obstr, "replace"); 
    //newstr = PyObject_CallMethod(obstr, "replace", args); 
    newstr = PyObject_CallObject(func, args); 

    tbstr = PyString_AsString(newstr); 

    rv = fmtstr("plugin:%s", tbstr); 

cleanup:
    PyErr_Restore(type, value, traceback);

    if (rv == NULL)
    {
        rv = tbstr ? tbstr : "";
    }

    Py_DecRef(func);
    Py_DecRef(args);
    Py_DecRef(newstr);
    Py_DecRef(iostr);
    Py_DecRef(obstr);
    Py_DecRef(iostrmod);
    Py_DecRef(tbmod);


    TARGET_THREAD_END_BLOCK; 
    return rv;
}