summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2023-05-20 22:22:47 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2023-05-20 22:22:47 (GMT)
commitd7ede72c4351b11c064ccfee7036c7d8461ad2e8 (patch)
treef7f23ae8a19e9267385054c1d2f9a8deecda8a8a
parent4293dfb9d679799fc46240436636fdcd431bccad (diff)
Simplify the Python plugins interface by deleting one of the relative GLib type.
-rw-r--r--plugins/pychrysalide/core.c6
-rw-r--r--plugins/pychrysalide/helpers.h29
-rw-r--r--plugins/pychrysalide/plugins/plugin.c592
-rw-r--r--plugins/pychrysalide/plugins/plugin.h32
4 files changed, 250 insertions, 409 deletions
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index d4f2292..c3a6cf2 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -312,7 +312,7 @@ static bool install_metaclass_for_python_gobjects(void)
/**
* Les extensions Python sont chargées à partir de la fonction load_python_plugins(),
- * qui fait appel à g_python_plugin_new(). Une instance y est construite via un
+ * qui fait appel à create_python_plugin(). Une instance y est construite via un
* appel à PyObject_CallFunction() avec la classe spécifiée par l'alias AutoLoad
* dans le fichier __init__.py présent dans chaque module d'extension.
*
@@ -862,7 +862,7 @@ static void load_python_plugins(GPluginModule *plugin)
filename = stradd(filename, G_DIR_SEPARATOR_S);
filename = stradd(filename, entry->d_name);
- pyplugin = g_python_plugin_new(modname, filename);
+ pyplugin = create_python_plugin(modname, filename);
if (pyplugin == NULL)
{
@@ -1227,7 +1227,7 @@ void log_pychrysalide_exception(const char *prefix, ...)
*
* C'est par exemple le cas quand un greffon Python ne peut se lancer
* correctement ; l'exception est alors levée à partir de la fonction
- * g_python_plugin_new() et le plantage intervient en sortie d'exécution,
+ * create_python_plugin() et le plantage intervient en sortie d'exécution,
* au moment de la libération de l'extension Python :
*
* ==14939== Jump to the invalid address stated on the next line
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 348c110..c9cc098 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -87,26 +87,21 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
#name "(" args ")\n--\n\n" doc \
}
-#define PYTHON_VOID_WRAPPER_DEF(name, args, flags, doc) \
- { \
- #name, (PyCFunction)py_return_none, \
- flags, \
- #name "(" args ")\n--\n\n" doc \
+#define PYTHON_WRAPPER_DEF_WITH(name, args, flags, defcb, doc) \
+ { \
+ #name, (PyCFunction)defcb, \
+ flags, \
+ #name "(" args ")\n--\n\n" doc \
}
-#define PYTHON_FALSE_WRAPPER_DEF(name, args, flags, doc)\
- { \
- #name, (PyCFunction)py_return_false, \
- flags, \
- #name "(" args ")\n--\n\n" doc \
- }
+#define PYTHON_VOID_WRAPPER_DEF(name, args, flags, doc) \
+ PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_none, doc)
-#define PYTHON_TRUE_WRAPPER_DEF(name, args, flags, doc)\
- { \
- #name, (PyCFunction)py_return_true, \
- flags, \
- #name "(" args ")\n--\n\n" doc \
- }
+#define PYTHON_FALSE_WRAPPER_DEF(name, args, flags, doc) \
+ PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_false, doc)
+
+#define PYTHON_TRUE_WRAPPER_DEF(name, args, flags, doc) \
+ PYTHON_WRAPPER_DEF_WITH(name, args, flags, py_return_true, doc)
/**
* Il ne semble pas exister de moyen de déterminer
diff --git a/plugins/pychrysalide/plugins/plugin.c b/plugins/pychrysalide/plugins/plugin.c
index a87d0a6..06bbd83 100644
--- a/plugins/pychrysalide/plugins/plugin.c
+++ b/plugins/pychrysalide/plugins/plugin.c
@@ -51,21 +51,29 @@
/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_plugin_module_new(PyTypeObject *, PyObject *, PyObject *);
-
/* Initialise la classe des greffons d'extension. */
static void py_plugin_module_init_gclass(GPluginModuleClass *, gpointer);
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(plugin_module, G_TYPE_PLUGIN_MODULE, py_plugin_module_init_gclass);
+
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_plugin_module_init(PyObject *self, PyObject *args, PyObject *kwds);
/* Encadre une étape de la vie d'un greffon. */
static bool py_plugin_module_manage_wrapper(GPluginModule *);
+/* Assiste la désactivation d'un greffon. */
+static bool py_plugin_module_exit(GPluginModule *);
+
/* Accompagne la fin du chargement des modules natifs. */
static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *, PluginAction);
+/* Fournit le nom brut associé au greffon par défaut. */
+static PyObject *py_plugin_module_get_modname_by_default(PyObject *, PyObject *);
+
+/* Fournit le nom brut associé au greffon. */
+static char *py_plugin_module_get_modname_wrapper(const GPluginModule *);
+
#ifdef HAVE_GTK_SUPPORT
/* Complète une liste de resources pour thème. */
@@ -102,42 +110,6 @@ static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule *
-/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */
-
-
-/* Ligne de représentation de code binaire (instance) */
-struct _GPythonPlugin
-{
- GPluginModule parent; /* Instance parente */
-
-};
-
-
-/* Ligne de représentation de code binaire (classe) */
-struct _GPythonPluginClass
-{
- GPluginModuleClass parent; /* Classe parente */
-
-};
-
-
-/* Initialise la classe des greffons Python. */
-static void g_python_plugin_class_init(GPythonPluginClass *);
-
-/* Initialise l'instance d'un greffon Python. */
-static void g_python_plugin_init(GPythonPlugin *);
-
-/* Supprime toutes les références externes. */
-static void g_python_plugin_dispose(GPythonPlugin *);
-
-/* Description : Procède à la libération totale de la mémoire. */
-static void g_python_plugin_finalize(GPythonPlugin *);
-
-/* Fournit le nom brut associé au greffon. */
-static char *g_python_plugin_get_modname(const GPythonPlugin *);
-
-
-
/* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */
@@ -165,69 +137,6 @@ static PyObject *py_plugin_module_get_interface(PyObject *, void *);
/******************************************************************************
* *
-* Paramètres : type = type du nouvel objet à mettre en place. *
-* args = éventuelle liste d'arguments. *
-* kwds = éventuel dictionnaire de valeurs mises à disposition. *
-* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
-* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_plugin_module_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject *result; /* Objet à retourner */
- PyTypeObject *base; /* Type de base à dériver */
- bool first_time; /* Evite les multiples passages*/
- GType gtype; /* Nouveau type de processeur */
- bool status; /* Bilan d'un enregistrement */
-
- /* Validations diverses */
-
- base = get_python_plugin_module_type();
-
- if (type == base)
- {
- result = NULL;
- PyErr_Format(PyExc_RuntimeError, _("%s is an abstract class"), type->tp_name);
- goto exit;
- }
-
- /* Mise en place d'un type dédié */
-
- first_time = (g_type_from_name(type->tp_name) == 0);
-
- gtype = build_dynamic_type(G_TYPE_PYTHON_PLUGIN, type->tp_name,
- (GClassInitFunc)py_plugin_module_init_gclass, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type, base);
-
- if (!status)
- {
- result = NULL;
- goto exit;
- }
-
- }
-
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
-
- result = PyType_GenericNew(type, args, kwds);
-
- exit:
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : class = classe à initialiser. *
* unused = données non utilisées ici. *
* *
@@ -243,10 +152,12 @@ static void py_plugin_module_init_gclass(GPluginModuleClass *class, gpointer unu
{
class->init = NULL;
class->manage = py_plugin_module_manage_wrapper;
- class->exit = NULL;
+ class->exit = py_plugin_module_exit;
class->plugins_loaded = py_plugin_module_notify_plugins_loaded_wrapper;
+ class->get_modname = py_plugin_module_get_modname_wrapper;
+
#ifdef HAVE_GTK_SUPPORT
class->include_theme = py_plugin_module_include_theme_wrapper;
class->notify_panel = py_plugin_module_notify_panel_creation_wrapper;
@@ -504,6 +415,51 @@ static bool py_plugin_module_manage_wrapper(GPluginModule *plugin)
/******************************************************************************
* *
* Paramètres : plugin = greffon à manipuler. *
+* *
+* Description : Assiste la désactivation d'un greffon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_plugin_module_exit(GPluginModule *plugin)
+{
+ bool result; /* Bilan à faire remonter */
+ plugin_interface *final; /* Interface finale conservée */
+
+ result = true;
+
+ final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface;
+
+ if (final != NULL)
+ {
+ if (final->name != NULL) free(final->name);
+ if (final->desc != NULL) free(final->desc);
+ if (final->version != NULL) free(final->version);
+ if (final->url != NULL) free(final->url);
+
+ assert(final->required_count == 1);
+
+ if (final->required != NULL)
+ free(final->required);
+
+ if (final->actions != NULL)
+ free(final->actions);
+
+ free(final);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
* action = type d'action attendue. *
* *
* Description : Accompagne la fin du chargement des modules natifs. *
@@ -559,6 +515,98 @@ static void py_plugin_module_notify_plugins_loaded_wrapper(GPluginModule *plugin
}
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* args = arguments fournis à l'appel. *
+* *
+* Description : Fournit le nom brut associé au greffon par défaut. *
+* *
+* Retour : Désignation brute du greffon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_plugin_module_get_modname_by_default(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à retourner */
+ GPluginModule *plugin; /* Version native du greffon */
+ char *path; /* Chemin à traiter */
+
+ plugin = G_PLUGIN_MODULE(pygobject_get(self));
+
+ path = strdup(g_plugin_module_get_filename(plugin));
+
+ result = PyUnicode_FromString(basename(path));
+
+ free(path);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à valider. *
+* *
+* Description : Fournit le nom brut associé au greffon. *
+* *
+* Retour : Désignation brute du greffon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *py_plugin_module_get_modname_wrapper(const GPluginModule *plugin)
+{
+ char *result; /* Désignation brute à renvoyer*/
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan d'exécution */
+
+#define PLUGIN_MODULE_GET_MODNAME_WRAPPER PYTHON_WRAPPER_DEF_WITH \
+( \
+ _get_modname, "$self, /", \
+ METH_VARARGS, py_plugin_module_get_modname_by_default, \
+ "(Abstract) method providing the raw module name of the plugin.\n" \
+ " loaded.\n" \
+ "\n" \
+ "The result should be a short string value.\n" \
+ "\n" \
+ "A default implementation builds the module name from the Python" \
+ " script filename." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(plugin));
+
+ if (has_python_method(pyobj, "_get_modname"))
+ {
+ pyret = run_python_method(pyobj, "_get_modname", NULL);
+
+ if (!PyUnicode_Check(pyret))
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("The returned raw name must be a string"));
+
+ else
+ result = strdup(PyUnicode_DATA(pyret));
+
+ Py_XDECREF(pyret);
+
+ }
+
+ Py_DECREF(pyobj);
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
#ifdef HAVE_GTK_SUPPORT
@@ -1312,262 +1360,6 @@ static void py_plugin_module_detect_external_tools_wrapper(const GPluginModule *
/* ---------------------------------------------------------------------------------- */
-/* INTERFACE INTERNE POUR GREFFONS PYTHON */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini par la GLib pour le greffon Python. */
-G_DEFINE_TYPE(GPythonPlugin, g_python_plugin, G_TYPE_PLUGIN_MODULE);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des greffons Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_python_plugin_class_init(GPythonPluginClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GPluginModuleClass *plugin; /* Version parente de la classe*/
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_python_plugin_dispose;
- object->finalize = (GObjectFinalizeFunc)g_python_plugin_finalize;
-
- plugin = G_PLUGIN_MODULE_CLASS(klass);
-
- plugin->get_modname = (pg_get_modname_fc)g_python_plugin_get_modname;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = instance à initialiser. *
-* *
-* Description : Initialise l'instance d'un greffon Python. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_python_plugin_init(GPythonPlugin *plugin)
-{
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_python_plugin_dispose(GPythonPlugin *plugin)
-{
-#if 0
- PyThreadState *tstate; /* Contexte d'environnement */
-
- /**
- * Cf. https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
- *
- * Cependant, comme on se trouve à priori dans le thread principal de l'interpréteur,
- * PyGILState_Ensure() ne pose aucun verrou. Ce qui aboutit à la situation suivante :
- *
- * Fatal Python error: drop_gil: GIL is not locked
- *
- * On peut forcer les choses avec PyEval_AcquireLock(), mais cette fonction est marquée
- * comme dépréciée depuis Python 3.2.
- *
- * Donc on choisit les alternatives officielles.
- *
- * Cependant, PyThreadState_Get() renvoit l'erreur suivante :
- *
- * Fatal Python error: PyThreadState_Get: no current thread
- *
- * Donc on se rabat sur une sauvegarde, qui n'est initialisée que lorsque l'interpréteur
- * est intégré dans l'éditeur.
- */
-
- tstate = get_pychrysalide_main_tstate();
-
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
-
- if (tstate != NULL)
- PyEval_SaveThread();
-#endif
-
- G_OBJECT_CLASS(g_python_plugin_parent_class)->dispose(G_OBJECT(plugin));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_python_plugin_finalize(GPythonPlugin *plugin)
-{
- plugin_interface *final; /* Interface finale conservée */
-
- final = (plugin_interface *)G_PLUGIN_MODULE(plugin)->interface;
-
- if (final != NULL)
- {
- if (final->name != NULL) free(final->name);
- if (final->desc != NULL) free(final->desc);
- if (final->version != NULL) free(final->version);
- if (final->url != NULL) free(final->url);
-
- assert(final->required_count == 1);
-
- if (final->required != NULL)
- free(final->required);
-
- if (final->actions != NULL)
- free(final->actions);
-
- free(final);
-
- }
-
- G_OBJECT_CLASS(g_python_plugin_parent_class)->finalize(G_OBJECT(plugin));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : plugin = greffon à valider. *
-* *
-* Description : Fournit le nom brut associé au greffon. *
-* *
-* Retour : Désignation brute du greffon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static char *g_python_plugin_get_modname(const GPythonPlugin *plugin)
-{
- char *result; /* Désignation brute à renvoyer*/
- char *path; /* Chemin à traiter */
-
- path = strdup(g_plugin_module_get_filename(G_PLUGIN_MODULE(plugin)));
-
- result = strdup(basename(path));
-
- free(path);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : modname = nom du module à charger. *
-* filename = chemin d'accès au code Python à charger. *
-* *
-* Description : Crée un greffon à partir de code Python. *
-* *
-* Retour : Adresse de la structure mise en place ou NULL si erreur. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GPluginModule *g_python_plugin_new(const char *modname, const char *filename)
-{
- GPythonPlugin *result; /* Structure à retourner */
- PyObject *name; /* Chemin d'accès pour Python */
- PyObject *module; /* Script Python chargé */
- PyObject *dict; /* Dictionnaire associé */
- PyObject *class; /* Classe à instancier */
- PyObject *instance; /* Instance Python du greffon */
-
- name = PyUnicode_FromString(modname);
- if (name == NULL) goto bad_exit;
-
- module = PyImport_Import(name);
- Py_DECREF(name);
-
- if (module == NULL) goto no_import;
-
- dict = PyModule_GetDict(module);
- class = PyDict_GetItemString(dict, "AutoLoad");
-
- if (class == NULL) goto no_class;
- if (!PyType_Check(class->ob_type)) goto no_class;
-
- instance = PyObject_CallFunction(class, NULL);
- if (instance == NULL) goto no_instance;
-
- result = G_PYTHON_PLUGIN(pygobject_get(instance));
-
- G_PLUGIN_MODULE(result)->filename = strdup(filename);
-
- /**
- * L'instance Python et l'objet GLib résultante sont un même PyGObject.
- *
- * Donc pas besoin de toucher au comptage des références ici, la libération
- * se réalisera à la fin, quand l'objet GLib sera libéré.
- */
-
- Py_DECREF(module);
-
- return G_PLUGIN_MODULE(result);
-
- no_instance:
-
- log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance"));
-
- no_class:
-
- if (class == NULL)
- log_plugin_simple_message(LMT_ERROR,
- _("An error occured when looking for the 'AutoLoad': item not found!"));
-
- no_import:
-
- Py_XDECREF(module);
-
- log_pychrysalide_exception(_("An error occured when importing '%s'"), modname);
-
- bad_exit:
-
- return NULL;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
/* MODULE PYTHON POUR LES SCRIPTS */
/* ---------------------------------------------------------------------------------- */
@@ -1877,6 +1669,7 @@ PyTypeObject *get_python_plugin_module_type(void)
static PyMethodDef py_plugin_module_methods[] = {
PLUGIN_MODULE_MANAGE_WRAPPER,
PLUGIN_MODULE_NOTIFY_PLUGINS_LOADED_WRAPPER,
+ PLUGIN_MODULE_GET_MODNAME_WRAPPER,
#ifdef HAVE_GTK_SUPPORT
PLUGIN_MODULE_INCLUDE_THEME_WRAPPER,
PLUGIN_MODULE_ON_PANEL_CREATION_WRAPPER,
@@ -1952,7 +1745,7 @@ bool ensure_python_plugin_module_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_class_for_pygobject(dict, G_TYPE_PYTHON_PLUGIN, type, &PyGObject_Type))
+ if (!register_class_for_pygobject(dict, G_TYPE_PLUGIN_MODULE, type, &PyGObject_Type))
return false;
if (!define_plugin_module_constants(type))
@@ -1963,3 +1756,82 @@ bool ensure_python_plugin_module_is_registered(void)
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : modname = nom du module à charger. *
+* filename = chemin d'accès au code Python à charger. *
+* *
+* Description : Crée un greffon à partir de code Python. *
+* *
+* Retour : Adresse de la structure mise en place ou NULL si erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPluginModule *create_python_plugin(const char *modname, const char *filename)
+{
+ GPluginModule *result; /* Structure à retourner */
+ PyObject *name; /* Chemin d'accès pour Python */
+ PyObject *module; /* Script Python chargé */
+ PyObject *dict; /* Dictionnaire associé */
+ PyObject *class; /* Classe à instancier */
+ PyObject *instance; /* Instance Python du greffon */
+
+ name = PyUnicode_FromString(modname);
+ if (name == NULL) goto bad_exit;
+
+ module = PyImport_Import(name);
+ Py_DECREF(name);
+
+ if (module == NULL) goto no_import;
+
+ dict = PyModule_GetDict(module);
+ class = PyDict_GetItemString(dict, "AutoLoad");
+
+ if (class == NULL) goto no_class;
+ if (!PyType_Check(class->ob_type)) goto no_class;
+
+ Py_INCREF(class);
+
+ instance = PyObject_CallFunction(class, NULL);
+ if (instance == NULL) goto no_instance;
+
+ result = G_PLUGIN_MODULE(pygobject_get(instance));
+
+ result->filename = strdup(filename);
+
+ /**
+ * L'instance Python et l'objet GLib résultante sont un même PyGObject.
+ *
+ * Donc pas besoin de toucher au comptage des références ici, la libération
+ * se réalisera à la fin, quand l'objet GLib sera libéré.
+ */
+
+ Py_DECREF(module);
+
+ return result;
+
+ no_instance:
+
+ log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance"));
+
+ no_class:
+
+ if (class == NULL)
+ log_plugin_simple_message(LMT_ERROR,
+ _("An error occured when looking for the 'AutoLoad': item not found!"));
+
+ no_import:
+
+ Py_XDECREF(module);
+
+ log_pychrysalide_exception(_("An error occured when importing '%s'"), modname);
+
+ bad_exit:
+
+ return NULL;
+
+}
diff --git a/plugins/pychrysalide/plugins/plugin.h b/plugins/pychrysalide/plugins/plugin.h
index ff805f4..ad54b8e 100644
--- a/plugins/pychrysalide/plugins/plugin.h
+++ b/plugins/pychrysalide/plugins/plugin.h
@@ -35,41 +35,15 @@
-/* --------------------- INTERFACE INTERNE POUR GREFFONS PYTHON --------------------- */
-
-
-#define G_TYPE_PYTHON_PLUGIN (g_python_plugin_get_type())
-#define G_PYTHON_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PYTHON_PLUGIN, GPythonPlugin))
-#define G_IS_PYTHON_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PYTHON_PLUGIN))
-#define G_PYTHON_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PYTHON_PLUGIN, GPythonPluginClass))
-#define G_IS_PYTHON_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PYTHON_PLUGIN))
-#define G_PYTHON_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PYTHON_PLUGIN, GPythonPluginClass))
-
-
-/* Ligne de représentation de code binaire (instance) */
-typedef struct _GPythonPlugin GPythonPlugin;
-
-/* Ligne de représentation de code binaire (classe) */
-typedef struct _GPythonPluginClass GPythonPluginClass;
-
-
-/* Indique le type défini par la GLib pour le greffon Python. */
-GType g_python_plugin_get_type(void);
-
-/* Crée un greffon à partir de code Python. */
-GPluginModule *g_python_plugin_new(const char *, const char *);
-
-
-
-/* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */
-
-
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_plugin_module_type(void);
/* Prend en charge l'objet 'pychrysalide.plugins.PluginModule'. */
bool ensure_python_plugin_module_is_registered(void);
+/* Crée un greffon à partir de code Python. */
+GPluginModule *create_python_plugin(const char *, const char *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_PLUGINS_PLUGIN_H */