-///////////////////////////////////////////////////////
-// //
-// VTT Technical Research Centre of Finland LTD //
-// For internal use only. Do not redistribute. //
-// //
-// Authors: //
-// Antton Tapani ext-antton.tapani@vtt.fi //
-// //
-// Last modified by Antton Tapani 9.2016 //
-// //
-///////////////////////////////////////////////////////
+/*******************************************************************************
+ * Copyright (c) 2017-2019 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre - Initial API and implementation
+ * Semantum Oy - Improvements
+ *******************************************************************************/
#include "sclpy.h"
writeToSCL(PyObject *self, PyObject *args)
{
if (currentEnv != NULL && sclWriter != NULL) {
- Py_UNICODE *what;
+ wchar_t *what;
Py_ssize_t length;
JNIEnv *env = currentEnv;
JNIEXPORT void JNICALL
Java_org_simantics_pythonlink_PythonContext_initializePython(
JNIEnv *env, jobject thisObj, jobject writer) {
- Py_Initialize();
+ Py_InitializeEx(0);
{
static struct PyModuleDef moduledef = {
PyObject *formatExc = NULL, *args = NULL;
PyObject *tracebackModule = PyImport_ImportModule("traceback");
if (!tracebackModule) {
+ fputs("Python: No traceback module\n", stderr);
return NULL;
}
+ PyErr_NormalizeException(&exceptionType, &exception, &traceback);
+
if (exception && traceback) {
formatExc = PyDict_GetItemString(PyModule_GetDict(tracebackModule), "format_exception");
args = PyTuple_Pack(3, exceptionType, exception, traceback);
args = PyTuple_Pack(2, exceptionType, exception);
}
- Py_DECREF(tracebackModule);
-
if (formatExc != NULL && args != NULL) {
PyObject *result = PyObject_CallObject(formatExc, args);
+ if (!result) {
+ fputs("Python: No result from format_exception\n", stderr);
+ // Fallback to a direct string representation of the exception object
+ result = PyObject_Str(exception);
+ }
Py_XDECREF(args);
- Py_XDECREF(formatExc);
+ // Py_XDECREF(formatExc) - Borrowed reference
+ Py_DECREF(tracebackModule);
+
return result;
}
else {
+ if (!formatExc) fputs("Python: No format_exception\n", stderr);
+
Py_XDECREF(args);
- Py_XDECREF(formatExc);
+ // Py_XDECREF(formatExc) - Borrowed reference
+ Py_DECREF(tracebackModule);
+
return NULL;
}
}
+static void throwExceptionType(JNIEnv *env, PyObject *exceptionType) {
+ PyObject *ty_name = exceptionType ? PyObject_GetAttrString(exceptionType, "__name__") : NULL;
+ PyObject *str = ty_name ? PyUnicode_AsEncodedString(ty_name, "utf-8", "ignore") : NULL;
+
+ throwPythonException(env, str ? PyBytes_AsString(str) : "Internal error - no exception type");
+
+ Py_XDECREF(str);
+ Py_XDECREF(ty_name);
+}
+
JNIEXPORT jint JNICALL
Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(
JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {
currentEnv = env;
{
- PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals);
+ // PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals); - Not available in Py_LIMITED_API
+ PyObject *code = Py_CompileString(utfchars, "SCL_INPUT", Py_file_input);
+ PyObject *result = code ? PyEval_EvalCode(code,globals, globals) : NULL;
PyObject *exceptionType = PyErr_Occurred();
if (exceptionType != NULL) {
message = getExceptionMessage(exceptionType, exception, traceback);
if (message != NULL) {
- PyObject *emptyStr = PyUnicode_FromString("");
- PyObject *joined = PyUnicode_Join(emptyStr, message);
- char *messageStr = PyUnicode_AsUTF8(joined);
- throwPythonException(env, messageStr);
- Py_DECREF(joined);
- Py_DECREF(emptyStr);
+ if (PyList_Check(message)) {
+ PyObject *emptyStr = PyUnicode_FromString("");
+ PyObject *temp = PyUnicode_Join(emptyStr, message);
+ if (temp) {
+ Py_DECREF(message);
+ message = temp;
+ }
+
+ Py_DECREF(emptyStr);
+ }
+
+ if (!PyUnicode_Check(message)) {
+ PyObject *temp = PyObject_Str(message);
+ if (temp) {
+ Py_DECREF(message);
+ message = temp;
+ }
+ }
+
+ PyObject* str = PyUnicode_AsEncodedString(message, "utf-8", "ignore");
Py_DECREF(message);
+
+ if (str != NULL) {
+ throwPythonException(env, PyBytes_AsString(str));
+ Py_DECREF(str);
+ }
+ else {
+ fputs("Python: Encoding message string failed\n", stderr);
+ throwExceptionType(env, exceptionType);
+ }
}
else {
- PyTypeObject
- *ty = (PyTypeObject *)exceptionType;
- throwPythonException(
- env, ty ? ty->tp_name
- : "Internal error, null exception type");
+ fputs("Python: No exception message\n", stderr);
+ throwExceptionType(env, exceptionType);
}
-
- Py_XDECREF(exceptionType);
- Py_XDECREF(exception);
- Py_XDECREF(traceback);
}
+ Py_XDECREF(result);
+ Py_XDECREF(code);
+
PyEval_SaveThread();
(*env)->ReleaseStringUTFChars(env, statement, utfchars);