Imported Upstream version 3.1.0 46/138246/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:38:27 +0000 (08:38 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:38:29 +0000 (08:38 +0900)
Change-Id: I7ba3a430bce4104bf4e8ff695f0582bdc450560a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
27 files changed:
ChangeLog
NEWS
PKG-INFO
configure
configure.ac
gi/_glib/pygiochannel.c
gi/_glib/pyglib.c
gi/_glib/pyglib.h
gi/_glib/pygmainloop.c
gi/_gobject/gobjectmodule.c
gi/_gobject/pygobject.c
gi/gimodule.c
gi/overrides/GLib.py
gi/overrides/Gtk.py
gi/pygi-argument.c
gi/pygi-closure.c
gi/pygi-foreign-cairo.c
gi/pygi-marshal-cleanup.c
gi/pygi-marshal-from-py.c
gi/pygi-marshal-to-py.c
gi/pygi-property.c
tests/Makefile.am
tests/Makefile.in
tests/runtests-windows.py [new file with mode: 0644]
tests/test_everything.py
tests/test_gi.py
tests/test_overrides.py

index 9a645e7..a02ea05 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-commit e65d2fe75310a478e09eef1ab942ece09516d7d9
+commit 8ac474c15199ca00c729a73af9c926172657b842
 Author: Sebastian Pölsterl <sebp@k-d-w.org>
-Date:   Thu Feb 9 10:02:14 2012 +0100
+Date:   Mon Feb 6 19:11:52 2012 +0100
 
-    Prepare 3.0.4 release
+    Prepare 3.1.0 release
 
- NEWS |    5 +++++
- 1 files changed, 5 insertions(+), 0 deletions(-)
+ NEWS |   34 ++++++++++++++++++++++++++++++++++
+ 1 files changed, 34 insertions(+), 0 deletions(-)
 
-commit f24b5a4306fb83f6ff46920ecd7adc201d105b16
-Author: Martin Pitt <martin.pitt@ubuntu.com>
-Date:   Sat Jan 7 09:47:24 2012 +0100
+commit 18996ae455fb01a1e53a3826f0a1e79d06097c5b
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Mon Feb 6 19:04:41 2012 +0100
+
+    Updated DOAP file to only include people currently actively working
+    on the project
+
+    Removed obsolete MAINTAINERS file
+
+ MAINTAINERS    |   19 -------------------
+ pygobject.doap |   44 +++++++++++++++-----------------------------
+ 2 files changed, 15 insertions(+), 48 deletions(-)
+
+commit 0285e107be581c4d594127dc06cd05df1f02fb3f
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Mon Feb 6 18:57:01 2012 +0100
 
     Revert "Convert all strings to utf-8 encoding when retrieving from
     TreeModel"
 
-    This changes existing behaviour (model values being str instead of
-    unicode) and
-    also makes tree model behaviour incompatible to the rest of Gtk
-    behaviour
-    (which always returns UTF-8 encoded str objects, not unicode). The
-    original bug
-    description was a bug in the test case code, you cannot mix str
-    and unicode
-    objects in interpolation.
-
-    This reverts commit 33060639bc4857238f21c2329b8e8888fbd8fdc2.
+    This reverts commit 654711d0f940d7480d0f1cdb25a3dc9996f7a706.
 
-    https://bugzilla.gnome.org/show_bug.cgi?id=663610
+    Due to this commit breaking backwards compatability, we decided to
+    revert this change
 
  gi/overrides/Gtk.py     |   15 ---------------
  tests/compathelper.py   |    2 --
  tests/test_overrides.py |   31 +------------------------------
  3 files changed, 1 insertions(+), 47 deletions(-)
 
-commit cba8124389de92f98c45cbaf2bd9c320036d6407
-Author: Tomeu Vizoso <tomeu.vizoso@collabora.com>
-Date:   Fri Dec 23 12:20:15 2011 +0100
+commit 0e921cd26ed5a6e3bc6ef5f553e8b22b862d72a6
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Sun Feb 5 13:47:10 2012 +0100
 
-    Post-release bump to 3.0.4
+    tests: Fixed issues with python3
 
- configure.ac |    2 +-
+ tests/test_gi.py |    9 ++++++---
+ 1 files changed, 6 insertions(+), 3 deletions(-)
+
+commit ee62df4d2fc0cc63c2f29d3ad9b47b875dbd5f89
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Sun Feb 5 11:59:51 2012 +0100
+
+    Properly distinguish between different integer types for properties
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=664150
+
+ gi/pygi-property.c |   48 ++++++++++++++++++++++++++++++++++++---
+ tests/test_gi.py   |   62
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 106 insertions(+), 4 deletions(-)
+
+commit c329bf2aee8d75ce452638db75e09197ff2b9b65
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Sun Feb 5 11:46:21 2012 +0100
+
+    Distinguish between GArray and GPtrArray when cleaning up
+
+    This fixes a crash in test_gi.TestGPtrArray and makes sure
+    memory is free'd correctly
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=669393
+
+ gi/pygi-marshal-cleanup.c |   32 +++++++++++++++++++++++---------
+ 1 files changed, 23 insertions(+), 9 deletions(-)
+
+commit 4ea37c606f67df843788261b2c8acd6bac4c1e0c
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Sun Feb 5 18:51:53 2012 +0100
+
+    Add null_gerror_callback unit test
+
+    This models the case where the callback is successful and does not set
+    an error.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=669415
+
+ tests/test_everything.py |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+commit a41984780ee49dcf02c718ca1be87bba747472e5
+Author: Martin Pitt <martin.pitt@ubuntu.com>
+Date:   Mon Feb 6 09:34:28 2012 +0100
+
+    pyglib_error_check: Re-add missing NULL check
+
+    Commit adcfe96d49b09bc accidentally dropped the check if *error is
+    NULL, i. e.
+    any error is actually set. Due to that, pyglib_error_check()
+    always returned
+    TRUE. Reintroduce the check.
+
+    Thanks to Alberto Mardegan for spotting this!
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=669415
+
+ gi/_glib/pyglib.c |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+commit 2c797c17913999379e277788d5e4cce8d68cebb0
+Author: Michael Culbertson <michael.culbertson@gmail.com>
+Date:   Sat Feb 4 16:11:34 2012 +0100
+
+    Add tests/runtests-windows.py to source tarball
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=663288
+
+ tests/Makefile.am |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+commit d6a899cdf70e978534326155e3fad75a705f4b20
+Author: Sebastian Pölsterl <sebp@k-d-w.org>
+Date:   Sat Feb 4 15:55:55 2012 +0100
+
+    Don't issue a depreciation warning for GtkDialog's NO_SEPARATOR flag,
+    even when unused
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=665553
+
+ gi/overrides/Gtk.py |    6 ++----
+ 1 files changed, 2 insertions(+), 4 deletions(-)
+
+commit 534ec71c575a279ff1c05da20a8858bb1145b4d0
+Author: Nirbheek Chauhan <nirbheek@gentoo.org>
+Date:   Sat Feb 4 15:42:36 2012 +0100
+
+    Fix bool() operations on GLib.Variant objects
+
+    Defines __nonzero__ (python2) and __bool__ (python3) for GLib.Variant
+
+    Also adds some tests for boolean comparisons.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=647723
+
+ gi/overrides/GLib.py    |   18 ++++++++++++++++++
+ tests/test_overrides.py |   45
+ +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 0 deletions(-)
+
+commit 8d6a127df5dd1e5f26faeba8f977074b4496b24f
+Author: Nirbheek Chauhan <nirbheek@gentoo.org>
+Date:   Sat Feb 4 15:41:08 2012 +0100
+
+    Fix hash() and __eq__() for GLib.Variant objects
+
+    Define __hash__, __eq__, __ne__ for GLib.Variant so that objects can
+    be used in sets, dicts, and can be compared using == and != easily.
+
+    Also adds some tests for this.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=647725
+
+ gi/overrides/GLib.py    |   23 +++++++++++++++++++
+ tests/test_overrides.py |   56
+ +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 79 insertions(+), 0 deletions(-)
+
+commit f82404034be042bf2026bbb7f1e33b11d6e17a6f
+Author: Martin Pitt <martin.pitt@ubuntu.com>
+Date:   Wed Jan 25 07:01:06 2012 +0100
+
+    Fix method names of callback tests
+
+    Change test_everything.TestCallbacks.* test names from camelCase
+    to the
+    standard PEP-8 underscore_style. This is now consistent with all
+    other test
+    case names.
+
+ tests/test_everything.py |   30 +++++++++++++++---------------
+ 1 files changed, 15 insertions(+), 15 deletions(-)
+
+commit e37ee78fbf0aa72159a40da4165a26bea065faf1
+Author: Will Thompson <will.thompson@collabora.co.uk>
+Date:   Mon Jan 23 13:10:30 2012 +0000
+
+    Cairo: add missing braces around array-of-struct definition
+
+    This triggered a -Wmissing-braces warning.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=668497
+
+ gi/pygi-foreign-cairo.c |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
-commit 9ba741343e79f0d108074c0110f1aada5f7da4a3
-Merge: 3306063 8d1a36c
+commit db24865d6b60351d72f5b8f47103d6d0a6c63b2e
+Author: Will Thompson <will.thompson@collabora.co.uk>
+Date:   Mon Jan 23 13:06:41 2012 +0000
+
+    g_instance_init: cast to PyGObject * as needed
+
+    This squashes a compiler warning.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=668497
+
+ gi/_gobject/gobjectmodule.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+commit a8408cfd68cd5e7cdb0b8a83e107d9a0d828e4bd
+Author: Will Thompson <will.thompson@collabora.co.uk>
+Date:   Mon Jan 23 13:01:27 2012 +0000
+
+    Fix a few set-but-not-used warnings.
+
+    In a couple of cases, the variable in question was set to a value
+    spelled out again later in the function.
+
+    The 'sequence_cache' variable is re-declared five lines below.
+
+    The return value of 'read' was previously completely ignored. The
+    'gssize ret' variable was in fact added to squash an unused-result
+    warning.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=668497
+
+ gi/_glib/pygiochannel.c   |    2 +-
+ gi/_glib/pygmainloop.c    |    3 +--
+ gi/_gobject/pygobject.c   |    2 +-
+ gi/pygi-marshal-cleanup.c |    2 --
+ 4 files changed, 3 insertions(+), 6 deletions(-)
+
+commit 29a30490ed51e347e8f57d2bf9af69400734eee8
+Author: Stefano Facchini <stefano.facchini@gmail.com>
+Date:   Thu Jan 19 18:09:07 2012 +0100
+
+    pygmainloop: allow for extra arguments in 'quit' method
+
+    To allow for the common syntax:
+
+        object.connect('signal-name', main_loop.quit)
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=668288
+
+ gi/_glib/pygmainloop.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 557a61c12c01137a0d7c679c4b053973df09d445
+Author: Alexandre Rostovtsev <tetromino@gentoo.org>
+Date:   Mon Dec 26 00:44:56 2011 -0500
+
+    Fix bytearray test compatibility with python3
+
+    https://bugs.gentoo.org/show_bug.cgi?id=321879
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=666852
+
+ tests/test_gi.py |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit d69e5b3c7bdb9113382fd125c256b12bff4c24d2
+Author: Alberto Mardegan <mardy@users.sourceforge.net>
+Date:   Mon Jan 23 12:37:26 2012 +0200
+
+    Respect transfer-type when demarshalling GErrors
+
+    The marshaller previously ignored "transfer full" on GError*
+    arguments, causing
+    crashes due to double-freeing them. This causes the
+    testCallbackUserdata() test
+    case to crash after the previous GError/GHashTable marshalling fix.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=666270
+
+ gi/pygi-argument.c |   12 +++++++++++-
+ 1 files changed, 11 insertions(+), 1 deletions(-)
+
+commit 77f32d9110bfeb6dad8457f565b4c70b5998fef6
+Author: Alberto Mardegan <mardy@users.sourceforge.net>
+Date:   Thu Dec 15 16:12:01 2011 +0200
+
+    Support GHashTable and GError as callback/closure arguments
+
+    Marshalling of these types from C is already implemented, let's
+    take it
+    into use for calbacks and closures too.
+
+    Add corresponding test cases.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=666270
+
+    Signed-off-by: Martin Pitt <martin.pitt@ubuntu.com>
+
+ gi/pygi-closure.c        |    2 ++
+ tests/test_everything.py |   35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+), 0 deletions(-)
+
+commit 4b9dc03d0e49e9a1f4bf0f2df503bdff00d13a2b
+Author: Will Thompson <will.thompson@collabora.co.uk>
+Date:   Mon Jan 23 13:56:02 2012 +0000
+
+    Don't leak when marshalling GErrors to C
+
+    Python-land GLib.GErrors are supposed to have three attributes:
+    "message", "domain" and "code". If those attributes are missing,
+    or they
+    have the wrong types, the C GError is filled in with a message
+    describing the error. The present-but-ill-typed code paths did not
+    DECREF the ill-typed values.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=666098
+
+ gi/_glib/pyglib.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+commit adcfe96d49b09bcc550653d73de196610fd5144d
+Author: Will Thompson <will.thompson@collabora.co.uk>
+Date:   Fri Jan 20 16:20:10 2012 +0000
+
+    Support functions which return GError
+
+    GStreamer has the following method:
+
+      void gst_message_parse_error (
+          GstMessage *message,
+          GError **error,
+          gchar **debug_message);
+
+    With this patch, we marshal the GError out parameter as a
+    GObject.GError
+    exception, but return it rather than throwing it. The test cases cover
+    two variations on the theme of the function above (one with (transfer
+    full), as in GStreamer, and another with (transfer none)) as well as a
+    function with return type GError *.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=666098
+
+ gi/_glib/pyglib.c       |   46
+ +++++++++++++++++++++++++++++++++++-----------
+ gi/_glib/pyglib.h       |    1 +
+ gi/pygi-marshal-to-py.c |   16 +++++++++++++---
+ tests/test_gi.py        |   32 ++++++++++++++++++++++++++++++++
+ 4 files changed, 81 insertions(+), 14 deletions(-)
+
+commit 09f003729eac9d553a208c343c2a14d253b77d9a
+Author: Alberto Mardegan <mardy@users.sourceforge.net>
+Date:   Mon Jan 23 12:42:21 2012 +0200
+
+    Fix indentation of _pygi_argument_to_object()
+
+    Side issue in https://bugzilla.gnome.org/show_bug.cgi?id=666270
+
+    Signed-off-by: Martin Pitt <martin.pitt@ubuntu.com>
+
+ gi/pygi-argument.c |   26 +++++++++++++-------------
+ 1 files changed, 13 insertions(+), 13 deletions(-)
+
+commit c71c010be01d706f90bc200194325fd82f4071b2
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Sat Jan 14 14:24:23 2012 +0100
+
+    Avoid C99 syntax.
+
+ gi/gimodule.c |   10 ++++++----
+ 1 files changed, 6 insertions(+), 4 deletions(-)
+
+commit c299d058c22385ececaec64c872d1dd1bc1ae17a
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Fri Jan 6 13:39:31 2012 +0100
+
+    Connect to first action of a radio group.
+
+ gi/overrides/Gtk.py |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+commit dee2f179037902a3883bd0e61ff1c350e1fd8a4f
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Wed Jan 4 16:40:51 2012 +0100
+
+    Use g_slist_free_full in pygi-closure.
+
+ gi/pygi-closure.c |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+commit 2bee4207ab6f07dc9c0952affe72f0e304cfb624
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Wed Jan 4 15:24:13 2012 +0100
+
+    Avoid O(n^2) behavior when marshalling lists
+
+    Appending requires walking the list every time: just prepend and
+    reverse
+    the list at the end.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=667261
+
+ gi/pygi-marshal-from-py.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+commit d68455e99b1a9ebba31209b17a11317b1958678b
+Author: Paolo Borelli <pborelli@gnome.org>
+Date:   Tue Jan 3 16:57:40 2012 +0100
+
+    Handle NULL as a valid case of a char** array
+
+    Treat NULL as an empty array and add the corresponding testcase
+
+ gi/pygi-marshal-to-py.c |    9 +++++----
+ tests/test_gi.py        |    3 +++
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+commit e3451b8e6018bb76e9992fb6af24a71725de5cfd
 Author: Tomeu Vizoso <tomeu.vizoso@collabora.com>
