After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 722387 - Deprecate ability to derive from GLib.Source
Deprecate ability to derive from GLib.Source
Status: RESOLVED OBSOLETE
Product: pygobject
Classification: Bindings
Component: introspection
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2014-01-17 00:25 UTC by Simon Feltman
Modified: 2018-01-10 20:36 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Simon Feltman 2014-01-17 00:25:33 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
Comment 1 Simon Feltman 2014-01-17 00:38:27 UTC
Added skipped test:
https://git.gnome.org/browse/pygobject/commit/?id=df21dbb
Comment 2 GNOME Infrastructure Team 2018-01-10 20:36:35 UTC
-- 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.