[pygobject] enum/flags: use gir info for type names and __repr__ instead of the gtype name



commit b1788c9a445c8a820121c42260bcbdbc3ae8dfba
Author: Christoph Reiter <creiter src gnome org>
Date:   Mon Oct 26 11:17:34 2015 +0100

    enum/flags: use gir info for type names and __repr__ instead of the gtype name
    
    For example __name__ is now SpawnFlags instead of PyGLibSpawnFlags
    and __repr__ shows GLib.SpawnFlags in stead of PyGLibSpawnFlags.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=657915

 gi/gimodule.c               |   35 ++++++++++++++++++++++---
 gi/pygenum.c                |   59 +++++++++++++++++++++++++++++--------------
 gi/pygflags.c               |   31 ++++++++++++++++++----
 tests/test_gi.py            |   41 +++++++++++++++++++++++++++++
 tests/test_overrides_gdk.py |    6 ++--
 5 files changed, 140 insertions(+), 32 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 74bf7cd..cc8fd66 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -36,6 +36,33 @@ PyObject *PyGIWarning;
 PyObject *PyGIDeprecationWarning;
 PyObject *_PyGIDefaultArgPlaceholder;
 
+
+/* Returns a new flag/enum type or %NULL */
+static PyObject *
+flags_enum_from_gtype (GType g_type,
+                       PyObject * (add_func) (PyObject *, const char *,
+                                              const char *, GType))
+{
+    PyObject *new_type;
+    GIRepository *repository;
+    GIBaseInfo *info;
+    const gchar *type_name;
+
+    repository = g_irepository_get_default ();
+    info = g_irepository_find_by_gtype (repository, g_type);
+    if (info != NULL) {
+        type_name = g_base_info_get_name (info);
+        new_type = add_func (NULL, type_name, NULL, g_type);
+        g_base_info_unref (info);
+    } else {
+        type_name = g_type_name (g_type);
+        new_type = add_func (NULL, type_name, NULL, g_type);
+    }
+
+    return new_type;
+}
+
+
 static PyObject *
 _wrap_pyg_enum_add (PyObject *self,
                     PyObject *args,
@@ -56,7 +83,7 @@ _wrap_pyg_enum_add (PyObject *self,
         return NULL;
     }
 
-    return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
+    return flags_enum_from_gtype (g_type, pyg_enum_add);
 }
 
 static PyObject *
@@ -152,7 +179,7 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
     }
 
     g_free (full_name);
-    return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
+    return pyg_enum_add (NULL, type_name, NULL, g_type);
 }
 
 static PyObject *
@@ -175,7 +202,7 @@ _wrap_pyg_flags_add (PyObject *self,
         return NULL;
     }
 
-    return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
+    return flags_enum_from_gtype (g_type, pyg_flags_add);
 }
 
 static PyObject *
@@ -271,7 +298,7 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
     }
 
     g_free (full_name);
-    return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
+    return pyg_flags_add (NULL, type_name, NULL, g_type);
 }
 
 static void
