Imported Upstream version 3.7.4 14/138314/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:48:25 +0000 (08:48 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:48:29 +0000 (08:48 +0900)
Change-Id: Ida7f0ffc68fbd0b3af016f7988b2210cdf9afa1a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
32 files changed:
ChangeLog
NEWS
PKG-INFO
aclocal.m4
configure
configure.ac
gi/_gobject/propertyhelper.py
gi/_gobject/pygenum.c
gi/_gobject/pygobject.c
gi/_gobject/pygtype.c
gi/gimodule.c
gi/overrides/GObject.py
gi/overrides/Gtk.py
gi/pygi-argument.c
gi/pygi-cache.c
gi/pygi-closure.c
gi/pygi-info.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.py
tests/test_everything.py
tests/test_gi.py
tests/test_gio.py [moved from tests/test_overrides_gio.py with 66% similarity]
tests/test_gobject.py
tests/test_gtype.py
tests/test_overrides_gtk.py
tests/test_properties.py
tests/test_signal.py
tests/testhelpermodule.c

index ab16367..868baee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,648 @@
+commit bd6da84a4aec74e47f5d70e8ed18695c37e746c6
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 17:30:48 2013 +0100
+
+    release 3.7.4
+
+ NEWS | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+commit c90ef9dfac7dd51ec82c99c3605915996bea0f73
+Author: Simonas Kazlauskas <simonas@kazlauskas.me>
+Date:   Tue Dec 4 15:45:00 2012 +0200
+
+    Allow setting values through GtkTreeModelFilter
+
+    Previously, trying to set a value through filter throwed an exception
+    that the
+    model has no set_value() method. You had to first retrieve the
+    deepest child
+    model and set value to it.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=689624
+
+ gi/overrides/Gtk.py         |  5 +++++
+ tests/test_overrides_gtk.py | 11 +++++++++++
+ 2 files changed, 16 insertions(+)
+
+commit b092630efc691a6f7ae94ae896193254f5a961a6
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 12:37:18 2013 +0100
+
+    tests: Add (failing) test case for GParamSpec arguments
+
+    This reproduces
+    https://bugzilla.gnome.org/show_bug.cgi?id=682355
+
+ tests/test_gi.py | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 52d84b5da7f9fd4f65faea4e6fe3d250f937a208
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 12:20:27 2013 +0100
+
+    tests: Skip struct string member tests with g-i 1.34
+
+    We still support building against gobject-introspection 1.34, so
+    skip tests
+    which do not work with that version yet.
+
+ tests/test_gi.py | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit f9429192cb1002725a11a75a7b8f9300375b9caf
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 12:15:27 2013 +0100
+
+    Support GParamSpec signal arguments from Python
+
+    In pyg_value_from_pyobject(), recognize both the real GI
+    GObject.ParamSpec type
+    as well as the statically wrapped _gobject.GParamSpec type.
+
+    This fixes marshalling GObject.ParamSpec signal/vfunc arguments.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=683099
+
+ gi/_gobject/pygtype.c    |  6 +++++-
+ tests/test_signal.py     | 12 ++++++++++++
+ tests/testhelpermodule.c | 13 +++++++++++++
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+commit 99f72925c7de76611f7592bce9d8217a9ff46809
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 11:48:11 2013 +0100
+
+    pygobject_emit(): Fix cleanup on error
+
+    Dot not try to unset GValues which have not been initialized yet,
+    when type
+    conversion fails for a parameter.
+
+ gi/_gobject/pygobject.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit acef1d3266d11b2465d61185a55526df879a5c62
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon Dec 31 19:01:57 2012 -0800
+
+    Add signal emission methods to TreeModel which coerce the path
+    argument
+
+    Override TreeModel row_changed, row_inserted, row_has_child_toggled,
+    row_deleted, and rows_reordered methods to accept python iterables as
+    the path parameter. This is for compatibility with pygtk and
+    consistency
+    with the rest of the TreeModel and TreePath overrides.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=682933
+
+ gi/overrides/Gtk.py         | 31 ++++++++++++++++++++++++++++---
+ tests/test_overrides_gtk.py | 27 +++++++++++++++++++++++++++
+ 2 files changed, 55 insertions(+), 3 deletions(-)
+
+commit 9cfba517e1a6dced5e66786b28ed5e101b7b4a29
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 10:36:36 2013 +0100
+
+    Simplify overrides and tests using the new GObject.Value override
+
+    The previous commit added support for constructing a GObject.Value
+    with a given
+    GType and Python object conversion. Use this to simplify the Gtk
+    override and
+    the tests that construct GValues.
+
+    See https://bugzilla.gnome.org/show_bug.cgi?id=677473
+
+ gi/overrides/Gtk.py         | 88
+ +++------------------------------------------
+ tests/test_gi.py            | 26 +++++---------
+ tests/test_overrides_gtk.py |  2 +-
+ tests/test_signal.py        | 12 ++-----
+ 4 files changed, 17 insertions(+), 111 deletions(-)
+
+commit f62b98398177991bfdbe0b6753342e79e6cf170a
+Author: Bastian Winkler <buz@netbuz.org>
+Date:   Mon Jan 14 10:26:08 2013 +0100
+
+    Add override for GValue
+
+    Override GValue with a custom constructor and set_value()/get_value()
+    methods. This allows you to call
+
+    >>> GObject.Value(GObject.TYPE_FLOAT, 42.23)
+
+    instead of
+
+    >>> value = GObject.Value()
+    >>> value.init(GObject.TYPE_FLOAT)
+    >>> value.set_float(42.23)
+
+    This is especially useful for overrides that need to convert a Python
+    value to a expected type like G_TYPE_FLOAT.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=677473
+
+ gi/overrides/GObject.py | 127
+ +++++++++++++++++++++++++++++++++++++++++++++++-
+ tests/test_gobject.py   |  47 +++++++++++++++++-
+ 2 files changed, 172 insertions(+), 2 deletions(-)
+
+commit dc3d21173b75232f7ea0b9913f7309486456a69d
+Author: Mike Gorse <mgorse@suse.com>
+Date:   Thu Jan 10 15:48:30 2013 -0600
+
+    Mark caller-allocated boxed structures as having a slice allocated
+
+    When a C function takes a pointer and fills it with a boxed structure
+    (ie,
+    gtk_tree_store_insert_with_values), pygi should deallocate the slice
+    when the
+    box is no longer being used.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=699501
+
+ gi/pygi-marshal-to-py.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 0c496d230fee7fd3ada90ee9af10e0bc1e29ee12
+Author: Olivier Crête <olivier.crete@collabora.com>
+Date:   Fri Sep 14 21:31:32 2012 -0400
+
+    pygi-property: Support boxed GSList/GList types
+
+    Note that this does not yet work for construct properties.
+
+    Co-Authored-By: Martin Pitt <martinpitt@gnome.org>
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=684059
+
+ gi/pygi-property.c | 10 ++++++++--
+ tests/test_gi.py   | 21 +++++++++++++++++++++
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+commit 074f10d815453e58f4bee2f440c5db799add3876
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 07:48:31 2013 +0100
+
+    test_gio: Fix for Python 2
+
+    Python 2 does not yet take an "encoding" argument for str(), while
+    Python 3
+    requires it. Use a less fancy static test string instead.
+
+ tests/test_gio.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 734979d0c8317201148a7e94a323225fba2d1635
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 07:40:10 2013 +0100
+
+    tests: Add missing backwards compat methods for Python 2.6
+
+    Define skipIf(), assertLess(), and assertLessEqual() for running
+    the tests with
+    Python 2.6.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=691646
+
+ tests/runtests.py | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit dc0dafd1f6ca3ebbf04210768a45587387e44551
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Jan 14 07:34:46 2013 +0100
+
+    tests: Stop using assertSequenceEqual()
+
+    assertSequenceEqual() does not yet exist in Python 2.6, and is
+    not necessary
+    either as assertEqual() on sequences automatically does list
+    comparison.
+
+    Part of https://bugzilla.gnome.org/show_bug.cgi?id=691646
+
+ tests/test_gtype.py  | 6 ++----
+ tests/test_signal.py | 6 ++----
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+commit 0a5587b6a56d417a6703e342f153596f08cd5889
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun Jan 13 18:19:51 2013 -0800
+
+    Allow setting TreeModel values to None
+
+    Change TreeModel.set_value to use an empty but initialized GValue when
+    None is used as the value argument. This allows clearing of cell data
+    which was not accessible due to auto-coercion.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=684094
+
+ gi/overrides/Gtk.py         | 11 ++++++++---
+ tests/test_overrides_gtk.py |  8 ++++++++
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+commit 5ae129da436793478750f0dc9427a174a980e10b
+Author: Mike Gorse <mgorse@suse.com>
+Date:   Thu Jan 10 16:42:17 2013 -0600
+
+    Set clean-up handler for marshalled arrays
+
+    Arrays did not have a cleanup handler set in some cases, resulting
+    in a leak.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=691509
+
+ gi/pygi-cache.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 58bd307c57d542a8f69867dea2d0a0eb51230c7b
+Author: Vadim Rutkovsky <vrutkovs@redhat.com>
+Date:   Fri Jan 11 15:41:27 2013 +0100
+
+    Support setting string fields in structs
+
+    Co-Authored-By: Martin Pitt <martinpitt@gnome.org>
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=678401
+
+ gi/pygi-info.c   |  3 ++-
+ tests/test_gi.py | 16 ++++++++++++++++
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+commit f2bcaa43c1158040a8c2cbc3a2ba5070d126a410
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Fri Jan 11 14:58:44 2013 +0100
+
+    Re-enable test_gi.TestPropertiesObject.test_char test
+
+    The gobject-introspection bug got fixed:
+    https://bugzilla.gnome.org/show_bug.cgi?id=691524
+
+ tests/test_gi.py | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+commit 9a8c49087cf400e01c1f78241fa4d74b4d15f54e
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Fri Jan 11 09:46:56 2013 +0100
+
+    tests: Re-enable test_callback_scope_call_array() check
+
+    Drop the expected failure from test_callback_scope_call_array()
+    and just add
+    the explicit array length arguments. While it would look cleaner to
+    not pass
+    them, it is probably not worth breaking the API for this.
+
+ tests/test_everything.py | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit 609636424b5f9b659e99a4bb53a48c165187c430
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Fri Jan 11 09:13:36 2013 +0100
+
+    Permit plain integers for "gchar" values
+
+    Similar to guchar/guint8, allow plain integers (withing correct
+    boundaries) as
+    values for gchar/gint8 types.
+
+    This is covered by the test_gi.TestPropertiesObject.test_char
+    test when
+    removing the "expected failure" flag.
+
+ gi/_gobject/pygtype.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit a558d3d3a9274aeccfc54705bf5effdf71dee06b
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Fri Jan 11 09:09:41 2013 +0100
+
+    Allow single byte values for int8 types
+
+    When fixing gobject-introspection to consider "gchar" as signed (see
+    https://bugzilla.gnome.org/show_bug.cgi?id=691524), we must also
+    permit a
+    single-element "bytes" array as a valid value for int8, not just
+    for uint8.
+
+    This is caught by the test_overrides_gtk.TestTreeModel.test_tree_store
+    test.
+
+ gi/pygi-argument.c        |  4 ++--
+ gi/pygi-marshal-from-py.c | 34 +++++++++++++++++++++-------------
+ 2 files changed, 23 insertions(+), 15 deletions(-)
+
+commit aa7f6cd12fe403acb2cffc7890724af7abb9b990
+Author: Mike Gorse <mgorse@suse.com>
+Date:   Thu Jan 10 14:11:56 2013 -0600
+
+    Fix invalid memory access handling errors when registering an
+    enum type
+
+    Don't free the name until we are done with it.
+
+ gi/gimodule.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit ecd235959317d39b6d598662c00829e0ec717b17
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Thu Jan 10 16:42:46 2013 +0100
+
+    Fix (out) arguments in callbacks
+
+    Do not ignore the first argument in _pygi_closure_set_out_arguments().
+    Presumably that has been done to skip over "self", but callbacks
+    are not
+    required to have a self argument. As self is never (out), we can
+    safely include
+    it in the loop.
+
+ gi/pygi-closure.c | 2 +-
+ tests/test_gi.py  | 4 ----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+commit d8e241e24a816691acbd592775b73defd9aa4f44
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Thu Jan 10 15:14:05 2013 +0100
+
+    Fix C to Python marshalling of struct pointer arrays
+
+    Do not treat an array of pointers to values like an array of values on
+    marshalling from C. This makes the test_array_boxed_struct_return()
+    test case
+    work.
+
+ gi/pygi-marshal-to-py.c | 5 +++--
+ tests/test_gi.py        | 2 --
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 60544b02f6f98c0b212625ae83b94a4c6debddeb
+Author: Simonas Kazlauskas <simonas@kazlauskas.me>
+Date:   Tue Jan 8 23:22:54 2013 +0200
+
+    Add tests for GFile
+
+    Most notably this commit contains a test for
+    Gio.File.replace_contents_async(),
+    which currently fails. Disable the tests for now as it breaks the
+    other tests.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690525
+
+ tests/test_gio.py | 64
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+commit 118c5eaad045580455515876ba73b9537a8468b4
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Thu Jan 10 13:56:11 2013 +0100
+
+    Rename test_overrides_gio.py to test_gio.py
+
+    As we want to add more tests for non-overridden API.
+
+ tests/Makefile.am           |   2 +-
+ tests/test_gio.py           | 121
+ ++++++++++++++++++++++++++++++++++++++++++++
+ tests/test_overrides_gio.py | 121
+ --------------------------------------------
+ 3 files changed, 122 insertions(+), 122 deletions(-)
+
+commit 8117e6bce73581e89211371708ff7d5de7d870d4
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Thu Jan 10 12:13:16 2013 +0100
+
+    Don't let Property.setter() method names define property names
+
+    Defining property names in install_properties() is too late when using
+    @propname.setter decorators; their method names don't define a
+    property name,
+    nor are they even required to be a valid property identifier.
+
+    So change the logic to already fix the property name when using
+    a setter
+    decorator and use that instead of the member name in
+    install_properties().
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=688971
+
+ gi/_gobject/propertyhelper.py | 29 ++++++++++++++++++++++-------
+ tests/test_properties.py      | 18 ++++++++++++++++++
+ 2 files changed, 40 insertions(+), 7 deletions(-)
+
+commit c0bd060521cc1b481995648dbe286b7e2f9ecd80
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Wed Jan 9 10:39:36 2013 +0100
+
+    tests: Force UTF-8 file name encoding
+
+    The test_gi.TestFilename tests fail if the environment specifies
+    a non-UTF8
+    file name encoding. Force it to "UTF-8" for the tests.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=691355
+
+ tests/runtests.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c02a00ae9599a661076630b21b7e24e78fb88c29
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Tue Jan 8 16:56:40 2013 +0100
+
+    Use g-i stack allocation API
+
+    Where possible, i. e. when not keeping references across functions,
+    use the
+    _load_() methods instead of the _get_() ones from
+    gobject-introspection, which
+    is faster and less prone to memory leaks:
+
+      g_callable_info_get_arg () → g_callable_info_load_arg ()
+      g_callable_info_get_return_type() →
+      g_callable_info_load_return_type ()
+      g_arg_info_get_type() → g_arg_info_load_type ()
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=615982
+
+ gi/pygi-argument.c | 16 ++++------
+ gi/pygi-closure.c  | 88
+ ++++++++++++++++++++++++------------------------------
+ 2 files changed, 45 insertions(+), 59 deletions(-)
+
+commit 23d1f14f553069740465c82eaa937b877c41e0cb
+Author: Ray Strode <rstrode@redhat.com>
+Date:   Wed Dec 19 13:04:32 2012 -0500
+
+    pyg_value_from_pyobject: support GArray
+
+    This commit adds support for marshalling a python list (or other
+    sequence)
+    returned from signal handlers to GArray, if necessary.
+
+    This parallels the implementation written to marshal to (the now
+    deprecated)
+    GValueArray.
+
+    This fixes a crash in rhythmbox as seen downstream here:
+    https://bugzilla.redhat.com/show_bug.cgi?id=872851
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690514
+
+    Co-Authored-By: Martin Pitt <martinpitt@gnome.org>
+
+ gi/_gobject/pygtype.c    | 60
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ tests/test_everything.py | 22 ++++++++++++++++++
+ 2 files changed, 82 insertions(+)
+
+commit 2089dbb117bae769b0303411c2630b6f86dc7d2d
+Author: Marko Lindqvist <cazfi74@gmail.com>
+Date:   Fri Jan 4 07:01:29 2013 +0100
+
+    Fix obsolete automake macros
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=691101
+
+ configure.ac | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 6c02ab0ad720780f176192fdc6372aaa178812fd
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon Dec 31 02:53:07 2012 -0800
+
+    Change dynamic enum and flag gtype creation to use namespaced naming
+
+    Use the combination of g_base_info_get_namespace and
+    g_base_info_get_name
+    as the name for registering enum and flag types with glib through
+    g_enum_register_static and g_flags_register_static. This avoids
+    conflicts
+    with types like GLib.SeekType and Gst.SeekType. Add better exceptions
+    and memory cleanup for invalid registration problems.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690455
+
+ gi/_gobject/pygenum.c |  6 ++--
+ gi/gimodule.c         | 78
+ ++++++++++++++++++++++++++++++++++++++++++++-------
+ tests/test_gi.py      | 35 +++++++++++++++++++++++
+ 3 files changed, 106 insertions(+), 13 deletions(-)
+
+commit 692c80e11a05e2fb0515580acb22fd6fe65cede1
+Author: Dan Horák <dan@danny.cz>
+Date:   Fri Dec 28 22:12:32 2012 +0100
+
+    Fix test for GBytes.compare()
+
+    The result of the compare method is defined as equal, less than or
+    greater than zero
+    and the test must match to that. The underlaying memcmp() function
+    can return other
+    values than -1, 0 and 1. For example on architectures where it is
+    implemented directly
+    via a CPU instruction like on s390(x) where I can see -2 as a result
+    instead of the
+    "expected" -1.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690837
+
+ tests/test_gi.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 948dbcb223249a08f4398d4ad8861e92e3de0dfa
+Author: Jonathan Ballet <jon@multani.info>
+Date:   Thu Dec 27 16:04:51 2012 +0100
+
+    Fix Gtk.UIManager.add_ui_from_string() override for non-ASCII chars
+
+    The length argument is the size of the buffer in bytes, not in
+    characters.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690329
+
+    Co-Authored-By: Martin Pitt <martinpitt@gnome.org>
+
+ gi/overrides/Gtk.py         | 2 +-
+ tests/test_overrides_gtk.py | 7 +++++++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 53bc12a87da824cbfb006a4fd65731edec12ecc7
+Author: Mike Gorse <mgorse@suse.com>
+Date:   Wed Dec 19 20:51:03 2012 -0500
+
+    Don't dup strings before passing them to type registration functions
+
+    Strings passed to g_enum_register_static and g_flags_register_static
+    are
+    eventually passed to g_quark_from_string, which dups the string
+    passed to it if
+    needed and does not take ownership of it, so passing in a
+    dynamically-allocated
+    string without freeing it results in a small leak.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690532
+
+ gi/gimodule.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 9454c01f2b1b82d43eea0f72fe9a28ef50065fc9
+Author: Carlos Garnacho <carlos@lanedo.com>
+Date:   Tue Dec 18 22:47:09 2012 +0100
+
+    Fix marshalling of arrays of boxed struct values
+
+    This fixes methods like gtk_selection_set_with_data().  In such cases
+    data is passed as an array of struct pointers, so it must be converted
+    to an array of structs.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=656312
+
+    Co-Authored-By: Martin Pitt <martinpitt@gnome.org>
+
+ gi/pygi-marshal-from-py.c |  6 ++++++
+ tests/test_gi.py          | 12 ++++++++++++
+ 2 files changed, 18 insertions(+)
+
+commit 231d5a7cfc73518b4e2b0c926d4c1ce9a804797e
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Tue Dec 18 02:03:41 2012 -0800
+
+    Add reference counting tests for Object.bind_property
+
+    Add tests which ensure transform callbacks and user_data
+    are propertly ref-counted.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=690397
+
+ tests/test_gobject.py | 40 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 4 deletions(-)
+
+commit c29e11812d176b1f057074c9bab22c9614ae4f8c
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Tue Dec 18 11:43:04 2012 +0100
+
+    testhelpermodule.c: Do not unref called method
+
+    In _wrap_test_gerror_exception(), do not unref the method
+    arguments. This
+    causes a crash when being run with the stricter refcounting/memory
+    checks with
+    debug-enabled Python builds.
+
+ tests/testhelpermodule.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit ff0d9106bcd02a6b2c67cc3722481218c599a9f4
+Author: Martin Pitt <martinpitt@gnome.org>
+Date:   Mon Dec 17 23:20:50 2012 +0100
+
+    configure.ac: post-release bump to 3.7.4
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit 061b23d14386c0e54d2c3af113554231bbe85f16
 Author: Martin Pitt <martinpitt@gnome.org>
 Date:   Mon Dec 17 23:18:31 2012 +0100
diff --git a/NEWS b/NEWS
index 19ad872..4471f8e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,41 @@
+3.7.4   14-Jan-2013
+        - Allow setting values through GtkTreeModelFilter (Simonas Kazlauskas)
+          (#689624)
+        - Support GParamSpec signal arguments from Python (Martin Pitt)
+          (#683099)
+        - pygobject_emit(): Fix cleanup on error (Martin Pitt)
+        - Add signal emission methods to TreeModel which coerce the path
+          argument (Simon Feltman) (#682933)
+        - Add override for GValue (Bastian Winkler) (#677473)
+        - Mark caller-allocated boxed structures as having a slice allocated
+          (Mike Gorse) (#699501)
+        - pygi-property: Support boxed GSList/GList types (Olivier Crête)
+          (#684059)
+        - tests: Add missing backwards compat methods for Python 2.6
+          (Martin Pitt) (#691646)
+        - Allow setting TreeModel values to None (Simon Feltman) (#684094)
+        - Set clean-up handler for marshalled arrays (Mike Gorse) (#691509)
+        - Support setting string fields in structs (Vadim Rutkovsky) (#678401)
+        - Permit plain integers for "gchar" values (Martin Pitt)
+        - Allow single byte values for int8 types (Martin Pitt) (#691524)
+        - Fix invalid memory access handling errors when registering an enum
+          type (Mike Gorse)
+        - Fix (out) arguments in callbacks (Martin Pitt)
+        - Fix C to Python marshalling of struct pointer arrays (Martin Pitt)
+        - Don't let Property.setter() method names define property names
+          (Martin Pitt) (#688971)
+        - Use g-i stack allocation API (Martin Pitt) (#615982)
+        - pyg_value_from_pyobject: support GArray (Ray Strode) (#690514)
+        - Fix obsolete automake macros (Marko Lindqvist) (#691101)
+        - Change dynamic enum and flag gtype creation to use namespaced naming
+          (Simon Feltman) (#690455)
+        - Fix Gtk.UIManager.add_ui_from_string() override for non-ASCII chars
+          (Jonathan Ballet) (#690329)
+        - Don't dup strings before passing them to type registration functions
+          (Mike Gorse) (#690532)
+        - Fix marshalling of arrays of boxed struct values (Carlos Garnacho)
+          (#656312)
+
 3.7.3   17-Dec-2012
        - Add support for caller-allocated GArray out arguments (Martin Pitt)
          (#690041)
index 1956ce7..ca2e5bd 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: PyGObject
-Version: 3.7.3
+Version: 3.7.4
 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.7/pygobject-3.7.3.tar.gz
+Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.7/pygobject-3.7.4.tar.gz
 Description: Python bindings for GLib and GObject
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
index db21f54..2093554 100644 (file)
@@ -114,29 +114,6 @@ AC_PREREQ([2.50])dnl
 am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
-
-# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# This was merged into AC_PROG_CC in Autoconf.
-
-AU_DEFUN([AM_PROG_CC_STDC],
-[AC_PROG_CC
-AC_DIAGNOSE([obsolete], [$0:
-       your code should no longer depend upon `am_cv_prog_cc_stdc', but upon
-       `ac_cv_prog_cc_stdc'.  Remove this warning and the assignment when
-       you adjust the code.  You can also remove the above call to
-       AC_PROG_CC if you already called it elsewhere.])
-am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
-])
-AU_DEFUN([fp_PROG_CC_STDC])
-
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
 # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
@@ -439,18 +416,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
index 5e1cc46..2cd8aca 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.69 for pygobject 3.7.3.
+# Generated by GNU Autoconf 2.69 for pygobject 3.7.4.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='pygobject'
 PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.7.3'
-PACKAGE_STRING='pygobject 3.7.3'
+PACKAGE_VERSION='3.7.4'
+PACKAGE_STRING='pygobject 3.7.4'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
 PACKAGE_URL='https://live.gnome.org/PyGObject/'
 
@@ -1391,7 +1391,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.7.3 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.7.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1461,7 +1461,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pygobject 3.7.3:";;
+     short | recursive ) echo "Configuration of pygobject 3.7.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1593,7 +1593,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pygobject configure 3.7.3
+pygobject configure 3.7.4
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1871,7 +1871,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.7.3, which was
+It was created by pygobject $as_me 3.7.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2235,9 +2235,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 7" >>confdefs.h
 PYGOBJECT_MINOR_VERSION=7
 
 
-$as_echo "#define PYGOBJECT_MICRO_VERSION 3" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 4" >>confdefs.h
 
-PYGOBJECT_MICRO_VERSION=3
+PYGOBJECT_MICRO_VERSION=4
 
 
 ac_config_headers="$ac_config_headers config.h"
@@ -2748,7 +2748,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pygobject'
- VERSION='3.7.3'
+ VERSION='3.7.4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12419,676 +12419,6 @@ else
 fi
 
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-depcc="$CC"   am_compiler_list=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CC_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
-  # We make a subdir and do the tests there.  Otherwise we can end up
-  # making bogus files that we don't know about and never remove.  For
-  # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named `D' -- because `-MD' means `put the output
-  # in D'.
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  # Copy depcomp to subdir because otherwise we won't find it if we're
-  # using a relative directory.
-  cp "$am_depcomp" conftest.dir
-  cd conftest.dir
-  # We will build objects and dependencies in a subdirectory because
-  # it helps to detect inapplicable dependency modes.  For instance
-  # both Tru64's cc and ICC support -MD to output dependencies as a
-  # side effect of compilation, but ICC will put the dependencies in
-  # the current directory while Tru64 will put them in the object
-  # directory.
-  mkdir sub
-
-  am_cv_CC_dependencies_compiler_type=none
-  if test "$am_compiler_list" = ""; then
-     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
-  fi
-  am__universal=false
-  case " $depcc " in #(
-     *\ -arch\ *\ -arch\ *) am__universal=true ;;
-     esac
-
-  for depmode in $am_compiler_list; do
-    # Setup a source with many dependencies, because some compilers
-    # like to wrap large dependency lists on column 80 (with \), and
-    # we should not choose a depcomp mode which is confused by this.
-    #
-    # We need to recreate these files for each test, as the compiler may
-    # overwrite some of them when testing with obscure command lines.
-    # This happens at least with the AIX C compiler.
-    : > sub/conftest.c
-    for i in 1 2 3 4 5 6; do
-      echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
-      # Solaris 8's {/usr,}/bin/sh.
-      touch sub/conftst$i.h
-    done
-    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
-    # We check with `-c' and `-o' for the sake of the "dashmstdout"
-    # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle `-M -o', and we need to detect this.  Also, some Intel
-    # versions had trouble with output in subdirs
-    am__obj=sub/conftest.${OBJEXT-o}
-    am__minus_obj="-o $am__obj"
-    case $depmode in
-    gcc)
-      # This depmode causes a compiler race in universal mode.
-      test "$am__universal" = false || continue
-      ;;
-    nosideeffect)
-      # after this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested
-      if test "x$enable_dependency_tracking" = xyes; then
-       continue
-      else
-       break
-      fi
-      ;;
-    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
-      # This compiler won't grok `-c -o', but also, the minuso test has
-      # not run yet.  These depmodes are late enough in the game, and
-      # so weak that their functioning should not be impacted.
-      am__obj=conftest.${OBJEXT-o}
-      am__minus_obj=
-      ;;
-    none) break ;;
-    esac
-    if depmode=$depmode \
-       source=sub/conftest.c object=$am__obj \
-       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
-       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
-         >/dev/null 2>conftest.err &&
-       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
-       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
-       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
-       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
-      # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
-        am_cv_CC_dependencies_compiler_type=$depmode
-        break
-      fi
-    fi
-  done
-
-  cd ..
-  rm -rf conftest.dir
-else
-  am_cv_CC_dependencies_compiler_type=none
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
-
- if
-  test "x$enable_dependency_tracking" != xno \
-  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
-  am__fastdepCC_TRUE=
-  am__fastdepCC_FALSE='#'
-else
-  am__fastdepCC_TRUE='#'
-  am__fastdepCC_FALSE=
-fi
-
-
-
-am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
-
 if test "x$CC" != xcc; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
@@ -15552,10 +14882,6 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
-  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${HAVE_LIBFFI_TRUE}" && test -z "${HAVE_LIBFFI_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_LIBFFI\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -15965,7 +15291,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.7.3, which was
+This file was extended by pygobject $as_me 3.7.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16032,7 +15358,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.7.3
+pygobject config.status 3.7.4
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index dd5e078..6b88bba 100644 (file)
@@ -18,7 +18,7 @@ m4_define(python3_min_ver, 3.1)
 dnl the pygobject version number
 m4_define(pygobject_major_version, 3)
 m4_define(pygobject_minor_version, 7)
-m4_define(pygobject_micro_version, 3)
+m4_define(pygobject_micro_version, 4)
 m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
 
 dnl versions of packages we require ...
@@ -42,7 +42,7 @@ AC_SUBST(PYGOBJECT_MINOR_VERSION, pygobject_minor_version)
 AC_DEFINE(PYGOBJECT_MICRO_VERSION, pygobject_micro_version, [pygobject micro version])
 AC_SUBST(PYGOBJECT_MICRO_VERSION, pygobject_micro_version)
 
-AM_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS(config.h)
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)])
 AM_INIT_AUTOMAKE([1.11.1 foreign no-dist-gzip dist-xz])
 
@@ -80,7 +80,6 @@ LT_INIT([dlopen win32-dll disable-static])
 
 AC_SEARCH_LIBS([strerror],[cposix])
 AC_PROG_CC
-AM_PROG_CC_STDC
 AM_PROG_CC_C_O
 
 # option to specify python interpreter to use; this just sets $PYTHON, so that
index a038f1b..d5a1852 100644 (file)
@@ -149,6 +149,8 @@ class Property(object):
         @keyword maximum:  maximum allowed value (int, float, long only)
         """
 
+        self.name = None
+
         if type is None:
             type = object
         self.type = self._type_from_python(type)
@@ -180,7 +182,9 @@ class Property(object):
             getter = self._default_getter
             setter = self._default_setter
         self.getter(getter)
-        self.setter(setter)
+        # do not call self.setter() here, as this defines the property name
+        # already
+        self.fset = setter
 
         if minimum is not None:
             if minimum < self._get_minimum():
@@ -199,8 +203,6 @@ class Property(object):
             maximum = self._get_maximum()
         self.maximum = maximum
 
-        self.name = None
-
         self._exc = None
 
     def __repr__(self):
@@ -248,6 +250,11 @@ class Property(object):
     def setter(self, fset):
         """Set the setter function to fset. For use as a decorator."""
         self.fset = fset
+        # with a setter decorator, we must ignore the name of the method in
+        # install_properties, as this does not need to be a valid property name
+        # and does not define the property name. So set the name here.
+        if not self.name:
+            self.name = self.fget.__name__
         return self
 
     def _type_from_python(self, type_):
@@ -364,10 +371,18 @@ def install_properties(cls):
     props = []
     for name, prop in cls.__dict__.items():
         if isinstance(prop, Property):  # not same as the built-in
-            if name in gproperties:
-                raise ValueError('Property %s was already found in __gproperties__' % name)
-            prop.name = name
-            gproperties[name] = prop.get_pspec_args()
+            # if a property was defined with a decorator, it may already have
+            # a name; if it was defined with an assignment (prop = Property(...))
+            # we set the property's name to the member name
+            if not prop.name:
+                prop.name = name
+            # we will encounter the same property multiple times in case of
+            # custom setter methods
+            if prop.name in gproperties:
+                if gproperties[prop.name] == prop.get_pspec_args():
+                    continue
+                raise ValueError('Property %s was already found in __gproperties__' % prop.name)
+            gproperties[prop.name] = prop.get_pspec_args()
             props.append(prop)
 
     if not props:
index 9c3c455..89e3a06 100644 (file)
@@ -216,9 +216,9 @@ pyg_enum_add (PyObject *   module,
     int i;
 
     g_return_val_if_fail(typename != NULL, NULL);
-    if (!g_type_is_a(gtype, G_TYPE_ENUM)) {
-        g_warning("Trying to register gtype '%s' as enum when in fact it is of type '%s'",
-                  g_type_name(gtype), g_type_name(G_TYPE_FUNDAMENTAL(gtype)));
+    if (!g_type_is_a (gtype, G_TYPE_ENUM)) {
+        PyErr_Format (PyExc_TypeError, "Trying to register gtype '%s' as enum when in fact it is of type '%s'",
+                      g_type_name (gtype), g_type_name (G_TYPE_FUNDAMENTAL (gtype)));
         return NULL;
     }
 
index 3d0c819..00444bd 100644 (file)
@@ -1872,7 +1872,7 @@ pygobject_handler_unblock(PyGObject *self, PyObject *args)
 static PyObject *
 pygobject_emit(PyGObject *self, PyObject *args)
 {
-    guint signal_id, i;
+    guint signal_id, i, j;
     Py_ssize_t len;
     GQuark detail;
     PyObject *first, *py_ret, *repr = NULL;
@@ -1929,11 +1929,11 @@ pygobject_emit(PyGObject *self, PyObject *args)
            g_snprintf(buf, sizeof(buf),
                       "could not convert type %s to %s required for parameter %d",
                       Py_TYPE(item)->tp_name,
-               g_type_name(G_VALUE_TYPE(&params[i+1])), i);
+                       G_VALUE_TYPE_NAME(&params[i+1]), i);
            PyErr_SetString(PyExc_TypeError, buf);
 
-           for (i = 0; i < query.n_params + 1; i++)
-               g_value_unset(&params[i]);
+           for (j = 0; j <= i; j++)
+               g_value_unset(&params[j]);
 
            g_free(params);
            return NULL;
index 79c8387..227178f 100644 (file)
@@ -727,6 +727,63 @@ pyg_value_array_from_pyobject(GValue *value,
     return 0;
 }
 
+static int
+pyg_array_from_pyobject(GValue *value,
+                       PyObject *obj)
+{
+    int len;
+    GArray *array;
+    int i;
+
+    len = PySequence_Length(obj);
+    if (len == -1) {
+       PyErr_Clear();
+       return -1;
+    }
+
+    array = g_array_new(FALSE, TRUE, sizeof(GValue));
+
+    for (i = 0; i < len; ++i) {
+       PyObject *item = PySequence_GetItem(obj, i);
+       GType type;
+       GValue item_value = { 0, };
+       int status;
+
+       if (! item) {
+           PyErr_Clear();
+           g_array_free(array, FALSE);
+           return -1;
+       }
+
+       if (item == Py_None)
+           type = G_TYPE_POINTER; /* store None as NULL */
+       else {
+           type = pyg_type_from_object((PyObject*)Py_TYPE(item));
+           if (! type) {
+               PyErr_Clear();
+               g_array_free(array, FALSE);
+               Py_DECREF(item);
+               return -1;
+           }
+       }
+
+       g_value_init(&item_value, type);
+       status = pyg_value_from_pyobject(&item_value, item);
+       Py_DECREF(item);
+
+       if (status == -1) {
+           g_array_free(array, FALSE);
+           g_value_unset(&item_value);
+           return -1;
+       }
+
+       g_array_append_val(array, item_value);
+    }
+
+    g_value_take_boxed(value, array);
+    return 0;
+}
+
 /**
  * pyg_value_from_pyobject:
  * @value: the GValue object to store the converted value in.
@@ -766,12 +823,20 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
        }
        break;
     case G_TYPE_CHAR:
+       if (PYGLIB_PyLong_Check(obj)) {
+           glong val;
+           val = PYGLIB_PyLong_AsLong(obj);
+           if (val >= -128 && val <= 127)
+               g_value_set_schar(value, (gchar) val);
+           else
+               return -1;
+       }
 #if PY_VERSION_HEX < 0x03000000
-       if (PyString_Check(obj)) {
+       else if (PyString_Check(obj)) {
            g_value_set_schar(value, PyString_AsString(obj)[0]);
-       } else
+       }
 #endif
-       if (PyUnicode_Check(obj)) {
+       else if (PyUnicode_Check(obj)) {
            tmp = PyUnicode_AsUTF8String(obj);
            g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
            Py_DECREF(tmp);
@@ -786,7 +851,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
            glong val;
            val = PYGLIB_PyLong_AsLong(obj);
            if (val >= 0 && val <= 255)
-             g_value_set_uchar(value, (guchar)PYGLIB_PyLong_AsLong (obj));
+             g_value_set_uchar(value, (guchar) val);
            else
              return -1;
 #if PY_VERSION_HEX < 0x03000000
@@ -959,6 +1024,9 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
         else if (PySequence_Check(obj) &&
                   G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
            return pyg_value_array_from_pyobject(value, obj, NULL);
+        else if (PySequence_Check(obj) &&
+                  G_VALUE_HOLDS(value, G_TYPE_ARRAY))
+           return pyg_array_from_pyobject(value, obj);
        else if (PYGLIB_PyUnicode_Check(obj) &&
                  G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
             GString *string;
@@ -980,7 +1048,11 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
        break;
     }
     case G_TYPE_PARAM:
-       if (PyGParamSpec_Check(obj))
+        /* we need to support both the wrapped _gobject.GParamSpec and the GI
+         * GObject.ParamSpec */
+        if (G_IS_PARAM_SPEC (pygobject_get (obj)))
+           g_value_set_param(value, G_PARAM_SPEC (pygobject_get (obj)));
+        else if (PyGParamSpec_Check(obj))
            g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
        else
            return -1;
index 76530f1..bb5c306 100644 (file)
@@ -62,7 +62,9 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
     gint n_values;
     GEnumValue *g_enum_values;
     int i;
+    const gchar *namespace;
     const gchar *type_name;
+    gchar *full_name;
     GType g_type;
 
     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
@@ -79,6 +81,10 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
 
     info = (GIEnumInfo *)py_info->info;
     n_values = g_enum_info_get_n_values (info);
+
+    /* The new memory is zero filled which fulfills the registration
+     * function requirement that the last item is zeroed out as a terminator.
+     */
     g_enum_values = g_new0 (GEnumValue, n_values + 1);
 
     for (i = 0; i < n_values; i++) {
@@ -105,14 +111,36 @@ _wrap_pyg_enum_register_new_gtype_and_add (PyObject *self,
         g_base_info_unref ((GIBaseInfo *) value_info);
     }
 
-    g_enum_values[n_values].value = 0;
-    g_enum_values[n_values].value_nick = NULL;
-    g_enum_values[n_values].value_name = NULL;
-
+    namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
     type_name = g_base_info_get_name ((GIBaseInfo *) info);
-    type_name = g_strdup (type_name);
-    g_type = g_enum_register_static (type_name, g_enum_values);
+    full_name = g_strconcat (namespace, type_name, NULL);
+
+    /* If enum registration fails, free all the memory allocated
+     * for the values array. This needs to leak when successful
+     * as GObject keeps a reference to the data as specified in the docs.
+     */
+    g_type = g_enum_register_static (full_name, g_enum_values);
+    if (g_type == G_TYPE_INVALID) {
+        for (i = 0; i < n_values; i++) {
+            GEnumValue *enum_value = &g_enum_values[i];
+
+            /* Only free value_name if it is different from value_nick to avoid
+             * a double free. The pointer might have been is re-used in the case
+             * c_identifier was NULL in the above loop.
+             */
+            if (enum_value->value_name != enum_value->value_nick)
+                g_free ((gchar *) enum_value->value_name);
+            g_free ((gchar *) enum_value->value_nick);
+        }
+
+        PyErr_Format (PyExc_RuntimeError, "Unable to register enum '%s'", full_name);
+
+        g_free (g_enum_values);
+        g_free (full_name);
+        return NULL;
+    }
 
+    g_free (full_name);
     return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
 }
 
@@ -150,7 +178,9 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
     gint n_values;
     GFlagsValue *g_flags_values;
     int i;
+    const gchar *namespace;
     const gchar *type_name;
+    gchar *full_name;
     GType g_type;
 
     if (!PyArg_ParseTupleAndKeywords (args, kwargs,
@@ -167,6 +197,10 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
 
     info = (GIEnumInfo *)py_info->info;
     n_values = g_enum_info_get_n_values (info);
+
+    /* The new memory is zero filled which fulfills the registration
+     * function requirement that the last item is zeroed out as a terminator.
+     */
     g_flags_values = g_new0 (GFlagsValue, n_values + 1);
 
     for (i = 0; i < n_values; i++) {
@@ -193,14 +227,36 @@ _wrap_pyg_flags_register_new_gtype_and_add (PyObject *self,
         g_base_info_unref ((GIBaseInfo *) value_info);
     }
 
-    g_flags_values[n_values].value = 0;
-    g_flags_values[n_values].value_nick = NULL;
-    g_flags_values[n_values].value_name = NULL;
-
+    namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
     type_name = g_base_info_get_name ((GIBaseInfo *) info);
-    type_name = g_strdup (type_name);
-    g_type = g_flags_register_static (type_name, g_flags_values);
+    full_name = g_strconcat (namespace, type_name, NULL);
+
+    /* If enum registration fails, free all the memory allocated
+     * for the values array. This needs to leak when successful
+     * as GObject keeps a reference to the data as specified in the docs.
+     */
+    g_type = g_flags_register_static (full_name, g_flags_values);
+    if (g_type == G_TYPE_INVALID) {
+        for (i = 0; i < n_values; i++) {
+            GFlagsValue *flags_value = &g_flags_values[i];
+
+            /* Only free value_name if it is different from value_nick to avoid
+             * a double free. The pointer might have been is re-used in the case
+             * c_identifier was NULL in the above loop.
+             */
+            if (flags_value->value_name != flags_value->value_nick)
+                g_free ((gchar *) flags_value->value_name);
+            g_free ((gchar *) flags_value->value_nick);
+        }
+
+        PyErr_Format (PyExc_RuntimeError, "Unable to register flags '%s'", full_name);
+
+        g_free (g_flags_values);
+        g_free (full_name);
+        return NULL;
+    }
 
+    g_free (full_name);
     return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
 }
 
index c0198b3..41062e2 100644 (file)
@@ -4,6 +4,7 @@
 # Copyright (C) 2012 Canonical Ltd.
 # Author: Martin Pitt <martin.pitt@ubuntu.com>
 # Copyright (C) 2012 Simon Feltman <sfeltman@src.gnome.org>
+# Copyright (C) 2012 Bastian Winkler <buz@netbuz.org>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -205,10 +206,134 @@ __all__ += ['add_emission_hook', 'features', 'list_properties',
 
 
 class Value(GObjectModule.Value):
+    def __new__(cls, *args, **kwargs):
+        return GObjectModule.Value.__new__(cls)
+
+    def __init__(self, value_type=None, py_value=None):
+        GObjectModule.Value.__init__(self)
+        if value_type is not None:
+            self.init(value_type)
+            if py_value is not None:
+                self.set_value(py_value)
+
     def __del__(self):
-        if self._free_on_dealloc:
+        if self._free_on_dealloc and self.g_type != TYPE_INVALID:
             self.unset()
 
+    def set_value(self, py_value):
+        if self.g_type == _gobject.TYPE_INVALID:
+            raise TypeError("GObject.Value needs to be initialized first")
+        elif self.g_type == TYPE_BOOLEAN:
+            self.set_boolean(py_value)
+        elif self.g_type == TYPE_CHAR:
+            self.set_char(py_value)
+        elif self.g_type == TYPE_UCHAR:
+            self.set_uchar(py_value)
+        elif self.g_type == TYPE_INT:
+            self.set_int(py_value)
+        elif self.g_type == TYPE_UINT:
+            self.set_uint(py_value)
+        elif self.g_type == TYPE_LONG:
+            self.set_long(py_value)
+        elif self.g_type == TYPE_ULONG:
+            self.set_ulong(py_value)
+        elif self.g_type == TYPE_INT64:
+            self.set_int64(py_value)
+        elif self.g_type == TYPE_UINT64:
+            self.set_uint64(py_value)
+        elif self.g_type == TYPE_FLOAT:
+            self.set_float(py_value)
+        elif self.g_type == TYPE_DOUBLE:
+            self.set_double(py_value)
+        elif self.g_type == TYPE_STRING:
+            if isinstance(py_value, str):
+                py_value = str(py_value)
+            elif sys.version_info < (3, 0):
+                if isinstance(py_value, unicode):
+                    py_value = py_value.encode('UTF-8')
+                else:
+                    raise ValueError("Expected string or unicode but got %s%s" %
+                                     (py_value, type(py_value)))
+            else:
+                raise ValueError("Expected string but got %s%s" %
+                                 (py_value, type(py_value)))
+            self.set_string(py_value)
+        elif self.g_type == TYPE_PARAM:
+            self.set_param(py_value)
+        elif self.g_type.is_a(TYPE_ENUM):
+            self.set_enum(py_value)
+        elif self.g_type.is_a(TYPE_FLAGS):
+            self.set_flags(py_value)
+        elif self.g_type.is_a(TYPE_BOXED):
+            self.set_boxed(py_value)
+        elif self.g_type == TYPE_POINTER:
+            self.set_pointer(py_value)
+        elif self.g_type.is_a(TYPE_OBJECT):
+            self.set_object(py_value)
+        elif self.g_type == TYPE_UNICHAR:
+            self.set_uint(int(py_value))
+        # elif self.g_type == TYPE_OVERRIDE:
+        #     pass
+        elif self.g_type == TYPE_GTYPE:
+            self.set_gtype(py_value)
+        elif self.g_type == TYPE_VARIANT:
+            self.set_variant(py_value)
+        elif self.g_type == TYPE_PYOBJECT:
+            self.set_boxed(py_value)
+        else:
+            raise TypeError("Unknown value type %s" % self.g_type)
+
+    def get_value(self):
+        if self.g_type == TYPE_BOOLEAN:
+            return self.get_boolean()
+        elif self.g_type == TYPE_CHAR:
+            return self.get_char()
+        elif self.g_type == TYPE_UCHAR:
+            return self.get_uchar()
+        elif self.g_type == TYPE_INT:
+            return self.get_int()
+        elif self.g_type == TYPE_UINT:
+            return self.get_uint()
+        elif self.g_type == TYPE_LONG:
+            return self.get_long()
+        elif self.g_type == TYPE_ULONG:
+            return self.get_ulong()
+        elif self.g_type == TYPE_INT64:
+            return self.get_int64()
+        elif self.g_type == TYPE_UINT64:
+            return self.get_uint64()
+        elif self.g_type == TYPE_FLOAT:
+            return self.get_float()
+        elif self.g_type == TYPE_DOUBLE:
+            return self.get_double()
+        elif self.g_type == TYPE_STRING:
+            return self.get_string()
+        elif self.g_type == TYPE_PARAM:
+            return self.get_param()
+        elif self.g_type.is_a(TYPE_ENUM):
+            return self.get_enum()
+        elif self.g_type.is_a(TYPE_FLAGS):
+            return self.get_flags()
+        elif self.g_type.is_a(TYPE_BOXED):
+            return self.get_boxed()
+        elif self.g_type == TYPE_POINTER:
+            return self.get_pointer()
+        elif self.g_type.is_a(TYPE_OBJECT):
+            return self.get_object()
+        elif self.g_type == TYPE_UNICHAR:
+            return self.get_uint()
+        elif self.g_type == TYPE_GTYPE:
+            return self.get_gtype()
+        elif self.g_type == TYPE_VARIANT:
+            return self.get_variant()
+        elif self.g_type == TYPE_PYOBJECT:
+            pass
+        else:
+            return None
+
+    def __repr__(self):
+        return '<Value (%s) %s>' % (self.g_type.name, self.get_value())
+
 Value = override(Value)
 __all__.append('Value')
 
index 78bbd36..15c0ae6 100644 (file)
@@ -294,7 +294,7 @@ class UIManager(Gtk.UIManager):
         if not isinstance(buffer, _basestring):
             raise TypeError('buffer must be a string')
 
-        length = len(buffer)
+        length = len(buffer.encode('UTF-8'))
 
         return Gtk.UIManager.add_ui_from_string(self, buffer, length)
 
@@ -780,6 +780,12 @@ class TreeModel(Gtk.TreeModel):
                 raise IndexError("could not find tree path '%s'" % key)
             return aiter
 
+    def _coerce_path(self, path):
+        if isinstance(path, Gtk.TreePath):
+            return path
+        else:
+            return TreePath(path)
+
     def __getitem__(self, key):
         aiter = self._getiter(key)
         return TreeModelRow(self, aiter)
@@ -796,9 +802,7 @@ class TreeModel(Gtk.TreeModel):
         return TreeModelRowIter(self, self.get_iter_first())
 
     def get_iter(self, path):
-        if not isinstance(path, Gtk.TreePath):
-            path = TreePath(path)
-
+        path = self._coerce_path(path)
         success, aiter = super(TreeModel, self).get_iter(path)
         if not success:
             raise ValueError("invalid tree path '%s'" % path)
@@ -872,84 +876,11 @@ class TreeModel(Gtk.TreeModel):
             self.set_value(treeiter, column, value)
 
     def _convert_value(self, column, value):
-        if value is None:
-            return None
+        '''Convert value to a GObject.Value of the expected type'''
 
-        # we may need to convert to a basic type
-        type_ = self.get_column_type(column)
-        if type_ == GObject.TYPE_STRING:
-            if isinstance(value, str):
-                value = str(value)
-            elif sys.version_info < (3, 0):
-                if isinstance(value, unicode):
-                    value = value.encode('UTF-8')
-                else:
-                    raise ValueError('Expected string or unicode for column %i but got %s%s' % (column, value, type(value)))
-            else:
-                raise ValueError('Expected a string for column %i but got %s' % (column, type(value)))
-        elif type_ == GObject.TYPE_FLOAT or type_ == GObject.TYPE_DOUBLE:
-            if isinstance(value, float):
-                value = float(value)
-            else:
-                raise ValueError('Expected a float for column %i but got %s' % (column, type(value)))
-        elif type_ == GObject.TYPE_LONG or type_ == GObject.TYPE_INT:
-            if isinstance(value, int):
-                value = int(value)
-            elif sys.version_info < (3, 0):
-                if isinstance(value, long):
-                    value = long(value)
-                else:
-                    raise ValueError('Expected an long for column %i but got %s' % (column, type(value)))
-            else:
-                raise ValueError('Expected an integer for column %i but got %s' % (column, type(value)))
-        elif type_ == GObject.TYPE_BOOLEAN:
-            cmp_classes = [int]
-            if sys.version_info < (3, 0):
-                cmp_classes.append(long)
-
-            if isinstance(value, tuple(cmp_classes)):
-                value = bool(value)
-            else:
-                raise ValueError('Expected a bool for column %i but got %s' % (column, type(value)))
-        else:
-            # use GValues directly to marshal to the correct type
-            # standard object checks should take care of validation
-            # so we don't have to do it here
-            value_container = GObject.Value()
-            value_container.init(type_)
-            if type_ == GObject.TYPE_CHAR:
-                value_container.set_char(value)
-                value = value_container
-            elif type_ == GObject.TYPE_UCHAR:
-                value_container.set_uchar(value)
-                value = value_container
-            elif type_ == GObject.TYPE_UNICHAR:
-                cmp_classes = [str]
-                if sys.version_info < (3, 0):
-                    cmp_classes.append(unicode)
-
-                if isinstance(value, tuple(cmp_classes)):
-                    value = ord(value[0])
-
-                value_container.set_uint(value)
-                value = value_container
-            elif type_ == GObject.TYPE_UINT:
-                value_container.set_uint(value)
-                value = value_container
-            elif type_ == GObject.TYPE_ULONG:
-                value_container.set_ulong(value)
-                value = value_container
-            elif type_ == GObject.TYPE_INT64:
-                value_container.set_int64(value)
-                value = value_container
-            elif type_ == GObject.TYPE_UINT64:
-                value_container.set_uint64(value)
-                value = value_container
-            elif type_ == GObject.TYPE_PYOBJECT:
-                value_container.set_boxed(value)
-                value = value_container
-
-        return value
+        if isinstance(value, GObject.Value):
+            return value
+        return GObject.Value(self.get_column_type(column), value)
 
     def get(self, treeiter, *columns):
         n_columns = self.get_n_columns()
@@ -969,6 +900,27 @@ class TreeModel(Gtk.TreeModel):
     def filter_new(self, root=None):
         return super(TreeModel, self).filter_new(root)
 
+    #
+    # Signals supporting python iterables as tree paths
+    #
+    def row_changed(self, path, iter):
+        return super(TreeModel, self).row_changed(self._coerce_path(path), iter)
+
+    def row_inserted(self, path, iter):
+        return super(TreeModel, self).row_inserted(self._coerce_path(path), iter)
+
+    def row_has_child_toggled(self, path, iter):
+        return super(TreeModel, self).row_has_child_toggled(self._coerce_path(path),
+                                                            iter)
+
+    def row_deleted(self, path):
+        return super(TreeModel, self).row_deleted(self._coerce_path(path))
+
+    def rows_reordered(self, path, iter, new_order):
+        return super(TreeModel, self).rows_reordered(self._coerce_path(path),
+                                                     iter, new_order)
+
+
 TreeModel = override(TreeModel)
 __all__.append('TreeModel')
 
@@ -1592,6 +1544,11 @@ class TreeModelFilter(Gtk.TreeModelFilter):
     def set_visible_func(self, func, data=None):
         super(TreeModelFilter, self).set_visible_func(func, data)
 
+    def set_value(self, iter, column, value):
+        # Delegate to child model
+        iter = self.convert_iter_to_child_iter(iter)
+        self.get_model().set_value(iter, column, value)
+
 TreeModelFilter = override(TreeModelFilter)
 __all__.append('TreeModelFilter')
 
index 4e3c464..34c4970 100644 (file)
@@ -410,7 +410,8 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
             /* No check; every Python object has a truth value. */
             break;
         case GI_TYPE_TAG_UINT8:
-            /* UINT8 types can be characters */
+        case GI_TYPE_TAG_INT8:
+            /* (U)INT8 types can be characters */
             if (PYGLIB_PyBytes_Check(object)) {
                 if (PYGLIB_PyBytes_Size(object) != 1) {
                     PyErr_Format (PyExc_TypeError, "Must be a single character");
@@ -420,7 +421,6 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
 
                 break;
             }
-        case GI_TYPE_TAG_INT8:
         case GI_TYPE_TAG_INT16:
         case GI_TYPE_TAG_UINT16:
         case GI_TYPE_TAG_INT32:
@@ -811,22 +811,18 @@ _pygi_argument_to_array (GIArgument  *arg,
                         return g_array;
                     }
                     gint length_arg_pos;
-                    GIArgInfo *length_arg_info;
-                    GITypeInfo *length_type_info;
+                    GIArgInfo length_arg_info;
+                    GITypeInfo length_type_info;
 
                     length_arg_pos = g_type_info_get_array_length (type_info);
                     g_assert (length_arg_pos >= 0);
                     g_assert (callable_info);
-                    length_arg_info = g_callable_info_get_arg (callable_info, length_arg_pos);
-                    length_type_info = g_arg_info_get_type (length_arg_info);
-                    g_base_info_unref ( (GIBaseInfo *) length_arg_info);
+                    g_callable_info_load_arg (callable_info, length_arg_pos, &length_arg_info);
+                    g_arg_info_load_type (&length_arg_info, &length_type_info);
                     if (!gi_argument_to_gssize (args[length_arg_pos],
-                                                g_type_info_get_tag (length_type_info),
-                                                &length)) {
-                        g_base_info_unref ( (GIBaseInfo *) length_type_info);
+                                                g_type_info_get_tag (&length_type_info),
+                                                &length))
                         return NULL;
-                    }
-                    g_base_info_unref ( (GIBaseInfo *) length_type_info);
                 }
             }
 
index 2a44c02..0848ccf 100644 (file)
@@ -480,6 +480,7 @@ _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
             child_cache = _arg_cache_alloc ();
         } else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
                    child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
+            arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
             return TRUE;
         }
 
index 0e49c72..f2f21f0 100644 (file)
@@ -154,8 +154,8 @@ static GIArgument *
 _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
 {
     gint num_args, i;
-    GIArgInfo *arg_info;
-    GITypeInfo *arg_type;
+    GIArgInfo arg_info;
+    GITypeInfo arg_type;
     GITypeTag tag;
     GIDirection direction;
     GIArgument *g_args;
@@ -164,10 +164,10 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
     g_args = g_new0 (GIArgument, num_args);
 
     for (i = 0; i < num_args; i++) {
-        arg_info = g_callable_info_get_arg (callable_info, i);
-        arg_type = g_arg_info_get_type (arg_info);
-        tag = g_type_info_get_tag (arg_type);
-        direction = g_arg_info_get_direction (arg_info);
+        g_callable_info_load_arg (callable_info, i, &arg_info);
+        g_arg_info_load_type (&arg_info, &arg_type);
+        tag = g_type_info_get_tag (&arg_type);
+        direction = g_arg_info_get_direction (&arg_info);
 
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
             g_args[i].v_pointer = * (gpointer *) args[i];
@@ -214,7 +214,7 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
                     GIBaseInfo *interface;
                     GIInfoType interface_type;
 
-                    interface = g_type_info_get_interface (arg_type);
+                    interface = g_type_info_get_interface (&arg_type);
                     interface_type = g_base_info_get_type (interface);
 
                     if (interface_type == GI_INFO_TYPE_OBJECT ||
@@ -249,8 +249,6 @@ _pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args)
                     g_args[i].v_pointer = 0;
             }
         }
-        g_base_info_unref ( (GIBaseInfo *) arg_info);
-        g_base_info_unref ( (GIBaseInfo *) arg_type);
     }
     return g_args;
 }
@@ -283,19 +281,21 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
         if (i == user_data_arg || i == destroy_notify_arg)
             continue;
 
-        GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i);
-        GIDirection direction = g_arg_info_get_direction (arg_info);
+        GIArgInfo arg_info;
+        g_callable_info_load_arg (callable_info, i, &arg_info);
+        GIDirection direction = g_arg_info_get_direction (&arg_info);
 
         if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
-            GITypeInfo *arg_type = g_arg_info_get_type (arg_info);
-            GITypeTag arg_tag = g_type_info_get_tag (arg_type);
-            GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
+            GITypeInfo arg_type;
+            g_arg_info_load_type (&arg_info, &arg_type);
+            GITypeTag arg_tag = g_type_info_get_tag (&arg_type);
+            GITransfer transfer = g_arg_info_get_ownership_transfer (&arg_info);
             PyObject *value;
             GIArgument *arg;
             gboolean free_array = FALSE;
 
             if (direction == GI_DIRECTION_IN && arg_tag == GI_TYPE_TAG_VOID &&
-                    g_type_info_is_pointer (arg_type)) {
+                    g_type_info_is_pointer (&arg_type)) {
 
                 if (user_data == NULL) {
                     Py_INCREF (Py_None);
@@ -310,7 +310,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
                 GIBaseInfo *info;
                 GIInfoType info_type;
 
-                info = g_type_info_get_interface (arg_type);
+                info = g_type_info_get_interface (&arg_type);
                 info_type = g_base_info_get_type (info);
 
                 arg = (GIArgument*) &g_args[i];
@@ -318,10 +318,10 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
                 if (info_type == GI_INFO_TYPE_CALLBACK) {
                     gpointer user_data = NULL;
                     GDestroyNotify destroy_notify = NULL;
-                    GIScopeType scope = g_arg_info_get_scope(arg_info);
+                    GIScopeType scope = g_arg_info_get_scope(&arg_info);
 
-                    user_data_arg = g_arg_info_get_closure(arg_info);
-                    destroy_notify_arg = g_arg_info_get_destroy(arg_info);
+                    user_data_arg = g_arg_info_get_closure(&arg_info);
+                    destroy_notify_arg = g_arg_info_get_destroy(&arg_info);
 
                     if (user_data_arg != -1)
                         user_data = g_args[user_data_arg].v_pointer;
@@ -335,39 +335,31 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
                                                 (GIFunctionInfo *) info,
                                                 destroy_notify);
                 } else
-                    value = _pygi_argument_to_object (arg, arg_type, transfer);
+                    value = _pygi_argument_to_object (arg, &arg_type, transfer);
 
                 g_base_info_unref (info);
-                if (value == NULL) {
-                    g_base_info_unref (arg_type);
-                    g_base_info_unref (arg_info);
+                if (value == NULL)
                     goto error;
-                }
             } else {
                 if (direction == GI_DIRECTION_IN)
                     arg = (GIArgument*) &g_args[i];
                 else
                     arg = (GIArgument*) g_args[i].v_pointer;
                 
-                if (g_type_info_get_tag (arg_type) == GI_TYPE_TAG_ARRAY)
+                if (g_type_info_get_tag (&arg_type) == GI_TYPE_TAG_ARRAY)
                     arg->v_pointer = _pygi_argument_to_array (arg, (GIArgument **) args, 
-                                                              callable_info, arg_type, &free_array);
+                                                              callable_info, &arg_type, &free_array);
 
-                value = _pygi_argument_to_object (arg, arg_type, transfer);
+                value = _pygi_argument_to_object (arg, &arg_type, transfer);
                 
                 if (free_array)
                     g_array_free (arg->v_pointer, FALSE);
                 
-                if (value == NULL) {
-                    g_base_info_unref (arg_type);
-                    g_base_info_unref (arg_info);
+                if (value == NULL)
                     goto error;
-                }
             }
             PyTuple_SET_ITEM (*py_args, n_in_args, value);
             n_in_args++;
-
-            g_base_info_unref (arg_type);
         }
 
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
@@ -375,7 +367,6 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
             n_out_args++;
         }
 
-        g_base_info_unref (arg_info);
     }
 
     if (_PyTuple_Resize (py_args, n_in_args) == -1)
@@ -399,37 +390,38 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
                                  void *resp)
 {
     int n_args, i, i_py_retval, i_out_args;
-    GITypeInfo *return_type_info;
+    GITypeInfo return_type_info;
     GITypeTag return_type_tag;
 
     i_py_retval = 0;
-    return_type_info = g_callable_info_get_return_type (callable_info);
-    return_type_tag = g_type_info_get_tag (return_type_info);
+    g_callable_info_load_return_type (callable_info, &return_type_info);
+    return_type_tag = g_type_info_get_tag (&return_type_info);
     if (return_type_tag != GI_TYPE_TAG_VOID) {
         GITransfer transfer = g_callable_info_get_caller_owns (callable_info);
         if (PyTuple_Check (py_retval)) {
             PyObject *item = PyTuple_GET_ITEM (py_retval, 0);
             _pygi_closure_assign_pyobj_to_retval (resp, item,
-                return_type_info, transfer);
+                &return_type_info, transfer);
         } else {
             _pygi_closure_assign_pyobj_to_retval (resp, py_retval,
-                return_type_info, transfer);
+                &return_type_info, transfer);
         }
         i_py_retval++;
     }
-    g_base_info_unref (return_type_info);
 
     i_out_args = 0;
     n_args = g_callable_info_get_n_args (callable_info);
-    for (i = 1; i < n_args; i++) {
-        GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i);
-        GITypeInfo *type_info = g_arg_info_get_type (arg_info);
-        GIDirection direction = g_arg_info_get_direction (arg_info);
+    for (i = 0; i < n_args; i++) {
+        GIArgInfo arg_info;
+        g_callable_info_load_arg (callable_info, i, &arg_info);
+        GITypeInfo type_info;
+        g_arg_info_load_type (&arg_info, &type_info);
+        GIDirection direction = g_arg_info_get_direction (&arg_info);
 
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
-            GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
+            GITransfer transfer = g_arg_info_get_ownership_transfer (&arg_info);
 
-            if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ERROR) {
+            if (g_type_info_get_tag (&type_info) == GI_TYPE_TAG_ERROR) {
                 /* TODO: check if an exception has been set and convert it to a GError */
                 out_args[i_out_args].v_pointer = NULL;
                 i_out_args++;
@@ -439,10 +431,10 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
             if (PyTuple_Check (py_retval)) {
                 PyObject *item = PyTuple_GET_ITEM (py_retval, i_py_retval);
                 _pygi_closure_assign_pyobj_to_out_argument (
-                    out_args[i_out_args].v_pointer, item, type_info, transfer);
+                    out_args[i_out_args].v_pointer, item, &type_info, transfer);
             } else if (i_py_retval == 0) {
                 _pygi_closure_assign_pyobj_to_out_argument (
-                    out_args[i_out_args].v_pointer, py_retval, type_info,
+                    out_args[i_out_args].v_pointer, py_retval, &type_info,
                     transfer);
             } else
                 g_assert_not_reached();
@@ -450,8 +442,6 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
             i_out_args++;
             i_py_retval++;
         }
-        g_base_info_unref (type_info);
-        g_base_info_unref (arg_info);
     }
 }
 
index e726b2d..cd3d97d 100644 (file)
@@ -1510,7 +1510,8 @@ _wrap_g_field_info_set_value (PyGIBaseInfo *self,
 
         g_base_info_unref (info);
     } else if (g_type_info_is_pointer (field_type_info)
-            && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID) {
+            && (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID
+                || g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_UTF8)) {
 
         value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
         if (PyErr_Occurred()) {
index dc14ca5..4ddfbb4 100644 (file)
@@ -262,22 +262,30 @@ _pygi_marshal_from_py_int8 (PyGIInvokeState   *state,
     PyObject *py_long;
     long long_;
 
-    if (!PyNumber_Check (py_arg)) {
-        PyErr_Format (PyExc_TypeError, "Must be number, not %s",
-                      py_arg->ob_type->tp_name);
-        return FALSE;
-    }
+    if (PYGLIB_PyBytes_Check (py_arg)) {
 
-    py_long = PYGLIB_PyNumber_Long (py_arg);
-    if (!py_long)
-        return FALSE;
+        if (PYGLIB_PyBytes_Size (py_arg) != 1) {
+            PyErr_Format (PyExc_TypeError, "Must be a single character");
+            return FALSE;
+        }
 
-    long_ = PYGLIB_PyLong_AsLong (py_long);
-    Py_DECREF (py_long);
+        long_ = (char)(PYGLIB_PyBytes_AsString (py_arg)[0]);
+    } else if (PyNumber_Check (py_arg)) {
+        py_long = PYGLIB_PyNumber_Long (py_arg);
+        if (!py_long)
+            return FALSE;
 
-    if (PyErr_Occurred ()) {
-        PyErr_Clear ();
-        PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
+        long_ = PYGLIB_PyLong_AsLong (py_long);
+        Py_DECREF (py_long);
+
+        if (PyErr_Occurred ()) {
+            PyErr_Clear ();
+            PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
+            return FALSE;
+        }
+    } else {
+        PyErr_Format (PyExc_TypeError, "Must be number or single byte string, not %s",
+                      py_arg->ob_type->tp_name);
         return FALSE;
     }
 
@@ -1009,6 +1017,12 @@ _pygi_marshal_from_py_array (PyGIInvokeState   *state,
                             if (from_py_cleanup)
                                 from_py_cleanup (state, item_arg_cache, item.v_pointer, TRUE);
                         }
+                    } else if (is_boxed && !item_iface_cache->arg_cache.is_pointer) {
+                        /* The array elements are not expected to be pointers, but the
+                         * elements obtained are boxed pointers themselves, so insert
+                         * the pointed to data.
+                         */
+                        g_array_insert_vals (array_, i, item.v_pointer, 1);
                     } else {
                         g_array_insert_val (array_, i, item);
                     }
index 950895d..d5a0734 100644 (file)
@@ -434,13 +434,14 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
                                 item_arg.v_pointer = g_variant_ref_sink (g_array_index (array_, gpointer, i));
                               else
                                 item_arg.v_pointer = g_array_index (array_, gpointer, i);
-                            } else if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+                            } else if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && !item_arg_cache->is_pointer) {
+                                /* array elements are structs */
                                 gpointer *_struct = g_malloc (item_size);
                                 memcpy (_struct, array_->data + i * item_size,
                                         item_size);
                                 item_arg.v_pointer = _struct;
                             } else if (item_arg_cache->is_pointer)
-                                /* this is the case for GAtom* arrays */
+                                /* array elements are pointers to values */
                                 item_arg.v_pointer = g_array_index (array_, gpointer, i);
                             else
                                 item_arg.v_pointer = array_->data + i * item_size;
@@ -814,7 +815,9 @@ _pygi_marshal_to_py_interface_struct (PyGIInvokeState   *state,
                                                               arg->v_pointer);
     } else if (g_type_is_a (type, G_TYPE_BOXED)) {
         py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer, 
-                                  arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+                                  arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->is_caller_allocates);
+        if (arg_cache->is_caller_allocates)
+          ((PyGIBoxed *)py_obj)->slice_allocated = TRUE;
     } else if (g_type_is_a (type, G_TYPE_POINTER)) {
         if (iface_cache->py_type == NULL ||
                 !PyType_IsSubtype ( (PyTypeObject *)iface_cache->py_type, &PyGIStruct_Type)) {
index 6079efc..2e32fea 100644 (file)
@@ -217,7 +217,10 @@ pygi_get_property_value_real (PyGObject *instance, GParamSpec *pspec)
             break;
         case GI_TYPE_TAG_GLIST:
         case GI_TYPE_TAG_GSLIST:
-            arg.v_pointer = g_value_get_pointer (&value);
+            if (G_VALUE_HOLDS_BOXED(&value))
+                arg.v_pointer = g_value_get_boxed (&value);
+            else
+                arg.v_pointer = g_value_get_pointer (&value);
             break;
         case GI_TYPE_TAG_ARRAY:
         {
@@ -384,7 +387,10 @@ pygi_set_property_value_real (PyGObject *instance,
             g_value_set_boxed (&value, arg.v_pointer);
             break;
         case GI_TYPE_TAG_GLIST:
-            g_value_set_pointer (&value, arg.v_pointer);
+            if (G_VALUE_HOLDS_BOXED(&value))
+                g_value_set_boxed (&value, arg.v_pointer);
+            else
+                g_value_set_pointer (&value, arg.v_pointer);
             break;
         case GI_TYPE_TAG_ARRAY:
         {
index 77efd2e..1d40539 100644 (file)
@@ -84,6 +84,7 @@ EXTRA_DIST = \
        test-unknown.h \
        te_ST@nouppera \
        org.gnome.test.gschema.xml \
+       test_gio.py \
        test_glib.py \
        test_gobject.py \
        test_gtype.py \
@@ -101,7 +102,6 @@ EXTRA_DIST = \
        test_gi.py \
        test_gdbus.py \
        test_overrides.py \
-       test_overrides_gio.py \
        test_overrides_glib.py \
        test_overrides_pango.py \
        test_overrides_gdk.py \
index 5aa69dc..8e4e802 100644 (file)
@@ -330,6 +330,7 @@ EXTRA_DIST = \
        test-unknown.h \
        te_ST@nouppera \
        org.gnome.test.gschema.xml \
+       test_gio.py \
        test_glib.py \
        test_gobject.py \
        test_gtype.py \
@@ -347,7 +348,6 @@ EXTRA_DIST = \
        test_gi.py \
        test_gdbus.py \
        test_overrides.py \
-       test_overrides_gio.py \
        test_overrides_glib.py \
        test_overrides_pango.py \
        test_overrides_gdk.py \
index 9f3a7ec..1bd1be0 100755 (executable)
@@ -18,6 +18,13 @@ if sys.version_info[:2] == (2, 6):
     unittest.skipUnless = skipUnless
     unittest.expectedFailure = lambda obj: obj
 
+    def skipIf(condition, reason):
+        if condition:
+            sys.stderr.write('[expected failure] ')
+        return lambda obj: obj
+
+    unittest.skipIf = skipUnless
+
     def assertGreater(self, a, b, msg=None):
         if not a > b:
             self.fail('%s not greater than %s' % (repr(a), repr(b)))
@@ -26,12 +33,22 @@ if sys.version_info[:2] == (2, 6):
         if not a >= b:
             self.fail('%s not greater than or equal to %s' % (repr(a), repr(b)))
 
+    def assertLess(self, a, b, msg=None):
+        if not a < b:
+            self.fail('%s not less than %s' % (repr(a), repr(b)))
+
+    def assertLessEqual(self, a, b, msg=None):
+        if not a <= b:
+            self.fail('%s not less than or equal to %s' % (repr(a), repr(b)))
+
     def assertIsInstance(self, obj, cls, msg=None):
         if not isinstance(obj, cls):
             self.fail('%s is not an instance of %r' % (repr(obj), cls))
 
     unittest.TestCase.assertGreaterEqual = assertGreaterEqual
     unittest.TestCase.assertGreater = assertGreater
+    unittest.TestCase.assertLessEqual = assertLessEqual
+    unittest.TestCase.assertLess = assertLess
     unittest.TestCase.assertIsInstance = assertIsInstance
 
 if sys.version_info[:2] == (2, 7):
@@ -59,6 +76,7 @@ os.environ['G_DEBUG'] = 'fatal-warnings fatal-criticals'
 # first.
 os.environ['GSETTINGS_BACKEND'] = 'memory'
 os.environ['GSETTINGS_SCHEMA_DIR'] = tests_builddir
+os.environ['G_FILENAME_ENCODING'] = 'UTF-8'
 
 # Load tests.
 if 'TEST_NAMES' in os.environ:
index f1f14b7..dcc61e8 100644 (file)
@@ -675,17 +675,14 @@ class TestCallbacks(unittest.TestCase):
         self.assertEqual(TestCallbacks.called, 2)
         self.assertEqual(sys.getrefcount(callback), refcount)
 
-    # FIXME: TypeError: callback() takes 2 positional arguments but 4 were given
-    # does not remove the array length arguments
-    @unittest.expectedFailure
     def test_callback_scope_call_array(self):
         # This tests a callback that gets called multiple times from a
         # single scope call in python with array arguments
         TestCallbacks.callargs = []
 
-        # works with:
-        #def callback(one, one_length, two, two_length):
-        def callback(one, two):
+        # FIXME: would be cleaner without the explicit length args:
+        # def callback(one, two):
+        def callback(one, one_length, two, two_length):
             TestCallbacks.callargs.append((one, two))
             return len(TestCallbacks.callargs)
 
@@ -1195,6 +1192,28 @@ class TestSignals(unittest.TestCase):
         obj.emit_sig_with_uint64()
         self.assertEqual(obj.callback_i, GObject.G_MAXUINT64)
 
+    def test_intarray_ret(self):
+        obj = Everything.TestObj()
+
+        def callback(obj, i):
+            obj.callback_i = i
+            return [i, i + 1]
+
+        obj.callback_i = None
+
+        try:
+            obj.connect('sig-with-intarray-ret', callback)
+        except TypeError as e:
+            # compat with g-i 1.34.x
+            if 'unknown signal' in str(e):
+                return
+            raise
+
+        rv = obj.emit('sig-with-intarray-ret', 42)
+        self.assertEqual(obj.callback_i, 42)
+        self.assertEqual(type(rv), GLib.Array)
+        self.assertEqual(rv.len, 2)
+
 
 @unittest.skipUnless(has_cairo, 'built without cairo support')
 @unittest.skipUnless(Gtk, 'Gtk not available')
index a2664f1..29a69d0 100644 (file)
@@ -812,6 +812,18 @@ class TestArray(unittest.TestCase):
 
         GIMarshallingTests.array_struct_in([struct1, struct2, struct3])
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests, 'array_struct_value_in'),
+                         'too old gobject-introspection')
+    def test_array_boxed_struct_value_in(self):
+        struct1 = GIMarshallingTests.BoxedStruct()
+        struct1.long_ = 1
+        struct2 = GIMarshallingTests.BoxedStruct()
+        struct2.long_ = 2
+        struct3 = GIMarshallingTests.BoxedStruct()
+        struct3.long_ = 3
+
+        GIMarshallingTests.array_struct_value_in([struct1, struct2, struct3])
+
     def test_array_boxed_struct_take_in(self):
         struct1 = GIMarshallingTests.BoxedStruct()
         struct1.long_ = 1
@@ -824,13 +836,11 @@ class TestArray(unittest.TestCase):
 
         self.assertEqual(1, struct1.long_)
 
-    @unittest.expectedFailure
     def test_array_boxed_struct_return(self):
         (struct1, struct2, struct3) = GIMarshallingTests.array_zero_terminated_return_struct()
         self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct1))
         self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct2))
         self.assertEqual(GIMarshallingTests.BoxedStruct, type(struct3))
-        # FIXME: gets bogus values
         self.assertEqual(42, struct1.long_)
         self.assertEqual(43, struct2.long_)
         self.assertEqual(44, struct3.long_)
@@ -1042,8 +1052,8 @@ class TestGBytes(unittest.TestCase):
         self.assertFalse(b.equal(a2))
 
         self.assertEqual(0, a1.compare(a2))
-        self.assertEqual(1, a1.compare(b))
-        self.assertEqual(-1, b.compare(a1))
+        self.assertLess(0, a1.compare(b))
+        self.assertGreater(0, b.compare(a1))
 
 
 class TestGByteArray(unittest.TestCase):
@@ -1213,32 +1223,24 @@ class TestGValue(unittest.TestCase):
 
     def test_gvalue_in(self):
         GIMarshallingTests.gvalue_in(42)
-        value = GObject.Value()
-        value.init(GObject.TYPE_INT)
-        value.set_int(42)
+        value = GObject.Value(GObject.TYPE_INT, 42)
         GIMarshallingTests.gvalue_in(value)
 
     def test_gvalue_int64_in(self):
-        value = GObject.Value()
-        value.init(GObject.TYPE_INT64)
-        value.set_int64(GObject.G_MAXINT64)
+        value = GObject.Value(GObject.TYPE_INT64, GObject.G_MAXINT64)
         GIMarshallingTests.gvalue_int64_in(value)
 
     def test_gvalue_in_with_type(self):
-        value = GObject.Value()
-        value.init(GObject.TYPE_STRING)
-        value.set_string('foo')
+        value = GObject.Value(GObject.TYPE_STRING, 'foo')
         GIMarshallingTests.gvalue_in_with_type(value, GObject.TYPE_STRING)
 
-        value = GObject.Value()
-        value.init(GIMarshallingTests.Flags.__gtype__)
-        value.set_flags(GIMarshallingTests.Flags.VALUE1)
+        value = GObject.Value(GIMarshallingTests.Flags.__gtype__,
+                              GIMarshallingTests.Flags.VALUE1)
         GIMarshallingTests.gvalue_in_with_type(value, GObject.TYPE_FLAGS)
 
     def test_gvalue_in_enum(self):
-        value = GObject.Value()
-        value.init(GIMarshallingTests.Enum.__gtype__)
-        value.set_enum(GIMarshallingTests.Enum.VALUE3)
+        value = GObject.Value(GIMarshallingTests.Enum.__gtype__,
+                              GIMarshallingTests.Enum.VALUE3)
         GIMarshallingTests.gvalue_in_enum(value)
 
     def test_gvalue_out(self):
@@ -1252,9 +1254,7 @@ class TestGValue(unittest.TestCase):
 
     def test_gvalue_inout(self):
         self.assertEqual('42', GIMarshallingTests.gvalue_inout(42))
-        value = GObject.Value()
-        value.init(GObject.TYPE_INT)
-        value.set_int(42)
+        value = GObject.Value(int, 42)
         self.assertEqual('42', GIMarshallingTests.gvalue_inout(value))
 
     def test_gvalue_flat_array_in(self):
@@ -1367,13 +1367,11 @@ class TestCallbacks(unittest.TestCase):
             return 5
         self.assertEqual(GIMarshallingTests.callback_return_value_only(cb), 5)
 
-    @unittest.expectedFailure
     def test_one_out_arg(self):
         def cb():
             return 5.5
         self.assertAlmostEqual(GIMarshallingTests.callback_one_out_parameter(cb), 5.5)
 
-    @unittest.expectedFailure
     def test_multiple_out_args(self):
         def cb():
             return (5.5, 42.0)
@@ -1381,7 +1379,6 @@ class TestCallbacks(unittest.TestCase):
         self.assertAlmostEqual(res[0], 5.5)
         self.assertAlmostEqual(res[1], 42.0)
 
-    @unittest.expectedFailure
     def test_return_and_one_out_arg(self):
         def cb():
             return (5, 42.0)
@@ -1389,7 +1386,6 @@ class TestCallbacks(unittest.TestCase):
         self.assertEqual(res[0], 5)
         self.assertAlmostEqual(res[1], 42.0)
 
-    @unittest.expectedFailure
     def test_return_and_multiple_out_arg(self):
         def cb():
             return (5, 42, -1000)
@@ -1477,6 +1473,26 @@ class TestEnum(unittest.TestCase):
         self.assertTrue(hasattr(GIMarshallingTests.Enum, "VALUE1"))
         self.assertRaises(AttributeError, getattr, GIMarshallingTests.SecondEnum, "VALUE1")
 
+    def test_enum_gtype_name_is_namespaced(self):
+        self.assertEqual(GIMarshallingTests.Enum.__gtype__.name,
+                         'GIMarshallingTestsEnum')
+
+    def test_enum_double_registration_error(self):
+        # a warning is printed for double registration and pygobject will
+        # also raise a RuntimeError.
+        old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
+        try:
+            self.assertRaises(RuntimeError,
+                              gi._gi.enum_register_new_gtype_and_add,
+                              GIMarshallingTests.Enum.__info__)
+        finally:
+            GLib.log_set_always_fatal(old_mask)
+
+    def test_enum_add_type_error(self):
+        self.assertRaises(TypeError,
+                          gi._gi.enum_add,
+                          GIMarshallingTests.NoTypeFlags.__gtype__)
+
 
 class TestGEnum(unittest.TestCase):
 
@@ -1609,6 +1625,21 @@ class TestNoTypeFlags(unittest.TestCase):
         self.assertTrue(isinstance(flags, GIMarshallingTests.NoTypeFlags))
         self.assertEqual(flags, GIMarshallingTests.NoTypeFlags.VALUE1)
 
+    def test_flags_gtype_name_is_namespaced(self):
+        self.assertEqual(GIMarshallingTests.NoTypeFlags.__gtype__.name,
+                         'GIMarshallingTestsNoTypeFlags')
+
+    def test_flags_double_registration_error(self):
+        # a warning is printed for double registration and pygobject will
+        # also raise a RuntimeError.
+        old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
+        try:
+            self.assertRaises(RuntimeError,
+                              gi._gi.flags_register_new_gtype_and_add,
+                              GIMarshallingTests.NoTypeFlags.__info__)
+        finally:
+            GLib.log_set_always_fatal(old_mask)
+
 
 class TestStructure(unittest.TestCase):
 
@@ -1704,6 +1735,8 @@ class TestStructure(unittest.TestCase):
 
         del struct
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests.BoxedStruct, 'string_'),
+                         'too old gobject-introspection')
     def test_boxed_struct(self):
         self.assertTrue(issubclass(GIMarshallingTests.BoxedStruct, GObject.GBoxed))
 
@@ -1711,30 +1744,44 @@ class TestStructure(unittest.TestCase):
         self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
 
         self.assertEqual(0, struct.long_)
+        self.assertEqual(None, struct.string_)
         self.assertEqual([], struct.g_strv)
 
         del struct
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests.BoxedStruct, 'string_'),
+                         'too old gobject-introspection')
     def test_boxed_struct_new(self):
         struct = GIMarshallingTests.BoxedStruct.new()
         self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
+        self.assertEqual(struct.long_, 0)
+        self.assertEqual(struct.string_, None)
 
         del struct
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests.BoxedStruct, 'string_'),
+                         'too old gobject-introspection')
     def test_boxed_struct_copy(self):
         struct = GIMarshallingTests.BoxedStruct()
+        struct.long_ = 42
+        struct.string_ = 'hello'
 
         new_struct = struct.copy()
         self.assertTrue(isinstance(new_struct, GIMarshallingTests.BoxedStruct))
+        self.assertEqual(new_struct.long_, 42)
+        self.assertEqual(new_struct.string_, 'hello')
 
         del new_struct
         del struct
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests.BoxedStruct, 'string_'),
+                         'too old gobject-introspection')
     def test_boxed_struct_return(self):
         struct = GIMarshallingTests.boxed_struct_returnv()
 
         self.assertTrue(isinstance(struct, GIMarshallingTests.BoxedStruct))
         self.assertEqual(42, struct.long_)
+        self.assertEqual('hello', struct.string_)
         self.assertEqual(['0', '1', '2'], struct.g_strv)
 
         del struct
@@ -1767,6 +1814,14 @@ class TestStructure(unittest.TestCase):
         del in_struct
         del out_struct
 
+    def test_struct_field_assignment(self):
+        struct = GIMarshallingTests.BoxedStruct()
+
+        struct.long_ = 42
+        struct.string_ = 'hello'
+        self.assertEqual(struct.long_, 42)
+        self.assertEqual(struct.string_, 'hello')
+
     def test_union(self):
         union = GIMarshallingTests.Union()
 
@@ -2442,6 +2497,15 @@ class TestGErrorReturn(unittest.TestCase):
 
 
 class TestParamSpec(unittest.TestCase):
+    # https://bugzilla.gnome.org/show_bug.cgi?id=682355
+    @unittest.skipUnless(hasattr(GIMarshallingTests, 'param_spec_in_bool'),
+                         'too old gobject-introspection')
+    @unittest.expectedFailure
+    def test_param_spec_in_bool(self):
+        ps = GObject.param_spec_boolean('mybool', 'test-bool', 'boolblurb',
+                                        True, GObject.ParamFlags.READABLE)
+        GIMarshallingTests.param_spec_in_bool(ps)
+
     def test_param_spec_return(self):
         obj = GIMarshallingTests.param_spec_return()
         self.assertEqual(obj.name, 'test-param')
@@ -2528,18 +2592,10 @@ class TestPropertiesObject(unittest.TestCase):
         obj = GIMarshallingTests.PropertiesObject(some_boolean=True)
         self.assertEqual(obj.props.some_boolean, True)
 
-    @unittest.expectedFailure
     def test_char(self):
-        # gobject-introspection thinks it has a guint8 type tag, which is
-        # wrong; this will raise an assertion critical which we need to ignore
-        old_mask = GLib.log_set_always_fatal(
-            GLib.LogLevelFlags.LEVEL_WARNING | GLib.LogLevelFlags.LEVEL_ERROR)
-        try:
-            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)
-        finally:
-            GLib.log_set_always_fatal(old_mask)
+        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)
 
         obj = GIMarshallingTests.PropertiesObject(some_char=-42)
         self.assertEqual(obj.props.some_char, -42)
@@ -2686,6 +2742,27 @@ class TestPropertiesObject(unittest.TestCase):
         obj = GIMarshallingTests.PropertiesObject(some_boxed_struct=struct1)
         self.assertEqual(obj.props.some_boxed_struct.long_, 1)
 
+    @unittest.skipUnless(hasattr(GIMarshallingTests.PropertiesObject, 'some_boxed_glist'),
+                         'too old gobject-introspection')
+    def test_boxed_glist(self):
+        self.assertEqual(self.obj.props.some_boxed_glist, [])
+
+        l = [GObject.G_MININT, 42, GObject.G_MAXINT]
+        self.obj.props.some_boxed_glist = l
+        self.assertEqual(self.obj.props.some_boxed_glist, l)
+        self.obj.props.some_boxed_glist = []
+        self.assertEqual(self.obj.props.some_boxed_glist, [])
+
+        self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', 1)
+        self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', 'foo')
+        self.assertRaises(TypeError, setattr, self.obj.props, 'some_boxed_glist', ['a'])
+
+    @unittest.expectedFailure
+    def test_boxed_glist_ctor(self):
+        l = [GObject.G_MININT, 42, GObject.G_MAXINT]
+        obj = GIMarshallingTests.PropertiesObject(some_boxed_glist=l)
+        self.assertEqual(obj.props.some_boxed_glist, l)
+
     @unittest.skipUnless(hasattr(GIMarshallingTests.PropertiesObject, 'some_variant'),
                          'too old gobject-introspection')
     def test_variant(self):
similarity index 66%
rename from tests/test_overrides_gio.py
rename to tests/test_gio.py
index 10d634e..942ee00 100644 (file)
@@ -119,3 +119,67 @@ class TestGSettings(unittest.TestCase):
         self.assertEqual(len(empty), 0)
         self.assertEqual(bool(empty), True)
         self.assertEqual(empty.keys(), [])
+
+
+class TestGFile(unittest.TestCase):
+    def setUp(self):
+        self.file, self.io_stream = Gio.File.new_tmp('TestGFile.XXXXXX')
+
+    def tearDown(self):
+        try:
+            self.file.delete(None)
+            # test_delete and test_delete_async already remove it
+        except GLib.GError:
+            pass
+
+    def test_replace_contents(self):
+        content = b'hello\0world\x7F!'
+        succ, etag = self.file.replace_contents(content, None, False,
+                                                Gio.FileCreateFlags.NONE, None)
+        new_succ, new_content, new_etag = self.file.load_contents(None)
+
+        self.assertTrue(succ)
+        self.assertTrue(new_succ)
+        self.assertEqual(etag, new_etag)
+        self.assertEqual(content, new_content)
+
+    # https://bugzilla.gnome.org/show_bug.cgi?id=690525
+    def disabled_test_replace_contents_async(self):
+        content = b''.join(bytes(chr(i), 'utf-8') for i in range(128))
+
+        def callback(f, result, d):
+            # Quit so in case of failed assertations loop doesn't keep running.
+            main_loop.quit()
+            succ, etag = self.file.replace_contents_finish(result)
+            new_succ, new_content, new_etag = self.file.load_contents(None)
+            d['succ'], d['etag'] = self.file.replace_contents_finish(result)
+            load = self.file.load_contents(None)
+            d['new_succ'], d['new_content'], d['new_etag'] = load
+
+        data = {}
+        self.file.replace_contents_async(content, None, False,
+                                         Gio.FileCreateFlags.NONE, None,
+                                         callback, data)
+        main_loop = GLib.MainLoop()
+        main_loop.run()
+        self.assertTrue(data['succ'])
+        self.assertTrue(data['new_succ'])
+        self.assertEqual(data['etag'], data['new_etag'])
+        self.assertEqual(content, data['new_content'])
+
+    def test_tmp_exists(self):
+        # A simple test to check if Gio.File.new_tmp is working correctly.
+        self.assertTrue(self.file.query_exists(None))
+
+    def test_delete(self):
+        self.file.delete(None)
+        self.assertFalse(self.file.query_exists(None))
+
+    def test_delete_async(self):
+        def callback(f, result, data):
+            main_loop.quit()
+
+        self.file.delete_async(0, None, callback, None)
+        main_loop = GLib.MainLoop()
+        main_loop.run()
+        self.assertFalse(self.file.query_exists(None))
index 99f471b..9b4f5f7 100644 (file)
@@ -5,7 +5,7 @@ import gc
 import unittest
 import warnings
 
-from gi.repository import GObject
+from gi.repository import GObject, GLib
 from gi import PyGIDeprecationWarning
 from gi.module import get_introspection_module
 from gi._gobject import _gobject
@@ -491,19 +491,27 @@ class TestPropertyBindings(unittest.TestCase):
         self.assertEqual(self.target.int_prop, 1)
 
     def test_transform_bidirectional(self):
+        test_data = object()
+
         def transform_to(binding, value, user_data=None):
-            self.assertEqual(user_data, 'test-data')
+            self.assertEqual(user_data, test_data)
             return value * 2
 
         def transform_from(binding, value, user_data=None):
-            self.assertEqual(user_data, 'test-data')
-            return value / 2
+            self.assertEqual(user_data, test_data)
+            return value // 2
+
+        test_data_ref_count = sys.getrefcount(test_data)
+        transform_to_ref_count = sys.getrefcount(transform_to)
+        transform_from_ref_count = sys.getrefcount(transform_from)
 
         # bidirectional bindings
         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
                                             GObject.BindingFlags.BIDIRECTIONAL,
-                                            transform_to, transform_from, 'test-data')
+                                            transform_to, transform_from, test_data)
         binding = binding  # PyFlakes
+        binding_ref_count = sys.getrefcount(binding())
+        binding_gref_count = binding().__grefcount__
 
         self.source.int_prop = 1
         self.assertEqual(self.source.int_prop, 1)
@@ -513,6 +521,30 @@ class TestPropertyBindings(unittest.TestCase):
         self.assertEqual(self.source.int_prop, 2)
         self.assertEqual(self.target.int_prop, 4)
 
+        self.assertEqual(sys.getrefcount(binding()), binding_ref_count)
+        self.assertEqual(binding().__grefcount__, binding_gref_count)
+
+        # test_data ref count increases by 2, once for each callback.
+        self.assertEqual(sys.getrefcount(test_data), test_data_ref_count + 2)
+        self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count + 1)
+        self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count + 1)
+
+        # Unbind should clear out the binding and its transforms
+        binding.unbind()
+        self.assertEqual(binding(), None)
+        del binding
+        gc.collect()
+
+        # Setting source or target should not change the other.
+        self.target.int_prop = 3
+        self.source.int_prop = 5
+        self.assertEqual(self.target.int_prop, 3)
+        self.assertEqual(self.source.int_prop, 5)
+
+        self.assertEqual(sys.getrefcount(test_data), test_data_ref_count)
+        self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count)
+        self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count)
+
     def test_explicit_unbind_clears_connection(self):
         self.assertEqual(self.source.int_prop, 0)
         self.assertEqual(self.target.int_prop, 0)
@@ -563,5 +595,50 @@ class TestPropertyBindings(unittest.TestCase):
         self.assertEqual(ref(), None)
         self.assertEqual(binding(), None)
 
+
+class TestGValue(unittest.TestCase):
+    def test_no_type(self):
+        value = GObject.Value()
+        self.assertEqual(value.g_type, GObject.TYPE_INVALID)
+        self.assertRaises(TypeError, value.set_value, 23)
+        self.assertEqual(value.get_value(), None)
+
+    def test_int(self):
+        value = GObject.Value(GObject.TYPE_UINT)
+        self.assertEqual(value.g_type, GObject.TYPE_UINT)
+        value.set_value(23)
+        self.assertEqual(value.get_value(), 23)
+        value.set_value(42.0)
+        self.assertEqual(value.get_value(), 42)
+
+    def test_string(self):
+        value = GObject.Value(str, 'foo_bar')
+        self.assertEqual(value.g_type, GObject.TYPE_STRING)
+        self.assertEqual(value.get_value(), 'foo_bar')
+
+    def test_float(self):
+        # python float is G_TYPE_DOUBLE
+        value = GObject.Value(float, 23.4)
+        self.assertEqual(value.g_type, GObject.TYPE_DOUBLE)
+
+        value = GObject.Value(GObject.TYPE_FLOAT, 23.4)
+        self.assertEqual(value.g_type, GObject.TYPE_FLOAT)
+        self.assertRaises(TypeError, value.set_value, 'string')
+
+    def test_enum(self):
+        value = GObject.Value(GLib.FileError, GLib.FileError.FAILED)
+        self.assertEqual(value.get_value(), GLib.FileError.FAILED)
+
+    def test_flags(self):
+        value = GObject.Value(GLib.IOFlags, GLib.IOFlags.IS_READABLE)
+        self.assertEqual(value.get_value(), GLib.IOFlags.IS_READABLE)
+
+    def test_object(self):
+        class TestObject(GObject.Object):
+            pass
+        obj = TestObject()
+        value = GObject.Value(GObject.TYPE_OBJECT, obj)
+        self.assertEqual(value.get_value(), obj)
+
 if __name__ == '__main__':
     unittest.main()
index dec716e..8099101 100644 (file)
@@ -37,15 +37,13 @@ class TestTypeModuleLevelFunctions(unittest.TestCase):
         self.assertRaises(TypeError, GObject.type_is_a, 1, 2)
 
     def test_type_children(self):
-        self.assertSequenceEqual(GObject.type_children(CustomBase),
-                                 [CustomChild.__gtype__])
+        self.assertEqual(GObject.type_children(CustomBase), [CustomChild.__gtype__])
         self.assertEqual(len(GObject.type_children(CustomChild)), 0)
 
     def test_type_interfaces(self):
         self.assertEqual(len(GObject.type_interfaces(CustomBase)), 0)
         self.assertEqual(len(GObject.type_interfaces(CustomChild)), 1)
-        self.assertSequenceEqual(GObject.type_interfaces(CustomChild),
-                                 [GIMarshallingTests.Interface.__gtype__])
+        self.assertEqual(GObject.type_interfaces(CustomChild), [GIMarshallingTests.Interface.__gtype__])
 
     def test_type_parent(self):
         self.assertEqual(GObject.type_parent(CustomChild), CustomBase.__gtype__)
index 7ed8344..d429d4d 100644 (file)
@@ -1,4 +1,5 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
+# coding: UTF-8
 # vim: tabstop=4 shiftwidth=4 expandtab
 
 import unittest
@@ -114,6 +115,12 @@ class TestGtk(unittest.TestCase):
         self.assertEqual(ag, groups[-2])
         self.assertEqual(ag2, groups[-1])
 
+    def test_uimanager_nonascii(self):
+        ui = Gtk.UIManager()
+        ui.add_ui_from_string(b'<ui><menubar name="menub\xc3\xa6r1" /></ui>'.decode('UTF-8'))
+        mi = ui.get_widget("/menubær1")
+        self.assertEqual(type(mi), Gtk.MenuBar)
+
     def test_builder(self):
         self.assertEqual(Gtk.Builder, gi.overrides.Gtk.Builder)
 
@@ -1300,7 +1307,53 @@ class TestTreeModel(unittest.TestCase):
         def set_row3():
             model[0][:2] = ("0", 0)
 
-        self.assertRaises(ValueError, set_row3)
+        self.assertRaises(TypeError, set_row3)
+
+    def test_tree_model_set_value_to_none(self):
+        # Tests allowing the usage of None to set an empty value on a model.
+        store = Gtk.ListStore(str)
+        row = store.append(['test'])
+        self.assertSequenceEqual(store[0][:], ['test'])
+        store.set_value(row, 0, None)
+        self.assertSequenceEqual(store[0][:], [None])
+
+    def test_signal_emission_tree_path_coerce(self):
+        class Model(GObject.Object, Gtk.TreeModel):
+            pass
+
+        model = Model()
+        tree_paths = []
+
+        def on_any_signal(model, path, *args):
+            tree_paths.append(path.to_string())
+
+        model.connect('row-changed', on_any_signal)
+        model.connect('row-deleted', on_any_signal)
+        model.connect('row-has-child-toggled', on_any_signal)
+        model.connect('row-inserted', on_any_signal)
+
+        model.row_changed('0', Gtk.TreeIter())
+        self.assertEqual(tree_paths[-1], '0')
+
+        model.row_deleted('1')
+        self.assertEqual(tree_paths[-1], '1')
+
+        model.row_has_child_toggled('2', Gtk.TreeIter())
+        self.assertEqual(tree_paths[-1], '2')
+
+        model.row_inserted('3', Gtk.TreeIter())
+        self.assertEqual(tree_paths[-1], '3')
+
+    def test_tree_model_filter(self):
+        model = Gtk.ListStore(int, str, float)
+        model.append([1, "one", -0.1])
+        model.append([2, "two", -0.2])
+
+        filtered = Gtk.TreeModelFilter(child_model=model)
+
+        self.assertEqual(filtered[0][1], 'one')
+        filtered[0][1] = 'ONE'
+        self.assertEqual(filtered[0][1], 'ONE')
 
 
 @unittest.skipUnless(Gtk, 'Gtk not available')
index fe286e2..d19970f 100644 (file)
@@ -541,6 +541,24 @@ class TestProperty(unittest.TestCase):
         self.assertEqual(o.value, 'blah')
         self.assertEqual(o.props.value, 'blah')
 
+    def test_decorator_private_setter(self):
+        class C(GObject.GObject):
+            _value = 'value'
+
+            @GObject.Property
+            def value(self):
+                return self._value
+
+            @value.setter
+            def _set_value(self, value):
+                self._value = value
+
+        o = C()
+        self.assertEqual(o.value, 'value')
+        o.value = 'blah'
+        self.assertEqual(o.value, 'blah')
+        self.assertEqual(o.props.value, 'blah')
+
     def test_decorator_with_call(self):
         class C(GObject.GObject):
             _value = 1
index fc8c835..8f31c35 100644 (file)
@@ -362,6 +362,7 @@ class CM(GObject.GObject):
         test_string=(GObject.SignalFlags.RUN_LAST, str, (str,)),
         test_object=(GObject.SignalFlags.RUN_LAST, object, (object,)),
         test_paramspec=(GObject.SignalFlags.RUN_LAST, GObject.ParamSpec, ()),
+        test_paramspec_in=(GObject.SignalFlags.RUN_LAST, GObject.ParamSpec, (GObject.ParamSpec, )),
         test_gvalue=(GObject.SignalFlags.RUN_LAST, GObject.Value, (GObject.Value,)),
         test_gvalue_ret=(GObject.SignalFlags.RUN_LAST, GObject.Value, (GObject.TYPE_GTYPE,)),
     )
@@ -418,6 +419,17 @@ class _TestCMarshaller:
         self.assertEqual(rv.name, "test-param")
         self.assertEqual(rv.nick, "test")
 
+    @unittest.skipUnless(hasattr(GObject, 'param_spec_boolean'),
+                         'too old gobject-introspection')
+    def test_paramspec_in(self):
+        rv = GObject.param_spec_boolean('mybool', 'test-bool', 'do something',
+                                        True, GObject.ParamFlags.READABLE)
+
+        rv2 = self.obj.emit("test-paramspec-in", rv)
+        self.assertEqual(type(rv), type(rv2))
+        self.assertEqual(rv2.name, "mybool")
+        self.assertEqual(rv2.nick, "test-bool")
+
     def test_C_paramspec(self):
         self.notify_called = False
 
@@ -436,9 +448,7 @@ class _TestCMarshaller:
         self.assertEqual(rv, 42)
 
         # explicit float
-        v = GObject.Value()
-        v.init(GObject.TYPE_FLOAT)
-        v.set_float(1.234)
+        v = GObject.Value(GObject.TYPE_FLOAT, 1.234)
         rv = self.obj.emit("test-gvalue", v)
         self.assertAlmostEqual(rv, 1.234, 4)
 
@@ -447,9 +457,7 @@ class _TestCMarshaller:
         self.assertAlmostEqual(rv, 1.234, 4)
 
         # explicit int64
-        v = GObject.Value()
-        v.init(GObject.TYPE_INT64)
-        v.set_int64(GObject.G_MAXINT64)
+        v = GObject.Value(GObject.TYPE_INT64, GObject.G_MAXINT64)
         rv = self.obj.emit("test-gvalue", v)
         self.assertEqual(rv, GObject.G_MAXINT64)
 
@@ -459,9 +467,7 @@ class _TestCMarshaller:
         #self.assertEqual(rv, GObject.G_MAXINT64)
 
         # explicit uint64
-        v = GObject.Value()
-        v.init(GObject.TYPE_UINT64)
-        v.set_uint64(GObject.G_MAXUINT64)
+        v = GObject.Value(GObject.TYPE_UINT64, GObject.G_MAXUINT64)
         rv = self.obj.emit("test-gvalue", v)
         self.assertEqual(rv, GObject.G_MAXUINT64)
 
@@ -794,11 +800,9 @@ class TestSignalModuleLevelFunctions(unittest.TestCase):
         my_signal_expected_query_result = [my_signal_id, 'my-signal', C.__gtype__,
                                            1, GObject.TYPE_NONE, (GObject.TYPE_INT,)]
         # signal_query(name, type)
-        self.assertSequenceEqual(GObject.signal_query('my-signal', C),
-                                 my_signal_expected_query_result)
+        self.assertEqual(list(GObject.signal_query('my-signal', C)), my_signal_expected_query_result)
         # signal_query(signal_id)
-        self.assertSequenceEqual(GObject.signal_query(my_signal_id),
-                                 my_signal_expected_query_result)
+        self.assertEqual(list(GObject.signal_query(my_signal_id)), my_signal_expected_query_result)
         # invalid query returns None instead of raising
         self.assertEqual(GObject.signal_query(0), None)
         self.assertEqual(GObject.signal_query('NOT_A_SIGNAL', C),
index 16bb39e..9ca82bc 100644 (file)
@@ -402,6 +402,15 @@ test_gvalue_ret_callback (GObject *object, GType type)
   return ret;
 }
 
+static GParamSpec *
+test_paramspec_in_callback (GObject *object, GParamSpec *p)
+{
+  g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+  g_return_val_if_fail (G_IS_PARAM_SPEC (p), NULL);
+
+  return p;
+}
+
 static void
 connectcallbacks (GObject *object)
 {
@@ -460,6 +469,10 @@ connectcallbacks (GObject *object)
                     "test_gvalue_ret",
                     G_CALLBACK (test_gvalue_ret_callback), 
                     NULL);
+  g_signal_connect (G_OBJECT (object),
+                    "test_paramspec_in",
+                    G_CALLBACK (test_paramspec_in_callback), 
+                    NULL);
 }
 
 static PyObject *
@@ -530,7 +543,6 @@ _wrap_test_gerror_exception(PyObject *self, PyObject *args)
         return NULL;
     }      
 
-    Py_DECREF(py_method);
     Py_DECREF(py_args);
     Py_DECREF(py_ret);