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 694604 - Non-introspected signals do not marshal foreign types
Non-introspected signals do not marshal foreign types
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: introspection
unspecified
Other Mac OS
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
: 726856 (view as bug list)
Depends on: 707735
Blocks:
 
 
Reported: 2013-02-24 17:30 UTC by jessevdk@gmail.com
Modified: 2014-05-06 03:52 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Simple example exposing the issue (1.79 KB, application/x-xz-compressed-tar)
2013-02-25 08:40 UTC, jessevdk@gmail.com
  Details
ctypes hack (1.35 KB, text/x-python)
2013-02-25 12:30 UTC, Simon Feltman
  Details
Move pygi foreign API into pygi-foreign-api.h (18.35 KB, patch)
2014-03-24 03:34 UTC, Simon Feltman
committed Details | Review
Add cairo marshaling support for non-introspected signals (19.16 KB, patch)
2014-03-24 03:34 UTC, Simon Feltman
none Details | Review
Add cairo marshaling support for non-introspected signals (21.27 KB, patch)
2014-03-24 03:36 UTC, Simon Feltman
reviewed Details | Review
Initialize the foreign API at PyGI load time (2.49 KB, patch)
2014-05-06 03:27 UTC, Simon Feltman
committed Details | Review
tests: Move cairo tests into test_cairo.py (6.10 KB, patch)
2014-05-06 03:29 UTC, Simon Feltman
committed Details | Review
Add cairo marshaling support for non-introspected signals (12.06 KB, patch)
2014-05-06 03:52 UTC, Simon Feltman
committed Details | Review

Description jessevdk@gmail.com 2013-02-24 17:30:28 UTC
pygobject currently does not seem to marshal foreign types in signal handlers which are not introspectable. One example where I hit this issue is the "draw" event of the cairooverlay gst element (see  http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-cairooverlay.html).

Is it not possible to also marshal foreign types in signals which are not introspected? At least for cairo.Context, it seems possible since there is a gobject type (CAIRO_GOBJECT_TYPE_CONTEXT) used in signals?
Comment 1 Simon Feltman 2013-02-25 05:31:49 UTC
Can you provide a minimal example which demonstrates the problem? This might also be related to bug 694233.
Comment 2 Simon Feltman 2013-02-25 06:35:05 UTC
This might also be related to bug 666862
Comment 3 jessevdk@gmail.com 2013-02-25 08:40:29 UTC
Created attachment 237338 [details]
Simple example exposing the issue

I've attached a simple example exposing the issue mentioned.
Comment 4 Simon Feltman 2013-02-25 10:21:17 UTC
Thanks. Verified. It seems like this could be possible but very difficult. I am planning an attempt to unify marshaling code paths post 3.8 and will keep this in mind. It should also be considered if support is added for custom marshalers described in bug 686261.

I guess the GstCairoOverlay has no introspection typelib and this is why it is a problem?
Comment 5 jessevdk@gmail.com 2013-02-25 10:27:35 UTC
Indeed. This holds generally for any software which uses a similar dynamic plugin type of system, although I guess it will not occur a lot. That said, it would be nice to have good support for gstreamer in pygobject. Thanks for looking into it.
Comment 6 Simon Feltman 2013-02-25 12:30:34 UTC
Created attachment 237351 [details]
ctypes hack

