mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-04-28 04:07:32 -07:00
This commit represents a new era for Gentoo: Storing the gentoo-x86 tree in Git, as converted from CVS. This commit is the start of the NEW history. Any historical data is intended to be grafted onto this point. Creation process: 1. Take final CVS checkout snapshot 2. Remove ALL ChangeLog* files 3. Transform all Manifests to thin 4. Remove empty Manifests 5. Convert all stale $Header$/$Id$ CVS keywords to non-expanded Git $Id$ 5.1. Do not touch files with -kb/-ko keyword flags. Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> X-Thanks: Alec Warner <antarus@gentoo.org> - did the GSoC 2006 migration tests X-Thanks: Robin H. Johnson <robbat2@gentoo.org> - infra guy, herding this project X-Thanks: Nguyen Thai Ngoc Duy <pclouds@gentoo.org> - Former Gentoo developer, wrote Git features for the migration X-Thanks: Brian Harring <ferringb@gentoo.org> - wrote much python to improve cvs2svn X-Thanks: Rich Freeman <rich0@gentoo.org> - validation scripts X-Thanks: Patrick Lauer <patrick@gentoo.org> - Gentoo dev, running new 2014 work in migration X-Thanks: Michał Górny <mgorny@gentoo.org> - scripts, QA, nagging X-Thanks: All of other Gentoo developers - many ideas and lots of paint on the bikeshed
316 lines
11 KiB
Diff
316 lines
11 KiB
Diff
From 9456ba70fdb98b3a4eb7ee2f630182387a54ca00 Mon Sep 17 00:00:00 2001
|
|
From: Martin Pitt <martinpitt@gnome.org>
|
|
Date: Tue, 19 Feb 2013 15:39:56 +0100
|
|
Subject: [PATCH] Move property and signal creation into _class_init()
|
|
|
|
We must not add class interfaces after g_type_class_ref() has been called the
|
|
first time. Move signal and property creation from pyg_type_register() into
|
|
pyg_object_class_init(), and drop the hack of registering interfaces twice.
|
|
|
|
This is a backport of commit efcb0f9fd for 2.28.x. This allows old pygtk
|
|
applications to work with pygobject 2.28.x and glib 2.35.x.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=694108
|
|
---
|
|
gobject/gobjectmodule.c | 177 +++++++++++++++++++-----------------------------
|
|
1 file changed, 70 insertions(+), 107 deletions(-)
|
|
|
|
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
|
|
index 2a84606..91f7315 100644
|
|
--- a/gobject/gobjectmodule.c
|
|
+++ b/gobject/gobjectmodule.c
|
|
@@ -312,13 +312,6 @@ pyg_object_get_property (GObject *object, guint property_id,
|
|
pyglib_gil_state_release(state);
|
|
}
|
|
|
|
-static void
|
|
-pyg_object_class_init(GObjectClass *class, PyObject *py_class)
|
|
-{
|
|
- class->set_property = pyg_object_set_property;
|
|
- class->get_property = pyg_object_get_property;
|
|
-}
|
|
-
|
|
typedef struct _PyGSignalAccumulatorData {
|
|
PyObject *callable;
|
|
PyObject *user_data;
|
|
@@ -484,15 +477,14 @@ override_signal(GType instance_type, const gchar *signal_name)
|
|
}
|
|
|
|
static PyObject *
|
|
-add_signals (GType instance_type, PyObject *signals)
|
|
+add_signals (GObjectClass *klass, PyObject *signals)
|
|
{
|
|
gboolean ret = TRUE;
|
|
- GObjectClass *oclass;
|
|
Py_ssize_t pos = 0;
|
|
PyObject *key, *value, *overridden_signals = NULL;
|
|
+ GType instance_type = G_OBJECT_CLASS_TYPE (klass);
|
|
|
|
overridden_signals = PyDict_New();
|
|
- oclass = g_type_class_ref(instance_type);
|
|
while (PyDict_Next(signals, &pos, &key, &value)) {
|
|
const gchar *signal_name;
|
|
gchar *signal_name_canon, *c;
|
|
@@ -530,7 +522,6 @@ add_signals (GType instance_type, PyObject *signals)
|
|
if (!ret)
|
|
break;
|
|
}
|
|
- g_type_class_unref(oclass);
|
|
if (ret)
|
|
return overridden_signals;
|
|
else {
|
|
@@ -800,14 +791,12 @@ pyg_param_spec_from_object (PyObject *tuple)
|
|
}
|
|
|
|
static gboolean
|
|
-add_properties (GType instance_type, PyObject *properties)
|
|
+add_properties (GObjectClass *klass, PyObject *properties)
|
|
{
|
|
gboolean ret = TRUE;
|
|
- GObjectClass *oclass;
|
|
Py_ssize_t pos = 0;
|
|
PyObject *key, *value;
|
|
|
|
- oclass = g_type_class_ref(instance_type);
|
|
while (PyDict_Next(properties, &pos, &key, &value)) {
|
|
const gchar *prop_name;
|
|
GType prop_type;
|
|
@@ -873,7 +862,7 @@ add_properties (GType instance_type, PyObject *properties)
|
|
Py_DECREF(slice);
|
|
|
|
if (pspec) {
|
|
- g_object_class_install_property(oclass, 1, pspec);
|
|
+ g_object_class_install_property(klass, 1, pspec);
|
|
} else {
|
|
PyObject *type, *value, *traceback;
|
|
ret = FALSE;
|
|
@@ -883,7 +872,7 @@ add_properties (GType instance_type, PyObject *properties)
|
|
g_snprintf(msg, 256,
|
|
"%s (while registering property '%s' for GType '%s')",
|
|
PYGLIB_PyUnicode_AsString(value),
|
|
- prop_name, g_type_name(instance_type));
|
|
+ prop_name, G_OBJECT_CLASS_NAME(klass));
|
|
Py_DECREF(value);
|
|
value = PYGLIB_PyUnicode_FromString(msg);
|
|
}
|
|
@@ -892,11 +881,63 @@ add_properties (GType instance_type, PyObject *properties)
|
|
}
|
|
}
|
|
|
|
- g_type_class_unref(oclass);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
+pyg_object_class_init(GObjectClass *class, PyObject *py_class)
|
|
+{
|
|
+ PyObject *gproperties, *gsignals, *overridden_signals;
|
|
+ PyObject *class_dict = ((PyTypeObject*) py_class)->tp_dict;
|
|
+
|
|
+ class->set_property = pyg_object_set_property;
|
|
+ class->get_property = pyg_object_get_property;
|
|
+
|
|
+ /* install signals */
|
|
+ /* we look this up in the instance dictionary, so we don't
|
|
+ * accidentally get a parent type's __gsignals__ attribute. */
|
|
+ gsignals = PyDict_GetItemString(class_dict, "__gsignals__");
|
|
+ if (gsignals) {
|
|
+ if (!PyDict_Check(gsignals)) {
|
|
+ PyErr_SetString(PyExc_TypeError,
|
|
+ "__gsignals__ attribute not a dict!");
|
|
+ return;
|
|
+ }
|
|
+ if (!(overridden_signals = add_signals(class, gsignals))) {
|
|
+ return;
|
|
+ }
|
|
+ if (PyDict_SetItemString(class_dict, "__gsignals__",
|
|
+ overridden_signals)) {
|
|
+ return;
|
|
+ }
|
|
+ Py_DECREF(overridden_signals);
|
|
+
|
|
+ PyDict_DelItemString(class_dict, "__gsignals__");
|
|
+ } else {
|
|
+ PyErr_Clear();
|
|
+ }
|
|
+
|
|
+ /* install properties */
|
|
+ /* we look this up in the instance dictionary, so we don't
|
|
+ * accidentally get a parent type's __gproperties__ attribute. */
|
|
+ gproperties = PyDict_GetItemString(class_dict, "__gproperties__");
|
|
+ if (gproperties) {
|
|
+ if (!PyDict_Check(gproperties)) {
|
|
+ PyErr_SetString(PyExc_TypeError,
|
|
+ "__gproperties__ attribute not a dict!");
|
|
+ return;
|
|
+ }
|
|
+ if (!add_properties(class, gproperties)) {
|
|
+ return;
|
|
+ }
|
|
+ PyDict_DelItemString(class_dict, "__gproperties__");
|
|
+ /* Borrowed reference. Py_DECREF(gproperties); */
|
|
+ } else {
|
|
+ PyErr_Clear();
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
pyg_register_class_init(GType gtype, PyGClassInitFunc class_init)
|
|
{
|
|
GSList *list;
|
|
@@ -1068,7 +1109,7 @@ pygobject__g_instance_init(GTypeInstance *instance,
|
|
*/
|
|
static void
|
|
pyg_type_add_interfaces(PyTypeObject *class, GType instance_type,
|
|
- PyObject *bases, gboolean new_interfaces,
|
|
+ PyObject *bases,
|
|
GType *parent_interfaces, guint n_parent_interfaces)
|
|
{
|
|
int i;
|
|
@@ -1082,7 +1123,6 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type,
|
|
guint k;
|
|
PyObject *base = PyTuple_GET_ITEM(bases, i);
|
|
GType itype;
|
|
- gboolean is_new = TRUE;
|
|
const GInterfaceInfo *iinfo;
|
|
GInterfaceInfo iinfo_copy;
|
|
|
|
@@ -1099,16 +1139,6 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type,
|
|
if (!G_TYPE_IS_INTERFACE(itype))
|
|
continue;
|
|
|
|
- for (k = 0; k < n_parent_interfaces; ++k) {
|
|
- if (parent_interfaces[k] == itype) {
|
|
- is_new = FALSE;
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if ((new_interfaces && !is_new) || (!new_interfaces && is_new))
|
|
- continue;
|
|
-
|
|
iinfo = pyg_lookup_interface_info(itype);
|
|
if (!iinfo) {
|
|
gchar *error;
|
|
@@ -1129,7 +1159,7 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type,
|
|
int
|
|
pyg_type_register(PyTypeObject *class, const char *type_name)
|
|
{
|
|
- PyObject *gtype, *gsignals, *gproperties, *overridden_signals;
|
|
+ PyObject *gtype;
|
|
GType parent_type, instance_type;
|
|
GType *parent_interfaces;
|
|
guint n_parent_interfaces;
|
|
@@ -1216,88 +1246,22 @@ pyg_type_register(PyTypeObject *class, const char *type_name)
|
|
}
|
|
|
|
/*
|
|
- * Note: Interfaces to be implemented are searched twice. First
|
|
- * we register interfaces that are already implemented by a parent
|
|
- * type. The second time, the remaining interfaces are
|
|
- * registered, i.e. the ones that are not implemented by a parent
|
|
- * type. In between these two loops, properties and signals are
|
|
- * registered. It has to be done this way, in two steps,
|
|
- * otherwise glib will complain. If registering all interfaces
|
|
- * always before properties, you get an error like:
|
|
- *
|
|
- * ../gobject:121: Warning: Object class
|
|
- * test_interface+MyObject doesn't implement property
|
|
- * 'some-property' from interface 'TestInterface'
|
|
- *
|
|
- * If, on the other hand, you register interfaces after
|
|
- * registering the properties, you get something like:
|
|
- *
|
|
- * ../gobject:121: Warning: cannot add interface type
|
|
- * `TestInterface' to type `test_interface+MyUnknown', since
|
|
- * type `test_interface+MyUnknown' already conforms to
|
|
- * interface
|
|
- *
|
|
- * This looks like a GLib quirk, but no bug has been filed
|
|
- * upstream. However we have a unit test for this particular
|
|
- * problem, which can be found in test_interfaces.py, class
|
|
- * TestInterfaceImpl.
|
|
+ * Note, all interfaces need to be registered before the first
|
|
+ * g_type_class_ref(), see bug #686149.
|
|
*
|
|
* See also comment above pyg_type_add_interfaces().
|
|
*/
|
|
- pyg_type_add_interfaces(class, instance_type, class->tp_bases, FALSE,
|
|
+ pyg_type_add_interfaces(class, instance_type, class->tp_bases,
|
|
parent_interfaces, n_parent_interfaces);
|
|
|
|
- /* we look this up in the instance dictionary, so we don't
|
|
- * accidentally get a parent type's __gsignals__ attribute. */
|
|
- gsignals = PyDict_GetItemString(class->tp_dict, "__gsignals__");
|
|
- if (gsignals) {
|
|
- if (!PyDict_Check(gsignals)) {
|
|
- PyErr_SetString(PyExc_TypeError,
|
|
- "__gsignals__ attribute not a dict!");
|
|
- g_free(parent_interfaces);
|
|
- return -1;
|
|
- }
|
|
- if (!(overridden_signals = add_signals(instance_type, gsignals))) {
|
|
- g_free(parent_interfaces);
|
|
- return -1;
|
|
- }
|
|
- if (PyDict_SetItemString(class->tp_dict, "__gsignals__",
|
|
- overridden_signals)) {
|
|
- g_free(parent_interfaces);
|
|
- return -1;
|
|
- }
|
|
- Py_DECREF(overridden_signals);
|
|
- } else {
|
|
- PyErr_Clear();
|
|
- }
|
|
|
|
- /* we look this up in the instance dictionary, so we don't
|
|
- * accidentally get a parent type's __gsignals__ attribute. */
|
|
- gproperties = PyDict_GetItemString(class->tp_dict, "__gproperties__");
|
|
- if (gproperties) {
|
|
- if (!PyDict_Check(gproperties)) {
|
|
- PyErr_SetString(PyExc_TypeError,
|
|
- "__gproperties__ attribute not a dict!");
|
|
- g_free(parent_interfaces);
|
|
- return -1;
|
|
- }
|
|
- if (!add_properties(instance_type, gproperties)) {
|
|
- g_free(parent_interfaces);
|
|
- return -1;
|
|
- }
|
|
- PyDict_DelItemString(class->tp_dict, "__gproperties__");
|
|
- /* Borrowed reference. Py_DECREF(gproperties); */
|
|
- } else {
|
|
- PyErr_Clear();
|
|
+ gclass = g_type_class_ref(instance_type);
|
|
+ if (PyErr_Occurred() != NULL) {
|
|
+ g_type_class_unref(gclass);
|
|
+ g_free(parent_interfaces);
|
|
+ return -1;
|
|
}
|
|
|
|
- /* Register new interfaces, that are _not_ already defined by
|
|
- * the parent type. FIXME: See above.
|
|
- */
|
|
- pyg_type_add_interfaces(class, instance_type, class->tp_bases, TRUE,
|
|
- parent_interfaces, n_parent_interfaces);
|
|
-
|
|
- gclass = g_type_class_ref(instance_type);
|
|
if (pyg_run_class_init(instance_type, gclass, class)) {
|
|
g_type_class_unref(gclass);
|
|
g_free(parent_interfaces);
|
|
@@ -1306,9 +1270,8 @@ pyg_type_register(PyTypeObject *class, const char *type_name)
|
|
g_type_class_unref(gclass);
|
|
g_free(parent_interfaces);
|
|
|
|
- if (gsignals)
|
|
- PyDict_DelItemString(class->tp_dict, "__gsignals__");
|
|
-
|
|
+ if (PyErr_Occurred() != NULL)
|
|
+ return -1;
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
1.8.3.2
|
|
|