-Date:   Fri Dec 23 12:18:00 2011 +0100
+Date:   Fri Dec 23 12:01:43 2011 +0100
+
+    Branching, bump version to 3.1.0
 
-    Merge branch 'master' into pygobject-3-0
+ configure.ac |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
 
 commit 8d1a36cc73f5f4df091ecb289c8a7b38ec2ab605
 Author: Tomeu Vizoso <tomeu.vizoso@collabora.com>
@@ -118,28 +485,6 @@ Date:   Thu Dec 1 11:50:38 2011 -0300
  pygi-convert.sh |   14 ++++++++++++++
  1 files changed, 14 insertions(+), 0 deletions(-)
 
-commit 33060639bc4857238f21c2329b8e8888fbd8fdc2
-Author: Sebastian Pölsterl <sebp@k-d-w.org>
-Date:   Tue Nov 8 12:38:12 2011 +0100
-
-    Convert all strings to utf-8 encoding when retrieving from TreeModel
-
-    https://bugzilla.gnome.org/show_bug.cgi?id=663610
-
- gi/overrides/Gtk.py     |   15 +++++++++++++++
- tests/compathelper.py   |    2 ++
- tests/test_overrides.py |   31 ++++++++++++++++++++++++++++++-
- 3 files changed, 47 insertions(+), 1 deletions(-)
-
-commit c9884283153c38f5b200a19b9abfaf6d9e698818
-Author: Sebastian Pölsterl <sebp@k-d-w.org>
-Date:   Fri Nov 25 18:51:53 2011 +0100
-
-    Post release version bump
-
- configure.ac |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
 commit 654711d0f940d7480d0f1cdb25a3dc9996f7a706
 Author: Sebastian Pölsterl <sebp@k-d-w.org>
 Date:   Tue Nov 8 12:38:12 2011 +0100
