From 9f4abb8a20871c64b33f88ad5538bbbe111c1d4c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 24 May 2023 02:24:00 +0200
Subject: Update the YAML Python bindings code.

---
 plugins/yaml/collection-int.h    |  4 +++
 plugins/yaml/collection.c        | 29 +++++++++++++++++-
 plugins/yaml/python/collection.c | 64 +++++++++++++++++++++++++++-------------
 plugins/yaml/python/collection.h |  2 +-
 plugins/yaml/python/module.c     | 12 ++------
 plugins/yaml/python/node.c       | 57 ++++++++++++++++++++++++++++++-----
 plugins/yaml/python/node.h       |  2 +-
 plugins/yaml/python/pair.c       | 23 +++++++++------
 plugins/yaml/python/pair.h       |  2 +-
 9 files changed, 144 insertions(+), 51 deletions(-)

diff --git a/plugins/yaml/collection-int.h b/plugins/yaml/collection-int.h
index ae9607a..453976d 100644
--- a/plugins/yaml/collection-int.h
+++ b/plugins/yaml/collection-int.h
@@ -52,5 +52,9 @@ struct _GYamlCollectionClass
 };
 
 
+/* Met en place une collection de noeuds YAML. */
+bool g_yaml_collection_create(GYamlCollection *, bool);
+
+
 
 #endif  /* PLUGINS_YAML_COLLECTION_INT_H */
diff --git a/plugins/yaml/collection.c b/plugins/yaml/collection.c
index 03ab071..cdc63d9 100644
--- a/plugins/yaml/collection.c
+++ b/plugins/yaml/collection.c
@@ -180,7 +180,34 @@ GYamlCollection *g_yaml_collection_new(bool seq)
 
     result = g_object_new(G_TYPE_YAML_COLLEC, NULL);
 
-    result->is_seq = seq;
+    if (!g_yaml_collection_create(result, seq))
+        g_clear_object(&result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = noeud d'arborescence YAML à initialiser pleinement. *
+*                seq    = indique la nature de la future collection.          *
+*                                                                             *
+*  Description : Met en place une collection de noeuds YAML.                  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_yaml_collection_create(GYamlCollection *collec, bool seq)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    collec->is_seq = seq;
 
     return result;
 
diff --git a/plugins/yaml/python/collection.c b/plugins/yaml/python/collection.c
index a3ea76c..fd8e08a 100644
--- a/plugins/yaml/python/collection.c
+++ b/plugins/yaml/python/collection.c
@@ -28,16 +28,20 @@
 #include <pygobject.h>
 
 
+#include <i18n.h>
+#include <plugins/pychrysalide/access.h>
 #include <plugins/pychrysalide/helpers.h>
 
 
 #include "node.h"
-#include "../collection.h"
+#include "../collection-int.h"
 
 
 
-/* Crée un nouvel objet Python de type 'YamlCollection'. */
-static PyObject *py_yaml_collection_new(PyTypeObject *, PyObject *, PyObject *);
+CREATE_DYN_CONSTRUCTOR(yaml_collection, G_TYPE_YAML_COLLEC);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_yaml_collection_init(PyObject *, PyObject *, PyObject *);
 
 /* Indique la nature d'une collection YAML. */
 static PyObject *py_yaml_collection_is_sequence(PyObject *, void *);
@@ -49,21 +53,20 @@ static PyObject *py_yaml_collection_get_nodes(PyObject *, void *);
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : type = type de l'objet à instancier.                         *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
 *                args = arguments fournis à l'appel.                          *
 *                kwds = arguments de type key=val fournis.                    *
 *                                                                             *
-*  Description : Crée un nouvel objet Python de type 'YamlCollection'.        *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
 *                                                                             *
-*  Retour      : Instance Python mise en place.                               *
+*  Retour      : 0.                                                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_yaml_collection_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    PyObject *result;                       /* Instance à retourner        */
     int seq;                                /* Indicateur de type          */
     int ret;                                /* Bilan de lecture des args.  */
     GYamlCollection *collec;                /* Création GLib à transmettre */
@@ -78,16 +81,28 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb
     "Where *seq* is a boolean value which defines if the collection will be a"      \
     " sequence or a mapping of nodes."
 
+    /* Récupération des paramètres */
+
     ret = PyArg_ParseTuple(args, "p", &seq);
-    if (!ret) return NULL;
+    if (!ret) return -1;
 
-    collec = g_yaml_collection_new(seq);
+    /* Initialisation d'un objet GLib */
 
-    g_object_ref_sink(G_OBJECT(collec));
-    result = pygobject_new(G_OBJECT(collec));
-    g_object_unref(collec);
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
 
-    return result;
+    /* Eléments de base */
+
+    collec = G_YAML_COLLEC(pygobject_get(self));
+
+    if (!g_yaml_collection_create(collec, seq))
+    {
+        PyErr_SetString(PyExc_ValueError, _("Unable to create YAML collection."));
+        return -1;
+
+    }
+
+    return 0;
 
 }
 
