GNOME Bugzilla – Bug 722387
Deprecate ability to derive from GLib.Source
Last modified: 2018-01-10 20:36:35 UTC
The GLib.Source static bindings [1] suffer a memory management problem where sources can be added to a main context, free'd from Python, and then subsequently break. The problem can be observed as follows: #### class MySource(GLib.Source): def prepare(self) ... def add_my_source(): source = MySource() source.attach() add_my_source() GLib.MainContext.default().iteration() #### In the C world, this is a valid technique because source.attach will add a reference to the GSource tying it to the main context. The main context then owns the GSource after code in add_my_source unrefs it (implicitly in Python). Currently however, the GSource remains alive and owned by the main context as expected, but the Python source instance held by it dies. The static GSource binding will then attempt to call the Python source functions on an invalid PyObject. We could add a ref to the PyObject held by the GSource, but this creates a circular reference leaking both the PyObject and the GSource (finalize will never be called). There is really no way around this in terms of a GLib/Python binding setup when using a pattern of inheritance with GLib.Source and callback methods (this is exactly what toggle refs solve with GObjects). A way around the problems could be to use a pattern of explicitly setting the callback functions for custom sources: GLib.Source.new_with_py_funcs(prepare, check, dispatch, finalize) In this case, the GSource can hold strong references to each of the functions and avoid a circular reference with the GSource and a Python sub-class because individual functions would not hold references to the GSource. We could then deprecate deriving from GLib.Source (but keep it for compatibility). Overrides mockup: #### gi/overrides/GLib.py class Source(GLib.Source): def __new__(cls): if cls != Source and issubclass(cls, Source): warnings.warn(...) cls.new_from_py_funcs(cls.prepare, cls.check, cls.dispatch, cls.finalize) #### https://git.gnome.org/browse/pygobject/tree/gi/pygi-source.c?id=3.11.4
Added skipped test: https://git.gnome.org/browse/pygobject/commit/?id=df21dbb
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pygobject/issues/63.