diff --git a/gi/pygenum.c b/gi/pygenum.c
index 053518f..fe78fb9 100644
--- a/gi/pygenum.c
+++ b/gi/pygenum.c
@@ -71,29 +71,50 @@ pyg_enum_richcompare(PyGEnum *self, PyObject *other, int op)
 static PyObject *
 pyg_enum_repr(PyGEnum *self)
 {
-  GEnumClass *enum_class;
-  const char *value;
-  guint index;
-  static char tmp[256];
-  long l;
+    PyObject *module;
+    GEnumClass *enum_class;
+    const char *value;
+    guint index;
+    char *namespace, *module_str;
+    static char tmp[256];
+    long l;
+
+    module = PyObject_GetAttrString ((PyObject *)self, "__module__");
+    if (module == NULL)
+        return NULL;
 
-  enum_class = g_type_class_ref(self->gtype);
-  g_assert(G_IS_ENUM_CLASS(enum_class));
+    if (!PYGLIB_PyUnicode_Check (module)) {
+        Py_DECREF (module);
+        return NULL;
+    }
 
-  l = PYGLIB_PyLong_AS_LONG(self);
-  for (index = 0; index < enum_class->n_values; index++) 
-      if (l == enum_class->values[index].value)
-          break;
+    enum_class = g_type_class_ref(self->gtype);
+    g_assert(G_IS_ENUM_CLASS(enum_class));
 
-  value = enum_class->values[index].value_name;
-  if (value)
-      sprintf(tmp, "<enum %s of type %s>", value, g_type_name(self->gtype));
-  else
-      sprintf(tmp, "<enum %ld of type %s>", PYGLIB_PyLong_AS_LONG(self), g_type_name(self->gtype));
+    l = PYGLIB_PyLong_AS_LONG(self);
+    for (index = 0; index < enum_class->n_values; index++)
+        if (l == enum_class->values[index].value)
+            break;
 
-  g_type_class_unref(enum_class);
+    module_str = PYGLIB_PyUnicode_AsString (module);
+    namespace = g_strrstr (module_str, ".");
+    if (namespace == NULL) {
+        namespace = module_str;
+    } else {
+        namespace += 1;
+    }
+
+    value = enum_class->values[index].value_name;
+    if (value)
+        sprintf(tmp, "<enum %s of type %s.%s>", value,
+                namespace, Py_TYPE (self)->tp_name);
+    else
+        sprintf(tmp, "<enum %ld of type %s.%s>", PYGLIB_PyLong_AS_LONG(self),
+                namespace, Py_TYPE (self)->tp_name);
+    Py_DECREF (module);
+    g_type_class_unref(enum_class);
 
-  return PYGLIB_PyUnicode_FromString(tmp);
+    return PYGLIB_PyUnicode_FromString(tmp);
 }
 
 static PyObject *
diff --git a/gi/pygflags.c b/gi/pygflags.c
index a7df8ce..ce146ae 100644
--- a/gi/pygflags.c
+++ b/gi/pygflags.c
@@ -105,18 +105,37 @@ generate_repr(GType gtype, guint value)
 static PyObject *
 pyg_flags_repr(PyGFlags *self)
 {
-    char *tmp, *retval;
-    PyObject *pyretval;
+    char *tmp, *retval, *module_str, *namespace;
+    PyObject *pyretval, *module;
 
     tmp = generate_repr(self->gtype, PYGLIB_PyLong_AsUnsignedLong(self));
 
+    module = PyObject_GetAttrString ((PyObject *)self, "__module__");
+    if (module == NULL)
+        return NULL;
+
+    if (!PYGLIB_PyUnicode_Check (module)) {
+        Py_DECREF (module);
+        return NULL;
+    }
+
+    module_str = PYGLIB_PyUnicode_AsString (module);
+    namespace = g_strrstr (module_str, ".");
+    if (namespace == NULL) {
+        namespace = module_str;
+    } else {
+        namespace += 1;
+    }
+
     if (tmp)
-        retval = g_strdup_printf("<flags %s of type %s>", tmp,
-                                 g_type_name(self->gtype));
+        retval = g_strdup_printf("<flags %s of type %s.%s>", tmp,
+                                 namespace, Py_TYPE (self)->tp_name);
     else
-        retval = g_strdup_printf("<flags %ld of type %s>", PYGLIB_PyLong_AsUnsignedLong(self),
-                                 g_type_name(self->gtype));
+        retval = g_strdup_printf("<flags %ld of type %s.%s>",
+                                 PYGLIB_PyLong_AsUnsignedLong (self),
+                                 namespace, Py_TYPE (self)->tp_name);
     g_free(tmp);
+    Py_DECREF (module);
 
     pyretval = PYGLIB_PyUnicode_FromString(retval);
     g_free(retval);
diff --git a/tests/test_gi.py b/tests/test_gi.py
index abd2466..1fbc216 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -1544,6 +1544,16 @@ class TestEnum(unittest.TestCase):
                           gi._gi.enum_add,
                           GIMarshallingTests.NoTypeFlags.__gtype__)
 
+    def test_type_module_name(self):
+        self.assertEqual(GIMarshallingTests.Enum.__name__, "Enum")
+        self.assertEqual(GIMarshallingTests.Enum.__module__,
+                         "gi.repository.GIMarshallingTests")
+
+    def test_repr(self):
+        self.assertEqual(repr(GIMarshallingTests.Enum.VALUE3),
+                         "<enum GI_MARSHALLING_TESTS_ENUM_VALUE3 of type "
+                         "GIMarshallingTests.Enum>")
+
 
 class TestEnumVFuncResults(unittest.TestCase):
     class EnumTester(GIMarshallingTests.Object):
