2 * gnm-py-interpreter.c : GObject wrapper around Python interpreter
4 * Author: Zbigniew Chyla (cyba@gnome.pl)
7 #include <gnumeric-config.h>
11 #include "py-gnumeric.h"
12 #include "gnm-py-interpreter.h"
13 #include "gnm-python.h"
15 #include <goffice/goffice.h>
16 #include <goffice/app/module-plugin-defs.h>
17 #include <gsf/gsf-impl-utils.h>
18 #include <glib/gi18n-lib.h>
20 struct _GnmPyInterpreter
{
21 GObject parent_instance
;
23 PyThreadState
*py_thread_state
;
24 PyObject
*stringio_class
;
29 GObjectClass parent_class
;
31 void (*set_current
) (GnmPyInterpreter
*interpreter
);
32 } GnmPyInterpreterClass
;
39 static guint signals
[LAST_SIGNAL
] = { 0 };
40 static GObjectClass
*parent_class
= NULL
;
43 gnm_py_interpreter_init (GnmPyInterpreter
*interpreter
)
45 interpreter
->py_thread_state
= NULL
;
46 interpreter
->stringio_class
= NULL
;
47 interpreter
->plugin
= NULL
;
51 gnm_py_interpreter_finalize (GObject
*obj
)
53 GnmPyInterpreter
*interpreter
= GNM_PY_INTERPRETER (obj
);
55 if (interpreter
->stringio_class
!= NULL
) {
56 Py_DECREF (interpreter
->stringio_class
);
59 parent_class
->finalize (obj
);
63 gnm_py_interpreter_class_init (GObjectClass
*gobject_class
)
65 parent_class
= g_type_class_peek_parent (gobject_class
);
67 gobject_class
->finalize
= gnm_py_interpreter_finalize
;
69 signals
[SET_CURRENT_SIGNAL
] =
72 G_TYPE_FROM_CLASS (gobject_class
),
74 G_STRUCT_OFFSET (GnmPyInterpreterClass
, set_current
),
76 g_cclosure_marshal_VOID__VOID
,
80 static char *plugin_argv
[] = {(char *) "/dev/null/python/is/buggy/gnumeric", NULL
};
83 gnm_py_interpreter_new (GOPlugin
*plugin
)
85 GnmPyInterpreter
*interpreter
;
86 PyThreadState
*py_thread_state
;
88 g_return_val_if_fail (plugin
== NULL
|| GO_IS_PLUGIN (plugin
), NULL
);
91 py_thread_state
= Py_NewInterpreter ();
93 py_thread_state
= PyThreadState_Get ();
95 g_return_val_if_fail (py_thread_state
!= NULL
, NULL
);
97 interpreter
= g_object_new (GNM_PY_INTERPRETER_TYPE
, NULL
);
98 interpreter
->py_thread_state
= py_thread_state
;
99 interpreter
->plugin
= plugin
;
101 PySys_SetArgv (G_N_ELEMENTS (plugin_argv
) - 1, plugin_argv
);
102 py_initgnumeric (interpreter
);
108 gnm_py_interpreter_destroy (GnmPyInterpreter
*interpreter
,
109 GnmPyInterpreter
*new_interpreter
)
111 g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter
));
113 gnm_py_interpreter_switch_to (interpreter
);
114 Py_EndInterpreter (interpreter
->py_thread_state
);
115 (void) PyThreadState_Swap (new_interpreter
->py_thread_state
);
116 interpreter
->py_thread_state
= NULL
;
117 g_object_unref (interpreter
);
121 gnm_py_interpreter_switch_to (GnmPyInterpreter
*interpreter
)
123 g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter
));
125 if (PyThreadState_Get ()->interp
!= interpreter
->py_thread_state
->interp
) {
126 (void) PyThreadState_Swap (interpreter
->py_thread_state
);
128 interpreter
, signals
[SET_CURRENT_SIGNAL
], 0);
133 run_print_string (const char *cmd
, PyObject
*stdout_obj
)
136 m
= PyImport_AddModule ((char *) "__main__");
139 d
= PyModule_GetDict (m
);
140 v
= PyRun_String ((char *) cmd
, Py_single_input
, d
, d
);
143 if (Py_FlushLine () != 0)
145 if (v
&& v
!= Py_None
&& stdout_obj
) {
146 if (PyFile_WriteObject (v
, stdout_obj
, Py_PRINT_RAW
) != 0)
155 gnm_py_interpreter_run_string (GnmPyInterpreter
*interpreter
, const char *cmd
,
156 char **opt_stdout
, char **opt_stderr
)
158 PyObject
*sys_module
, *sys_module_dict
;
159 PyObject
*saved_stdout_obj
= NULL
, *stdout_obj
= NULL
,
160 *saved_stderr_obj
= NULL
, *stderr_obj
= NULL
;
163 g_return_if_fail (GNM_IS_PY_INTERPRETER (interpreter
));
165 gnm_py_interpreter_switch_to (interpreter
);
167 sys_module
= PyImport_AddModule ((char *) "sys");
168 if (sys_module
== NULL
)
170 g_return_if_fail (sys_module
!= NULL
);
171 sys_module_dict
= PyModule_GetDict (sys_module
);
172 g_return_if_fail (sys_module_dict
!= NULL
);
173 if (interpreter
->stringio_class
== NULL
) {
174 PyObject
*stringio_module
, *stringio_module_dict
;
176 stringio_module
= PyImport_ImportModule ((char *) "StringIO");
177 if (stringio_module
== NULL
)
179 g_return_if_fail (stringio_module
!= NULL
);
180 stringio_module_dict
= PyModule_GetDict (stringio_module
);
181 g_return_if_fail (stringio_module_dict
!= NULL
);
182 interpreter
->stringio_class
183 = PyDict_GetItemString (stringio_module_dict
,
184 (char *) "StringIO");
185 g_return_if_fail (interpreter
->stringio_class
!= NULL
);
186 Py_INCREF (interpreter
->stringio_class
);
188 if (opt_stdout
!= NULL
) {
189 stdout_obj
= PyInstance_New(interpreter
->stringio_class
,
191 if (stdout_obj
== NULL
)
193 g_return_if_fail (stdout_obj
!= NULL
);
194 saved_stdout_obj
= PyDict_GetItemString (sys_module_dict
,
196 g_return_if_fail (saved_stdout_obj
!= NULL
);
197 Py_INCREF (saved_stdout_obj
);
198 PyDict_SetItemString (sys_module_dict
, (char *) "stdout",
201 if (opt_stderr
!= NULL
) {
202 stderr_obj
= PyInstance_New(interpreter
->stringio_class
,
204 if (stderr_obj
== NULL
)
206 g_return_if_fail (stderr_obj
!= NULL
);
207 saved_stderr_obj
= PyDict_GetItemString (sys_module_dict
,
209 g_return_if_fail (saved_stderr_obj
!= NULL
);
210 Py_INCREF (saved_stderr_obj
);
211 PyDict_SetItemString (sys_module_dict
, (char *) "stderr",
214 run_print_string (cmd
, stdout_obj
);
215 if (opt_stdout
!= NULL
) {
216 PyDict_SetItemString (sys_module_dict
, (char *) "stdout",
218 Py_DECREF (saved_stdout_obj
);
219 py_str
= PyObject_CallMethod (stdout_obj
, (char *) "getvalue",
221 if (py_str
&& PyString_Check (py_str
))
222 *opt_stdout
= g_strdup (PyString_AsString (py_str
));
227 Py_DECREF (stdout_obj
);
229 if (opt_stderr
!= NULL
) {
230 PyDict_SetItemString (sys_module_dict
, (char *) "stderr",
232 Py_DECREF (saved_stderr_obj
);
233 py_str
= PyObject_CallMethod (stderr_obj
, (char *) "getvalue",
235 if (py_str
&& PyString_Check (py_str
))
236 *opt_stderr
= g_strdup (PyString_AsString (py_str
));
241 Py_DECREF (stderr_obj
);
246 gnm_py_interpreter_get_name (GnmPyInterpreter
*interpreter
)
248 g_return_val_if_fail (GNM_IS_PY_INTERPRETER (interpreter
), NULL
);
250 if (interpreter
->plugin
!= NULL
) {
251 return go_plugin_get_name (interpreter
->plugin
);
253 return _("Default interpreter");
258 gnm_py_interpreter_get_plugin (GnmPyInterpreter
*interpreter
)
260 g_return_val_if_fail (GNM_IS_PY_INTERPRETER (interpreter
), NULL
);
262 return interpreter
->plugin
;
266 gnm_py_interpreter_compare (gconstpointer a
, gconstpointer b
)
268 const GnmPyInterpreter
*int_a
= a
, *int_b
= b
;
270 if (int_a
->plugin
== NULL
&& int_b
->plugin
== NULL
) {
272 } else if (int_a
->plugin
== NULL
) {
274 } else if (int_b
->plugin
== NULL
) {
277 return g_utf8_collate (go_plugin_get_name (int_a
->plugin
),
278 go_plugin_get_name (int_b
->plugin
));
282 GSF_DYNAMIC_CLASS (GnmPyInterpreter
, gnm_py_interpreter
,
283 gnm_py_interpreter_class_init
, gnm_py_interpreter_init
,