You could hack it with ctypes, but this might not be portable and could break in the future. We might eventually expose a pointer attribute for boxed types as a capsule which might work better.
Comment 7 jessevdk@gmail.com 2013-02-25 12:38:05 UTC
Yes I thought about that, but it seemed a bit fragile to take the context id + offset as a pointer to the boxed cairo_t*. In the end I went with a small C extension which does the same, but then just uses pygobject and pycairo.
Comment 8 Mark Howell 2014-02-28 22:26:19 UTC
(In reply to comment #6)

Thanks for this hack Simon, works for me with py(2)cairo and cairooverlay element from GStreamer 1.2.3.

Portability/fragility concerns noted.
Comment 9 Allison Karlitskaya (desrt) 2014-03-22 04:28:46 UTC
*** Bug 726856 has been marked as a duplicate of this bug. ***
Comment 10 Simon Feltman 2014-03-22 05:34:25 UTC
Looking into this a bit deeper, it turns out to be fairly trivial to fix. Notes on a potential approach:

* Add a dependency to cairo-gobject [1] in the PyGObject _gi_cairo module [2].
* In the module init of pygi-foreign-cairo.c [3], register a GValue marshaler using "pyg_register_gtype_custom" [4] with simple converters, similar to what it is already doing for foreign marshaling.

[1] http://cgit.freedesktop.org/cairo/tree/util/cairo-gobject
[2] https://git.gnome.org/browse/pygobject/tree/gi/Makefile.am?id=3.11.92#n138
[3] https://git.gnome.org/browse/pygobject/tree/gi/pygi-foreign-cairo.c
[4] https://git.gnome.org/browse/pygobject/tree/gi/pygtype.c?id=3.11.92#n631
Comment 11 Simon Feltman 2014-03-24 03:34:37 UTC
Created attachment 272720 [details] [review]
Move pygi foreign API into pygi-foreign-api.h

Move only APIs necessary for registering foreign marshalers into pygi-foreign-api.h
Remove "_real" from unused foreign APIs and add necessary includes to the rest of
pygobject for calling these APIs directly.
This is needed to avoid compilation problems when including pygobject.h in a foreign
marshaling plugin which conflicts with pygobject-private.h, causing an inability to
use the pygobject API from foreign marshaling plugins.
Comment 12 Simon Feltman 2014-03-24 03:34:39 UTC
Created attachment 272721 [details] [review]
Add cairo marshaling support for non-introspected signals

Add link dependency of cairo-gobject to _gi_cairo_la needed for retrieving
the GTypes of cairo classes.
Always initialize foreign marshaling list at gi import time. This allows
direct importing of gi._gi_cairo needed to bootstrap new GValue marshalers.
Add GValue marshalers for cairo Context, Surface, FontFace, ScaledFont,
and Pattern classes.
Add override for CairoGObject (gi.repository.cairo) which bootstraps the
cairo foreign marshaling plugin needed to install the GValue marshalers.
Move all cairo related unittests into new tests/test_cairo.py file and
add non-introspected signal marshaling tests.
Comment 13 Simon Feltman 2014-03-24 03:36:28 UTC
Created attachment 272722 [details] [review]
Add cairo marshaling support for non-introspected signals

(added missed file)
Comment 14 Simon Feltman 2014-05-05 20:31:28 UTC
Review of attachment 272720 [details] [review]:

::: gi/pygi-foreign-cairo.c
@@ +32,3 @@
 #endif
 
+#include <cairo-gobject.h>

This is a mistake that should go in the next patch.

@@ +36,2 @@
+/* Limit PyGObject includes to externally usable APIs since _gi_cairo is
+ * built as a separate shared library.

Clarify this comment.
Comment 15 Simon Feltman 2014-05-05 20:37:50 UTC
Review of attachment 272722 [details] [review]:

(self review)

::: gi/overrides/cairo.py
@@ +40,3 @@
+ScaledFont = CairoGObject.ScaledFont
+Surface = CairoGObject.Surface
+image_surface_create = CairoGObject.image_surface_create

Not sure we need to do all this, I think importing gi._gi_cairo should load the necessary GTypes...

::: tests/test_cairo.py
@@ +7,3 @@
+try:
+    import cairo
+    from gi.repository import cairo as CairoGObject

It is unfortunate if this is really needed. Perhaps a new technique needs to be looked at which can bootstrap the foreign lib automatically...

::: tests/test_everything.py
@@ -48,3 @@
 class TestEverything(unittest.TestCase):
 
-    def test_cairo_context(self):

Moving these tests should go in a separate patch applied before this one.
Comment 16 Simon Feltman 2014-05-05 23:01:31 UTC
Review of attachment 272722 [details] [review]:

::: tests/test_cairo.py
@@ +7,3 @@
+try:
+    import cairo
+    from gi.repository import cairo as CairoGObject

As noted in g_irepository_find_by_gtype [1] it is not possible to deduce the GI namespace of a GType if the GI repository is not loaded. In this particular case, we have a signal without introspection information passing a CairoGObjectContext to PyGI without gi.repository.cairo being loaded.

I think a cleaner approach would be to use the "gi.require_foreign" API from bug 707735 which loads the appropriate GI repository.

So instead of:
  import cairo
  from gi.repository import cairo as CairoGObject

We would have:
  import cairo
  gi.require_foreign('cairo')

At which point we don't need to cairo overrides hack.

[1] https://developer.gnome.org/gi/stable/GIRepository.html#g-irepository-find-by-gtype
Comment 17 Simon Feltman 2014-05-05 23:18:37 UTC
Comment on attachment 272720 [details] [review]
Move pygi foreign API into pygi-foreign-api.h

Attachment 272720 [details] pushed as def4714 - Move pygi foreign API into pygi-foreign-api.h
Comment 18 Simon Feltman 2014-05-06 03:26:58 UTC
The following fix has been pushed:
31ecd93 Initialize the foreign API at PyGI load time
Comment 19 Simon Feltman 2014-05-06 03:27:02 UTC
Created attachment 275929 [details] [review]
Initialize the foreign API at PyGI load time

Initialize the foreign struct list at gi._gi module load time. This ensures
we always have a valid (non-null) list of foreign marshalers outside of the
context of marshaling.
Comment 20 Simon Feltman 2014-05-06 03:29:06 UTC
The following fix has been pushed:
4ee91a4 tests: Move cairo tests into test_cairo.py
Comment 21 Simon Feltman 2014-05-06 03:29:09 UTC
Created attachment 275930 [details] [review]
tests: Move cairo tests into test_cairo.py

Move cairo related tests from test_everything.py into test_cairo.py
Comment 22 Simon Feltman 2014-05-06 03:49:19 UTC
The following fix has been pushed:
de827d0 Add cairo marshaling support for non-introspected signals

Notes:
Beyond the added tests which round trip non-introspected cairo
objects through signals, the following has also been verified
to bootstrap cairo GI for non-introspected foreign marshaling:
    gi.require_foreign('cairo')
or
    from gi.repository import cairo as CairoGObject

gi.require_foreign is preferred.
Comment 23 Simon Feltman 2014-05-06 03:51:59 UTC
The following fix has been pushed:
de827d0 Add cairo marshaling support for non-introspected signals
Comment 24 Simon Feltman 2014-05-06 03:52:03 UTC
Created attachment 275933 [details] [review]
Add cairo marshaling support for non-introspected signals

Add link dependency of cairo-gobject to _gi_cairo_la needed for retrieving
the GTypes of cairo classes.
Add GValue marshalers for cairo Context, Surface, FontFace, ScaledFont,
and Pattern classes.