diff --git a/NEWS b/NEWS
index b52e88f..afb1181 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,36 @@
-3.0.4   09-Feb-2012
-        - Revert "Convert all strings to utf-8 encoding when retrieving from TreeModel" (Martin Pitt)
+3.1.0   06-Feb-2012
+        - Updated DOAP file to only include people currently actively working on the project (Sebastian Pölsterl)
+        - Revert "Convert all strings to utf-8 encoding when retrieving from TreeModel" (Sebastian Pölsterl)
+        - tests: Fixed issues with python3 (Sebastian Pölsterl)
+        - Properly distinguish between different integer types for properties (Sebastian Pölsterl)
+        - Distinguish between GArray and GPtrArray when cleaning up (Sebastian Pölsterl)
+        - Add null_gerror_callback unit test (Paolo Borelli)
+        - pyglib_error_check: Re-add missing NULL check (Martin Pitt)
+        - Add tests/runtests-windows.py to source tarball (Michael Culbertson)
+        - Don't issue a depreciation warning for GtkDialog's NO_SEPARATOR flag, even when unused (Sebastian Pölsterl)
+        - Fix bool() operations on GLib.Variant objects (Nirbheek Chauhan)
+        - Fix hash() and __eq__() for GLib.Variant objects (Nirbheek Chauhan)
+        - Fix method names of callback tests (Martin Pitt)
+        - Cairo: add missing braces around array-of-struct definition (Will Thompson)
+        - g_instance_init: cast to PyGObject * as needed (Will Thompson)
+        - Fix a few set-but-not-used warnings. (Will Thompson)
+        - pygmainloop: allow for extra arguments in 'quit' method (Stefano Facchini)
+        - Fix bytearray test compatibility with python3 (Alexandre Rostovtsev)
+        - Respect transfer-type when demarshalling GErrors (Alberto Mardegan)
+        - Support GHashTable and GError as callback/closure arguments (Alberto Mardegan)
+        - Don't leak when marshalling GErrors to C (Will Thompson)
+        - Support functions which return GError (Will Thompson)
+        - Fix indentation of _pygi_argument_to_object() (Alberto Mardegan)
+        - Avoid C99 syntax. (Paolo Borelli)
+        - Connect to first action of a radio group. (Paolo Borelli)
+        - Use g_slist_free_full in pygi-closure. (Paolo Borelli)
+        - Avoid O(n^2) behavior when marshalling lists (Paolo Borelli)
+        - Handle NULL as a valid case of a char** array (Paolo Borelli)
+        - Branching, bump version to 3.1.0 (Tomeu Vizoso)
+        - Add notes about branching to HACKING (Tomeu Vizoso)
         - Fixed bug where GObject.property did not respect minimum and maximum values (Sebastian Pölsterl)
         - Remove mention of removed option --enable-docs (Tomeu Vizoso)
+        - Fix sebp's name in NEWS (Tomeu Vizoso)
 
 3.0.3   12-Dec-2011
         - Convert all modifier constants to Gdk.ModifierType (Manuel Quiñones)
index 96fc700..3bc50b1 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: PyGObject
-Version: 3.0.4
+Version: 3.1.0
 Summary: Python bindings for GObject
 Home-page: http://www.pygtk.org/
 Author: James Henstridge
@@ -8,7 +8,7 @@ Author-email: james@daa.com.au
 Maintainer: Johan Dahlin
 Maintainer-email: johan@gnome.org
 License: GNU LGPL
-Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.0/pygobject-3.0.4.tar.gz
+Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.1/pygobject-3.1.0.tar.gz
 Description: Python bindings for GLib and GObject
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
index aa023a5..5e92327 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for pygobject 3.0.4.
+# Generated by GNU Autoconf 2.68 for pygobject 3.1.0.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
 #
@@ -571,8 +571,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='pygobject'
 PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.0.4'
-PACKAGE_STRING='pygobject 3.0.4'
+PACKAGE_VERSION='3.1.0'
+PACKAGE_STRING='pygobject 3.1.0'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
 PACKAGE_URL=''
 
@@ -1359,7 +1359,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pygobject 3.0.4 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.1.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1429,7 +1429,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pygobject 3.0.4:";;
+     short | recursive ) echo "Configuration of pygobject 3.1.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1554,7 +1554,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pygobject configure 3.0.4
+pygobject configure 3.1.0
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1832,7 +1832,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pygobject $as_me 3.0.4, which was
+It was created by pygobject $as_me 3.1.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2191,14 +2191,14 @@ $as_echo "#define PYGOBJECT_MAJOR_VERSION 3" >>confdefs.h
 PYGOBJECT_MAJOR_VERSION=3
 
 
-$as_echo "#define PYGOBJECT_MINOR_VERSION 0" >>confdefs.h
+$as_echo "#define PYGOBJECT_MINOR_VERSION 1" >>confdefs.h
 
-PYGOBJECT_MINOR_VERSION=0
+PYGOBJECT_MINOR_VERSION=1
 
 
-$as_echo "#define PYGOBJECT_MICRO_VERSION 4" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 0" >>confdefs.h
 
-PYGOBJECT_MICRO_VERSION=4
+PYGOBJECT_MICRO_VERSION=0
 
 
 ac_config_headers="$ac_config_headers config.h"
@@ -2682,7 +2682,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pygobject'
- VERSION='3.0.4'
+ VERSION='3.1.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12018,7 +12018,7 @@ Usage: $0 [OPTIONS]
 Report bugs to <bug-libtool@gnu.org>."
 
 lt_cl_version="\
-pygobject config.lt 3.0.4
+pygobject config.lt 3.1.0
 configured by $0, generated by GNU Autoconf 2.68.
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -16727,7 +16727,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pygobject $as_me 3.0.4, which was
+This file was extended by pygobject $as_me 3.1.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16793,7 +16793,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-pygobject config.status 3.0.4
+pygobject config.status 3.1.0
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
index 20256ec..d7fb8a8 100644 (file)
@@ -11,8 +11,8 @@ m4_define(python3_min_ver, 3.1)
 
 dnl the pygobject version number
 m4_define(pygobject_major_version, 3)
-m4_define(pygobject_minor_version, 0)
-m4_define(pygobject_micro_version, 4)
+m4_define(pygobject_minor_version, 1)
+m4_define(pygobject_micro_version, 0)
 m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
 
 dnl versions of packages we require ...
index 4f77e28..3921cac 100644 (file)
@@ -477,7 +477,7 @@ py_io_channel_add_watch(PyObject *self, PyObject *args, PyObject *kwargs)
     data->user_data = user_data; Py_XINCREF(user_data);
     data->iochannel = self; Py_INCREF(self);
 
