summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2013-10-14 20:38:13 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2013-10-14 20:49:39 -0700
commita2fa531b4dee73c193cac92fa3e870808688b5d7 (patch)
treebc31480c09ae5f7d5aa02ca74ab7a841c1239511
parent799989ada2f6b1d729f078f204445651c808a2c7 (diff)
downloadpygobject-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.c29
-rw-r--r--tests/test_gi.py14
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):