1 |
tetromino 13/10/02 17:15:46 |
2 |
|
3 |
Added: pygobject-2.28.6-glib-2.36-class_init.patch |
4 |
Log: |
5 |
Fix class interface setup to be compatible with glib-2.36. Remove old alternatives symlink removal hack since it fails badly with binpkgs (bug #459180, thanks to Fabio Erculiani). |
6 |
|
7 |
(Portage version: 2.2.7/cvs/Linux x86_64, signed Manifest commit with key CF0ADD61) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 dev-python/pygobject/files/pygobject-2.28.6-glib-2.36-class_init.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pygobject/files/pygobject-2.28.6-glib-2.36-class_init.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-python/pygobject/files/pygobject-2.28.6-glib-2.36-class_init.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: pygobject-2.28.6-glib-2.36-class_init.patch |
16 |
=================================================================== |
17 |
From 9456ba70fdb98b3a4eb7ee2f630182387a54ca00 Mon Sep 17 00:00:00 2001 |
18 |
From: Martin Pitt <martinpitt@×××××.org> |
19 |
Date: Tue, 19 Feb 2013 15:39:56 +0100 |
20 |
Subject: [PATCH] Move property and signal creation into _class_init() |
21 |
|
22 |
We must not add class interfaces after g_type_class_ref() has been called the |
23 |
first time. Move signal and property creation from pyg_type_register() into |
24 |
pyg_object_class_init(), and drop the hack of registering interfaces twice. |
25 |
|
26 |
This is a backport of commit efcb0f9fd for 2.28.x. This allows old pygtk |
27 |
applications to work with pygobject 2.28.x and glib 2.35.x. |
28 |
|
29 |
https://bugzilla.gnome.org/show_bug.cgi?id=694108 |
30 |
--- |
31 |
gobject/gobjectmodule.c | 177 +++++++++++++++++++----------------------------- |
32 |
1 file changed, 70 insertions(+), 107 deletions(-) |
33 |
|
34 |
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c |
35 |
index 2a84606..91f7315 100644 |
36 |
--- a/gobject/gobjectmodule.c |
37 |
+++ b/gobject/gobjectmodule.c |
38 |
@@ -312,13 +312,6 @@ pyg_object_get_property (GObject *object, guint property_id, |
39 |
pyglib_gil_state_release(state); |
40 |
} |
41 |
|
42 |
-static void |
43 |
-pyg_object_class_init(GObjectClass *class, PyObject *py_class) |
44 |
-{ |
45 |
- class->set_property = pyg_object_set_property; |
46 |
- class->get_property = pyg_object_get_property; |
47 |
-} |
48 |
- |
49 |
typedef struct _PyGSignalAccumulatorData { |
50 |
PyObject *callable; |
51 |
PyObject *user_data; |
52 |
@@ -484,15 +477,14 @@ override_signal(GType instance_type, const gchar *signal_name) |
53 |
} |
54 |
|
55 |
static PyObject * |
56 |
-add_signals (GType instance_type, PyObject *signals) |
57 |
+add_signals (GObjectClass *klass, PyObject *signals) |
58 |
{ |
59 |
gboolean ret = TRUE; |
60 |
- GObjectClass *oclass; |
61 |
Py_ssize_t pos = 0; |
62 |
PyObject *key, *value, *overridden_signals = NULL; |
63 |
+ GType instance_type = G_OBJECT_CLASS_TYPE (klass); |
64 |
|
65 |
overridden_signals = PyDict_New(); |
66 |
- oclass = g_type_class_ref(instance_type); |
67 |
while (PyDict_Next(signals, &pos, &key, &value)) { |
68 |
const gchar *signal_name; |
69 |
gchar *signal_name_canon, *c; |
70 |
@@ -530,7 +522,6 @@ add_signals (GType instance_type, PyObject *signals) |
71 |
if (!ret) |
72 |
break; |
73 |
} |
74 |
- g_type_class_unref(oclass); |
75 |
if (ret) |
76 |
return overridden_signals; |
77 |
else { |
78 |
@@ -800,14 +791,12 @@ pyg_param_spec_from_object (PyObject *tuple) |
79 |
} |
80 |
|
81 |
static gboolean |
82 |
-add_properties (GType instance_type, PyObject *properties) |
83 |
+add_properties (GObjectClass *klass, PyObject *properties) |
84 |
{ |
85 |
gboolean ret = TRUE; |
86 |
- GObjectClass *oclass; |
87 |
Py_ssize_t pos = 0; |
88 |
PyObject *key, *value; |
89 |
|
90 |
- oclass = g_type_class_ref(instance_type); |
91 |
while (PyDict_Next(properties, &pos, &key, &value)) { |
92 |
const gchar *prop_name; |
93 |
GType prop_type; |
94 |
@@ -873,7 +862,7 @@ add_properties (GType instance_type, PyObject *properties) |
95 |
Py_DECREF(slice); |
96 |
|
97 |
if (pspec) { |
98 |
- g_object_class_install_property(oclass, 1, pspec); |
99 |
+ g_object_class_install_property(klass, 1, pspec); |
100 |
} else { |
101 |
PyObject *type, *value, *traceback; |
102 |
ret = FALSE; |
103 |
@@ -883,7 +872,7 @@ add_properties (GType instance_type, PyObject *properties) |
104 |
g_snprintf(msg, 256, |
105 |
"%s (while registering property '%s' for GType '%s')", |
106 |
PYGLIB_PyUnicode_AsString(value), |
107 |
- prop_name, g_type_name(instance_type)); |
108 |
+ prop_name, G_OBJECT_CLASS_NAME(klass)); |
109 |
Py_DECREF(value); |
110 |
value = PYGLIB_PyUnicode_FromString(msg); |
111 |
} |
112 |
@@ -892,11 +881,63 @@ add_properties (GType instance_type, PyObject *properties) |
113 |
} |
114 |
} |
115 |
|
116 |
- g_type_class_unref(oclass); |
117 |
return ret; |
118 |
} |
119 |
|
120 |
static void |
121 |
+pyg_object_class_init(GObjectClass *class, PyObject *py_class) |
122 |
+{ |
123 |
+ PyObject *gproperties, *gsignals, *overridden_signals; |
124 |
+ PyObject *class_dict = ((PyTypeObject*) py_class)->tp_dict; |
125 |
+ |
126 |
+ class->set_property = pyg_object_set_property; |
127 |
+ class->get_property = pyg_object_get_property; |
128 |
+ |
129 |
+ /* install signals */ |
130 |
+ /* we look this up in the instance dictionary, so we don't |
131 |
+ * accidentally get a parent type's __gsignals__ attribute. */ |
132 |
+ gsignals = PyDict_GetItemString(class_dict, "__gsignals__"); |
133 |
+ if (gsignals) { |
134 |
+ if (!PyDict_Check(gsignals)) { |
135 |
+ PyErr_SetString(PyExc_TypeError, |
136 |
+ "__gsignals__ attribute not a dict!"); |
137 |
+ return; |
138 |
+ } |
139 |
+ if (!(overridden_signals = add_signals(class, gsignals))) { |
140 |
+ return; |
141 |
+ } |
142 |
+ if (PyDict_SetItemString(class_dict, "__gsignals__", |
143 |
+ overridden_signals)) { |
144 |
+ return; |
145 |
+ } |
146 |
+ Py_DECREF(overridden_signals); |
147 |
+ |
148 |
+ PyDict_DelItemString(class_dict, "__gsignals__"); |
149 |
+ } else { |
150 |
+ PyErr_Clear(); |
151 |
+ } |
152 |
+ |
153 |
+ /* install properties */ |
154 |
+ /* we look this up in the instance dictionary, so we don't |
155 |
+ * accidentally get a parent type's __gproperties__ attribute. */ |
156 |
+ gproperties = PyDict_GetItemString(class_dict, "__gproperties__"); |
157 |
+ if (gproperties) { |
158 |
+ if (!PyDict_Check(gproperties)) { |
159 |
+ PyErr_SetString(PyExc_TypeError, |
160 |
+ "__gproperties__ attribute not a dict!"); |
161 |
+ return; |
162 |
+ } |
163 |
+ if (!add_properties(class, gproperties)) { |
164 |
+ return; |
165 |
+ } |
166 |
+ PyDict_DelItemString(class_dict, "__gproperties__"); |
167 |
+ /* Borrowed reference. Py_DECREF(gproperties); */ |
168 |
+ } else { |
169 |
+ PyErr_Clear(); |
170 |
+ } |
171 |
+} |
172 |
+ |
173 |
+static void |
174 |
pyg_register_class_init(GType gtype, PyGClassInitFunc class_init) |
175 |
{ |
176 |
GSList *list; |
177 |
@@ -1068,7 +1109,7 @@ pygobject__g_instance_init(GTypeInstance *instance, |
178 |
*/ |
179 |
static void |
180 |
pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, |
181 |
- PyObject *bases, gboolean new_interfaces, |
182 |
+ PyObject *bases, |
183 |
GType *parent_interfaces, guint n_parent_interfaces) |
184 |
{ |
185 |
int i; |
186 |
@@ -1082,7 +1123,6 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, |
187 |
guint k; |
188 |
PyObject *base = PyTuple_GET_ITEM(bases, i); |
189 |
GType itype; |
190 |
- gboolean is_new = TRUE; |
191 |
const GInterfaceInfo *iinfo; |
192 |
GInterfaceInfo iinfo_copy; |
193 |
|
194 |
@@ -1099,16 +1139,6 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, |
195 |
if (!G_TYPE_IS_INTERFACE(itype)) |
196 |
continue; |
197 |
|
198 |
- for (k = 0; k < n_parent_interfaces; ++k) { |
199 |
- if (parent_interfaces[k] == itype) { |
200 |
- is_new = FALSE; |
201 |
- break; |
202 |
- } |
203 |
- } |
204 |
- |
205 |
- if ((new_interfaces && !is_new) || (!new_interfaces && is_new)) |
206 |
- continue; |
207 |
- |
208 |
iinfo = pyg_lookup_interface_info(itype); |
209 |
if (!iinfo) { |
210 |
gchar *error; |
211 |
@@ -1129,7 +1159,7 @@ pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, |
212 |
int |
213 |
pyg_type_register(PyTypeObject *class, const char *type_name) |
214 |
{ |
215 |
- PyObject *gtype, *gsignals, *gproperties, *overridden_signals; |
216 |
+ PyObject *gtype; |
217 |
GType parent_type, instance_type; |
218 |
GType *parent_interfaces; |
219 |
guint n_parent_interfaces; |
220 |
@@ -1216,88 +1246,22 @@ pyg_type_register(PyTypeObject *class, const char *type_name) |
221 |
} |
222 |
|
223 |
/* |
224 |
- * Note: Interfaces to be implemented are searched twice. First |
225 |
- * we register interfaces that are already implemented by a parent |
226 |
- * type. The second time, the remaining interfaces are |
227 |
- * registered, i.e. the ones that are not implemented by a parent |
228 |
- * type. In between these two loops, properties and signals are |
229 |
- * registered. It has to be done this way, in two steps, |
230 |
- * otherwise glib will complain. If registering all interfaces |
231 |
- * always before properties, you get an error like: |
232 |
- * |
233 |
- * ../gobject:121: Warning: Object class |
234 |
- * test_interface+MyObject doesn't implement property |
235 |
- * 'some-property' from interface 'TestInterface' |
236 |
- * |
237 |
- * If, on the other hand, you register interfaces after |
238 |
- * registering the properties, you get something like: |
239 |
- * |
240 |
- * ../gobject:121: Warning: cannot add interface type |
241 |
- * `TestInterface' to type `test_interface+MyUnknown', since |
242 |
- * type `test_interface+MyUnknown' already conforms to |
243 |
- * interface |
244 |
- * |
245 |
- * This looks like a GLib quirk, but no bug has been filed |
246 |
- * upstream. However we have a unit test for this particular |
247 |
- * problem, which can be found in test_interfaces.py, class |
248 |
- * TestInterfaceImpl. |
249 |
+ * Note, all interfaces need to be registered before the first |
250 |
+ * g_type_class_ref(), see bug #686149. |
251 |
* |
252 |
* See also comment above pyg_type_add_interfaces(). |
253 |
*/ |
254 |
- pyg_type_add_interfaces(class, instance_type, class->tp_bases, FALSE, |
255 |
+ pyg_type_add_interfaces(class, instance_type, class->tp_bases, |
256 |
parent_interfaces, n_parent_interfaces); |
257 |
|
258 |
- /* we look this up in the instance dictionary, so we don't |
259 |
- * accidentally get a parent type's __gsignals__ attribute. */ |
260 |
- gsignals = PyDict_GetItemString(class->tp_dict, "__gsignals__"); |
261 |
- if (gsignals) { |
262 |
- if (!PyDict_Check(gsignals)) { |
263 |
- PyErr_SetString(PyExc_TypeError, |
264 |
- "__gsignals__ attribute not a dict!"); |
265 |
- g_free(parent_interfaces); |
266 |
- return -1; |
267 |
- } |
268 |
- if (!(overridden_signals = add_signals(instance_type, gsignals))) { |
269 |
- g_free(parent_interfaces); |
270 |
- return -1; |
271 |
- } |
272 |
- if (PyDict_SetItemString(class->tp_dict, "__gsignals__", |
273 |
- overridden_signals)) { |
274 |
- g_free(parent_interfaces); |
275 |
- return -1; |
276 |
- } |
277 |
- Py_DECREF(overridden_signals); |
278 |
- } else { |
279 |
- PyErr_Clear(); |
280 |
- } |
281 |
|
282 |
- /* we look this up in the instance dictionary, so we don't |
283 |
- * accidentally get a parent type's __gsignals__ attribute. */ |
284 |
- gproperties = PyDict_GetItemString(class->tp_dict, "__gproperties__"); |
285 |
- if (gproperties) { |
286 |
- if (!PyDict_Check(gproperties)) { |
287 |
- PyErr_SetString(PyExc_TypeError, |
288 |
- "__gproperties__ attribute not a dict!"); |
289 |
- g_free(parent_interfaces); |
290 |
- return -1; |
291 |
- } |
292 |
- if (!add_properties(instance_type, gproperties)) { |
293 |
- g_free(parent_interfaces); |
294 |
- return -1; |
295 |
- } |
296 |
- PyDict_DelItemString(class->tp_dict, "__gproperties__"); |
297 |
- /* Borrowed reference. Py_DECREF(gproperties); */ |
298 |
- } else { |
299 |
- PyErr_Clear(); |
300 |
+ gclass = g_type_class_ref(instance_type); |
301 |
+ if (PyErr_Occurred() != NULL) { |
302 |
+ g_type_class_unref(gclass); |
303 |
+ g_free(parent_interfaces); |
304 |
+ return -1; |
305 |
} |
306 |
|
307 |
- /* Register new interfaces, that are _not_ already defined by |
308 |
- * the parent type. FIXME: See above. |
309 |
- */ |
310 |
- pyg_type_add_interfaces(class, instance_type, class->tp_bases, TRUE, |
311 |
- parent_interfaces, n_parent_interfaces); |
312 |
- |
313 |
- gclass = g_type_class_ref(instance_type); |
314 |
if (pyg_run_class_init(instance_type, gclass, class)) { |
315 |
g_type_class_unref(gclass); |
316 |
g_free(parent_interfaces); |
317 |
@@ -1306,9 +1270,8 @@ pyg_type_register(PyTypeObject *class, const char *type_name) |
318 |
g_type_class_unref(gclass); |
319 |
g_free(parent_interfaces); |
320 |
|
321 |
- if (gsignals) |
322 |
- PyDict_DelItemString(class->tp_dict, "__gsignals__"); |
323 |
- |
324 |
+ if (PyErr_Occurred() != NULL) |
325 |
+ return -1; |
326 |
return 0; |
327 |
} |
328 |
|
329 |
-- |
330 |
1.8.3.2 |