@@ -223,7 +238,9 @@ PyTypeObject *get_python_yaml_collection_type(void)
 
         .tp_methods     = py_yaml_collection_methods,
         .tp_getset      = py_yaml_collection_getseters,
-        .tp_new         = py_yaml_collection_new
+
+        .tp_init        = py_yaml_collection_init,
+        .tp_new         = py_yaml_collection_new,
 
     };
 
@@ -234,7 +251,7 @@ PyTypeObject *get_python_yaml_collection_type(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
+*  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Prend en charge l'objet 'pychrysalide.....YamlCollection.    *
 *                                                                             *
@@ -244,19 +261,24 @@ PyTypeObject *get_python_yaml_collection_type(void)
 *                                                                             *
 ******************************************************************************/
 
-bool register_python_yaml_collection(PyObject *module)
+bool ensure_python_yaml_collection_is_registered(void)
 {
     PyTypeObject *type;                     /* Type Python 'YamlCollection'*/
+    PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
     type = get_python_yaml_collection_type();
 
-    dict = PyModule_GetDict(module);
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.plugins.yaml");
+
+        dict = PyModule_GetDict(module);
 
-    /* TODO : ensure get_python_yaml_node_type() */
+        if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type))
+            return false;
 
-    if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type))
-        return false;
+    }
 
     return true;
 
diff --git a/plugins/yaml/python/collection.h b/plugins/yaml/python/collection.h
index f06984f..24875d0 100644
--- a/plugins/yaml/python/collection.h
+++ b/plugins/yaml/python/collection.h
@@ -35,7 +35,7 @@
 PyTypeObject *get_python_yaml_collection_type(void);
 
 /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlCollection'. */
-bool register_python_yaml_collection(PyObject *);
+bool ensure_python_yaml_collection_is_registered(void);
 
 /* Tente de convertir en collection de noeuds de format YAML. */
 int convert_to_yaml_collection(PyObject *, void *);
diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c
index 756b068..3d6a4e8 100644
--- a/plugins/yaml/python/module.c
+++ b/plugins/yaml/python/module.c
@@ -107,18 +107,12 @@ bool add_yaml_module_to_python_module(void)
 bool populate_yaml_module(void)
 {
     bool result;                            /* Bilan à retourner           */
-    PyObject *module;                       /* Module à recompléter        */
 
     result = populate_yaml_module_with_parsers();
-    if (!result) goto exit;
 
-    module = get_access_to_python_module("pychrysalide.plugins.yaml");
-
-    if (result) result = register_python_yaml_node(module);
-    if (result) result = register_python_yaml_collection(module);
-    if (result) result = register_python_yaml_pair(module);
-
- exit:
+    if (result) result = ensure_python_yaml_node_is_registered();
+    if (result) result = ensure_python_yaml_collection_is_registered();
+    if (result) result = ensure_python_yaml_pair_is_registered();
 
     assert(result);
 
diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c
index 7f7c383..7d2fef0 100644
--- a/plugins/yaml/python/node.c
+++ b/plugins/yaml/python/node.c
@@ -28,6 +28,7 @@
 #include <pygobject.h>
 
 
+#include <plugins/pychrysalide/access.h>
 #include <plugins/pychrysalide/helpers.h>
 
 
@@ -35,6 +36,34 @@
 
 
 
+CREATE_DYN_ABSTRACT_CONSTRUCTOR(yaml_node, G_TYPE_YAML_NODE, NULL);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_yaml_node_init(PyObject *, PyObject *, PyObject *);
+
+/* Recherche le premier noeud correspondant à un chemin. */
+static PyObject *py_yaml_node_find_first_by_path(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0.                                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_yaml_node_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
 #define YAML_NODE_DOC                                                                               \
     "YamlNode handles a node in a YAML tree.\n"                                                     \
     "\n"                                                                                            \
@@ -42,11 +71,14 @@
     "* pair, implemented by the pychrysalide.plugins.yaml.YamlPair object;\n"                       \
     "* sequence and mapping, implemented by the pychrysalide.plugins.yaml.YamlCollection object."
 
+    /* Initialisation d'un objet GLib */
 
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
 
-/* Recherche le premier noeud correspondant à un chemin. */
-static PyObject *py_yaml_node_find_first_by_path(PyObject *, PyObject *);
+    return 0;
 
+}
 
 
 /******************************************************************************
@@ -145,7 +177,9 @@ PyTypeObject *get_python_yaml_node_type(void)
 
         .tp_methods     = py_yaml_node_methods,
         .tp_getset      = py_yaml_node_getseters,
-        .tp_new         = no_python_constructor_allowed
+
+        .tp_init        = py_yaml_node_init,
+        .tp_new         = py_yaml_node_new,
 
     };
 
@@ -156,7 +190,7 @@ PyTypeObject *get_python_yaml_node_type(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
+*  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlNode.  *
 *                                                                             *
@@ -166,17 +200,24 @@ PyTypeObject *get_python_yaml_node_type(void)
 *                                                                             *
 ******************************************************************************/
 
-bool register_python_yaml_node(PyObject *module)
+bool ensure_python_yaml_node_is_registered(void)
 {
     PyTypeObject *type;                     /* Type Python 'YamlNode'      */
+    PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
     type = get_python_yaml_node_type();
 
-    dict = PyModule_GetDict(module);
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.plugins.yaml");
 
-    if (!register_class_for_pygobject(dict, G_TYPE_YAML_NODE, type))
-        return false;
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_YAML_NODE, type))
+            return false;
+
+    }
 
     return true;
 
