diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2013-10-14 20:38:13 -0700 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2013-10-14 20:49:39 -0700 |
commit | a2fa531b4dee73c193cac92fa3e870808688b5d7 (patch) | |
tree | bc31480c09ae5f7d5aa02ca74ab7a841c1239511 | |
parent | 799989ada2f6b1d729f078f204445651c808a2c7 (diff) | |
download | pygobject-a2fa531b4dee73c193cac92fa3e870808688b5d7.tar.gz |
Add dir method to GObject props accessor
Remove special case __members__ attribute from the props accessor
objects getattr method. This has been deprecated since Python 2.3 and
removed in Python 3. Replace this with a __dir__ method making use of the
old members list building code. Additionally fix error where the
GObjectClass was being unref'd too many times when using dir(Object.props),
causing a GLib critical.
https://bugzilla.gnome.org/show_bug.cgi?id=705754
-rw-r--r-- | gi/_gobject/pygobject.c | 29 | ||||
-rw-r--r-- | tests/test_gi.py | 14 |
2 files changed, 35 insertions, 8 deletions
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c index c107a178..f78b7f51 100644 --- a/gi/_gobject/pygobject.c +++ b/gi/_gobject/pygobject.c @@ -241,14 +241,13 @@ build_parameter_list(GObjectClass *class) g_free(name); } - g_type_class_unref(class); - if (props) g_free(props); return props_list; } + static PyObject* PyGProps_getattro(PyGProps *self, PyObject *attr) { @@ -265,12 +264,6 @@ PyGProps_getattro(PyGProps *self, PyObject *attr) } class = g_type_class_ref(self->gtype); - - if (!strcmp(attr_name, "__members__")) { - ret = build_parameter_list(class); - g_type_class_unref(class); - return ret; - } /* g_object_class_find_property recurses through the class hierarchy, * so the resulting pspec tells us the owner_type that owns the property @@ -440,6 +433,25 @@ pygobject_props_get_iter(PyGProps *self) return (PyObject *) iter; } +static PyObject* +pygobject_props_dir(PyGProps *self) +{ + PyObject *ret; + GObjectClass *class; + + class = g_type_class_ref (self->gtype); + ret = build_parameter_list (class); + g_type_class_unref (class); + + return ret; +} + +static PyMethodDef pygobject_props_methods[] = { + { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS}, + { NULL, NULL, 0} +}; + + static Py_ssize_t PyGProps_length(PyGProps *self) { @@ -2413,6 +2425,7 @@ pygobject_object_register_types(PyObject *d) "Python attributes."; PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse; PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter; + PyGProps_Type.tp_methods = pygobject_props_methods; if (PyType_Ready(&PyGProps_Type) < 0) return; diff --git a/tests/test_gi.py b/tests/test_gi.py index 4f66c236..43c226ef 100644 --- a/tests/test_gi.py +++ b/tests/test_gi.py @@ -2893,6 +2893,20 @@ class TestPropertiesObject(unittest.TestCase): self.assertEqual(42, obj.props.some_int) self.assertEqual(54, obj.props.some_uchar) + def test_props_accessor_dir(self): + # Test class + props = dir(GIMarshallingTests.PropertiesObject.props) + self.assertTrue('some_float' in props) + self.assertTrue('some_double' in props) + self.assertTrue('some_variant' in props) + + # Test instance + obj = GIMarshallingTests.PropertiesObject() + props = dir(obj.props) + self.assertTrue('some_float' in props) + self.assertTrue('some_double' in props) + self.assertTrue('some_variant' in props) + class TestKeywords(unittest.TestCase): def test_method(self): |