-    handler_id = g_io_add_watch_full(((PyGIOChannel *) self)->channel,
+    handler_id = g_io_add_watch_full(iochannel,
                                      priority, condition,
                                     pyg_iowatch_marshal, data,
                                     (GDestroyNotify) pyg_iowatch_data_free);
index f127fb4..40df53b 100644 (file)
@@ -233,30 +233,28 @@ pyglib_set_thread_block_funcs (PyGLibThreadBlockFunc block_threads_func,
     _PyGLib_API->unblock_threads = unblock_threads_func;
 }
 
-
 /**
- * pyglib_error_check:
+ * pyglib_error_marshal:
  * @error: a pointer to the GError.
  *
- * Checks to see if the GError has been set.  If the error has been
- * set, then the glib.GError Python exception will be raised, and
- * the GError cleared.
+ * Checks to see if @error has been set.  If @error has been set, then a
+ * GLib.GError Python exception object is returned (but not raised).
  *
- * Returns: True if an error was set.
+ * Returns: a GLib.GError Python exception object, or NULL.
  */
-gboolean
-pyglib_error_check(GError **error)
+PyObject *
+pyglib_error_marshal (GError **error)
 {
     PyGILState_STATE state;
     PyObject *exc_type;
     PyObject *exc_instance;
     PyObject *d;
 
-    g_return_val_if_fail(error != NULL, FALSE);
+    g_return_val_if_fail(error != NULL, NULL);
 
     if (*error == NULL)
-       return FALSE;
-    
+       return NULL;
+
     state = pyglib_gil_state_ensure();
 
     exc_type = _PyGLib_API->gerror_exception;
@@ -289,7 +287,35 @@ pyglib_error_check(GError **error)
     } else {
        PyObject_SetAttrString(exc_instance, "message", Py_None);
     }
+
+    pyglib_gil_state_release(state);
     
+    return exc_instance;
+}
+
+/**
+ * pyglib_error_check:
+ * @error: a pointer to the GError.
+ *
+ * Checks to see if the GError has been set.  If the error has been
+ * set, then the glib.GError Python exception will be raised, and
+ * the GError cleared.
+ *
+ * Returns: True if an error was set.
+ */
+gboolean
+pyglib_error_check(GError **error)
+{
+    PyGILState_STATE state;
+    PyObject *exc_instance;
+
+    g_return_val_if_fail(error != NULL, FALSE);
+    if (*error == NULL)
+       return FALSE;
+
+    state = pyglib_gil_state_ensure();
+
+    exc_instance = pyglib_error_marshal (error);
     PyErr_SetObject(_PyGLib_API->gerror_exception, exc_instance);
     Py_DECREF(exc_instance);
     g_clear_error(error);
@@ -339,6 +365,7 @@ pyglib_gerror_exception_check(GError **error)
     py_message = PyObject_GetAttrString(value, "message");
     if (!py_message || !PYGLIB_PyUnicode_Check(py_message)) {
         bad_gerror_message = "gi._glib.GError instances must have a 'message' string attribute";
+        Py_XDECREF(py_message);
         goto bad_gerror;
     }
 
@@ -346,6 +373,7 @@ pyglib_gerror_exception_check(GError **error)
     if (!py_domain || !PYGLIB_PyUnicode_Check(py_domain)) {
         bad_gerror_message = "gi._glib.GError instances must have a 'domain' string attribute";
         Py_DECREF(py_message);
+        Py_XDECREF(py_domain);
         goto bad_gerror;
     }
 
@@ -354,6 +382,7 @@ pyglib_gerror_exception_check(GError **error)
         bad_gerror_message = "gi._glib.GError instances must have a 'code' int attribute";
         Py_DECREF(py_message);
         Py_DECREF(py_domain);
+        Py_XDECREF(py_code);
         goto bad_gerror;
     }
 
index 44ead47..261af7b 100644 (file)
@@ -37,6 +37,7 @@ PyGILState_STATE pyglib_gil_state_ensure(void);
 void pyglib_gil_state_release(PyGILState_STATE state);
 int pyglib_enable_threads(void);
 gboolean pyglib_error_check(GError **error);
+PyObject *pyglib_error_marshal (GError **error);
 gboolean pyglib_gerror_exception_check(GError **error);
 PyObject *pyglib_register_exception_for_domain(gchar *name,
                                               gint error_domain);
index 43dcf92..5dabef6 100644 (file)
@@ -158,9 +158,8 @@ pyg_signal_watch_check(GSource *source)
     PySignalWatchSource *real_source = (PySignalWatchSource *)source;
     GPollFD *poll_fd = &real_source->fd;
     unsigned char dummy;
-    gssize ret;
     if (poll_fd->revents & G_IO_IN)
-       ret = read(poll_fd->fd, &dummy, 1);
+        (void) read(poll_fd->fd, &dummy, 1);
 #endif
 
     state = pyglib_gil_state_ensure();
@@ -315,7 +314,7 @@ _wrap_g_main_loop_is_running (PyGMainLoop *self)
 }
 
 static PyObject *
