From 65371f53dbb06180b750dad7c19e7bcf0f8651d6 Mon Sep 17 00:00:00 2001 From: monsta Date: Sun, 6 Nov 2016 14:42:18 +0300 Subject: drop Python plugins support and --enable-python build option it requires PyGTK so won't even build with GTK+3 but keep plugins themselves for future porting to libpeas --- plugin-loaders/python/pluma-plugin-loader-python.c | 719 --------------------- 1 file changed, 719 deletions(-) delete mode 100644 plugin-loaders/python/pluma-plugin-loader-python.c (limited to 'plugin-loaders/python/pluma-plugin-loader-python.c') diff --git a/plugin-loaders/python/pluma-plugin-loader-python.c b/plugin-loaders/python/pluma-plugin-loader-python.c deleted file mode 100644 index 6c856844..00000000 --- a/plugin-loaders/python/pluma-plugin-loader-python.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - * pluma-plugin-loader-python.c - * This file is part of pluma - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "pluma-plugin-loader-python.h" -#include "pluma-plugin-python.h" -#include - -#define NO_IMPORT_PYGOBJECT -#define NO_IMPORT_PYGTK - -#include -#include -#include -#include -#include "config.h" - -#if PY_VERSION_HEX < 0x02050000 -typedef int Py_ssize_t; -#define PY_SSIZE_T_MAX INT_MAX -#define PY_SSIZE_T_MIN INT_MIN -#endif - -#define PLUMA_PLUGIN_LOADER_PYTHON_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), PLUMA_TYPE_PLUGIN_LOADER_PYTHON, PlumaPluginLoaderPythonPrivate)) - -struct _PlumaPluginLoaderPythonPrivate -{ - GHashTable *loaded_plugins; - guint idle_gc; - gboolean init_failed; -}; - -typedef struct -{ - PyObject *type; - PyObject *instance; - gchar *path; -} PythonInfo; - -static void pluma_plugin_loader_iface_init (gpointer g_iface, gpointer iface_data); - -/* Exported by pypluma module */ -void pypluma_register_classes (PyObject *d); -void pypluma_add_constants (PyObject *module, const gchar *strip_prefix); -extern PyMethodDef pypluma_functions[]; - -/* Exported by pyplumautils module */ -void pyplumautils_register_classes (PyObject *d); -extern PyMethodDef pyplumautils_functions[]; - -/* Exported by pyplumacommands module */ -void pyplumacommands_register_classes (PyObject *d); -extern PyMethodDef pyplumacommands_functions[]; - -/* We retreive this to check for correct class hierarchy */ -static PyTypeObject *PyPlumaPlugin_Type; - -PLUMA_PLUGIN_LOADER_REGISTER_TYPE (PlumaPluginLoaderPython, pluma_plugin_loader_python, G_TYPE_OBJECT, pluma_plugin_loader_iface_init); - - -static PyObject * -find_python_plugin_type (PlumaPluginInfo *info, - PyObject *pymodule) -{ - PyObject *locals, *key, *value; - Py_ssize_t pos = 0; - - locals = PyModule_GetDict (pymodule); - - while (PyDict_Next (locals, &pos, &key, &value)) - { - if (!PyType_Check(value)) - continue; - - if (PyObject_IsSubclass (value, (PyObject*) PyPlumaPlugin_Type)) - return value; - } - - g_warning ("No PlumaPlugin derivative found in Python plugin '%s'", - pluma_plugin_info_get_name (info)); - return NULL; -} - -static PlumaPlugin * -new_plugin_from_info (PlumaPluginLoaderPython *loader, - PlumaPluginInfo *info) -{ - PythonInfo *pyinfo; - PyTypeObject *pytype; - PyObject *pyobject; - PyGObject *pygobject; - PlumaPlugin *instance; - PyObject *emptyarg; - - pyinfo = (PythonInfo *)g_hash_table_lookup (loader->priv->loaded_plugins, info); - - if (pyinfo == NULL) - return NULL; - - pytype = (PyTypeObject *)pyinfo->type; - - if (pytype->tp_new == NULL) - return NULL; - - emptyarg = PyTuple_New(0); - pyobject = pytype->tp_new (pytype, emptyarg, NULL); - Py_DECREF (emptyarg); - - if (pyobject == NULL) - { - g_error ("Could not create instance for %s.", pluma_plugin_info_get_name (info)); - return NULL; - } - - pygobject = (PyGObject *)pyobject; - - if (pygobject->obj != NULL) - { - Py_DECREF (pyobject); - g_error ("Could not create instance for %s (GObject already initialized).", pluma_plugin_info_get_name (info)); - return NULL; - } - - pygobject_construct (pygobject, - "install-dir", pyinfo->path, - "data-dir-name", pluma_plugin_info_get_module_name (info), - NULL); - - if (pygobject->obj == NULL) - { - g_error ("Could not create instance for %s (GObject not constructed).", pluma_plugin_info_get_name (info)); - Py_DECREF (pyobject); - - return NULL; - } - - /* now call tp_init manually */ - if (PyType_IsSubtype (pyobject->ob_type, pytype) && - pyobject->ob_type->tp_init != NULL) - { - emptyarg = PyTuple_New(0); - pyobject->ob_type->tp_init (pyobject, emptyarg, NULL); - Py_DECREF (emptyarg); - } - - instance = PLUMA_PLUGIN (pygobject->obj); - pyinfo->instance = (PyObject *)pygobject; - - /* make sure to register the python instance for the PlumaPluginPython - object to it can wrap the virtual pluma plugin funcs back to python */ - _pluma_plugin_python_set_instance (PLUMA_PLUGIN_PYTHON (instance), (PyObject *)pygobject); - - /* we return a reference here because the other is owned by python */ - return PLUMA_PLUGIN (g_object_ref (instance)); -} - -static PlumaPlugin * -add_python_info (PlumaPluginLoaderPython *loader, - PlumaPluginInfo *info, - PyObject *module, - const gchar *path, - PyObject *type) -{ - PythonInfo *pyinfo; - - pyinfo = g_new (PythonInfo, 1); - pyinfo->path = g_strdup (path); - pyinfo->type = type; - - Py_INCREF (pyinfo->type); - - g_hash_table_insert (loader->priv->loaded_plugins, info, pyinfo); - - return new_plugin_from_info (loader, info); -} - -static const gchar * -pluma_plugin_loader_iface_get_id (void) -{ - return "Python"; -} - -static PlumaPlugin * -pluma_plugin_loader_iface_load (PlumaPluginLoader *loader, - PlumaPluginInfo *info, - const gchar *path) -{ - PlumaPluginLoaderPython *pyloader = PLUMA_PLUGIN_LOADER_PYTHON (loader); - PyObject *main_module, *main_locals, *pytype; - PyObject *pymodule, *fromlist; - gchar *module_name; - PlumaPlugin *result; - - if (pyloader->priv->init_failed) - { - g_warning ("Cannot load python plugin Python '%s' since pluma was" - "not able to initialize the Python interpreter.", - pluma_plugin_info_get_name (info)); - return NULL; - } - - /* see if py definition for the plugin is already loaded */ - result = new_plugin_from_info (pyloader, info); - - if (result != NULL) - return result; - - main_module = PyImport_AddModule ("pluma.plugins"); - if (main_module == NULL) - { - g_warning ("Could not get pluma.plugins."); - return NULL; - } - - /* If we have a special path, we register it */ - if (path != NULL) - { - PyObject *sys_path = PySys_GetObject ("path"); - PyObject *pypath = PyString_FromString (path); - - if (PySequence_Contains (sys_path, pypath) == 0) - PyList_Insert (sys_path, 0, pypath); - - Py_DECREF (pypath); - } - - main_locals = PyModule_GetDict (main_module); - - /* we need a fromlist to be able to import modules with a '.' in the - name. */ - fromlist = PyTuple_New(0); - module_name = g_strdup (pluma_plugin_info_get_module_name (info)); - - pymodule = PyImport_ImportModuleEx (module_name, - main_locals, - main_locals, - fromlist); - - Py_DECREF(fromlist); - - if (!pymodule) - { - g_free (module_name); - PyErr_Print (); - return NULL; - } - - PyDict_SetItemString (main_locals, module_name, pymodule); - g_free (module_name); - - pytype = find_python_plugin_type (info, pymodule); - - if (pytype) - return add_python_info (pyloader, info, pymodule, path, pytype); - - return NULL; -} - -static void -pluma_plugin_loader_iface_unload (PlumaPluginLoader *loader, - PlumaPluginInfo *info) -{ - PlumaPluginLoaderPython *pyloader = PLUMA_PLUGIN_LOADER_PYTHON (loader); - PythonInfo *pyinfo; - PyGILState_STATE state; - - pyinfo = (PythonInfo *)g_hash_table_lookup (pyloader->priv->loaded_plugins, info); - - if (!pyinfo) - return; - - state = pyg_gil_state_ensure (); - Py_XDECREF (pyinfo->instance); - pyg_gil_state_release (state); - - pyinfo->instance = NULL; -} - -static gboolean -run_gc (PlumaPluginLoaderPython *loader) -{ - while (PyGC_Collect ()) - ; - - loader->priv->idle_gc = 0; - return FALSE; -} - -static void -pluma_plugin_loader_iface_garbage_collect (PlumaPluginLoader *loader) -{ - PlumaPluginLoaderPython *pyloader; - - if (!Py_IsInitialized()) - return; - - pyloader = PLUMA_PLUGIN_LOADER_PYTHON (loader); - - /* - * We both run the GC right now and we schedule - * a further collection in the main loop. - */ - - while (PyGC_Collect ()) - ; - - if (pyloader->priv->idle_gc == 0) - pyloader->priv->idle_gc = g_idle_add ((GSourceFunc)run_gc, pyloader); -} - -static void -pluma_plugin_loader_iface_init (gpointer g_iface, - gpointer iface_data) -{ - PlumaPluginLoaderInterface *iface = (PlumaPluginLoaderInterface *)g_iface; - - iface->get_id = pluma_plugin_loader_iface_get_id; - iface->load = pluma_plugin_loader_iface_load; - iface->unload = pluma_plugin_loader_iface_unload; - iface->garbage_collect = pluma_plugin_loader_iface_garbage_collect; -} - -static void -pluma_python_shutdown (PlumaPluginLoaderPython *loader) -{ - if (!Py_IsInitialized ()) - return; - - if (loader->priv->idle_gc != 0) - { - g_source_remove (loader->priv->idle_gc); - loader->priv->idle_gc = 0; - } - - while (PyGC_Collect ()) - ; - - Py_Finalize (); -} - - -/* C equivalent of - * import pygtk - * pygtk.require ("2.0") - */ -static gboolean -pluma_check_pygtk2 (void) -{ - PyObject *pygtk, *mdict, *require; - - /* pygtk.require("2.0") */ - pygtk = PyImport_ImportModule ("pygtk"); - if (pygtk == NULL) - { - g_warning ("Error initializing Python interpreter: could not import pygtk."); - return FALSE; - } - - mdict = PyModule_GetDict (pygtk); - require = PyDict_GetItemString (mdict, "require"); - PyObject_CallObject (require, - Py_BuildValue ("(S)", PyString_FromString ("2.0"))); - if (PyErr_Occurred()) - { - g_warning ("Error initializing Python interpreter: pygtk 2 is required."); - return FALSE; - } - - return TRUE; -} - -/* Note: the following two functions are needed because - * init_pyobject and init_pygtk which are *macros* which in case - * case of error set the PyErr and then make the calling - * function return behind our back. - * It's up to the caller to check the result with PyErr_Occurred() - */ -static void -pluma_init_pygobject (void) -{ - init_pygobject_check (2, 11, 5); /* FIXME: get from config */ -} - -static void -pluma_init_pygtk (void) -{ - PyObject *gtk, *mdict, *version, *required_version; - - init_pygtk (); - - /* there isn't init_pygtk_check(), do the version - * check ourselves */ - gtk = PyImport_ImportModule("gtk"); - mdict = PyModule_GetDict(gtk); - version = PyDict_GetItemString (mdict, "pygtk_version"); - if (!version) - { - PyErr_SetString (PyExc_ImportError, - "PyGObject version too old"); - return; - } - - required_version = Py_BuildValue ("(iii)", 2, 4, 0); /* FIXME */ - - if (PyObject_Compare (version, required_version) == -1) - { - PyErr_SetString (PyExc_ImportError, - "PyGObject version too old"); - Py_DECREF (required_version); - return; - } - - Py_DECREF (required_version); -} - -static void -old_gtksourceview_init (void) -{ - PyErr_SetString(PyExc_ImportError, - "gtksourceview module not allowed, use gtksourceview2"); -} - -static void -pluma_init_pygtksourceview (void) -{ - PyObject *gtksourceview, *mdict, *version, *required_version; - - gtksourceview = PyImport_ImportModule("gtksourceview2"); - if (gtksourceview == NULL) - { - PyErr_SetString (PyExc_ImportError, - "could not import gtksourceview"); - return; - } - - mdict = PyModule_GetDict (gtksourceview); - version = PyDict_GetItemString (mdict, "pygtksourceview2_version"); - if (!version) - { - PyErr_SetString (PyExc_ImportError, - "PyGtkSourceView version too old"); - return; - } - - required_version = Py_BuildValue ("(iii)", 0, 8, 0); /* FIXME */ - - if (PyObject_Compare (version, required_version) == -1) - { - PyErr_SetString (PyExc_ImportError, - "PyGtkSourceView version too old"); - Py_DECREF (required_version); - return; - } - - Py_DECREF (required_version); - - /* Create a dummy 'gtksourceview' module to prevent - * loading of the old 'gtksourceview' modules that - * has conflicting symbols with the gtksourceview2 module. - * Raise an exception when trying to import it. - */ - PyImport_AppendInittab ("gtksourceview", old_gtksourceview_init); -} - -static gboolean -pluma_python_init (PlumaPluginLoaderPython *loader) -{ - PyObject *mdict, *tuple; - PyObject *pluma, *plumautils, *plumacommands, *plumaplugins; - PyObject *gettext, *install, *gettext_args; - //char *argv[] = { "pluma", NULL }; - char *argv[] = { PLUMA_PLUGINS_LIBS_DIR, NULL }; -#ifdef HAVE_SIGACTION - gint res; - struct sigaction old_sigint; -#endif - - if (loader->priv->init_failed) - { - /* We already failed to initialized Python, don't need to - * retry again */ - return FALSE; - } - - if (Py_IsInitialized ()) - { - /* Python has already been successfully initialized */ - return TRUE; - } - - /* We are trying to initialize Python for the first time, - set init_failed to FALSE only if the entire initialization process - ends with success */ - loader->priv->init_failed = TRUE; - - /* Hack to make python not overwrite SIGINT: this is needed to avoid - * the crash reported on bug #326191 */ - - /* CHECK: can't we use Py_InitializeEx instead of Py_Initialize in order - to avoid to manage signal handlers ? - Paolo (Dec. 31, 2006) */ - -#ifdef HAVE_SIGACTION - /* Save old handler */ - res = sigaction (SIGINT, NULL, &old_sigint); - if (res != 0) - { - g_warning ("Error initializing Python interpreter: cannot get " - "handler to SIGINT signal (%s)", - g_strerror (errno)); - - return FALSE; - } -#endif - - /* Python initialization */ - Py_Initialize (); - -#ifdef HAVE_SIGACTION - /* Restore old handler */ - res = sigaction (SIGINT, &old_sigint, NULL); - if (res != 0) - { - g_warning ("Error initializing Python interpreter: cannot restore " - "handler to SIGINT signal (%s).", - g_strerror (errno)); - - goto python_init_error; - } -#endif - - PySys_SetArgv (1, argv); - - if (!pluma_check_pygtk2 ()) - { - /* Warning message already printed in check_pygtk2 */ - goto python_init_error; - } - - /* import gobject */ - pluma_init_pygobject (); - if (PyErr_Occurred ()) - { - g_warning ("Error initializing Python interpreter: could not import pygobject."); - - goto python_init_error; - } - - /* import gtk */ - pluma_init_pygtk (); - if (PyErr_Occurred ()) - { - g_warning ("Error initializing Python interpreter: could not import pygtk."); - - goto python_init_error; - } - - /* import gtksourceview */ - pluma_init_pygtksourceview (); - if (PyErr_Occurred ()) - { - PyErr_Print (); - - g_warning ("Error initializing Python interpreter: could not import pygtksourceview."); - - goto python_init_error; - } - - /* import pluma */ - pluma = Py_InitModule ("pluma", pypluma_functions); - mdict = PyModule_GetDict (pluma); - - pypluma_register_classes (mdict); - pypluma_add_constants (pluma, "PLUMA_"); - - /* pluma version */ - tuple = Py_BuildValue("(iii)", - PLUMA_MAJOR_VERSION, - PLUMA_MINOR_VERSION, - PLUMA_MICRO_VERSION); - PyDict_SetItemString(mdict, "version", tuple); - Py_DECREF(tuple); - - /* Retrieve the Python type for pluma.Plugin */ - PyPlumaPlugin_Type = (PyTypeObject *) PyDict_GetItemString (mdict, "Plugin"); - if (PyPlumaPlugin_Type == NULL) - { - PyErr_Print (); - - goto python_init_error; - } - - /* import pluma.utils */ - plumautils = Py_InitModule ("pluma.utils", pyplumautils_functions); - PyDict_SetItemString (mdict, "utils", plumautils); - - /* import pluma.commands */ - plumacommands = Py_InitModule ("pluma.commands", pyplumacommands_functions); - PyDict_SetItemString (mdict, "commands", plumacommands); - - /* initialize empty pluma.plugins module */ - plumaplugins = Py_InitModule ("pluma.plugins", NULL); - PyDict_SetItemString (mdict, "plugins", plumaplugins); - - mdict = PyModule_GetDict (plumautils); - pyplumautils_register_classes (mdict); - - mdict = PyModule_GetDict (plumacommands); - pyplumacommands_register_classes (mdict); - - /* i18n support */ - gettext = PyImport_ImportModule ("gettext"); - if (gettext == NULL) - { - g_warning ("Error initializing Python interpreter: could not import gettext."); - - goto python_init_error; - } - - mdict = PyModule_GetDict (gettext); - install = PyDict_GetItemString (mdict, "install"); - gettext_args = Py_BuildValue ("ss", GETTEXT_PACKAGE, PLUMA_LOCALEDIR); - PyObject_CallObject (install, gettext_args); - Py_DECREF (gettext_args); - - /* Python has been successfully initialized */ - loader->priv->init_failed = FALSE; - - return TRUE; - -python_init_error: - - g_warning ("Please check the installation of all the Python related packages required " - "by pluma and try again."); - - PyErr_Clear (); - - pluma_python_shutdown (loader); - - return FALSE; -} - -static void -pluma_plugin_loader_python_finalize (GObject *object) -{ - PlumaPluginLoaderPython *pyloader = PLUMA_PLUGIN_LOADER_PYTHON (object); - - g_hash_table_destroy (pyloader->priv->loaded_plugins); - pluma_python_shutdown (pyloader); - - G_OBJECT_CLASS (pluma_plugin_loader_python_parent_class)->finalize (object); -} - -static void -pluma_plugin_loader_python_class_init (PlumaPluginLoaderPythonClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = pluma_plugin_loader_python_finalize; - - g_type_class_add_private (object_class, sizeof (PlumaPluginLoaderPythonPrivate)); -} - -static void -pluma_plugin_loader_python_class_finalize (PlumaPluginLoaderPythonClass *klass) -{ -} - -static void -destroy_python_info (PythonInfo *info) -{ - PyGILState_STATE state = pyg_gil_state_ensure (); - Py_XDECREF (info->type); - pyg_gil_state_release (state); - - g_free (info->path); - g_free (info); -} - -static void -pluma_plugin_loader_python_init (PlumaPluginLoaderPython *self) -{ - self->priv = PLUMA_PLUGIN_LOADER_PYTHON_GET_PRIVATE (self); - - /* initialize python interpreter */ - pluma_python_init (self); - - /* loaded_plugins maps PlumaPluginInfo to a PythonInfo */ - self->priv->loaded_plugins = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)destroy_python_info); -} - -PlumaPluginLoaderPython * -pluma_plugin_loader_python_new () -{ - GObject *loader = g_object_new (PLUMA_TYPE_PLUGIN_LOADER_PYTHON, NULL); - - return PLUMA_PLUGIN_LOADER_PYTHON (loader); -} - -- cgit v1.2.1