From 49ae908b6aa3c8c6bca2c79b0a68f587f51b600f Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 20 May 2024 00:30:44 +0200 Subject: Load the GLib module from the GI repository at Python bindings startup. --- plugins/pychrysalide/core.c | 97 ++++++++++++++++++++++++++++++++++++++++++++- plugins/pychrysalide/core.h | 3 ++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index 1157e73..c7ebf72 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -525,7 +525,9 @@ static void PyExit_pychrysalide(void) "In both cases, this is a good start point to have a look at already existing plugins to quickly learn " \ "how the API works.\n" \ "\n" \ - "These plugins are located in the 'plugins/python' directory." + "These plugins are located in the 'plugins/python' directory.\n" \ + "\n" \ + "The *pychrysalide* module imports the GLib module (version 2.0) from the GI repository at startup." PyMODINIT_FUNC PyInit_pychrysalide(void) { @@ -591,6 +593,30 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) if (!install_metaclass_for_python_gobjects()) goto exit; + /** + * Le chargement forcé de l'espace GLib pour Python permet d'éviter un écueil, + * à savoir des types convertis de façon incomplète. Par exemple, pour une + * structure GChecksum, le type à l'exécution est : + * + * - sans module GLib : [, ] + * + * - avec module GLib : [, , , ] + * + * Par ailleurs, il est à noter que le message suivant n'apparaît qu'avec + * la version debug de Python3 (version de python3-gi : 3.42.2-3) : + * + * :673: ImportWarning: DynamicImporter.exec_module() not found; falling back to load_module() + * + * Code de reproduction dans un interpréteur classique : + * + * import gi + * gi.require_version('GLib', '2.0') + * from gi.repository import GLib + * + */ + if (!import_namespace_from_gi_repository("GLib", "2.0")) + goto exit; + #if 0 #ifdef INCLUDE_GTK_SUPPORT if (!set_version_for_gtk_namespace("3.0")) @@ -1174,6 +1200,75 @@ G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *pl /****************************************************************************** * * +* Paramètres : namespace = module particulier à charger à partir de gi. * +* version = idenfiant de la version à stipuler. * +* * +* Description : Charge un module GI dans Python avec une version attendue. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool import_namespace_from_gi_repository(const char *namespace, const char *version) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Module Python-GObject */ + PyObject *args; /* Arguments à fournir */ + int ret; /* Bilan d'une mise en place */ + + result = false; + + /* Sélection d'une version */ + + module = PyImport_ImportModule("gi"); + + if (module != NULL) + { + args = Py_BuildValue("ss", namespace, version); + + run_python_method(module, "require_version", args); + + result = (PyErr_Occurred() == NULL); + + Py_DECREF(args); + Py_DECREF(module); + + } + + /* Importation du module visé */ + + if (result) + { + args = PyTuple_New(1); + + ret = PyTuple_SetItem(args, 0, PyUnicode_FromString(namespace)); + if (ret != 0) + { + result = false; + goto args_error; + } + + module = PyImport_ImportModuleEx("gi.repository", NULL, NULL, args); + + result = (module != NULL); + + Py_XDECREF(module); + + args_error: + + Py_DECREF(args); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : prefix = message d'introduction à faire apparaître à l'écran.* * * * Description : Présente dans le journal une exception survenue. * diff --git a/plugins/pychrysalide/core.h b/plugins/pychrysalide/core.h index 88c4140..5d25d3d 100644 --- a/plugins/pychrysalide/core.h +++ b/plugins/pychrysalide/core.h @@ -55,6 +55,9 @@ G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *, Plugin /* Crée une instance à partir d'un type dynamique externe. */ G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *, PluginAction, GType); +/* Charge un module GI dans Python avec une version attendue. */ +bool import_namespace_from_gi_repository(const char *, const char *); + /* Présente dans le journal une exception survenue. */ void log_pychrysalide_exception(const char *, ...); -- cgit v0.11.2-87-g4458