Canonical Voices

Posts tagged with 'pygobject'

pitti

This announcement comes very late (a week after release), but better late than never..

The first PyGObject 3.3 series release is now out, with lots of yummy fixes and improvements. Dieter, Sebastian, and I went through a round of bugzilla spring cleaning to clean up old bugs, fix simple bugs, and apply good patches that were waiting, so as a result the patch queue is now almost empty and PyGObject works better than ever.

There was also quite some work on the test suite: it became a lot stricter and robust, and now also enforces PEP8 compatibility and absence of pyflake errors of the code.

One small but handy new feature is that the freeze_notify() and handler_block() methods are now context managers, i. e. they automatically call the corresponding thaw_notify()/handler_unblock() at the end of the with statement in an exception-safe way. ((#672324)

There are almost no API changes in this release, so it should work fine with GNOME 3.4 and applications developed with pygobject 3.2. The one exception is the removal of the Gobject.get_data() and Gobject.set_data() methods. They were prone to errors and crashes as they are not safely bindable, and in Python you can and should just use normal Python object attributes instead.

Complete list of changes:

  • GSettings: allow extra keyword arguments (Giovanni Campagna) (#675105)
  • pygtkcompat: Correct Userlist module use (Jose Rostagno) (#675084)
  • Add release-news make rule (Martin Pitt)
  • Add “make check.nemiver” target (Martin Pitt)
  • Test flags and enums in GHash values (Martin Pitt) (#637466)
  • tests: Activate test_hash_in and apply workaround (Martin Pitt) (#666636)
  • Add special case for Gdk.Atom array entries from Python (Martin Pitt) (#661709)
  • test_gdbus: Call GetConnectionUnixProcessID() with correct signature (Martin Pitt) (#667954)
  • Add test case for Gtk.ListStore custom sort (Martin Pitt) (#674475)
  • GTK overrides: Add missing keyword arguments (Martin Pitt) (#660018)
  • Add missing override for TreeModel.iter_previous() (Martin Pitt) (#660018)
  • pygi-convert.py: Drop obsolete drag method conversions (Martin Pitt) (#652860)
  • tests: Replace deprecated assertEquals() with assertEqual() (Martin Pitt)
  • Plug tiny leak in constant_info_get_value (Paolo Borelli) (#642754)
  • Fix len_arg_index for array arguments (Bastian Winkler) (#674271)
  • Support defining GType properties from Python (Martin Pitt) (#674351)
  • Handle GType properties correctly (Bastian Winkler) (#674351)
  • Add missing GObject.TYPE_GTYPE (Martin Pitt)
  • Fix test_mainloop.py for Python 3 (Martin Pitt)
  • Make callback exception propagation test stricter (Martin Pitt) (#616279)
  • Add context management to freeze_notify() and handler_block(). (Simon Feltman) (#672324)
  • Add support for GFlags properties (Martin Pitt) (#620943)
  • Wrap GLib.Source.is_destroyed() method (Martin Pitt) (#524719)
  • Fix error message when trying to override a non-GI class (Martin Pitt) (#646667)
  • Fix segfault when accessing __grefcount__ before creating the GObject (Steve Frécinaux) (#640434)
  • Do not bind gobject_get_data() and gobject_set_data() (Steve Frécinaux) (#641944)
  • Add test case for multiple GLib.MainLoop instances (Martin Pitt) (#663068)
  • Add a ccallback type which is used to invoke callbacks passed to a vfunc (John (J5) Palmieri) (#644926)
  • Regression test: marshalling GValues in GHashTable (Alberto Mardegan) (#668903)
  • Update .gitignore (Martin Pitt)
  • Fix “distcheck” and tests with out-of-tree builds (Martin Pitt)
  • Add a pep8 check to the makefile (Johan Dahlin) (#672627)
  • PEP8 whitespace fixes (Johan Dahlin) (#672627)
  • PEP8: Remove trailing ; (Johan Dahlin) (#672627)
  • tests: Replace deprecated Python API (Martin Pitt)
  • Fail tests if they use or encounter deprecations (Martin Pitt)
  • Do not run tests in two phases any more (Martin Pitt)
  • test_overrides: Find local gsettings schema with current glib (Martin Pitt)
  • Add GtkComboBoxEntry compatibility (Paolo Borelli) (#672589)
  • Correct review comments from Martin (Johan Dahlin) (#672578)
  • Correct pyflakes warnings/errors (Johan Dahlin) (#672578)
  • Make tests fail on CRITICAL logs, too, and apply to all tests (Martin Pitt)
  • Support marshalling GI_TYPE_TAG_INTERFACE (Alberto Mardegan) (#668903)
  • Fix warnings on None values in added tree/list store rows (Martin Pitt) (#672463)
  • pygtkcompat test: Properly clean up PixbufLoader (Martin Pitt)

Read more
pitti

I just released a new pygobject version 3.1.92, for this week’s GNOME 3.3.92. This was my first-ever GNOME release (yay!), so please bear with me.

One highlight of this release is the new pygtkcompat module, contributed by Johan Dahlin. It provides backwards compatibility to pygtk far beyond to what the Gtk overrrides do, and also includes some shims for the old static webkit, gudev, and other modules. You can, and have to, enable them individually:

import gi.pygtkcompat

# enable "gobject" and "glib" modules
gi.pygtkcompat.enable()
gi.pygtkcompat.enable_gtk(version='3.0')

import glib
import gtk

Now you can use gtk.Window(), glib.timeout_add() etc. as before, and these will be transparently be converted into their modern GI counterparts. Please note that this is still in its infancy, and also mostly meant to ease the porting to GI. It’s not something we’ll keep forever.

Thanks to Michel Dänzer this release now also works properly on big-endian machines.

I mostly worked on fixing the calls of methods which take a list of GValues as arguments, such as Gtk.ListStore.insert_with_valuesv() and similar functions, and made the override API for tree models (append() etc. with providing row data) atomic wrt. the signals it sends out.

I want to thank Johan and Paolo for the nice teamwork with reviewing each other’s patches. That’s open source at its best!

Complete list of changes:

  • Correct Gtk.TreePath.__iter__ to work with Python 3 (Johan Dahlin)
  • Fix test_everything.TestSignals.test_object_param_signal test case (Martin Pitt)
  • Add a PyGTK compatibility layer (Johan Dahlin)
  • pygtkcompat: Remove first argument for get_origin() (Johan Dahlin)
  • Fix pygtkcompat.py to work with Python 3 (Martin Pitt)
  • GtkViewport: Add a default values for the adjustment constructor parameters (Johan Dahlin)
  • GtkIconSet: Add a default value for the pixbuf constructor parameter (Johan Dahlin)
  • PangoLayout: Add a default value for set_markup() (Johan Dahlin)
  • Gtk[HV]Scrollbar: Add a default value for the adjustment constructor parameter (Johan Dahlin)
  • GtkToolButton: Add a default value for the stock_id constructor parameter (Johan Dahlin)
  • GtkIconView: Add a default value for the model constructor parameter (Johan Dahlin)
  • Add a default value for column in Gtk.TreeView.get_cell_area() (Johan Dahlin)
  • Atomic inserts in Gtk.{List,Tree}Store overrides (Martin Pitt)
  • Fix Gtk.Button constructor to accept use_stock parameter (Martin Pitt)
  • Correct bad rebase, remove duplicate Window (Johan Dahlin)
  • Add bw-compatible arguments to Gtk.Adjustment (Johan Dahlin)
  • GtkTreePath: make it iterable (Johan Dahlin)
  • Add a default argument to TreeModelFilter.set_visible_func() (Johan Dahlin)
  • Add a default argument to Gtk.TreeView.set_cursor (Johan Dahlin)
  • Add a default argument to Pango.Context.get_metrics() (Johan Dahlin)
  • Fix double-freeing GValues in arrays (Martin Pitt)
  • Renamed “property” class to “Property” (Simon Feltman)
  • Fix Python to C marshalling of GValue arrays (Martin Pitt)
  • Correct the Gtk.Window hierarchy (Johan Dahlin)
  • Renamed getter/setter instance attributes to fget/fset respectively. (Simon Feltman)
  • Add Gtk.Arrow/Gtk.Window constructor override (Johan Dahlin)
  • Fix marshalling to/from Python to work on big endian machines. (Michel Dänzer)
  • Use gi_cclosure_marshal_generic instead of duplicating it. (Michel Dänzer)
  • Override Gtk.TreeView.get_visible_range to fix return (René Stadler)
  • Plug memory leak in _is_union_member (Paolo Borelli)
  • tests: Split TestInterfaces into separate tests (Sebastian Pölsterl)
  • README: Update current maintainers (Martin Pitt)

Read more
mandel

Yesterday I was working on a small UI that uses a WebKit.WebView to show certain information to the user. My idea yesterday was to try and show a native context menu on the view that does not have the default menu items that the WebView has, the only way I’ve found to this is a as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from gi.repository import GObject, Gdk, Gtk, WebKit
from utils import get_data_file
 
 
class CustomView(Gtk.EventBox):
    """Main window used to show the ui and generate signals."""
 
    def __init__(self):
        """Create a new instance."""
        super(CustomView, self).__init__()
        self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
        self._create_context_menu()
        self.scroll = Gtk.ScrolledWindow()
        self.scroll.show()
        self.view = WebKit.WebView()
        self.view.show()
        self.scroll.add(self.view)
        # load the html used for the main window, from that point
        # on we will let the html and js do the work and raise
        # signals via the title
        self.view.open(get_data_file(MAIN_WINDOW_HMTL))
        # lets no use the webkit context menu
        settings = self.view.get_settings()
        settings.set_property('enable-default-context-menu',
                              False)
        self.view.set_settings(settings)
        self.add(self.scroll)
        # connect the on button pressed event of the event box
        # so that we can add a context menu
        self.connect('button_press_event', self._on_button_press_event)
 
    def _create_context_menu(self):
        """Create the context menu."""
        self.menu = Gtk.Menu()
        delete_menu = Gtk.MenuItem("Delete Task")
        self.menu.append(delete_menu)
 
    def _on_button_press_event(self, widget, event):
        """Deal with the button press event."""
        if event.button == 3:
            self.menu.popup(None, None, None, None, event.button, event.time)
            self.menu.show_all()

Does any one out there know a better way to do this. I know that there is a “populate-popup” signal I can listen to but I cannot get my head around on how to do exactly what I want, which is remove all defaul menu items and add my own. And, does it make sense to have to do that for every popup signal?

Read more
pitti

As a followup action to my recent Talk about PyGI I now re-used my notes to provide some real wiki documentation.

It would be great if you could add package name info for Fedora/SUSE/etc., and perhaps add more example links for porting different kinds of software! Please also let me know if you have suggestions how to improve the structure of the page.

Read more
pitti

(Update: Link to Tomeu’s blog post, repost for planet.gnome.org)

Last week I was in Prague to attend the GNOME/Python 2011 Hackfest for gobject-introspection, to which Tomeu Vizoso kindly invited me after I started working with PyGI some months ago. It happened at a place called brmlab which was quite the right environment for a bunch of 9 hackers: Some comfy couches and chairs, soldering irons, lots of old TV tubes, chips, and other electronics, a big Pirate flag, really good Wifi, plenty of Club Mate and Coke supplies, and not putting unnecessary effort into mundane things like wallpapers.

It was really nice to get to know the upstream experts John (J5) Palmieri and Tomeu Vizoso (check out Tomeu’s blog post for his summary and some really nice photos). When sitting together in a room, fully focussing on this area for a full week, it’s so much easier to just ask them about something and getting things done and into upstream than on IRC or bugzilla, where you don’t know each other personally. I certainly learned a lot this week (and not only how great Czech beer tastes :-) )!

So what did I do?

Application porting

After already having ported four Ubuntu PyGTK applications to GI before (apport, jockey, aptdaemon, and language-selector),
my main goal and occupation during this week was to start porting a bigger PyGTK application. I picked system-config-printer, as it’s two magnitudes bigger than the previous projects, exercises quite a lot more of the GTK GI bindings, and thus also exposes a lot more GTK annotation and pygobject bugs. This resulted in a new pygi s-c-p branch which has the first 100 rounds of “test, break, fix” iterations. It now at least starts, and you can do a number of things with it, but a lot of functionality is still broken.

As a kind of “finger exercise” and also to check for how well pygi-convert works for small projects now, I also ported computer-janitor. This went really well (I had it working after about 30 minutes), and also led me to finally fixing the unicode vs. str mess for GtkTreeView that you got so far with Python 2.x.

pygobject and GTK fixes

Porting system-config-printer and computer-janitor uncovered a lot of opportunities to improve pygi-convert.sh, a big “perl -e” kind of script to do the mechanical grunt work of the porting process. It doesn’t fix up changed signatures (such as adding missing arguments which were default arguments in PyGTK, or the ubiquitous “user_data” argument for signal handlers), but at least it gets a lot of namespaces, method, and constant names right.

I also fixed three annotation fixes in GTK+. We also collaboratively reviewed and tested Pavel’s annotation branch which helped to fix tons of problems, especially after Steve Frécinaux’s excellent reference leak fix, so if you play around with current pygobject git head, you really also have to use the current GTK+ git head.

Speaking of which, if you want to port applications and always stay on top of the pygobject/GTK development without having to clutter your package system with “make install”s of those, it works very well to have this in your ~/.bashrc:

export GI_TYPELIB_PATH=$HOME/projects/gtk/gtk:$HOME/projects/gtk/gdk
export PYTHONPATH=$HOME/projects/pygobject

Better GVariant/GDBus support

The GNOME world is moving from the old dbus-glib python bindings to GDBus, which is integrated into GLib. However, dbus-python exposed a really nice and convenient way of doing D-Bus calls, while using GDBus from Python was hideously complicated, especially for nontrivial arguments with empty or nested arrays:

from gi.repository import Gio, GLib
from gi._gi import variant_type_from_string

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

vb = GLib.VariantBuilder()
vb.init(variant_type_from_string('r'))
vb.add_value(GLib.Variant('s', 'test'))
vb.add_value(GLib.Variant('u', 1))
vb.add_value(GLib.Variant('s', 'gtk-ok'))
vb.add_value(GLib.Variant('s', 'Hello World!'))
vb.add_value(GLib.Variant('s', 'Subtext'))
# add an empty array
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('as'))
vb.add_value(eavb.end())
# add an empty dict
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('a{sv}'))
vb.add_value(eavb.end())
vb.add_value(GLib.Variant('i', 10000))
args = vb.end()

result = notify.call_sync('Notify', args, 0, -1, None)
id = result.get_child_value(0).get_uint32()
print id

So I went to making the GLib.Variant constructor work properly with nested types and boxed variants, adding Pythonic GVariant iterators and indexing (so that you can treat GVariant dictionaries/arrays/tuples just like their Python equivalents), and finally a Variant.unpack() method for converting the return value of a D-Bus call back into a native Python data type. This looks a lot friendlier now:

from gi.repository import Gio, GLib

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

args = GLib.Variant('(susssasa{sv}i)', ('test', 1, 'gtk-ok', 'Hello World!',
    'Subtext', [], {}, 10000))
result = notify.call_sync('Notify', args, 0, -1, None)
id = result.unpack()[0]
print id

I also prepared another patch in GNOME#640181 which will provide the icing on the cake, i. e. handle the variant building/unpacking transparently and make the explicit call_sync() unnecessary:

from gi.repository import Gio, GLib

d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
    '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)

result = notify.Notify('(susssasa{sv}i)', 'test', 1, 'gtk-ok', 'Hello World!',
            'Subtext', [], {}, 10000)
print result[0]

I hope that I can get this reviewed and land this soon.

Thanks to our sponsors!

Many thanks to the GNOME Foundation and Collabora for sponsoring this event!

Read more