diff --git a/plugins/yaml/python/node.h b/plugins/yaml/python/node.h
index 4d1a50f..80d8a65 100644
--- a/plugins/yaml/python/node.h
+++ b/plugins/yaml/python/node.h
@@ -35,7 +35,7 @@
 PyTypeObject *get_python_yaml_node_type(void);
 
 /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlNode'. */
-bool register_python_yaml_node(PyObject *);
+bool ensure_python_yaml_node_is_registered(void);
 
 /* Tente de convertir en noeud d'arborescence de format YAML. */
 int convert_to_yaml_node(PyObject *, void *);
diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c
index 59ca0a9..1fffbeb 100644
--- a/plugins/yaml/python/pair.c
+++ b/plugins/yaml/python/pair.c
@@ -31,6 +31,7 @@
 
 
 #include <i18n.h>
+#include <plugins/pychrysalide/access.h>
 #include <plugins/pychrysalide/helpers.h>
 
 
@@ -501,7 +502,6 @@ PyTypeObject *get_python_yaml_pair_type(void)
         .tp_init        = py_yaml_pair_init,
         .tp_new         = py_yaml_pair_new,
 
-
     };
 
     return &py_yaml_pair_type;
@@ -511,7 +511,7 @@ PyTypeObject *get_python_yaml_pair_type(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
+*  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlPair.  *
 *                                                                             *
@@ -521,22 +521,27 @@ PyTypeObject *get_python_yaml_pair_type(void)
 *                                                                             *
 ******************************************************************************/
 
-bool register_python_yaml_pair(PyObject *module)
+bool ensure_python_yaml_pair_is_registered(void)
 {
     PyTypeObject *type;                     /* Type Python 'YamlPair'      */
+    PyObject *module;                       /* Module à recompléter        */
     PyObject *dict;                         /* Dictionnaire du module      */
 
     type = get_python_yaml_pair_type();
 
-    dict = PyModule_GetDict(module);
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.plugins.yaml");
 
-    /* TODO : get_python_yaml_node_type() */
+        dict = PyModule_GetDict(module);
 
-    if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type))
-        return false;
+        if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type))
+            return false;
 
-    if (!define_yaml_pair_constants(type))
-        return false;
+        if (!define_yaml_pair_constants(type))
+            return false;
+
+    }
 
     return true;
 
diff --git a/plugins/yaml/python/pair.h b/plugins/yaml/python/pair.h
index 0e7e04c..b03b984 100644
--- a/plugins/yaml/python/pair.h
+++ b/plugins/yaml/python/pair.h
@@ -35,7 +35,7 @@
 PyTypeObject *get_python_yaml_pair_type(void);
 
 /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlPair'. */
-bool register_python_yaml_pair(PyObject *);
+bool ensure_python_yaml_pair_is_registered(void);
 
 /* Tente de convertir en noeud d'arborescence de format YAML. */
 int convert_to_yaml_pair(PyObject *, void *);
-- 
cgit v0.11.2-87-g4458