summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog645
-rw-r--r--NEWS38
-rw-r--r--PKG-INFO4
-rw-r--r--aclocal.m435
-rwxr-xr-xconfigure698
-rw-r--r--configure.ac5
-rw-r--r--gi/_gobject/propertyhelper.py29
-rw-r--r--gi/_gobject/pygenum.c6
-rw-r--r--gi/_gobject/pygobject.c8
-rw-r--r--gi/_gobject/pygtype.c82
-rw-r--r--gi/gimodule.c80
-rw-r--r--gi/overrides/GObject.py127
-rw-r--r--gi/overrides/Gtk.py119
-rw-r--r--gi/pygi-argument.c20
-rw-r--r--gi/pygi-cache.c1
-rw-r--r--gi/pygi-closure.c90
-rw-r--r--gi/pygi-info.c3
-rw-r--r--gi/pygi-marshal-from-py.c40
-rw-r--r--gi/pygi-marshal-to-py.c9
-rw-r--r--gi/pygi-property.c10
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/Makefile.in2
-rwxr-xr-xtests/runtests.py18
-rw-r--r--tests/test_everything.py31
-rw-r--r--tests/test_gi.py151
-rw-r--r--tests/test_gio.py (renamed from tests/test_overrides_gio.py)64
-rw-r--r--tests/test_gobject.py87
-rw-r--r--tests/test_gtype.py6
-rw-r--r--tests/test_overrides_gtk.py55
-rw-r--r--tests/test_properties.py18
-rw-r--r--tests/test_signal.py30
-rw-r--r--tests/testhelpermodule.c14
32 files changed, 1538 insertions, 989 deletions
diff --git a/ChangeLog b/ChangeLog
index ab16367..868baee 100644
--- 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
--- 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)
diff --git a/PKG-INFO b/PKG-INFO
index 1956ce7..ca2e5bd 100644
--- 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
diff --git a/aclocal.m4 b/aclocal.m4
index db21f54..2093554 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -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,
diff --git a/configure b/configure
index 5e1cc46..2cd8aca 100755
--- 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\\"
diff --git a/configure.ac b/configure.ac
index dd5e078..6b88bba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py
index a038f1b..d5a1852 100644
--- a/gi/_gobject/propertyhelper.py
+++ b/gi/_gobject/propertyhelper.py
@@ -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:
diff --git a/gi/_gobject/pygenum.c b/gi/_gobject/pygenum.c
index 9c3c455..89e3a06 100644
--- a/gi/_gobject/pygenum.c
+++ b/gi/_gobject/pygenum.c
@@ -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;
}
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 3d0c819..00444bd 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -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;
diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c
index 79c8387..227178f 100644
--- a/gi/_gobject/pygtype.c
+++ b/gi/_gobject/pygtype.c
@@ -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;
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 76530f1..bb5c306 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -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);
}
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index c0198b3..41062e2 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -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')
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 78bbd36..15c0ae6 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -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')
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 4e3c464..34c4970 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -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);
}
}
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 2a44c02..0848ccf 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -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;
}
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 0e49c72..f2f21f0 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -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);
}
}
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index e726b2d..cd3d97d 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -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()) {
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index dc14ca5..4ddfbb4 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -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);
}
diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
index 950895d..d5a0734 100644
--- a/gi/pygi-marshal-to-py.c
+++ b/gi/pygi-marshal-to-py.c
@@ -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)) {
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
index 6079efc..2e32fea 100644
--- a/gi/pygi-property.c
+++ b/gi/pygi-property.c
@@ -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:
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 77efd2e..1d40539 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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 \
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5aa69dc..8e4e802 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -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 \
diff --git a/tests/runtests.py b/tests/runtests.py
index 9f3a7ec..1bd1be0 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -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:
diff --git a/tests/test_everything.py b/tests/test_everything.py
index f1f14b7..dcc61e8 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -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')
diff --git a/tests/test_gi.py b/tests/test_gi.py
index a2664f1..29a69d0 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -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):
diff --git a/tests/test_overrides_gio.py b/tests/test_gio.py
index 10d634e..942ee00 100644
--- a/tests/test_overrides_gio.py
+++ b/tests/test_gio.py
@@ -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))
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index 99f471b..9b4f5f7 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -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()
diff --git a/tests/test_gtype.py b/tests/test_gtype.py
index dec716e..8099101 100644
--- a/tests/test_gtype.py
+++ b/tests/test_gtype.py
@@ -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__)
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index 7ed8344..d429d4d 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -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')
diff --git a/tests/test_properties.py b/tests/test_properties.py
index fe286e2..d19970f 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -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
diff --git a/tests/test_signal.py b/tests/test_signal.py
index fc8c835..8f31c35 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -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),
diff --git a/tests/testhelpermodule.c b/tests/testhelpermodule.c
index 16bb39e..9ca82bc 100644
--- a/tests/testhelpermodule.c
+++ b/tests/testhelpermodule.c
@@ -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);