@@ -1604,6 +1614,16 @@ class TestGEnum(unittest.TestCase):
         self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
         self.assertEqual(genum, GIMarshallingTests.GEnum.VALUE1)
 
+    def test_type_module_name(self):
+        self.assertEqual(GIMarshallingTests.GEnum.__name__, "GEnum")
+        self.assertEqual(GIMarshallingTests.GEnum.__module__,
+                         "gi.repository.GIMarshallingTests")
+
+    def test_repr(self):
+        self.assertEqual(repr(GIMarshallingTests.GEnum.VALUE3),
+                         "<enum GI_MARSHALLING_TESTS_GENUM_VALUE3 of type "
+                         "GIMarshallingTests.GEnum>")
+
 
 class TestGFlags(unittest.TestCase):
 
@@ -1657,6 +1677,16 @@ class TestGFlags(unittest.TestCase):
         self.assertTrue(isinstance(flags, GIMarshallingTests.Flags))
         self.assertEqual(flags, GIMarshallingTests.Flags.VALUE1)
 
+    def test_type_module_name(self):
+        self.assertEqual(GIMarshallingTests.Flags.__name__, "Flags")
+        self.assertEqual(GIMarshallingTests.Flags.__module__,
+                         "gi.repository.GIMarshallingTests")
+
+    def test_repr(self):
+        self.assertEqual(repr(GIMarshallingTests.Flags.VALUE2),
+                         "<flags GI_MARSHALLING_TESTS_FLAGS_VALUE2 of type "
+                         "GIMarshallingTests.Flags>")
+
 
 class TestNoTypeFlags(unittest.TestCase):
 
@@ -1706,6 +1736,17 @@ class TestNoTypeFlags(unittest.TestCase):
         self.assertEqual(GIMarshallingTests.NoTypeFlags.__gtype__.name,
                          'PyGIMarshallingTestsNoTypeFlags')
 
+    def test_type_module_name(self):
+        self.assertEqual(GIMarshallingTests.NoTypeFlags.__name__,
+                         "NoTypeFlags")
+        self.assertEqual(GIMarshallingTests.NoTypeFlags.__module__,
+                         "gi.repository.GIMarshallingTests")
+
+    def test_repr(self):
+        self.assertEqual(repr(GIMarshallingTests.NoTypeFlags.VALUE2),
+                         "<flags GI_MARSHALLING_TESTS_NO_TYPE_FLAGS_VALUE2 of "
+                         "type GIMarshallingTests.NoTypeFlags>")
+
 
 class TestStructure(unittest.TestCase):
 
diff --git a/tests/test_overrides_gdk.py b/tests/test_overrides_gdk.py
index 9559a09..a0ffac4 100644
--- a/tests/test_overrides_gdk.py
+++ b/tests/test_overrides_gdk.py
@@ -157,16 +157,16 @@ class TestGdk(unittest.TestCase):
         self.assertEqual(Gdk.ModifierType.META_MASK | 0, 0x10000000)
         self.assertEqual(hex(Gdk.ModifierType.META_MASK), '0x10000000')
         self.assertEqual(str(Gdk.ModifierType.META_MASK),
-                         '<flags GDK_META_MASK of type GdkModifierType>')
+                         '<flags GDK_META_MASK of type Gdk.ModifierType>')
 
         self.assertEqual(Gdk.ModifierType.RELEASE_MASK | 0, 0x40000000)
         self.assertEqual(hex(Gdk.ModifierType.RELEASE_MASK), '0x40000000')
         self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK),
-                         '<flags GDK_RELEASE_MASK of type GdkModifierType>')
+                         '<flags GDK_RELEASE_MASK of type Gdk.ModifierType>')
 
         self.assertEqual(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK, 0x50000000)
         self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK),
-                         '<flags GDK_META_MASK | GDK_RELEASE_MASK of type GdkModifierType>')
+                         '<flags GDK_META_MASK | GDK_RELEASE_MASK of type Gdk.ModifierType>')
 
     def test_color_parse(self):
         with capture_glib_deprecation_warnings():


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]