From b1788c9a445c8a820121c42260bcbdbc3ae8dfba Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Mon, 26 Oct 2015 11:17:34 +0100 Subject: [PATCH] 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 | 57 +++++++++++++++++++++++++++++++-------------- gi/pygflags.c | 31 +++++++++++++++++++----- tests/test_gi.py | 41 ++++++++++++++++++++++++++++++++ tests/test_overrides_gdk.py | 6 ++--- 5 files changed, 139 insertions(+), 31 deletions(-) diff --git a/gi/gimodule.c b/gi/gimodule.c index 74bf7cd0..cc8fd667 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 053518f8..fe78fb97 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, "", value, g_type_name(self->gtype)); - else - sprintf(tmp, "", 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, "", value, + namespace, Py_TYPE (self)->tp_name); + else + sprintf(tmp, "", 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 a7df8ce2..ce146ae2 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("", tmp, - g_type_name(self->gtype)); + retval = g_strdup_printf("", tmp, + namespace, Py_TYPE (self)->tp_name); else - retval = g_strdup_printf("", PYGLIB_PyLong_AsUnsignedLong(self), - g_type_name(self->gtype)); + retval = g_strdup_printf("", + 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 abd2466c..1fbc216f 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), + "") + 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), + "") + 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), + "") + 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), + "") + class TestStructure(unittest.TestCase): diff --git a/tests/test_overrides_gdk.py b/tests/test_overrides_gdk.py index 9559a093..a0ffac42 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), - '') + '') self.assertEqual(Gdk.ModifierType.RELEASE_MASK | 0, 0x40000000) self.assertEqual(hex(Gdk.ModifierType.RELEASE_MASK), '0x40000000') self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK), - '') + '') self.assertEqual(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK, 0x50000000) self.assertEqual(str(Gdk.ModifierType.RELEASE_MASK | Gdk.ModifierType.META_MASK), - '') + '') def test_color_parse(self): with capture_glib_deprecation_warnings(): -- 2.11.4.GIT