-_wrap_g_main_loop_quit (PyGMainLoop *self)
+_wrap_g_main_loop_quit (PyGMainLoop *self, PyObject *args, PyObject *kwargs)
 {
     g_main_loop_quit(self->loop);
     
@@ -346,7 +345,7 @@ _wrap_g_main_loop_run (PyGMainLoop *self)
 static PyMethodDef _PyGMainLoop_methods[] = {
     { "get_context", (PyCFunction)_wrap_g_main_loop_get_context, METH_NOARGS },
     { "is_running", (PyCFunction)_wrap_g_main_loop_is_running, METH_NOARGS },
-    { "quit", (PyCFunction)_wrap_g_main_loop_quit, METH_NOARGS },
+    { "quit", (PyCFunction)_wrap_g_main_loop_quit, METH_VARARGS|METH_KEYWORDS },
     { "run", (PyCFunction)_wrap_g_main_loop_run, METH_NOARGS },
     { NULL, NULL, 0 }
 };
index ac065a5..7ac31f6 100644 (file)
@@ -1070,7 +1070,7 @@ pygobject__g_instance_init(GTypeInstance   *instance,
         /* float the wrapper ref here because we are going to orphan it
          * so we don't destroy the wrapper. The next call to pygobject_new_full
          * will take the ref */
-        pygobject_ref_float (wrapper);
+        pygobject_ref_float ((PyGObject *) wrapper);
         args = PyTuple_New(0);
         kwargs = PyDict_New();
         if (Py_TYPE(wrapper)->tp_init(wrapper, args, kwargs))
index 0f0e5e2..8020b40 100644 (file)
@@ -1275,7 +1275,7 @@ pygobject_get_properties(PyGObject *self, PyObject *args)
 
         property_name = PYGLIB_PyUnicode_AsString(py_property);
 
-        pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj),
+        pspec = g_object_class_find_property(class,
                                         property_name);
         if (!pspec) {
            PyErr_Format(PyExc_TypeError,
index 873a56e..1961c17 100644 (file)
@@ -60,8 +60,9 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
     GIEnumInfo *info;
     gint n_values;
     GEnumValue *g_enum_values;
-    GType g_type;
+    int i;
     const gchar *type_name;
+    GType g_type;
 
     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                       "O:enum_add_make_new_gtype",
@@ -79,7 +80,7 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
     n_values = g_enum_info_get_n_values (info);
     g_enum_values = g_new0 (GEnumValue, n_values + 1);
 
-    for (int i=0; i < n_values; i++) {
+    for (i = 0; i < n_values; i++) {
         GIValueInfo *value_info;
         GEnumValue *enum_value;
         const gchar *name;
@@ -147,8 +148,9 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
     GIEnumInfo *info;
     gint n_values;
     GFlagsValue *g_flags_values;
-    GType g_type;
+    int i;
     const gchar *type_name;
+    GType g_type;
 
     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                       "O:flags_add_make_new_gtype",
@@ -166,7 +168,7 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
     n_values = g_enum_info_get_n_values (info);
     g_flags_values = g_new0 (GFlagsValue, n_values + 1);
 
-    for (int i=0; i < n_values; i++) {
+    for (i = 0; i < n_values; i++) {
         GIValueInfo *value_info;
         GFlagsValue *flags_value;
         const gchar *name;
index f3abe28..27fe017 100644 (file)
@@ -172,6 +172,24 @@ class Variant(GLib.Variant):
     def __repr__(self):
         return '<GLib.Variant(%s)>' % getattr(self, 'print')(True)
 
+    def __eq__(self, other):
+        try:
+            return self.equal(other)
+        except TypeError:
+            return False
+
+    def __ne__(self, other):
+        try:
+            return not self.equal(other)
+        except TypeError:
+            return True
+
+    def __hash__(self):
+        # We're not using just hash(self.unpack()) because otherwise we'll have
+        # hash collisions between the same content in different variant types,
+        # which will cause a performance issue in set/dict/etc.
+        return hash((self.get_type_string(), self.unpack()))
+
     def unpack(self):
         '''Decompose a GVariant into a native Python object.'''
 
@@ -277,6 +295,7 @@ class Variant(GLib.Variant):
     def __len__(self):
         if self.get_type_string() in ['s', 'o', 'g']:
             return len(self.get_string())
+        # Array, dict, tuple
         if self.get_type_string().startswith('a') or self.get_type_string().startswith('('):
             return self.n_children()
         raise TypeError('GVariant type %s does not have a length' % self.get_type_string())
@@ -314,6 +333,28 @@ class Variant(GLib.Variant):
 
         raise TypeError('GVariant type %s is not a container' % self.get_type_string())
 
+    #
+    # Pythonic bool operations
+    #
+    def __nonzero__(self):
+        return self.__bool__()
+
+    def __bool__(self):
+        if self.get_type_string() in ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']:
+            return self.unpack() != 0
+        if self.get_type_string() in ['b']:
+            return self.get_boolean()
+        if self.get_type_string() in ['s', 'o', 'g']:
+            return len(self.get_string()) != 0
+        # Array, dict, tuple
+        if self.get_type_string().startswith('a') or self.get_type_string().startswith('('):
+            return self.n_children() != 0
+        if self.get_type_string() in ['v']:
+            # unpack works recursively, hence bool also works recursively
+            return bool(self.unpack())
+        # Everything else is True
+        return True
+
     def keys(self):
         if not self.get_type_string().startswith('a{'):
             return TypeError, 'GVariant type %s is not a dictionary' % self.get_type_string()
index 7945cc8..1d0cb49 100644 (file)
@@ -276,9 +276,9 @@ class ActionGroup(Gtk.ActionGroup):
 
         if first_action is not None and on_change is not None:
             if user_data is None:
-                action.connect('changed', on_change)
+                first_action.connect('changed', on_change)
             else:
-                action.connect('changed', on_change, user_data)
+                first_action.connect('changed', on_change, user_data)
 
 ActionGroup = override(ActionGroup)
 __all__.append('ActionGroup')
@@ -411,10 +411,8 @@ class Dialog(Gtk.Dialog, Container):
             self.set_destroy_with_parent(True)
 
         # NO_SEPARATOR has been removed from Gtk 3
-        try:
-            if flags & Gtk.DialogFlags.NO_SEPARATOR:
-                self.set_has_separator(False)
-        except AttributeError:
+        if hasattr(Gtk.DialogFlags, "NO_SEPARATOR") and (flags & Gtk.DialogFlags.NO_SEPARATOR):
+            self.set_has_separator(False)
             import warnings
             warnings.warn("Gtk.DialogFlags.NO_SEPARATOR has been depricated since Gtk+-3.0", DeprecationWarning)
 
index 3b36c2f..9d99c35 100644 (file)
@@ -1785,19 +1785,29 @@ _pygi_argument_to_object (GIArgument  *arg,
             break;
         }
         case GI_TYPE_TAG_ERROR:
-             if (pyglib_error_check ( (GError **) &arg->v_pointer)) {
-                 PyObject *err_type;
-                 PyObject *err_value;
-                 PyObject *err_trace;
-                 PyErr_Fetch (&err_type, &err_value, &err_trace);
-                 Py_XDECREF (err_type);
-                 Py_XDECREF (err_trace);
-                 object = err_value;
-             } else {
-                 object = Py_None;
-                 Py_INCREF (object);
-                 break;
-             }
+        {
+            GError *error = (GError *) arg->v_pointer;
+            if (error != NULL && transfer == GI_TRANSFER_NOTHING) {
+                /* If we have not been transferred the ownership we must copy
+                 * the error, because pyglib_error_check() is going to free it.
+                 */
+                error = g_error_copy (error);
+            }
+
+            if (pyglib_error_check (&error)) {
+                PyObject *err_type;
+                PyObject *err_value;
+                PyObject *err_trace;
+                PyErr_Fetch (&err_type, &err_value, &err_trace);
+                Py_XDECREF (err_type);
+                Py_XDECREF (err_trace);
+                object = err_value;
+            } else {
+                object = Py_None;
+                Py_INCREF (object);
+                break;
+            }
+        }
     }
 
     return object;
index f770b20..6fc08fb 100644 (file)
@@ -163,6 +163,8 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
 
                     g_base_info_unref (interface);
                 }
+                case GI_TYPE_TAG_ERROR:
+                case GI_TYPE_TAG_GHASH:
                 case GI_TYPE_TAG_GLIST:
                 case GI_TYPE_TAG_GSLIST:
                     g_args[i].v_pointer = * (gpointer *) args[i];
@@ -421,8 +423,7 @@ _pygi_make_native_closure (GICallableInfo* info,
     ffi_closure *fficlosure;
 
     /* Begin by cleaning up old async functions */
-    g_slist_foreach (async_free_list, (GFunc) _pygi_invoke_closure_free, NULL);
-    g_slist_free (async_free_list);
+    g_slist_free_full (async_free_list, (GDestroyNotify) _pygi_invoke_closure_free);
     async_free_list = NULL;
 
     /* Build the closure itself */
index c6303f8..4e12df3 100644 (file)
@@ -112,7 +112,7 @@ cairo_surface_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
-static PyMethodDef _gi_cairo_functions[] = {0,};
+static PyMethodDef _gi_cairo_functions[] = { {0,} };
 PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
 {
 #if PY_VERSION_HEX < 0x03000000
index f80ebfa..e65731a 100644 (file)
@@ -311,7 +311,8 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
                                      gboolean         was_processed)
 {
     if (was_processed) {
-        GArray *array_;
+        GArray *array_ = NULL;
+        GPtrArray *ptr_array_ = NULL;
         PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
 
         /* If this isn't a garray create one to help process variable sized
@@ -322,6 +323,8 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
             if (array_ == NULL)
                 return;
             
+        } else if (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
+            ptr_array_ = (GPtrArray *) data;
         } else {
             array_ = (GArray *) data;
         }
@@ -329,13 +332,14 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
         /* clean up items first */
         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
             gsize i;
+            guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
             PyGIMarshalCleanupFunc cleanup_func =
                 sequence_cache->item_cache->from_py_cleanup;
 
-            for(i = 0; i < array_->len; i++) {
+            for(i = 0; i < len; i++) {
                 cleanup_func (state,
                               sequence_cache->item_cache,
-                              g_array_index (array_, gpointer, i),
+                              (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i),
                               TRUE);
             }
         }
@@ -345,7 +349,10 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
             g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING);
         } else if (state->failed ||
                    arg_cache->transfer == GI_TRANSFER_NOTHING) {
-            g_array_free (array_, TRUE);
+            if (array_ != NULL)
+                g_array_free (array_, TRUE);
+            else
+                g_ptr_array_free (ptr_array_, TRUE);
         }
     }
 }
@@ -356,11 +363,10 @@ _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
                                    gpointer         data,
                                    gboolean         was_processed)
 {
-    PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
-
     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING ||
         arg_cache->transfer == GI_TRANSFER_CONTAINER) {
-        GArray *array_;
+        GArray *array_ = NULL;
+        GPtrArray *ptr_array_ = NULL;
         PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
 
         /* If this isn't a garray create one to help process variable sized
@@ -370,24 +376,30 @@ _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
             
             if (array_ == NULL)
                 return;
-            
+
+        } else if (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
+            ptr_array_ = (GPtrArray *) data;
         } else {
             array_ = (GArray *) data;
         }
 
         if (sequence_cache->item_cache->to_py_cleanup != NULL) {
             gsize i;
+            guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
 
             PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup;
-            for (i = 0; i < array_->len; i++) {
+            for (i = 0; i < len; i++) {
                 cleanup_func (state,
                               sequence_cache->item_cache,
-                              g_array_index (array_, gpointer, i),
+                              (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i),
                               was_processed);
             }
         }
 
-        g_array_free (array_, TRUE);
+        if (array_ != NULL)
+            g_array_free (array_, TRUE);
+        else
+            g_ptr_array_free (ptr_array_, TRUE);
     }
 }
 
index 3b3109c..4de874b 100644 (file)
@@ -959,7 +959,7 @@ _pygi_marshal_from_py_glist (PyGIInvokeState   *state,
                                  &item))
             goto err;
 
-        list_ = g_list_append (list_, item.v_pointer);
+        list_ = g_list_prepend (list_, item.v_pointer);
         continue;
 err:
         /* FIXME: clean up list
@@ -972,7 +972,7 @@ err:
         return FALSE;
     }
 
-    arg->v_pointer = list_;
+    arg->v_pointer = g_list_reverse (list_);
     return TRUE;
 }
 
@@ -1026,7 +1026,7 @@ _pygi_marshal_from_py_gslist (PyGIInvokeState   *state,
                             &item))
             goto err;
 
-        list_ = g_slist_append (list_, item.v_pointer);
+        list_ = g_slist_prepend (list_, item.v_pointer);
         continue;
 err:
         /* FIXME: Clean up list
@@ -1040,7 +1040,7 @@ err:
         return FALSE;
     }
 
-    arg->v_pointer = list_;
+    arg->v_pointer = g_slist_reverse (list_);
     return TRUE;
 }
 
index 1e4a8aa..4b99278 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <time.h>
 
+#include <pyglib.h>
 #include <pygobject.h>
 #include <pyglib-python-compat.h>
 
@@ -264,8 +265,6 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
     gsize processed_items = 0;
 
-    array_ = arg->v_pointer;
-
      /* GArrays make it easier to iterate over arrays
       * with different element sizes but requires that
       * we allocate a GArray if the argument was a C array
@@ -276,8 +275,9 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
             g_assert(arg->v_pointer != NULL);
             len = seq_cache->fixed_size;
         } else if (seq_cache->is_zero_terminated) {
-            g_assert(arg->v_pointer != NULL);
-            if(seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
+            if (arg->v_pointer == NULL) {
+                len = 0;
+            } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
                 len = strlen (arg->v_pointer);
             } else {
                 len = g_strv_length ((gchar **)arg->v_pointer);
@@ -303,6 +303,8 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
             g_free (array_->data);
         array_->data = arg->v_pointer;
         array_->len = len;
+    } else {
+        array_ = arg->v_pointer;
     }
 
     if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
@@ -597,11 +599,20 @@ _pygi_marshal_to_py_gerror (PyGIInvokeState   *state,
                             PyGIArgCache      *arg_cache,
                             GIArgument        *arg)
 {
+    GError *error = arg->v_pointer;
     PyObject *py_obj = NULL;
 
-    PyErr_Format (PyExc_NotImplementedError,
-                  "Marshalling for gerror to PyObject is not implemented");
-    return py_obj;
+    py_obj = pyglib_error_marshal(&error);
+
+    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) {
+        g_error_free (error);
+    }
+
+    if (py_obj != NULL) {
+        return py_obj;
+    } else {
+        Py_RETURN_NONE;
+    }
 }
 
 PyObject *
index 2f8970d..f400820 100644 (file)
@@ -121,16 +121,36 @@ pygi_get_property_value_real (PyGObject *instance,
             arg.v_boolean = g_value_get_boolean (&value);
             break;
         case GI_TYPE_TAG_INT8:
+            arg.v_int8 = g_value_get_schar (&value);
+            break;
         case GI_TYPE_TAG_INT16:
         case GI_TYPE_TAG_INT32:
+            if (G_VALUE_HOLDS_LONG (&value))
+                arg.v_long = g_value_get_long (&value);
+            else
+                arg.v_int = g_value_get_int (&value);
+            break;
         case GI_TYPE_TAG_INT64:
-            arg.v_int = g_value_get_int (&value);
+            if (G_VALUE_HOLDS_LONG (&value))
+                arg.v_long = g_value_get_long (&value);
+            else
+                arg.v_int64 = g_value_get_int64 (&value);
             break;
         case GI_TYPE_TAG_UINT8:
+            arg.v_uint8 = g_value_get_uchar (&value);
+            break;
         case GI_TYPE_TAG_UINT16:
         case GI_TYPE_TAG_UINT32:
+            if (G_VALUE_HOLDS_ULONG (&value))
+                arg.v_ulong = g_value_get_ulong (&value);
+            else
+                arg.v_uint = g_value_get_uint (&value);
+            break;
         case GI_TYPE_TAG_UINT64:
-            arg.v_uint = g_value_get_uint (&value);
+            if (G_VALUE_HOLDS_ULONG (&value))
+                arg.v_ulong = g_value_get_ulong (&value);
+            else
+                arg.v_uint64 = g_value_get_uint64 (&value);
             break;
         case GI_TYPE_TAG_FLOAT:
             arg.v_float = g_value_get_float (&value);
@@ -296,16 +316,36 @@ pygi_set_property_value_real (PyGObject *instance,
             g_value_set_boolean (&value, arg.v_boolean);
             break;
         case GI_TYPE_TAG_INT8:
+            g_value_set_schar (&value, arg.v_int8);
+            break;
         case GI_TYPE_TAG_INT16:
         case GI_TYPE_TAG_INT32:
+            if (G_VALUE_HOLDS_LONG (&value))
+                g_value_set_long (&value, arg.v_long);
+            else
+                g_value_set_int (&value, arg.v_int);
+            break;
         case GI_TYPE_TAG_INT64:
-            g_value_set_int (&value, arg.v_int);
+            if (G_VALUE_HOLDS_LONG (&value))
+                g_value_set_long (&value, arg.v_long);
+            else
+                g_value_set_int64 (&value, arg.v_int64);
             break;
         case GI_TYPE_TAG_UINT8:
+            g_value_set_uchar (&value, arg.v_uint8);
+            break;
         case GI_TYPE_TAG_UINT16:
         case GI_TYPE_TAG_UINT32:
+            if (G_VALUE_HOLDS_ULONG (&value))
+                g_value_set_ulong (&value, arg.v_ulong);
+            else
+                g_value_set_uint (&value, arg.v_uint);
+            break;
         case GI_TYPE_TAG_UINT64:
-            g_value_set_uint (&value, arg.v_uint);
+            if (G_VALUE_HOLDS_ULONG (&value))
+                g_value_set_ulong (&value, arg.v_ulong);
+            else
+                g_value_set_uint64 (&value, arg.v_uint64);
             break;
         case GI_TYPE_TAG_FLOAT:
             g_value_set_float (&value, arg.v_float);
index 4ec6477..06d4768 100644 (file)
@@ -87,6 +87,7 @@ TEST_FILES_GI = \
 EXTRA_DIST = \
        compathelper.py \
        runtests.py \
+       runtests-windows.py \
        testmodule.py \
        test-floating.h \
        test-thread.h \
index f0b3f95..e27fb71 100644 (file)
@@ -303,9 +303,9 @@ TEST_FILES_GI = \
        test_gdbus.py \
        test_overrides.py
 
-EXTRA_DIST = compathelper.py runtests.py testmodule.py test-floating.h \
-       test-thread.h test-unknown.h te_ST@nouppera \
-       org.gnome.test.gschema.xml $(TEST_FILES_STATIC) \
+EXTRA_DIST = compathelper.py runtests.py runtests-windows.py \
+       testmodule.py test-floating.h test-thread.h test-unknown.h \
+       te_ST@nouppera org.gnome.test.gschema.xml $(TEST_FILES_STATIC) \
        $(TEST_FILES_GI)
 DBUS_LAUNCH = $(shell which dbus-launch)
 RUN_TESTS_ENV_VARS = \
diff --git a/tests/runtests-windows.py b/tests/runtests-windows.py
new file mode 100644 (file)
index 0000000..ae81202
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
+import os
+import sys
+import glob
+import unittest
+
+os.environ['PYGTK_USE_GIL_STATE_API'] = ''
+sys.path.insert(0, os.path.dirname(__file__))
+sys.argv.append('--g-fatal-warnings')
+
+from gi.repository import GObject
+GObject.threads_init()
+
+
+SKIP_FILES = ['runtests',
+              'test_mainloop',      # no os.fork on windows
+              'test_subprocess']    # blocks on testChildWatch
+
+
+if __name__ == '__main__':
+    testdir = os.path.split(os.path.abspath(__file__))[0]
+    os.chdir(testdir)
+
+    def gettestnames():
+        files = glob.glob('*.py')
+        names = map(lambda x: x[:-3], files)
+        map(names.remove, SKIP_FILES)
+        return names
+
+    suite = unittest.TestSuite()
+    loader = unittest.TestLoader()
+
+    for name in gettestnames():
+        try:
+            suite.addTest(loader.loadTestsFromName(name))
+        except Exception, e:
+            print 'Could not load %s: %s' % (name, e)
+
+    testRunner = unittest.TextTestRunner()
+    testRunner.verbosity = 2
+    testRunner.run(suite)
index 43735e5..82edfcf 100644 (file)
@@ -12,6 +12,7 @@ import cairo
 
 from gi.repository import GObject
 from gi.repository import GLib
+from gi.repository import Gio
 from gi.repository import Regress as Everything
 
 if sys.version_info < (3, 0):
@@ -201,7 +202,7 @@ class TestCallbacks(unittest.TestCase):
     called = False
     main_loop = GObject.MainLoop()
 
-    def testCallback(self):
+    def test_callback(self):
         TestCallbacks.called = False
         def callback():
             TestCallbacks.called = True
@@ -209,7 +210,7 @@ class TestCallbacks(unittest.TestCase):
         Everything.test_simple_callback(callback)
         self.assertTrue(TestCallbacks.called)
 
-    def testCallbackException(self):
+    def test_callback_exception(self):
         """
         This test ensures that we get errors from callbacks correctly
         and in particular that we do not segv when callbacks fail
@@ -222,7 +223,7 @@ class TestCallbacks(unittest.TestCase):
         except ZeroDivisionError:
             pass
 
-    def testDoubleCallbackException(self):
+    def test_double_callback_exception(self):
         """
         This test ensures that we get errors from callbacks correctly
         and in particular that we do not segv when callbacks fail
@@ -240,7 +241,7 @@ class TestCallbacks(unittest.TestCase):
         except ZeroDivisionError:
             pass
 
-    def testReturnValueCallback(self):
+    def test_return_value_callback(self):
         TestCallbacks.called = False
         def callback():
             TestCallbacks.called = True
@@ -249,7 +250,7 @@ class TestCallbacks(unittest.TestCase):
         self.assertEquals(Everything.test_callback(callback), 44)
         self.assertTrue(TestCallbacks.called)
     
-    def testCallbackAsync(self):
+    def test_callback_async(self):
         TestCallbacks.called = False
         def callback(foo):
             TestCallbacks.called = True
@@ -260,7 +261,7 @@ class TestCallbacks(unittest.TestCase):
         self.assertEquals(44, i);
         self.assertTrue(TestCallbacks.called)
 
-    def testCallbackScopeCall(self):
+    def test_callback_scope_call(self):
         TestCallbacks.called = 0
         def callback():
             TestCallbacks.called += 1
@@ -269,7 +270,7 @@ class TestCallbacks(unittest.TestCase):
         Everything.test_multi_callback(callback)
         self.assertEquals(TestCallbacks.called, 2)
 
-    def testCallbackUserdata(self):
+    def test_callback_userdata(self):
         TestCallbacks.called = 0
         def callback(userdata):
             self.assertEquals(userdata, "Test%d" % TestCallbacks.called)
@@ -282,7 +283,7 @@ class TestCallbacks(unittest.TestCase):
             
         self.assertEquals(TestCallbacks.called, 100)
 
-    def testCallbackUserdataRefCount(self):
+    def test_callback_userdata_refcount(self):
         TestCallbacks.called = False
         def callback(userdata):
             TestCallbacks.called = True
@@ -299,7 +300,7 @@ class TestCallbacks(unittest.TestCase):
 
         self.assertEquals(start_ref_count, end_ref_count)
 
-    def testAsyncReadyCallback(self):
+    def test_async_ready_callback(self):
         TestCallbacks.called = False
         TestCallbacks.main_loop = GObject.MainLoop()
 
@@ -313,7 +314,7 @@ class TestCallbacks(unittest.TestCase):
 
         self.assertTrue(TestCallbacks.called)
 
-    def testCallbackDestroyNotify(self):
+    def test_callback_destroy_notify(self):
         def callback(user_data):
             TestCallbacks.called = True
             return 42
@@ -323,7 +324,7 @@ class TestCallbacks(unittest.TestCase):
         self.assertTrue(TestCallbacks.called)
         self.assertEquals(Everything.test_callback_thaw_notifications(), 42)
 
-    def testCallbackInMethods(self):
+    def test_callback_in_methods(self):
         object_ = Everything.TestObj()
 
         def callback():
@@ -346,10 +347,53 @@ class TestCallbacks(unittest.TestCase):
         obj_ = Everything.TestObj.new_callback(callbackWithUserData, None)
         self.assertTrue(TestCallbacks.called)
 
-    def testCallbackNone(self):
+    def test_callback_none(self):
         # make sure this doesn't assert or crash
         Everything.test_simple_callback(None)
 
+    def test_callback_gerror(self):
+        def callback(error):
+            self.assertEqual(error.message, 'regression test error')
+            self.assertTrue('g-io' in error.domain)
+            self.assertEqual(error.code, Gio.IOErrorEnum.NOT_SUPPORTED)
+            TestCallbacks.called = True
+
+        TestCallbacks.called = False
+        Everything.test_gerror_callback(callback)
+        self.assertTrue(TestCallbacks.called)
+
+    def test_callback_null_gerror(self):
+        def callback(error):
+            self.assertEqual(error, None)
+            TestCallbacks.called = True
+
+        TestCallbacks.called = False
+        Everything.test_null_gerror_callback(callback)
+        self.assertTrue(TestCallbacks.called)
+
+    def test_callback_owned_gerror(self):
+        def callback(error):
+            self.assertEqual(error.message, 'regression test owned error')
+            self.assertTrue('g-io' in error.domain)
+            self.assertEqual(error.code, Gio.IOErrorEnum.PERMISSION_DENIED)
+            TestCallbacks.called = True
+
+        TestCallbacks.called = False
+        Everything.test_owned_gerror_callback(callback)
+        self.assertTrue(TestCallbacks.called)
+
+    def test_callback_hashtable(self):
+        def callback(data):
+            self.assertEqual(data, mydict)
+            mydict['new'] = 42
+            TestCallbacks.called = True
+
+        mydict = { 'foo': 1, 'bar': 2 }
+        TestCallbacks.called = False
+        Everything.test_hash_table_callback(mydict, callback)
+        self.assertTrue(TestCallbacks.called)
+        self.assertEqual(mydict, { 'foo': 1, 'bar': 2, 'new': 42 })
+
 class TestClosures(unittest.TestCase):
     def test_int_arg(self):
         def callback(num):
index 0a9b1b2..b066626 100644 (file)
@@ -743,6 +743,9 @@ class TestArray(unittest.TestCase):
     def test_array_zero_terminated_return(self):
         self.assertEquals(['0', '1', '2'], GIMarshallingTests.array_zero_terminated_return())
 
+    def test_array_zero_terminated_return_null(self):
+        self.assertEquals([], GIMarshallingTests.array_zero_terminated_return_null())
+
     def test_array_zero_terminated_in(self):
         GIMarshallingTests.array_zero_terminated_in(Sequence(['0', '1', '2']))
 
@@ -772,19 +775,22 @@ class TestArray(unittest.TestCase):
     
     def test_array_gvariant_none_in(self):
         v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
-        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
+        returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
+        self.assertEquals([27, "Hello"], returned)
     
     def test_array_gvariant_container_in(self):
         v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
-        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
+        returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
+        self.assertEquals([27, "Hello"], returned)
     
     def test_array_gvariant_full_in(self):
         v = [GLib.Variant("i", 27), GLib.Variant("s", "Hello")]
-        self.assertEquals([27, "Hello"], map(GLib.Variant.unpack, GIMarshallingTests.array_gvariant_none_in(v)))
+        returned = [GLib.Variant.unpack(r) for r in GIMarshallingTests.array_gvariant_none_in(v)]
+        self.assertEquals([27, "Hello"], returned)
 
     def test_bytearray_gvariant(self):
-        v = GLib.Variant.new_bytestring("foo")
-        self.assertEquals(v.get_bytestring(), "foo")
+        v = GLib.Variant.new_bytestring(b"foo")
+        self.assertEquals(v.get_bytestring(), b"foo")
 
 class TestGArray(unittest.TestCase):
 
@@ -1826,6 +1832,38 @@ class TestGErrorArrayInCrash(unittest.TestCase):
     def test_gerror_array_in_crash(self):
         self.assertRaises(GObject.GError, GIMarshallingTests.gerror_array_in, [1, 2, 3])
 
+class TestGErrorOut(unittest.TestCase):
+    # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+    def test_gerror_out(self):
+        error, debug = GIMarshallingTests.gerror_out()
+
+        self.assertIsInstance(error, GObject.GError)
+        self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+        self.assertEquals(debug, GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE)
+
+class TestGErrorOutTransferNone(unittest.TestCase):
+    # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+    def test_gerror_out_transfer_none(self):
+        error, debug = GIMarshallingTests.gerror_out_transfer_none()
+
+        self.assertIsInstance(error, GObject.GError)
+        self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+        self.assertEquals(GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE, debug)
+
+class TestGErrorReturn(unittest.TestCase):
+    # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+    def test_return_gerror(self):
+        error = GIMarshallingTests.gerror_return()
+
+        self.assertIsInstance(error, GObject.GError)
+        self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+
 class TestKeywordArgs(unittest.TestCase):
     def test_calling(self):
         kw_func = GIMarshallingTests.int_three_in_three_out
@@ -1883,3 +1921,65 @@ class TestKeywordArgs(unittest.TestCase):
         d2 = d.copy()
         GIMarshallingTests.int_three_in_three_out(1, c=4, **d)
         self.assertEqual(d, d2)
+
+class TestPropertiesObject(unittest.TestCase):
+
+    def setUp(self):
+        self.obj = GIMarshallingTests.PropertiesObject()
+
+    def test_boolean(self):
+        self.assertEqual(self.obj.props.some_boolean, False)
+        self.obj.props.some_boolean = True
+        self.assertEqual(self.obj.props.some_boolean, True)
+
+    @unittest.expectedFailure
+    def test_char(self):
+        # gobject-introspection thinks it has a guint8 type tag, which is wrong
+        self.assertEqual(self.obj.props.some_char, 0)
+        self.obj.props.some_char = GObject.G_MAXINT8
+        self.assertEqual(self.obj.props.some_char, GObject.G_MAXINT8)
+
+    def test_uchar(self):
+        self.assertEqual(self.obj.props.some_uchar, 0)
+        self.obj.props.some_uchar = GObject.G_MAXUINT8
+        self.assertEqual(self.obj.props.some_uchar, GObject.G_MAXUINT8)
+
+    def test_int(self):
+        self.assertEqual(self.obj.props.some_int, 0)
+        self.obj.props.some_int = GObject.G_MAXINT
+        self.assertEqual(self.obj.props.some_int, GObject.G_MAXINT)
+
+    def test_uint(self):
+        self.assertEqual(self.obj.props.some_uint, 0)
+        self.obj.props.some_uint = GObject.G_MAXUINT
+        self.assertEqual(self.obj.props.some_uint, GObject.G_MAXUINT)
+
+    def test_long(self):
+        self.assertEqual(self.obj.props.some_long, 0)
+        self.obj.props.some_long = GObject.G_MAXLONG
+        self.assertEqual(self.obj.props.some_long, GObject.G_MAXLONG)
+
+    def test_ulong(self):
+        self.assertEqual(self.obj.props.some_ulong, 0)
+        self.obj.props.some_ulong = GObject.G_MAXULONG
+        self.assertEqual(self.obj.props.some_ulong, GObject.G_MAXULONG)
+
+    def test_int64(self):
+        self.assertEqual(self.obj.props.some_int64, 0)
+        self.obj.props.some_int64 = GObject.G_MAXINT64
+        self.assertEqual(self.obj.props.some_int64, GObject.G_MAXINT64)
+
+    def test_uint64(self):
+        self.assertEqual(self.obj.props.some_uint64, 0)
+        self.obj.props.some_uint64 = GObject.G_MAXUINT64
+        self.assertEqual(self.obj.props.some_uint64, GObject.G_MAXUINT64)
+
+    def test_float(self):
+        self.assertEqual(self.obj.props.some_float, 0)
+        self.obj.props.some_float = GObject.G_MAXFLOAT
+        self.assertEqual(self.obj.props.some_float, GObject.G_MAXFLOAT)
+
+    def test_double(self):
+        self.assertEqual(self.obj.props.some_double, 0)
+        self.obj.props.some_double = GObject.G_MAXDOUBLE
+        self.assertEqual(self.obj.props.some_double, GObject.G_MAXDOUBLE)
index 8974273..ea74fb3 100644 (file)
@@ -347,6 +347,107 @@ class TestGLib(unittest.TestCase):
         self.assertEqual(GLib.Variant.split_signature('(a{iv}(ii)((ss)a{s(ss)}))'), 
                 ['a{iv}', '(ii)', '((ss)a{s(ss)})'])
 
+    def test_variant_hash(self):
+        v1 = GLib.Variant('s', 'somestring')
+        v2 = GLib.Variant('s', 'somestring')
+        v3 = GLib.Variant('s', 'somestring2')
+
+        self.assertTrue(v2 in set([v1, v3]))
+        self.assertTrue(v2 in frozenset([v1, v3]))
+        self.assertTrue(v2 in {v1: '1', v3:'2' })
+
+    def test_variant_compare(self):
+        # Check if identical GVariant are equal
+
+        def assert_equal(vtype, value):
+            self.assertEqual(GLib.Variant(vtype, value), GLib.Variant(vtype, value))
+
+        def assert_not_equal(vtype1, value1, vtype2, value2):
+            self.assertNotEqual(GLib.Variant(vtype1, value1), GLib.Variant(vtype2, value2))
+
+        numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
+        for num in numbers:
+            assert_equal(num, 42)
+            assert_not_equal(num, 42, num, 41)
+            assert_not_equal(num, 42, 's', '42')
+
+        assert_equal('s', 'something')
+        assert_not_equal('s', 'something', 's', 'somethingelse')
+        assert_not_equal('s', 'something', 'i', 1234)
+
+        assert_equal('g', 'dustybinqhogx')
+        assert_not_equal('g', 'dustybinqhogx', 'g', 'dustybin')
+        assert_not_equal('g', 'dustybinqhogx', 'i', 1234)
+
+        assert_equal('o', '/dev/null')
+        assert_not_equal('o', '/dev/null', 'o', '/dev/zero')
+        assert_not_equal('o', '/dev/null', 'i', 1234)
+
+        assert_equal('(s)', ('strtuple',))
+        assert_not_equal('(s)', ('strtuple',), '(s)', ('strtuple2',))
+
+        assert_equal('a{si}', {'str': 42})
+        assert_not_equal('a{si}', {'str': 42}, 'a{si}', {'str': 43})
+
+        assert_equal('v', GLib.Variant('i', 42))
+        assert_not_equal('v', GLib.Variant('i', 42), 'v', GLib.Variant('i', 43))
+
+    def test_variant_bool(self):
+        # Check if the GVariant bool matches the unpacked Pythonic bool
+
+        def assert_equals_bool(vtype, value):
+            self.assertEqual(bool(GLib.Variant(vtype, value)), bool(value))
+
+        # simple values
+        assert_equals_bool('b', True)
+        assert_equals_bool('b', False)
+
+        numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
+        for number in numbers:
+            assert_equals_bool(number, 0)
+            assert_equals_bool(number, 1)
+
+        assert_equals_bool('s', '')
+        assert_equals_bool('g', '')
+        assert_equals_bool('s', 'something')
+        assert_equals_bool('o', '/dev/null')
+        assert_equals_bool('g', 'dustybinqhogx')
+
+        # arrays
+        assert_equals_bool('ab', [True])
+        assert_equals_bool('ab', [False])
+        for number in numbers:
+            assert_equals_bool('a'+number, [])
+            assert_equals_bool('a'+number, [0])
+        assert_equals_bool('as', [])
+        assert_equals_bool('as', [''])
+        assert_equals_bool('ao', [])
+        assert_equals_bool('ao', ['/'])
+        assert_equals_bool('ag', [])
+        assert_equals_bool('ag', [''])
+        assert_equals_bool('aai', [[]])
+
+        # tuples
+        assert_equals_bool('()', ())
+        for number in numbers:
+            assert_equals_bool('('+number+')', (0,))
+        assert_equals_bool('(s)', ('',))
+        assert_equals_bool('(o)', ('/',))
+        assert_equals_bool('(g)', ('',))
+        assert_equals_bool('(())', ((),))
+
+        # dictionaries
+        assert_equals_bool('a{si}', {})
+        assert_equals_bool('a{si}', {'': 0})
+
+        # complex types, always True
+        assert_equals_bool('(as)', ([],))
+        assert_equals_bool('a{s(i)}', {'': (0,)})
+
+        # variant types, recursive unpacking
+        assert_equals_bool('v', GLib.Variant('i', 0))
+        assert_equals_bool('v', GLib.Variant('i', 1))
+
 class TestPango(unittest.TestCase):
 
     def test_default_font_description(self):