From: DongHun Kwak Date: Tue, 11 Jul 2017 23:40:27 +0000 (+0900) Subject: Imported Upstream version 3.11.5 X-Git-Tag: upstream/3.9.92~71 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F57%2F138257%2F1;p=platform%2Fupstream%2Fpygobject2.git Imported Upstream version 3.11.5 Change-Id: I5b5a3e71a92ea82cb98feb0c11f00c68804188dc Signed-off-by: DongHun Kwak --- diff --git a/ChangeLog b/ChangeLog index e69de29..fe30f0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -0,0 +1,30224 @@ +commit 058d944e3b9ef9157e912e6374b54a2eb5f7f5d1 +Author: Simon Feltman +Date: Mon Feb 3 06:45:09 2014 -0800 + + Restore pygobject_version API needed for pygobject.h + + Add gi._gobject.pygobject_version which was removed with commit: + https://git.gnome.org/browse/pygobject/commit/?id=2624bd2b + This is needed for pygobject.h to function properly. + + gi/_gobject/__init__.py | 1 + + 1 file changed, 1 insertion(+) + +commit f3be4cedcb1d395a3fabee95d7460bce86268153 +Author: Simon Feltman +Date: Mon Feb 3 06:29:07 2014 -0800 + + cache refactoring: Add comments to arg cache setup functions + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/pygi-cache.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +commit 56ac6bd9ed99d6bb2cb8641581a594105036be68 +Author: Simon Feltman +Date: Mon Feb 3 06:24:18 2014 -0800 + + cache refactoring: Use consistent prefix for arg cache functions + + Use "pygi_arg_cache" as the prefix for arg cache memory related + functions. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/pygi-array.c | 6 ++-- + gi/pygi-basictype.c | 4 +-- + gi/pygi-cache.c | 74 + ++++++++++++++++++++++++------------------------ + gi/pygi-cache.h | 58 ++++++++++++++++++++----------------- + gi/pygi-ccallback.c | 2 +- + gi/pygi-closure.c | 6 ++-- + gi/pygi-enum-marshal.c | 4 +-- + gi/pygi-error.c | 4 +-- + gi/pygi-hashtable.c | 30 ++++++++++---------- + gi/pygi-info.c | 2 +- + gi/pygi-invoke.c | 2 +- + gi/pygi-list.c | 2 +- + gi/pygi-object.c | 2 +- + gi/pygi-struct-marshal.c | 2 +- + 14 files changed, 102 insertions(+), 96 deletions(-) + +commit 204f5a187782c5325ed6bed96c9a940f3aa67d04 +Author: Simon Feltman +Date: Sun Jan 12 12:26:30 2014 -0800 + + marshal refactoring: Move GValue marshaling from pytype into + pygi-value + + Move marshaling of GValues to and from PyObjects into + pygi-value.c. Make + PyGTypeMarshal struct and related functions accessible via pygtype.h. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/gobjectmodule.c | 2 + + gi/pygi-struct-marshal.c | 1 + + gi/pygi-value.c | 720 + +++++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-value.h | 12 + + gi/pygobject-private.h | 16 -- + gi/pygobject.c | 2 +- + gi/pygtype.c | 728 + +---------------------------------------------- + gi/pygtype.h | 17 ++ + 8 files changed, 757 insertions(+), 741 deletions(-) + +commit b8120d848dc5d36832123b1a913015f6e1fd8cdc +Author: Simon Feltman +Date: Sun Jan 12 11:41:20 2014 -0800 + + marshal refactoring: Move GIArgument from GValue code to new file + + Add gi/pygi-value.h and .c files with initial contents of + _pygi_argument_from_g_value. Eventually this file will contain + all code + related to GValue marshaling from various code locations in the + project. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 126 +---------------------------------------- + gi/pygi-argument.h | 3 - + gi/pygi-signal-closure.c | 1 + + gi/pygi-value.c | 144 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-value.h | 32 +++++++++++ + 6 files changed, 180 insertions(+), 128 deletions(-) + +commit c2d5857e9b964427190e1230be32ae7919e86bc0 +Author: Simon Feltman +Date: Sat Oct 12 21:26:55 2013 -0700 + + cache refactoring: Move enum and flags arg setup and marshaling to + new file + + Move enum and flags argument cache setup and marshaling fragments into + isolated file: pygi-enum-marshal.c. Remove pygi-marshal-from/to files. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 6 +- + gi/pygi-argument.c | 2 - + gi/pygi-cache.c | 74 ++------- + gi/pygi-enum-marshal.c | 408 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-enum-marshal.h | 42 +++++ + gi/pygi-marshal-from-py.c | 206 ----------------------- + gi/pygi-marshal-from-py.h | 57 ------- + gi/pygi-marshal-to-py.c | 152 ----------------- + gi/pygi-marshal-to-py.h | 34 ---- + 9 files changed, 464 insertions(+), 517 deletions(-) + +commit 1d0f120d77582509b4e75d83f500a1ace7ed6421 +Author: Simon Feltman +Date: Sat Oct 12 20:00:12 2013 -0700 + + cache refactoring: Move various struct arg setup and marshaling to + new file + + Move struct (boxed, union, gvalue, gclosure, variant, and pointer) + argument + cache setup and marshaling fragments into isolated file: + pygi-struct-marshal.c. + Remove redundant and dead code related to boxed and union marshaling. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 1 + + gi/pygi-array.c | 3 + + gi/pygi-cache.c | 72 +------ + gi/pygi-cache.h | 1 + + gi/pygi-marshal-cleanup.c | 48 ----- + gi/pygi-marshal-cleanup.h | 16 -- + gi/pygi-marshal-from-py.c | 288 -------------------------- + gi/pygi-marshal-from-py.h | 33 --- + gi/pygi-marshal-to-py.c | 120 ----------- + gi/pygi-marshal-to-py.h | 27 --- + gi/pygi-object.c | 2 +- + gi/pygi-struct-marshal.c | 516 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-struct-marshal.h | 73 +++++++ + 14 files changed, 607 insertions(+), 595 deletions(-) + +commit 4dcaa2b988239e01224994098c3e7cbe8b455fe0 +Author: Simon Feltman +Date: Sat Oct 12 16:40:58 2013 -0700 + + cache refactoring: Move GObject arg setup and marshaling into new file + + Move GObject argument cache setup and marshaling fragments into + isolated file: pygi-object.c. + Break GIInterfaceCache creation and setup into API for interface based + argument cache usage. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 7 +- + gi/pygi-cache.c | 183 ++++++++++++++----------------- + gi/pygi-cache.h | 7 ++ + gi/pygi-marshal-cleanup.c | 27 ----- + gi/pygi-marshal-cleanup.h | 10 -- + gi/pygi-marshal-from-py.c | 123 --------------------- + gi/pygi-marshal-from-py.h | 12 -- + gi/pygi-marshal-to-py.c | 31 ------ + gi/pygi-marshal-to-py.h | 8 -- + gi/pygi-object.c | 273 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-object.h | 46 ++++++++ + 12 files changed, 416 insertions(+), 313 deletions(-) + +commit 2cddba811592fbb990322fbf2dce516ffd7e94cd +Author: Simon Feltman +Date: Sat Oct 12 12:39:20 2013 -0700 + + cache refactoring: Move closure setup and marshaling into pygi-closure + + Move closure argument caching and marshaling fragments into + pygi-closure.c. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/pygi-cache.c | 111 ++-------------- + gi/pygi-cache.h | 9 -- + gi/pygi-closure.c | 314 + +++++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-closure.h | 13 +- + gi/pygi-marshal-cleanup.c | 14 --- + gi/pygi-marshal-cleanup.h | 5 - + gi/pygi-marshal-from-py.c | 160 ----------------------- + gi/pygi-marshal-from-py.h | 6 - + gi/pygi-marshal-to-py.c | 13 -- + gi/pygi-marshal-to-py.h | 4 - + 10 files changed, 333 insertions(+), 316 deletions(-) + +commit 18d8274724484a27e05d2e60baac1f20c72b6d2b +Author: Simon Feltman +Date: Sat Oct 12 11:30:36 2013 -0700 + + cache refactoring: Move GError arg setup and marshaling to new file + + Move GError argument caching and marshaling fragments into + isolated file: pygi-error.c. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-cache.c | 93 ++++++++++++--------------------------- + gi/pygi-error.c | 109 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-error.h | 35 +++++++++++++++ + gi/pygi-marshal-from-py.c | 13 ------ + gi/pygi-marshal-from-py.h | 6 --- + gi/pygi-marshal-to-py.c | 22 ---------- + gi/pygi-marshal-to-py.h | 4 -- + 8 files changed, 174 insertions(+), 110 deletions(-) + +commit c45cafd07fc62ad545f3e58f2b7350ee4b2bb9b7 +Author: Simon Feltman +Date: Sat Oct 12 03:07:53 2013 -0700 + + cache refactoring: Move GArray arg setup and marshaling into new file + + Move GArray argument caching and marshaling fragments into an + isolated file: pygi-array.c. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-array.c | 906 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-array.h | 42 +++ + gi/pygi-cache.c | 236 +----------- + gi/pygi-marshal-cleanup.c | 150 -------- + gi/pygi-marshal-cleanup.h | 10 - + gi/pygi-marshal-from-py.c | 354 ------------------ + gi/pygi-marshal-from-py.h | 6 - + gi/pygi-marshal-to-py.c | 210 ----------- + gi/pygi-marshal-to-py.h | 4 - + 10 files changed, 963 insertions(+), 957 deletions(-) + +commit 4697a3793b46a803c6dbef749ba75c0fee80020d +Author: Simon Feltman +Date: Fri Oct 11 23:26:08 2013 -0700 + + cache refactoring: Move GList/GSList arg setup and marshaling into + new file + + Move GList and GSList argument caching and marshaling fragments + into an + isolated file: pygi-list.c. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-cache.c | 71 ++----- + gi/pygi-list.c | 466 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-list.h | 38 ++++ + gi/pygi-marshal-cleanup.c | 80 -------- + gi/pygi-marshal-cleanup.h | 10 - + gi/pygi-marshal-from-py.c | 156 ---------------- + gi/pygi-marshal-from-py.h | 12 -- + gi/pygi-marshal-to-py.c | 98 ---------- + gi/pygi-marshal-to-py.h | 8 - + 10 files changed, 517 insertions(+), 424 deletions(-) + +commit c48ddacf4479d2cf80beb9c614cdce2a61599b3b +Author: Simon Feltman +Date: Fri Oct 11 21:30:45 2013 -0700 + + cache refactoring: Break sequence cache up for array vs list + + Add new arg cache type specialized for arrays. This cleans up + the basic + sequence cache type which does not need length and size related + info. Remove + fixed length checks from GList and GSList from_py marshaling + because these + will always be -1. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/pygi-cache.c | 160 + +++++++++++++++++++++++++++++++++++----------- + gi/pygi-cache.h | 16 ++++- + gi/pygi-invoke.c | 4 +- + gi/pygi-marshal-cleanup.c | 28 ++++---- + gi/pygi-marshal-from-py.c | 37 ++++------- + gi/pygi-marshal-to-py.c | 23 +++---- + 6 files changed, 177 insertions(+), 91 deletions(-) + +commit c1a2a86a7b51f4dc5a5da9f8808552c38acadf9d +Author: Simon Feltman +Date: Fri Oct 11 20:12:01 2013 -0700 + + cache refactoring: Move basic type arg setup and marshaling into + new file + + Move all basic type arg caching and marshaling fragments into + an isolated + file where most functions are made static. pygi-basictype.h exposes: + pygi_arg_basic_type_new_from_info, _pygi_marshal_from_py_basic_type, + and + _pygi_marshal_to_py_basic_type which allows continued use for all + marshaling + code paths. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 1 + + gi/pygi-basictype.c | 824 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-basictype.h | 42 +++ + gi/pygi-cache.c | 82 +---- + gi/pygi-cache.h | 1 + + gi/pygi-marshal-cleanup.c | 26 -- + gi/pygi-marshal-cleanup.h | 10 - + gi/pygi-marshal-from-py.c | 478 --------------------------- + gi/pygi-marshal-from-py.h | 18 - + gi/pygi-marshal-to-py.c | 155 --------- + gi/pygi-marshal-to-py.h | 11 - + 12 files changed, 880 insertions(+), 770 deletions(-) + +commit 4a6bf3be49cc5aec7287c41ec02c78d60df1d44c +Author: Simon Feltman +Date: Fri Oct 11 17:39:31 2013 -0700 + + cache refactoring: Move PyGIHashCache and related marshaling into + new file + + Re-organize hash table arg cache and its marshaling by moving all + related code fragments into an isolated file where most of it is made + static. pygi-hashtable.h exposes a single function: + pygi_arg_hash_table_new_from_info. This is all the caching system + needs to + produce the proper bits for handling hash table marshaling. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/Makefile.am | 4 +- + gi/pygi-cache.c | 103 +----------- + gi/pygi-cache.h | 21 ++- + gi/pygi-hashtable.c | 413 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-hashtable.h | 35 ++++ + gi/pygi-marshal-cleanup.c | 63 ------- + gi/pygi-marshal-cleanup.h | 10 -- + gi/pygi-marshal-from-py.c | 125 -------------- + gi/pygi-marshal-from-py.h | 6 - + gi/pygi-marshal-to-py.c | 85 ---------- + gi/pygi-marshal-to-py.h | 4 - + 11 files changed, 471 insertions(+), 398 deletions(-) + +commit 983d0c2252f91e63d5fa0222ef2b67722cb97434 +Author: Simon Feltman +Date: Fri Oct 11 15:49:32 2013 -0700 + + cache refactoring: Separate ArgCache creation and setup + + Move PyGIArgCache and PyGIInterfaceCache generic setup into standalone + functions: pygi_arg_base_setup and pygi_arg_interface_setup + respectively. + Shift argument order and move arguments which will eventually + be removed + from the signature into the tail with comment. Isolate special + casing for + GI_INFO_TYPE_CALLBACK ArgCache creation to a single location in + _arg_cache_new_for_interface. + + https://bugzilla.gnome.org/show_bug.cgi?id=709700 + + gi/pygi-cache.c | 263 + ++++++++++++++++++++++++++++++++------------------------ + gi/pygi-cache.h | 15 ++++ + 2 files changed, 167 insertions(+), 111 deletions(-) + +commit 0af98aca40fe266d1fd93caaa7256bb92ba1d3e4 +Author: Simon Feltman +Date: Sun Feb 2 15:52:24 2014 -0800 + + tests: Add skip and expectedFailure to test_gi.test_callback_owned_box + + https://bugzilla.gnome.org/show_bug.cgi?id=722899 + + tests/test_gi.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit e79d2acc54c1e3b052835de5de20feb0b7069476 +Author: Mike Gorse +Date: Fri Jan 24 05:17:06 2014 -0600 + + tests: Add test for an owned boxed struct passed in a callback + + https://bugzilla.gnome.org/show_bug.cgi?id=722899 + + tests/test_gi.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit b12ceed8cc5fa398cea2061813aac6a5ba100b6f +Author: Simon Feltman +Date: Thu Jan 23 17:19:12 2014 -0800 + + Rename gi.types.GIObjectMeta to gi.types.GObjectMeta + + Rename GIObjectMeta to GObjectMeta reverting it to its original + name prior + to commit https://git.gnome.org/browse/pygobject/commit/?id=2624bd2b + That change could have been considered an API break for anyone + deriving from + gi.types.GObjectMeta since it is essentially public API. Rename + base meta + class to _GObjectMetaBase which was previously gi._gobject before + commit 2624bd2b (private API). + + gi/module.py | 8 ++++---- + gi/types.py | 10 +++++----- + 2 files changed, 9 insertions(+), 9 deletions(-) + +commit 15fdd827ce4bff847fb35c817c6ea2d3650eec00 +Author: Patrick Welche +Date: Thu Jan 23 23:49:51 2014 +0000 + + build: Add --without-common configure option for package maintainers + + https://bugzilla.gnome.org/show_bug.cgi?id=721646 + + Makefile.am | 2 ++ + configure.ac | 7 +++++++ + gi/Makefile.am | 2 ++ + 3 files changed, 11 insertions(+) + +commit df21dbbc84fa319af2a0f0664de436ca30df616e +Author: Simon Feltman +Date: Thu Jan 16 16:33:41 2014 -0800 + + tests: Add skipped test for GLib.Source inheritance problems + + Add test showing memory problems with sub-classes of GLib.Source. + + https://bugzilla.gnome.org/show_bug.cgi?id=722387 + + tests/test_source.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +commit 7222a37a4b4955fe6c1dcc86e0eb798d653711e8 +Author: Simon Feltman +Date: Wed Jan 15 12:51:57 2014 -0800 + + Fix reference sharing of gi sub-modules in Python 2 + + Ensure we add a new reference to sub-modules added to gi._gi. This may + have caused GC errors upon exiting the Python process since a + reference was + shared by sys.modules and gi._gi. + + https://bugzilla.gnome.org/show_bug.cgi?id=722274 + + gi/gimodule.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 8c838b683220bcbf2091bba97b91ddb56b275aed +Author: Simon Feltman +Date: Tue Jan 14 23:46:44 2014 -0800 + + demo: Add TreeModel interface implementation demonstration + + Add demo which shows how to implement the Gtk.TreeModel interfaces + virtual + methods. + + demos/gtk-demo/demos/TreeView/treemodel_large.py | 143 + +++++++++++++++++++++++ + 1 file changed, 143 insertions(+) + +commit 911898bac5d0ad5a42ed9990588bd98871f4a8a4 +Author: Simon Feltman +Date: Tue Jan 14 23:33:16 2014 -0800 + + demo: Remove "Icon View" and "Tree View" directories + + demos/gtk-demo/demos/Icon View/__init__.py | 0 + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 220 ---------------- + demos/gtk-demo/demos/Icon View/iconviewedit.py | 98 -------- + demos/gtk-demo/demos/Tree View/__init__.py | 0 + demos/gtk-demo/demos/Tree View/liststore.py | 210 ---------------- + .../gtk-demo/demos/Tree View/treemodel_filelist.py | 234 + ----------------- + .../gtk-demo/demos/Tree View/treemodel_filetree.py | 279 + --------------------- + 7 files changed, 1041 deletions(-) + +commit f89fa08ba756a1c529ff48beb39025f834a249bf +Author: Simon Feltman +Date: Tue Jan 14 23:08:33 2014 -0800 + + demo: Remove spaces from demo sub-directories + + Move "Icon View" to IconView and "Tree View" to TreeView. This + will help + ability to package the demos in tarball releases in future versions. + + demos/gtk-demo/demos/IconView/__init__.py | 0 + demos/gtk-demo/demos/IconView/iconviewbasics.py | 220 ++++++++++++++++ + demos/gtk-demo/demos/IconView/iconviewedit.py | 98 ++++++++ + demos/gtk-demo/demos/TreeView/__init__.py | 0 + demos/gtk-demo/demos/TreeView/liststore.py | 210 ++++++++++++++++ + .../gtk-demo/demos/TreeView/treemodel_filelist.py | 234 + +++++++++++++++++ + .../gtk-demo/demos/TreeView/treemodel_filetree.py | 279 + +++++++++++++++++++++ + 7 files changed, 1041 insertions(+) + +commit 0b7d85f3379adfb3cf1122588e333707ee089e46 +Author: Simon Feltman +Date: Tue Jan 14 14:28:52 2014 -0800 + + build: Remove _glib directory include from testhelper CFLAGS + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 35b5a85aad91f48935dd49fee60d69e6184eff2c +Author: Colin Walters +Date: Tue Jan 14 16:33:38 2014 -0500 + + build: Set PLATFORM_VERSION again to 3.0 + + We are installing headers to: + /usr/include/pygobject-$(PLATFORM_VERSION)/pygobject.h + + If the variable isn't set, then things attempting to use pygobject + obviously fail. + + This was a regression from a build system refactoring. + + gi/Makefile.am | 2 ++ + 1 file changed, 2 insertions(+) + +commit f2a79904ff4d60bff657bfbfd6a2ce8ab9307848 +Author: Simon Feltman +Date: Tue Jan 14 12:54:42 2014 -0800 + + Fix Python 2 build warning for module definitions + + Define PYGLIB_MODULE_ERROR_RETURN as NULL for both Python 2 and + 3. This is + needed now that the function signature created with + PYGLIB_MODULE_START is + consistent between the two versions. + + gi/pyglib-python-compat.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 61b4af05646a8f014cfb00a5507fec2deb9aafa6 +Author: Simon Feltman +Date: Tue Jan 14 12:26:16 2014 -0800 + + tests: Run PyFlakes and PEP8 only on SUBDIRS + + Move PyFlakes and PEP8 checks into check-local of the root + Makefile.am. Only + run these tools on selective subdirs of top_srcdir. This fixes + a problem + where vpath build directories within the srcdir would contain links + to the + source files, causing these tools to run multiple times slowing + down the + check process. + + Makefile.am | 21 ++++++++++++++++++++- + tests/Makefile.am | 6 ------ + 2 files changed, 20 insertions(+), 7 deletions(-) + +commit 9a7f6f08c1dc0eb0dd91437da8ac429fbafc8a4a +Author: Simon Feltman +Date: Tue Jan 14 12:25:09 2014 -0800 + + Remove _glib include path from gi module target + + gi/Makefile.am | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +commit 8afd7e880a72a44e6ea46c763bab82146fd75c96 +Author: Simon Feltman +Date: Wed Jan 8 19:22:08 2014 -0800 + + Move Python glib options module into gi package + + Move gi/_glib/option.py into gi/_option.py. Remove gi/_glib since + it is no + longer needed. + + https://bugzilla.gnome.org/show_bug.cgi?id=712197 + + Makefile.am | 3 +- + configure.ac | 1 - + gi/Makefile.am | 1 - + gi/_glib/Makefile.am | 21 --- + gi/_glib/__init__.py | 20 --- + gi/_glib/option.py | 363 + ------------------------------------------------ + gi/_option.py | 363 + ++++++++++++++++++++++++++++++++++++++++++++++++ + gi/overrides/GLib.py | 2 +- + gi/overrides/GObject.py | 2 +- + 9 files changed, 367 insertions(+), 409 deletions(-) + +commit ad565e5bbc9d12607c39be9479bc671a8f2de6e3 +Author: Simon Feltman +Date: Wed Jan 8 18:57:58 2014 -0800 + + Merge static PyGLib module into PyGI + + Remove gi._glib._glib as a separately compiled module. Move all C + files into + pygobject/gi. Remove compilation and use of libpyglib-gi-2.0-python.so + as a + shared dependency since we do not distribute header files for it. + Remove unused threading macros. + + https://bugzilla.gnome.org/show_bug.cgi?id=712197 + + gi/Makefile.am | 16 +- + gi/_glib/Makefile.am | 74 +------ + gi/_glib/__init__.py | 5 - + gi/_glib/glibmodule.c | 103 --------- + gi/_glib/option.py | 2 +- + gi/_glib/pyglib-private.h | 49 ----- + gi/_glib/pyglib-python-compat.h | 195 ----------------- + gi/_glib/pyglib.c | 475 + ---------------------------------------- + gi/_glib/pyglib.h | 77 ------- + gi/_glib/pygoptioncontext.c | 337 ---------------------------- + gi/_glib/pygoptioncontext.h | 39 ---- + gi/_glib/pygoptiongroup.c | 298 ------------------------- + gi/_glib/pygoptiongroup.h | 42 ---- + gi/_glib/pygspawn.c | 259 ---------------------- + gi/_glib/pygspawn.h | 32 --- + gi/gimodule.c | 9 + + gi/glibmodule.c | 77 +++++++ + gi/gobjectmodule.c | 5 +- + gi/overrides/GLib.py | 2 +- + gi/pyglib-private.h | 43 ++++ + gi/pyglib-python-compat.h | 195 +++++++++++++++++ + gi/pyglib.c | 402 ++++++++++++++++++++++++++++++++++ + gi/pyglib.h | 67 ++++++ + gi/pygoptioncontext.c | 337 ++++++++++++++++++++++++++++ + gi/pygoptioncontext.h | 39 ++++ + gi/pygoptiongroup.c | 298 +++++++++++++++++++++++++ + gi/pygoptiongroup.h | 42 ++++ + gi/pygspawn.c | 259 ++++++++++++++++++++++ + gi/pygspawn.h | 32 +++ + 29 files changed, 1819 insertions(+), 1991 deletions(-) + +commit 2624bd2b4a465a2d234951dd5b855fe8a0d46e1c +Author: Simon Feltman +Date: Thu Oct 31 03:13:53 2013 -0700 + + Move gobject sub-module Python files into the main gi package + + This moves the signalhelper, propertyhelper, and constants Python + modules + from gi/_gobject into gi. Keep gi/_gobject/__init__.py around because + it is + still needed to maintain the "_PyGObject_API" exposed by + pygobject.h. This + allows external modules compiled with prior versions of PyGObject to + continue working with newer versions. + + https://bugzilla.gnome.org/show_bug.cgi?id=712197 + + Makefile.am | 5 +- + gi/__init__.py | 19 +- + gi/_constants.py | 49 +++++ + gi/_gobject/Makefile.am | 5 +- + gi/_gobject/__init__.py | 42 +---- + gi/_gobject/constants.py | 50 ----- + gi/_gobject/propertyhelper.py | 417 + ------------------------------------------ + gi/_gobject/signalhelper.py | 259 -------------------------- + gi/_propertyhelper.py | 417 + ++++++++++++++++++++++++++++++++++++++++++ + gi/_signalhelper.py | 258 ++++++++++++++++++++++++++ + gi/module.py | 16 +- + gi/overrides/GObject.py | 7 +- + gi/overrides/__init__.py | 2 +- + gi/types.py | 41 ++++- + pygtkcompat/pygtkcompat.py | 4 +- + tests/test_gi.py | 2 +- + tests/test_gobject.py | 4 +- + tests/test_properties.py | 2 +- + tests/test_signal.py | 2 +- + 19 files changed, 796 insertions(+), 805 deletions(-) + +commit d3e8946dbb23197a2e9d7de351a7b9cd04d360b9 +Author: Simon Feltman +Date: Thu Oct 31 02:22:03 2013 -0700 + + Merge gobject static code into the gi module + + Remove gi._gobject._gobject as a separately compiled static module and + move all the files into gi._gi. + Remove dead module initialization macros from "pyglib-python-compat.h" + + https://bugzilla.gnome.org/show_bug.cgi?id=712197 + + gi/Makefile.am | 31 +- + gi/_glib/pyglib-python-compat.h | 62 +- + gi/_gobject/Makefile.am | 69 +- + gi/_gobject/__init__.py | 4 +- + gi/_gobject/constants.py | 3 +- + gi/_gobject/gobjectmodule.c | 2213 + ----------------------------------- + gi/_gobject/propertyhelper.py | 16 +- + gi/_gobject/pygboxed.c | 235 ---- + gi/_gobject/pygboxed.h | 27 - + gi/_gobject/pygenum.c | 371 ------ + gi/_gobject/pygenum.h | 27 - + gi/_gobject/pygflags.c | 497 -------- + gi/_gobject/pygflags.h | 27 - + gi/_gobject/pyginterface.c | 124 -- + gi/_gobject/pyginterface.h | 40 - + gi/_gobject/pygobject-private.h | 204 ---- + gi/_gobject/pygobject.c | 2473 + --------------------------------------- + gi/_gobject/pygobject.h | 636 ---------- + gi/_gobject/pygparamspec.c | 418 ------- + gi/_gobject/pygparamspec.h | 31 - + gi/_gobject/pygpointer.c | 198 ---- + gi/_gobject/pygpointer.h | 27 - + gi/_gobject/pygtype.c | 1927 ------------------------------ + gi/_gobject/pygtype.h | 28 - + gi/_gobject/signalhelper.py | 3 +- + gi/gimodule.c | 13 +- + gi/gobjectmodule.c | 2213 + +++++++++++++++++++++++++++++++++++ + gi/module.py | 4 +- + gi/pygboxed.c | 235 ++++ + gi/pygboxed.h | 27 + + gi/pygenum.c | 371 ++++++ + gi/pygenum.h | 27 + + gi/pygflags.c | 497 ++++++++ + gi/pygflags.h | 27 + + gi/pygi-argument.c | 3 +- + gi/pygi-boxed.c | 2 +- + gi/pygi-ccallback.c | 2 +- + gi/pygi-foreign.c | 2 +- + gi/pygi-info.c | 2 +- + gi/pygi-marshal-to-py.c | 3 +- + gi/pygi-private.h | 2 +- + gi/pygi-source.c | 3 +- + gi/pygi-struct.c | 2 +- + gi/pygi.h | 3 +- + gi/pyginterface.c | 124 ++ + gi/pyginterface.h | 40 + + gi/pygobject-private.h | 205 ++++ + gi/pygobject.c | 2473 + +++++++++++++++++++++++++++++++++++++++ + gi/pygobject.h | 636 ++++++++++ + gi/pygparamspec.c | 418 +++++++ + gi/pygparamspec.h | 33 + + gi/pygpointer.c | 198 ++++ + gi/pygpointer.h | 27 + + gi/pygtype.c | 1927 ++++++++++++++++++++++++++++++ + gi/pygtype.h | 28 + + gi/types.py | 3 +- + tests/Makefile.am | 2 +- + 57 files changed, 9594 insertions(+), 9649 deletions(-) + +commit a329f559002f2be0898309c9d81cdf2c34aef158 +Author: Simon Feltman +Date: Tue Jan 14 10:15:53 2014 -0800 + + tests: Fix test_torture_profile to return a number from its callback + + Return a number from rather than None from the callback passed to + regress_test_torture_signature_2. This fixes a TypeError being + raised in + callback return argument marshaling which was ignored by the test + suite. + + tests/test_everything.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a50a8386aae54dace7e46569415fdef85758fb9c +Author: Martin Pitt +Date: Tue Jan 14 08:53:25 2014 +0100 + + Add test for callback user data arguments with following arguments + + In this case we can't use the varargs userdata handling. Provides + test case for + https://bugzilla.gnome.org/show_bug.cgi?id=722104. + + tests/test_everything.py | 48 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +commit 3563a2d21a9e08a802d1cf30e04ba340e0bcfb49 +Author: Simon Feltman +Date: Mon Jan 13 08:19:02 2014 -0800 + + valgrind: Add suppression files for python3.3 and python3.3dm + + Add new suppression files for Python 3. Use PYTHON_BASENAME for the + suppression filename in the various make check.valgrind + targets. Rename + python.supp to python2.7.supp + + tests/Makefile.am | 6 +- + tests/python.supp | 387 ---------------------------------------- + tests/python2.7.supp | 387 ++++++++++++++++++++++++++++++++++++++++ + tests/python3.3.supp | 471 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/python3.3dm.supp | 471 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 1332 insertions(+), 390 deletions(-) + +commit 5c6f8afed5f6aa05d65d64509a2c9b8041a66b05 +Author: Simon Feltman +Date: Mon Jan 13 18:53:55 2014 -0800 + + Makefile.am: Fix NEWS and ChangeLog generation under vpath builds + + Make sure NEWS generation uses top_srcdir to allow "make release-news" + to + work under a vpath build (directory outside the source tree). + Update ChangeLog target to use $(top_srcdir)/missing. This fixes + a problem + where running "make dist" under a vpath build directory would + include an + empty ChangeLog. + + Makefile.am | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 056325cba3c86aefcf45ba10f2b7cf86e9fc1800 +Author: Simon Feltman +Date: Mon Jan 13 18:53:02 2014 -0800 + + Update HACKING to include better release tagging instructions + + HACKING | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +commit c0a43d259c003c5d06db23debd0675b87e805b74 +Author: Simon Feltman +Date: Mon Jan 13 17:20:17 2014 -0800 + + configure.ac: post release version bump to 3.11.5 + + NEWS | 16 ++++++++++++++++ + configure.ac | 2 +- + 2 files changed, 17 insertions(+), 1 deletion(-) + +commit 44d003798d9d14dde16fb44c69b94a411bdee26b +Author: Simon Feltman +Date: Mon Jan 13 16:51:41 2014 -0800 + + Fix mid-argument list callback user data expecting a tuple + + Ensure user data arguments are always packed into a tuple during + callback + marshaling. This fixes cases where there is mid-argument user data + which is + not in the form of a variable length tuple. + + https://bugzilla.gnome.org/show_bug.cgi?id=722104 + + gi/pygi-marshal-from-py.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +commit 415b240e3baab522f3bf9752995610f950ba609e +Author: Simon Feltman +Date: Tue Oct 15 03:57:52 2013 -0700 + + Remove special case GObject base class check when creating GI classes + + Replace explicit GObject.Object string name check when calculating the + introspection class hierarchy with a more generalized technique. This + allows + any C based wrapper of a GType to "underride" an introspection class + automatically. This currently only handles the case of GObject.Object, + but + will be used for fundamentals and GParamSpec. + + https://bugzilla.gnome.org/show_bug.cgi?id=631901 + + gi/module.py | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +commit 9b02b29016958791dfa9d7ebfc6c2ec44ab5690d +Author: Simon Feltman +Date: Tue Jan 7 09:16:54 2014 -0800 + + overrides: Fix __repr__ for various Gdk structs + + Change __repr__ overrides for Gdk.Color, Gdk.RGBA, and Gdk.Atom to + return a + string reprentation that is valid Python given an expected + environment. + See: http://docs.python.org/2/reference/datamodel.html#object.__repr__ + + gi/overrides/Gdk.py | 10 +++++----- + tests/test_atoms.py | 7 +++++-- + tests/test_overrides_gdk.py | 9 +++++++++ + 3 files changed, 19 insertions(+), 7 deletions(-) + +commit f6a87935596a3b59c238a5572b288f34691b53d1 +Author: Simon Feltman +Date: Tue Jan 7 07:31:22 2014 -0800 + + docs: Fix array length argument skipping with preceding out arguments + + Remove split_function_info_args and use a list of all arguments for + generating skipped index lists. Determine argument skipping based + on the + full argument list in each in/inout and out/inout argument list + buildouts. + This fixes a problem where out arguments preceding array length + arguments + would still show array length arguments in the docstring. This was + due to an + index mismatch when using split lists instead of list of all + arguments. + + gi/docstring.py | 38 ++++++++++++-------------------------- + tests/test_docstring.py | 37 +++++++++++++++---------------------- + 2 files changed, 27 insertions(+), 48 deletions(-) + +commit f114edc0a0afa64077a13459034afc4255b7a3f1 +Author: Simon Feltman +Date: Mon Jan 6 22:10:47 2014 -0800 + + overrides: Remove GLib.Source.attach + + Remove GLib.Source.attach override now that tail end allow-none + arguments + default to None when not specified. + + gi/overrides/GLib.py | 5 ----- + tests/test_glib.py | 7 +++++++ + 2 files changed, 7 insertions(+), 5 deletions(-) + +commit 50ab6a8b70cbe7b67fc8d804b7773bb2c9b47251 +Author: Simon Feltman +Date: Mon Jan 6 21:42:09 2014 -0800 + + overrides: Remove Gtk overrides with tail end allow-none keywords + + Remove overrides for Widget.render_icon, TextIter.begins_tag, + ends_tag, + toggles_tag, and TreeModel.filter_new. These overrides added an + optional keyword=None for allow-none arguments. This is now implicitly + accepted by the PyGObject machinery so the overrides can go away. + + gi/overrides/Gtk.py | 16 ---------------- + tests/test_overrides_gtk.py | 11 +++++++++++ + 2 files changed, 11 insertions(+), 16 deletions(-) + +commit 2d388fcfca4bf1258d01b4491b4168589f3dd2b0 +Author: Simon Feltman +Date: Mon Jan 6 21:22:41 2014 -0800 + + overrides: Remove Pango.Context.get_metrics + + Remove the override for Pango.Context and the get_metrics method. This + can + be done now that tail end method arguments with "allow-none" + are implicitly + defaulted to use None/NULL. + + gi/overrides/Pango.py | 9 --------- + tests/test_overrides_pango.py | 12 ++++++++++++ + 2 files changed, 12 insertions(+), 9 deletions(-) + +commit 43b35b1df3b6c0d8679f3cc0b08ef6ddcb276331 +Author: Simon Feltman +Date: Mon Jan 6 17:35:04 2014 -0800 + + Add enum and flags member methods + + Add all methods from GIEnumInfo to both enums and flags classes. + + https://bugzilla.gnome.org/show_bug.cgi?id=693099 + + gi/module.py | 2 ++ + tests/test_gi.py | 9 +++++++++ + 2 files changed, 11 insertions(+) + +commit 731a2cb4372084eac6cfe5bf190f6efa730e97e4 +Author: Patrick Welche +Date: Mon Jan 6 22:31:48 2014 +0000 + + python.m4: g/c JD_PYTHON_CHECK_VERSION + + We currently require automake 1.11.1, and its AM_PYTHON_CHECK_VERSION + is identical (made here). + + https://bugzilla.gnome.org/show_bug.cgi?id=721662 + + configure.ac | 4 ++-- + m4/python.m4 | 23 ++--------------------- + 2 files changed, 4 insertions(+), 23 deletions(-) + +commit aaaead18e2167c2becb309f1d9ae199222c0256b +Author: Simon Feltman +Date: Sat Jan 4 16:31:56 2014 -0800 + + Support union creation with PyGIStruct + + Add additional case for allowing the creation bare unions wrapped with + PyGIStruct. This is needed because PyGIStruct wraps both GIStruct and + GIUnion types. + + gi/pygi-struct.c | 39 ++++++++++++++++++++++++++++++++++----- + tests/test_repository.py | 13 +++++++++++++ + 2 files changed, 47 insertions(+), 5 deletions(-) + +commit 64f15961b637a7e1388bd8d2cd08f04fa20e4de4 +Author: Simon Feltman +Date: Sat Jan 4 16:07:44 2014 -0800 + + Fix crash in error handling when creating struct with mismatched + info type + + Error handling code was attempting to get the PyType of a pointer to a + pointer. Use the correct amount of indirection so an exception is + raised as + intended rather than a segfault. + + gi/pygi-info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 07abf8343bbeac6f36d370ced654fa6506b22175 +Author: Simon Feltman +Date: Wed Jan 1 20:23:17 2014 -0800 + + docs: Skip display of default constructor for disguised structs + + Structs which have zero length should now show a default constructor. + Structs with a length should not show keyword arguments in the default + constructor. + + https://bugzilla.gnome.org/show_bug.cgi?id=708060 + + gi/docstring.py | 9 ++++++++- + tests/test_docstring.py | 18 ++++++++++++++++-- + 2 files changed, 24 insertions(+), 3 deletions(-) + +commit e8359847136e9ad76a670a382c0abc61cb4e81d3 +Author: Simon Feltman +Date: Wed Jan 1 19:57:06 2014 -0800 + + Cleanup disguised struct constructor error and add it to boxed + + Give a cleaner error message when an attempt is made to create + a disguised + struct which also gives a hint to look at the pydoc. Add similar + error to + disguised boxed/unions. + + https://bugzilla.gnome.org/show_bug.cgi?id=647249 + + gi/pygi-boxed.c | 17 ++++++++++++++--- + gi/pygi-struct.c | 2 +- + tests/test_everything.py | 1 - + tests/test_glib.py | 4 ++++ + 4 files changed, 19 insertions(+), 5 deletions(-) + +commit 9ce527b09ed032f2cc83c2d83de8bb6d7b19be02 +Author: Simon Feltman +Date: Wed Jan 1 19:54:59 2014 -0800 + + docs: List default constructor in doc strings + + Add default constructor to class docs strings as: + Object(**properties) + + https://bugzilla.gnome.org/show_bug.cgi?id=708060 + + gi/docstring.py | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +commit 9bfd73e7c3f2ec4975b3e530ba7c2cc55ee793d5 +Author: Simon Feltman +Date: Wed Jan 1 17:34:32 2014 -0800 + + docs: List constructors in object and struct doc strings + + Add type dispatching to gi.docstring documentation generator for + info types + of StructInfo and ObjectInfo. Add lazy doc string generation to + Object and Struct meta classes by using a property for __doc__. This + lists + available constructors immediately in all GObject.Object and Struct + docs. + ipython example: + + >>> Gtk.Button? + :Constructors: + Button(**properties) + new() + new_from_icon_name(icon_name:str, size:int) + new_from_stock(stock_id:str) + new_with_label(label:str) + new_with_mnemonic(label:str) + + https://bugzilla.gnome.org/show_bug.cgi?id=708060 + + gi/docstring.py | 36 +++++++++++++++++++++++++++++------- + gi/types.py | 9 +++++++++ + tests/test_docstring.py | 8 ++++++++ + 3 files changed, 46 insertions(+), 7 deletions(-) + +commit 44612636575dd93c97210a7255c4490e2c84db67 +Author: Simon Feltman +Date: Wed Jan 1 17:10:15 2014 -0800 + + docs: Cleanup PyGIBaseInfo repr + + Remove angle brackets and pointer address from + PyGIBaseInfo.__repr__. This + cleans up documentation and makes it easier to read. + + gi/pygi-info.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 826c0e63eabac68fd665335950d311988a1405e3 +Author: Simon Feltman +Date: Tue Dec 31 21:45:21 2013 -0800 + + docs: Add return values and skip implicit out arguments in functions + + Add gi.CallableInfo.skip_return static binding for testing if + the return + value should show up in docs. Skip implicit list index arguments + for out + values. + + https://bugzilla.gnome.org/show_bug.cgi?id=697356 + + gi/docstring.py | 26 +++++++++++++++++++++----- + gi/pygi-info.c | 7 +++++++ + tests/test_docstring.py | 6 ++++++ + 3 files changed, 34 insertions(+), 5 deletions(-) + +commit aeccdaddf32dc7b48a79a1cd95a421a26895c9b2 +Author: Simon Feltman +Date: Tue Dec 31 21:15:27 2013 -0800 + + docs: Replace usage of functools.wraps with a custom version + + Using functools.wraps in overrides would cause docstring evaluation + which + can hurt performance during overrides loading. Add custom wraps + decorator + which only copies __name__ and __module__ attributes. Remove function + wrapping used within gi.overrides.overridefunc because the wrapping + was not + doing anything, this preserves __doc__ ability without causing an + eval at + load time. + + https://bugzilla.gnome.org/show_bug.cgi?id=697356 + + gi/overrides/GObject.py | 3 +-- + gi/overrides/__init__.py | 21 ++++++++++++--------- + 2 files changed, 13 insertions(+), 11 deletions(-) + +commit cebf5314f195bf4bd6ee19a1da3bbb50c2c9bbd6 +Author: Simon Feltman +Date: Tue Dec 31 19:42:02 2013 -0800 + + docs: Move GIArgInfo.get_pytype_hint into gi.docstring + + Move the C implementation of pytype hinting into pure Python. Now that + doc strings are lazily evaluated we can simplify this tedious bit of C + code with Python. This is precursory work for getting return + types into + function doc strings. + + https://bugzilla.gnome.org/show_bug.cgi?id=697356 + + gi/docstring.py | 50 ++++++++++++++++++++++++++++++++++++++--- + gi/pygi-info.c | 49 ---------------------------------------- + gi/pygi-type.c | 58 + ------------------------------------------------ + gi/pygi-type.h | 2 -- + tests/test_docstring.py | 8 ++++--- + tests/test_repository.py | 1 - + 6 files changed, 52 insertions(+), 116 deletions(-) + +commit 28a178e385e32c56910f1c430b370a8872218081 +Author: Simon Feltman +Date: Tue Dec 31 17:50:36 2013 -0800 + + docs: Skip implicit array length args when building function doc + strings + + https://bugzilla.gnome.org/show_bug.cgi?id=697356 + + gi/docstring.py | 8 ++++++-- + tests/test_docstring.py | 4 ++++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +commit 2ef59b89311529e34366d4d7aa8f8ae9a8ea6371 +Author: Simon Feltman +Date: Tue Dec 31 13:41:20 2013 -0800 + + gtk-demo: Avoid crash in CSS demos + + Avoid a potential crash in the CSS demos where the text editing + buffer is + out of sync with the last good CSS parsing buffer. In the case of CSS + warnings, we get a parsing-error callback but no exception is raised. + This would cause the buffers to become out of sync and accessing + position + information from the parsing-error section would crash the text + editor due + to an out of range iterator being created. + + demos/gtk-demo/demos/Css/css_basics.py | 31 + +++++++++++++++++++++-------- + demos/gtk-demo/demos/Css/css_multiplebgs.py | 31 + +++++++++++++++++++++-------- + 2 files changed, 46 insertions(+), 16 deletions(-) + +commit b81f9c9b4e62d8cf589576aba8d9abbac4c80953 +Author: Simon Feltman +Date: Tue Dec 31 02:05:46 2013 -0800 + + gtk-demo: Add info bar and better error handling to CSS demos + + Use an info bar for displaying CSS parsing errors. Store the last good + stylesheet text for use as a backup when a parsing error occures. This + gives + a seamless look while typing changes into the text editor. + + https://bugzilla.gnome.org/show_bug.cgi?id=719722 + + demos/gtk-demo/demos/Css/css_basics.py | 28 + +++++++++++++++++++++------- + demos/gtk-demo/demos/Css/css_multiplebgs.py | 29 + ++++++++++++++++++++++------- + 2 files changed, 43 insertions(+), 14 deletions(-) + +commit becb56734e13df182fd31cfe46c465477dfc4d2c +Author: Gian Mario Tagliaretti +Date: Mon Dec 30 16:36:28 2013 +0100 + + gtk-demo: Add CSS demos + + Add a couple of demos demostrating the use of CSS, the css files are + stored into a GResource binary file compiled with + glib-compile-resources, + the comments in gtk-demo.py explain the usage of GResource. + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=719722 + + .gitignore | 1 + + demos/gtk-demo/demos/Css/__init__.py | 0 + demos/gtk-demo/demos/Css/css_accordion.py | 94 +++++++++++++++ + demos/gtk-demo/demos/Css/css_basics.py | 119 +++++++++++++++++++ + demos/gtk-demo/demos/Css/css_multiplebgs.py | 157 + ++++++++++++++++++++++++++ + demos/gtk-demo/demos/data/brick.png | Bin 0 -> 5043 bytes + demos/gtk-demo/demos/data/brick2.png | Bin 0 -> 10713 bytes + demos/gtk-demo/demos/data/css_accordion.css | 52 +++++++++ + demos/gtk-demo/demos/data/css_basics.css | 22 ++++ + demos/gtk-demo/demos/data/css_multiplebgs.css | 136 + ++++++++++++++++++++++ + demos/gtk-demo/demos/data/cssview.css | 41 +++++++ + demos/gtk-demo/demos/data/demo.gresource | Bin 0 -> 31110 bytes + demos/gtk-demo/demos/data/demo.gresource.xml | 18 +++ + demos/gtk-demo/demos/data/reset.css | 68 +++++++++++ + demos/gtk-demo/gtk-demo.py | 16 ++- + 15 files changed, 723 insertions(+), 1 deletion(-) + +commit 2ff095ea0b0c05fbf6cc332eeadf26cfeb9e69f7 +Author: Colin Watson +Date: Tue Dec 24 22:19:02 2013 +0000 + + build: Avoid clash between gi/types.py and stdlib + + Use non-recursive make for the Python modules in gi/ to work around a + clash between gi/types.py and the standard library's types module when + running py-compile. + + https://bugzilla.gnome.org/show_bug.cgi?id=721025 + + Signed-off-by: Martin Pitt + + Makefile.am | 24 ++++++++++++++++++++++++ + gi/Makefile.am | 20 ++------------------ + 2 files changed, 26 insertions(+), 18 deletions(-) + +commit b9716853fb7727fcf2b5ea59a3368d5a5b2e6be2 +Author: Simon Feltman +Date: Mon Dec 16 04:17:28 2013 -0800 + + configure.ac: post-release bump to 3.11.4 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2ec00c2563bebff1e55faf97c67e44fda862ad5b +Author: Simon Feltman +Date: Mon Dec 16 04:10:54 2013 -0800 + + release 3.11.3 + + NEWS | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 7fb55f93e207378992cd9f3e0663604a4de2213f +Author: Simon Feltman +Date: Thu Dec 12 01:35:11 2013 -0800 + + Replace usage of PyGIBoxed_Type with PyGIStruct_Type + + Remove empty definition of PyGIBoxed_Type and use PyGIStruct_Type + in its + place for GI_INFO_TYPE_BOXED based infos in repositories. As noted in + the docs: "GI_INFO_TYPE_BOXED boxed, see GIStructInfo or GIUnionInfo" + we can use the GIStructInfo API for boxed types because we also + dispatch + base classes on GType checks as seen in: + https://git.gnome.org/browse/pygobject/tree/gi/module.py?id=3.11.2#n186 + This fixes some of the issues noted in bug 581525. + + https://bugzilla.gnome.org/show_bug.cgi?id=581525 + + gi/pygi-info.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +commit b3c85eec75c62c138c136531ebe49a33351941f0 +Author: Simon Feltman +Date: Sun Nov 17 20:12:50 2013 -0800 + + configure.ac: post release version bump to 3.11.3 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d1314af8f237a634dbfefb0a1c319f910d3d8765 +Author: Simon Feltman +Date: Sun Nov 17 20:04:49 2013 -0800 + + release 3.11.2 + + NEWS | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 6fc3d977f17397e514aed492055e93d03c410f60 +Author: Simon Feltman +Date: Tue Nov 12 23:04:50 2013 -0800 + + gtk-demo: Fix pyflakes error after recent commit + + demos/gtk-demo/demos/pixbuf.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a309b3baf5ee99139cc2d1817339233e24391bc2 +Author: Simon Feltman +Date: Tue Nov 12 18:41:35 2013 -0800 + + gkt-demo: Change main info/source notebook into a GtkStack + + Use the new in 3.10 GtkStack and GtkStackSwitcher for switching + between Info + and Source tabs. Beyond giving a newer look and feel to the demo, + this also + provides an example for how to use a GtkStack. + + demos/gtk-demo/gtk-demo.py | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +commit 69ff43bf6292fb3ddaea027cfc595139c4f1655d +Author: Simon Feltman +Date: Tue Nov 12 19:32:18 2013 -0800 + + gtk-demo: Cleanup deprecated calls throughout demo code + + Specify constructor arguments as keyword args for various object + creation calls. Update combobox demo to use bind_property instead + of manual + signal connections with update callbacks. + + demos/gtk-demo/demos/Entry/entry_buffer.py | 6 ++--- + demos/gtk-demo/demos/Entry/entry_completion.py | 6 ++--- + demos/gtk-demo/demos/Entry/search_entry.py | 8 +++--- + demos/gtk-demo/demos/Tree View/liststore.py | 8 +++--- + .../gtk-demo/demos/Tree View/treemodel_filelist.py | 2 +- + .../gtk-demo/demos/Tree View/treemodel_filetree.py | 2 +- + demos/gtk-demo/demos/appwindow.py | 4 +-- + demos/gtk-demo/demos/combobox.py | 30 + +++------------------- + demos/gtk-demo/demos/dialogs.py | 26 + +++++++++---------- + demos/gtk-demo/demos/expander.py | 9 +++---- + demos/gtk-demo/demos/images.py | 2 +- + demos/gtk-demo/demos/infobars.py | 23 +++++++++-------- + demos/gtk-demo/demos/links.py | 10 ++++---- + demos/gtk-demo/demos/menus.py | 4 +-- + demos/gtk-demo/demos/pickers.py | 8 +++--- + demos/gtk-demo/demos/pixbuf.py | 4 +-- + demos/gtk-demo/demos/rotatedtext.py | 2 +- + 17 files changed, 64 insertions(+), 90 deletions(-) + +commit 890fb7b97823985d5c800284ead43a49174db244 +Author: Simon Feltman +Date: Tue Nov 12 18:19:34 2013 -0800 + + Revert TreeStore and ListStore initializer replacements + + Revert changes to Tree/ListStore where the __init__ overrides were + replaced + with __new__ overrides which accept column types directly. The + issue with + the change is sub-classes of these types can override __init__ + themself + passing in their own column types to the super class. These + sub-classes + expect the super class to handle column type setup via __init__ + and hence + the change described is an API break. This reverts parts of commit: + 2f2069c9efcd8f312ce9ffa572df371fbc08822d + + gi/overrides/Gtk.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +commit 795201873a3aae530598f5e16470b6a8d2d55c23 +Author: Simon Feltman +Date: Thu Aug 15 20:01:48 2013 -0700 + + Deprecate Gdk.Cursor constructor dispatching + + Give deprecation warning for the overridden __new__ method on + Gdk.Cursor when more than one argument is used. Recommend using + Gdk.Cursor.new_for_display, new_from_pixbuf, and new_from_pixmap + instead. + + https://bugzilla.gnome.org/show_bug.cgi?id=705810 + + gi/overrides/Gdk.py | 48 + ++++++++++++++++++++++++++------------------- + tests/test_overrides_gdk.py | 17 ++++++++++++---- + 2 files changed, 41 insertions(+), 24 deletions(-) + +commit 2f2069c9efcd8f312ce9ffa572df371fbc08822d +Author: Simon Feltman +Date: Thu Aug 15 19:23:18 2013 -0700 + + Cleanup overzealous new and init implementations + + Remove PyGObject initializer code attempting to set properties on + GObjects that have already been created. There were a number of + overridden __new__ and __init__ methods that stripped away + arguments before calling the base class to work around attempted + property sets and argument count errors (fixing the symptom not + the problem). + Use Gtk.ListStore/TreeStore.new with __new__ override instead + of __init__ with set_column_types. + + https://bugzilla.gnome.org/show_bug.cgi?id=705810 + + gi/_gobject/gobjectmodule.c | 35 ++++++++++++++--------------------- + gi/_gobject/pygobject.c | 16 ++++++++++++++-- + gi/overrides/GObject.py | 3 --- + gi/overrides/Gdk.py | 15 --------------- + gi/overrides/Gtk.py | 11 ++++------- + gi/overrides/Pango.py | 5 ----- + gi/pygi-boxed.c | 6 ------ + 7 files changed, 32 insertions(+), 59 deletions(-) + +commit 86a37d67455dc5d435ade35f17b27c5de2b288f5 +Author: Simon Feltman +Date: Tue Aug 13 18:02:54 2013 -0700 + + Add deprecation warnings and cleanup class initializer overrides + + Print deprecation warnings for calls to class initializers which + don't explicitly specify keywords. Print deprecation warning + for overrides that have renamed keywords (Gtk.Table.rows should + be n_rows). Additionally deprecate non-standard defaults with + initializers (Gtk.SizeGroup.mode defaults to HORIZONTAL in GTK+ + and VERTICAL in PyGI). + Remove AboutDialog override because it doesn't do anything. + + https://bugzilla.gnome.org/show_bug.cgi?id=705810 + + gi/overrides/Gio.py | 6 +- + gi/overrides/Gtk.py | 367 + ++++++++++++++++++++++---------------------- + gi/overrides/__init__.py | 88 +++++++++++ + tests/test_gi.py | 75 +++++++++ + tests/test_overrides_gtk.py | 95 ++++++++---- + 5 files changed, 411 insertions(+), 220 deletions(-) + +commit d2e9be8e2b3d21b55e1aad3d0b22dcff3421b702 +Author: Simon Feltman +Date: Tue Aug 13 17:42:11 2013 -0700 + + tests: Use explicit keywords args when calling initializers + + Replace all usage of GObject creation that relies on positional + arguments from overrides. Positional initializer args will be + deprecated, updating the tests as a first pass proves backwards + and forwards compatibility of the deprecation. + + https://bugzilla.gnome.org/show_bug.cgi?id=705810 + + tests/test_overrides_gtk.py | 107 + +++++++++++++++++++++++--------------------- + 1 file changed, 55 insertions(+), 52 deletions(-) + +commit 8342302dac9bf3fcb49ec3ac334dbf014b4db025 +Author: Simon Feltman +Date: Tue Nov 12 03:46:08 2013 -0800 + + Revert "Add type checking to positional Gtk.Box and Gtk.Window + ctor arguments" + + This reverts commit 7193f0509a0ed7da7c810daa6733e34a22db3180. + + gi/overrides/Gtk.py | 7 ------- + tests/test_overrides_gtk.py | 18 ------------------ + tests/test_properties.py | 9 --------- + 3 files changed, 34 deletions(-) + +commit 1f37340c4623262a2146ec8cd25b487cdf4234bd +Author: Simon Feltman +Date: Sun Nov 10 03:26:10 2013 -0800 + + Fix dir method for static GParamSpec in Python 3 + + Add a __dir__ method which lists GParamSpec attributes and remove + code from + getattr which made use of the deprecated __members__ technique for dir + (removed in Python 3). This makes dir(pspec) work again in Python 3. + + gi/_gobject/pygparamspec.c | 218 + ++++++++++++++++++++++++--------------------- + tests/test_gi.py | 10 +++ + 2 files changed, 126 insertions(+), 102 deletions(-) + +commit 7193f0509a0ed7da7c810daa6733e34a22db3180 +Author: Martin Pitt +Date: Tue Nov 5 15:28:12 2013 +0100 + + Add type checking to positional Gtk.Box and Gtk.Window ctor arguments + + Gtk.Box and Gtk.Window are base classes of a lot of widgets. Avoid + confusion + when trying to create a subclass of them through the GObject + constructor with + positional arguments by at least verifying that their type is + right. Otherwise + you can do things like + + chooser = Gtk.FileChooserWidget(Gtk.FileChooserAction.SELECT_FOLDER) + + which succeeds, but does not have the desired effect (it sets the + "homogenous" + property of the Gtk.Box superclass instead). + + https://bugzilla.gnome.org/show_bug.cgi?id=711487 + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides_gtk.py | 18 ++++++++++++++++++ + tests/test_properties.py | 9 +++++++++ + 3 files changed, 34 insertions(+) + +commit 79aea2655db11bc9d2c0ad75c87862b2b66da594 +Author: Simon Feltman +Date: Mon Nov 4 03:29:57 2013 -0800 + + Remove overzealous argument checking for callback userdata + + Remove check which ensures userdata is None if the callback is None. + This check would need to become more complicated with recent + versions of + PyGObject where userdata can be variable (would also need to check + against + a tuple containing None). Instead of adding more complex checking, + simply + remove the checking as it is unnecessary to begin with. + + https://bugzilla.gnome.org/show_bug.cgi?id=711173 + + gi/pygi-marshal-from-py.c | 7 ------- + tests/test_overrides_gtk.py | 11 +++++++---- + 2 files changed, 7 insertions(+), 11 deletions(-) + +commit f32d649b72f865e32cc2b62a54d927b8345da0c8 +Author: Martin Pitt +Date: Mon Oct 28 16:00:57 2013 +0100 + + configure.ac: post-release bump to 3.11.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5bcdb56433d0ba2976f05946c6c5b6ffe3e84901 +Author: Martin Pitt +Date: Mon Oct 28 15:59:51 2013 +0100 + + release 3.11.1 + + NEWS | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +commit 65b8f7bd77474e361c80905ec23de6dbde27970c +Author: Simon Feltman +Date: Sun Oct 27 22:09:27 2013 -0700 + + Fix toggleref safety problems by always enabling the GIL + + Call PyEval_InitThreads for the base gi module import. This forces the + Python internals create the GIL and always support threading with the + various thread state enter/exit funcs. This is needed since we cannot + predict which GI repositories might accept Python callbacks and run + them in + non-Python threads or trigger toggle ref notifications in a thread + other + than main. + + https://bugzilla.gnome.org/show_bug.cgi?id=709223 + + gi/__init__.py | 2 -- + gi/gimodule.c | 18 +++++++----------- + gi/overrides/GLib.py | 8 ++------ + 3 files changed, 9 insertions(+), 19 deletions(-) + +commit 57195c9c864bc25521bb3cb98286e6d6f0645652 +Author: Simon Feltman +Date: Sun Oct 27 16:02:13 2013 -0700 + + Add consistent GLib.MainLoop SIGINT cleanup + + Remove auto cleanup of SIGINT source handling by returning True + from the + signal callback. This gives the __del__ method consistent cleanup + semantics + regardless of whether or not a SIGINT occurred. + + https://bugzilla.gnome.org/show_bug.cgi?id=710978 + + gi/overrides/GLib.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 1c03ebba9598e7b6d5293889f46b015bfac3611c +Author: Simon Feltman +Date: Sun Oct 27 15:16:09 2013 -0700 + + tests: Fix source testing to handle critical with non-existing sources + + Silence new critical coming from g_source_remove on non-existing + sources. + This function still returns False, but we need to silence the new + critical + so the test suite doesn't fail. See bug 710724. + + https://bugzilla.gnome.org/show_bug.cgi?id=710978 + + tests/test_source.py | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +commit ac776da7e56b78a2fa422487f0ef0d8771bcb78f +Author: Simon Feltman +Date: Sun Jul 28 00:01:35 2013 -0700 + + docs: Add a keyword value of None for allow-none annotations + + Update documentation generator for allow-none arguments and + user_data arguments to show a keyword value of None. + Add skip for GDestroyNotify closure arguments. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/docstring.py | 20 +++++++++++++++++--- + tests/test_docstring.py | 10 ++++++++++ + 2 files changed, 27 insertions(+), 3 deletions(-) + +commit e1bf9c069644ea0bff0c6a7efa72a285e122a414 +Author: Simon Feltman +Date: Sat Oct 19 19:03:12 2013 -0700 + + Remove overrides for supporting pre-3.10 GObject signal functions + + Remove GObject override code for supporting pre-3.10 signal functions + which + annotate the object argument as "gpointer". With PyGObject 3.11 + having a + dependency on GObject 3.10, clear the special case overrides out. + + gi/overrides/GObject.py | 76 + ++++++------------------------------------------- + 1 file changed, 9 insertions(+), 67 deletions(-) + +commit 0c308de528c402f67808b13760ca30d55d4c99d7 +Author: Simon Feltman +Date: Fri Oct 18 17:15:06 2013 -0700 + + Add threads_init back as a requirement for non-Python threaded repos + + Re-add a "threads_init" function to gi for explicit intialization + of Python + threading support. This was marked as deprecated in the previous cycle + because using Python threads already initializes everything. + However, we still need an explicit initalization when using + repositories + with non-Python threads which may interact with Python callbacks + (GStreamer). + + https://bugzilla.gnome.org/show_bug.cgi?id=710447 + + gi/__init__.py | 2 ++ + gi/gimodule.c | 10 ++++++++++ + gi/overrides/GLib.py | 11 +++++++---- + 3 files changed, 19 insertions(+), 4 deletions(-) + +commit a2fa531b4dee73c193cac92fa3e870808688b5d7 +Author: Simon Feltman +Date: Mon Oct 14 20:38:13 2013 -0700 + + Add dir method to GObject props accessor + + Remove special case __members__ attribute from the props accessor + objects getattr method. This has been deprecated since Python 2.3 and + removed in Python 3. Replace this with a __dir__ method making use + of the + old members list building code. Additionally fix error where the + GObjectClass was being unref'd too many times when using + dir(Object.props), + causing a GLib critical. + + https://bugzilla.gnome.org/show_bug.cgi?id=705754 + + gi/_gobject/pygobject.c | 29 +++++++++++++++++++++-------- + tests/test_gi.py | 14 ++++++++++++++ + 2 files changed, 35 insertions(+), 8 deletions(-) + +commit 799989ada2f6b1d729f078f204445651c808a2c7 +Author: Simon Feltman +Date: Fri May 3 04:37:13 2013 -0700 + + Remove PyGObjectWeakRef now that g_binding_unbind exists + + Remove the static code for managing GBinding weak references now + that GLib + has a method (unbind) for clearing out bindings. + + https://bugzilla.gnome.org/show_bug.cgi?id=699571 + + gi/_gobject/pygobject.c | 59 + +------------------------------------------------ + gi/overrides/GObject.py | 19 ++++++++++++++++ + tests/test_gobject.py | 41 ++++++++++++++++++++-------------- + 3 files changed, 44 insertions(+), 75 deletions(-) + +commit fe217e0afbd63f05285e59628533f351896377d9 +Author: Simon Feltman +Date: Wed Oct 9 00:34:37 2013 -0700 + + Fix GArray, GList, GSList, and GHashTable marshaling leaks + + Remove calling of cleanup code for transfer-everything modes by + ensuring + cleanup_data is set to NULL in from_py marshalers. Use array and hash + table ref/unref functions for container transfer mode to ensure we + have a + valid container ref after invoke and during from_py cleanup of + contents. + Rework restrictions with to_py marshaling cleanup so we always + unref the + container for transfer-everything and transfer-container modes. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-marshal-cleanup.c | 54 +++++++++++---------------------- + gi/pygi-marshal-from-py.c | 77 + ++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 84 insertions(+), 47 deletions(-) + +commit 7407367f424595c2780a2d6a47d936ad0bd91735 +Author: Simon Feltman +Date: Mon Oct 7 14:11:39 2013 -0700 + + Add cleanup_data argument used for Python to C marshaler cleanup + + Add a new output argument to all from_py marshalers which is used for + keeping track of marshaling data that later needs cleanup. Previously + most + marshalers would rely on the GIArgument->v_pointer as the means + for data + cleanup. However, this pointer would get clobbered in the case of + bi-directional arguments (inout) and the memory lost. + Use the new cleanup_data for storing temporarily wrapped C arrays + so we + don't need to re-calculate the length argument during cleanup. + + Additionally delay the from_py marshaling cleanup function until after + _invoke_marshal_out_args is called. This gives inout arguments + which don't + modify the pointer sufficient time to exist until they marshaled + back to + Python (gi_marshalling_tests_gvalue_inout). + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-argument.c | 4 +- + gi/pygi-cache.h | 3 +- + gi/pygi-invoke-state-struct.h | 7 +- + gi/pygi-invoke.c | 20 +++--- + gi/pygi-marshal-cleanup.c | 43 +++++------- + gi/pygi-marshal-from-py.c | 160 + ++++++++++++++++++++++++++++-------------- + gi/pygi-marshal-from-py.h | 45 ++++++++---- + 7 files changed, 177 insertions(+), 105 deletions(-) + +commit 9456e83233a927f1f01c6ffcb1f07c62b491a1df +Author: Simon Feltman +Date: Wed Aug 7 12:08:15 2013 -0700 + + Add support for variable user data arguments + + Support a variable number of user data arguments for all callback + connection function where the user data is the last explicit argument. + This adds convience as well as consistency with the rest of PyGObject. + Cleanup overrides for GLib.idle_add, timeout_add, timeout_add_seconds, + io_add_watch, and child_watch_add which manually implemented this + feature. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/overrides/GLib.py | 75 + +++++++++++++++-------------------------------- + gi/pygi-cache.c | 14 +++++++++ + gi/pygi-cache.h | 3 ++ + gi/pygi-closure.c | 37 +++++++++++++++-------- + gi/pygi-invoke.c | 71 + +++++++++++++++++++++++++++++++------------- + gi/pygi-marshal-from-py.c | 5 ++++ + tests/test_everything.py | 32 ++++++++++++++++++++ + tests/test_glib.py | 21 +++++++++++++ + tests/test_subprocess.py | 8 ++--- + 9 files changed, 177 insertions(+), 89 deletions(-) + +commit ba4a0a65bf9ec44c3b9449f63d63035bff75d8df +Author: Martin Pitt +Date: Mon Oct 14 12:57:04 2013 +0200 + + Bump glib and g-i dependencies to latest stable. + + glib 2.38 and g-i 1.38 are from stable GNOME 3.10 which we now + assume as + minimal version. + + Drop @unittest.skipUnless tags from tests which didn't work with + g-i 1.36. + + README | 3 ++- + configure.ac | 6 +++--- + tests/test_gi.py | 2 -- + 3 files changed, 5 insertions(+), 6 deletions(-) + +commit 2a5ad2af6bc91b187a2f07fc8d001ec7ad618adf +Author: Nuno Araujo +Date: Fri Oct 11 18:41:48 2013 +0200 + + Fix TypeError when setting drag target_list to None + + When calling Widget.drag_dest_set_target_list(None) or + Widget.drag_source_set_target_list(None) + a "TypeError: 'NoneType' object is not iterable" is thrown. + + According to Gtk documentation [1] [2], this shouldn't be the case + since client code should be + able to pass NULL in calls made to gtk_drag_dest_set_target_list and + gtk_drag_source_set_target_list. + + We now check if the target_list is None and do not try to create a + TargetList if it is the case. + + [1] + https://developer.gnome.org/gtk3/3.10/gtk3-Drag-and-Drop.html#gtk-drag-dest-set-target-list + [2] + https://developer.gnome.org/gtk3/3.10/gtk3-Drag-and-Drop.html#gtk-drag-source-set-target-list + + https://bugzilla.gnome.org/show_bug.cgi?id=709926 + + gi/overrides/Gtk.py | 4 ++-- + tests/test_overrides_gtk.py | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +commit 27e9f6ede021fc58e952491b67d69c2a5cdd6acb +Author: Simon Feltman +Date: Tue Oct 1 17:09:39 2013 -0700 + + Use qdata for wrapper retrieval in toggle reference notifications + + Replace usage of user data holding PyGObject wrappers in toggle ref + notifications with GObject qdata retrieval. This fixes thread + safety issues + where a toggle notify may be called from another thread during + the PyGObject + wrappers dealloc. In this case the toggle notify is blocked because + the GIL + is held in dealloc, and when it continues, the user data would be + holding an + invalid PyGObject wrapper. Using qdata solves this by ensuring + the wrapper + retrieval is done within the safety of the GIL and may turn up + as NULL. + + https://bugzilla.gnome.org/show_bug.cgi?id=709223 + + gi/_gobject/pygobject.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +commit 55d925d5f0fb87464b1f391c325c1e70da10d33d +Author: Simon Feltman +Date: Thu Oct 10 16:10:16 2013 -0700 + + Add expected failure to deal with fixes in gimarshallingtests.c + + Fix test_object_full_inout based on newer gimarshallingtests.c > + 1.38.0. + Add expectedFailure to deal with previous versions of + gimarshallingtests.c. + + https://bugzilla.gnome.org/show_bug.cgi?id=709796 + + tests/test_gi.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit d866d422cc39b229f443dd08a3ea50cb3f7df8e6 +Author: Simon Feltman +Date: Mon Oct 7 01:17:08 2013 -0700 + + Fix memory leaks for inout array arguments + + Add tracking for array allocations to from_py marashalers in the + argument states extra data (arg_data). This is then used later + for inout + marshaling cleanup to call the array cleanup function. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-invoke.c | 1 + + gi/pygi-marshal-cleanup.c | 1 + + gi/pygi-marshal-from-py.c | 13 +++++++++---- + 3 files changed, 11 insertions(+), 4 deletions(-) + +commit 31263ac117027446c8e2fd1b56d7e348384aabef +Author: Simon Feltman +Date: Sun Oct 6 21:54:15 2013 -0700 + + Fix to Python marshaling leaks for arrays holding GVariants + + Add early check for array items holding pointers and simply assign the + pointer to GIArgument.v_pointer prior giving it to the per-item + marshaler. + This simplifies marshaling and fixes leaks regarding arrays of + GVariants by + removing the unneeded g_variant_ref_sink (variants are always + pointers). + Conditionalize the use of g_variant_ref_sink based on transfer mode + in the + per-item marshaler. This fixes a reference leak where we are given + ownership + of the variant (transfer full) but added a new ref anyway. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-marshal-to-py.c | 34 ++++++++++++++++++---------------- + 1 file changed, 18 insertions(+), 16 deletions(-) + +commit c9580ce1156789221aa19b00c7aab404db5431b5 +Author: Simon Feltman +Date: Sun Oct 6 04:26:18 2013 -0700 + + Cleanup per-item array marshaling code for flat arrays + + Add an early per-item check which tests if the item being marshaled + is a + pointer and simply copies the pointer into the array. This takes + care of the + GdkAtom and GVariant special cases because these items are always + reported + as pointers. + Fix error condition cleanup code when an item fails marshaling in + the middle + of an array. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-marshal-from-py.c | 87 + +++++++++++++++++++++-------------------------- + tests/test_gi.py | 32 +++++++++++++++++ + 2 files changed, 71 insertions(+), 48 deletions(-) + +commit 4623caa71c54958ab821db27a9eff2790acb3975 +Author: Simon Feltman +Date: Sat Oct 5 17:00:54 2013 -0700 + + Fix GValue array marshaling leaks and crash fallout + + * Decrement references for results of PySequence_GetItem. There were + a few + places we were not decrementing the Python reference, leaking + the value. + * Add tracking of Python arguments with recursive marshaling + cleanup. This + allows arrays of GValues which have been coerced from Python types + to be + properly free'd (also fixes bug 703662). + * Use g_variant_ref for variant arguments marked as transfer + everything. + This fixes double free's caused by the decrementing of + PySequence_GetItem + results. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-cache.h | 1 + + gi/pygi-invoke.c | 1 + + gi/pygi-marshal-cleanup.c | 50 + +++++++++++++++++++++++++++++++++++++++++------ + gi/pygi-marshal-cleanup.h | 14 +++++++++++++ + gi/pygi-marshal-from-py.c | 20 ++++++++++++++++--- + gi/pygi-marshal-to-py.c | 1 + + 6 files changed, 78 insertions(+), 9 deletions(-) + +commit 549f849ef8854352483657df3d7558688a4b0007 +Author: Simon Feltman +Date: Sat Sep 28 00:26:28 2013 -0700 + + Refactor GLib.io_add_watch to make it more testable + + Break the argument munging code into a separate function which + can be tested in isolation of adding an io watch. + Add additional failing test which specifies all args as keywords + which we eventually need to support for consistency with the + rest of PyGObject. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/overrides/GLib.py | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +commit bc780ed17bc4cc62959c63c3f0142161a924679f +Author: Simon Feltman +Date: Fri Sep 27 20:59:45 2013 -0700 + + Refactor GLib.child_watch_add to make it more testable + + Break the argument munging code into a separate function which + can be tested in isolation of adding a child watch. Update tests + to reflect this. Add additional failing test which specify + all args as keywords which we eventually need to support for + consistency with the rest of PyGObject. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/overrides/GLib.py | 25 +++++++++----- + tests/test_subprocess.py | 88 + +++++++++++++++++++++--------------------------- + 2 files changed, 56 insertions(+), 57 deletions(-) + +commit 73c6213e8b47fa7c4c2c7a517fe7b56126145888 +Author: Simon Feltman +Date: Thu Sep 26 19:05:20 2013 -0700 + + Don't pass None to callbacks when user data is not specified + + For APIs which support a callback and optional user data, + don't pass the user data to the callback if it was not explicitly + specified when the callback was connected. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-closure.c | 17 ++++++++++++++--- + gi/pygi-marshal-from-py.c | 5 ----- + tests/test_everything.py | 7 ++----- + 3 files changed, 16 insertions(+), 13 deletions(-) + +commit a76b06179cdca43f1c7d1feb8e2563e3d884a8ff +Author: Simon Feltman +Date: Fri Oct 4 17:27:47 2013 -0700 + + Add missing methods on PyGIBaseInfo and sub-classes + + Expose all methods of GIBaseBase info and its sub-classes. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/_glib/pyglib-python-compat.h | 1 + + gi/pygi-info.c | 550 + +++++++++++++++++++++++++++++++++++++++- + tests/test_repository.py | 134 ++++++++++ + 3 files changed, 677 insertions(+), 8 deletions(-) + +commit e190eb75093e8bf36190dc1beb18d1c1b95b9582 +Author: Simon Feltman +Date: Fri Oct 4 13:46:36 2013 -0700 + + Expose all GI enum and flags types + + Add new types for GIDirection, GITransfer, GIArrayType, GIScopeType, + GIVFuncInfoFlags, GIFieldInfoFlags, GIFuncitonInfoFlags, GITypeTag, + and + GInfoType. These types are found in the gi._gi module exposed + without the + "GI" prefix and contain all of their values as class attributes. e.g. + gi._gi.Transfer.EVERYTHING. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/docstring.py | 10 ++-- + gi/pygi-info.c | 150 + ++++++++++++++++++++++++++++++++++++++++++++--- + tests/test_repository.py | 13 +++- + 3 files changed, 158 insertions(+), 15 deletions(-) + +commit 0120af6c418d0f67f39c02a4e8327813645b97f4 +Author: Simon Feltman +Date: Fri Oct 4 13:42:34 2013 -0700 + + Avoid calling g_base_info_get_name on GI_INFO_TYPE_TYPE + + Calling g_base_info_get_name on infos tagged with GI_INFO_TYPE_TYPE + will + cause a crash. Avoid this by adding _safe_base_info_get_name and + using that + throughout the bindings. + Logged GI bug as: https://bugzilla.gnome.org/show_bug.cgi?id=709456 + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 35 +++++++++++++++++++++++++---------- + 1 file changed, 25 insertions(+), 10 deletions(-) + +commit c86b2fe8d01070f06c45fffd910d890afba1313a +Author: Simon Feltman +Date: Fri Oct 4 13:41:08 2013 -0700 + + Add GIBaseInfo.equal method + + Break PyGIBaseInfo rich compare into two methods: equal and + richcompare. + Equal is a direct exposure of the GI method and richcompare makes + use of + this with additional support for Pyton "==" and "!=" operators. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 32 ++++++++++++++++++++++++-------- + tests/test_repository.py | 1 + + 2 files changed, 25 insertions(+), 8 deletions(-) + +commit e7b758badd0ab0b147117859f7871c39fb5399c1 +Author: Simon Feltman +Date: Fri Oct 4 13:36:11 2013 -0700 + + Move info string retrieval into generic function + + Add get_info_string for sharing binding of simple string retrieval on + GIBaseInfo objects. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +commit d2aef364de778da966bc1cfffe184d649f9ebb21 +Author: Simon Feltman +Date: Tue Sep 24 06:26:17 2013 -0700 + + Move child info retrieval into generic function + + Add a generic function for bindings which return a single child info. + This trivializes binding methods like PyGIObjectInfo.get_parent and + fixes leaks in PyGIObjectInfo.get_class_struct and + PyGIVFuncInfo.get_invoker. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 56 + +++++++++++++++++++++++--------------------------------- + 1 file changed, 23 insertions(+), 33 deletions(-) + +commit cdd03a2b0baef19797a5b55c2880e5b7acf1dd93 +Author: Simon Feltman +Date: Tue Sep 24 02:52:22 2013 -0700 + + Move info tuple retrieval into generic function + + Create new generic function for retrieving a tuple of child infos. + This greatly simplifies all the bindings which return tuples from + a common pattern of functions on GIBaseInfo based instances. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 469 + ++++++++------------------------------------------------- + 1 file changed, 59 insertions(+), 410 deletions(-) + +commit 62f185bef20b42f18290a3cf1d3b19dddc957f8a +Author: Simon Feltman +Date: Sun Oct 6 16:41:37 2013 -0700 + + tests: Update check.valgrind with always-malloc and add logging + options + + Based on notes in https://wiki.gnome.org/Valgrind we need to use + always-malloc for valgrind runs. + Add check.valgrindlog and check.valgrindxml which output valgrind + logs into + an ignored local tmp. Output logs are named -$TEST_NAMES.log + so we + can track commits and use diff tools on the logs. + + .gitignore | 1 + + Makefile.am | 6 ++++++ + tests/Makefile.am | 10 +++++++++- + 3 files changed, 16 insertions(+), 1 deletion(-) + +commit 314c933626c4dc5fc585d0e5b6c45ddb17c2e52f +Author: Simon Feltman +Date: Fri Oct 4 20:43:02 2013 -0700 + + Move existing repository tests into test_repository + + Move flags and enum double registration tests into test_repository.py. + Remove duplicate ObjectInfo tests from test_gi.py. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + tests/test_gi.py | 38 -------------------------------------- + tests/test_repository.py | 28 ++++++++++++++++++++++++++++ + 2 files changed, 28 insertions(+), 38 deletions(-) + +commit 31840888c8948aab78041da93c329572f3aabb64 +Author: Simon Feltman +Date: Fri Oct 4 17:31:21 2013 -0700 + + Add unittests for GIRepository + + Add basic unittests for the existing classes and methods exposed for + the GIRepository module (gi._gi). + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + tests/Makefile.am | 1 + + tests/test_repository.py | 170 + +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 171 insertions(+) + +commit 4408f83be70e92c5e3943f5ce85c551e7f2c87d0 +Author: Simon Feltman +Date: Fri Oct 4 15:50:05 2013 -0700 + + Derive SignalInfo info from CallableInfo + + Change Python class derivation of PyGISignalInfo to use + PyGICallableInfo as + the base class. This accurately reflects the GI class layout and + provides + the callable information for signals. + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit b01daba04ff001b9e63d343938e879d339d9a98c +Author: Simon Feltman +Date: Fri Oct 4 15:48:05 2013 -0700 + + Use PYGLIB_PyLong_FromLong for GIDirection return + + https://bugzilla.gnome.org/show_bug.cgi?id=709008 + + gi/pygi-info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d644cbd0c0ad85142286754838db848c4eb1707f +Author: Simon Feltman +Date: Thu Oct 3 19:25:34 2013 -0700 + + Fix memory leak for caller allocated GValue out arguments + + Swizzle the order of type checks in _cleanup_caller_allocates so + G_TYPE_VALUE arguments are checked before G_TYPE_BOXED. The + ordering is + important because G_TYPE_VALUE is a sub-type of boxed and so its + specialized + cleanup code was never being called (g_value_unset). + Additionally update check to use g_type_is_a instead of a compare + to handle + the potential case of a G_TYPE_VALUE sub-type. + + https://bugzilla.gnome.org/show_bug.cgi?id=709397 + + gi/pygi-marshal-cleanup.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +commit 510789d52e9e2fd863d26613f3282364eb175601 +Author: Simon Feltman +Date: Sun Jul 28 14:44:51 2013 -0700 + + Add support for default arguments annotated with allow-none + + Support default value of NULL for tail end arguments which are + marked with allow-none. + The implementation uses a place holder object for un-supplied + arguments + which are annotated with allow-none. This is then used later during + marshaling to supply NULL as the default. + Additionally support an implicit default for callback user_data + using the same technique. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/gimodule.c | 6 +++ + gi/pygi-cache.c | 103 + ++++++++++++++++++++++++++++++---------------- + gi/pygi-cache.h | 8 ++++ + gi/pygi-invoke.c | 42 +++++++++++++------ + gi/pygi-marshal-from-py.c | 5 +++ + gi/pygi.h | 1 + + tests/test_everything.py | 16 +++++++ + tests/test_gi.py | 30 ++++++++++++++ + 8 files changed, 162 insertions(+), 49 deletions(-) + +commit 03f531ffb1adde0c48e98f92bd92f79416654fbe +Author: Simon Feltman +Date: Fri Aug 2 22:27:10 2013 -0700 + + cache refactoring: Move arg cache field assignments into + _arg_cache_new + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +commit cb7e7311bff57eb4c79c7772b6db4d00084656bb +Author: Simon Feltman +Date: Fri Aug 2 20:27:02 2013 -0700 + + cache refactoring: Cleanup array length argument marshaling + + Add shared function: _arg_cache_array_len_arg_setup for use + with both to and from array marshaling setup. This function + consolidates all of the edge cases regarding array length setup + and removes the need for flagging arguments with + PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 145 + +++++++++++++++++++++++++++----------------------------- + gi/pygi-cache.h | 5 -- + 2 files changed, 71 insertions(+), 79 deletions(-) + +commit c9d8639401ae82977e960de44d80b94a501a2184 +Author: Simon Feltman +Date: Sat Aug 3 00:26:11 2013 -0700 + + cache refactoring: Move variable declarations to blocks where they + are used + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +commit dbc2cf5f1fa0f9cc046170efa6afb086b90253cb +Author: Simon Feltman +Date: Thu Aug 1 19:33:27 2013 -0700 + + cache refactoring: Remove continue statements from + _args_cache_generate + + Remove continue and goto statements from the large loop within + _args_cache_generate. This simplifies the sharing of parts of + the loop for future refactoring. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 126 + +++++++++++++++++++++++++++----------------------------- + 1 file changed, 61 insertions(+), 65 deletions(-) + +commit 87ae14b8b4a0ed9beb22f48314247e988a2e017f +Author: Simon Feltman +Date: Wed Jul 31 18:10:05 2013 -0700 + + cache refactoring: Use bit field for PyGIDirection instead of enum + + This supports cleaner logic when testing the direction of + arguments due to the majority of these tests being along the + lines of: (direction == FROM_PYTHON || direction == BIDIRECTIONAL) + Which is replaced with: (direction & FROM_PYTHON) + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 64 + ++++++++++++++++++++++++++++----------------------------- + gi/pygi-cache.h | 6 +++--- + 2 files changed, 35 insertions(+), 35 deletions(-) + +commit d5925b76afa3a429092cbafd82aed40bb0cf0b18 +Author: Simon Feltman +Date: Sun Jul 28 20:45:05 2013 -0700 + + cache refactoring: Remove special case marshaling for instance + arguments + + Remove duplicate code for marshaling struct and objects for + instance arguments. Re-use individual cache marshalers for + structs and objects with the instance argument. This required + removal of passing GITypeInfo to the marshaler because it is + not available for instance arguments. Instead always assume + "is_pointer" for the instance argument by using the cache. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-argument.c | 4 +-- + gi/pygi-cache.c | 16 ++++----- + gi/pygi-marshal-from-py.c | 87 + +++-------------------------------------------- + gi/pygi-marshal-from-py.h | 16 ++------- + 4 files changed, 16 insertions(+), 107 deletions(-) + +commit c19bed69c669160737e12d92cc29f3e6d1b008cc +Author: Simon Feltman +Date: Sun Jul 28 16:44:01 2013 -0700 + + cache refactoring: Use GPtrArray for callable arg cache + + Replace manual management of the C array holding individual + argument caches with usage of GPtrArray. This provides storage + of the array length along with item memory management. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 62 + +++++++++++++++++++++++------------------------ + gi/pygi-cache.h | 16 +++++++++--- + gi/pygi-invoke.c | 16 ++++++------ + gi/pygi-marshal-cleanup.c | 8 +++--- + gi/pygi-marshal-from-py.c | 6 ++--- + gi/pygi-marshal-to-py.c | 6 ++--- + 6 files changed, 62 insertions(+), 52 deletions(-) + +commit 52ea3afb0a6494423eca36a54af928d4ae5d9954 +Author: Simon Feltman +Date: Sun Jul 28 15:02:51 2013 -0700 + + cache refactoring: Move PyGI direction code into new function + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.c | 42 +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +commit 83208bf495b152e93a28a231d445f43ea827d2eb +Author: Simon Feltman +Date: Fri Aug 2 15:59:25 2013 -0700 + + cache refactoring: Add comments to callable cache structure + + Add comments to count fields on _PyGICallableCache. + + https://bugzilla.gnome.org/show_bug.cgi?id=640812 + + gi/pygi-cache.h | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +commit 0a8d5695972601eaa9f7f463bac173d02b0380a0 +Author: Simon Feltman +Date: Wed Jul 24 01:14:29 2013 -0700 + + Remove support for allowing PyObjects as void pointers + + Final removal of marshaling Python object addresses as + void pointers. This ensures we can successfully pass + integer values as the pointer without the Python object + leaking or crashing due to invalid memory. + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/pygi-marshal-from-py.c | 20 ++++++-------------- + gi/pygi-marshal-to-py.c | 14 ++------------ + tests/test_signal.py | 5 +---- + 3 files changed, 9 insertions(+), 30 deletions(-) + +commit 1469403ee2faa699430055384b338f0cd8e672d7 +Author: Simon Feltman +Date: Wed Sep 25 18:21:22 2013 -0700 + + configure.ac: bump trunk to 3.11.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8e774e61d62c82efa3d907c1201359121878b4b5 +Author: Simon Feltman +Date: Mon Sep 23 03:57:03 2013 -0700 + + configure.ac: post-release bump to 3.10.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 95af6279a9affff5c816db2db53207ff0f19872d +Author: Simon Feltman +Date: Mon Sep 23 03:17:19 2013 -0700 + + release 3.10.0 + + NEWS | 3 +++ + configure.ac | 4 ++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit c626be6317b610277c95461108573d1ae6f42b6d +Author: Martin Pitt +Date: Mon Sep 23 12:06:11 2013 +0200 + + Fix test_gi.TestProjectVersion.test_version_str() + + In this test case we only do a string comparison, not a proper + "by version + component" numerical one. So relax the test to also work with 3.10. + + tests/test_gi.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0a30f8d02099e582ea3ded800303e14d2e7ab212 +Author: Martin Pitt +Date: Mon Sep 16 10:12:33 2013 -0500 + + release 3.9.92 + + NEWS | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 506f1e35a9375be80a6a79421bf8272165fdd90a +Author: Simon Feltman +Date: Mon Sep 16 01:23:49 2013 -0700 + + Update current maintainers list in README + + README | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit ef120498e060e88a1efcb82de385a23c1fa9c7da +Author: Simon Feltman +Date: Tue Sep 10 17:11:21 2013 -0700 + + Fix union argument regression when marshaling from python + + Check for union members when marshaling boxed types from Python. + This is a regression caused by stricter type checking added when + merging code from pygi-argument.c. + Re-add pyg_boxed_check to the same bit of code in addition to + __gtype__ checking to avoid a double regression. + + https://bugzilla.gnome.org/show_bug.cgi?id=703873 + + gi/pygi-marshal-from-py.c | 53 + ++++++++++++++++++++++++++--------------------- + 1 file changed, 29 insertions(+), 24 deletions(-) + +commit 59a2964141e963d2961e55d4b84a777927b4f21b +Author: Simon Feltman +Date: Wed Sep 11 05:05:33 2013 -0700 + + Fix GLib.Source sub-classing with initializer args + + Add variable args and keyword args to the GLib.Source.__new__ + method to support sub-classes which want to implement __init__. + + https://bugzilla.gnome.org/show_bug.cgi?id=707904 + + gi/overrides/GLib.py | 2 +- + tests/test_source.py | 11 +++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +commit afa42ab95327da1de0cf86005974cd8ab0d46872 +Author: Vratislav Podzimek +Date: Wed Sep 4 14:17:31 2013 +0200 + + Copy __doc__ when wrapping function + + Signed-off-by: Vratislav Podzimek + Signed-off-by: Martin Pitt + + gi/overrides/__init__.py | 1 + + 1 file changed, 1 insertion(+) + +commit 7914a6828a533d8c579a5b422351e18b9f9afc8c +Author: Martin Pitt +Date: Mon Sep 2 14:56:24 2013 +0200 + + configure.ac: post-release bump to 3.9.92 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ad8b7d1a89eb2d030a504d521f7589a4c1d835fb +Author: Martin Pitt +Date: Mon Sep 2 14:38:41 2013 +0200 + + release 3.9.91 + + NEWS | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 9df8eb79929025f12d51bc7f79b1d160156c2755 +Author: Simon Feltman +Date: Mon Sep 2 04:19:35 2013 -0700 + + Fix GObject signal methods to work with new annotations + + Add conditional support for signal methods annotated as gpointer + or GObject.Object. This is needed to work with newer versions of + glib which changed annotations to GObject.Object (bug #685387). + + https://bugzilla.gnome.org/show_bug.cgi?id=707280 + + gi/overrides/GObject.py | 106 + ++++++++++++++++++++++++++++++------------------ + 1 file changed, 66 insertions(+), 40 deletions(-) + +commit 9b6b6c7ee6a621cba99f51857eadd622a1535118 +Author: Chun-wei Fan +Date: Thu Aug 15 14:41:40 2013 +0800 + + Fix build on C89 Compilers + + Avoid a variable declaration at the middle of the block + + https://bugzilla.gnome.org/show_bug.cgi?id=707264 + + gi/pygi-closure.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 19c1a2dfb91a83a6fb0ca76b9c95c42a49a3736e +Author: Simon Feltman +Date: Sun Sep 1 20:44:26 2013 -0700 + + Change boxed type checking in marshaling to use __gtype__ attribute + + Replace usage of pyg_boxed_check(pyboxed) with g_type_is_a and + pyg_type_from_object. This has the effect of using the __gtype__ + attribute stashed on object class instead of the PyGBoxed + internally held gtype. This fixes type descrepencies for objects + marshaled into overridden signal class closures and passed back + to functions taking an alias their type. + + https://bugzilla.gnome.org/show_bug.cgi?id=707140 + + gi/pygi-marshal-from-py.c | 8 +++++++- + tests/test_overrides_gtk.py | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+), 1 deletion(-) + +commit dab0c09f1996e124ca98334e5aea0852904b44b5 +Author: Simon Feltman +Date: Sun Sep 1 17:49:09 2013 -0700 + + Use G_IS_VALUE for checking return values in closure marshaling + + Replace return_value argument NULL checks in GClosureMarshal + implementations with G_IS_VALUE. This checks both NULL and + validity of the value (!= G_TYPE_INVALID). This is needed + because GLib can pass either NULL or an invalid value based + on whether or not G_ENABLE_DEBUG is set. + See: https://bugzilla.gnome.org/show_bug.cgi?id=707249 + + https://bugzilla.gnome.org/show_bug.cgi?id=707170 + + gi/_gobject/pygtype.c | 4 ++-- + gi/pygi-signal-closure.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit c7b75a8c250078ac8ea28752f087ed687bd20edd +Author: Yanko Kaneti +Date: Wed Aug 21 08:53:07 2013 +0200 + + Fix PEP-8 errors in propertyhelper.py + + https://bugzilla.gnome.org/show_bug.cgi?id=706319 + + Signed-off-by: Martin Pitt + + gi/_gobject/propertyhelper.py | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit 6fdd58404103596accb6ab04d4de33846d853c58 +Author: Martin Pitt +Date: Mon Aug 19 17:13:30 2013 +0200 + + configure.ac: post-release bump to 3.9.91 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6fbe2580deda215896e9583b418b8bc1aceb2f96 +Author: Martin Pitt +Date: Mon Aug 19 17:10:52 2013 +0200 + + release 3.9.90 + + NEWS | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit a8d5da559ef088b05062681206758d2718946269 +Author: Martin Pitt +Date: Mon Aug 19 11:38:31 2013 +0200 + + NEWS: retroactively fix last version number + + NEWS | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit aba45eb2617c4b35168089bc9028f351732a617f +Author: Benjamin Berg +Date: Tue Aug 6 00:41:52 2013 +0200 + + Create GLib.Pid in the same way on python 2 and 3 + + https://bugzilla.gnome.org/show_bug.cgi?id=705451 + + gi/_glib/pygspawn.c | 8 -------- + 1 file changed, 8 deletions(-) + +commit 2d203b7529c95ba4461a5a6d4c6b67169fabc4cf +Author: Benjamin Berg +Date: Mon Aug 5 17:04:15 2013 +0200 + + Use PyLong_Type.tp_new for GLib.Pid + + For GLib.Pid the original implementation for __new__ needs to be used, + as it is able to initialize the integer correctly. + + https://bugzilla.gnome.org/show_bug.cgi?id=705451 + + gi/_glib/pygspawn.c | 1 + + tests/test_subprocess.py | 1 + + 2 files changed, 2 insertions(+) + +commit c32793dafbd52eab87b14ca064b47f5a4fb9000b +Author: Simon Feltman +Date: Mon Aug 5 14:40:38 2013 -0700 + + Add accumulator and accu_data arguments to GObject.Signal decorator + + Update __init__, __call__, and copy methods to accept and pass + accumulators and associated user data through them. Update + accumulator unittests to use Signal decorators for testing accumulator + pass throughs. Verified the __gsignals__ dictionary accepts None + as valid values for accumulator and accu_data so specialization + for these arguments is not necessary. + + https://bugzilla.gnome.org/show_bug.cgi?id=705533 + + gi/_gobject/signalhelper.py | 17 ++++++++++----- + tests/test_signal.py | 52 + ++++++++++++++++++++++++--------------------- + 2 files changed, 40 insertions(+), 29 deletions(-) + +commit 78f72654f5cb6c06e76ed9a532fc1ee328b60e50 +Author: Simon Feltman +Date: Mon Aug 5 14:12:24 2013 -0700 + + Pass return values through the GObject.Signal.emit wrapper + + Return the result of GObject.emit from the Signal decorators wrapping. + Update unittest for decorated return type to use skipUnless for + Python 3. + Add test for Signal decorator return type. + + https://bugzilla.gnome.org/show_bug.cgi?id=705530 + + gi/_gobject/signalhelper.py | 2 +- + tests/test_signal.py | 37 +++++++++++++++++++++---------------- + 2 files changed, 22 insertions(+), 17 deletions(-) + +commit 08cc206afeaefd1ce50ecfd1411807225a11c8f8 +Author: Simon Feltman +Date: Mon Jul 29 03:33:40 2013 -0700 + + configure.ac: post-release bump to 3.9.90 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2d8f5490cdc078b3e56a92deb9eca71b3fc5ef17 +Author: Simon Feltman +Date: Mon Jul 29 02:23:02 2013 -0700 + + release 3.9.5 + + NEWS | 41 +++++++++++++++++++++++++++++++++++++++++ + configure.ac | 2 +- + 2 files changed, 42 insertions(+), 1 deletion(-) + +commit ec3de7608ec970f6f272c9d7937344f02c6e9c3d +Author: Simon Feltman +Date: Mon Jul 29 01:21:19 2013 -0700 + + Ensure exceptions set in closure out argument marshaling are printed + + Call PyErr_Print when an exception occurs after marshaling closure + out arguments. These exceptions were being ignored and cleared out + only to show up in debug builds of Python. + + https://bugzilla.gnome.org/show_bug.cgi?id=705064 + + gi/pygi-closure.c | 8 ++++++++ + tests/test_generictreemodel.py | 17 +++++++++++------ + 2 files changed, 19 insertions(+), 6 deletions(-) + +commit b5dcb1800839f747a052e487643c234668384677 +Author: Simon Feltman +Date: Sun Jul 28 23:00:26 2013 -0700 + + Use Python error messages for marshaling integers from Python + + Use Pythons default error messages where possible. + Change all explicitly raised ValueError to use OverflowError + for out of range data. + + https://bugzilla.gnome.org/show_bug.cgi?id=705057 + + gi/pygi-marshal-from-py.c | 76 + +++++++++++++++++------------------------------ + tests/test_everything.py | 52 ++++++++++++++++---------------- + tests/test_gi.py | 64 +++++++++++++++++++-------------------- + tests/test_gobject.py | 2 +- + 4 files changed, 86 insertions(+), 108 deletions(-) + +commit 3c83bfb14b850670eb7c0208e55c120ca203f8af +Author: Simon Feltman +Date: Sat Jul 27 21:10:07 2013 -0700 + + Use Py_CLEAR for closure cleanup instead of test with Py_DECREF + + gi/pygi-closure.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +commit f5e3876dee512ca82af6ea798b10d5ecad785dd1 +Author: Simon Feltman +Date: Sat Jul 27 15:25:20 2013 -0700 + + Cleanup invoke args and kwargs combiner code + + Change _py_args_combine_and_check_length use cleaner reference + counting. + It no longer DECREFs input arguments and always returns a new value + reference. + Use PyGICallableCache directly as an argument instead of passing + various + members. + + gi/pygi-invoke.c | 44 +++++++++++++++++--------------------------- + 1 file changed, 17 insertions(+), 27 deletions(-) + +commit 91c49822363d8a1efc82163b46daa667d6cfc1b7 +Author: Simon Feltman +Date: Wed Jul 17 16:10:25 2013 -0700 + + Replace Python VFunc descriptor directly with PyGIVFuncInfo + + Add tp_getdesc (__get__) to PyGIVFuncInfo to allow the object + to be used directly as a callable descriptor. This piggy backs + off the added support for functions and constructors in previous + patches. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/pygi-info.c | 25 +++++++++++++++++++++++-- + gi/types.py | 33 ++++----------------------------- + 2 files changed, 27 insertions(+), 31 deletions(-) + +commit 35f79b22ec5abf02fd0bb66352eb1f251b65a078 +Author: Simon Feltman +Date: Tue Jul 16 16:00:14 2013 -0700 + + Add callable and descriptor protocols to PyGICallableInfo + + Add tp_call (__call__) function to callable info objects. + This allows for replacement of wrapped invoke methods directly + with the already created callable info object. This has the + additional side effect of making doc strings lazily bound + (only generated when __doc__ is accessed). + + Add tp_desc_get (__get__) to PyGIFunctionInfo which returns + a bound version of itself for methods and constructors. + + Update various internal type checks to reflect the changes. + Update tests to reflect the new callable type being the same + across Python 2 & 3. + + This patch gives roughly a %17 speedup for Gtk imports and + an %11 speedup for GI method calls. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/module.py | 5 +- + gi/overrides/__init__.py | 10 ++- + gi/pygi-info.c | 179 + ++++++++++++++++++++++++++++++++++++++++++-- + gi/pygi.h | 13 ++++ + gi/types.py | 35 +-------- + tests/test_docstring.py | 6 +- + tests/test_gi.py | 32 +++----- + tests/test_overrides_gtk.py | 4 +- + 8 files changed, 212 insertions(+), 72 deletions(-) + +commit 2339e030e4dc4d93ea770bca380a89f831d56be6 +Author: Simon Feltman +Date: Fri Jul 26 19:33:32 2013 -0700 + + Move "from Python" GObject out arg marshaler into specialized function + + Move hacks specific to out argument marshaling for vfuncs into a + a specialized function. This allows standard function call marshaling + to continue working correctly when there are no extra references + holding the arguments "foo(SomeObject())". This is currently being + masked because all GI functions are wrapped by additional layers + of Python functions. When these layers are removed, it exposes + bugs introduced by reference counting hacks intended for vfunc + return arguments. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/pygi-argument.c | 2 +- + gi/pygi-marshal-from-py.c | 37 ++++++++++++++++++++++++++++++------- + gi/pygi-marshal-from-py.h | 3 +++ + 3 files changed, 34 insertions(+), 8 deletions(-) + +commit 627c5faaa54ed9a2b59ac1547833c171cd1a1e87 +Author: Simon Feltman +Date: Fri Jul 26 17:34:01 2013 -0700 + + Add underscore prefix and _cache_adapter suffix to marshaling + functions + + Add underscores to all _pygi_marshal_* functions. We don't currently + export symbols, but we might need to for C unittesting. This will + ensure we don't have a "public API". + Add _cache_adapter suffix to marshaling functions which are light + weight wrappers intended only for cached marshalers. + + gi/pygi-argument.c | 40 +++++++++++----------- + gi/pygi-cache.c | 10 +++--- + gi/pygi-marshal-from-py.c | 86 + +++++++++++++++++++++++------------------------ + gi/pygi-marshal-from-py.h | 44 ++++++++++++------------ + gi/pygi-marshal-to-py.c | 48 +++++++++++++------------- + gi/pygi-marshal-to-py.h | 34 +++++++++---------- + 6 files changed, 131 insertions(+), 131 deletions(-) + +commit bec0b543be8d993996d8a17c343c3f2f33a9398f +Author: Simon Feltman +Date: Tue Jul 16 11:13:17 2013 -0700 + + Add common attribute accessors to PyGIBaseInfo + + Add __name__, __module__, and __doc__ accessors to + PyGIBaseInfo object. This is a precursory patch for setting + up PyGICallableInfo as a directly callable object with lazy + doc string evaluation. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/_glib/pyglib-python-compat.h | 5 +++ + gi/pygi-info.c | 83 + +++++++++++++++++++++++++++++++++++++++-- + gi/types.py | 7 ++-- + 3 files changed, 88 insertions(+), 7 deletions(-) + +commit ea194404843a16555f9a475cc973872a4428bfe1 +Author: Simon Feltman +Date: Sat Jul 13 23:10:31 2013 -0700 + + Merge method and constructor setup + + Merge _setup_constructors into _setup_methods as they contain same + basic logic. This removes an unnecessary call with additional + filtering of GIObjectInfo.get_methods() which can be large for + objects with many methods. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/types.py | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +commit 6b36fbe904d19f515578f447daa7657d3a9a859c +Author: Simon Feltman +Date: Sat Jul 13 18:11:18 2013 -0700 + + Remove redundant info.get_name calls + + Remove a number of redundant calls to GIBaseInfo.get_name. Info + names are already cached on function objects so re-use them when + possible. This gives a small load time improvement by removing over + 2000 calls when importing Gtk. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/module.py | 1 - + gi/types.py | 8 +++----- + 2 files changed, 3 insertions(+), 6 deletions(-) + +commit 6fdde256e840600c84a648ab21da2fe5c212e5bc +Author: Simon Feltman +Date: Fri Jul 12 12:21:54 2013 -0700 + + Move doc string generator into separate module + + Move the doc string generator for creating function signatures + into "gi.docstring". This includes a new API for getting and + setting the doc string creation functions: + + gi.docstring.get_doc_string_generator + gi.docstring.set_doc_string_generator + gi.docstring.generate_doc_string + + Beyond adding the ability for custom doc string generators, + this API is a necessary step for adding lazy __doc__ + attribute access for optimization. + + https://bugzilla.gnome.org/show_bug.cgi?id=704037 + + gi/Makefile.am | 3 +- + gi/docstring.py | 106 + ++++++++++++++++++++++++++++++++++++++++++++++++ + gi/types.py | 55 ++----------------------- + tests/Makefile.am | 1 + + tests/test_docstring.py | 49 ++++++++++++++++++++++ + tests/test_gi.py | 30 -------------- + 6 files changed, 161 insertions(+), 83 deletions(-) + +commit f86701b15ee04c717d9c6bf688101606165e4f83 +Author: Simon Feltman +Date: Wed Jul 24 19:36:28 2013 -0700 + + tests: Change GHashTable marshaling test to use GValue + + Add test to explicitly use a boxed GStrv GValue in addition to a + Python list sub-class. + + https://bugzilla.gnome.org/show_bug.cgi?id=666636 + + tests/test_everything.py | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +commit 6ea41b60691e1ba7e21374582d7aea072af71103 +Author: Simon Feltman +Date: Thu Jul 25 18:00:47 2013 -0700 + + gtk-demo: Change demo to use Gtk.Application + + Replace deriving from Gtk.Window with deriving from Gtk.Application + connected to a Gtk.ApplicationWindow instance. + + https://bugzilla.gnome.org/show_bug.cgi?id=698547 + + demos/gtk-demo/demos/printing.py | 2 +- + demos/gtk-demo/gtk-demo.py | 40 + ++++++++++++++++++++-------------------- + 2 files changed, 21 insertions(+), 21 deletions(-) + +commit fae58044ea0b2e7f47fbdacc5b58ac36f673ecbd +Author: Simon Feltman +Date: Tue Jul 23 14:25:01 2013 -0700 + + Move _pygi_argument_to_object_basic_type into pygi-marshal-to-py.c + + Move _pygi_argument_to_object_basic_type into pygi-marshal-to-py.c + and rename to _pygi_marshal_to_py_basic_type. + Cleanup and simplify dependant sub-marshalers for unichar, utf8, + and filename types. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 73 +----------------------------- + gi/pygi-argument.h | 4 -- + gi/pygi-cache.c | 4 +- + gi/pygi-marshal-to-py.c | 115 + +++++++++++++++++++++++++++++++++++++----------- + gi/pygi-marshal-to-py.h | 27 +++--------- + 5 files changed, 99 insertions(+), 124 deletions(-) + +commit cba401ac1543c2fdb68fff0dba8f6da7eed23bfa +Author: Simon Feltman +Date: Tue Jul 23 13:06:33 2013 -0700 + + Unify and clean up from Python marshalers for basic types + + Unify and cleanup boolean, float, double, gtype, unichar, utf8, + and filename marshalers. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-cache.c | 101 + ++-------------------------------------------- + gi/pygi-marshal-from-py.c | 86 ++++++++++++--------------------------- + gi/pygi-marshal-from-py.h | 30 -------------- + 3 files changed, 28 insertions(+), 189 deletions(-) + +commit 9e6e01d065bf0acc5b99ae0e8c034d689231bfe1 +Author: Simon Feltman +Date: Tue Jul 23 12:35:06 2013 -0700 + + Unify from Python int64 and uint64 marshalers + + Replaced int64 and uint64 cached marshalers with usage of the + unified basic type marshaler. Replace a large amount of int64 + exception formatting code with usage of %S for Python 3 and + give a more vague message for Python 2. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-cache.c | 36 +-------- + gi/pygi-marshal-from-py.c | 193 + ++++++++++------------------------------------ + gi/pygi-marshal-from-py.h | 10 --- + 3 files changed, 43 insertions(+), 196 deletions(-) + +commit 46653922003c7d1d5d16f5cdb39b3faadf9aff27 +Author: Simon Feltman +Date: Tue Jul 23 11:03:14 2013 -0700 + + Unify from Python int16 and int32 marshalers + + Add PyNumber_Check to unified basic type marshaler. + Add bounds checking to unified int16 and int32 marshalers. + Replaced int16 and int32 cached marshalers with usage of + unified basic type marshaler. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-cache.c | 69 +-------------- + gi/pygi-marshal-from-py.c | 218 + ++++++++++------------------------------------ + gi/pygi-marshal-from-py.h | 20 ----- + 3 files changed, 48 insertions(+), 259 deletions(-) + +commit 4b9c725a615fcf4a5e8d089d275d4586032d0d1f +Author: Simon Feltman +Date: Tue Jul 23 00:27:14 2013 -0700 + + Unify from Python boolean, int8, and uint8 marshalers + + Replaced boolean, int8, and uint8 cached marshalers with usage of + unified basic type marshaler. Add bounds checking to unified int8 + marshalers. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-cache.c | 48 +++------------ + gi/pygi-marshal-from-py.c | 146 + +++++++++++----------------------------------- + gi/pygi-marshal-from-py.h | 20 ++----- + 3 files changed, 45 insertions(+), 169 deletions(-) + +commit f517bfbc134b78a23b754332e59b9bb67bb68e98 +Author: Simon Feltman +Date: Mon Jul 22 23:24:13 2013 -0700 + + Add support for PyBytes with int8 and uint8 from Python marshaler + + This additional type marshaling is necessary for unifying marhalers + due to the same feature being available with cached argument + marshaling. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-marshal-from-py.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit fe9df90531f3dd04c0d13d73ebd4ae7dd396c9b1 +Author: Simon Feltman +Date: Mon Jul 22 23:23:29 2013 -0700 + + Move from Python integer marshaling into separate function + + Add _pygi_marshal_from_py_long for marshaling Python objects + that can convert to a PyLong type. This allows for better + sharing of code amongst marshalers along with unifying + them across Python 2.7 and 3.0. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 3 +- + gi/pygi-marshal-from-py.c | 159 + ++++++++++++++++++++++++---------------------- + 2 files changed, 84 insertions(+), 78 deletions(-) + +commit f7748affae3d6ef0cc2e409f65761fb29c01b038 +Author: Simon Feltman +Date: Mon Jul 22 22:19:26 2013 -0700 + + Move _pygi_argument_from_object_basic_type into pygi-marshal-from-py.c + + Move _pygi_argument_from_object_basic_type into pygi-marshal-from-py.c + and rename to: _pygi_marshal_from_py_basic_type + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 149 + +--------------------------------------------- + gi/pygi-marshal-from-py.c | 147 + +++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-from-py.h | 4 ++ + 3 files changed, 152 insertions(+), 148 deletions(-) + +commit 9c9510eec782f242280af24e86adf3561e4fac72 +Author: Simon Feltman +Date: Fri Jul 19 23:37:35 2013 -0700 + + Move basic type marshaling out of _pygi_argument_from_object + + Move the marshaling of Python objects to GI arguments for basic types + into a new function: _pygi_argument_from_object_basic_type + This is staging work needed before unifying basic type marshaling + of arguments from Python to GI. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 73 + ++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 46 insertions(+), 27 deletions(-) + +commit 0e2441518ef31bd2b4102ba5780c3ded00bec59a +Author: Simon Feltman +Date: Fri Jul 19 20:16:10 2013 -0700 + + Replace to Python cached marshalers with unified basic type marshaler + + Add cached arg marshaler "_pygi_marshal_to_py_basic_type" which + unifies functions, vfuncs, signals, and property marshaling for + "basic types". Remove all the individual cached arg marshalers + for these types. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 104 +++++++++++------------------------ + gi/pygi-argument.h | 4 ++ + gi/pygi-cache.c | 114 +++++++------------------------------- + gi/pygi-marshal-to-py.c | 142 + ++++-------------------------------------------- + gi/pygi-marshal-to-py.h | 48 ++-------------- + 5 files changed, 73 insertions(+), 339 deletions(-) + +commit 663fe5893bbc9f34bf8aa4da3cb6f9186a8233b1 +Author: Simon Feltman +Date: Fri Jul 19 18:00:40 2013 -0700 + + Move to Python basic type marshaling out of _pygi_argument_to_object + + Move the marshaling of GI arguments to Python objects for basic types + into a new function. The required information for this marshaler + is a GITypeTag and GITransfer. Argument marshaling matching these + requirments are now found in: _pygi_argument_to_object_basic_type. + The new marshaler can be used with a generic argument cache marshaler + to unify all of the "basic type" marshaling. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 86 + +++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 63 insertions(+), 23 deletions(-) + +commit dd43a1e19440dbe025451d2e4e07a6074086498d +Author: Simon Feltman +Date: Sat Jul 6 14:16:36 2013 -0700 + + Override GValue.set/get_boxed with static C marshaler + + Override boxed type get/set methods on GValue to use the static C + GValue marshaler. This works around the inability of the introspection + version of these methods to know what the held GValue type is. + With this, all boxed types will now marshal properly with GValues as + their storage. + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/_gobject/gobjectmodule.c | 38 ++++++++++++++++++++++++++++++++++++++ + gi/overrides/GObject.py | 9 +++++++++ + 2 files changed, 47 insertions(+) + +commit 2cff4827e6d15bcad630316a8a4e67968a70bbbf +Author: Simon Feltman +Date: Sat Jul 6 14:10:20 2013 -0700 + + Refactor pyg_value_from_pyobject into two functions + + Break pyg_value_from_pyobject into two functions. One which keeps + Python exceptions queued (pyg_value_from_pyobject_with_error) and + one which clears them (pyg_value_from_pyobject). This allows for + re-use for code which want to keep the errors around + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/_gobject/gobjectmodule.c | 4 ++- + gi/_gobject/pygobject-private.h | 1 + + gi/_gobject/pygobject.h | 2 ++ + gi/_gobject/pygtype.c | 67 + ++++++++++++++++++++++++++++++++--------- + 4 files changed, 59 insertions(+), 15 deletions(-) + +commit 84e91a9da3522d042faca65fd2ada1ccaee60153 +Author: Simon Feltman +Date: Sat Jul 6 20:41:19 2013 -0700 + + Fix indentation for pyg_value_from_pyobject + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/_gobject/pygtype.c | 744 + +++++++++++++++++++++++++------------------------- + 1 file changed, 372 insertions(+), 372 deletions(-) + +commit 6a29d9be14ec33d06816ade67a5ccf5c7a1cf398 +Author: Simon Feltman +Date: Sat Jul 6 13:32:39 2013 -0700 + + Add deprecation warning for marshaling arbitrary objects as pointers + + Add deprecation warning for marshaling arbitrary objects to/from void + pointers with the exception of integers, PyCapsules, and None. + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/pygi-marshal-from-py.c | 17 ++++++++++++++++- + gi/pygi-marshal-to-py.c | 10 ++++++++-- + 2 files changed, 24 insertions(+), 3 deletions(-) + +commit 077aefed8566adcb99d7570f52fe09c74c2098e5 +Author: Simon Feltman +Date: Sat Jul 6 13:34:53 2013 -0700 + + Move PyGIDeprecationWarning to C for shared Python/C usage + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/__init__.py | 19 ++++--------------- + gi/gimodule.c | 18 ++++++++++++++++++ + gi/pygi.h | 2 ++ + 3 files changed, 24 insertions(+), 15 deletions(-) + +commit 90427107af36ea3c624b36967ee181ed13b9828f +Author: Simon Feltman +Date: Thu Jul 18 14:59:55 2013 -0700 + + Replace usage of __import__ with importlib.import_module + + https://bugzilla.gnome.org/show_bug.cgi?id=682320 + + gi/module.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 6391a8e4f03d4010c0d7de79fc83138fd69e0e33 +Author: Mike Gorse +Date: Wed Jul 10 16:44:23 2013 -0500 + + Always unref the GiTypeInfo when generating an argument cache + + We were leaking a GiTypeInfo when handling child arguments. + + https://bugzilla.gnome.org/show_bug.cgi?id=703973 + + gi/pygi-cache.c | 1 + + 1 file changed, 1 insertion(+) + +commit ce0ad7066ebdb7018fdce58dc32bbaa715206a0c +Author: Mike Gorse +Date: Wed Jul 10 12:10:16 2013 -0500 + + Unref interface info when fetching enums or flags + + When calling g_type_info_get_interface, the resulting interface should + be dereferenced by calling g_base_info_unref. + + https://bugzilla.gnome.org/show_bug.cgi?id=703960 + + gi/pygi-marshal-from-py.c | 8 +++++++- + gi/pygi-marshal-to-py.c | 3 +++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +commit a93755ddba9a1761b627583d7b9be63783c2c063 +Author: Daniel Drake +Date: Tue Jul 9 13:03:36 2013 -0600 + + Speed up MRO calculation + + Optimize gi.type.mro() with the following observations and tricks: + + 1. Python prepares all the base classes before trying to calculate the + MRO of the current one (it first needs to populate __bases__, for + example). So we can assume that the base class MRO is already + available + in __mro__ and this will have been previously calculated (by us, + in the + case of gi classes). This avoids repeating a lot of MRO-calculating + work, + and also avoids (re)calculating MROs for inheritance chains + that don't + have any gi classes in them anyway. + + 2. With that simplification in place, we can avoid recursion, which + is not + all that great in Python... + + 3. ...except in the uncommon case of a Python2 old-style classes, + where + __mro__ is not available. There doesn't seem to be any existing + function to calculate or read MRO of old-style python classes, + so just + keep doing as before: calculate the C3 MRO of the old-style + class via + recursion. That behaviour is not really correct, and the + recursion is + not desirable, so we print a warning here. + + This makes the "hello world" Sugar app start up approximately + 0.5 seconds + faster on XO-1.5. + + https://bugzilla.gnome.org/show_bug.cgi?id=703829 + + gi/types.py | 30 +++++++++++++++++++++++++++--- + tests/test_gi.py | 16 ++++++++++++---- + 2 files changed, 39 insertions(+), 7 deletions(-) + +commit 7aca95781fc76f3e820e63325ccc07d128a60075 +Author: Daniel Drake +Date: Wed Jul 10 10:45:47 2013 -0600 + + tests: Add tests for MRO override + + Add tests for the MRO override to prevent against unintended + behaviour changes. + + https://bugzilla.gnome.org/show_bug.cgi?id=703829 + + tests/test_gi.py | 66 + ++++++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 50 insertions(+), 16 deletions(-) + +commit a15333a36e31b76ea6b80251553840269ec5deb1 +Author: Simon Feltman +Date: Sat Jul 6 13:34:13 2013 -0700 + + Add GIL safety to pyobject_copy for copying boxed PyObjects + + https://bugzilla.gnome.org/show_bug.cgi?id=688081 + + gi/_gobject/pygobject.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit 097c116d43a21bebf8e4bccde9cacc551db1e1e5 +Author: Simon Feltman +Date: Sat Jul 6 09:48:35 2013 -0700 + + testhelper: Fix import requirement for GObject + + Replace the importing of gi._gobject._gobject with + gi.repository.GObject + in tests/testhelpermodule.c + + The testhelper module was only importing the static bindings + (gi._gobject._gobject) and not the overrides (gi.repository.GObject). + This was causing some tests to fail when test_thread was the first + test to run in the suite due to it registering new types based on + PyGObject_Type. + + https://bugzilla.gnome.org/show_bug.cgi?id=703647 + + tests/testhelpermodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0f6c571755e65b5e77d3d84e4516ef90d8ce0162 +Author: Simon Feltman +Date: Wed Jul 3 05:26:12 2013 -0700 + + Add marshalling of GI_TYPE_TAG_VOID held in a GValue to int + + Replace assertion for this case with a simple marshalling of the + pointer value to a Python int. While not particularly useful + this allows some callbacks in WebKit to function without causing + a segfault. + + https://bugzilla.gnome.org/show_bug.cgi?id=694233 + + gi/pygi-argument.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit e0084e7e73845fa2a2da29017d3622f361f11dfb +Author: Cole Robinson +Date: Sat Feb 16 17:26:43 2013 -0500 + + GTK overrides: Make connect_signals handle tuple + + This is used for passing extra arguments to callbacks during + signal emission in the form of: + builder.connect_signals({'on_clicked': (on_clicked, arg1, arg2)}) + + Co-Authored-By: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=693994 + + gi/overrides/Gtk.py | 51 ++++++++---- + tests/test_overrides_gtk.py | 196 + +++++++++++++++++++++++++++++--------------- + 2 files changed, 165 insertions(+), 82 deletions(-) + +commit 466567373289e6f141709f08efa80ba588d3d64a +Author: Simon Feltman +Date: Tue Jul 2 18:06:01 2013 -0700 + + Re-add support for passing GValue's by reference + + Fix special casing when marshaling from a Python held GValue + to a GValue argument intended for a function call. + The re-factoring of GValue marshaling in commit #9e47afe459df942d9f + broke this by always making a copy of the GValue. This removed the + ability to retrieve values with functions like + gtk_style_context_get_style_property. + + https://bugzilla.gnome.org/show_bug.cgi?id=701058 + + gi/pygi-argument.c | 2 +- + gi/pygi-marshal-from-py.c | 32 +++++++++++++++----------------- + 2 files changed, 16 insertions(+), 18 deletions(-) + +commit 40a3cd18fd7111ae177f6ab716f78d131f59a1c0 +Author: Simon Feltman +Date: Tue Jul 2 19:20:04 2013 -0700 + + tests: Add test for pass-by-reference GValue + + https://bugzilla.gnome.org/show_bug.cgi?id=701058 + + tests/test_gi.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 3b3251593ea107f06b160234b0ca5393cb39ac1b +Author: Simon Feltman +Date: Tue Jul 2 23:02:17 2013 -0700 + + Clear return value of closures to zero when an exception occures + + For return types other than void, set the ffi closure return argument + to 0 when a Python exception occures. This a good default in general + but also has the side affect of fixing failing idle callbacks + by causing them to be removed from main loops (after their stack + is printed). + + https://bugzilla.gnome.org/show_bug.cgi?id=702552 + + gi/pygi-closure.c | 14 ++++++++++++++ + tests/test_gi.py | 8 ++++++++ + 2 files changed, 22 insertions(+) + +commit ae3439f1d22482d6a920a869d3d17e7054af6f80 +Author: Martin Pitt +Date: Wed Jul 3 10:40:28 2013 +0200 + + Don't use doctest syntax in docstrings for examples + + These are not actual doctests, so don't use the >>> syntax there. Just + indent + them. + + This fixes pyflakes 0.7 failures. + + https://bugzilla.gnome.org/show_bug.cgi?id=701009 + + gi/_gobject/propertyhelper.py | 11 +++++------ + gi/overrides/GObject.py | 8 ++++---- + gi/overrides/Gtk.py | 2 +- + 3 files changed, 10 insertions(+), 11 deletions(-) + +commit b96a6dc968566d339a2dfd7dd631ae52d812302a +Author: Garrett Regier +Date: Tue Jul 2 06:07:15 2013 -0700 + + Add support for properties of type GInterface + + Add support for G_TYPE_INTERFACE/GInterface to switch + statement which handles G_TYPE_OBJECT based properties. + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=703456 + + gi/_gobject/gobjectmodule.c | 1 + + gi/_gobject/propertyhelper.py | 3 ++- + tests/test_properties.py | 16 ++++++++++++++++ + 3 files changed, 19 insertions(+), 1 deletion(-) + +commit 61b268e44af63d6d78feae42578bf75aa5cfd511 +Author: Martin Pitt +Date: Fri Jun 21 07:27:48 2013 +0200 + + pygtkcompat: Fix for missing methods on Windows + + Deal with non-existing Gtk.Clipboard.get() and + GdkPixbuf.Pixbuf.new_from_file_at_scale() methods. + + https://bugzilla.gnome.org/show_bug.cgi?id=702787 + + pygtkcompat/pygtkcompat.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit 5e3ab0bb974cc785659666b871d795730b4f06b3 +Author: Chun-wei Fan +Date: Fri Jun 21 12:32:33 2013 +0800 + + gi/pygi-info.c: Avoid C99-style variable declaration + + https://bugzilla.gnome.org/show_bug.cgi?id=702786 + + gi/pygi-info.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 94167e12c118c85cd3172f9f5824fe53e55bcc2d +Author: Martin Pitt +Date: Wed May 29 11:20:35 2013 +0200 + + GLib overrides: fix typo in deprecation message + + Spotted by Dmitrijs Ledkovs, thanks! + + gi/overrides/GLib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 86569b69ade0fe157fa87365e9369dde84cd5c90 +Author: Martin Pitt +Date: Tue May 28 17:57:20 2013 +0200 + + configure.ac: post-release version bump to 3.9.3 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 10f703189ed6a7104252907d1b1a114f26d79559 +Author: Martin Pitt +Date: Tue May 28 17:56:07 2013 +0200 + + release 3.9.2 + + NEWS | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit af8d048442b924c72a1d0ae868ee63ccf292759d +Author: Martin Pitt +Date: Fri May 24 13:03:07 2013 +0200 + + examples/option.py: Port to GI and Python 3 + + examples/option.py | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +commit bef5939ca77f4d6939cd9229bd124dfe825b3bdb +Author: Simon Feltman +Date: Sun May 12 18:58:06 2013 -0700 + + Fix vfunc info search for classes with multiple inheritance + + Ensure the search for vfunc GI info continues recursively even if the + current class being looked at does not contain GI info of type + InterfaceInfo. This more exhaustive search is needed for setups with + multiple sub-classes and multiple inheritance. + + https://bugzilla.gnome.org/show_bug.cgi?id=700092 + + gi/types.py | 12 +++++++----- + tests/test_gi.py | 1 - + 2 files changed, 7 insertions(+), 6 deletions(-) + +commit 5b8dff59baa1a3e524dac7877dd5b33dea52b026 +Author: Simon Feltman +Date: Sun May 12 22:19:38 2013 -0700 + + Fix closure argument conversion for enum and flag in args + + Replace incorrect cast and assignment of double with uint for flags + and enums. + + gi/pygi-closure.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 065503d5e284dc89bacd79d0d9a72eb739882bf8 +Author: Simon Feltman +Date: Sat May 11 21:47:54 2013 -0700 + + tests: Add tests for overriding vfunc implementations + + Add tests for overriding vfuncs for both single inheritance + and multiple inheritance with an interface (currently failing). + + https://bugzilla.gnome.org/show_bug.cgi?id=700092 + + tests/test_gi.py | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +commit c4e1112840004af264b4f2a052f333ea38f95cb6 +Author: Simon Feltman +Date: Sat May 11 20:28:22 2013 -0700 + + Fix marshaling Python to FFI return value for enum and flags + + Add break to GI_TYPE_TAG_INTERFACE case. This was falling through + causing + assignment of arg.v_pointer to the ffi return arg. + + gi/pygi-closure.c | 1 + + 1 file changed, 1 insertion(+) + +commit a703217eaf4075e9720d4247351e1dfc4f553772 +Author: Simon Feltman +Date: Fri Apr 19 06:37:24 2013 -0700 + + Remove half implemented GC in PyGIBaseInfo, PyGIStruct, and PyGIBoxed + + Remove half implemented GC tracking from PyGIBaseInfo as it was not + needed (the implemented was also missing usage of + PyObject_GC_New/Track). + Ensure weakref list for PyGIBaseInfo is initialized to NULL and + cleared + properly. + Remove invalid calls to PyObject_GC_UnTrack and PyObject_ClearWeakRefs + for both PyGIStruct and PyGIBoxed as these types were not being + advertised as GC aware with Py_TPFLAGS_HAVE_GC. + + https://bugzilla.gnome.org/show_bug.cgi?id=677091 + + gi/pygi-boxed.c | 4 ---- + gi/pygi-info.c | 20 +++++--------------- + gi/pygi-struct.c | 4 ---- + 3 files changed, 5 insertions(+), 23 deletions(-) + +commit 87e41db2e060acd689a2ac043bc1ac51007de6f3 +Author: Simon Feltman +Date: Fri May 3 02:00:07 2013 -0700 + + Replace usage of pyg_begin_allow_threads with Py_BEGIN_ALLOW_THREADS + + Replace all usage of pyg[lib]_begin_allow_threads with direct usage + of Py_BEGIN_ALLOW_THREADS. + + https://bugzilla.gnome.org/show_bug.cgi?id=699440 + + gi/_glib/pyglib.h | 4 ---- + gi/_glib/pygoptioncontext.c | 4 ++-- + gi/_gobject/pygobject.c | 33 ++++++++++++++++----------------- + gi/gimodule.c | 4 ++-- + gi/pygi-invoke.c | 4 ++-- + 5 files changed, 22 insertions(+), 27 deletions(-) + +commit c9e95663d05de98a9abd3d1479554b1f09753382 +Author: Simon Feltman +Date: Thu May 2 03:57:05 2013 -0700 + + Remove and deprecate API for setting of thread blocking functions + + Remove pyglib_set_thread_block_funcs and deprecate + pyg_set_thread_block_funcs. + The thread block function APIs are no longer be neccessary because + PyGObject + can use the Python C API directly when working with threads. + + https://bugzilla.gnome.org/show_bug.cgi?id=699440 + + gi/_glib/pyglib.c | 41 ----------------------------------- + gi/_glib/pyglib.h | 9 ++++---- + gi/_gobject/gobjectmodule.c | 25 ++++++++------------- + gi/_gobject/pygobject-private.h | 33 ---------------------------- + gi/_gobject/pygobject.h | 48 + ++++++++++++++++++++--------------------- + gi/gimodule.c | 15 +++++++------ + 6 files changed, 46 insertions(+), 125 deletions(-) + +commit 05498a5732582a5ed1944bd1383af154ca5fc4e6 +Author: Martin Pitt +Date: Tue Apr 30 11:51:05 2013 -0700 + + configure.ac: Post-release bump to 3.9.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 902bb6685fd9c90c7d81127861a152b0fab4b107 +Author: Martin Pitt +Date: Tue Apr 30 11:49:03 2013 -0700 + + release 3.9.1 + + NEWS | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +commit f463d7cfaf65e0f3594ec15d897325f84225f1c5 +Author: Simon Feltman +Date: Sun Apr 28 19:59:35 2013 -0700 + + gtk-demo: Wrap description strings at 80 characters + + Wrap trailing demo description strings so they are easier to read + in a programming editor. The gtk-demo itself re-wraps this using + textwrap and the Gtk.TextView dynamic wrapping. + + https://bugzilla.gnome.org/show_bug.cgi?id=698547 + + demos/gtk-demo/demos/Entry/search_entry.py | 6 +++--- + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 8 ++++---- + demos/gtk-demo/demos/Icon View/iconviewedit.py | 5 +++-- + demos/gtk-demo/demos/Tree View/liststore.py | 5 ++++- + demos/gtk-demo/demos/images.py | 6 ++++-- + demos/gtk-demo/demos/menus.py | 20 + ++++++++++++++++---- + demos/gtk-demo/demos/pickers.py | 4 ++-- + demos/gtk-demo/demos/pixbuf.py | 5 +++-- + demos/gtk-demo/demos/rotatedtext.py | 6 ++++-- + 9 files changed, 43 insertions(+), 22 deletions(-) + +commit f0d4b963c42ac31d4d17ec0f2271940df2568644 +Author: Simon Feltman +Date: Sat Apr 27 22:30:35 2013 -0700 + + gtk-demo: Use textwrap to reformat description for Gtk.TextView + + https://bugzilla.gnome.org/show_bug.cgi?id=698547 + + demos/gtk-demo/gtk-demo.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit ed41e260dcf5745fcc0656412be3c4a520ee20fc +Author: Simon Feltman +Date: Sat Apr 27 21:58:28 2013 -0700 + + gtk-demo: Use GtkSource.View for showing source code + + Replace manual syntax highlighting of Gtk.TextView with usage of + GtkSource.View when available. Fall back to TextView with no + hightlighting when GtkSource is not available. + + https://bugzilla.gnome.org/show_bug.cgi?id=698547 + + demos/gtk-demo/gtk-demo.py | 170 + ++++++++++++--------------------------------- + 1 file changed, 44 insertions(+), 126 deletions(-) + +commit 150104db47ac5ba32758fba0c156adaecc0fbcc0 +Author: Mike Ruprecht +Date: Sun Apr 28 01:40:34 2013 -0500 + + Use correct class for GtkEditable's get_selection_bounds() function + + https://bugzilla.gnome.org/show_bug.cgi?id=699096 + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 61663928259f6f48c11f6e43334a62dd2b3eb8e6 +Author: Simon Feltman +Date: Thu Apr 25 05:27:35 2013 -0700 + + Test results of g_base_info_get_name for NULL + + Block against potential NULL result when generating type hint with + _g_arg_get_pytype_hint. + + https://bugzilla.gnome.org/show_bug.cgi?id=698829 + + gi/pygi-info.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +commit 0dff1940caf52ea5f1de27cc801ea6d4dab3a446 +Author: Jose Rostagno +Date: Sun Apr 21 19:09:59 2013 -0300 + + Remove g_type_init conditional call + + It's deprecated in the glib version we depend on. + + https://bugzilla.gnome.org/show_bug.cgi?id=698763 + + gi/_gobject/gobjectmodule.c | 3 --- + 1 file changed, 3 deletions(-) + +commit c84b071ed8d3b78b4e4a6aef12f5f8bb99bdc107 +Author: Jose Rostagno +Date: Sat Mar 30 20:59:44 2013 -0300 + + Update deps versions also in README + + commit f957e33bc1ef2a4175bab85cfcd9b5faf092aa2f missed to update + that file + + https://bugzilla.gnome.org/show_bug.cgi?id=698763 + + README | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4f25fa43e1e5c0f3cd22bcdadadb1d731f01fe34 +Author: Jose Rostagno +Date: Sat Mar 30 20:50:35 2013 -0300 + + Drop compat code for old python version + + https://bugzilla.gnome.org/show_bug.cgi?id=698763 + + gi/_glib/pyglib-python-compat.h | 12 ------------ + 1 file changed, 12 deletions(-) + +commit 8104fa04cac2cba74337e6c4b3ecf56fd6cbb80b +Author: Niklas Koep +Date: Thu Apr 25 06:14:12 2013 +0200 + + Remove duplicate call to _gi.Repository.require() + + repository.require() was called twice in IntrospectionModule's + constructor. + + https://bugzilla.gnome.org/show_bug.cgi?id=698797 + + gi/module.py | 1 - + 1 file changed, 1 deletion(-) + +commit f22b95033c0bcd99e9c70e6f0dc999f5e64b08a6 +Author: Johan Dahlin +Date: Mon Oct 1 03:02:10 2012 -0700 + + Add ObjectInfo.get_class_struct() + + https://bugzilla.gnome.org/show_bug.cgi?id=685218 + + gi/pygi-info.c | 15 +++++++++++++++ + tests/test_gi.py | 4 ++++ + 2 files changed, 19 insertions(+) + +commit 2d34d35e5db06b0eb29cba91d0999b20a5c0b450 +Author: Simon Feltman +Date: Mon Apr 22 03:43:23 2013 -0700 + + Change interpretation of NULL pointer field from None to 0 + + The usage of 0 is needed because these fields should generally + be used to store integer indices or hashes, not necessarily + pointers to actual data. + + https://bugzilla.gnome.org/show_bug.cgi?id=698366 + + gi/pygi-argument.c | 11 +---------- + tests/test_everything.py | 5 +++-- + 2 files changed, 4 insertions(+), 12 deletions(-) + +commit 8d61ad38eb90d639da08289c036ae4cb99336c2a +Author: Sobhan Mohammadpour +Date: Fri Mar 8 08:25:58 2013 +0330 + + Do not build tests until needed + + Originally by [Alexandre Rostovtsev + + https://bugzilla.gnome.org/show_bug.cgi?id=698444 + + tests/Makefile.am | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit f61f23b999ae6e27ca852753da906de4ab8e6e25 +Author: Kai Willadsen +Date: Sun Apr 14 15:16:40 2013 +1000 + + pygi-convert: Support toolbar styles + + https://bugzilla.gnome.org/show_bug.cgi?id=698477 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 7a92ade7ee5fe2f9eb8de2626c34650e2e5c06df +Author: Kai Willadsen +Date: Sun Apr 14 10:54:04 2013 +1000 + + pygi-convert: Support new-style constructors for Gio.File + + https://bugzilla.gnome.org/show_bug.cgi?id=698477 + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 1e8120992dc103ac817351be3c150e6cb25f719f +Author: Kai Willadsen +Date: Sun Apr 14 10:22:55 2013 +1000 + + pygi-convert: Add some support for recent manager constructs + + https://bugzilla.gnome.org/show_bug.cgi?id=698477 + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 17d349f98d62ea7947c1553e0ef7e867301523aa +Author: Kai Willadsen +Date: Sun Apr 14 07:37:24 2013 +1000 + + pygi-convert: Check for double quote in require statement + + https://bugzilla.gnome.org/show_bug.cgi?id=698477 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit cc8bd6bd3fdf99762aa3431ceee347a05f6f3200 +Author: Kai Willadsen +Date: Sun Apr 14 07:37:00 2013 +1000 + + pygi-convert: Don't transform arbitrary keysym imports + + https://bugzilla.gnome.org/show_bug.cgi?id=698477 + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 99872a18ed1468b2c85cc7b96a0d12f2ae5167f0 +Author: Simon Feltman +Date: Thu Apr 11 04:09:59 2013 -0700 + + Remove Python keyword escapement in Repository.find_by_name + + Strip trailing underscore from module level items before + calling g_irepository_find_by_name. This fixes a problem + with GI module level items having the same name as a Python + keyword raising an AttributeError during access (Pango.break_). + + https://bugzilla.gnome.org/show_bug.cgi?id=697363 + + gi/pygi-info.c | 32 ++++++++++++++++++++++---------- + gi/pygi-info.h | 2 ++ + gi/pygi-repository.c | 16 ++++++++++++++++ + tests/test_overrides_pango.py | 5 +++++ + 4 files changed, 45 insertions(+), 10 deletions(-) + +commit c07404461b126206e369270b56e613f81369c70a +Author: Daniel Drake +Date: Mon Mar 18 16:08:09 2013 -0600 + + Optimize signal lookup in gi repository + + Now that we have GSignalQuery results available to us when connecting + signals, we already know which GType implements the signal in + question. + + Therefore there is no need to traverse the class parent hierarchy + looking for this, which takes a considerable amount of CPU time. + + There is also no need to canonicalize the signal name; both before + and after this patch, by the time we reach this point we have already + successfully looked up the signal name as presented from Python. + + https://bugzilla.gnome.org/show_bug.cgi?id=696143 + + gi/_gobject/pygobject.c | 5 ++-- + gi/pygi-signal-closure.c | 59 + +++++++++++++----------------------------------- + gi/pygi-signal-closure.h | 1 + + gi/pygi.h | 4 +++- + 4 files changed, 23 insertions(+), 46 deletions(-) + +commit e220706b3e4d9fd454613fbfe1e60e7e1da94ae0 +Author: Daniel Drake +Date: Mon Mar 18 15:38:19 2013 -0600 + + Optimize connection of Python-implemented signals + + Like properties, when working with signals we must detect if the + signal is implemented in a Python class or if it originates from the + gi repository, and act accordingly. + + Asking the gi repository if it can find a signal that is implemented + in a Python class (it can't) takes a considerable amount of CPU time. + + Use g_signal_query() to find out which GType implements the signal. + Then perform a simple test to see if this type is implemented at the + Python level, allowing us to to skip the GI querying in this case. + + https://bugzilla.gnome.org/show_bug.cgi?id=696143 + + gi/_gobject/pygobject.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +commit e91b35d72f93678a79623347dce271148d57046f +Author: Daniel Drake +Date: Mon Mar 18 15:24:52 2013 -0600 + + Consolidate signal connection code + + This code was repeated 4 times with very little variance; + consolidate it and add simple tests to ensure basic coverage. + + https://bugzilla.gnome.org/show_bug.cgi?id=696143 + + gi/_gobject/pygobject.c | 129 + +++++++++++++++-------------------------------- + tests/test_everything.py | 33 ++++++++++++ + 2 files changed, 74 insertions(+), 88 deletions(-) + +commit cd91e1d5db617d470acbf8c5bc74c11c92f946f6 +Author: Daniel Drake +Date: Mon Mar 18 15:11:16 2013 -0600 + + Fix setting of struct property values + + "goto out" in this context means that an error occurred, but this + particular instance was sitting in the "good" codepath. + + Fixes setting of struct property values. + + gi/pygi-property.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 8981ea0422c6837d488311dafe8937593372e736 +Author: Daniel Drake +Date: Mon Mar 18 14:25:45 2013 -0600 + + Optimize property get/set when using GObject.props + + Skip GI repository lookup for properties defined on Python + defined GObject types. + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=696143 + + gi/_gobject/pygobject.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +commit 266e389ff90d982151bae3ac22b9b8b0739f520f +Author: Christoph Reiter +Date: Sat Apr 13 17:28:26 2013 +0200 + + configure.ac: Fix PYTHON_SO with Python3.3 + + https://bugzilla.gnome.org/show_bug.cgi?id=696646 + + configure.ac | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit e54c2d1df3812a1789ee240b0ba71ddf77c2f90a +Author: Daniel Drake +Date: Mon Mar 18 14:13:37 2013 -0600 + + Simplify registration of custom types + + Use custom quark data to track Python created GTypes. + + Remove previous mechanism to track registration of python-implemented + GTypes as it was unused (no custom registration was ever tracked). + + Leave vtable pointer and set to NULL to avoid an ABI break. + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=696143 + + gi/_gobject/gobjectmodule.c | 11 +++++-- + gi/_gobject/pygobject-private.h | 8 ++--- + gi/_gobject/pygobject.c | 8 ++--- + gi/_gobject/pygobject.h | 9 +++--- + gi/_gobject/pygtype.c | 69 + +++-------------------------------------- + 5 files changed, 22 insertions(+), 83 deletions(-) + +commit 50702a09344825e3a8aa54365d78de807f989d88 +Author: Christoph Reiter +Date: Sat Apr 13 16:04:17 2013 +0200 + + pygi-convert.sh: Add GStreamer rules + + https://bugzilla.gnome.org/show_bug.cgi?id=697951 + + pygi-convert.sh | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +commit b289176e6b37cb2825bd555cea019b85b68d5c57 +Author: Jussi Kukkonen +Date: Sun Mar 10 15:04:40 2013 +0200 + + pygi-convert: Add rule for TreeModelFlags + + Signed-off-by: Simon Feltman + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 09610bf42be76f65d7d2afe1c691f7b4a7c64e5b +Author: Simon Feltman +Date: Fri Mar 29 03:20:44 2013 -0700 + + Unify interface struct to Python GI marshaling code + + Add pygi_marshal_to_py_interface_struct used for direct gi method + call out args and vfunc in args. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 72 ++++++------------------------- + gi/pygi-marshal-to-py.c | 112 + +++++++++++++++++++++++++++++------------------- + gi/pygi-marshal-to-py.h | 8 ++++ + 3 files changed, 91 insertions(+), 101 deletions(-) + +commit 6d3a0751e71ee3c37b3bb646723aed75971e5b39 +Author: Simon Feltman +Date: Thu Mar 28 22:41:51 2013 -0700 + + Unify Python interface struct to GI marshaling code + + Add pygi_marshal_from_py_interface_struct used for direct gi method + call in args and vfunc out args. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 75 +++++++-------------- + gi/pygi-cache.c | 12 +--- + gi/pygi-marshal-from-py.c | 167 + +++++++++++++++++++++++++++++----------------- + gi/pygi-marshal-from-py.h | 11 +++ + 4 files changed, 141 insertions(+), 124 deletions(-) + +commit 1ea654b4d34e0d119556b232796cd9370b2572f1 +Author: Simon Feltman +Date: Thu Mar 28 06:17:15 2013 -0700 + + Unify Python float and double to GI marshaling code + + Change _pygi_argument_from_object to use the cachers marshalers + (_pygi_marshal_from_py_float/double) directly instead of keeping a + copy of the code. + Refactor _pygi_marshal_from_py_float/double to use a common utility + _pygi_py_arg_to_double for initial error checking and conversion. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 26 ++++---------------------- + gi/pygi-marshal-from-py.c | 42 ++++++++++++++++++++---------------------- + 2 files changed, 24 insertions(+), 44 deletions(-) + +commit 2eb2a712864a1a685d19018e0860cf0da7c5c9ab +Author: Simon Feltman +Date: Thu Mar 28 05:29:08 2013 -0700 + + Unify filename to Python GI marshaling code + + Change _pygi_argument_to_object to use the cachers marshaler + (_pygi_marshal_to_py_filename) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 22 ++-------------------- + gi/pygi-marshal-to-py.c | 6 ++---- + 2 files changed, 4 insertions(+), 24 deletions(-) + +commit 54aa043d96deb02589e13042a46917405ca53780 +Author: Simon Feltman +Date: Thu Mar 28 05:20:00 2013 -0700 + + Unify utf8 to Python GI marshaling code + + Change _pygi_argument_to_object to use the cachers marshaler + (_pygi_marshal_to_py_utf8) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 11 ++++------- + gi/pygi-marshal-to-py.c | 4 +--- + 2 files changed, 5 insertions(+), 10 deletions(-) + +commit 03ff41ae4bb83858338d96cc6210092c7fb82464 +Author: Simon Feltman +Date: Thu Mar 28 05:10:45 2013 -0700 + + Unify unichar to Python GI marshaling code + + Change _pygi_argument_to_object to use the cachers marshaler + (_pygi_marshal_to_py_unichar) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 19 ++----------------- + 1 file changed, 2 insertions(+), 17 deletions(-) + +commit 594ad084c2cc21cebce209c11740e6d4866b0b82 +Author: Simon Feltman +Date: Sat Feb 16 19:49:59 2013 -0800 + + Unify Python unicode to filename GI marshaling code + + Change _pygi_argument_from_object to use the cachers marshaler + (_pygi_marshal_from_py_filename) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 30 ++---------------------------- + 1 file changed, 2 insertions(+), 28 deletions(-) + +commit a62e8cdf90f7b03cfc8116125ef3557f9ad08dde +Author: Simon Feltman +Date: Sat Feb 16 19:32:54 2013 -0800 + + Unify Python unicode to utf8 GI marshaling code + + Change _pygi_argument_from_object to use the cachers marshaler + (_pygi_marshal_from_py_utf8) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 32 ++------------------------------ + 1 file changed, 2 insertions(+), 30 deletions(-) + +commit e253c73335fccabc61e0329f8528a90f79858c67 +Author: Simon Feltman +Date: Sat Feb 16 19:16:43 2013 -0800 + + Unify Python unicode to unichar GI marshaling code + + Change _pygi_argument_from_object to use the cachers marshaler + (_pygi_marshal_from_py_unichar) directly instead of keeping a + copy of the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 34 ++-------------------------------- + gi/pygi-marshal-from-py.c | 9 +++++++++ + 2 files changed, 11 insertions(+), 32 deletions(-) + +commit 216caf590b262fed40d10bb34d020089d1197160 +Author: Simon Feltman +Date: Thu Apr 4 15:57:12 2013 -0700 + + Fix enum and flags marshaling type assumptions + + Replace assignments of GFlags and GEnum values to various GIArgument + members with v_uint and v_int respectively. + + gi/pygi-argument.c | 6 +++--- + gi/pygi-property.c | 4 ++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +commit 4799ef1d0cb9a4b27c7952585d33b58ea9ec34ca +Author: Christoph Reiter +Date: Thu Apr 4 10:08:38 2013 +0200 + + Make AM_CHECK_PYTHON_LIBS not depend on AM_CHECK_PYTHON_HEADERS + + https://bugzilla.gnome.org/show_bug.cgi?id=696648#c6 + + m4/python.m4 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit f82f755a0f419539c223e4a74e33145726c6e69f +Author: Christoph Reiter +Date: Thu Apr 4 09:05:48 2013 +0200 + + Use distutils.sysconfig to retrieve the python include path. + + https://bugzilla.gnome.org/show_bug.cgi?id=696648 + + m4/python.m4 | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +commit cf81dd66e6387bf27122a71176e91ca39beb6519 +Author: Martin Pitt +Date: Thu Apr 4 06:47:56 2013 +0200 + + Use g_strdup() consistently + + https://bugzilla.gnome.org/show_bug.cgi?id=696650 + + gi/pygi-marshal-from-py.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6c22fea63fa6978c2a717ff12ff84d3aff776b5e +Author: Christoph Reiter +Date: Tue Mar 26 16:03:59 2013 +0100 + + Support PEP 3149 (ABI version tagged .so files) + + Add a ABI suffix to the shared library retrieved from + distutils.sysconfig + instead of hardcoding it. This should also make things more robust + on Windows. + + https://bugzilla.gnome.org/show_bug.cgi?id=696646 + + configure.ac | 3 +++ + gi/Makefile.am | 14 +++++++------- + gi/_glib/Makefile.am | 14 +++++++------- + gi/_gobject/Makefile.am | 14 +++++++------- + 4 files changed, 24 insertions(+), 21 deletions(-) + +commit 2259ccac8aa2ec23240e92e303ea3f2c53dc2a88 +Author: Simon Feltman +Date: Sun Mar 31 01:32:34 2013 -0700 + + Fix stack corruption due to incorrect format for argument parser + + Fix call to PyArg_ParseTupleAndKeywords that used a format parser + of "l" meaning long (8 bytes) in combination with an output pointer + of guint (4 bytes). Change to use gulong with a format of "k". + + https://bugzilla.gnome.org/show_bug.cgi?id=696892 + + gi/_gobject/pygflags.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 48e52210ece0e144b4c959e773ea542a912358e7 +Author: Simon Feltman +Date: Thu Mar 7 00:26:37 2013 -0800 + + Deprecate GLib and GObject threads_init + + Remove a handful of Python threading related helper functions + from pyglib and pygobject. The binding internals required + GLib.threads_init to be called for PyGObject to work with + Python threads. This was removed as it should not be a requirement. + Using the Python threading module already initializes threading + for us (PyEval_InitThreads). + + https://bugzilla.gnome.org/show_bug.cgi?id=686914 + + gi/_glib/glibmodule.c | 16 -------- + gi/_glib/pyglib.c | 94 + --------------------------------------------- + gi/_glib/pyglib.h | 28 +++++++------- + gi/_gobject/gobjectmodule.c | 31 ++++----------- + gi/overrides/GLib.py | 8 +++- + gi/overrides/GObject.py | 2 +- + 6 files changed, 28 insertions(+), 151 deletions(-) + +commit 89d05f91cee419d46cb5318d4a9001ec315a3475 +Author: Martin Pitt +Date: Mon Mar 25 09:03:51 2013 +0100 + + Drop support for Python 2.6 + + 2.7 has been released long ago, nobody tests PyGObject with 2.6 any + more, and + this unblocks e. g. GNOME #682320. + + Drop usage of PyCObject_* (which has been superseded by PyCapsule + for >= 2.7), + and drop Python 2.6 specific workarounds. + + configure.ac | 2 +- + gi/_glib/pyglib-python-compat.h | 20 ------------------ + gi/_gobject/pygobject.h | 6 ------ + gi/pygi.h | 4 ---- + m4/python.m4 | 2 +- + tests/runtests.py | 45 + +---------------------------------------- + tests/test_gobject.py | 1 - + tests/test_signal.py | 4 ---- + 8 files changed, 3 insertions(+), 81 deletions(-) + +commit 56347953abb1e214817186581eaf2b2d8762cf97 +Author: Martin Pitt +Date: Wed Oct 24 16:43:25 2012 +0200 + + Remove static PollFD bindings + + Use the GLib API through GI instead, and provide an override to keep a + backwards compatible constructor syntax. + + https://bugzilla.gnome.org/show_bug.cgi?id=686795 + + gi/_glib/Makefile.am | 2 -- + gi/_glib/glibmodule.c | 2 -- + gi/_glib/pygsource.c | 98 + --------------------------------------------------- + gi/_glib/pygsource.h | 36 ------------------- + gi/overrides/GLib.py | 17 +++++++-- + 5 files changed, 15 insertions(+), 140 deletions(-) + +commit a93eb5ecc982b5fe1bdf8f78b15ba10351a63b89 +Author: Martin Pitt +Date: Mon Mar 25 08:44:24 2013 +0100 + + Drop test skipping due to too old g-i + + We depend on gobject-introspection 1.35.9 now, which has all this API. + + tests/test_gi.py | 24 ------------------------ + tests/test_object_marshaling.py | 14 -------------- + 2 files changed, 38 deletions(-) + +commit f957e33bc1ef2a4175bab85cfcd9b5faf092aa2f +Author: Martin Pitt +Date: Mon Mar 25 08:37:37 2013 +0100 + + Bump glib and g-i dependencies + + Now require g-i 1.35.9 and glib 2.35.9, i. e. the current stable + GNOME 3.8 + versions. This allows us to drop the conditional test suite skips + and drop the + static PollFD bindings. + + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 252556d044322207429c0d0c269365f48e4d819a +Author: Martin Pitt +Date: Mon Mar 25 08:43:53 2013 +0100 + + configure.ac: post-release version bump to 3.9.1 + + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 5f82e007e2dcdbfd82a20d8c4d54f9cd7b3b77ac +Author: Martin Pitt +Date: Mon Mar 25 08:12:10 2013 +0100 + + release 3.8.0 + + NEWS | 4 ++++ + 1 file changed, 4 insertions(+) + +commit bb4fa093d59173f68a0b16e10016bafe7cd18f62 +Author: Simon Feltman +Date: Wed Mar 20 23:45:01 2013 -0700 + + tests: Fix incorrect assumption when testing pyglib version + + Replace version test of 3.7.2 with 3.0.0 as it is the only reasonable + value that can be used for a future proof unittest here. + + tests/test_glib.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 78b7b0bea3068b81ba67deea4d06b1fb27434841 +Author: Martin Pitt +Date: Mon Mar 18 14:02:29 2013 +0100 + + configure.ac: post-release bump to 3.8.0 + + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit defbd63e95faafaa84230f160bc95dad0f55e37d +Author: Martin Pitt +Date: Mon Mar 18 14:01:05 2013 +0100 + + release 3.7.92 + + NEWS | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +commit a0844a896603c5c91bed24cf94106765f0ced74e +Author: Simon Feltman +Date: Sun Mar 17 23:22:38 2013 -0700 + + Fix stack smasher when marshaling enums as a vfunc return value + + Add special case for marshaling GI_TYPE_TAG_INTERFACE with enum or + flag types. Default interfaces to marshal as a pointer. + Add explicit cases for GType and Unichar out/return marshaling. + Fix leaking of GIBaseInfo when marshaling interface as out arg. + + https://bugzilla.gnome.org/show_bug.cgi?id=637832 + + gi/pygi-closure.c | 69 + ++++++++++++++++++++++++++++++++++++++++++++++--------- + tests/test_gi.py | 19 +++++++++++++++ + 2 files changed, 77 insertions(+), 11 deletions(-) + +commit 669e15c35213dbce6ceb0a4a3d474aae620910ce +Author: Simon Feltman +Date: Sun Mar 17 15:37:09 2013 -0700 + + Change base class of PyGIDeprecationWarning based on minor version + + Use RuntimeWarning as the base class of PyGIDeprecationWarning + for unstable (odd minor version) and use DeprecationWarning for + stable (even minor version). This is so PyGObject deprecations + behave the same as regular Python deprecations in stable releases. + + https://bugzilla.gnome.org/show_bug.cgi?id=696011 + + gi/__init__.py | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +commit 755b2e6fc635489d98d48254ea60b2631b43dfbd +Author: Alban Browaeys +Date: Thu Feb 28 18:57:21 2013 +0100 + + autogen.sh: Source gnome-autogen to fix out of source builddir + + https://bugzilla.gnome.org/show_bug.cgi?id=694889 + + autogen.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a38392a9d713b0001cf30066d337b1abbbbbc59e +Author: Martin Pitt +Date: Tue Mar 5 12:22:15 2013 +0100 + + Add 3.7.91.1 NEWS entry + + Forgot to push this back then. + + NEWS | 3 +++ + 1 file changed, 3 insertions(+) + +commit 85f8aae849dd0fb21de8722a3af9234ca20ea1e0 +Author: Simon Feltman +Date: Sun Mar 17 04:19:57 2013 -0700 + + pygtkcompat: Make gdk.Window.get_geometry return tuple of 5 + + Make get_geometry return a tuple of (x, y, width, height, depth) + as it did in pygtk 2. + Update pygtkcompat.enable_gtk() to default to version 3.0 because + version 2.0 core dumps trying to use introspection with gtk 2. + + pygtkcompat/pygtkcompat.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit 38683f721c33cc35f0260868e58643fd35f04cbe +Author: Simon Feltman +Date: Sun Mar 17 02:08:03 2013 -0700 + + testhelpermodule: Fix build warning for PyGObject_Type redefinition + + Remove dynamic retrieval of PyGObject_Type as it is available + in pygobject.h since commit 2656bc47 (causing this compile warning) + + tests/testhelpermodule.c | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +commit a3ec8867945da7722beebb7e77c6255ee3ba8bb8 +Author: Simon Feltman +Date: Sun Mar 17 01:51:33 2013 -0700 + + pygtkcompat: Initialize hint to zero in set_geometry_hints + + pygtkcompat/pygtkcompat.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 471204953d6fc93b3d311afd133d40f7d75ec541 +Author: Simon Feltman +Date: Fri Mar 15 04:33:22 2013 -0700 + + Remove incorrect bounds check with property helper flags + + Remove bounds check for flags as it is not necessary for the + helper to make these kind of judgement calls in general. + e.g. leave it to marshaling/internals to complain about potential + problems. The flags were being bounds checked to a maximum + value of 32 (the intention was most likely to limit it to 32 bits). + + gi/_gobject/propertyhelper.py | 3 --- + tests/test_properties.py | 1 - + 2 files changed, 4 deletions(-) + +commit 2656bc47ca1219b329066da1c2c58018ae624866 +Author: Simon Feltman +Date: Thu Mar 7 18:07:17 2013 -0800 + + Fix crash when setting property of type object to an incorrect type + + Add type check when marshaling an object from Python for GObject + types. + Add PyGObject_Type as part of the pygobject API to check for this. + + https://bugzilla.gnome.org/show_bug.cgi?id=695420 + + gi/_gobject/gobjectmodule.c | 3 ++- + gi/_gobject/pygobject.h | 2 ++ + gi/pygi-marshal-from-py.c | 8 ++++++++ + tests/test_object_marshaling.py | 4 ++++ + 4 files changed, 16 insertions(+), 1 deletion(-) + +commit 44587f42224a44a480629223c8d78a426bc32a12 +Author: Simon Feltman +Date: Thu Mar 7 17:59:02 2013 -0800 + + Remove skipping of object property tests + + These were showing up as unexpected successes now that bug 675726 + is fixed. + + https://bugzilla.gnome.org/show_bug.cgi?id=695420 + + tests/test_object_marshaling.py | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +commit 10214ba2d96fd6d66eeea159219f585abff8632a +Author: Simon Feltman +Date: Thu Mar 7 15:34:49 2013 -0800 + + Give more informative error when setting property to incorrect type + + https://bugzilla.gnome.org/show_bug.cgi?id=695420 + + gi/_gobject/pygobject.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit 9ab6e5451aea43ed086c0d26324c4efed24476d7 +Author: Martin Pitt +Date: Tue Mar 5 12:04:55 2013 +0100 + + Revert "Drop gi.overrides.overridefunc()" + + This reverts commit 1dc2bc9f65669417ae1964d70b85f115928b2963. External + modules + like GEdit plugins use @overrides for functions as well, we must + not break + them. + + https://bugzilla.gnome.org/show_bug.cgi?id=695199 + + gi/overrides/Gtk.py | 7 ++++--- + gi/overrides/__init__.py | 24 ++++++++++++++++++++++-- + 2 files changed, 26 insertions(+), 5 deletions(-) + +commit 862de794bf01a66aa6d796c674bce375cad37ba7 +Author: Martin Pitt +Date: Mon Mar 4 17:33:51 2013 +0100 + + configure.ac: Post-release bump to 3.7.92 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit bb12e652d661cf6ce931b44a89c11951894101bf +Author: Martin Pitt +Date: Mon Mar 4 17:27:50 2013 +0100 + + release 3.7.91 + + NEWS | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +commit 25a6f90f28b065dd4f1cd352826598577402dc0b +Author: Martin Pitt +Date: Mon Mar 4 17:16:22 2013 +0100 + + Dot not clobber original Gdk/Gtk functions with overrides + + https://bugzilla.gnome.org/show_bug.cgi?id=686835 + + gi/overrides/Gdk.py | 3 ++- + gi/overrides/Gtk.py | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +commit d50d16428edf42799489fe1befbc4ce56f0fa181 +Author: Martin Pitt +Date: Mon Mar 4 15:30:31 2013 +0100 + + tests: Reorganize GError and GClosure tests + + Split TestGClosure.test_gclosure_in() into its three components. + + Merge the various TestGError* classes into one, to match the structure + of the + other tests. + + tests/test_gi.py | 59 + +++++++++++++++++++++++++------------------------------- + 1 file changed, 26 insertions(+), 33 deletions(-) + +commit 8cfd596c7849bf78a74fee04630fbbb104f02080 +Author: Martin Pitt +Date: Mon Mar 4 15:16:25 2013 +0100 + + Fix memory leaks in property setting/getting + + Do not leak GValues and string arrays, free them properly. As we + always free + the intermediate GValues, use g_value_dup_boxed() instead of + g_value_get_boxed() when appropriate. + + Detected by test_gi.TestPropertiesObject.test_strv test case. + + gi/pygi-property.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +commit eec8c3a932d42e92ccaf7f97d3d90948842e263f +Author: Martin Pitt +Date: Mon Mar 4 12:43:24 2013 +0100 + + Fix memory leak in pyg_flags_get_value_nicks() + + Discovered by test_gi.TestKeywords.test_uppercase() test. + + gi/_gobject/pygflags.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 002a834dd993b82508a4fe262269befcf1a6d341 +Author: Martin Pitt +Date: Mon Mar 4 12:10:03 2013 +0100 + + Fix memory leak in _pygi_argument_to_array() + + Free the originally allocated GArray data before setting it to + our already + existing C array. + + Discovered by test_gi.TestStructure.test_boxed_struct_return test + case. + + gi/pygi-argument.c | 1 + + 1 file changed, 1 insertion(+) + +commit d32b410a1b1fcca6d10d75fbd771ea789999da64 +Author: Martin Pitt +Date: Mon Mar 4 10:19:34 2013 +0100 + + Fix leaking inout C arrays + + g_*_info_invoke() changes the original state->in_args and state->args + C arrays + to the output values for (inout) arguments, thus losing the pointer + to the + originally allocated array. Remember that in state->args_data, + so that we can + free it in _pygi_marshal_cleanup_from_py_array(). + + Reproduced by test_gi.TestArray.test_array_fixed_inout test case. + + gi/pygi-marshal-cleanup.c | 6 ++++++ + gi/pygi-marshal-from-py.c | 4 ++++ + 2 files changed, 10 insertions(+) + +commit e4098cbc28ff9324fa851bca2e423da4e51b5091 +Author: Martin Pitt +Date: Fri Mar 1 15:12:31 2013 +0100 + + Fix leak in _PyGI_ERROR_PREFIX() + + Properly clean up our allocated py_error_prefix string. + + Fixes memory leak in e. g. test_gi.TestArray.test_array_fixed_int_in. + + gi/pygi-private.h | 1 + + 1 file changed, 1 insertion(+) + +commit b388c3e87ce86d26560337c88eb33d0a95647db8 +Author: Martin Pitt +Date: Fri Mar 1 15:01:06 2013 +0100 + + Fix leaking of boxed array elements + + Commit 631d8ef879a copies struct array elements, but this needlessly + duplicates + and leaks the array element for boxed types. So only do it for + plain structs. + + This fixes the memory leak with + test_gi.TestGValue.test_gvalue_flat_array_out. + + https://bugzilla.gnome.org/show_bug.cgi?id=693402 + + gi/pygi-marshal-to-py.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 1dc2bc9f65669417ae1964d70b85f115928b2963 +Author: Martin Pitt +Date: Fri Mar 1 14:04:34 2013 +0100 + + Drop gi.overrides.overridefunc() + + This just adds an unnecessary extra function call and is not really + needed. + Drop it from the only remaining function which uses this + (Gtk.main_quit) and + drop overridefunc(). + + https://bugzilla.gnome.org/show_bug.cgi?id=686835 + + gi/overrides/Gtk.py | 7 +++---- + gi/overrides/__init__.py | 24 ++---------------------- + 2 files changed, 5 insertions(+), 26 deletions(-) + +commit 1edc4ba31b3f9375ec3920aab5b71eb066ee3739 +Author: Martin Pitt +Date: Fri Mar 1 14:02:02 2013 +0100 + + Add some tests for overridden Gdk/Gtk functions + + Add tests for Gtk.main_quit, Gtk.stock_parse(), and Gdk.color_parse(), + as we + have overrides for them. + + tests/test_overrides_gdk.py | 7 +++++++ + tests/test_overrides_gtk.py | 15 +++++++++++++++ + 2 files changed, 22 insertions(+) + +commit 6f6c0ceff00fea83bc85756b10694f7c96039abc +Author: Martin Pitt +Date: Fri Mar 1 11:10:01 2013 +0100 + + Fix GLib.Source ref leak upon destruction + + In GLib.Source.__del__(), manually unref the source if we are a + custom Source. + As we use a static binding to create it, the GI part won't unref it + for us, + leading to finalize() method not being called and the GSource + object leaking. + + https://bugzilla.gnome.org/show_bug.cgi?id=510511 + + gi/overrides/GLib.py | 4 ++++ + tests/test_source.py | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +commit 91f76dd94fb0afc6888a821a31c3a4e2e053360e +Author: Martin Pitt +Date: Thu Feb 28 15:08:56 2013 +0100 + + Add performance test for Gtk.ListStore.append + + We are going to optimize this in various ways, so let's measure it. + + tests/test_overrides_gtk.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit b1ff74b085bdca72c272f019be4dd387073a991a +Author: Simon Feltman +Date: Thu Feb 28 04:32:30 2013 -0800 + + Optimize GValue.get/set_value by setting GValue.g_type to a local + + This increases performance by a factor of 2x for types later + in the dispatch. + + https://bugzilla.gnome.org/show_bug.cgi?id=694857 + + gi/overrides/GObject.py | 98 + +++++++++++++++++++++++++------------------------ + 1 file changed, 51 insertions(+), 47 deletions(-) + +commit 105e6738ee249b64904da26ae45dd273ca4eeba8 +Author: Martin Pitt +Date: Thu Feb 28 11:43:47 2013 +0100 + + Fix leak of caller-allocated boxed values + + Add a new "allocated_slice" argument to _pygi_boxed_new() which + specifies + whether its "boxed" pointer was allocated using a slice (by giving + its size) or + malloc (by specifying 0), as _pygi_boxed_new cannot determine that + itself any + more. + + Use this in _pygi_marshal_to_py_interface_struct() for + caller-allocated boxed + values, as _caller_alloc() uses _pygi_boxed_alloc() for those + (i. e. slices), + which would otherwise leak. + + Thanks to Mike Gorse for the original patch! + + https://bugzilla.gnome.org/show_bug.cgi?id=691501 + + gi/gimodule.c | 2 +- + gi/pygi-argument.c | 2 +- + gi/pygi-boxed.c | 14 ++++++++++---- + gi/pygi-boxed.h | 3 ++- + gi/pygi-marshal-to-py.c | 6 ++++-- + gi/pygi-source.c | 3 ++- + 6 files changed, 20 insertions(+), 10 deletions(-) + +commit 64bcca2d39fed1734ad1abbe291406387e901f5c +Author: Martin Pitt +Date: Thu Feb 28 10:48:18 2013 +0100 + + Fix memory handling of caller-allocated boxed types + + _pygi_marshal_to_py_interface_struct() and other places treat + subtypes of + G_TYPE_BOXED as boxed values and wrap them with _pygi_boxed_new(). Fix + _caller_alloc() and _cleanup_caller_allocates() to consider + G_TYPE_BOXED + subtypes as well and use the slice allocator instead of malloc()'ing + a struct. + This avoids trying to free an malloc'ed struct with g_slice_free() + and properly + cleans up the boxed values. + + The leak was produced with: + + G_SLICE=debug-blocks PYTHONPATH=. valgrind --tool=memcheck + --leak-check=full --show-possibly-lost=no \ + python3 -c 'from gi.repository import Gtk; b=Gtk.TextBuffer(); + (s,e) = b.get_bounds()' + + gi/pygi-invoke.c | 2 +- + gi/pygi-marshal-cleanup.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 4f5e8b7554b6388aa2d0eb4a3b285d99499163be +Author: Martin Pitt +Date: Wed Feb 27 23:21:34 2013 +0100 + + Fix cleanup of GValue arrays + + Commit bc1fd8 introduced a thinko: We must not change + item_arg_cache->from_py_cleanup, as it's a global cache. Revert + the original + change, and instead put the hack into + _pygi_marshal_cleanup_from_py_array(), + which now short-circuits + _pygi_marshal_cleanup_from_py_interface_struct_gvalue() to avoid + trying to release a slice which has never been allocated in + _pygi_marshal_from_py_array(). + + https://bugzilla.gnome.org/show_bug.cgi?id=672224 + + gi/pygi-marshal-cleanup.c | 11 ++++++++++- + gi/pygi-marshal-from-py.c | 10 +++------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +commit 70118c3840b10e1585d066a4be485c097cd23e99 +Author: Martin Pitt +Date: Wed Feb 27 21:52:43 2013 +0100 + + Revert "Mark caller-allocated boxed structures as having a slice + allocated" + + This is wrong after all, as it sets slice_allocated to TRUE, but + doesn't set a + corresponding size. Also, poking in internal fields from that place + is ugly; + this should rather be fixed in gi/pygi-marshal-cleanup.c + _cleanup_caller_allocates(). + + This reverts commit dc3d21173b75232f7ea0b9913f7309486456a69d. + + gi/pygi-marshal-to-py.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit a51c72c771dafc0c13d7990f1ff3e428dca729a1 +Author: Martin Pitt +Date: Wed Feb 27 21:51:30 2013 +0100 + + Run tests with G_SLICE=debug_blocks + + This will help finding regressions in slice management, like in + https://bugzilla.gnome.org/show_bug.cgi?id=691501 + + tests/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 4f6ebcfe0605a7a593dc3f9dd322a4da9bd091a3 +Author: Martin Pitt +Date: Wed Feb 27 18:30:23 2013 +0100 + + Add override helper for stripping boolean returns + + Introduce a gi.overrides.strip_boolean_result() helper which checks + a boolean + return value and if True, return the remaining arguments, otherwise + return a + default. This pattern is being used by a lot of overrides, which get + significantly smaller and more consistent that way. + + https://bugzilla.gnome.org/show_bug.cgi?id=694431 + + gi/overrides/Gdk.py | 27 +------- + gi/overrides/Gtk.py | 156 + +++++++++-------------------------------------- + gi/overrides/__init__.py | 22 +++++++ + 3 files changed, 53 insertions(+), 152 deletions(-) + +commit 08c97b0bd3140921f1b5c74f7764e23d3a9bf0ee +Author: Martin Pitt +Date: Wed Feb 27 15:39:23 2013 +0100 + + Drop obsolete pygobject_register_sinkfunc() declaration + + There is no definition for this any more, nor is it being used + anywhere. + + https://bugzilla.gnome.org/show_bug.cgi?id=639849 + + gi/_gobject/pygobject-private.h | 2 -- + 1 file changed, 2 deletions(-) + +commit b6fefd625b843d4fc3dabc456584a2ad27a48c8c +Author: Martin Pitt +Date: Wed Feb 27 13:41:55 2013 +0100 + + Fix marshalling of C arrays with explicit length in signal arguments + + We need _pygi_argument_to_array() from both closure marshalling + (where we have + the arguments as GIArgument array) and signal closure marshalling + (where we + have the arguments in a GValue array). Add an alternative + "args_values" + parameter to _pygi_argument_to_array() so that callers can specify + one or the + other depending on which type they have available. + + This allows us to pass on the full argument list for signal closures, + so that + _pygi_argument_to_array() can access the explicit length argument + for an + array. + + This fixes the GSettings:change-event signal. + + https://bugzilla.gnome.org/show_bug.cgi?id=662241 + + gi/pygi-argument.c | 36 ++++++++++++++++++++++++++++-------- + gi/pygi-argument.h | 1 + + gi/pygi-closure.c | 2 +- + gi/pygi-info.c | 4 ++-- + gi/pygi-signal-closure.c | 3 ++- + tests/test_gio.py | 18 ++++++++++++++++++ + 6 files changed, 52 insertions(+), 12 deletions(-) + +commit caeeeb7e4282e183eefc3c53b2d53c8c2bb7de89 +Author: Martin Pitt +Date: Wed Feb 27 08:07:20 2013 +0100 + + Fix signedness, overflow checking, and 32 bit overflow of GFlags + + GFlagsValue.value is a guint, so we must access it as unsigned + type. Define two + new macros PYGLIB_PyLong_FromUnsignedLong() and + PYGLIB_PyLong_AsUnsignedLong() + for that purpose, and consistently use them for handling flag + values. Use the + checked variant of these functions which produce OverflowErrors + instead + of the unchecked PYGLIB_PyLong_AS_LONG(). + + Insert zero padding after the PyLongObject in PyGFlags and + PyGEnum. Without + this, the directly adjacent GType field seems to confuse + PyLong_FromUnsignedLong() and includes the GType into the numeric + value. + + https://bugzilla.gnome.org/show_bug.cgi?id=693121 + + gi/_glib/pyglib-python-compat.h | 8 +++++++ + gi/_gobject/gobjectmodule.c | 2 +- + gi/_gobject/pygflags.c | 52 + +++++++++++++++++++++++++---------------- + gi/_gobject/pygobject-private.h | 10 ++++---- + gi/_gobject/pygobject.h | 4 ++-- + gi/_gobject/pygtype.c | 6 ++--- + tests/test_overrides_gdk.py | 15 ++++++++++++ + 7 files changed, 67 insertions(+), 30 deletions(-) + +commit b3a3da37e369f3f5d434c8dc9f3c7f1e74d537ac +Author: Chun-wei Fan +Date: Tue Feb 26 16:15:36 2013 +0800 + + gi/pygi-marshal-from-py.c: Fix build on Visual C++ + + Since Visual C++ does not provide the INFINITY and NAN constants + in its + math.h (they are items defined by C99), provide fallback + implementations + for it here. The INFINITY constant can be provided with HUGE_VAL, + since + we are using INFINITY to check the value of a variable of double + type, and + we could use a rather simple workaround for NAN. + + Also avoid declaring variables in the middle of the block. + + https://bugzilla.gnome.org/show_bug.cgi?id=692856 + + gi/pygi-marshal-from-py.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +commit 5210e3d5bb7936a21b6a2c938ede505bf1d848c9 +Author: Martin Pitt +Date: Tue Feb 26 16:42:19 2013 +0100 + + Fix some style issues with previous patch + + gi/pygi-cache.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 999679beaa9f5b36d9483abdbd30cd5e113b6bf6 +Author: Martin Pitt +Date: Tue Feb 26 10:15:22 2013 +0100 + + Raise DeprecationWarning on deprecated callables + + Check if a callable is marked as deprecated and raise a + DeprecationWarning in + that case. + + Notes: + - Python hides DeprecationWarning by default, you need to enable + them with -Wd + - The deprecation message is currently not in the typelib (bug + #694728) + + https://bugzilla.gnome.org/show_bug.cgi?id=665084 + + gi/pygi-cache.c | 14 ++++++++++++++ + tests/test_gi.py | 10 ++++++++++ + 2 files changed, 24 insertions(+) + +commit 9f8258cfdcf562aa6cf37b9e66075b7f6a6ed97a +Author: Simon Feltman +Date: Mon Feb 18 00:39:45 2013 -0800 + + pygtkcompat: Add Widget.window, scroll_to_mark, and window methods + + Fix gi.pygtkcompat attempting relative import in Python < 3.0. + Add Gtk.Widget.window property which uses get_window() + Add Gtk.TextView.scroll_to_mark with defaults + Add Gtk.window_list_toplevels and Gtk.window_set_default_icon_name + + https://bugzilla.gnome.org/show_bug.cgi?id=694067 + + gi/pygtkcompat.py | 2 ++ + pygtkcompat/pygtkcompat.py | 14 ++++++++++++++ + 2 files changed, 16 insertions(+) + +commit e8e2bbee7bb79039bbd9a968f7db88438bd937f9 +Author: Simon Feltman +Date: Sun Dec 16 02:56:06 2012 -0800 + + pygtkcompat: Add Gtk.Window.set_geometry_hints which accepts keyword + arguments + + Monkey patch a keyword argument version of set_geometry_hints onto + Gtk.Window. + This version is compatible with pygtk and takes keywords instead of a + Gdk.Geometry and Gdk.GeometryMask. + + https://bugzilla.gnome.org/show_bug.cgi?id=694067 + + pygtkcompat/pygtkcompat.py | 44 + ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +commit 1ca0e142709843cdae9ca965dfa6cc292ef53ab5 +Author: Martin Pitt +Date: Tue Feb 26 10:09:47 2013 +0100 + + tests: Fix warning behaviour + + -Werror::* does not seem to do what it says on the tin, these + options are + ignored entirely apparently. Just keep -Wd to actually show all + warnings + including DeprecationWarning, which is hidden by default. + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e7ea6952c7a2d8da68ed8b66770d889cd756df9a +Author: Martin Pitt +Date: Tue Feb 26 08:49:10 2013 +0100 + + Ship pygobject.doap for autogen.sh + + https://bugzilla.gnome.org/show_bug.cgi?id=694591 + + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit 80ed803dab3ad914d7214a475e3c6ed743dfdccc +Author: Simon Feltman +Date: Tue Feb 19 03:07:19 2013 -0800 + + Fix crashes in various GObject signal handler functions + + Fix crashes in a large amount of signal handler functions exposed + on the GObject module. This is possible now that the underlying + GObject pointer is exposed to Python as a PyCapsule which marshaling + can handle. The following functions in the GObject module have been + verified: + + signal_handler_unblock + signal_handler_disconnect + signal_handler_is_connected + signal_stop_emission + signal_stop_emission_by_name + signal_has_handler_pending + signal_connect_closure + signal_connect_closure_by_id + signal_handler_find + signal_handlers_destroy + + https://bugzilla.gnome.org/show_bug.cgi?id=633927 + + gi/_gobject/gobjectmodule.c | 57 ++-------------- + gi/overrides/GObject.py | 158 + ++++++++++++++++++++++++++++++++++---------- + tests/test_signal.py | 121 ++++++++++++++++++++++++++++++++- + 3 files changed, 247 insertions(+), 89 deletions(-) + +commit e9c578c1d47375cb2249ccdd86873faad04b89e1 +Author: Olivier Crête +Date: Fri Sep 14 21:29:53 2012 -0400 + + pygi-closure: Protect the GSList prepend with the GIL + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=684060 + + gi/pygi-closure.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 6e0a32f6d9febbd782dc56a619974f009e79abd9 +Author: Simon Feltman +Date: Wed Feb 20 01:21:32 2013 -0800 + + generictreemodel: Fix bad default return type for get_column_type + + pygtkcompat/generictreemodel.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8ec5c335e223bdf00c7bb6c9aac3e7ac7791e38e +Author: Martin Pitt +Date: Tue Feb 19 12:23:13 2013 +0100 + + configure.ac: post-release bump to 3.7.91 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f2fb7f6142cd7112db9c2526d7f1c642a50cfc2a +Author: Martin Pitt +Date: Tue Feb 19 12:19:35 2013 +0100 + + Release 3.7.90 + + NEWS | 17 +++++++++++++++++ + configure.ac | 2 +- + 2 files changed, 18 insertions(+), 1 deletion(-) + +commit 840c871441cb215f24cc6e7ed26b9f38e5aad0df +Author: Simon Feltman +Date: Mon Feb 18 01:46:22 2013 -0800 + + overrides: Fix inconsistencies with drag and drop target list API + + Add support to Gtk.Widget.drag_dest_set_target_list and + Gtk.Widget.drag_source_set_target_list to accept iterables containing + mixed TargetEntry or a tuple of (target, flags, info). + Add support to Gtk.TreeView.enable_model_drag_source and + Gtk.TreeView.enable_model_drag_dest to accept a list of + Gtk.TargetEntry + items. + + https://bugzilla.gnome.org/show_bug.cgi?id=680640 + + gi/overrides/Gtk.py | 40 +++++++++++++++++++++++++++++----------- + tests/test_overrides_gtk.py | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 11 deletions(-) + +commit 62e94b0f87845bb7a1cfddf70dcdc89ff7a80bf7 +Author: Simon Feltman +Date: Mon Feb 18 03:19:34 2013 -0800 + + tests: Add test_marshaling_object to Makefile.am + + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit a10fb7216de57046d1ecacb73dd032eaadcbad09 +Author: Simon Feltman +Date: Wed Aug 29 03:46:23 2012 -0700 + + pygtkcompat: Add pygtk compatible GenericTreeModel implementation + + Add Python implementation of the GenericTreeModel that was + available in pygtk. The implementation attempts a better job + than the original at ref counting by guaranteeing no leaks + upon deletion of the model itself. Or by using the extra "node" + argument to the row_deleted signal. The model is available in + the pygtkcompat package directly as + pygtkcompat.generictreemodel.GenericTreeModel or with as + gtk.GenericTreeModel when pygtkcompat.enable_gtk() is set. + + Add file list and tree demos making use of GenericTreeModel + to gtk-demo. + + Auto-expand gtk-demo app tree to give a better overview of + the demos available. + + https://bugzilla.gnome.org/show_bug.cgi?id=682933 + + .../gtk-demo/demos/Tree View/treemodel_filelist.py | 234 ++++++++++++ + .../gtk-demo/demos/Tree View/treemodel_filetree.py | 279 ++++++++++++++ + demos/gtk-demo/gtk-demo.py | 2 +- + gi/pygtkcompat.py | 2 +- + pygtkcompat/Makefile.am | 1 + + pygtkcompat/generictreemodel.py | 420 + +++++++++++++++++++++ + pygtkcompat/pygtkcompat.py | 3 + + tests/Makefile.am | 1 + + tests/test_generictreemodel.py | 406 + ++++++++++++++++++++ + 9 files changed, 1346 insertions(+), 2 deletions(-) + +commit 871878c7a1e18fbdbf0744e0dd52cbcc6b610cdb +Author: Simon Feltman +Date: Mon Feb 18 02:54:14 2013 -0800 + + overrides: Add support for iterables besides tuples for TreePath + creation + + Allow Gtk.TreePath to accept any iterable for creation of the path. + + https://bugzilla.gnome.org/show_bug.cgi?id=682933 + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 93c1536b45f56c20b6d874c41c4cacd2b6cdca0a +Author: Simon Feltman +Date: Fri Feb 15 22:56:29 2013 -0800 + + Unify Python callable to GClosure GI marshaling code + + Add pygi_marshal_from_py_gclosure which can be used for direct + gi method + call args and vfunc out args. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 14 +----------- + gi/pygi-marshal-from-py.c | 55 + ++++++++++++++++++++++++++++------------------- + gi/pygi-marshal-from-py.h | 3 +++ + 3 files changed, 37 insertions(+), 35 deletions(-) + +commit 9e47afe459df942d9ffc4f71b39f1443976293df +Author: Simon Feltman +Date: Fri Feb 15 20:56:12 2013 -0800 + + Unify Python object to GValue GI marshaling code + + Add pygi_marshal_from_py_g_value which can be used for direct + gi method + call args and vfunc out args. The new method also adds an + "is_allocated" + parameter that will be used to fix leaks in the future. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 43 +++++++-------------------- + gi/pygi-marshal-from-py.c | 74 + ++++++++++++++++++++++++++++++++--------------- + gi/pygi-marshal-from-py.h | 5 ++++ + 3 files changed, 65 insertions(+), 57 deletions(-) + +commit 15cd7be5ad80e2411d6c13b04f5e2c33e4f5605e +Author: Simon Feltman +Date: Fri Feb 15 23:07:57 2013 -0800 + + Rename pygi_marshal_from_py_object to make it more explicit + + Rename pygi_marshal_from_py_object to pygi_marshal_from_py_gobject + to make it more explicit and give consistency with future refactoring. + + https://bugzilla.gnome.org/show_bug.cgi?id=693405 + + gi/pygi-argument.c | 2 +- + gi/pygi-marshal-from-py.c | 22 +++++++++++++--------- + gi/pygi-marshal-from-py.h | 6 +++--- + 3 files changed, 17 insertions(+), 13 deletions(-) + +commit 84103dfabd05742d1a18729663a609e9bf7c45f8 +Author: Niklas Koep +Date: Fri Feb 15 21:23:01 2013 -0800 + + Prefix __module__ attribute of function objects with gi.repository + + This allows gi module methods to work with pydoc and help(). + Additionally correct typo in two docstrings of the same module. + + Co-authored-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=693839 + + gi/overrides/__init__.py | 3 ++- + gi/types.py | 6 +++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +commit f6d4d2da676ae63d7a24dd172775b488ce665fe4 +Author: Jonathan Ballet +Date: Thu Feb 14 07:50:02 2013 +0100 + + configure.ac: only enable code coverage when available + + When building with an older gnome-common which does not yet provide + code + coverage support, disable it instead of breaking the configure script. + + https://bugzilla.gnome.org/show_bug.cgi?id=693328 + + configure.ac | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit 42cbff60e2032f715d9be6ab280954211899e03c +Author: Jonathan Ballet +Date: Tue Feb 12 23:03:00 2013 +0100 + + Correctly set properties on object with statically defined properties + + Fix failures in GObject.Object.set_properties() when used with + statically defined properties: + + * Calling the method was raising a "SystemError: error return without + exception set" since `result` was (most of the time) still NULL at the + end of pygobject_set_properties() + + * Calling the method with several properties would only set one of + the properties, since the function was exiting too early. + + Signed-off-by: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=693618 + + gi/_gobject/pygobject.c | 19 +++++++++++-------- + tests/test_gi.py | 6 ++++++ + 2 files changed, 17 insertions(+), 8 deletions(-) + +commit 2384769810a61d6ed08d8742b7ae976ebfaa8cb5 +Author: Martin Pitt +Date: Mon Feb 11 18:08:37 2013 +0100 + + autogen.sh: Use gnome-autogen.sh + + We depend on gnome-common now anyway, so use gnome-autogen.sh. This + will result + in a much better error message when gnome-common is not installed, + too. + + https://bugzilla.gnome.org/show_bug.cgi?id=693328 + + autogen.sh | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +commit c107bb1f9275a748b494d3f32818f227e07cadf0 +Author: Christoph Reiter +Date: Mon Feb 11 10:07:47 2013 +0100 + + GTK tests: Add and use context manager for realized widgets + + https://bugzilla.gnome.org/show_bug.cgi?id=693377 + + tests/test_overrides_gtk.py | 91 + +++++++++++++++++++++++++-------------------- + 1 file changed, 50 insertions(+), 41 deletions(-) + +commit e6670ee26b7682e6213f71deef813ce2e7cd6730 +Author: Martin Pitt +Date: Mon Feb 11 08:55:19 2013 +0100 + + _pygi_marshal_from_py_array: Fix uninitialized variable + + gi/pygi-marshal-from-py.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a37bfdcb3d9dcc8bcdd8126ad55d80fab4729c62 +Author: Christoph Reiter +Date: Mon Feb 11 08:34:42 2013 +0100 + + Skip some vfunc tests with gi 1.34 + + https://bugzilla.gnome.org/show_bug.cgi?id=693374 + + tests/test_object_marshaling.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit aff2ea1b681c3019f7dbdc841c2e33de78dbb88f +Author: Simon Feltman +Date: Sun Feb 10 13:40:45 2013 -0800 + + Remove workaround for g_struct_info_get_size reporting incorrect size + + Remove workaround for g_struct_info_get_size reporting incorrect size + for boxed GValues. Verified this now returns the correct size of 24. + + https://bugzilla.gnome.org/show_bug.cgi?id=622711 + + gi/pygi-boxed.c | 31 +++++++++++++------------------ + 1 file changed, 13 insertions(+), 18 deletions(-) + +commit 5efe2e5c8458d9f4d72329ea1209d96b5ebecfb4 +Author: Simon Feltman +Date: Mon Feb 4 20:50:10 2013 -0800 + + Fix reference leaks with transient floating objects + + Unify and refactor caller and callee GObject argument marshalers. + Combine code from the large switch statement used to marshal + arguments to and from vfuncs/closures with the marshalers used + for direct calls to gi functions. This fixes a reference leak + when marshalling GObjects to Python with transfer=full due to + the diverging code paths. + Replace ability in gobject_new_full to optionally sink objects + with ability to optionaly "steal" objects. This fits the premise + that binding layers should always sink objects initially. The + steal argument is then used for marshalling arguments which are + transfer=full. + Add hacks and comments to work around GTK+ bugs 693393 and 693400. + + https://bugzilla.gnome.org/show_bug.cgi?id=687522 + + gi/_gobject/gobjectmodule.c | 10 +++++-- + gi/_gobject/pygobject-private.h | 2 +- + gi/_gobject/pygobject.c | 45 ++++++++++++++++++++---------- + gi/_gobject/pygobject.h | 8 ++++-- + gi/pygi-argument.c | 52 +++++++++++++++++------------------ + gi/pygi-marshal-from-py.c | 61 + +++++++++++++++++++++++++++++++++++++---- + gi/pygi-marshal-from-py.h | 6 ++++ + gi/pygi-marshal-to-py.c | 45 +++++++++++++++--------------- + gi/pygi-marshal-to-py.h | 5 ++++ + tests/test_object_marshaling.py | 44 ++++++++++++++--------------- + 10 files changed, 181 insertions(+), 97 deletions(-) + +commit bd54b8ab30fc957849e7f57e9ee4c4b41aa37013 +Author: Simon Feltman +Date: Wed Feb 6 12:56:44 2013 -0800 + + tests: Fix spelling mistakes in new vfunc object marshalling tests + + tests/test_object_marshaling.py | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit cd96fd8b8e10add9890f36ec237bb78548de7002 +Author: Martin Pitt +Date: Tue Feb 5 07:53:38 2013 +0100 + + configure.ac: post-release bump to 3.7.6 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 92b1404e61f46348168f32720eff4a482531e5e3 +Author: Martin Pitt +Date: Tue Feb 5 07:46:46 2013 +0100 + + release 3.7.5.1 + + NEWS | 3 +++ + configure.ac | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +commit a3a30559240077194f23c4651d6f382fa59b7d63 +Author: Simon Feltman +Date: Mon Feb 4 15:16:37 2013 -0800 + + Fix API break with pygobject.h + + Move pygobject_new_full after everything in the public API table. + This fixes a break that went in along with bug 675726. + + https://bugzilla.gnome.org/show_bug.cgi?id=675726 + + gi/_gobject/gobjectmodule.c | 5 +++-- + gi/_gobject/pygobject.h | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +commit b3ca7e27494c35620995840d777037a097082661 +Author: Martin Pitt +Date: Mon Feb 4 19:53:26 2013 +0100 + + configure.ac: post-release bump to 3.7.6 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 77f638411314218748f349b337a36e2864eed1f4 +Author: Martin Pitt +Date: Mon Feb 4 19:37:14 2013 +0100 + + release 3.7.5 + + NEWS | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +commit 50da4fca1435f8c27072e15875227c5e7fb9b7e4 +Author: Simon Feltman +Date: Sun Feb 3 23:56:14 2013 -0800 + + Fix pointer cast warning that was missed in bug 675726 + + https://bugzilla.gnome.org/show_bug.cgi?id=675726 + + gi/_gobject/pygobject.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b31d8a952cd57dc92b06a381e054199660a2d570 +Author: Simon Feltman +Date: Thu Jan 31 02:35:36 2013 -0800 + + Move various signal methods from static bindings to gi and python + + Move disconnect, handler_is_connected, handler_block, handler_unblock, + and stop_emission from static to gi python overrides. + + https://bugzilla.gnome.org/show_bug.cgi?id=692918 + + gi/_gobject/pygobject.c | 90 + ------------------------------------------------- + gi/overrides/GObject.py | 44 +++++++++++++++++------- + tests/test_signal.py | 19 ++++++----- + 3 files changed, 42 insertions(+), 111 deletions(-) + +commit 3a6a4a7a21a0f5e851518b7912d8ff455aa3ede4 +Author: Paolo Borelli +Date: Fri Feb 1 21:09:26 2013 +0100 + + GLib overrides: Support unpacking 'maybe' variants + + Automatically unpack 'maybe' variants to None or to their actual value + as we do for other kind of variants + + https://bugzilla.gnome.org/show_bug.cgi?id=693032 + + gi/overrides/GLib.py | 5 +++++ + tests/test_overrides_glib.py | 8 ++++++++ + 2 files changed, 13 insertions(+) + +commit 9bc3e6807f6c14fb0e132a90ff8f9984229896f6 +Author: Mike Gorse +Date: Mon Jan 21 16:45:52 2013 -0600 + + Fix ref count leak when creating pygobject wrappers for input args + + Only sink input references for closures and vfuncs when transfer is + everything. This fixes cases where incoming floating references for + callbacks need to maintain their floating state throughout the + callback so they don't leak a strong reference. Re-introduce a + working "sink" argument to pygobject_new_full which allows for this. + Change existing callers to always sink in order maintain behavior. + + Co-Authored-By: Simon Feltman + + https://bugzilla.gnome.org/show_bug.cgi?id=675726 + + gi/_gobject/gobjectmodule.c | 5 +-- + gi/_gobject/pygobject.c | 7 ++-- + gi/_gobject/pygobject.h | 2 ++ + gi/pygi-argument.c | 13 +++---- + tests/test_object_marshaling.py | 76 + +++++++++++++++++++++++++++++++++++++---- + 5 files changed, 85 insertions(+), 18 deletions(-) + +commit a53a9176a3f87cfb26f3ad98ea746ada0f1a39fa +Author: Simon Feltman +Date: Thu Jan 31 01:50:44 2013 -0800 + + Add tests for signal stop_emission, disconnect, and + handler_is_connected + + Add tests for methods which will be moving from static bindings to gi + by using the new __gpointer__ attribute of GObject. + + https://bugzilla.gnome.org/show_bug.cgi?id=692918 + + tests/test_signal.py | 51 + ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 50 insertions(+), 1 deletion(-) + +commit df18f9cc3828d1bcf6b6cdf26af786fd9f36d77e +Author: Simon Feltman +Date: Wed Jan 30 21:37:07 2013 -0800 + + Add __gpointer__ property to GObject static binding + + Add access to the underlying C GObject pointer by wrapping it in a + PyCapsule/PyCPointer and exposing it as __gpointer__. + Add special case marshaling for gi parameters annotated as gpointer + to accept a PyCapsule and extract the underlying pointer as the arg. + This allows usage of methods like GObject.signal_handler_disconnect + which we can start replacing the static bindings with. + + https://bugzilla.gnome.org/show_bug.cgi?id=692918 + + gi/_gobject/pygobject.c | 11 +++++++++-- + gi/pygi-marshal-from-py.c | 6 +++++- + 2 files changed, 14 insertions(+), 3 deletions(-) + +commit 571e0cb246baa4ef7db179b20da6b325f358fe5b +Author: Simon Feltman +Date: Sun Jan 27 01:22:37 2013 -0800 + + Prefix names of typeless enums and flags for GType registration + + Prefix names given to g_flags_register_static and + g_enum_register_static + with "Py". This avoids conflicts with GTypes of the same name being + registered later by a library which does not provide a "get-type" + annotation. + + https://bugzilla.gnome.org/show_bug.cgi?id=692515 + + gi/gimodule.c | 10 ++++++++-- + tests/test_gi.py | 4 ++-- + 2 files changed, 10 insertions(+), 4 deletions(-) + +commit 97f48f5dcabc8dad4480727a78416b1c2a220777 +Author: Simon Feltman +Date: Wed Jan 30 04:35:32 2013 -0800 + + Add tests for vfunc object arguments and returns + + Add tests which use different combinations of floating, transfer full, + transfer none, and held wrapper as in, out, or return arguments + to vfuncs. + Most of these are marked as skip or expectedFailure due to various + bugs + noted on the tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=687522 + + gi/overrides/GObject.py | 15 +- + tests/test_object_marshaling.py | 540 + ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 550 insertions(+), 5 deletions(-) + +commit 73a83186329ede7702501d5bc49df269482461e4 +Author: Paolo Borelli +Date: Wed Jan 30 17:48:12 2013 +0100 + + Cosmetic fix to last patch + + gi/pygi-argument.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 9e0c41509d62e8df7d0d82608a8be75f3defe05c +Author: Chun-wei Fan +Date: Fri Jan 25 13:05:18 2013 +0800 + + gi/pygi-info.c, gi/pygi-repository.c: Deal with C99isms + + Drop the array forward static declarations. They are not necessary + and are not + valid in C89. + + Also move declarations of variables to the top of their respective + blocks. + + https://bugzilla.gnome.org/show_bug.cgi?id=692856 + + gi/pygi-info.c | 18 ++++++++++-------- + gi/pygi-repository.c | 2 -- + 2 files changed, 10 insertions(+), 10 deletions(-) + +commit 2e7c458ef6377a872043634b47737ef12eed744a +Author: Chun-wei Fan +Date: Fri Jan 25 13:00:48 2013 +0800 + + Move variable declaration to top of blocks (C99ism) + + Move variable declarations to the top of their respective blocks, + so that these + code will build under C89 compilers such as Visual C++. + + https://bugzilla.gnome.org/show_bug.cgi?id=692856 + + gi/pygi-argument.c | 10 ++++++---- + gi/pygi-closure.c | 23 +++++++++++++++-------- + gi/pygi-invoke.c | 3 ++- + gi/pygi-marshal-cleanup.c | 3 ++- + gi/pygi-property.c | 3 ++- + 5 files changed, 27 insertions(+), 15 deletions(-) + +commit 20fc5aa7514215fc7807adceb603d17f7943304a +Author: Chun-wei Fan +Date: Fri Jan 25 12:58:26 2013 +0800 + + gi/pygobject-external.h: Remove GCCism + + We can use G_GNUC_UNUSED from GLib that does the same purpose of + __attribute__ ( (unused)) when we are using a GCC that provides this. + + The GLib headers that defines that macro should have already been + included + before this header is included (due to use of gboolean). + + https://bugzilla.gnome.org/show_bug.cgi?id=692856 + + gi/pygobject-external.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5d2f453f3fdb167a4b4a833011ae777bfd228eb9 +Author: Martin Pitt +Date: Wed Jan 30 14:59:11 2013 +0100 + + tests: Update test_double() after e65c1248 + + Commit e65c1248 introduced support for NaN and ±inf as valid + float values, + rendering the "expect ValueError on 2*double" check broken. Just + remove it. + + tests/test_everything.py | 1 - + 1 file changed, 1 deletion(-) + +commit b8bf4ec6c2478275dc9c813946a90b82ded6d9ce +Author: Martin Pitt +Date: Wed Jan 23 07:14:16 2013 +0100 + + Do not immediately initialize Gdk and Gtk on import + + Raising an exception if Gdk/Gtk cannot be imported makes it + impossible to + merely import a module for e. g. nosetests without actually running + it. + + Programs who want to provide a proper error message should check + Gtk.initialized explicitly after importing. Check initialized + status in + Window.__init__() instead to provide a reasonably early error message + for most + programs. + + https://bugzilla.gnome.org/show_bug.cgi?id=692300 + + gi/overrides/Gdk.py | 2 -- + gi/overrides/Gtk.py | 5 +++-- + 2 files changed, 3 insertions(+), 4 deletions(-) + +commit 93d5cc2986cb3d3d979694b1beb1719d2d8fed53 +Author: Chun-wei Fan +Date: Fri Jan 25 12:49:18 2013 +0800 + + gi/overrides/Glib.py: Fix running on Windows/non-Unix + + The definition of self._signal_source uses a Unix-specific GLib + API, which + does not exist or have a direct equivilant on Windows. + + Only define and use that variable when we aren't on Windows. + + gi/overrides/GLib.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +commit e65c124893ceaa9c97eb4c8c743fbeb756b9a6e6 +Author: Martin Pitt +Date: Wed Jan 23 14:56:02 2013 +0100 + + Accept ±inf and NaN as float and double values + + Also fix the broken error message when a float value is out of range. + PyErr_Format() does not support float macros. + + https://bugzilla.gnome.org/show_bug.cgi?id=692381 + + gi/pygi-marshal-from-py.c | 37 +++++++++++++++++++------------------ + tests/test_gobject.py | 14 ++++++++++++++ + 2 files changed, 33 insertions(+), 18 deletions(-) + +commit a52245381fab3c2aebd330cc9c5e717a93c9607d +Author: Martin Pitt +Date: Wed Jan 23 14:28:42 2013 +0100 + + Fix repr() of GLib.Variant + + When using a standard constructor like GLib.Variant.new_*(), the + object does + not have a format_string property, and previously repr() would + crash. Fall back + to get_type_string() instead. + + Also drop the unintended type annotations in repr(). + + gi/overrides/GLib.py | 6 +++++- + tests/test_overrides_glib.py | 15 ++++++++++++++- + 2 files changed, 19 insertions(+), 2 deletions(-) + +commit 2270cf15012005362dc47456213c5d9e7f6ed28a +Author: Martin Pitt +Date: Wed Jan 23 14:14:29 2013 +0100 + + Fix gtk-demo for Python 3 + + It was crashing with + + package = __import__(packagename, globals(), locals(), + [modulename], -1) + ValueError: level must be >= 0 + + Using level zero works with both Python 2 and 3. + + demos/gtk-demo/gtk-demo.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b24d07577da1e17c8e27f758fc1a23d7f2d0f668 +Author: Colin Walters +Date: Tue Jan 22 10:49:57 2013 -0500 + + build: Add autogen.sh to EXTRA_DIST + + So downstreams that patch the autotools can use it. + + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit ed7fb99efa81854d947ae548d41a03f5275c5884 +Author: Martin Pitt +Date: Thu Jan 17 08:23:02 2013 +0100 + + Define GObject.TYPE_VALUE gtype constant + + gi/overrides/GObject.py | 4 +++- + tests/test_gobject.py | 4 ++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +commit fd32acdd97f49f086a8ad5cf2b65862c4e6ccc44 +Author: Olivier Crête +Date: Mon Sep 17 15:37:04 2012 -0400 + + gobject: Go through introspection on property setting + + Consider introspected properties in object.set_property(). + + https://bugzilla.gnome.org/show_bug.cgi?id=684062 + + gi/_gobject/pygobject.c | 18 +++++++++++++++++- + tests/test_properties.py | 13 ++++++++++--- + 2 files changed, 27 insertions(+), 4 deletions(-) + +commit 9a2060f26c2cc2f9ef79ab6fb9f512c317004856 +Author: Mike Gorse +Date: Tue Jan 15 20:04:46 2013 -0600 + + Clean up caller-allocated GValues and their memory + + When space for a GValue is allocated by the caller (as in + gtk_tree_model_get_value), we need to free the space allocated for the + value along with its contents. The GValue is not needed after + Pyg_value_as_pyobject is called, so call _cleanup_caller_allocates and + have it unset the value and deallocate the memory. + + https://bugzilla.gnome.org/show_bug.cgi?id=691820 + + gi/pygi-marshal-cleanup.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +commit 45b7975d0a3d78f01f1112ae7b3f4208f15694d8 +Author: Dmitry Shachnev +Date: Wed Jan 16 13:44:42 2013 +0400 + + tests: define correct unittest.skipIf for python 2.6 + + tests/runtests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4706cd686ea1b25260c9ecc77abd324d6e4cf505 +Author: Martin Pitt +Date: Wed Jan 16 09:17:13 2013 +0100 + + tests: More robust tree view realization + + With current GNOME git head, the Gtk.TreeViews were not realized + enough any + more to receive property values. Put them into a Gtk.Dialog now and + show it to + ensure that they are realized. + + tests/test_overrides_gtk.py | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +commit 90c6f596df2a96f9c8059ae9157bc467a80b7574 +Author: Martin Pitt +Date: Tue Jan 15 10:42:49 2013 +0100 + + Drop deprecated g_thread_create() + + Replace with g_thread_new(). This is available with glib >= 2.32, + and we + already require >= 2.34. + + tests/test-thread.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 98504273dead9eade6e53c2297bcaec7bea6265a +Author: Martin Pitt +Date: Tue Jan 15 10:37:52 2013 +0100 + + Drop usage of deprecated GStaticPrivate + + Replace with GPrivate. + + gi/_gobject/gobjectmodule.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 655e2eece14f5de3baf4505f524d17484b8b5a75 +Author: Martin Pitt +Date: Tue Jan 15 10:29:47 2013 +0100 + + Don't call g_type_init() with glib >= 2.35.x + + This fixes a deprecation warning. + + gi/_gobject/gobjectmodule.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 206e736380ba798c68de09f661d75c8e27451117 +Author: Martin Pitt +Date: Tue Jan 15 09:47:11 2013 +0100 + + Use GNOME_COMPILE_WARNINGS from gnome-common + + As we are now using gnome-common anyway for the code coverage macro, + also use + GNOME_COMPILE_WARNINGS, and only manually specify the extra options + that we + want beyond that. + + This also enables -Wstrict-prototypes. + + configure.ac | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +commit 137679426ff39507e15f08e9e6428d851fee06b7 +Author: Martin Pitt +Date: Tue Jan 15 09:46:01 2013 +0100 + + Fix function prototypes and static functions + + These cause errors/warnings with -Wstrict-prototypes. + + gi/_glib/pyglib-python-compat.h | 2 ++ + gi/pygi-foreign.c | 2 +- + gi/pygi-marshal-from-py.c | 4 ++-- + gi/pygi-marshal-to-py.c | 4 ++-- + gi/pygi-source.c | 2 +- + gi/pygi-source.h | 2 +- + 6 files changed, 9 insertions(+), 7 deletions(-) + +commit d47927f1701a11aec8566425f22688c5df73d7f2 +Author: Martin Pitt +Date: Mon Jan 14 17:38:23 2013 +0100 + + configure.ac: post-release bump to 3.7.5 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit bd6da84a4aec74e47f5d70e8ed18695c37e746c6 +Author: Martin Pitt +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 + + 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 +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 +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 +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 +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 +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 +Date: Fri Jan 11 15:41:27 2013 +0100 + + Support setting string fields in structs + + Co-Authored-By: Martin Pitt + + 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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 + + gi/_gobject/pygtype.c | 60 + ++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_everything.py | 22 ++++++++++++++++++ + 2 files changed, 82 insertions(+) + +commit 2089dbb117bae769b0303411c2630b6f86dc7d2d +Author: Marko Lindqvist +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 +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 +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 +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 + + gi/overrides/Gtk.py | 2 +- + tests/test_overrides_gtk.py | 7 +++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit 53bc12a87da824cbfb006a4fd65731edec12ecc7 +Author: Mike Gorse +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 +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 + + gi/pygi-marshal-from-py.c | 6 ++++++ + tests/test_gi.py | 12 ++++++++++++ + 2 files changed, 18 insertions(+) + +commit 231d5a7cfc73518b4e2b0c926d4c1ce9a804797e +Author: Simon Feltman +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 +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 +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 +Date: Mon Dec 17 23:18:31 2012 +0100 + + release 3.7.3 + + NEWS | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit a242f02823a63c9dca5d0b1ce84b031221053690 +Author: Martin Pitt +Date: Mon Dec 17 23:11:29 2012 +0100 + + Add (failing) tests for callbacks with out arguments + + Most of these fail and need marshalling fixes. + + tests/test_gi.py | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +commit 449b1ef0d94450c1e457770a093abd6d6c9e6291 +Author: Martin Pitt +Date: Mon Dec 17 22:50:59 2012 +0100 + + Add tests for internal API + + These cover functions like pygobject_new(), pyg_value_from_pyobject() + and + pyg_value_as_pyobject() that are wrapped by testhelpermodule.c. With + that these + functions can be tested in isolation without the whole GI stack + around them. + + tests/Makefile.am | 1 + + tests/test_internal_api.py | 73 + ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 74 insertions(+) + +commit e44312139426f51e576ef9e880819542cc224383 +Author: Martin Pitt +Date: Mon Dec 17 18:02:15 2012 +0100 + + Add support for caller-allocated GArray out arguments + + https://bugzilla.gnome.org/show_bug.cgi?id=690041 + + gi/pygi-cache.c | 2 +- + gi/pygi-invoke.c | 57 + ++++++++++++++++++++++++++++++-------------------------- + tests/test_gi.py | 5 +++-- + 3 files changed, 35 insertions(+), 29 deletions(-) + +commit f262320ac22b48a9d007c425633f3ca426b7fb4a +Author: Martin Pitt +Date: Mon Dec 17 16:18:24 2012 +0100 + + Add (failing) test for caller-allocated GArray return value + + Call new GIMarshallingTests.garray_utf8_full_out_caller_allocated() + function + which reproduces https://bugzilla.gnome.org/show_bug.cgi?id=690041. + + The test is failing and causing a segfault right now, so disable it + until this + actually works. + + tests/test_gi.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 1cb4c30c3cf19690210010d39b6272965f489c58 +Author: Martin Pitt +Date: Mon Dec 17 15:56:44 2012 +0100 + + GLib overrides: Avoid calling deprecated GLib.unix_signal_add_full() + + glib 2.35.x fixed the API to be GLib.unix_signal_add(). Call the + modern API if + available, but fall back to GLib.unix_signal_add_full() until we + depend on glib + 2.36. + + gi/overrides/GLib.py | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +commit 945263a89c3adee61f95d4211cf13b254ad6d51f +Author: Martin Pitt +Date: Fri Nov 30 14:17:18 2012 +0100 + + Re-support calling GLib.io_add_watch with an fd or Python file + + This does not strictly adhere to the GLib API, but it's very + convenient and + unlike the other modes, does not change the number or order of + arguments. So + let's keep support for this and drop the deprecation warning. + + gi/overrides/GLib.py | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +commit 263b9f97e748746e1d26847a82a4d6e53a42798a +Author: Martin Pitt +Date: Fri Nov 30 09:04:20 2012 +0100 + + Robustify test_glib.TestGLib.test_io_add_watch_pyfile + + Use a longer timeout to avoid races on slow architectures, and cut + the main + loop as soon as we received all expected events. + + tests/test_glib.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 8e4e822cb273db4eb7e6e40f4739eeebee00798a +Author: Martin Pitt +Date: Fri Nov 30 08:44:56 2012 +0100 + + test_overrides_gtk: Ignore GVFS warnings from FileChooserDialog + + Do not cause GVFS warnings from Gtk.FileChooserDialog (which may + concern + unavailable monitor backends in the test environment) to fail + the tests. + + tests/test_overrides_gtk.py | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +commit d47283936b4c0b5e8b6ede8886c4badbf6d6e694 +Author: Martin Pitt +Date: Thu Nov 29 16:45:49 2012 +0100 + + pygtkcompat: Work around IndexError on large flags + + On 32 bit systems pygtkcompat currently fails with + + File "pygtkcompat/pygtkcompat.py", line 74, in _install_enums + name = flag.value_names[-1].replace(modname + '_', '') + IndexError: cannot fit 'int' into an index-sized integer + + on 32 bit systems as some flags in Gdk are too large to fit into a + 32 bit + "long". Work around this crash until this gets fixed properly + (marked as + FIXME). + + pygtkcompat/pygtkcompat.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 3fa31b1a7936c556e76bd8a42030567c6a867e0d +Author: Martin Pitt +Date: Thu Nov 29 14:11:29 2012 +0100 + + Fix pyg_value_from_pyobject() range check for uint + + We cannot use PYGLIB_PyLong_AsLong() for the range check, as on 32 + bit machines + this overflows large uints. Use PyLong_AsLongLong() separately to + check for + negative values, and PyLong_AsUnsignedLong() for the actual + conversion. + + gi/_gobject/pygtype.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +commit 05d767a602571805e80099f1db47ad4164575c53 +Author: Martin Pitt +Date: Thu Nov 29 13:30:56 2012 +0100 + + Fix tests to work with g-i 1.34.2 + + Do not try to call GIMarshallingTests API which isn't present + when running + against g-i 1.34.2. This can be dropped when the g-i dependency gets + bumped to + 1.35.x. + + tests/test_gi.py | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit a107c928ef85b4e3b9075a408774b74879586029 +Author: Martin Pitt +Date: Thu Nov 29 13:13:14 2012 +0100 + + Fix wrong refcount for GVariant property defaults + + Drop the bogus DECREF for the GVariant default argument, as we need + to keep it + around in the class. Otherwise the refcount drops to zero, and + the next + garbage collection run causes segfaults. + + https://bugzilla.gnome.org/show_bug.cgi?id=689267 + + gi/_gobject/gobjectmodule.c | 1 - + 1 file changed, 1 deletion(-) + +commit 9b7dd1318cf540d5f8d03655da03534ed72707ec +Author: Martin Pitt +Date: Thu Nov 29 11:44:22 2012 +0100 + + test_gi: Fix TestFilename failure under C locale + + tests/test_gi.py | 1 + + 1 file changed, 1 insertion(+) + +commit 37ab227555ba8628b4fa99aa286bd046208745ed +Author: Martin Pitt +Date: Thu Nov 29 11:16:26 2012 +0100 + + Fix array arguments on 32 bit + + In _pygi_argument_from_object() we never put the actual element + GType into the + constructed array. The array contains GIArguments, or bytes in the + case of + passing a string as an array. + + This happened to work on 64 bit machines where GIArgument and char* + have the + same size, but not on 32 bit machines + (test_gi.TestPropertiesObject.test_strv + fails there). + + gi/pygi-argument.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 7bd852fc82f92dac8723e18b61a56ed1b1a1b81c +Author: Martin Pitt +Date: Thu Nov 29 10:20:27 2012 +0100 + + test_gi: Disable failing check in test_module_name() + + When calling this under some conditions, such as + + TEST_NAMES='test_thread test_gi.TestOverrides' + + then the module name of GObject.InitiallyUnowned comes out as + "importlib._bootstrap" instead of "gi.repository.GObject". To be + investigated. + Add a couple of other tests to ensure that it is not broken in + general. + + tests/test_gi.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit 94a6cc93a104b22dcee2ac73cae36b83a4b5d9c1 +Author: Martin Pitt +Date: Thu Nov 29 09:40:32 2012 +0100 + + test_gdbus: Drop failure if timeout=0 works differently + + In some test environments we do not actually get a timeout exceptions + with + timeout=0, but a different error message. So only ensure that we + get the right + kind of error. + + tests/test_gdbus.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit c3b2f5fee573aa03a8a9563efbbbc1bc4fa25da7 +Author: Martin Pitt +Date: Thu Nov 29 09:29:05 2012 +0100 + + test_glib: Drop some assumptions about XDG dirs + + Some directories do not exist in minimal test environments, and this + is not + important for testing that calling these GLib functions works. + + tests/test_glib.py | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit e45c690bc83b6d513887649de88965a9752e316d +Author: Martin Pitt +Date: Wed Nov 28 12:20:31 2012 +0100 + + Add backwards compatible API for GLib.unix_signal_add_full() + + This was renamed to GLib.unix_signal_add() in + http://git.gnome.org/browse/glib/commit/?id=fca30c3e165 + + Provide a backwards compatible shim with a deprecation message. + + gi/overrides/GLib.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 00b9ea32d766ae486249f402d9dee511fd9f53a9 +Author: Martin Pitt +Date: Mon Nov 26 08:11:36 2012 +0100 + + Drop MININT64/MAXUINT64 workaround + + g-i 1.34.2 properly handles 64 bit constants now, so bug 685022 has + been fixed + properly now. Drop the workaround in the overrides to manually + set these + constants. + + gi/overrides/GLib.py | 7 ------- + 1 file changed, 7 deletions(-) + +commit d16604f64d25d18409270d7537fc993113b65c19 +Author: Simonas Kazlauskas +Date: Fri Nov 23 19:57:56 2012 +0200 + + Fix maximum and minimum ranges of TYPE_(U)INT64 properties + + In corner case where properties use values 2 ** 62 < ±x < 2 ** 63 for + TYPE_INT64 and 2 ** 63 < x < 2 ** 64 for TYPE_UINT64 they will raise + warnings even tough values are valid. + + https://bugzilla.gnome.org/show_bug.cgi?id=688949 + + gi/_gobject/propertyhelper.py | 6 +++--- + tests/test_properties.py | 11 ++++------- + 2 files changed, 7 insertions(+), 10 deletions(-) + +commit 93e9e309d8ba54884881cfca203e8bc355c2727e +Author: Martin Pitt +Date: Wed Nov 21 12:58:07 2012 +0100 + + Test virtual methods with in and out arguments + + ... and both caller and callee out argument allocation. + + This came up in https://bugzilla.gnome.org/show_bug.cgi?id=688783 + + tests/test_gi.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +commit 25a9cfb043448efbab9168ef66f852cc34b9909b +Author: Martin Pitt +Date: Tue Nov 20 07:00:44 2012 +0100 + + Ship pygi-convert.sh in tarballs + + https://bugzilla.gnome.org/show_bug.cgi?id=688697 + + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit 4a8d31e6f56a3f1360bdb880ffd9a6eb139c02d8 +Author: Martin Pitt +Date: Mon Nov 19 15:25:38 2012 +0100 + + Post-release version bump to 3.7.3 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d0ed62afbc4cada0bf6abc4f8754e5a8d73036e4 +Author: Martin Pitt +Date: Mon Nov 19 15:13:28 2012 +0100 + + release 3.7.2 + + NEWS | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +commit 29dc7425dd7584411b52ef07b50f929ed119a000 +Author: Martin Pitt +Date: Mon Nov 19 14:37:02 2012 +0100 + + Fix distcheck + + Commit e617f76e forgot to rename the file in EXTRA_DIST + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 567aae6e7c56bb89f53fcfccb1b0bc732f85b847 +Author: Martin Pitt +Date: Mon Nov 19 14:34:13 2012 +0100 + + tests: Fix unicode vs. str issues in Python 2 + + Some of the tests assumed a system default encoding of UTF-8, which + is not true + in Python 2 unless pygtkcompat is imported. Commit e617f76 uncovered + this. + + tests/test_gi.py | 8 ++++---- + tests/test_iochannel.py | 16 +++++++++------- + 2 files changed, 13 insertions(+), 11 deletions(-) + +commit 509e5ac1a6dd8504e89c33c559fe4f72156a1ddf +Author: Martin Pitt +Date: Mon Nov 19 14:20:56 2012 +0100 + + tests: Fix previous commit to fail properly on test failures + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e617f76e5b0c301c3ae92e1091aa86792de4d8e8 +Author: Martin Pitt +Date: Mon Nov 19 14:09:14 2012 +0100 + + tests: Run pygtkcompat tests separately + + pygtkcompat changes the global namespace, in particular patching + Gdk and Gtk + overrides. Run the tests in a separate process so that the main + tests are not + potentially affected by the pygtkcompat test. + + runtests.py runs all tests/test_*.py by default, so rename to + compat_test_pygtk.py and run that explicitly after successfully + running the + main tests. + + See https://bugzilla.gnome.org/show_bug.cgi?id=688219 + + tests/Makefile.am | 3 + + tests/compat_test_pygtk.py | 147 + +++++++++++++++++++++++++++++++++++++++++++++ + tests/test_pygtkcompat.py | 147 + --------------------------------------------- + 3 files changed, 150 insertions(+), 147 deletions(-) + +commit 8180b8092f99b7c9f0dee1742418efdbd23ab330 +Author: Simon Feltman +Date: Thu Nov 15 02:51:52 2012 -0800 + + Move pygtkcompat into sibling package of gi + + Move the pygtkcompat module out of the gi package and into + a sibling package as follows: + + pygobject/ + gi/ + pygtkcompat/ + + This allows for pygtkcompat to grow without affecting the gi package. + Add deprecation message to gi/pygtkcompat.py + + https://bugzilla.gnome.org/show_bug.cgi?id=688219 + + Makefile.am | 2 +- + configure.ac | 1 + + gi/pygtkcompat.py | 524 + +++------------------------------------------ + pygtkcompat/Makefile.am | 15 ++ + pygtkcompat/__init__.py | 20 ++ + pygtkcompat/pygtkcompat.py | 501 + +++++++++++++++++++++++++++++++++++++++++++ + tests/test_pygtkcompat.py | 6 +- + 7 files changed, 565 insertions(+), 504 deletions(-) + +commit f736694d09e9d0fca4769d9f1f34ec34e6354d87 +Author: Martin Pitt +Date: Mon Nov 19 13:59:20 2012 +0100 + + Bump g-i dependency to >= 1.34.2 + + We need this for updated GLib annotations and new test API. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f6c994c76cd8010460b76bf455e1a341348d735b +Author: Martin Pitt +Date: Mon Nov 19 10:39:26 2012 +0100 + + test_gi: Fix failing tests with g-i 1.34.x + + Skip tests which require g-i test API from 1.35.x when building + with g-i + 1.34.x. + + tests/test_gi.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 8ce0d028fe79e2ce52cfecbb682afba6651a7a70 +Author: Martin Pitt +Date: Wed Nov 14 11:57:21 2012 +0100 + + test_gi: Add tests for type "filename" + + tests/test_gi.py | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +commit 3408a151e49d9520f54ad9bc04f620c7777125ec +Author: Martin Pitt +Date: Wed Nov 14 11:09:33 2012 +0100 + + Drop foreign GVariant registration/support + + This is dead code. We have tests for GVariant in and out method + arguments, + callback arguments and return values, properties, etc to ensure that + this stays + working. + + gi/Makefile.am | 2 -- + gi/pygi-foreign-gvariant.c | 63 + ---------------------------------------------- + gi/pygi-foreign-gvariant.h | 41 ------------------------------ + gi/pygi-foreign.c | 8 +----- + 4 files changed, 1 insertion(+), 113 deletions(-) + +commit 47c46d847bb69ebc139d5e0b6c609da6f27201f2 +Author: Martin Pitt +Date: Wed Nov 14 10:33:24 2012 +0100 + + test_properties.py: Fix PEP-8 errors + + tests/test_properties.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 78f49e6253500bfa382ce6c07412613d8f7f9d7f +Author: Martin Pitt +Date: Wed Nov 14 10:14:36 2012 +0100 + + Add support for GVariant properties defined in Python + + gi/_gobject/gobjectmodule.c | 13 +++++++ + gi/_gobject/propertyhelper.py | 11 ++++-- + tests/test_properties.py | 81 + +++++++++++++++++++++++++++++++++++++------ + 3 files changed, 91 insertions(+), 14 deletions(-) + +commit f3b77f4304be20b7422c262b973f3eeb540c4bf6 +Author: Martin Pitt +Date: Wed Nov 14 09:33:43 2012 +0100 + + pyg_value_from_pyobject(): Simplify GVariant type check + + Use pyg_type_from_object_strict() instead of the much more expensive + and local + pyg_get_gvariant_type(). + + gi/_gobject/pygtype.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +commit 0c0fb8ef88a2c61cf95cd1cb96f6d5f296cad5fc +Author: Martin Pitt +Date: Wed Nov 14 09:27:42 2012 +0100 + + test_everything: Add test for callback returning wrong type + + This covers the "expected a GVariant, got something else" check in + pyg_value_from_pyobject(). + + tests/test_everything.py | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +commit 84db7109dfbaf443758a5a4871ee385686d2703d +Author: Martin Pitt +Date: Wed Nov 14 08:42:53 2012 +0100 + + Add type checking to GVariant argument assignment + + gi/pygi-argument.c | 7 ++++++- + tests/test_gi.py | 5 ++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +commit e944caf5ff53143a98dd4a5578530996358013ec +Author: Martin Pitt +Date: Wed Nov 14 08:22:35 2012 +0100 + + Add support for GVariant properties defined in C + + Note that trying to assign a non-GVariant value to a GVariant property + currently crashes. + + gi/pygi-property.c | 6 +++++- + tests/test_gi.py | 21 +++++++++++++++++++++ + 2 files changed, 26 insertions(+), 1 deletion(-) + +commit 614cc9594cb34d92a6d4b00773427d4fb023c65e +Author: Martin Pitt +Date: Wed Nov 14 07:09:58 2012 +0100 + + test_unknown.py: Check property interface + + NB that the property implementation in test-unknown.c does not + actually do + anything, we just want to assert that the properties are properly + registered. + + tests/test_unknown.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 9d7771affcf788d251cced65da56fc2773a278b3 +Author: Martin Pitt +Date: Wed Nov 14 07:01:24 2012 +0100 + + Fix previous commit for Python 2 + + gi/pygi-foreign-cairo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 997d4e70b2793039d916acf8921087576622152e +Author: Martin Pitt +Date: Wed Nov 14 06:57:04 2012 +0100 + + pygi-foreign-cairo.c: Use official py3cairo API + + Do not clobber py3cairo's Pycairo_CAPI global variable, and use + import_cairo() + instead of our own code. + + gi/pygi-foreign-cairo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit cec5d1a55347b81c1ae4ddc47ea2b4fbf964d239 +Author: Martin Pitt +Date: Wed Nov 14 06:47:23 2012 +0100 + + Drop dead code from pygi-callbacks.[hc] + + _pygi_create_callback() and _pygi_scan_for_callbacks() are not + used anywhere. + _pygi_destroy_notify_create() fits better in pygi-marshal-from-py.c, + so move it + there, and drop pygi-callbacks.[hc] completely. + + gi/Makefile.am | 2 - + gi/pygi-callbacks.c | 217 + ---------------------------------------------- + gi/pygi-callbacks.h | 48 ---------- + gi/pygi-marshal-from-py.c | 44 ++++++++++ + gi/pygi-private.h | 1 - + 5 files changed, 44 insertions(+), 268 deletions(-) + +commit 55070cc9c98993ccda7ebcb05783fad182b2eb11 +Author: Carlos Garnacho +Date: Tue Nov 13 18:24:28 2012 +0100 + + Fix marshalling of arrays of struct pointers to Python + + Fill in the pointer to the struct, not the pointer to the + array position. This makes the GdkAtom** argument in + gtk_clipboard_wait_for_targets() work. + + https://bugzilla.gnome.org/show_bug.cgi?id=678620 + + gi/pygi-marshal-to-py.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit fc021516552b1720bacc4afe6b7a610c413194c4 +Author: Martin Pitt +Date: Wed Nov 14 06:27:17 2012 +0100 + + test_atoms.py: Add test for out array + + This reproduces https://bugzilla.gnome.org/show_bug.cgi?id=678620 + + tests/test_atoms.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit e2790d22610aae773635d4caef2458082a307283 +Author: Martin Pitt +Date: Tue Nov 13 16:38:36 2012 +0100 + + Fix Gdk.Atom str()/repr() fallback + + Fix regression in commit 6713618: If an atom does not have a name, + do not + recursively call our own str()/repr() methods, but just print + "Gdk.Atom". + + gi/overrides/Gdk.py | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 9879fd41a7d8d72f8db9cadf5b1ee29fc4d5d6bf +Author: Martin Pitt +Date: Tue Nov 13 13:16:14 2012 +0100 + + test_gi: Stop using GLib.bytes.unref_to_array() + + This method isn't safe for GI, and should be (skip)ed. Use get_data() + instead + which is safe and works fine. + + See https://bugzilla.gnome.org/show_bug.cgi?id=688242 + + tests/test_gi.py | 6 ------ + 1 file changed, 6 deletions(-) + +commit 671361841de797ef62b59d1d7568fc3d431898c7 +Author: Martin Pitt +Date: Tue Nov 13 12:56:11 2012 +0100 + + Fix Gdk.Atom to have a proper str() and repr() + + Gdk.Atom is not proper GType'd class, so we cannot override the + whole class. + Just override its __str__() and __repr__() methods so that printing + atoms shows + something sensible. For nameless/invalid atoms, fall back to the old + output to help with debugging. + + https://bugzilla.gnome.org/show_bug.cgi?id=678620 + + gi/overrides/Gdk.py | 21 +++++++++++++++++++++ + tests/test_atoms.py | 12 ++++++++++++ + 2 files changed, 33 insertions(+) + +commit 56e62858e9c2bdde3186f5cf4e83be94fb4e5306 +Author: Simon Feltman +Date: Tue Nov 13 02:53:34 2012 -0800 + + Make sure g_value_set_boxed does not cause a buffer overrun with + GStrvs + + Add NULL terminator to gchar** passed to g_value_set_boxed to + make sure it does not overrun memory in pygi_set_property_value_real. + Add MALLOC_CHECK_=3 to "make check" which prints an error and aborts + in these cases. + + https://bugzilla.gnome.org/show_bug.cgi?id=688232 + + gi/pygi-property.c | 8 ++++++-- + tests/Makefile.am | 1 + + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit ca11ec124fdd3fb2b67efdeb3ac93aaeb8b3fd83 +Author: Martin Pitt +Date: Mon Nov 12 08:35:28 2012 +0100 + + types.py: Fix PEP-8 violation + + gi/types.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit df589458358d7e7bf178dff4e6ad937a70f806e3 +Author: Simon Feltman +Date: Sun Nov 11 22:26:19 2012 -0800 + + Fix leaks with GValues holding boxed and object types + + Expose read access to PyGIBoxed.free_on_dealloc. + Add GObject.Value.__del__ override and call unset() to + correctly free reference counts. + + https://bugzilla.gnome.org/show_bug.cgi?id=688137 + + gi/overrides/GObject.py | 9 +++++++++ + gi/pygi-boxed.c | 12 ++++++++++++ + tests/test_gi.py | 2 -- + 3 files changed, 21 insertions(+), 2 deletions(-) + +commit c01c95b9fb3d726385efac945f6d1270ae65d109 +Author: Simon Feltman +Date: Sun Nov 11 19:46:15 2012 -0800 + + Add expectantly failing unittests for GValue boxed/object leaks + + https://bugzilla.gnome.org/show_bug.cgi?id=688137 + + tests/test_gi.py | 80 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + +commit 13629f5a9c9a7022f3521a3616d9ce8fa4a6161b +Author: Simon Feltman +Date: Thu Aug 16 15:09:08 2012 -0700 + + Add doc strings showing method signatures for gi methods + + Add signature based doc string to all methods pulled in from + introspection. For example: Gtk.SpinButton.get_icon_area.__doc__ + get_icon_area(self, icon_pos:Gtk.EntryIconPosition) -> + icon_area:cairo.RectangleInt + + https://bugzilla.gnome.org/show_bug.cgi?id=681967 + + gi/overrides/GIMarshallingTests.py | 1 + + gi/pygi-info.c | 103 + +++++++++++++++++++++++++++++++++---- + gi/pygi-type.c | 60 +++++++++++++++++++++ + gi/pygi-type.h | 1 + + gi/types.py | 92 + ++++++++++++++++++++++++++------- + tests/test_gi.py | 30 +++++++++++ + 6 files changed, 259 insertions(+), 28 deletions(-) + +commit 7b7277f3cc099280f8e2d6cf6693490290fedc24 +Author: Simon Feltman +Date: Fri Nov 9 19:17:03 2012 -0800 + + Set Property instance doc string and blurb to getter doc string + + Assign Property getter __doc__ strings or explicit blurb parameters + to the Property instances __doc__ attribute. This clobbers the + default Property classes lengthy and unhelpful doc string in the case + of instances. + + https://bugzilla.gnome.org/show_bug.cgi?id=688025 + + gi/_gobject/propertyhelper.py | 10 +++++++--- + tests/test_properties.py | 14 ++++++++++---- + 2 files changed, 17 insertions(+), 7 deletions(-) + +commit c5343d329ebb452d97afac30e4120ebab8477556 +Author: Martin Pitt +Date: Mon Nov 12 07:47:02 2012 +0100 + + tests: Fix for Python 2 + + Add quirks for Python 2's string handling, and disable the + Everything.test_array_gint8_in() as there seems to be no way of + creating a byte + array in Python 2. + + tests/test_everything.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 964f33ca3a74bfb7d850f136d0844ac1551d36e9 +Author: Martin Pitt +Date: Sat Nov 10 15:52:15 2012 +0100 + + test_everything: Add tests for more Regress data and container types + + Add more tests for Regress' data and container type test API. + + This detects a number of bugs, which have been marked as expected + failure, or + disabled completely for the cases where they cause crashes: + + * unsigned enums with values >= 0x80000000 do not work + * nested ghashes in return values do not work + * array length arguments in callbacks are passed instead of + suppressed + + tests/test_everything.py | 156 + ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 154 insertions(+), 2 deletions(-) + +commit 476e29d1ba3eda92cc021710017bce4ec252e5b5 +Author: Martin Pitt +Date: Fri Nov 9 18:45:22 2012 +0100 + + test_everything: Add tests for Regress type tests + + Add tests for all the data type handling tests of g-i's Regress + module. + + tests/test_everything.py | 183 + +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 183 insertions(+) + +commit 0d7974396e8379b518403983d9d13629066680d7 +Author: Martin Pitt +Date: Fri Nov 9 18:44:50 2012 +0100 + + Add GObject.G_MINSSIZE + + gi/_gobject/gobjectmodule.c | 1 + + gi/overrides/GObject.py | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +commit b800a6903300dbe9435ed8eb3677eb9c0536ec31 +Author: Martin Pitt +Date: Fri Nov 9 16:02:00 2012 +0100 + + Fix marshalling of GByteArrays + + In _pygi_marshal_from_py_array(), set the array length after copying + the data + in the GI_TYPE_TAG_UINT8 case (which applies for GByteArrays), + otherwise it + will always come out as zero length. + + Enable the TestGByteArray.test_bytearray_none_in() test case as that + works now. + + gi/pygi-marshal-from-py.c | 1 + + tests/test_gi.py | 3 +-- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit fa568949c46dd4b537357f1af74d1f675294b760 +Author: Martin Pitt +Date: Fri Nov 9 15:23:37 2012 +0100 + + Fix marshalling of ssize_t to smaller ints + + Add missing marshalling cases for (u)int8 and (u)int16. This fixes the + TestArray.test_array_in test, so drop the expected failure. + + gi/pygi-marshal-from-py.c | 30 +++++++++++++++++++++++++++++- + tests/test_gi.py | 2 -- + 2 files changed, 29 insertions(+), 3 deletions(-) + +commit 5a5940a0a0704be8e222d4cad6cedda1ad3e0f71 +Author: Martin Pitt +Date: Fri Nov 9 09:37:00 2012 +0100 + + test_gi: Enable GByteArray constructor tests + + GByteArray annotations have been fixed in GLib now, enable the + test case. + + Drop the redundant disabled_test_bytearray_none_in_from_bytes() + test, as this + is the same as disabled_test_bytearray_none_in(). + + tests/test_gi.py | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +commit e2c545896ab08b1f1885b502a8472db83f193d08 +Author: Martin Pitt +Date: Fri Nov 9 09:11:38 2012 +0100 + + test_gi: Enable GBytes test cases + + GBytes annotations are fixed in GLib now, enable the test case and + add more + for g_bytes_new_take() and g_bytes_{compare,equal}(). + + Please note that calling unref_to_array() on a GBytes object that + we created + ourselves currently causes a double free crash, so disable that part + for now. + + tests/test_gi.py | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +commit 1ba4e201f86ffa28c645d7c9eea99cf31080ea43 +Author: Martin Pitt +Date: Fri Nov 9 08:26:29 2012 +0100 + + test_gi: Add missing data type tests from GIMarshallingTests + + Add tests for types time_t, GBytes, GByteArray, and various variants + of passing + around GValues, flags, enums, arrays, and boxed structs. This tests + API which + is provided by GIMarshallingTests, but which we did not cover yet. + + This detects a number of bugs in annotations and our + marshalling. These have + been marked as expected failure, or disabled completely for the + cases where + they cause crashes. + + tests/test_gi.py | 152 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 152 insertions(+) + +commit 0456d9c892b76ed79134230a4a8610a23c602964 +Author: Martin Pitt +Date: Fri Nov 9 06:44:46 2012 +0100 + + autogen.sh: Only enable code coverage if lcov is installed + + Otherwise we break minimal build environments. + + autogen.sh | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit 76a3acebf73f930c541d0f30249f67d254f948ab +Author: Martin Pitt +Date: Fri Nov 9 06:41:58 2012 +0100 + + Lower autoconf dependency to 2.68 again + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f1a5f1b92d577c542d4258e63e595d4da9acd484 +Author: Martin Pitt +Date: Thu Nov 8 14:54:30 2012 +0100 + + Add support for lcov code coverage + + Use gnome-common's new code coverage flags. Default to enabling + code coverage + in autogen.sh (but not for dist). + + To use this, run "make check-code-coverage" after building. + + .gitignore | 1 + + Makefile.am | 2 ++ + autogen.sh | 2 +- + configure.ac | 6 ++++++ + 4 files changed, 10 insertions(+), 1 deletion(-) + +commit e46af4aba220cfaf4b84a9be847f3363da556993 +Author: Martin Pitt +Date: Wed Nov 7 17:14:22 2012 +0100 + + Update documentation files + + Update AUTHORS to have the current maintainers. + + Update HACKING to drop Tomeu's GNOME login (this should be set in + ~/.ssh/config) + + Update INSTALL to current upstream version. + + AUTHORS | 13 ++- + HACKING | 4 +- + INSTALL | 380 + +++++++++++++++++++++++++++++++++++++++++++--------------------- + 3 files changed, 267 insertions(+), 130 deletions(-) + +commit 06f5ed0ebabce34eca6bc6de80221cba6453feec +Author: Martin Pitt +Date: Wed Nov 7 17:08:11 2012 +0100 + + Quiesce automake output + + Use $(AM_V_GEN) with custom $(LINK) commands, and avoid error + messages about + existing symlinks on rebuilds. + + gi/Makefile.am | 2 +- + gi/_glib/Makefile.am | 2 +- + gi/_gobject/Makefile.am | 2 +- + tests/Makefile.am | 6 +++--- + 4 files changed, 6 insertions(+), 6 deletions(-) + +commit 37270de8ead0b281a1824ff204a4aa9686a7225b +Author: Martin Pitt +Date: Wed Nov 7 16:50:07 2012 +0100 + + Drop unused variable, fail builds on those + + Build with -Werror=unused-variable, as these could hide programming + errors or + incomplete refactoring, and are not platform dependent. + + Drop unused variable in pyg_type_add_interfaces(). + + configure.ac | 1 + + gi/_gobject/gobjectmodule.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +commit 495fd98555e0c89724bb8fa9478dc096c5d61e22 +Author: Martin Pitt +Date: Wed Nov 7 16:37:04 2012 +0100 + + configure.ac: Drop maintainer mode, modernize libtool declarations + + Use all arguments of AC_INIT. + + AM_MAINTAINER_MODE is discouraged now, drop it. + + Use LT_PREREQ and LT_INIT for libtool initialization instead of + the older + declarations. + + See https://live.gnome.org/GnomeGoals/ModernAutotools + + configure.ac | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +commit 059d0cb879fe5a7b0296ec21f3bfcb64c8596cb0 +Author: Martin Pitt +Date: Wed Nov 7 16:21:13 2012 +0100 + + autoupdate configure.ac + + Result of "autoupdate", with slight manual beautification. + + See https://live.gnome.org/GnomeGoals/ModernAutotools + + configure.ac | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +commit a932446e6648ecd98c9038298b18c6fbd36c01aa +Author: Jose Rostagno +Date: Mon Nov 5 14:26:05 2012 -0300 + + pygi-convert: remove deprecated GLib → GObject conversions + + Using these functions from the GObject module is deprecated now, + they should be + used from GLib. + + pygi-convert.sh | 5 ----- + 1 file changed, 5 deletions(-) + +commit 21076d4b8f3ec8e253ca236fa3b20b07fde237fe +Author: Simon Feltman +Date: Wed Nov 7 03:49:24 2012 -0800 + + Use hasattr when testing for __info__ when finding vfuncs + + Change gi.types.find_vfunc_info_in_interface to use hasattr + when finding vfuncs. Using '__info__' in __dict__ was skipping + overridden interfaces which don't directly contain the __info__. + + gi/types.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1b5c9b3d1499b3bc59afb297672abc671e175546 +Author: Martin Pitt +Date: Wed Nov 7 12:05:24 2012 +0100 + + tests: Ensure that the fatal mask is always reset + + On test case failures the fatal mask might be left in a wrong state, + so ensure + with "finally" that it is reset on failed tests as well, to avoid + hiding other + failures. + + tests/test_gi.py | 11 ++++++----- + tests/test_overrides_gtk.py | 33 +++++++++++++++++++-------------- + tests/test_pygtkcompat.py | 6 ++++-- + tests/test_signal.py | 6 ++++-- + 4 files changed, 33 insertions(+), 23 deletions(-) + +commit 463f660cd6bb78ae7f2ea7c70c0491e6b4744942 +Author: Simon Feltman +Date: Tue Nov 6 21:34:06 2012 -0800 + + Replace GObject notify methods with introspection and python + + Replace static context managers for freeze_notify and + handler_block with python context managers. Remove notify, + freeze_notify, thaw_notify static methods as the introspection + versions work fine. + + https://bugzilla.gnome.org/show_bug.cgi?id=672727 + + gi/_gobject/pygobject.c | 173 + ++---------------------------------------------- + gi/overrides/GObject.py | 61 +++++++++++++++-- + tests/test_gobject.py | 26 ++++++-- + tests/test_signal.py | 13 +++- + 4 files changed, 91 insertions(+), 182 deletions(-) + +commit 3fcd987272a779e5ee9173a2c3a043b4b7475842 +Author: Simon Feltman +Date: Tue Oct 23 13:56:32 2012 -0700 + + Add support for overriding GObject.Object + + Shift pygi module mechanics so the introspection generated 'Object' + class becomes derived from the static GObject class. Add initial + GObject.Object override which sets all static methods back essentially + leapfrogging the introspection methods. This sets the stage for having + the ability to remove static methods piecemeal in favor of + introspection/python in future commits. + + https://bugzilla.gnome.org/show_bug.cgi?id=672727 + + gi/module.py | 30 +++++++++++--------- + gi/overrides/GObject.py | 74 + ++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygobject-external.h | 10 +------ + gi/types.py | 7 +++++ + tests/test_gobject.py | 31 ++++++++++++++++---- + tests/testhelpermodule.c | 2 +- + 6 files changed, 126 insertions(+), 28 deletions(-) + +commit 4da6f93d86b104941c5533c3da5edb4a00ec62e9 +Author: Martin Pitt +Date: Tue Nov 6 13:55:21 2012 +0100 + + Bump glib dependency to >= 2.34.2 + + We need 2.34.2 or 2.35.2 as we now depend on the GIOChannel annotation + fixes. + + README | 2 +- + configure.ac | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 85c8dd7a9bc81fb5df5abc6d8a95f966955ec775 +Author: Martin Pitt +Date: Tue Nov 6 11:28:42 2012 +0100 + + Update README + + Point to python-hackers-list instead of the old pygtk list, update + required + versions, and point to wiki page and IRC. + + README | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +commit 6d8b29ba56fb085948a155c75af36dcea9c71da8 +Author: Martin Pitt +Date: Tue Nov 6 11:21:32 2012 +0100 + + Add --with-python configure option + + This behaves like setting $PYTHON, but also works in build systems + like jhbuild + which do not support setting environment variables. + + Update README accordingly. + + README | 15 +++++++++------ + configure.ac | 43 ++++++++++++++++++++++++++++++++++--------- + 2 files changed, 43 insertions(+), 15 deletions(-) + +commit 4e5556a5238a3b86da9a0e40fd0e23004ed6af75 +Author: Martin Pitt +Date: Tue Nov 6 10:39:27 2012 +0100 + + python.m4: Add python3.3, do not prefer unversioned "python" + + Add python 3.3 to the search list. + + http://www.python.org/dev/peps/pep-0394/ broke the well-defined + meaning of + "python", so use that as last fallback if more specific versions do + not exist. + + configure.ac | 2 +- + m4/python.m4 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit e71c046ed8f5b06e6b7383ddc0fc18f06de6abee +Author: Martin Pitt +Date: Tue Nov 6 09:48:50 2012 +0100 + + m4: Update py-compile to current upstream version + + Update py-compile to current versions from automake 1.11.6. + + m4/py-compile | 81 + +++++++++++++++++++++++++++++++++++------------------------ + 1 file changed, 48 insertions(+), 33 deletions(-) + +commit 8406b39f4e9ff98e0d59e880dde3ddb5e5131726 +Author: Martin Pitt +Date: Tue Nov 6 09:57:00 2012 +0100 + + m4: Update introspection.m4 to current upstream version + + m4/introspection.m4 | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 4ffa61b7c39cf038440dc9acfe8d214c9b77c3a6 +Author: Martin Pitt +Date: Tue Nov 6 09:53:15 2012 +0100 + + option.py: Fix PEP-8 error + + gi/_glib/option.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2cbb54e79c23b96486d4a2bfa170460df5bd6c84 +Author: Simon Feltman +Date: Mon Nov 5 18:27:56 2012 -0800 + + Remove DynamicGLibModule and DynamicGObjectModule + + Move final bits of _glib static binding imports directly into + the GLib override. Change _glib/option use the .so directly + rather than the staged variables in _glib/__init__.py. + Remove DynamicGLibModule and DynamicGObjectModule and update + unittest. + + https://bugzilla.gnome.org/show_bug.cgi?id=687488 + + gi/_glib/__init__.py | 11 ---------- + gi/_glib/option.py | 16 +++++++------- + gi/importer.py | 12 ++--------- + gi/module.py | 60 + ---------------------------------------------------- + gi/overrides/GLib.py | 14 ++++++++++++ + tests/test_gi.py | 9 ++------ + 6 files changed, 26 insertions(+), 96 deletions(-) + +commit 901c1b6e3722a9cd999e4948297e2c460f101d20 +Author: Daniel Drake +Date: Thu Nov 1 14:46:22 2012 +0000 + + Fix property lookup in class hierarchy + + Commit 4bfe7972546413f46f5c36737ff03bb5612c1921 introduced a bug where + a Python subclass of a gi-provided base class overrides a property + from the + base class. + + The new behaviour in the above commit causes pygobject to seek + the property + in the base class and try to read it from there (resulting in + confusion) + rather than noticing that the property is overridden and present + in the + Python object instance. + + To provide a nicer solution here, we can exploit the fact that + g_object_class_find_property() will traverse the hierarchy in order to + find the right GParamSpec, and the returned GParamSpec can tell + us exactly + which GType introduces the property. The strategy is: + + 1. Find pspec with g_object_class_find_property() + 2. Find the class that owns that property (pspec->owner_type) + 3. See if girepository owns that class. + 3a. If yes, get property from there. + 3b. If not, get property "directly" + + And the same for property setting. + + Now that _pygi_lookup_property_from_g_type is always passed the + type that + implements the property, it no longer has to go recursing through + parent + classes, which was the original cause of confusion. + + https://bugzilla.gnome.org/show_bug.cgi?id=686942 + + gi/_gobject/pygobject.c | 92 +++++++++++++++++++++++---------- + gi/pygi-property.c | 130 + ++++++++++++++++++++++------------------------- + gi/pygi-property.h | 4 +- + gi/pygi.h | 12 ++--- + tests/test_properties.py | 30 +++++++++++ + 5 files changed, 164 insertions(+), 104 deletions(-) + +commit efcb0f9fda65e24ae98438d61487d06db9eac1b1 +Author: Martin Pitt +Date: Sat Nov 3 16:14:01 2012 +0100 + + Move property and signal creation into _class_init() + + We must not add class interfaces after g_type_class_ref() has been + called the + first time. Move signal and property creation from pyg_type_register() + into + pyg_object_class_init(), and drop the hack of registering interfaces + twice. + + This changed class initialization order now exposes GLib's warning + about + unknown signals, so adjust + test_signal.TestGSignalsError.test_invalid_name() to + not abort on that. + + https://bugzilla.gnome.org/show_bug.cgi?id=686149 + + gi/_gobject/gobjectmodule.c | 177 + ++++++++++++++++++-------------------------- + tests/test_signal.py | 6 +- + 2 files changed, 75 insertions(+), 108 deletions(-) + +commit 655a5002ffaa088b775adbc59e5125444f7bc1ca +Author: Jose Rostagno +Date: Sat Nov 3 13:21:52 2012 -0300 + + Remove unused macro definitions + + PYGLIB_*_VERSION are not used anywhere any more, remove those. + (dropped in commit 8d52bceb1) + + gi/_glib/glibmodule.c | 5 ----- + 1 file changed, 5 deletions(-) + +commit fa054fd15b8874760bee97d9af168a2969e6ece4 +Author: Martin Pitt +Date: Mon Nov 5 14:38:07 2012 +0100 + + testhelpermodule.c: Drop obsolete g_thread_init() + + We already require a new enough glib version as we dropped + g_thread_init() in + the main code a long time ago. But for formality's sake, bump glib + requirement + to >= 2.32. + + configure.ac | 4 ++-- + tests/testhelpermodule.c | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +commit 2e57530a27a44e94927d487cf2f2d9e543777654 +Author: Martin Pitt +Date: Mon Nov 5 14:37:11 2012 +0100 + + pygi-source.c: Drop dead code + + gi/pygi-source.c | 2 -- + 1 file changed, 2 deletions(-) + +commit 2a24c9ccd59bff719fa817a0ec5c959f6da03e1c +Author: Simon Feltman +Date: Sun Nov 4 22:22:53 2012 -0800 + + Move TYPE constants from _gobject to GObject + + Clear out TYPE constants from _gobject/__init__.py and move them + into the + GObject overrides. Disperse class imports among modules that use + them instead + of using _gobject/__init__.py as a staging area (e.g. GInterface). + + https://bugzilla.gnome.org/show_bug.cgi?id=687487 + + gi/_gobject/__init__.py | 30 ------------------------------ + gi/_gobject/constants.py | 2 +- + gi/module.py | 38 +++++++++++++++++++++++++------------- + gi/overrides/__init__.py | 9 ++++++--- + gi/types.py | 10 ++++++---- + 5 files changed, 38 insertions(+), 51 deletions(-) + +commit c2aa6f0d0ed4c4e60f081b106dc7a65513963fce +Author: Martin Pitt +Date: Mon Nov 5 13:10:05 2012 +0100 + + Move G_MIN/MAX constants into GObject overrides + + These really ought to come from GLib's typelib, but are not right + now so we + need to keep the static bindings for those. But drop them from + gi/_gobject/ and + move them into the overrides where they belong. + + gi/_gobject/__init__.py | 17 ----------------- + gi/_gobject/constants.py | 21 --------------------- + gi/_gobject/propertyhelper.py | 2 +- + gi/overrides/GObject.py | 9 +++++++++ + tests/test_gi.py | 32 ++++++++++++++++---------------- + 5 files changed, 26 insertions(+), 55 deletions(-) + +commit 12b84727edc36f686a7031b5c4c6bf662838908d +Author: Martin Pitt +Date: Mon Nov 5 11:04:54 2012 +0100 + + Replace static OPTION_* constants with GI + + Drop static definitions of GLib.OPTION_* constants and use the ones + from GI + instead. + + https://bugzilla.gnome.org/show_bug.cgi?id=686765 + + gi/_glib/__init__.py | 13 ------------- + gi/_glib/glibmodule.c | 32 -------------------------------- + gi/_glib/option.py | 46 + ++++++++++++++++++++++++---------------------- + gi/overrides/GLib.py | 13 +++++++++++++ + gi/overrides/GObject.py | 2 +- + 5 files changed, 38 insertions(+), 68 deletions(-) + +commit 7372e3c9ecb8e836894c32975eab8c4107ba0b28 +Author: Martin Pitt +Date: Mon Nov 5 10:14:52 2012 +0100 + + tests: Do not use deprecated assertRaisesRegexp() + + Use assertRaisesRegex() instead and provide 2.7 compatibility in + tests/runtests.py. + + tests/runtests.py | 3 +++ + tests/test_signal.py | 8 ++++---- + 2 files changed, 7 insertions(+), 4 deletions(-) + +commit da2106902eb3dabebdff1674743cb3040566a745 +Author: Simon Feltman +Date: Sun Nov 4 02:57:29 2012 -0800 + + Move gobject static functions and constants to gi + + Replace the following functions with gi and overrides: + type_children, type_interfaces, signal_list_ids, signal_list_names, + signal_lookup, signal_name, type_parent. Assign SIGNAL_* and + PARAM_* from gi SignalFlags and ParamFlags respectively. + Move module level assignments of a number of static functions to + the GObject.py overrides file. + + https://bugzilla.gnome.org/show_bug.cgi?id=687487 + + docs/reference/pygobject-functions.xml | 25 --- + gi/_gobject/__init__.py | 72 +-------- + gi/_gobject/gobjectmodule.c | 272 + --------------------------------- + gi/overrides/GObject.py | 208 ++++++++++++++++++++++++- + gi/overrides/__init__.py | 5 +- + tests/test_signal.py | 11 +- + 6 files changed, 215 insertions(+), 378 deletions(-) + +commit f4acd6a9d14248d459708f61fd01f6d4735f087d +Author: Simon Feltman +Date: Sun Nov 4 02:52:19 2012 -0800 + + Make unitests for gobject functions moving to gi more strict + + Add expected failure test for invalid SystemError's coming from + signal_lookup and signal_list_ids. Remove excessive type_name + tests and type_from_name tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=687487 + + tests/test_gtype.py | 53 + ---------------------------------------------------- + tests/test_signal.py | 40 ++++++++++++++++++++++++--------------- + 2 files changed, 25 insertions(+), 68 deletions(-) + +commit 3267808318b284814e52f2803b17af56fca648ad +Author: Martin Pitt +Date: Sat Nov 3 14:17:25 2012 +0100 + + [API change] Remove static filename_from_utf8() binding + + Replace static GLib.filename_from_utf8() with GI. The old static + binding always + tried to convert the result to an Unicode object, which will fail + if the result + is not UTF-8 encoded (which is the whole point of this function + really!), so + return bytes now. + + Although the static binding was rather useless before, this is + technically an + API break. + + docs/reference/pyglib-functions.xml | 32 -------------------------------- + gi/_glib/__init__.py | 1 - + gi/_glib/glibmodule.c | 26 -------------------------- + gi/_gobject/__init__.py | 1 - + gi/overrides/GLib.py | 8 ++++++++ + gi/overrides/GObject.py | 3 ++- + tests/test_glib.py | 8 ++++++++ + 7 files changed, 18 insertions(+), 61 deletions(-) + +commit 8d52bceb1e0aa0dc79cf77f36dda9f953f170459 +Author: Martin Pitt +Date: Sat Nov 3 13:14:15 2012 +0100 + + Drop static glib_version and pyglib_version constants + + Use the GLib version from GI instead, and the already existing + gi.version_info. + + docs/reference/pyglib-constants.xml | 50 + ---------------------------------- + docs/reference/pygobject-constants.xml | 19 ------------- + gi/_glib/__init__.py | 2 -- + gi/_glib/glibmodule.c | 21 -------------- + gi/_gobject/__init__.py | 1 - + gi/overrides/GLib.py | 8 +++++- + gi/overrides/GObject.py | 3 +- + tests/test_glib.py | 12 ++++++++ + 8 files changed, 21 insertions(+), 95 deletions(-) + +commit 9f96325e75f7c5f88789ea3f74a068e73cfde1a2 +Author: Martin Pitt +Date: Sat Nov 3 12:12:44 2012 +0100 + + Drop static G_MININT8 and related constants + + Use the introspected constants from GLib instead. + + gi/_gobject/__init__.py | 12 ------------ + gi/_gobject/constants.py | 12 ------------ + gi/_gobject/gobjectmodule.c | 18 +----------------- + gi/overrides/GObject.py | 17 +++++++++++++++++ + tests/test_gobject.py | 4 ++++ + 5 files changed, 22 insertions(+), 41 deletions(-) + +commit 3354c4eda0f098d1a8f744264ef9a2565a38b50d +Author: Martin Pitt +Date: Sat Nov 3 11:58:40 2012 +0100 + + test_gobject: Add test case for min/max int constants + + Related to https://bugzilla.gnome.org/show_bug.cgi?id=685022 + + tests/test_gobject.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit d70cb32789e057fe5a16e61a0cce77d9c54a3ee1 +Author: Jose Rostagno +Date: Sat Oct 27 15:37:32 2012 -0300 + + Use g_object_info_find_signal() + + Replace our custom code with a call to the corresponding + gobject-instrospection + function. + + https://bugzilla.gnome.org/show_bug.cgi?id=687371 + + gi/pygi-signal-closure.c | 21 ++++----------------- + 1 file changed, 4 insertions(+), 17 deletions(-) + +commit ae6d0aada9587cd4dca168375527b80785b604a0 +Author: Martin Pitt +Date: Sat Nov 3 11:23:06 2012 +0100 + + GLib overrides: code cleanup + + Factorize the logic to handle zero or multiple user_data arguments + into + user_data_varargs_shim(), and put code that handles deprecated API + into the + corresponding "then" branches, to improve readability. + + gi/overrides/GLib.py | 87 + ++++++++++++++++++++++++++++------------------------ + 1 file changed, 47 insertions(+), 40 deletions(-) + +commit d7f095b01e7208273703c880f4f0dfcc1a152a9a +Author: Martin Pitt +Date: Sat Nov 3 09:33:08 2012 +0100 + + Restore actual GLib API after previous fix + + Re-fix the acceptance of priority as first argument for idle_add(), + io_add_watch() and timeout_add(), as that is the real GLib API. Ensure + that + this keeps supporting the backwards compatible API with supplying + multiple user + data arguments. + + https://bugzilla.gnome.org/show_bug.cgi?id=687047 + + gi/overrides/GLib.py | 117 + +++++++++++++++++++++++++----------------------- + tests/test_iochannel.py | 74 +++++++++++++++++++++++++++--- + tests/test_source.py | 30 +++++++++++++ + 3 files changed, 158 insertions(+), 63 deletions(-) + +commit 648b653d85bf3bc28dc59c6d309f15d388076af9 +Author: Simon Feltman +Date: Fri Nov 2 21:01:38 2012 -0700 + + Add unittests for module level type and signal functions + + Add tests for the following methods: signal_list_ids, + signal_name, signal_lookup, signal_query, type_children, + type_from_name, type_name, type_is_a, and type_interfaces. + + https://bugzilla.gnome.org/show_bug.cgi?id=687487 + + tests/Makefile.am | 1 + + tests/test_gtype.py | 106 + +++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_signal.py | 43 +++++++++++++++++++++ + 3 files changed, 150 insertions(+) + +commit 80db2a50feab9898d7c5f88ea27aadc3dfb5bec3 +Author: Simon Feltman +Date: Tue Oct 30 18:33:44 2012 -0700 + + Fix GLib override incompatibilities with old static API + + Change idle_add, timeout_add, timeout_add_seconds, and + io_add_watch to accept *args and **kwargs as arguments + to the callback functions instead of only accepting a single + user_data arg. This ensures the new overridden introspection + methods are backwards compatible with the static versions + they replaced. + + https://bugzilla.gnome.org/show_bug.cgi?id=687047 + + gi/overrides/GLib.py | 98 + ++++++++++++++++++++++++++++--------------------- + tests/test_iochannel.py | 37 +++++++++++++++++-- + 2 files changed, 90 insertions(+), 45 deletions(-) + +commit 9c6399bbf75c312b1ef4933d079712ea5b05a935 +Author: Simon Feltman +Date: Tue Oct 30 12:01:44 2012 -0700 + + Fix IOChannel unittests for python 2.7 + + Use __future__ unicode_literals to minimize difference + between python 2.7 and 3. Comparisons need to encode arguments as + 'UTF-8' for testing readline operations. + Add backwards compatible "next" to support the python 2.7 iteration. + Change isinstance(channel, file) to hasattr(channel, 'fileno') to + support all python versions (and duck typing). + + https://bugzilla.gnome.org/show_bug.cgi?id=687047 + + gi/overrides/GLib.py | 4 +++- + tests/test_iochannel.py | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +commit 0f94a0a4ebd2bbfd06d8f9a2bb2b17dabf7678ef +Author: Martin Pitt +Date: Mon Oct 29 23:00:31 2012 +0100 + + Allow calling io_add_watch with a file object + + The old static bindings allowed that, so we need to allow it to + maintain + backwards compatibility. Deprecate this mode as well, so that we + can get rid of + it at some point. + + https://bugzilla.gnome.org/show_bug.cgi?id=687047 + + gi/overrides/GLib.py | 7 +++++++ + tests/test_glib.py | 26 ++++++++++++++++++++++++++ + 2 files changed, 33 insertions(+) + +commit 3ba67fd41944309077eb81c4c03397519ed29dc4 +Author: John Ralls +Date: Mon Oct 29 14:57:22 2012 -0700 + + Fix duplicate symbols error on OSX + + gi/pygi-source.c | 1 + + 1 file changed, 1 insertion(+) + +commit 5a367aa067e369f2b1e713199614e3426fecc10e +Author: Martin Pitt +Date: Sun Oct 28 17:42:34 2012 +0100 + + Drop removed markup-escape-text() from reference documentation + + docs/reference/pyglib-functions.xml | 36 + ------------------------------------ + 1 file changed, 36 deletions(-) + +commit 057b3d3791e6f1947004f2482c0ae40529de03ae +Author: Martin Pitt +Date: Sun Oct 28 17:41:03 2012 +0100 + + Drop some dead code from gi/_glib/glibmodule.c + + gi/_glib/glibmodule.c | 45 --------------------------------------------- + 1 file changed, 45 deletions(-) + +commit 7b12803bce3418bb487127f497f022c973f35888 +Author: Martin Pitt +Date: Sun Oct 28 17:37:29 2012 +0100 + + Remove static get_current_time() binding + + Use GLib.get_real_time() through GI instead. Deprecate the function, + as + GLib.get_real_time() should be called directly. + + docs/reference/pyglib-functions.xml | 26 -------------------------- + gi/_glib/__init__.py | 1 - + gi/_glib/glibmodule.c | 11 ----------- + gi/_glib/pyglib.c | 16 ---------------- + gi/_glib/pyglib.h | 1 - + gi/_gobject/__init__.py | 1 - + gi/overrides/GLib.py | 8 ++++++++ + gi/overrides/GObject.py | 2 +- + tests/test_glib.py | 6 +++++- + 9 files changed, 14 insertions(+), 58 deletions(-) + +commit b3dfb780b3a74f6933e3afcd2ba512b36dfbe514 +Author: Martin Pitt +Date: Sun Oct 28 17:23:23 2012 +0100 + + Add more tests for GLib.spawn_async() + + Check spawn_async() with getting stdin/out/err pipes and specifying + envp. + + tests/test_subprocess.py | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +commit 70d78eee4a04dcaefea4615fe351e33fa717dffa +Author: Martin Pitt +Date: Sun Oct 28 14:15:05 2012 +0100 + + Remove static child_add_watch() binding + + Use the GLib API through GI instead, and provide override to keep + backwards + compatible API. Also allow using the actual GLib API, and deprecate + the old + static API of calling without a priority as first argument. + + docs/reference/pyglib-functions.xml | 61 --------------------------- + gi/_glib/__init__.py | 1 - + gi/_glib/glibmodule.c | 72 ------------------------------- + gi/_gobject/__init__.py | 1 - + gi/overrides/GLib.py | 46 ++++++++++++++++++++ + gi/overrides/GObject.py | 2 +- + tests/test_mainloop.py | 2 +- + tests/test_subprocess.py | 84 + ++++++++++++++++++++++++++++++++++--- + 8 files changed, 127 insertions(+), 142 deletions(-) + +commit 4b16427714b850e33c6020d8de1833bae19a3b87 +Author: Martin Pitt +Date: Sun Oct 28 13:44:23 2012 +0100 + + test_subprocess: Cover more child_watch_add() cases + + Verify that priority is set correctly, and also test calling without + userdata. + + tests/test_subprocess.py | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +commit 83ff5938612d37d52f112867a472777dd6786d69 +Author: Colin Walters +Date: Sat Oct 27 12:22:53 2012 -0400 + + gi/__init__.py: Pacify pep8 style checker + + It was complaining about finding only 1 blank line. Regression + likely introduced by f976d05b. + + https://bugzilla.gnome.org/show_bug.cgi?id=686991 + + gi/__init__.py | 1 + + 1 file changed, 1 insertion(+) + +commit f976d05b04f26e733d19988e68989e340eb3a29e +Author: Martin Pitt +Date: Fri Oct 26 10:39:28 2012 +0200 + + Use a custom deprecation warning to make them visible by default + + DeprecationWarning is not shown by default, and is thus rather + useless for + developers. Use a custom PyGIDeprecationWarning class and derive + it from + RuntimeWarning to make it visible. + + gi/__init__.py | 5 +++++ + gi/overrides/GLib.py | 5 +++-- + gi/overrides/Gtk.py | 5 +++-- + gi/overrides/__init__.py | 4 ++-- + gi/pygtkcompat.py | 4 ++-- + tests/Makefile.am | 2 +- + tests/test_glib.py | 5 +++-- + tests/test_gobject.py | 3 ++- + tests/test_iochannel.py | 5 +++-- + tests/test_source.py | 3 ++- + 10 files changed, 26 insertions(+), 15 deletions(-) + +commit 366f5d2d3902c6293d0031e0b7dc5d6641a05ac7 +Author: Martin Pitt +Date: Fri Oct 26 09:26:17 2012 +0200 + + Remove static io_add_watch() binding + + Use the GLib API through GI instead, and provide override to keep + backwards + compatible API. Also allow using the actual GLib API, and deprecate + all other + variants: + - calling with an fd as first argument instead of an IOChannel + - calling without a priority as second argument + + docs/reference/pyglib-functions.xml | 106 + ------------------------------------ + gi/_glib/__init__.py | 1 - + gi/_glib/glibmodule.c | 98 + --------------------------------- + gi/_gobject/__init__.py | 1 - + gi/overrides/GLib.py | 51 ++++++++++++++--- + gi/overrides/GObject.py | 3 +- + tests/test_glib.py | 15 ++++- + tests/test_iochannel.py | 70 +++++++++++++++++++++++- + 8 files changed, 126 insertions(+), 219 deletions(-) + +commit 284de1eb5c37a3f6caa7d846dbd439f1eac410a2 +Author: Martin Pitt +Date: Fri Oct 26 08:48:35 2012 +0200 + + Add tests for GLib.io_add_watch() + + tests/test_glib.py | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +commit 15e717ce2c2a26c02c913f79bc7cf6876d943e92 +Author: Martin Pitt +Date: Thu Oct 25 15:55:46 2012 +0200 + + Remove static GIOChannel bindings + + Use the GLib API through GI instead, and provide overrides to keep + backwards + compatible API, including its bugs. + + We still need to keep a static wrapper around + g_io_channel_read_chars() until + we teach PyGObject to correctly handle caller allocated out array + arguments. + + https://bugzilla.gnome.org/show_bug.cgi?id=686795 + + gi/_glib/Makefile.am | 2 - + gi/_glib/__init__.py | 1 - + gi/_glib/glibmodule.c | 2 - + gi/_glib/pygiochannel.c | 748 + ------------------------------------------------ + gi/_glib/pygiochannel.h | 29 -- + gi/_gobject/__init__.py | 1 - + gi/gimodule.c | 72 +++++ + gi/overrides/GLib.py | 95 +++++- + 8 files changed, 161 insertions(+), 789 deletions(-) + +commit 0bfa6b44b808d9f8f55199216c29c1aec96c7719 +Author: Martin Pitt +Date: Thu Oct 25 12:59:46 2012 +0200 + + test_iochannel.py: Fix data type of IOFlags + + ~GLib.IOFlags.NONBLOCK yields an int instead of a GLib.IOFlags, + so ensure that + the result is of type GLib.IOFlags again. + + tests/test_iochannel.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 25d12afd06863ce223a161ba1317bfe5503bca5c +Author: Martin Pitt +Date: Thu Oct 25 08:24:31 2012 +0200 + + Add environment variable to disable pep8 checks + + pep8 takes quite long for "make check". Skip it if $SKIP_PEP8 is + set, which + makes the test/fix turnaround time faster. + + tests/Makefile.am | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit e9624ed1d38c777de2b430e3b0fbae2acbf34956 +Author: Simon Feltman +Date: Wed Oct 24 04:31:26 2012 -0700 + + [API add] Add get_introspection_module for getting un-overridden + modules + + Add gi.module.get_introspection_module to explicitly get a + wrapped module pulled in through introspection without static + and python override handling. This API is intended for python + overrides to use rather than having them access + gi.importer.modules['']._introspection_module directly. + Replace aforementioned usage in all overrides. + + https://bugzilla.gnome.org/show_bug.cgi?id=686828 + + gi/module.py | 38 + +++++++++++++++++++++++++++++++++++--- + gi/overrides/GIMarshallingTests.py | 4 ++-- + gi/overrides/GLib.py | 4 ++-- + gi/overrides/Gdk.py | 6 +++--- + gi/overrides/Gio.py | 4 ++-- + gi/overrides/Gtk.py | 5 +++-- + gi/overrides/Pango.py | 4 ++-- + tests/test_overrides.py | 29 +++++++++++++++++++++++++++++ + 8 files changed, 78 insertions(+), 16 deletions(-) + +commit e6e047ef9b8575c852b3cdc3f5d4dfbb548cc648 +Author: Martin Pitt +Date: Wed Oct 24 15:16:13 2012 +0200 + + test_option: Use public API + + Use GLib.option, not gi._glib.option. + + tests/test_option.py | 42 ++++++++++++++++++++---------------------- + 1 file changed, 20 insertions(+), 22 deletions(-) + +commit 6a586af41b8740c4ba590591d1068d80071ff2dc +Author: Martin Pitt +Date: Wed Oct 24 14:12:05 2012 +0200 + + Drop static SPAWN_* constants + + Use the introspected constants instead, which are identical. Add + backwards + compatible aliases. + + These constants are covered by tests/test_subprocess.py. + + https://bugzilla.gnome.org/show_bug.cgi?id=686765 + + docs/reference/pyglib-constants.xml | 68 + ---------------------------------- + docs/reference/pyglib-functions.xml | 26 ++++++------- + docs/reference/pygobject-constants.xml | 67 + --------------------------------- + gi/_glib/__init__.py | 7 ---- + gi/_glib/glibmodule.c | 15 -------- + gi/_gobject/__init__.py | 7 ---- + gi/overrides/GLib.py | 6 +++ + gi/overrides/GObject.py | 6 ++- + tests/test_subprocess.py | 6 ++- + 9 files changed, 29 insertions(+), 179 deletions(-) + +commit 0137a7af7bf69421e0c8e94120a1f8cff01fbeea +Author: Martin Pitt +Date: Wed Oct 24 13:59:31 2012 +0200 + + Drop static IO_* constants + + Use the introspected constants instead, which are identical. Add + backwards + compatible aliases. + + These constants are covered by tests/test_iochannel.py. + + docs/reference/pyglib-constants.xml | 52 + ------------------------------------- + gi/_glib/__init__.py | 19 -------------- + gi/_glib/glibmodule.c | 32 ----------------------- + gi/_gobject/__init__.py | 18 ------------- + gi/overrides/GLib.py | 18 ++++++++++++- + gi/overrides/GObject.py | 8 +++++- + tests/test_iochannel.py | 1 + + tests/test_source.py | 2 +- + 8 files changed, 26 insertions(+), 124 deletions(-) + +commit 0e1a6ccee45ae2239da1c44de1866596343165ba +Author: Martin Pitt +Date: Wed Oct 24 12:50:50 2012 +0200 + + Fix various bugs in GLib.IOChannel + + - Fix segfault when using an IOChannel as an iterator: PyIter_Next() + returns + NULL on the last element, instead of raising a StopIteration. + + - The default encoding of a stream is 'UTF-8', not NULL. NULL means + that the + stream is being used in binary mode; in that case, we should not + attempt to + do any automagic conversion to an Unicode object. As this special + case is + inconsistent and has never worked anyway, and the current buggy + implementation breaks binary streams, just drop it without + replacement. + (Introduced in commit de9eae4dfcce8) + + These bugs were uncovered by the previously committed tests. + + gi/_glib/pygiochannel.c | 25 +++++-------------------- + 1 file changed, 5 insertions(+), 20 deletions(-) + +commit a98c37937a4f7cb81a0b02c023d12097f386a22c +Author: Martin Pitt +Date: Wed Oct 24 12:49:04 2012 +0200 + + Add tests for GLib.IOChannel + + This did not have any code coverage at all. The tests uncover a + range of bugs, + which will be fixed in the next commit. + + tests/Makefile.am | 1 + + tests/test_iochannel.py | 262 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 263 insertions(+) + +commit 1b27432abf6004553e9476d5ffeb2bf603534419 +Author: Martin Pitt +Date: Wed Oct 24 08:50:37 2012 +0200 + + Remove static idle_add/timeout_add bindings + + Use the GLib functions through GI instead. Add overrides to ensure + that default + arguments continue to work as before, and that callbacks are called + without an + userdata argument if it wasn't specified. + + docs/reference/pyglib-functions.xml | 165 + ------------------------------------ + gi/_glib/__init__.py | 3 - + gi/_glib/glibmodule.c | 139 ------------------------------ + gi/_gobject/__init__.py | 3 - + gi/overrides/GLib.py | 31 +++++++ + gi/overrides/GObject.py | 3 +- + tests/test_source.py | 19 +++++ + 7 files changed, 52 insertions(+), 311 deletions(-) + +commit 2357f4a0237feabcf6886f2a448aa3f42f6781b9 +Author: Martin Pitt +Date: Wed Oct 24 09:14:57 2012 +0200 + + Add tests for priority argument of idle_add/timeout_add + + There is a potential to treat the priority as user data in a call like + "GLib.idle_add(cb, GLib.PRIORITY_HIGH)". The current static bindings + force + using a keyword argument for the priority (but silently ignore it + if you + specify both userdata and priority as a positional argument). + + Test the correct handling of priority as well. + + tests/test_source.py | 63 + ++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 59 insertions(+), 4 deletions(-) + +commit dceb4d60e210cb1531ad81935733a3f0be0c8edb +Author: Martin Pitt +Date: Wed Oct 24 08:40:50 2012 +0200 + + Drop old ChangeLog.pre-2.18 + + This is ancient by now, quite sizable, and the complete history can + always be + seen in the git log. + + ChangeLog.pre-2.18 | 3608 + ---------------------------------------------------- + Makefile.am | 1 - + 2 files changed, 3609 deletions(-) + +commit 127ef91f1563caa346bc2ac2adb064487a84e6a0 +Author: Martin Pitt +Date: Wed Oct 24 08:39:05 2012 +0200 + + Fix PEP-8 whitespace in previous commit + + tests/test_source.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 0bc0b55be0dae7528c2fc7439d672ad4e417335d +Author: Martin Pitt +Date: Wed Oct 24 08:33:49 2012 +0200 + + Add tests for idle_add()/timeout_add with and without user data + + This is implicitly spread over various test cases, but let's test + it explicitly + to ensure that the behaviour stays consistent when moving this to GI. + + tests/test_source.py | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +commit d0a0332feb7946f4bb6b43211d6fe3ae67e7dba5 +Author: Martin Pitt +Date: Wed Oct 24 08:05:43 2012 +0200 + + tests: consitent naming style + + Stop mixing camel case and underline naming, use the latter + consistently + in all tests. + + tests/test_gobject.py | 64 + +++++++++++++++++++++++------------------------ + tests/test_interface.py | 4 +-- + tests/test_option.py | 14 +++++------ + tests/test_pygtkcompat.py | 32 ++++++++++++------------ + tests/test_signal.py | 10 ++++---- + tests/test_source.py | 23 ++++++++--------- + tests/test_subprocess.py | 2 +- + tests/test_thread.py | 2 +- + tests/test_unknown.py | 2 +- + 9 files changed, 76 insertions(+), 77 deletions(-) + +commit 4b460e2eb18b8340fe99252063fdb08b0c222968 +Author: Martin Pitt +Date: Wed Oct 24 07:28:10 2012 +0200 + + Work around wrong 64 bit constants in GLib Gir + + GLib's gir currently has wrong constants for MININT64 and MAXUINT64; + explicitly + set them in an override, until this gets fixed properly. + + https://bugzilla.gnome.org/show_bug.cgi?id=685022 + + gi/overrides/GLib.py | 8 ++++++++ + tests/test_gi.py | 9 +++++++++ + 2 files changed, 17 insertions(+) + +commit f30efd2619911c89ca873fac6bec06a1b60fab82 +Author: Martin Pitt +Date: Tue Oct 23 13:32:14 2012 +0200 + + Mark GLib.Source.get_current_time() as deprecated + + This method has been deprecated in GLib long ago. We have a workaround + implementation using GLib.get_real_time(), but eventually this should + go away. + + gi/overrides/GLib.py | 5 ++++- + tests/test_source.py | 8 +++++++- + 2 files changed, 11 insertions(+), 2 deletions(-) + +commit 483c86267f2623eaa88d6a9e685c96ec3ba4f121 +Author: Martin Pitt +Date: Tue Oct 23 08:56:19 2012 +0200 + + Mark GLib API that is exposed in GObject as deprecated + + A lot of API in GObject really belongs into GLib and is just there for + historical/backwards compatible reasons. Mark these methods as + deprecated so + that at some point we can drop them. + + gi/overrides/GObject.py | 3 ++- + gi/overrides/__init__.py | 13 +++++++++++++ + tests/test_gobject.py | 24 ++++++++++++++---------- + 3 files changed, 29 insertions(+), 11 deletions(-) + +commit 191cf45af44850fc29f2392ae2f0042aed6d13a9 +Author: Martin Pitt +Date: Fri Oct 19 09:55:05 2012 +0200 + + Remove static MainLoop, MainContext, and some GSource bindings + + glib's MainLoop and MainContext are fully introspectable these days, + so remove + our static bindings. This reduces our code, as well enables GLib + API which + hasn't been available through the static bindings before. + + This also requires dropping our custom static types for GLib Source, + Timeout, + and Idle. The latter two work fine with introspection and just + need tiny + overrides for a backwards compatible API. g_source_new() is not + introspectable, + though, so we need to keep our static wrappers for that. Move + them from + gi/_glib/pygsource.c to gi/pygi-source.c, so that it can use the + GI API. + + Note that gi/_glib/pygsource.[hc] is still required for the static + PollFD type + which is used by the static IOChannel binding. Once the latter + goes away, + PollFD can be dropped as well. + + https://bugzilla.gnome.org/show_bug.cgi?id=686443 + + docs/Makefile.am | 6 +- + docs/reference/pyglib-classes.xml | 2 - + docs/reference/pyglib-constants.xml | 53 --- + docs/reference/pyglib-functions.xml | 58 --- + docs/reference/pyglib-maincontext.xml | 152 -------- + docs/reference/pyglib-mainloop.xml | 202 ----------- + gi/Makefile.am | 2 + + gi/_glib/Makefile.am | 4 - + gi/_glib/__init__.py | 12 - + gi/_glib/glibmodule.c | 45 +-- + gi/_glib/pyglib.c | 15 - + gi/_glib/pyglib.h | 1 - + gi/_glib/pygmaincontext.c | 126 ------- + gi/_glib/pygmaincontext.h | 40 --- + gi/_glib/pygmainloop.c | 362 ------------------- + gi/_glib/pygmainloop.h | 36 -- + gi/_glib/pygsource.c | 640 + ---------------------------------- + gi/_glib/pygsource.h | 3 - + gi/_gobject/__init__.py | 13 - + gi/gimodule.c | 9 + + gi/overrides/GLib.py | 116 +++++- + gi/overrides/GObject.py | 10 +- + gi/pygi-private.h | 1 + + gi/pygi-source.c | 247 +++++++++++++ + gi/pygi-source.h | 31 ++ + tests/test_glib.py | 22 +- + tests/test_gobject.py | 2 + + tests/test_source.py | 3 - + 28 files changed, 437 insertions(+), 1776 deletions(-) + +commit 326218a20681c1f2234a6eea1ed800382be57626 +Author: Simon Feltman +Date: Wed Sep 19 15:37:14 2012 -0700 + + Deprecate void pointer fields as general PyObject storage. + + Complete deprecation of gpointer struct fields as general + PyObject storage. Only int types are now allowed. + Assignment of anything other than an int or None raises + a TypeError stating the error and associated bug URL. + + https://bugzilla.gnome.org/show_bug.cgi?id=683599 + + gi/pygi-argument.c | 25 ++++++++++++++++----- + gi/pygi-info.c | 28 ++++-------------------- + tests/test_everything.py | 53 + +++++++++++++++++++++++++-------------------- + tests/test_overrides_gtk.py | 41 ----------------------------------- + 4 files changed, 54 insertions(+), 93 deletions(-) + +commit 3dba328010a4ffd9259700ffec95871c7341d491 +Author: Martin Pitt +Date: Tue Oct 23 11:59:08 2012 +0200 + + Add some MainLoop, MainContext, and Source test cases + + These cover the remaining static API and behaviour, so that we + have good + regression tests for converting them to GI. + + See https://bugzilla.gnome.org/show_bug.cgi?id=686443 + + tests/test_glib.py | 21 +++++++++++++++++++++ + tests/test_gobject.py | 11 +++++++++++ + tests/test_mainloop.py | 16 ++++++++++++++++ + tests/test_source.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 92 insertions(+) + +commit 7635340271df0a135873459e6a2a365fd4b187a2 +Author: Steve Frécinaux +Date: Wed Feb 9 18:37:33 2011 +0100 + + [API change] Do not bind gobject_get_data() and gobject_set_data() + + They will basically cause a crash if misused, and you can always use a + python member attribute instead. + + These methods were marked as deprecated for 3.4 and throwing a + warning, so + let's remove them for good now. + + https://bugzilla.gnome.org/show_bug.cgi?id=641944 + + Co-Authored-By: Martin Pitt + + docs/reference/pygobject.xml | 63 + -------------------------------------------- + gi/_gobject/pygobject.c | 44 ------------------------------- + 2 files changed, 107 deletions(-) + +commit cfec113e3b3eabf8db834f48b2f16792d1e841a3 +Author: Martin Pitt +Date: Tue Oct 23 08:17:40 2012 +0200 + + Add test for GLib.get_current_time() + + This adds a plausibility test, as well as ensuring the documented + return type. + This will be useful if/once we drop the static _glib binding. + + tests/test_glib.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit fb473b31054744e5ab59e9d4ed3b74571e27d3ff +Author: Martin Pitt +Date: Tue Oct 23 07:48:52 2012 +0200 + + Drop unnecessary static _glib bindings + + Drop static pyglib bindings which have straightforward and working + GLib GI + bindings. Add tests for all dropped functions to ensure they keep + working. + + docs/reference/pyglib-constants.xml | 59 ------- + docs/reference/pyglib-functions.xml | 270 ------------------------------ + gi/_glib/__init__.py | 24 --- + gi/_glib/glibmodule.c | 319 + ------------------------------------ + gi/_gobject/__init__.py | 9 - + gi/overrides/GLib.py | 16 ++ + gi/overrides/GObject.py | 32 ++++ + gi/overrides/Makefile.am | 1 + + tests/Makefile.am | 1 - + tests/test_glib.py | 46 ++++++ + tests/test_gobject.py | 4 + + tests/test_uris.py | 16 -- + 12 files changed, 99 insertions(+), 698 deletions(-) + +commit 126a10f765af3d3a6f08ce5db7ed9f3ef647848f +Author: Martin Pitt +Date: Tue Oct 23 06:12:08 2012 +0200 + + Fix OverflowError in source_remove() + + GSource IDs are unsigned, so we must use 'I' for parsing then, not + 'i'. + + https://bugzilla.gnome.org/show_bug.cgi?id=684526 + + gi/_glib/glibmodule.c | 2 +- + tests/test_source.py | 13 ++++++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +commit 15f7442bd0c45db25073e3d8494094f1c284ffa4 +Author: Martin Pitt +Date: Mon Oct 22 13:38:23 2012 +0200 + + Fix TestSource.testSources() test case + + PyGObject has established the assumption that the destruction of + a GLib.Source + Python object does not destroy the actual GSource, as shown in + TestSource.setup_timeout(), TestTimeout.test504337(), and + https://bugzilla.gnome.org/show_bug.cgi?id=504337. + + So we need to explicitly destroy our MySource and Idle objects + after using + them, as their callbacks always return True and we do not want them + to spill + over into other tests. + + Also fix the assertions to actually verify that MySources' callback + was callied + (pos > 0, not pos >= 0), and use the unittest comparison API instead + of a + simple assert statement. + + https://bugzilla.gnome.org/show_bug.cgi?id=686627 + + tests/test_source.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit b984a5fe0d065818a153f259db4dbde79534f084 +Author: Martin Pitt +Date: Mon Oct 22 17:38:56 2012 +0200 + + configure.ac: post-release bump to 3.7.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ce0825f58c3eba6084143e430605ffb597622369 +Author: Martin Pitt +Date: Mon Oct 22 17:37:17 2012 +0200 + + release 3.7.1 + + NEWS | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +commit a93763337ba7f952d787c42f45bfbb3ff02cc80d +Author: Martin Pitt +Date: Mon Oct 22 17:33:12 2012 +0200 + + Bump version to 3.7.1 + + Let's follow the real GNOME versioning from now on. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3fb13cc05a281970c3a624c2dd152996031b482c +Author: Martin Pitt +Date: Mon Oct 22 11:36:49 2012 +0200 + + test_mainloop code cleanup + + Ensure that sys.excepthook is always restored, even if the test + fails. Use the + assert{True,False,Equal} unittest API instead of simple asserts for + more useful + failure messages. + + tests/test_mainloop.py | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +commit 31061f20083aa60919f6763a12addbf2b052cab7 +Author: Simon Feltman +Date: Sun Oct 21 18:55:24 2012 -0700 + + Change install_properties to not use getattr on classes + + The usage of getattr for accessing a classes __gproperties__ + variable can be problematic due to the potential of it returning + the parent classes variable when it does not exist on the sub-class. + Similar to the fix for + https://bugzilla.gnome.org/show_bug.cgi?id=686496, + cls.__dict__.get is used to ensure this does not happen. + + https://bugzilla.gnome.org/show_bug.cgi?id=686559 + + gi/_gobject/propertyhelper.py | 2 +- + tests/test_properties.py | 6 ++++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +commit 438d3e68f19e2af5d027e18842ab05e0421d088d +Author: Simon Feltman +Date: Sat Oct 20 19:56:04 2012 -0700 + + Move property install function into propertyhelper.py + + Move _install_properties() into gi/_gobject/propertyhelper.py + and add unittests. + + https://bugzilla.gnome.org/show_bug.cgi?id=686559 + + gi/_gobject/__init__.py | 45 +++---------------------------- + gi/_gobject/propertyhelper.py | 45 +++++++++++++++++++++++++++++++ + tests/test_properties.py | 63 + +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 111 insertions(+), 42 deletions(-) + +commit 695a9077aa8f40357e050f090caa5e2b8c5c9593 +Author: Simon Feltman +Date: Sat Oct 20 03:11:07 2012 -0700 + + Fix Signal decorator to not use base class gsignals dict + + Fix install_signals to not use the parent classes __gsignals__ + dict if one does not exist on the given class. + + https://bugzilla.gnome.org/show_bug.cgi?id=686496 + + gi/_gobject/signalhelper.py | 2 +- + tests/test_signal.py | 43 + +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+), 1 deletion(-) + +commit 1ff04e846d50b948df6fa3260c548ef4f4779c58 +Author: Martin Pitt +Date: Fri Oct 19 09:05:01 2012 +0200 + + tests: Consistently use GLib.MainLoop + + ... instead of mixing GObject.MainLoop and GLib.MainLoop. + + tests/test_everything.py | 4 ++-- + tests/test_gdbus.py | 11 +++++------ + 2 files changed, 7 insertions(+), 8 deletions(-) + +commit ff7e7401b4cf50532fef70263f7559ea513b8333 +Author: Kalev Lember +Date: Wed Oct 17 18:27:14 2012 +0200 + + Install the .egg-info files into correct multilib directory + + This makes sure the .egg-info files end up in the same python + top level + directory as the rest of the gi .py files. + + https://bugzilla.gnome.org/show_bug.cgi?id=686315 + + Makefile.am | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 91e4cb2063d4e83fb1f6586a4396471d64f234f4 +Author: Simon Feltman +Date: Mon Oct 15 04:03:50 2012 -0700 + + Fix leaked vfunc return values + + Simple fix to dec ref returned values from closures wrapping + python functions. + + https://bugzilla.gnome.org/show_bug.cgi?id=686140 + + gi/pygi-closure.c | 1 + + tests/test_gi.py | 21 +++++++++++++++++++-- + 2 files changed, 20 insertions(+), 2 deletions(-) + +commit 75e373b99c3cb66dd60b13c803e5f7eec77cc415 +Author: Martin Pitt +Date: Mon Oct 15 07:42:05 2012 +0200 + + Skip Regress tests with --disable-cairo + + We need cairo to build g-i's Regress library, gir, and typelib. Update + configure.ac to only require cairo if --disable-cairo was not + given. With + --disable-cairo, skip building the Regress library and skip all + tests which use + it. + + https://bugzilla.gnome.org/show_bug.cgi?id=685094 + + configure.ac | 5 ++--- + tests/Makefile.am | 45 + +++++++++++++++++++++++++++------------------ + tests/test_everything.py | 15 +++++++++++---- + tests/test_overrides.py | 7 ++++++- + 4 files changed, 46 insertions(+), 26 deletions(-) + +commit a2ab72aa39824579d1767d1fdba7e1031341f86c +Author: Martin Pitt +Date: Fri Oct 12 11:05:24 2012 +0200 + + _pygi_marshal_from_py_uint64: Re-fix check of negative values + + Fix regression from commit 1bfcd5d94 (exposed by several test cases) + when using + Python 2.x. + + https://bugzilla.gnome.org/show_bug.cgi?id=685000 + + gi/pygi-marshal-from-py.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 22c22124b787ae67638aff89796d7ce14900ea8e +Author: Simon Feltman +Date: Mon Oct 8 05:54:30 2012 -0700 + + Fix leak with python callables as closure argument. + + The fix adds an extra args_data list to the PyGIInvokeState + structure. This list is used to track dynamically generated + closures that wrap python callables. This allows the ffi closure + and python callable to be freed when call scope has finished. + + https://bugzilla.gnome.org/show_bug.cgi?id=685598 + + gi/pygi-cache.c | 1 + + gi/pygi-closure.c | 41 +++++++++---- + gi/pygi-invoke-state-struct.h | 4 ++ + gi/pygi-invoke.c | 7 +++ + gi/pygi-marshal-cleanup.c | 14 +++++ + gi/pygi-marshal-cleanup.h | 4 ++ + gi/pygi-marshal-from-py.c | 57 ++++++++++++++---- + tests/test_everything.py | 137 + +++++++++++++++++++++++++++++++----------- + 8 files changed, 206 insertions(+), 59 deletions(-) + +commit c0bc69906df2db64560f7c054277ad1956aab57f +Author: Martin Pitt +Date: Thu Oct 11 17:49:30 2012 +0200 + + Gio overrides: Handle setting GSettings enum keys + + https://bugzilla.gnome.org/show_bug.cgi?id=685947 + + gi/overrides/Gio.py | 9 ++++++++- + tests/test_overrides_gio.py | 3 +++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit bbbb7c9ed047a22ac3c43f2b0331d3b5ea32e812 +Author: Martin Pitt +Date: Thu Oct 11 17:20:38 2012 +0200 + + tests: Check reading GSettings enums in Gio overrides + + Also split test_override() into several smaller test cases. + + tests/org.gnome.test.gschema.xml | 9 +++++++++ + tests/test_overrides_gio.py | 14 +++++++++----- + 2 files changed, 18 insertions(+), 5 deletions(-) + +commit 8a2e96cd4e33b6c119a368d73a9d5504576cdccb +Author: Martin Pitt +Date: Thu Oct 11 16:08:11 2012 +0200 + + Fix unsigned values in GArray/GList/GSList/GHash + + _pygi_hash_pointer_to_arg() needs to handle unsigned integers as well. + + https://bugzilla.gnome.org/show_bug.cgi?id=685860 + + gi/pygi-argument.c | 9 +++++++++ + tests/test_gi.py | 12 ++++++++++++ + 2 files changed, 21 insertions(+) + +commit d394acbb58b38e6f52ee71e8e663a892676ab9e4 +Author: Colin Walters +Date: Thu Oct 4 20:13:55 2012 -0400 + + build: Fix srcdir != builddir + + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1bfcd5d94b71edc9f03c8b3e87952a8bc8097586 +Author: Alban Browaeys +Date: Thu Sep 27 22:44:22 2012 +0200 + + _pygi_marshal_from_py_uint64(): Use correct data type in py2.7 check + + Casting an unsigned to signed and checking if positive was not + good. Check the + unsigned 64 is below G_MAXUINT64 instead. + + Side issue in https://bugzilla.gnome.org/show_bug.cgi?id=685000 + + gi/pygi-marshal-from-py.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit f0870336b9fc7797895f206e0d3ef17a19efe253 +Author: Johan Dahlin +Date: Tue Oct 2 05:30:16 2012 -0700 + + Install an .egg-info file + + This will help easy_install and pip to figure out that PyGObject + is already installed. + + https://bugzilla.gnome.org/show_bug.cgi?id=680138 + + Makefile.am | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +commit 4c9318d97aa34051a0460e8db2ed0f963126b7f5 +Author: Johan Dahlin +Date: Thu Oct 4 09:42:41 2012 +0200 + + PyGProps_getattro(): Fix GObjectClass leak + + https://bugzilla.gnome.org/show_bug.cgi?id=685218 + + gi/_gobject/pygobject.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 2aa61520eb4f293ce94d54605d7642a39e18e03d +Author: Olivier Crête +Date: Mon Sep 17 15:16:32 2012 -0400 + + pygobject.c: Don't leak GObjectClass reference + + https://bugzilla.gnome.org/show_bug.cgi?id=684062 + + gi/_gobject/pygobject.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 43d356d03d4c83e9de3c56f98a70d387b46f17af +Author: Alban Browaeys +Date: Sat Sep 29 01:17:14 2012 +0200 + + Fix memory leak in _pygi_argument_to_array() + + Length arg and type info need to be unref'ed. + + https://bugzilla.gnome.org/show_bug.cgi?id=685082 + + gi/pygi-argument.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit 34270a109d2af20391c80e88874ee7303eaf5c09 +Author: Martin Pitt +Date: Fri Sep 28 07:42:51 2012 +0200 + + Fix error messages for out of range numbers + + PyErr_Format() does not understand %lli and %li, it needs to be %lld + and %ld. + So we cannot use those and G_GINT64_FORMAT. + + Also remove the "if (long_ < G_MININT64 || long_ > G_MAXINT64)" + check, as long_ + is a gint64 which can't possibly overflow its own data type. It + would also have + an unprintable error message. + + https://bugzilla.gnome.org/show_bug.cgi?id=684314 + + gi/pygi-marshal-from-py.c | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +commit 7f1422bf929976722edd6144beb0b4c96d74391b +Author: Martin Pitt +Date: Fri Sep 28 06:59:38 2012 +0200 + + Kill dbus-daemon after running tests + + dbus-launch does not kill the spawned dbus-daemon by itself (see + https://bugs.freedesktop.org/show_bug.cgi?id=39196), so do that + after running + our tests. Take care to preserve the exit code. + + https://bugzilla.gnome.org/show_bug.cgi?id=685009 + + tests/Makefile.am | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit bfd9c8fac1ea240b29fbcd4185dc1702539c1e96 +Author: Martin Pitt +Date: Thu Sep 27 08:18:34 2012 +0200 + + GVariant overrides: Support empty tuple arrays + + Implement the "empty value" branch in _create_tuple(), so that + _create_array() + can call it for parsing the element type for an empty array. + + This fixes creating variants such as GLib.Variant('a(ii)', []). + + https://bugzilla.gnome.org/show_bug.cgi?id=684928 + + gi/overrides/GLib.py | 30 +++++++++++++++++++++++------- + tests/test_overrides_glib.py | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 7 deletions(-) + +commit 75d452ea5b179c3585adcf95356b4316c9180768 +Author: Martin Pitt +Date: Thu Sep 27 06:50:12 2012 +0200 + + TestGVariant: Split creation test case into several smaller ones + + tests/test_overrides_glib.py | 20 ++++++-------------- + 1 file changed, 6 insertions(+), 14 deletions(-) + +commit 4a20bcb3f97614044d351f8e436a81d332db55ba +Author: Martin Pitt +Date: Tue Sep 25 09:10:10 2012 +0200 + + Fix unused variables and results + + This gets rid of all warnings except the deprecated symbol ones. + + gi/_glib/pygiochannel.c | 9 +++------ + gi/pygi-argument.c | 4 +--- + gi/pygi-callbacks.c | 4 ---- + gi/pygi-ccallback.c | 1 - + gi/pygi-repository.c | 3 +-- + 5 files changed, 5 insertions(+), 16 deletions(-) + +commit 5285f14fee93d2729d4422c40a945adc2be69c14 +Author: Martin Pitt +Date: Tue Sep 25 08:56:20 2012 +0200 + + tests: Fix wrong return type in test_int64_callback() + + https://bugzilla.gnome.org/show_bug.cgi?id=684700 + + tests/testhelpermodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e14ebab6099d082466ec11ca21d44de0d6017216 +Author: Giovanni Campagna +Date: Wed Sep 19 00:10:57 2012 +0200 + + Fix GValue marshalling of long and unsigned long + + long can be equivalent to int64 or int32, depending on the + architecture, + and GI conflates this distinction in the typelib, but GType does + not, and + warns if the wrong accessor is used. + + https://bugzilla.gnome.org/show_bug.cgi?id=684331 + + gi/pygi-argument.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +commit 50571dd27d1f7c6bed8c5aaa518b504c9f4c4ab6 +Author: Simon Feltman +Date: Wed Sep 19 19:07:00 2012 -0700 + + Clean up deprecation message for assigning gpointers to objects. + + The previous deprecation message was worded as if the deprecation + had already occurred and it has not. + + https://bugzilla.gnome.org/show_bug.cgi?id=683599 + + gi/pygi-info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4bfe7972546413f46f5c36737ff03bb5612c1921 +Author: Olivier Crête +Date: Tue Sep 18 08:52:02 2012 +0200 + + pygi-property: Lookup property in base classes of non-introspected + types + + Look for introspection data in the base classes of non-introspected + gtypes. + This is necessary to look up introspection data for plugins. + + https://bugzilla.gnome.org/show_bug.cgi?id=684058 + + gi/pygi-property.c | 28 ++++++++++++++-------------- + tests/test_everything.py | 12 ++++++++++++ + 2 files changed, 26 insertions(+), 14 deletions(-) + +commit 7aa94cc861082147b9c382b930f3257f0a842c84 +Author: Martin Pitt +Date: Mon Sep 24 09:41:10 2012 +0200 + + post-release bump to 3.4.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fcceed3adb8d78baba68861a1408627321b2c1ef +Author: Martin Pitt +Date: Mon Sep 24 09:35:33 2012 +0200 + + release 3.4.0 + + NEWS | 3 +++ + configure.ac | 4 ++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit 645a9d9d4712f8f0d1b63899b309bbc97eb1f216 +Author: Martin Pitt +Date: Mon Sep 24 09:27:47 2012 +0200 + + Bump g-i dependency to 1.33.14 + + To ensure we have all the Regress test APIs that we use. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b6f4ef327fbeaa10fd74571c3df540311834d6ae +Author: Martin Pitt +Date: Mon Sep 17 22:52:49 2012 +0200 + + post-release bump to 3.3.93 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7e154cf01cf0ce7a8b52c45ba4db755f73b45d1d +Author: Martin Pitt +Date: Mon Sep 17 22:48:13 2012 +0200 + + release 3.3.92 + + NEWS | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit adbe30dc72b4d88bb31055f6ee33fddf32638af9 +Author: Martin Pitt +Date: Mon Sep 17 22:32:55 2012 +0200 + + release-news: Generate HTML changelog + + In addition to producing a NEWS paragraph from the changelog, + generate a + changelog HTML which can be put into blog announcements. + + Update HACKING to point this out, too. + + HACKING | 2 +- + Makefile.am | 22 ++++++++++++++++------ + 2 files changed, 17 insertions(+), 7 deletions(-) + +commit be4a0682bdd189ee908ab1961001f759a80e133c +Author: Simon Feltman +Date: Sun Sep 16 17:27:25 2012 -0700 + + [API add] Add ObjectInfo.get_abstract method + + Adds exposure of g_object_info_get_abstract to python for + helping with analysis of non-constructable objects from + within python. + + https://bugzilla.gnome.org/show_bug.cgi?id=675581 + + gi/pygi-info.c | 8 ++++++++ + tests/test_gi.py | 12 ++++++++++++ + 2 files changed, 20 insertions(+) + +commit 3ada408434860d0c8eee6c6a869b5a3d801cfbc8 +Author: Simon Feltman +Date: Thu Sep 13 20:53:22 2012 -0700 + + Add deprecation warning when setting gpointers to anything other + than int. + + This is a first pass which does not change anything except add + a warning + when anything other than an int is set on a gpointer on a boxed type. + + https://bugzilla.gnome.org/show_bug.cgi?id=683599 + + gi/pygi-info.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit a047f61f26d9c78b82d22948199313e5a389e918 +Author: Martin Pitt +Date: Mon Sep 17 09:41:24 2012 +0200 + + test_properties: Test accessing a property from a superclass + + We already cover accessing the superclass' property if that was + defined in + Python. Add a corresponding test case for a property defined in C. + + See https://bugzilla.gnome.org/show_bug.cgi?id=684058 + + tests/test_properties.py | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit 3e6a4000cbc4b0cb503fcd89b50202ed0b70d3a7 +Author: Martin Pitt +Date: Mon Sep 17 09:31:05 2012 +0200 + + test_properties.py: Consistent test names + + Use underscore style method/test case names consistently. Also rename + some test + cases to better describe what they do. + + tests/test_properties.py | 78 + ++++++++++++++++++++++++------------------------ + 1 file changed, 39 insertions(+), 39 deletions(-) + +commit 4069c3d8547f35437e0cee175a5912febe25326d +Author: Martin Pitt +Date: Wed Sep 12 06:51:24 2012 +0200 + + test_everything: Ensure TestSignals callback does get called + + tests/test_everything.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 4e4c87e3868948743e0446abe2ba0cf5626374c4 +Author: Nicolas Dufresne +Date: Fri Sep 7 17:17:09 2012 -0400 + + argument: Fix 64bit integer convertion from GValue + + Trying to get a 64bit integer using the wrong getter was resulting + in an + assertion and 0 being returned. + + Co-Authored-By: Martin Pitt + + https://bugzilla.gnome.org/show_bug.cgi?id=683596 + + gi/pygi-argument.c | 8 ++++++-- + tests/test_everything.py | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+), 2 deletions(-) + +commit e474ce243ea7a58358af344ccadb1418f4d2c8eb +Author: Martin Pitt +Date: Tue Sep 11 12:32:10 2012 +0200 + + Add Simon Feltman as a project maintainer + + Signed-off-By: Martin Pitt + Signed-off-By: Paolo Borelli + + pygobject.doap | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit ee1fc78258f10e8a7872ee3da6c9ad6e7984706e +Author: Martin Pitt +Date: Tue Sep 11 10:17:50 2012 +0200 + + test_signals.py: Drop global type variables + + Just use the real types and flags from GObject instead of redefining + aliases + for them. They weren't used consistently, make the tests harder to + read, and we + really do not want global single-letter variables like "f" and "l". + + tests/test_signal.py | 38 ++++++++++++++++---------------------- + 1 file changed, 16 insertions(+), 22 deletions(-) + +commit 3688cf6efe7161585b943cfaafcfd4610b7ad768 +Author: Martin Pitt +Date: Tue Sep 11 10:11:58 2012 +0200 + + test_signals.py: Consistent test names + + Use underscore style method/test case names consistently. + + tests/test_signal.py | 88 + ++++++++++++++++++++++++++-------------------------- + 1 file changed, 44 insertions(+), 44 deletions(-) + +commit 4559247553b792db956f69c9674c12344d719c82 +Author: Martin Pitt +Date: Tue Sep 11 09:43:14 2012 +0200 + + Add test cases for GValue signal arguments + + These cover various types, (u)int(64) and string. + + Keep the test case for implicit int64 GValues disabled, as this + currently does + not work and it is not clear whether it should: + https://bugzilla.gnome.org/show_bug.cgi?id=683775 + + tests/test_signal.py | 41 +++++++++++++++++++++++++++++++++++++++++ + tests/testhelpermodule.c | 17 +++++++++++++++++ + 2 files changed, 58 insertions(+) + +commit fddb01b0b71b68d154d130cf40fd5f38647b1a4d +Author: Martin Pitt +Date: Tue Sep 11 09:31:18 2012 +0200 + + Add test for GValue signal return values + + Another attempt to reproduce the reported error in + https://bugzilla.gnome.org/show_bug.cgi?id=683596 + but this works already. + + tests/test_signal.py | 13 +++++++++++++ + tests/testhelpermodule.c | 36 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+) + +commit 4f77c7798563ea436ff5b6306a987f03de50b211 +Author: Simon Feltman +Date: Fri Sep 7 02:32:15 2012 -0700 + + Improve setting pointer fields/arguments to NULL using None + + Setting gi pointers will set them to the address of the python object. + This is good except in the case of None which should be used to NULL + the pointer out as a special case. + + Commit 21b1d17d2a already fixed this. This improved patch + does that in a cleaner and safer way and adds more comments. + + https://bugzilla.gnome.org/show_bug.cgi?id=683150 + + gi/pygi-argument.c | 8 +------- + gi/pygi-info.c | 14 +++++++++++++- + 2 files changed, 14 insertions(+), 8 deletions(-) + +commit 15046b5a11f6c58a3e5a9c50cf0ce7f31f2cd55f +Author: Martin Pitt +Date: Mon Sep 10 16:46:30 2012 +0200 + + Test gint64 C signal arguments and return values + + tests/test_signal.py | 12 ++++++++++++ + tests/testhelpermodule.c | 14 ++++++++++++++ + 2 files changed, 26 insertions(+) + +commit 822d9e07a95f706a40f64335765293542787da90 +Author: Martin Pitt +Date: Mon Sep 10 16:29:32 2012 +0200 + + Test in/out int64 GValue method arguments. + + See https://bugzilla.gnome.org/show_bug.cgi?id=683596 + + tests/test_gi.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 2d83e52233812618493af4b165615e8741ba41c8 +Author: Martin Pitt +Date: Wed Sep 5 08:54:53 2012 +0200 + + Bump g-i dependency to 1.33.10 + + To ensure we have all the Regress test APIs that we use. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6a4f4dc9a3d21c3ac8a0aa51432fb8952b4e1ebf +Author: Thibault Saunier +Date: Wed Aug 8 12:57:41 2012 -0400 + + Fix -uninstalled.pc.in file + + https://bugzilla.gnome.org/show_bug.cgi?id=683379 + + pygobject-3.0-uninstalled.pc.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit d8f1398dbc7fa7803639c542a607f24f18614ad6 +Author: Martin Pitt +Date: Mon Sep 3 22:16:47 2012 +0200 + + post-release bump to 3.3.92 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ea992324b8197b2d04ff2849b9ab46f8a04b4ed7 +Author: Martin Pitt +Date: Mon Sep 3 22:04:01 2012 +0200 + + release 3.3.91 + + NEWS | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +commit 1e1f5b2f2f15547c1f2cbc948d2b764bd0a37c44 +Author: Martin Pitt +Date: Mon Sep 3 21:57:00 2012 +0200 + + Fix exception test case for Python 2 + + Regression from commit 77844c5 which did not work with Python 2. + + tests/test_everything.py | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +commit 41bb687c058e08b05108b4b2f081cd83d4f93da8 +Author: Martin Pitt +Date: Mon Sep 3 21:16:01 2012 +0200 + + Bump g-i dependency + + Require at least 1.33.9, as we got a couple of bug fixes there which + the tests, + and for some cases the code, depend on. We actually require 1.33.10 + for all + tests to succeed, but that hasn't been released yet. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 77844c571ad0badc189428b93de9f2572051b67e +Author: Martin Pitt +Date: Mon Sep 3 17:58:38 2012 +0200 + + Show proper exception when trying to allocate a disguised struct + + Instead of a simple "MemoryError" with no details, raise a proper + TypeError with a traceback and an explanation what happened. + + https://bugzilla.gnome.org/show_bug.cgi?id=639972 + + gi/pygi-struct.c | 7 +++++++ + tests/test_everything.py | 13 +++++++++++++ + 2 files changed, 20 insertions(+) + +commit 0d099bdb3f4bbd962e5e60b583673d9e6f5673cc +Author: Mark Nauwelaerts +Date: Mon Sep 3 16:47:22 2012 +0200 + + Support marshalling GParamSpec signal arguments + + Fix marshalling GParamSpec arguments from C to Python. + + https://bugzilla.gnome.org/show_bug.cgi?id=683099 + + Co-Authored-By: Martin Pitt + + gi/pygi-argument.c | 10 +++++++++- + tests/test_signal.py | 14 ++++++++++++++ + 2 files changed, 23 insertions(+), 1 deletion(-) + +commit 69fb92c22b3f3d1d5e8c3e14134eee3242fdc5fc +Author: Martin Pitt +Date: Mon Sep 3 16:06:49 2012 +0200 + + Add test for a signal that returns a GParamSpec + + https://bugzilla.gnome.org/show_bug.cgi?id=683265 + + tests/test_signal.py | 6 ++++++ + tests/testhelpermodule.c | 12 ++++++++++++ + 2 files changed, 18 insertions(+) + +commit a7c524219987fbf37e455a91e4c78d2b9b4db12d +Author: Simon Feltman +Date: Tue Mar 20 04:33:50 2012 -0700 + + [API add] Add Signal class for adding and connecting custom signals. + + The Signal class provides easy creation of signals and removes the + need for __gsignals__ in client code. The Signal class can also be + used as a decorator for wrapping up the custom closure. As well as + providing a "BoundSignal" when accessed on an instance for making + connections without specifying a signal name string. + Python3 annotations can also be used to supply closure argument and + return types when Signal is used as a decorator. For example: + + class Eggs(GObject.GObject): + @GObject.Signal + def spam(self, count:int): + pass + + https://bugzilla.gnome.org/show_bug.cgi?id=434924 + + examples/signal.py | 34 ++++-- + gi/_gobject/Makefile.am | 3 +- + gi/_gobject/__init__.py | 5 + + gi/_gobject/signalhelper.py | 251 + ++++++++++++++++++++++++++++++++++++++++++++ + tests/test_signal.py | 208 ++++++++++++++++++++++++++++++++++-- + 5 files changed, 482 insertions(+), 19 deletions(-) + +commit 96fa22369fd188465559fc904c7f76e73040e6dd +Author: Martin Pitt +Date: Mon Sep 3 15:32:12 2012 +0200 + + Fix pygtkcompat's Gtk.TreeView.insert_column_with_attributes() + + We have a proper implementation for insert_column_with_attributes() + now, so + drop pygtkcompat's empty stub for it. + + Also improve test case for + Gtk.TreeView.insert_column_with_attributes(). + + gi/pygtkcompat.py | 6 ------ + tests/test_overrides_gtk.py | 16 ++++++++-------- + 2 files changed, 8 insertions(+), 14 deletions(-) + +commit 542cf22c9de9b2094868c4e879b0f24b15c4c012 +Author: Marta Maria Casetti +Date: Mon Sep 3 13:06:22 2012 +0200 + + Add override for Gtk.TreeView.insert_column_with_attributes() + + https://bugzilla.gnome.org/show_bug.cgi?id=679415 + + Co-Authored-By: Martin Pitt + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides_gtk.py | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+) + +commit 1c73e845361e471b1c3a3f17e40e6a6cfa740877 +Author: Martin Pitt +Date: Mon Sep 3 11:09:55 2012 +0200 + + .gitignore: Add missing built files + + .gitignore | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +commit 96431f393036a688666dcf67911bf12b9824b264 +Author: Martin Pitt +Date: Mon Sep 3 11:07:32 2012 +0200 + + Ship tests/gi in tarball + + Spotted by distcheck. + + tests/Makefile.am | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit dc2c6e6f60d2757462cbceef6176b0b3013904d3 +Author: Martin Pitt +Date: Mon Sep 3 10:18:45 2012 +0200 + + Fix separate build tree and distcheck + + Fix regression from c7c95a79: We must set sys.path in runtests.py + properly and + cannot rely on setting $PYTHONPATH from Makefile.am only. Python + always + prepends the directory of the source file to sys.path, but that + points to the + source dir, not the build dir. The build dir has to take precedence, + otherwise + we fail to import the built libraries. + + tests/runtests-windows.py | 10 +++++++--- + tests/runtests.py | 13 ++++++++----- + 2 files changed, 15 insertions(+), 8 deletions(-) + +commit 2d8f48f4ff56bb75985136452b50b75895258608 +Author: Martin Pitt +Date: Mon Sep 3 07:57:01 2012 +0200 + + Split test_overrides.py + + Split the huge test_overrides.py into separate files for gdk, gtk, + gio, glib, + and pango. Further split the monolithic classes for Gtk and Gio + into several + ones. + + https://bugzilla.gnome.org/show_bug.cgi?id=683188 + + tests/Makefile.am | 5 + + tests/test_overrides.py | 2198 + +---------------------------------------- + tests/test_overrides_gdk.py | 119 +++ + tests/test_overrides_gio.py | 114 +++ + tests/test_overrides_glib.py | 445 +++++++++ + tests/test_overrides_gtk.py | 1517 ++++++++++++++++++++++++++++ + tests/test_overrides_pango.py | 32 + + 7 files changed, 2234 insertions(+), 2196 deletions(-) + +commit 1223358e2c558dd7ac3300126f989054ec5a5b3f +Author: Martin Pitt +Date: Mon Sep 3 07:17:57 2012 +0200 + + _pygi_argument_to_object(): Clean up array unmarshalling + + The NULL case is already handled at the top, so it does not need to be + re-checked again. + + Emit a critical if we fail to allocate a Python array of the + requested size. + + gi/pygi-argument.c | 47 ++++++++++++++++------------------------------- + 1 file changed, 16 insertions(+), 31 deletions(-) + +commit 65bfbc624bc9da6e18ff2945b14099ab8eeb7601 +Author: Alban Browaeys +Date: Wed Aug 29 21:24:17 2012 +0200 + + Fix memory leak in _pygi_argument_to_object() + + Avoid leaking the item_type_info when breaking out of the + switch in _pygi_argument_to_object() for unmarshalling arrays. + + https://bugzilla.gnome.org/show_bug.cgi?id=682979 + + gi/pygi-argument.c | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 21b1d17d2ada2edf4063a4262b3436c279da3dc2 +Author: Simon Feltman +Date: Sat Sep 1 03:40:31 2012 -0700 + + Fix setting pointer fields/arguments to NULL using None. + + Setting gi pointers will set them to the address of the python object. + This is good except in the case of None which should be used to NULL + the pointer out as a special case. + + https://bugzilla.gnome.org/show_bug.cgi?id=683150 + + gi/pygi-argument.c | 8 +++++++- + tests/test_overrides.py | 41 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+), 1 deletion(-) + +commit 6123e6f5001ca5eaea18123d8a53525abab31a45 +Author: Martin Pitt +Date: Thu Aug 23 06:44:27 2012 +0200 + + Fix for python 2.6, drop support for < 2.6 + + Replace sys.version_info.major access to tuple access which also + works for + Python 2.6. + + When building for Python 2.6, inject some missing unittest API such as + @unittest.skipUnless and assertGreaterEqual() into the unittest + module in + runtests.py, so that the tests have a chance to run. + + As building with Python 2.5 has been broken for a long time with + nobody + complaining, and 2.5 is ancient, bump minimum Python requirement to + 2.6. Drop + obsolete #ifdef paths which only apply to <= 2.5. + + https://bugzilla.gnome.org/show_bug.cgi?id=682422 + + configure.ac | 2 +- + gi/_glib/pyglib-python-compat.h | 8 -------- + gi/_gobject/gobjectmodule.c | 8 -------- + gi/module.py | 2 +- + tests/runtests.py | 27 +++++++++++++++++++++++++++ + tests/test_gi.py | 2 +- + 6 files changed, 30 insertions(+), 19 deletions(-) + +commit b1a9848a7a7255e6b1ccd98712dd62b1514078b9 +Author: Thibault Saunier +Date: Tue Aug 21 07:54:09 2012 +0200 + + Allow overrides in other directories than gi itself + + Use pkgutil.extend_path() for the gi and gi.overrides modules, so that + libraries can install overrides in a path that is different from + the one that + pygobject installs itself into. These overrides need to put this + into their + __init__.py at the top: + + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + + and put themselves somewhere into the default PYTHONPATH. + + https://bugzilla.gnome.org/show_bug.cgi?id=680913 + + Co-Authored-By: Martin Pitt + Co-Authored-By: Simon Feltman + + gi/__init__.py | 4 ++++ + gi/overrides/__init__.py | 4 ++++ + tests/gi/__init__.py | 2 ++ + tests/gi/overrides/Regress.py | 26 ++++++++++++++++++++++++++ + tests/gi/overrides/__init__.py | 2 ++ + tests/test_overrides.py | 6 ++++++ + 6 files changed, 44 insertions(+) + +commit c7c95a795eee499373499ea5b771447746317bfb +Author: Simon Feltman +Date: Thu Aug 23 06:03:09 2012 +0200 + + Clean up sys.path handling in tests + + Only set sys.path once in runtests.py, not in the individual test + modules. This + reduces hidden dependencies between tests by building up a run + order dependent + search path, and also makes it easier in the future to run the + tests against + the installed system libraries. + + Side issue in https://bugzilla.gnome.org/show_bug.cgi?id=680913 + + tests/runtests-windows.py | 6 +++++- + tests/runtests.py | 3 +++ + tests/test_everything.py | 1 - + tests/test_gdbus.py | 3 --- + tests/test_overrides.py | 3 --- + tests/test_pygtkcompat.py | 3 --- + 6 files changed, 8 insertions(+), 11 deletions(-) + +commit 3e3525e93d852cde0f63e835b774a9b004773c69 +Author: Simon Feltman +Date: Sun Aug 19 02:30:39 2012 -0700 + + Fix dynamic creation of enum and flag gi types for Python 3.3 + + Importing Gtk was crashing on instantiation of dynamic Enum and Flag + subclasses due to what looks to be an unsupported technique. Change + tp_new() method for classes dynamically derived from PyGEnum_Type and + PyGFlags_Type to call PyLong_Type.tp_new() instead of attempting + to call + __new__() as a python method. This technique seems to work with all + versions of python so the previous python version checking also became + unnecessary. + + https://bugzilla.gnome.org/show_bug.cgi?id=682323 + + gi/_gobject/pygenum.c | 29 ++++++++++++++++------------- + gi/_gobject/pygflags.c | 21 +++++++++------------ + 2 files changed, 25 insertions(+), 25 deletions(-) + +commit dd31b67e821f92b5f1c2ee0382cac5edd477cd11 +Author: Paolo Borelli +Date: Wed Aug 22 10:45:39 2012 +0200 + + [API add] Override g_menu_item_set_attribute + + This C utility API take a vararg, add a corresponding override that + takes a list of tuples + + https://bugzilla.gnome.org/show_bug.cgi?id=682436 + + gi/overrides/Gio.py | 10 ++++++++++ + tests/test_overrides.py | 11 +++++++++++ + 2 files changed, 21 insertions(+) + +commit 836902801373e386d370c44e7487aac3432f19f6 +Author: Martin Pitt +Date: Mon Aug 20 23:37:40 2012 +0200 + + post-release bump to 3.3.91 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6a629e23ff7b0d6f532184017577c7427d577e28 +Author: Martin Pitt +Date: Mon Aug 20 23:05:49 2012 +0200 + + release 3.3.90 + + NEWS | 13 +++++++++++++ + configure.ac | 2 +- + 2 files changed, 14 insertions(+), 1 deletion(-) + +commit 5cd18c9bd59a60b930ced0b35d728c12bb3291c7 +Author: Mathieu Duponchelle +Date: Mon Aug 20 22:54:52 2012 +0200 + + Implement marshalling for GParamSpec + + https://bugzilla.gnome.org/show_bug.cgi?id=681565 + + Co-Authored-By: Martin Pitt + + gi/pygi-marshal-to-py.c | 16 ++++++++++++---- + tests/test_gi.py | 14 ++++++++++++++ + 2 files changed, 26 insertions(+), 4 deletions(-) + +commit 16462de3f025f14706ec23fa9b3653feb66ad57f +Author: Martin Pitt +Date: Mon Aug 20 15:24:10 2012 +0200 + + Fix pep8/pyflakes invocation + + Fix regression from commit 1e056e4f4a: Do fail the tests if + pyflakes/pep8 + exist, but fail. + + tests/Makefile.am | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 1bee194274bcda9ba5f6751fa921218a92c8ac72 +Author: Simon Feltman +Date: Thu Aug 16 16:05:52 2012 -0700 + + Fix erronous import statements for Python 3.3 + + Update pygobject-external.h to use GType (which is what GTypeWrapper + is + exposed as) instead of GTypeWrapper when attempting import. + + Catch ImportError around attempted imports of a typelibs override file + which don't always exist (GObject...). This is a behavioural change in + Python 3.3 (http://bugs.python.org/issue15715), but let's fix + it anyway. + + https://bugzilla.gnome.org/show_bug.cgi?id=682051 + + gi/module.py | 7 +++++-- + gi/pygobject-external.h | 2 +- + 2 files changed, 6 insertions(+), 3 deletions(-) + +commit 1e056e4f4a19fd1139187467677c2592c2722290 +Author: Martin Pitt +Date: Mon Aug 20 11:52:08 2012 +0200 + + Do not fail tests if pyflakes or pep8 are not installed + + These tools might not be desirable in restricted build environments or + backports, and e. g. Fedora patches those out. So let the tests + work without + these tools. + + tests/Makefile.am | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit c219fa6da89a7d55c5c111751684aae6876a9fe3 +Author: Martin Pitt +Date: Mon Aug 20 11:42:47 2012 +0200 + + gtk-demo: Fix some PEP-8 whitespace issues + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 3 +-- + demos/gtk-demo/demos/dialogs.py | 2 +- + demos/gtk-demo/demos/rotatedtext.py | 3 +-- + 3 files changed, 3 insertions(+), 5 deletions(-) + +commit 0ac2a85cae368c046839b5619a96efc9e0b91ba3 +Author: Martin Pitt +Date: Mon Aug 20 11:38:50 2012 +0200 + + test_overrides.py: Fix PEP8 whitespacing + + tests/test_overrides.py | 48 + +++++++++++++++++++++++++----------------------- + 1 file changed, 25 insertions(+), 23 deletions(-) + +commit 631a9cd05cbc7dc3d0f743a84b948ef7d93c0ed4 +Author: Martin Pitt +Date: Mon Aug 20 11:36:19 2012 +0200 + + Ignore E124 pep8 error + + This is "closing bracket does not match visual indentation" which + is really + stupid. We do want the closing bracket at the same indentation level + as the + opening bracket, not the indentation level of the whole statement. + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 266d37719bb54e6f04d23ff21bcceb9514e20ff2 +Author: David Malcolm +Date: Mon Aug 20 11:27:52 2012 +0200 + + Fix unmarshalling of gssize + + Do not assume that the v_int union member always corresponds to a + gssize. This + is not true on big-endian 64 bit machines like ppc64, so add a new + gi_argument_to_gssize() and use it properly. + + https://bugzilla.gnome.org/show_bug.cgi?id=680693 + https://bugzilla.redhat.com/show_bug.cgi?id=842880 + + gi/pygi-argument.c | 53 + +++++++++++++++++++++++++++++++++++++++++++++--- + gi/pygi-argument.h | 1 + + gi/pygi-closure.c | 2 +- + gi/pygi-info.c | 4 ++-- + gi/pygi-signal-closure.c | 2 +- + 5 files changed, 55 insertions(+), 7 deletions(-) + +commit 1c5d497d3c354f4d02f1d4570df2c61d6f47300c +Author: David Malcolm +Date: Mon Aug 20 11:19:27 2012 +0200 + + Fix various endianess errors + + Fix code which assumed little endian behaviour when mixing different + types of + ints, putting ints into pointers, etc. + + https://bugzilla.gnome.org/show_bug.cgi?id=680692 + https://bugzilla.redhat.com/show_bug.cgi?id=841596 + + gi/pygi-argument.c | 64 +++++++++++++-- + gi/pygi-argument.h | 6 ++ + gi/pygi-cache.c | 2 + + gi/pygi-closure.c | 57 ++++++++++++- + gi/pygi-marshal-from-py.c | 203 + ++++++++++++++++++++++++++++++++++++---------- + gi/pygi-marshal-from-py.h | 3 + + gi/pygi-marshal-to-py.c | 137 ++++++++++++++++++++++++------- + 7 files changed, 391 insertions(+), 81 deletions(-) + +commit ee6da6f1aa2cd6e55834f9edc17f785613d00031 +Author: Paolo Borelli +Date: Wed Aug 15 13:16:11 2012 +0200 + + Add unit test for the TreeModelSort override + + tests/test_overrides.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 9f027daa5737107b5959964b699c0089aec8ab1e +Author: Simon Feltman +Date: Thu Aug 9 03:33:06 2012 -0700 + + Gtk overrides: Add TreeModelSort.__init__(self, model) + + This adds "model" as a required argument to TreeModelSort + instead of it being a hidden keyword argument. This is needed + because the model property is set to construct only and the + default value of None/NULL makes the object useless anyhow. + + https://bugzilla.gnome.org/show_bug.cgi?id=681477 + + gi/overrides/Gtk.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit c8424c2bb19356679e250e73542682dd5f4c74a5 +Author: Manuel Quiñones +Date: Fri Aug 10 09:38:24 2012 -0300 + + Convert Gtk.CellRendererState in the pygi-convert script + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=681596 + + pygi-convert.sh | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 54d829b34a0d32d852db370f61cc7f25c149f373 +Author: Paolo Borelli +Date: Mon Aug 6 16:19:28 2012 +0200 + + More updates to the HACKING file + + module-install has been replaced with 'ftpadmin install' and other + minor + changes + + HACKING | 26 ++++++++++---------------- + 1 file changed, 10 insertions(+), 16 deletions(-) + +commit 0788880c6cf4070d3db09896c165fe470d2ec186 +Author: Paolo Borelli +Date: Mon Aug 6 16:00:39 2012 +0200 + + Post-release version bump to 3.3.6 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 664403d953c3e07077d0db90bfae3b51c7f1767c +Author: Paolo Borelli +Date: Mon Aug 6 15:52:22 2012 +0200 + + release 3.3.5 + + NEWS | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +commit b748753a2a9af018001213e2e58c48d6c8bfadbd +Author: Paolo Borelli +Date: Mon Aug 6 15:44:32 2012 +0200 + + Update HACKING file to mention "make release-news" + + HACKING | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit 587a0c33901383b891f8eb77351c17f06af20b4f +Author: Paolo Borelli +Date: Mon Aug 6 15:38:23 2012 +0200 + + pygi-closure: remove unused variables + + These variables are assigned but never actually used + + gi/pygi-closure.c | 8 -------- + 1 file changed, 8 deletions(-) + +commit dbc6df6aad7197fcf8721ade429baadd749f7069 +Author: Martin Pitt +Date: Fri Aug 3 07:13:55 2012 +0200 + + tests: Do not break on Pango warnings + + In some restricted environments (like chroots) we sometimes get + warnings from + Pango when it cannot find an appropriate font. Do not make the tests + fail on + those. + + tests/test_overrides.py | 4 ++++ + tests/test_pygtkcompat.py | 6 ++++++ + 2 files changed, 10 insertions(+) + +commit 770e6abfd5bc5dad7d5f56a18f1ef63f9754ada9 +Author: Martin Pitt +Date: Fri Aug 3 06:45:48 2012 +0200 + + Fix list marshalling on big-endian machines + + On big endian machines we cannot simply set e. g. GIArgument.v_int8 + and expect + GIArgument.v_pointer to be a correct representation. This needs to use + GINT_TO_POINTER/GPOINTER_TO_INT properly, so use the already existing + _pygi_hash_pointer_to_arg()/_pygi_arg_to_hash_pointer() methods + in marshalling + to and from GList and GSList, and handle int8 and int16 as well. + + Part of porting pygobject to ppc64: + https://bugzilla.redhat.com/show_bug.cgi?id=842880 + https://bugzilla.gnome.org/show_bug.cgi?id=680693 + + gi/pygi-marshal-from-py.c | 48 ++++++++++++++++++++++++----------------- + gi/pygi-marshal-to-py.c | 54 + +++++++++++++++++++++++++++-------------------- + 2 files changed, 60 insertions(+), 42 deletions(-) + +commit b5cd13f47309ec26727b7574e33595a357602468 +Author: Colin Walters +Date: Tue Jul 31 11:47:02 2012 -0400 + + pygi-marshal: One more 32-bit -Werror=format fix + + gi/pygi-marshal-from-py.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 526bf43691cb6ed908589312b1693a6389eba00c +Author: Martin Pitt +Date: Tue Jul 31 17:14:37 2012 +0200 + + Beautify class/interface type mismatch error messages + + Avoid saying ".int", just skip the module name + completely if we do not have one. + + gi/pygi-marshal-from-py.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +commit 8fb18c62d9c7faff38df3886cb4289b618c81b85 +Author: Martin Pitt +Date: Tue Jul 31 13:13:21 2012 +0200 + + Skip instead of fail tests which need Pango, Atk, Gdk, Gtk + + On initial jhbuild bootstrap or restricted environments, the Pango, + Atk, Gdk, + and Gtk typelibs might not be available. Skip tests which need these + instead of + failing the testsuite. + + tests/test_atoms.py | 7 ++++++- + tests/test_everything.py | 9 ++++++++- + tests/test_overrides.py | 32 ++++++++++++++++++++++++++------ + tests/test_pygtkcompat.py | 30 ++++++++++++++++++++---------- + 4 files changed, 60 insertions(+), 18 deletions(-) + +commit a2e73c109f3ed6080eabc85810e624b9f984317e +Author: Colin Walters +Date: Tue Jul 31 09:02:24 2012 -0400 + + pygi-argument: Fix -Wformat warning on 32 bit builds + + gi/pygi-argument.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 7563bb9f8ed5740f52ddf0ca59daf7839853505b +Author: Martin Pitt +Date: Tue Jul 31 11:14:36 2012 +0200 + + Fix tests for Python 2 + + In Python 2 we get different error messages for a mismatching self + type. Fixes + check after commit 121b14028. + + tests/test_gi.py | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +commit 5c5b066854cc0b3b7702f31d212aa3f511c62127 +Author: Martin Pitt +Date: Tue Jul 31 10:30:22 2012 +0200 + + Build with -Werror=format + + This catches format string problems on particular architectures like + in commit + dea24f8e12 much more insistently. + + configure.ac | 1 + + 1 file changed, 1 insertion(+) + +commit 6e84a3052667fdc88c2081e20cc6dc3257ec9d6c +Author: Simon Feltman +Date: Mon Jul 30 02:00:16 2012 -0700 + + [API add] pygtkcompat: Add more pixbuf creation functions + + Add the following functions: + pixbuf_new_from_data + pixbuf_new_from_file_at_scale + pixbuf_new_from_file_at_size + pixbuf_new_from_inline + pixbuf_new_from_stream + pixbuf_new_from_stream_at_scale + pixbuf_new_from_xpm_data + pixbuf_get_file_info + + https://bugzilla.gnome.org/show_bug.cgi?id=680814 + + gi/pygtkcompat.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit dea24f8e1221516b2d8ea578e55124b0409d6a76 +Author: Colin Walters +Date: Mon Jul 30 22:17:44 2012 -0400 + + marshal: Fix a lot of format string warnings on 32 bit + + G_GUINT64_FORMAT and friends handle "%lld" portably. + + https://bugzilla.gnome.org/show_bug.cgi?id=680878 + + gi/pygi-marshal-from-py.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +commit b630038d9a1c8cb7e5914c77fbacbed646c154d1 +Author: Colin Walters +Date: Mon Jul 30 22:30:07 2012 -0400 + + marshal: Fix build break on Python 2 + + I *think* using this wrapper function instead is right. + + https://bugzilla.gnome.org/show_bug.cgi?id=680879 + + gi/pygi-marshal-from-py.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit a8338a991bbe919f0e2d9b92f7b71f89ccd2c875 +Author: Manuel Quiñones +Date: Mon Jul 30 12:53:36 2012 -0300 + + Improve testcase for tree_view_column_set_attributes + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=680320 + + tests/test_overrides.py | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +commit 121b1402860407fe46f7501e42447bf3607872ec +Author: Martin Pitt +Date: Tue Jul 31 00:37:55 2012 +0200 + + Fix error messages on interface/class type mismatches + + Previously, when you called a function with an argument which was not + compatible with the expected class/interface type, you got an + error message + like + + TypeError: Expected Gtk.TreeViewColumn, but got GObjectMeta + + which had the wrong (and useless) class name for the actual type, + and did not + tell you which argument caused the problem. With this it says e. g. + + TypeError: argument column: Expected Gtk.TreeViewColumn, but + got Gtk.Button + + instead. + + gi/pygi-marshal-from-py.c | 41 ++++++++++++++++++++++++++-------- + tests/test_gi.py | 57 + ++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 88 insertions(+), 10 deletions(-) + +commit 8f31e85db1392eb7222593fc0d05144c2bca06a3 +Author: Simon Feltman +Date: Sun Jul 29 23:36:25 2012 -0700 + + Fix crash when returning (False, None) from + Gtk.TreeModel.do_get_iter() + + Add a Py_None check before attempting memcpy(). + + https://bugzilla.gnome.org/show_bug.cgi?id=680812 + + Signed-off-by: Martin Pitt + + gi/pygi-closure.c | 10 +++++++--- + tests/test_overrides.py | 9 +++++++++ + 2 files changed, 16 insertions(+), 3 deletions(-) + +commit 94e5d58e7794de91d3291e0e51c42070da4fc92b +Author: Martin Pitt +Date: Mon Jul 30 11:58:24 2012 +0200 + + Add test case for Gtk.TextIter.forward_search() + + https://bugzilla.gnome.org/show_bug.cgi?id=679415 + + tests/test_overrides.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit aae4e77482c02e21154ab02b159f380f5f0f74be +Author: Martin Pitt +Date: Fri Jul 27 23:06:39 2012 +0200 + + Add missing static declarations + + This fixes a lot of -Wmissing-prototype warnings. + + Also remove _pygi_marshal_cleanup_closure_unref() which is not + used anywhere. + + gi/_gobject/gobjectmodule.c | 4 ++-- + gi/_gobject/pygobject.c | 2 +- + gi/pygi-cache.c | 2 +- + gi/pygi-foreign-cairo.c | 24 ++++++++++++------------ + gi/pygi-foreign.c | 2 +- + gi/pygi-marshal-cleanup.c | 9 --------- + tests/test-unknown.c | 2 +- + tests/testhelpermodule.c | 4 ++-- + 8 files changed, 20 insertions(+), 29 deletions(-) + +commit 5f88d3017f853c4ff5e9fd89ef39e4569a9b9c16 +Author: Martin Pitt +Date: Fri Jul 27 23:01:08 2012 +0200 + + Fix more missing #includes + + Add missing includes which caused -Wmissing-prototypes warnings. + + gi/_gobject/pygenum.c | 2 ++ + gi/_gobject/pyginterface.c | 2 ++ + 2 files changed, 4 insertions(+) + +commit 97b5184c6650964ae8a7616353f5ce8e3ca19af3 +Author: Martin Pitt +Date: Fri Jul 27 22:59:21 2012 +0200 + + Make some warnings fatal + + Add -Werror for some warnings which are real errors in the source + which we + really want to avoid. This includes -Wmissing-prototypes, but that + currently + breaks on building g-i's regress.c. + + configure.ac | 5 +++++ + 1 file changed, 5 insertions(+) + +commit c2ee8c550199de59dd220561ed028ec6fb8e1daf +Author: Martin Pitt +Date: Fri Jul 27 22:08:47 2012 +0200 + + Fix missing #includes + + Add missing includes which caused -Wmissing-prototypes warnings. + + gi/_glib/pygiochannel.c | 2 ++ + gi/_glib/pygspawn.c | 2 ++ + 2 files changed, 4 insertions(+) + +commit 8bc98fc6665ebab763ee92361929139a0ebe66b5 +Author: Martin Pitt +Date: Fri Jul 27 20:52:00 2012 +0200 + + pygi-info.c: Robustify pointer arithmetic + + In _wrap_g_field_info_{get,set}_value(), use explicit char* casts + to point out + that we are using byte offsets. Fixes warnings: + + pygi-info.c:1277:43: warning: pointer of type 'void *' used in + arithmetic [-Werror=pointer-arith] + + gi/pygi-info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d0a561057b727ebcc1fd06fa6a3b48f2a1f8338e +Author: Martin Pitt +Date: Fri Jul 27 20:50:30 2012 +0200 + + pyglib.c: Remove some dead code + + Drop unused pyglib_gil_state_ensure_py23() and + pyglib_gil_state_release_py23(). + + gi/_glib/pyglib.c | 18 ------------------ + 1 file changed, 18 deletions(-) + +commit a46d165d906d0ac7613f4d946542423e979f39d5 +Author: Manuel Quiñones +Date: Fri Jul 20 10:37:04 2012 -0300 + + Add set_attributes() override to Gtk.TreeViewColumn + + Looking at the C code, gtk_tree_view_column_set_attributesv just calls + gtk_cell_layout_clear_attributes and then + gtk_cell_layout_add_attribute for each (name, value) passed. This + patch makes the same in the overrides. + + Signed-off-by: Manuel Quiñones + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 13 insertions(+) + +commit 4df676e10a5ea595a0d491af10268f557dd722d7 +Author: Daniel Narvaez +Date: Tue Jul 24 13:49:15 2012 +0200 + + Drop git.mk + + The autogenerated gitignores was missing several files. So we + was using a manual .gitignore at the root. But since it's + enough to add a couple of entries to it to cover the whole + tree, there is no much point in using git.mk at all. + + https://bugzilla.gnome.org/show_bug.cgi?id=678192 + + Makefile.am | 3 - + docs/Makefile.am | 2 - + examples/Makefile.am | 3 - + gi/Makefile.am | 3 - + gi/_glib/Makefile.am | 3 - + gi/_gobject/Makefile.am | 2 - + gi/overrides/Makefile.am | 2 - + gi/repository/Makefile.am | 2 - + git.mk | 200 + ---------------------------------------------- + tests/Makefile.am | 2 - + 10 files changed, 222 deletions(-) + +commit 0d729c1534c7f3226b492f549d8f6ad3bb3ac8b7 +Author: Simon Feltman +Date: Fri Jul 20 19:55:46 2012 -0700 + + Gtk overrides: Add TreePath.__getitem__() + + Use pythons sub-script operator for indexing into TreePaths + as was the case in PyGtk. Also changed __iter__ to use + TreePath.get_indices as opposed to formatting and re-parsing + a string for getting an index list. + + https://bugzilla.gnome.org/show_bug.cgi?id=680353 + + gi/overrides/Gtk.py | 5 ++++- + tests/test_overrides.py | 4 ++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit affc7faa3fa7250e2e8c2c65e6860906f6fbc4fb +Author: Simon Feltman +Date: Fri Jul 20 21:34:33 2012 -0700 + + Fix property type mapping from int to TYPE_INT for python3. + + Python3 does not have a long type, however, propertyhelper.py was + using long_ = int; to get things working. Type mapping code + was then checking for long_ first and always returning TYPE_LONG. + Additional refactoring was done to move large if/elif statements + into dictionary lookups and usage of tuples instead of lists + for simple 'in' list of items tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=679939 + + gi/_gobject/propertyhelper.py | 117 + +++++++++++++++++++----------------------- + tests/test_properties.py | 55 +++++++++++++++----- + 2 files changed, 96 insertions(+), 76 deletions(-) + +commit 6fddba5bc5ea02938677a89ffeb0cfc53229b894 +Author: Manuel Quiñones +Date: Thu Jul 19 12:11:34 2012 -0300 + + Convert Gtk.DestDefaults constants in pygi-convert.sh script + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=680259 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit d58c3553062fd8704a81a8233b4a1563a6611718 +Author: Manuel Quiñones +Date: Thu Jul 19 12:04:03 2012 -0300 + + Convert all Gdk.WindowState constants in pygi-convert.sh + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=680257 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit a3aae2e152c0b955037b7b85e16d14d00881d870 +Author: Joe R. Nassimian +Date: Thu Jul 19 15:48:20 2012 +0200 + + [API add] Add API for checking pygobject's version + + Add a gi.__version__ attribute for the textual version, and + gi.version_info for + a version triple similar to sys.version_info. + + Also add a gi.require_version() which raises an + exception if + the pygobject version is older. + + https://bugzilla.gnome.org/show_bug.cgi?id=680176 + + Signed-off-by: Martin Pitt + + gi/__init__.py | 16 ++++++++++++++++ + tests/test_gi.py | 16 ++++++++++++++++ + 2 files changed, 32 insertions(+) + +commit a2d9b71d84f0fcb7aaf5ce483ffee3b3a1ccaca1 +Author: Manuel Quiñones +Date: Mon Jul 16 17:14:46 2012 -0300 + + pygi-convert.sh: Add some missing Gdk.CursorTypes + + This patch adds WATCH, ARROW and CLOCK. + + https://bugzilla.gnome.org/show_bug.cgi?id=680050 + + Signed-off-by: Manuel Quiñones + Signed-off-by: Martin Pitt + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 0b08c01414ac73a4604acd9a846e7af09574929f +Author: Manuel Kaufmann +Date: Tue Jul 17 09:05:27 2012 -0300 + + pygi-convert.sh: convert rsvg.Handle(data=...) + + Replace rsvg.Handle(data=data) with Rsvg.Handle.new_from_data(data) + + https://bugzilla.gnome.org/show_bug.cgi?id=680092 + + Signed-off-by: Manuel Kaufmann + Signed-off-by: Martin Pitt + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 975855d0fff7f2042fe1f0e843f96b9a37cc6b79 +Author: Martin Pitt +Date: Mon Jul 16 17:35:38 2012 +0200 + + configure.ac: post-release bump to 3.3.5 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 126842b7227fcc1381dc158acdc5a96d0a465515 +Author: Martin Pitt +Date: Mon Jul 16 17:33:08 2012 +0200 + + release 3.3.4 + + NEWS | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +commit 079b73b3eb9083bd53e06d095f9dccc02acf2a6e +Author: Martin Pitt +Date: Mon Jul 16 17:29:22 2012 +0200 + + test_gi: Fix for Python 2 + + tests/test_gi.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 30935fe31bfe201bbfdb7734f09fdd2bbaf80e08 +Author: Martin Pitt +Date: Mon Jul 16 16:35:33 2012 +0200 + + pygi-convert.sh: Drop bogus filter_new() conversion + + my_tree_model.filter_new() is still a method on GtkTreeModel, not a + constructor, so do not try to convert it to a constructor call. + + https://bugzilla.gnome.org/show_bug.cgi?id=679999 + + pygi-convert.sh | 1 - + 1 file changed, 1 deletion(-) + +commit c0607d970fc59528ca27d518282cf2871b92e909 +Author: Martin Pitt +Date: Mon Jul 16 16:00:40 2012 +0200 + + Fix help() for GI modules + + Derive DynamicModule from types.ModuleType, so that the inspect + modules' + ismodule() actually succeeds on those and generates useful help on + a GI + repository module. + + https://bugzilla.gnome.org/show_bug.cgi?id=679804 + + gi/module.py | 3 ++- + tests/test_gi.py | 15 +++++++++++++++ + 2 files changed, 17 insertions(+), 1 deletion(-) + +commit 3235f1a397c334de5a7570f5ceed4da709fe1714 +Author: Martin Pitt +Date: Mon Jul 16 15:53:31 2012 +0200 + + Skip gi.CallbackInfo objects from a module's dir() + + Skip gi.CallbackInfo items from IntrospectionModule's __dir__(), + as we do not + implement __getattr__ for those. + + Add a test case that dir() works on GI modules, contain expected + identifiers, + and that all identifiers in dir() can actually be retrieved. + + Prerequisite for https://bugzilla.gnome.org/show_bug.cgi?id=679804 + + gi/module.py | 7 +++++-- + tests/test_gi.py | 14 ++++++++++++++ + 2 files changed, 19 insertions(+), 2 deletions(-) + +commit f6cc039e014448a553d626aac4020ee69717edab +Author: Martin Pitt +Date: Mon Jul 16 15:38:05 2012 +0200 + + Fix __path__ module attribute + + get_typelib_path() returns bytes, not strings, so in Python 3 we + need to decode + it to get a proper __path__ attribute. + + gi/module.py | 17 +++++++++++++++++ + tests/test_gi.py | 10 ++++++++++ + 2 files changed, 27 insertions(+) + +commit 858048f7cec78129aa914e2341ab80aac0e95cc5 +Author: Joe R. Nassimian +Date: Mon Jul 16 15:02:10 2012 +0200 + + pygi-convert.sh: Fix some child → getChild() false positives + + https://bugzilla.gnome.org/show_bug.cgi?id=680004 + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a31fabdc12f1da301c8df0af319ca3f4181671ee +Author: Mikkel Kamstrup Erlandsen +Date: Thu Jul 12 09:19:42 2012 +0200 + + Fix array handling for interfaces, properties, and signals + + Fix lots of corner cases where arrays are not handled properly. + _pygi_argument_to_object() now has the documented expectation of + getting arrays + packed in GArrays. This was implicit before and not correctly done + on most call + sites. + + The helper _pygi_argument_to_array() has been improved to work on + any kind of + array. Fix all call sites of _pygi_argument_to_object() to do the + array conversion appropriately before calling + _pygi_argument_to_object(). + + Adds a test case that implements a GInterface with a method that + takes an array + of variants as input. + + https://bugzilla.gnome.org/show_bug.cgi?id=667244 + + gi/pygi-argument.c | 156 + ++++++++++++++++++++++++++++++++--------------- + gi/pygi-argument.h | 4 +- + gi/pygi-closure.c | 11 ++++ + gi/pygi-info.c | 20 ++++-- + gi/pygi-property.c | 1 + + gi/pygi-signal-closure.c | 14 ++++- + tests/test_gi.py | 18 ++++++ + 7 files changed, 167 insertions(+), 57 deletions(-) + +commit bb80d124269ee2389c04d03a478475868fd9ff7b +Author: Manuel Quiñones +Date: Wed Jul 11 22:05:41 2012 -0300 + + Add conversion of the Gdk.PropMode constants to pygi-convert.sh script + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=679775 + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit e3a63eefa5fb2abeabd210790e12642e577363c8 +Author: Manuel Quiñones +Date: Wed Jul 11 13:18:16 2012 -0300 + + Add the same rules for pack_start to convert pack_end + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=679760 + + pygi-convert.sh | 5 +++++ + 1 file changed, 5 insertions(+) + +commit b4bef457c2d0ca6899e06a021f1f06252a37e326 +Author: Dave Malcolm +Date: Wed Jul 11 08:21:27 2012 +0200 + + Add error-checking for the case where _arg_cache_new() fails + + This can happen when a typelib and its underlying library are + out-of-sync. This + converts the segfault into a more helpful traceback. + + https://bugzilla.gnome.org/show_bug.cgi?id=678914 + + gi/pygi-cache.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 41287d8a439c656e4ac60361fddec643c713234c +Author: Manuel Quiñones +Date: Wed Jul 11 11:13:38 2012 -0300 + + Add conversion of the Gdk.NotifyType constants to pygi-convert.sh + script + + Signed-off-by: Manuel Quiñones + + https://bugzilla.gnome.org/show_bug.cgi?id=679754 + + pygi-convert.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 5403149b900d1b73cbc78767dc43be2eb344c836 +Author: Simon Feltman +Date: Tue Jul 10 19:07:32 2012 -0700 + + Fix PyObject_Repr and PyObject_Str reference leaks + + Fix all calls to PyObject_Repr() and PyObject_Str() to be properly + DECREF'd. + + https://bugzilla.gnome.org/show_bug.cgi?id=675857 + + Signed-off-by: Martin Pitt + + gi/_glib/glibmodule.c | 10 +++++++-- + gi/_gobject/gobjectmodule.c | 17 ++++++++++----- + gi/_gobject/pygobject.c | 53 + ++++++++++++++++++++++++++++++--------------- + gi/pygi-marshal-from-py.c | 9 +++++--- + 4 files changed, 62 insertions(+), 27 deletions(-) + +commit 0ddfecf3bf0a5d7893cd02cff41503d810ef6ce8 +Author: Martin Pitt +Date: Wed Jul 4 08:46:30 2012 +0200 + + [API add] Gtk overrides: Add TreePath.__len__() + + Use the path depth as length of a Gtk.TreePath object. + + https://bugzilla.gnome.org/show_bug.cgi?id=679199 + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 7 insertions(+) + +commit e1e849d1a9af77c29ee35971db8d439bac60d573 +Author: Martin Pitt +Date: Wed Jul 4 08:35:16 2012 +0200 + + GLib.Variant: Fix repr(), add proper str() + + Fix the GLib.Variant override's repr() after commit 16280d6985. Also + add a + proper __str__() method, and tests for both. + + Thanks to Rul Matos for spotting this! + + https://bugzilla.gnome.org/show_bug.cgi?id=679336 + + gi/overrides/GLib.py | 6 +++++- + tests/test_overrides.py | 5 +++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +commit af20d7c929b9c1888454b52932a308d346e1c12b +Author: Martin Pitt +Date: Thu Jun 28 06:51:22 2012 +0200 + + m4/python.m4: Update Python version list + + Thanks to Dieter Verfaillie for pointing this out. + + m4/python.m4 | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit a96a26234e2aaa157837d26094864e3ad9b63edf +Author: Micah Carrick +Date: Mon Jun 25 09:05:59 2012 -0700 + + Remove "label" property from Gtk.MenuItem if it is not set + + The Gtk.MenuItem will not render as a separator if the "label" or + "user-underline" properties have been accessed. The constructor + for Gtk.MenuItem override should not pass the "label" property + as an argument if it is None since that will still result in an + empty label widget which breaks Gtk.SeparatorMenuItem. + + https://bugzilla.gnome.org/show_bug.cgi?id=670575 + + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit afa12faf339efb4f7780168e884ecf49b630644a +Author: Martin Pitt +Date: Mon Jun 25 16:36:31 2012 +0200 + + configure.ac: Post-release bump to 3.3.4. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 198066effc0ca44ccb897e9f0738ab627e8b3275 +Author: Martin Pitt +Date: Mon Jun 25 16:35:49 2012 +0200 + + release 3.3.3.1 + + NEWS | 3 +++ + configure.ac | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +commit cb70ae0aa52ab7624b2b8c30297d8a52a7db7f44 +Author: Martin Pitt +Date: Mon Jun 25 16:32:45 2012 +0200 + + Do not escape enum and flag names that are Python keywords + + These are translated to upper case, and thus can never be + keywords. This broke + existing API such as Gtk.ShadowType.IN. + + gi/module.py | 2 +- + gi/pygi-info.c | 7 +++++++ + tests/test_gi.py | 3 +++ + 3 files changed, 11 insertions(+), 1 deletion(-) + +commit f2524a982b0b8ba7cdbb77003372416af0b7a978 +Author: Martin Pitt +Date: Mon Jun 25 15:39:50 2012 +0200 + + configure.ac: Post-release version bump to 3.3.4 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fe56faa346c8e8f9fd5915602424778d458a776d +Author: Martin Pitt +Date: Mon Jun 25 15:36:37 2012 +0200 + + release 3.3.3 + + NEWS | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 299a2fd726f0aceaf67b1cec7a0ef8b21ff7bcbc +Author: Martin Pitt +Date: Mon Jun 25 15:35:19 2012 +0200 + + Bring back ChangeLog make target + + This is being used by "make dist". + + Makefile.am | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 760118e4ed73de2f022706ef897fcc848e90c005 +Author: Martin Pitt +Date: Mon Jun 25 15:31:14 2012 +0200 + + Remove obsolete ChangeLog and release-tag make targets + + Makefile.am | 23 ----------------------- + 1 file changed, 23 deletions(-) + +commit e92278692bb51679d6e957c2ac36db64498a7c73 +Author: Simon Schampijer +Date: Fri Jun 15 16:11:21 2012 +0200 + + Do not do any python calls when GObjects are destroyed after the + python interpreter has been finalized + + This happens when pygobject_data_free () function is called after + the python + interpreter shuts down, we can't do python calls after that. + + Benzea did the findings because of a bug in Sugar, and commented + in this + SugarLabs ticket: http://bugs.sugarlabs.org/ticket/3670 + + https://bugzilla.gnome.org/show_bug.cgi?id=678046 + + Signed-off-by: Benjamin Berg + Signed-off-by: Martin Pitt + + gi/_gobject/pygobject.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) + +commit de4aa426002eeb09a060f8fd70bd6cb25a17766a +Author: Martin Pitt +Date: Mon Jun 25 15:06:47 2012 +0200 + + Do not change constructor-only "type" Window property + + When reading a Gtk.Window subclass from a GtkBuilder object, + the object's + properties are already set at __init__ time. Do not try to set it + again, to + avoid a warning. + + https://bugzilla.gnome.org/show_bug.cgi?id=678510 + + gi/overrides/Gtk.py | 8 +++++++- + tests/test_overrides.py | 36 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+), 1 deletion(-) + +commit 16280d6985f2cf4db9cf062e857650e620fd9da8 +Author: Martin Pitt +Date: Mon Jun 25 09:40:38 2012 +0200 + + Escape identifiers which are Python keywords + + Add a trailing underscore to identifiers which are Python keywords. + + We use a per-major-version static identifier list derived from + keyword.kwlist + instead of calling out to Python's keyword.iskeyword(). This is + much faster, + and also allows us to tweak the result. For example, Python 3 dropped + "print" + as a keyword, but we still want to escape that to avoid breaking + the API + between different Python versions. + + Error out when building with a major Python version not covered yet, + so that we + do not forget to update the list in the future. + + https://bugzilla.gnome.org/show_bug.cgi?id=676746 + + gi/pygi-info.c | 38 +++++++++++++++++++++++++++++++++++++- + tests/test_gi.py | 17 +++++++++++++++++ + 2 files changed, 54 insertions(+), 1 deletion(-) + +commit 3864d7a3b7def035ee2daf22ba717371c8d261de +Author: Martin Pitt +Date: Fri Jun 22 13:13:37 2012 +0200 + + Ignore E123 in pep8 tests + + This is "closing bracket does not match indentation of opening + bracket's line", + but it really looks better to have the closing bracket on the + indentation level + of the opening bracket instead of the indentation level of the + line that + contains the opening bracket. + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fb436dd6d3b40b3f2a8ba6f402e2987752ad1902 +Author: Martin Pitt +Date: Fri Jun 22 13:08:34 2012 +0200 + + PEP8: Fix indentation + + Spotted by current pep8 checker. + + demos/gtk-demo/demos/Entry/entry_buffer.py | 6 +-- + demos/gtk-demo/demos/Entry/entry_completion.py | 6 +-- + demos/gtk-demo/demos/Entry/search_entry.py | 4 +- + demos/gtk-demo/demos/appwindow.py | 2 +- + demos/gtk-demo/demos/clipboard.py | 8 +-- + demos/gtk-demo/demos/colorselector.py | 6 +-- + demos/gtk-demo/demos/rotatedtext.py | 8 +-- + demos/gtk-demo/gtk-demo.py | 6 +-- + examples/option.py | 29 ++++++----- + examples/signal.py | 3 +- + gi/_glib/option.py | 6 +-- + gi/_gobject/propertyhelper.py | 18 +++---- + gi/module.py | 14 +++--- + gi/overrides/GLib.py | 2 +- + gi/overrides/Gio.py | 11 +++-- + gi/overrides/Gtk.py | 16 +++--- + gi/pygtkcompat.py | 7 ++- + gi/types.py | 17 ++++--- + tests/runtests.py | 2 +- + tests/test_gdbus.py | 55 +++++++++++---------- + tests/test_gi.py | 15 +++--- + tests/test_gobject.py | 18 +++---- + tests/test_option.py | 26 +++++----- + tests/test_overrides.py | 67 + +++++++++++++------------- + tests/test_properties.py | 30 ++++++------ + tests/test_signal.py | 2 +- + tests/test_uris.py | 9 ++-- + 27 files changed, 200 insertions(+), 193 deletions(-) + +commit 129462ccc4a2191ecbb42247030c91bd0f1454f6 +Author: Martin Pitt +Date: Fri Jun 22 12:36:54 2012 +0200 + + PEP8: Use isinstance() instead of direct type comparisons + + Spotted by current pep8 checker. + + gi/overrides/GLib.py | 2 +- + gi/overrides/__init__.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 50e45a624e6301e65c150e137aad6d092f203f3f +Author: Martin Pitt +Date: Fri Jun 22 12:30:10 2012 +0200 + + PEP8: Fix continuation lines + + Spotted by current pep8 checker. + + demos/gtk-demo/demos/Entry/search_entry.py | 6 +++--- + gi/__init__.py | 6 +++--- + gi/_gobject/__init__.py | 6 ++---- + gi/module.py | 6 +++--- + tests/test_overrides.py | 11 +++-------- + 5 files changed, 14 insertions(+), 21 deletions(-) + +commit ef06548b0dc6aee0e8ab208a78966dc1d5d917ee +Author: Martin Pitt +Date: Fri Jun 22 12:24:32 2012 +0200 + + PEP8: Consistent comparisons against True, False, and None + + Spotted by current pep8 checker. + + demos/gtk-demo/demos/clipboard.py | 4 ++-- + demos/gtk-demo/demos/drawingarea.py | 4 ++-- + demos/gtk-demo/gtk-demo.py | 8 ++++---- + gi/overrides/Gdk.py | 2 +- + gi/overrides/Gtk.py | 2 +- + tests/test_gi.py | 4 ++-- + tests/test_overrides.py | 3 +-- + 7 files changed, 13 insertions(+), 14 deletions(-) + +commit 379c1474a071292a1e8da413af2f5438cff09fc8 +Author: Martin Pitt +Date: Wed Jun 20 12:23:12 2012 +0200 + + Fix crash in GLib.find_program_in_path() + + We need to handle a NULL return value properly. + + https://bugzilla.gnome.org/show_bug.cgi?id=678119 + + gi/_glib/glibmodule.c | 10 ++++++++-- + tests/Makefile.am | 1 + + tests/test_glib.py | 15 +++++++++++++++ + 3 files changed, 24 insertions(+), 2 deletions(-) + +commit 73531fd7820bd1922347bd856298d68205a27877 +Author: Martin Pitt +Date: Wed Jun 20 11:16:39 2012 +0200 + + Revert "Do not bind gobject_get_data() and gobject_set_data()" + + We should have some deprecation period for this, so bring back + these two + methods and add deprecation warnings. + + This reverts commit 24cc09a7105299805fcc5bc151f53ac69958d728. + + https://bugzilla.gnome.org/show_bug.cgi?id=641944 + + gi/_gobject/pygobject.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +commit a0daa843801658929ffee5bcb9eb67d955dc7921 +Author: David Keijser +Date: Mon Jun 18 15:09:34 2012 +0200 + + GVariant: Raise proper TypeError on invalid tuple input + + https://bugzilla.gnome.org/show_bug.cgi?id=678317 + + Signed-off-by: Martin Pitt + + gi/overrides/GLib.py | 4 ++-- + tests/test_overrides.py | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +commit fb39ba934180e1e48fd15774e69d1cecf47a4c84 +Author: Martin Pitt +Date: Tue Jun 5 19:11:38 2012 +0200 + + configure.ac: Post-release bump to 3.3.3 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7f0995e7fa865ebde7490d0570a7135a2f962cdf +Author: Martin Pitt +Date: Tue Jun 5 19:09:12 2012 +0200 + + Release 3.3.2 + + NEWS | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +commit 8209c1ae1632c77768699481e574d5d378956e71 +Author: Martin Pitt +Date: Tue Jun 5 19:04:49 2012 +0200 + + Fix "release-news" make target + + Actually list changes since the previous release, not since 3.1.92. + + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b21f66d2a399b8c9a36a1758107b7bdff0ec8eaa +Author: Bastian Winkler +Date: Wed May 9 19:04:01 2012 +0200 + + foreign: Register cairo.Path and cairo.FontOptions foreign structs + + They are rarely used, but they are used at least by Gdk, PangoCairo + and + Clutter. + + clutter.Path is not used by any API that the test suite uses, so + leave that + without a test for now. + + https://bugzilla.gnome.org/show_bug.cgi?id=677388 + + Signed-off-by: Martin Pitt + + gi/pygi-foreign-cairo.c | 85 + ++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_everything.py | 8 +++++ + 2 files changed, 93 insertions(+) + +commit 635a7d1b48d99ddd1ea123797c493b18b0cdfd45 +Author: Marien Zwart +Date: Wed May 23 01:51:46 2012 +0200 + + Check types in GBoxed assignments + + Check if the Python value is GBoxed instead of assuming it is. + Without this, the following segfaults: + + from gi.repository import Soup + + msg = Soup.Message() + msg.props.uri = 'http://www.gnome.org' + + as we assume the new property is a GBoxed while it is actually a + string. + + https://bugzilla.gnome.org/show_bug.cgi?id=676603 + + Co-authored-by: Martin Pitt + Signed-off-by: Martin Pitt + + gi/pygi-argument.c | 10 +++++++--- + tests/test_gi.py | 19 +++++++++++++++++++ + 2 files changed, 26 insertions(+), 3 deletions(-) + +commit 2305dcd7e8841f87dc2fc683390df78453a5dc2a +Author: Bastian Winkler +Date: Sat May 12 14:08:51 2012 +0200 + + [API add] Gtk overrides: Add TreeModelRow.get_previous() + + TreeModelRow has get_next() and a next property, it should also have + get_previous() and previous. + + https://bugzilla.gnome.org/show_bug.cgi?id=677389 + + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 5501fba534696974899f2591929bff9e1b6ecd65 +Author: Bastian Winkler +Date: Sat May 12 13:50:02 2012 +0200 + + [API add] Add missing GObject.TYPE_VARIANT + + Add TYPE_VARIANT to constants to make it accessible as + GObject.TYPE_VARIANT. + + https://bugzilla.gnome.org/show_bug.cgi?id=677387 + + Signed-off-by: Martin Pitt + + gi/_gobject/__init__.py | 1 + + gi/_gobject/constants.py | 1 + + 2 files changed, 2 insertions(+) + +commit 4c51a5411092f8ab6f8f6e9692a9b49692f621a7 +Author: Jasper St. Pierre +Date: Fri Jun 1 02:53:13 2012 -0400 + + Fix boxed type equality + + Each boxed type has its own Python type, not PyGBoxed_Type. Use + PyObject_IsInstance instead of comparing against PyGBoxed_Type + directly. + + https://bugzilla.gnome.org/show_bug.cgi?id=677249 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygboxed.c | 3 ++- + tests/test_everything.py | 8 ++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +commit dc8eef26906753fcb3ce057b23ca110137897fa5 +Author: Jose Rostagno +Date: Fri Jun 1 13:43:38 2012 +0200 + + Fix TestProperties.testBoxed test + + A typo was preventing the test from being run. + + https://bugzilla.gnome.org/show_bug.cgi?id=676644 + + Signed-off-by: Martin Pitt + + tests/test_properties.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 853e6a71234ebd66af5a64dfb296e323c2c905a6 +Author: Carlos Garnacho +Date: Thu May 17 17:09:15 2012 +0200 + + Fix handling of by-reference structs as out parameters + + When marshalling back from python, copy the result of by-reference + structs into the memory expected by the native caller, instead of + attempting to handle it as a pointer. + + https://bugzilla.gnome.org/show_bug.cgi?id=653151 + + Signed-off-by: Martin Pitt + + gi/pygi-closure.c | 17 +++++++++++++++++ + tests/test_gi.py | 5 +++++ + 2 files changed, 22 insertions(+) + +commit bac9d526f6a9774821d1c9c0e7b35cc6db942975 +Author: Martin Pitt +Date: Fri Jun 1 12:28:53 2012 +0200 + + tests: Add more vfunc checks for GIMarshallingTestsObject + + tests/test_gi.py | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +commit e1aaf4a48453be0e69e7f3a70a2e7a790871a4d2 +Author: Martin Pitt +Date: Fri Jun 1 12:02:55 2012 +0200 + + Test caller-allocated GValue out parameter + + This came up as a side issue in + https://bugzilla.gnome.org/show_bug.cgi?id=653151 + + tests/test_gi.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit edc17e703e1a05e20545d3df9167ceb076450443 +Author: Bastian Winkler +Date: Wed May 16 11:13:05 2012 +0200 + + GObject.bind_property: Support transform functions + + Add support for optional transformation functions to + pygobject_bind_property(). It uses a custom PyGClosure to marshal the + return value correctly. + + https://bugzilla.gnome.org/show_bug.cgi?id=676169 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygobject.c | 130 + +++++++++++++++++++++++++++++++++++++++++++++--- + tests/test_gobject.py | 59 ++++++++++++++++++++++ + 2 files changed, 181 insertions(+), 8 deletions(-) + +commit 07a08b49aae83a297e2f91240448314e4663f724 +Author: Carlos Garnacho +Date: Mon May 14 15:31:14 2012 +0200 + + Fix lookup of vfuncs in parent classes + + https://bugzilla.gnome.org/show_bug.cgi?id=672864. + + As subclasses implemented in python override the attribute for the + vfunc, __mro__ has to be used so subclasses of the subclass overriding + methods may find the corresponding VFuncInfo. + + Co-Authored-by: Martin Pitt + + gi/types.py | 6 +++--- + tests/test_gi.py | 27 +++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 3 deletions(-) + +commit b965ee15bac6cd28d16d32205d96d2b1bdd3f0e1 +Author: Martin Pitt +Date: Fri Jun 1 08:18:40 2012 +0200 + + tests/test_properties.py: Fix whitespace + + The pep8 check failed on this. + + tests/test_properties.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 274d60a7c08d74a299f4b83d8054c00eadb4bdbd +Author: Jasper St. Pierre +Date: Wed May 30 16:45:53 2012 -0400 + + gi: Support zero-terminated arrays with length arguments + + Sometimes, you may see (array zero-terminated=1 length=length) + annotations. + Don't expose the length argument to the user in this case. + + https://bugzilla.gnome.org/show_bug.cgi?id=677124 + + gi/pygi-cache.c | 13 ++++--------- + tests/test_gi.py | 3 +++ + 2 files changed, 7 insertions(+), 9 deletions(-) + +commit 62c2e962a225ec2527aa3d7406aa0dae232a0886 +Author: Jasper St. Pierre +Date: Fri May 25 17:09:55 2012 -0400 + + Fix build + + libregress now needs cairo-gobject + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9477f0f2f17a6d9b97e5ee08378bc009b8d4c30a +Author: Martin Pitt +Date: Mon May 14 15:48:34 2012 +0200 + + Fix comment in previous commit + + tests/test_gobject.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6610428394d0c65987de5021bf2c38641cdb7116 +Author: Simon Feltman +Date: Tue May 8 20:04:09 2012 -0700 + + [API add] Add GObject.bind_property method + + This adds the "bind_property" method for binding two gobject + properties + together. The method returns a weak reference to a GBinding object. + The BindingWeakRef object is used to manage GBinding objects within + python + created through GObject.bind_property. It is a sub-class + PyGObjectWeakRef so + that we can maintain the same reference counting semantics between + Python + and GObject Binding objects. This gives explicit direct control of the + binding lifetime by using the "unbind" method on the BindingWeakRef + object + along with implicit management based on the lifetime of the source or + target objects. + + Note this does not yet include support for converter closures. This + can come + later after the initial implementation is accepted. + + https://bugzilla.gnome.org/show_bug.cgi?id=675582 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygobject.c | 104 + +++++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gobject.py | 90 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 193 insertions(+), 1 deletion(-) + +commit 88babe7377402f6e6f912a8b83615aab848eae81 +Author: Jose Rostagno +Date: Fri May 11 19:08:47 2012 -0300 + + pygtkcompat: Correctly set flags + + https://bugzilla.gnome.org/show_bug.cgi?id=675911 + + Signed-off-by: Martin Pitt + + gi/pygtkcompat.py | 5 ++--- + tests/test_pygtkcompat.py | 1 + + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 3f712b56397296bca2f5358cd52977b1a2011964 +Author: Jose Rostagno +Date: Fri May 11 12:39:05 2012 -0300 + + Gtk overrides: Implement __delitem__ on TreeModel + + https://bugzilla.gnome.org/show_bug.cgi?id=675892 + + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 16 ++++++++++++---- + tests/test_overrides.py | 9 +++++++++ + 2 files changed, 21 insertions(+), 4 deletions(-) + +commit 9a1a07742ec0b1821d469603f9996a2b7d832f40 +Author: Simon Feltman +Date: Sun May 6 18:10:39 2012 -0700 + + Gdk Color override should support red/green/blue_float properties + + Added red_float, green_float, and blue_float properties to Color. + Also added Color.from_floats, RGBA.to_color, and RGBA.from_color. + + https://bugzilla.gnome.org/show_bug.cgi?id=675579 + + Signed-off-by: Martin Pitt + + gi/overrides/Gdk.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ + tests/Makefile.am | 2 +- + tests/test_overrides.py | 17 +++++++++++++++++ + 3 files changed, 62 insertions(+), 1 deletion(-) + +commit d9608c332d9592f03545b110cfac8105453ea035 +Author: Martin Pitt +Date: Sat May 5 12:42:42 2012 -0700 + + Support marshalling of GVariants for closures + + Add GVariant handling to pyg_value_{as,from}_pyobject(), so that + closures can + be called with GVariant arguments and return GVariant. + + Unmark the corresponding test case as "expected failure", and also + add cases + for None values and type mismatches. + + https://bugzilla.gnome.org/show_bug.cgi?id=656554 + + gi/_gobject/pygtype.c | 47 + +++++++++++++++++++++++++++++++++++++++++++++-- + tests/test_everything.py | 16 ++++++++++++---- + 2 files changed, 57 insertions(+), 6 deletions(-) + +commit e7a909c16dc1c625ab11e270f23d540f15c71767 +Author: Johan Dahlin +Date: Mon May 7 10:33:40 2012 -0300 + + Require gobject-introspection 1.33.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9e8239684433631e0d1650d25416e4d7bf92a058 +Author: Martin Pitt +Date: Sun May 6 18:28:23 2012 -0700 + + NEWS: Add API additions since 3.2.0 + + NEWS | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit d1a2bf51eb25b54028fbf496d20dfad9546bcb5e +Author: Martin Pitt +Date: Sun May 6 18:25:23 2012 -0700 + + NEWS: Mark API changes since 3.2.0 + + NEWS | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit a3329539291bd8ea9aa6cb184a05ea7c21f8885a +Author: Martin Pitt +Date: Sun May 6 18:19:35 2012 -0700 + + Fix commit 168a087 for Python 3 + + Simplify the type check and use the already existing one. Fix the + string check + to work with both Python 2 and 3. + + gi/pygi-argument.c | 42 +++++++++--------------------------------- + 1 file changed, 9 insertions(+), 33 deletions(-) + +commit 42c717ed77613e02f3c8ef2685bc071462b87d73 +Author: Martin Pitt +Date: Sun May 6 18:08:57 2012 -0700 + + pygtkcompat.py: Typo fix + + Was missing a space around operator, causing the PEP8 check to fail. + + gi/pygtkcompat.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 168a08753cec1ff77ccca5d81b9a5fd2af5d3720 +Author: Martin Pitt +Date: Sun May 6 18:02:04 2012 -0700 + + _pygi_argument_from_object(): Check for compatible data type + + Verify that the passed PyObject actually matches the expected type + of the + argument. With this, trying to assign a wrong type to a property + will now raise + a proper TypeError. + + gi/pygi-argument.c | 39 +++++++++++++++++++++++++++++++++++++++ + gi/pygi-property.c | 3 +++ + tests/test_gi.py | 40 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 82 insertions(+) + +commit 5948b62ba3e08ea943e6965ee38c94c363186226 +Author: Martin Pitt +Date: Sun May 6 17:59:57 2012 -0700 + + pygtkcompat: Fix color conversion + + gtk_style_context_get_background_color() returns a GdkRGBA value, + which has + float values between 0 and 1. However, we construct a GdkColor + object from + that, so we need to scale to 0..65535 and round to int. + + gi/pygtkcompat.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 6af74c501bc604559f8b5b4e0d856d022ed882bb +Author: Martin Pitt +Date: Sun May 6 06:02:31 2012 -0700 + + test_gi: Check setting properties in constructor + + tests/test_gi.py | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +commit 9f50fd214e4214f83959b2883a0c667f7f157c97 +Author: Martin Pitt +Date: Sun May 6 05:50:00 2012 -0700 + + Support getting and setting GStrv properties + + gi/pygi-property.c | 36 ++++++++++++++++++++++++++++++++++++ + tests/test_gi.py | 11 +++++++++++ + 2 files changed, 47 insertions(+) + +commit 8321af2c7df499291e664c676376f149a0c3dcac +Author: Martin Pitt +Date: Sat May 5 13:58:29 2012 -0700 + + Support defining GStrv properties from Python + + gi/_gobject/propertyhelper.py | 10 ++++++-- + tests/test_properties.py | 58 + +++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 64 insertions(+), 4 deletions(-) + +commit f2494526e1c579c41babfe7ff67deef0f6966adf +Author: Martin Pitt +Date: Sat May 5 13:21:20 2012 -0700 + + Add GObject.TYPE_STRV constant + + gi/_gobject/__init__.py | 1 + + gi/_gobject/constants.py | 1 + + tests/test_everything.py | 2 +- + tests/test_signal.py | 2 +- + 4 files changed, 4 insertions(+), 2 deletions(-) + +commit 8c7306e4d6355ca45f8f1b4adf7d0595b4e8bcf8 +Author: Martin Pitt +Date: Sat May 5 09:28:36 2012 +0200 + + Unref GVariants when destroying the wrapper + + https://bugzilla.gnome.org/show_bug.cgi?id=675472 + + gi/overrides/GLib.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit d6c091d87c86c8ccc7cb54347fbceccedac61633 +Author: Martin Pitt +Date: Sat May 5 09:23:55 2012 +0200 + + Fix TestArrayGVariant test cases + + test_array_gvariant_container_in() and test_array_gvariant_full_in() + called + GIMarshallingTests.array_gvariant_none_in(), presumably a copy&paste + error. + Actually do what they mean to do now and call the corresponding + GIMarshallingTests methods. + + tests/test_gi.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit fda8a069d503e63c76a6b1ba285a181822549059 +Author: Jose Rostagno +Date: Sat May 5 08:52:41 2012 +0200 + + pygtkcompat: Add gdk.pixbuf_get_formats compat code + + https://bugzilla.gnome.org/show_bug.cgi?id=675489 + + Signed-off-by: Martin Pitt + + gi/pygtkcompat.py | 20 ++++++++++++++++++++ + tests/test_pygtkcompat.py | 8 ++++++++ + 2 files changed, 28 insertions(+) + +commit 2b49c5f58bb841de7a9077eeeaf996eb9851dab3 +Author: Jose Rostagno +Date: Mon Apr 30 13:44:19 2012 -0300 + + pygtkcompat: Add some more compat functions + + https://bugzilla.gnome.org/show_bug.cgi?id=675489 + + Signed-off-by: Martin Pitt + + gi/pygtkcompat.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit 16fbb17a9fd17eeb9f886af99e89a214d328dae1 +Author: Martin Pitt +Date: Thu May 3 12:25:04 2012 +0200 + + Fix tests for Python 3 + + cmp() does not exist any more in Python 3, replace with comparison + operators. + + GIMarshallingTests.array_in_nonzero_nonlen() expects a guint8 array, + so we + can't pass a str (which is an Unicode object in Python 3). Pass a + byte array + instead. + + tests/test_gi.py | 2 +- + tests/test_overrides.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit fd7f8eefbe8aba0b29d80e3eb9d985d33a268c8a +Author: Martin Pitt +Date: Thu May 3 09:38:56 2012 +0200 + + Fix building with --disable-cairo + + Build gobject-introspection's regress.c against cairo, not + pycairo/py3cairo. We + always need cairo to build, so unconditionally check for this in + configure.ac. + + In test_everything.py, gracefully handle the absence of the "cairo" + Python + module, which we do not have when building without cairo support. + + configure.ac | 3 +++ + tests/Makefile.am | 4 ++-- + tests/test_everything.py | 8 +++++++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +commit 1c5634e6d98c8b67b37a2747951c66f5d8f1907d +Author: Martin Pitt +Date: Thu May 3 09:28:51 2012 +0200 + + tests: Fix deprecated assertions + + assertAlmostEquals → assertAlmostEqual + assertNotEquals → assertNotEqual + + tests/test_everything.py | 4 ++-- + tests/test_gi.py | 12 ++++++------ + tests/test_overrides.py | 10 +++++----- + 3 files changed, 13 insertions(+), 13 deletions(-) + +commit 07f312e66c07357168098d3f96813d2c997e8dc7 +Author: Martin Pitt +Date: Wed May 2 12:08:19 2012 +0200 + + Run tests with MALLOC_PERTURB_ + + We mostly use the glib allocation functions, but this might + help to uncover access to already freed or uninitialized memory in + a few edge + cases. + + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit b0740d386c2cbbd153878209b584b568968e4d98 +Author: Martin Pitt +Date: Mon Apr 30 16:26:57 2012 +0200 + + configure.ac: Post-release bump to 3.3.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d3977266faadacd3d05705497c1cf51a01a6606f +Author: Martin Pitt +Date: Mon Apr 30 16:08:09 2012 +0200 + + Release 3.3.1 + + NEWS | 66 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +commit a8e222f04aac3bcf7e4421c4da8d080eeb8b5f56 +Author: Giovanni Campagna +Date: Sun Apr 29 23:55:15 2012 +0200 + + GSettings: allow extra keyword arguments + + All GObject constructors are expected to accept any construct + property as keyword argument, and overrides should respect that. + In particular, not doing this for GSettings prevents using a custom + GSettingsSchema. + + https://bugzilla.gnome.org/show_bug.cgi?id=675105 + + Signed-off-by: Martin Pitt + + gi/overrides/Gio.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 592c67482c254f65817c1a1b5c5de5dfcaab31b4 +Author: Jose Rostagno +Date: Sun Apr 29 12:56:50 2012 -0300 + + pygtkcompat: Correct Userlist module use + + https://bugzilla.gnome.org/show_bug.cgi?id=675084 + + Signed-off-by: Martin Pitt + + gi/pygtkcompat.py | 2 +- + tests/test_pygtkcompat.py | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +commit 3551462a429ef30274fa01fc8111da5025f9c342 +Author: Martin Pitt +Date: Sun Apr 29 20:17:47 2012 +0200 + + Add release-news make rule + + This produces a commit log since the previous release in our + current NEWS + format. This does not currently wrap long lines automatically, though. + + Do include bug numbers from now on, as they are very useful. + + Makefile.am | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +commit fe79ef612a7853f024b73c7997b8ec89015ae94c +Author: Martin Pitt +Date: Wed Apr 25 13:07:59 2012 +0200 + + Add "make check.nemiver" target + + Similar to "check.gdb", but invokes nemiver. + + Makefile.am | 3 +++ + tests/Makefile.am | 3 +++ + 2 files changed, 6 insertions(+) + +commit 3090cc70a7ce8df38dd6cf6c17350417a7367c0b +Author: Martin Pitt +Date: Tue Apr 24 13:24:00 2012 +0200 + + Test flags and enums in GHash values + + https://bugzilla.gnome.org/show_bug.cgi?id=637466 + + tests/test_everything.py | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +commit 88d189ec3e3d900a96496a50c1d6e76615b19558 +Author: Martin Pitt +Date: Tue Apr 24 13:03:36 2012 +0200 + + tests: Activate test_hash_in and apply workaround + + Work around pygobject's current inability to produce a GStrv object + from a + string array by explicitly producing a GStrV object, and reactivate + test case. + + https://bugzilla.gnome.org/show_bug.cgi?id=666636 + + tests/test_everything.py | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +commit 8ee21619b3cfc179cf114813478470d9aa3f6fb8 +Author: Martin Pitt +Date: Mon Apr 23 12:33:09 2012 +0200 + + Add special case for Gdk.Atom array entries from Python + + Gdk.Atom pretends to be a struct pointer, but is really just an + int wrapped + into a pointer. So we must not dereference it directly, nor free + it, but + instead just copy the pointer value. + + Also add a few other test cases for "single Atom return", "single + Atom argument + in", and Atom GList return", which already work fine. + + https://bugzilla.gnome.org/show_bug.cgi?id=661709 + + gi/pygi-marshal-from-py.c | 18 ++++++++++++++---- + tests/Makefile.am | 1 + + tests/test_atoms.py | 41 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 56 insertions(+), 4 deletions(-) + +commit b9f24b4fbc2ca9f9b94b86f029c59b2fc3e8590f +Author: Martin Pitt +Date: Mon Apr 23 20:09:43 2012 +0200 + + test_gdbus: Call GetConnectionUnixProcessID() with correct signature + + https://bugzilla.gnome.org/show_bug.cgi?id=667954 + + tests/test_gdbus.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3ae38d7519524288a57e5d522954b9d6725f0185 +Author: Martin Pitt +Date: Mon Apr 23 18:47:34 2012 +0200 + + Add test case for Gtk.ListStore custom sort + + This works in Python 2, but crashes in Python 3, another case of + the segfaults + we get when C calls a Python callback in Python 3. + + https://bugzilla.gnome.org/show_bug.cgi?id=674475 + + tests/test_overrides.py | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +commit c12b10ca0feaaf61f23354c7b6631a9ef3635c36 +Author: Martin Pitt +Date: Mon Apr 23 17:40:23 2012 +0200 + + GTK overrides: Add missing keyword arguments + + Add missing **kwargs to overridden __init__() constructors, to + allow specifying + arbitrary widget properties. + + https://bugzilla.gnome.org/show_bug.cgi?id=660018 + + gi/overrides/Gtk.py | 34 ++++++++++++++++++---------------- + tests/test_overrides.py | 6 ++++++ + 2 files changed, 24 insertions(+), 16 deletions(-) + +commit d37680bb9390426f7f58ea3d352c3e5e2106e978 +Author: Martin Pitt +Date: Mon Apr 23 15:24:04 2012 +0200 + + Add missing override for TreeModel.iter_previous() + + This should behave like the override for TreeModel.iter_next(). + + https://bugzilla.gnome.org/show_bug.cgi?id=660018 + + gi/overrides/Gtk.py | 6 ++++++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 10 insertions(+) + +commit e03284f852f0e404cc91374f3e2e42b0ac1977b4 +Author: Martin Pitt +Date: Sun Apr 22 16:45:06 2012 +0200 + + pygi-convert.py: Drop obsolete drag method conversions + + Drop conversion of drag_source_unset() and drag_dest_{,un}set(). These + were + fixed a while ago to be proper Widget methods again. + + https://bugzilla.gnome.org/show_bug.cgi?id=652860 + + pygi-convert.sh | 3 --- + 1 file changed, 3 deletions(-) + +commit f82eca6006dec21624796074af8ffe9b2256f7a4 +Author: Martin Pitt +Date: Sat Apr 21 14:00:50 2012 +0200 + + tests: Replace deprecated assertEquals() with assertEqual() + + tests/test_everything.py | 144 ++++++------- + tests/test_gi.py | 502 + +++++++++++++++++++++++----------------------- + tests/test_gobject.py | 58 +++--- + tests/test_option.py | 6 +- + tests/test_overrides.py | 352 ++++++++++++++++---------------- + tests/test_properties.py | 18 +- + tests/test_pygtkcompat.py | 42 ++-- + 7 files changed, 561 insertions(+), 561 deletions(-) + +commit ddb0bf01e694585d58af52673a21796e7c9578ea +Author: Paolo Borelli +Date: Sat Apr 21 12:02:54 2012 +0200 + + Plug tiny leak in constant_info_get_value + + Fixes https://bugzilla.gnome.org/show_bug.cgi?id=642754 + + gi/pygi-info.c | 1 + + 1 file changed, 1 insertion(+) + +commit 9c48a561c5ee010410df7d6e430353b41d5fbd88 +Author: Bastian Winkler +Date: Thu Apr 12 20:30:05 2012 +0200 + + Fix len_arg_index for array arguments + + Don't set len_arg_index for arrays without the length annotation + given. + This fixes methods like Clutter.Texture.set_from_rgb_data() and + Clutter.Image.set_data() + + https://bugzilla.gnome.org/show_bug.cgi?id=674271 + + Signed-off-by: Martin Pitt + + gi/pygi-cache.c | 4 +++- + gi/pygi-marshal-cleanup.c | 4 ++-- + tests/test_gi.py | 3 +++ + 3 files changed, 8 insertions(+), 3 deletions(-) + +commit 71246ca0568bf3e9b81e88dd13b6d29e9417e313 +Author: Martin Pitt +Date: Thu Apr 19 13:11:56 2012 +0200 + + Support defining GType properties from Python + + Commit 84e3471 fixed the handling of GType properties for properties + that are + defined in the C library already. Add the missing support for + defining such + properties in Python as well. + + https://bugzilla.gnome.org/show_bug.cgi?id=674351 + + gi/_gobject/gobjectmodule.c | 5 ++++- + gi/_gobject/propertyhelper.py | 9 ++++++--- + tests/test_properties.py | 42 + +++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 49 insertions(+), 7 deletions(-) + +commit 2158ecd05a2770d6538bae67d01d1f718855a7d4 +Author: Martin Pitt +Date: Thu Apr 19 16:12:29 2012 +0200 + + Fix typo in previous commit + + In the test case, actually assign the newly created object, so that + we test the + properties of the right object. + + tests/test_everything.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 84e3471ba4595534cbe6875f1c8b77776e1d1814 +Author: Bastian Winkler +Date: Wed Apr 18 21:44:08 2012 +0200 + + Handle GType properties correctly + + Fix conversion from/to properties of type G_TYPE_GTYPE + + https://bugzilla.gnome.org/show_bug.cgi?id=674351 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygtype.c | 9 +++++++-- + tests/test_everything.py | 15 +++++++++++++++ + 2 files changed, 22 insertions(+), 2 deletions(-) + +commit d1362451e070e156d2f49c9cde930cc38befb12b +Author: Martin Pitt +Date: Thu Apr 19 07:27:10 2012 +0200 + + Add missing GObject.TYPE_GTYPE + + gi/_gobject/__init__.py | 1 + + gi/_gobject/constants.py | 1 + + 2 files changed, 2 insertions(+) + +commit d3225f1540e09719caa73e52d402e946da3add24 +Author: Martin Pitt +Date: Tue Apr 10 12:44:00 2012 +0200 + + Fix test_mainloop.py for Python 3 + + tests/test_mainloop.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +commit 903283119896f3e054694484da4147788b02ce60 +Author: Martin Pitt +Date: Mon Apr 9 15:20:39 2012 +0200 + + Make callback exception propagation test stricter + + Propagating Python exceptions from callbacks through the C context + back to the + original caller does not currently happen, is nontrivial/unsafe + to implement, + and not desirable at this point any more as by now we have established + the + current behaviour. So remove the catching of ZeroDivisionError in + the tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=616279 + + tests/test_everything.py | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +commit 0fd900d351c8d7d57dc6a1b049ee05f342f6ab1d +Author: Simon Feltman +Date: Sun Mar 18 15:59:58 2012 -0700 + + Add context management to freeze_notify() and handler_block(). + + These methods now return a context manager object. Within the + __exit__ method + thaw_notify() and handler_unblock() are called respectively. This + allows + statements like the following: + + with obj.freeze_notify(): + obj.props.width = 100 + obj.props.height = 100 + obj.props.opacity = 0.5 + + This does not affect standard usage of these methods. + + https://bugzilla.gnome.org/show_bug.cgi?id=672324 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygobject.c | 138 +++++++++++++++++++++++++++++++++++++++--- + tests/test_gobject.py | 158 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 288 insertions(+), 8 deletions(-) + +commit c0922589964c1d8bffe5a56d2f56df96eedfac10 +Author: Martin Pitt +Date: Wed Apr 4 19:08:54 2012 +0200 + + Add support for GFlags properties + + https://bugzilla.gnome.org/show_bug.cgi?id=620943 + + gi/_gobject/propertyhelper.py | 9 +++++++-- + tests/test_properties.py | 28 +++++++++++++++++++++++++++- + 2 files changed, 34 insertions(+), 3 deletions(-) + +commit d4054be9de3b7e4ed64c8172ebbde0a697462c79 +Author: Martin Pitt +Date: Wed Apr 4 17:54:52 2012 +0200 + + Wrap GLib.Source.is_destroyed() method + + Based on original patch from Bryan Silverthorn. + + https://bugzilla.gnome.org/show_bug.cgi?id=524719 + + gi/_glib/pygsource.c | 15 +++++++++++++++ + tests/test_source.py | 24 ++++++++++++++++++++++++ + 2 files changed, 39 insertions(+) + +commit 05030a95a4d3090162ed5f510a26d69bbb152942 +Author: Martin Pitt +Date: Wed Apr 4 15:59:24 2012 +0200 + + Fix error message when trying to override a non-GI class + + Based on original patch by Juanje Ojeda . + + https://bugzilla.gnome.org/show_bug.cgi?id=646667 + + gi/overrides/__init__.py | 7 ++++--- + tests/test_overrides.py | 13 +++++++++++++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +commit 96f14989baea76fe8692f10c1a37e2dfc45fecbf +Author: Steve Frécinaux +Date: Wed Apr 4 15:30:55 2012 +0200 + + Fix segfault when accessing __grefcount__ before creating the GObject + + When creating a new instance using Type() and trying to access + __grefcount__ before calling the subclass's __init__ function, there + used to be a segmentation fault because we were trying to access the + not yet created object. Now raise a proper exception instead. + + https://bugzilla.gnome.org/show_bug.cgi?id=640434 + + Co-authored-by: Martin Pitt + + gi/_gobject/pygobject.c | 4 ++++ + tests/test_gobject.py | 11 +++++++++++ + 2 files changed, 15 insertions(+) + +commit 24cc09a7105299805fcc5bc151f53ac69958d728 +Author: Steve Frécinaux +Date: Wed Feb 9 18:37:33 2011 +0100 + + Do not bind gobject_get_data() and gobject_set_data() + + They will basically cause a crash if misused, and you can always use a + python member attribute instead. + + https://bugzilla.gnome.org/show_bug.cgi?id=641944 + + Signed-off-by: Martin Pitt + + gi/_gobject/pygobject.c | 40 ---------------------------------------- + 1 file changed, 40 deletions(-) + +commit 2a5a33a9c9c170830c98c2e32fa8dcea3c35f2e6 +Author: Martin Pitt +Date: Tue Apr 3 22:26:34 2012 +0200 + + Add test case for multiple GLib.MainLoop instances + + Commit 832f16f9 fixed a lockup with multiple GLib.MainLoops. Add + corresponding + test case. + + https://bugzilla.gnome.org/show_bug.cgi?id=663068 + + tests/test_mainloop.py | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +commit d03696c1aaa7e66f8f16554cf4a4b97addb5aea1 +Author: John (J5) Palmieri +Date: Tue Feb 21 15:13:42 2012 +0100 + + Add a ccallback type which is used to invoke callbacks passed to + a vfunc + + Used when overriding methods like gtk_container_forall wich pass in a + callback that needs to be executed on internal children: + def do_forall(self, callback, userdata): + callback(self.custom_child, userdata) + + https://bugzilla.gnome.org/show_bug.cgi?id=644926 + + Co-authored-by: Tomeu Vizoso + Co-authored-by: Simon Schampijer + + Signed-off-by: Martin Pitt + + gi/Makefile.am | 2 + + gi/gimodule.c | 1 + + gi/module.py | 5 +++ + gi/pygi-argument.c | 12 +---- + gi/pygi-cache.c | 28 ++++++++++-- + gi/pygi-cache.h | 9 ++-- + gi/pygi-ccallback.c | 100 + ++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-ccallback.h | 41 +++++++++++++++++ + gi/pygi-closure.c | 50 ++++++++++++++++++++- + gi/pygi-invoke-state-struct.h | 2 + + gi/pygi-invoke.c | 73 ++++++++++++++++++++---------- + gi/pygi-invoke.h | 3 ++ + gi/pygi-private.h | 1 + + gi/pygi.h | 10 +++++ + tests/test_gi.py | 16 +++++++ + 15 files changed, 312 insertions(+), 41 deletions(-) + +commit db7e1d078db16b6f11dee51aa97525c451346632 +Author: Alberto Mardegan +Date: Tue Mar 27 17:34:48 2012 +0200 + + Regression test: marshalling GValues in GHashTable + + https://bugzilla.gnome.org/show_bug.cgi?id=668903 + + Signed-off-by: Martin Pitt + + tests/test_everything.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit 7c0017c30129a8db391f902ed592782200d69c64 +Author: Martin Pitt +Date: Mon Mar 26 17:55:41 2012 +0200 + + Bump version to 3.3.1 + + 3.2.x is built from the pygobject-3-2 branch now, and 3.2.0 is + released. So + continue with 3.3.x on master. + + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8309f305e5ce508fc5f6411c8153bea2cee5f741 +Author: Martin Pitt +Date: Mon Mar 26 17:51:37 2012 +0200 + + Update .gitignore + + - Ignore *.o, backup files, and generated Makefiles in all + subdirectories + - Ignore *.pyc files. + - Do not ignore .gitignore, we actually want to track this. + + .gitignore | 61 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +commit 81de788a72b40acd2f857718d78bdeea01d12eb1 +Author: Martin Pitt +Date: Mon Mar 26 17:45:08 2012 +0200 + + Fix "distcheck" and tests with out-of-tree builds + + - Symlink *.py files from srcdir into builddir during build, as + Python does not + accept the extensions and modules in different paths. + - "make clean" should remove *.pyc files + - tests/runtests.py: Look for tests in srcdir, not in builddir + + Makefile.am | 6 ++++-- + gi/Makefile.am | 13 +++++++++++-- + gi/_glib/Makefile.am | 12 ++++++++++-- + gi/_gobject/Makefile.am | 12 ++++++++++-- + gi/overrides/Makefile.am | 10 ++++++++++ + gi/repository/Makefile.am | 11 +++++++++++ + tests/runtests.py | 6 ++++-- + 7 files changed, 60 insertions(+), 10 deletions(-) + +commit f83d95e6fff572bda659a48e309b4524dafa4e83 +Author: Johan Dahlin +Date: Thu Mar 22 11:14:03 2012 -0300 + + Add a pep8 check to the makefile + + Also reorganize the pyflakes check, since target dependencies do not + take the exit status of the shell command into account. + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + tests/Makefile.am | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +commit d1f5474c6c50163aefe660e0689dc7f30e6cd48b +Author: Johan Dahlin +Date: Thu Mar 22 10:56:59 2012 -0300 + + PEP8: Remaining whitespace fixes + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/Icon View/iconviewedit.py | 7 +++---- + demos/gtk-demo/demos/Tree View/liststore.py | 28 + +++++++++++++------------- + demos/gtk-demo/demos/appwindow.py | 10 ++++----- + demos/gtk-demo/demos/rotatedtext.py | 2 +- + examples/cairo-demo.py | 4 ++-- + tests/test_gi.py | 12 +++++------ + tests/test_overrides.py | 2 +- + 7 files changed, 32 insertions(+), 33 deletions(-) + +commit 032fcce2bf6070a9001cbb780e90403051e303b1 +Author: Johan Dahlin +Date: Thu Mar 22 10:56:03 2012 -0300 + + PEP8: Add spaces before # + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/drawingarea.py | 6 +++--- + demos/gtk-demo/demos/images.py | 10 +++++----- + demos/gtk-demo/demos/rotatedtext.py | 2 +- + gi/__init__.py | 2 +- + gi/_glib/option.py | 2 +- + gi/_gobject/__init__.py | 2 +- + gi/overrides/GLib.py | 12 ++++++------ + gi/types.py | 4 ++-- + tests/runtests.py | 2 +- + tests/test_gdbus.py | 4 ++-- + 10 files changed, 23 insertions(+), 23 deletions(-) + +commit 6a58edbf11c612e9a14347b1556d1e0dd2ec1823 +Author: Johan Dahlin +Date: Thu Mar 22 10:52:05 2012 -0300 + + PEP8: Add missing whitespace after : and , + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/Tree View/liststore.py | 2 +- + demos/gtk-demo/demos/appwindow.py | 2 +- + tests/test_everything.py | 23 +++++++++-------------- + tests/test_gi.py | 2 +- + tests/test_overrides.py | 2 +- + 5 files changed, 13 insertions(+), 18 deletions(-) + +commit a8d361e66b2a0e09cfa5dbade4725074b0cc2fd1 +Author: Johan Dahlin +Date: Thu Mar 22 10:49:52 2012 -0300 + + PEP8: Remove too whitespace before } + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + tests/test_overrides.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2b8eb9fa5b9ca454d7130b3eec15a982fee1bdc9 +Author: Johan Dahlin +Date: Thu Mar 22 10:49:27 2012 -0300 + + PEP8: Remove too many blank lines + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/rotatedtext.py | 1 - + tests/test_overrides.py | 1 - + 2 files changed, 2 deletions(-) + +commit 03e597cb8f3b075efae556ee51a598695a883ad3 +Author: Johan Dahlin +Date: Thu Mar 22 10:48:59 2012 -0300 + + PEP8: Fix whitespace around operators + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/images.py | 2 +- + examples/cairo-demo.py | 8 ++++---- + tests/test_gi.py | 4 ++-- + tests/test_overrides.py | 8 ++++---- + tests/test_properties.py | 14 +++++++------- + tests/test_signal.py | 2 +- + 6 files changed, 19 insertions(+), 19 deletions(-) + +commit 21aeb19107b718293116e51ecd6479d4d7198b8f +Author: Johan Dahlin +Date: Thu Mar 22 10:46:17 2012 -0300 + + PEP8: Remove whitespace before ( + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/Entry/entry_buffer.py | 2 +- + demos/gtk-demo/demos/Entry/entry_completion.py | 2 +- + demos/gtk-demo/demos/Entry/search_entry.py | 12 ++--- + demos/gtk-demo/demos/Icon View/iconviewedit.py | 4 +- + demos/gtk-demo/demos/Tree View/liststore.py | 2 +- + demos/gtk-demo/demos/dialogs.py | 12 ++--- + demos/gtk-demo/demos/pickers.py | 8 ++-- + demos/gtk-demo/demos/pixbuf.py | 4 +- + demos/gtk-demo/demos/printing.py | 8 ++-- + demos/gtk-demo/demos/rotatedtext.py | 2 +- + demos/gtk-demo/gtk-demo.py | 4 +- + gi/module.py | 4 +- + gi/overrides/Pango.py | 2 +- + gi/pygtkcompat.py | 4 +- + tests/test_everything.py | 4 +- + tests/test_overrides.py | 62 + +++++++++++++------------- + 16 files changed, 68 insertions(+), 68 deletions(-) + +commit b04d209930ab01bae6563b0d714aec829739bdc6 +Author: Johan Dahlin +Date: Thu Mar 22 10:40:46 2012 -0300 + + PEP8: Remove whitespace around {} + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + tests/test_signal.py | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +commit 725483a5dc36739dc7836716b5d6d48091564bf8 +Author: Johan Dahlin +Date: Thu Mar 22 10:38:59 2012 -0300 + + PEP8: run via --fix from craigds fork + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/Entry/entry_buffer.py | 1 + + demos/gtk-demo/demos/Entry/entry_completion.py | 1 + + demos/gtk-demo/demos/Entry/search_entry.py | 3 +- + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 1 + + demos/gtk-demo/demos/Icon View/iconviewedit.py | 2 + + demos/gtk-demo/demos/Tree View/liststore.py | 3 ++ + demos/gtk-demo/demos/appwindow.py | 13 +++++- + demos/gtk-demo/demos/assistant.py | 1 + + demos/gtk-demo/demos/builder.py | 1 + + demos/gtk-demo/demos/button_box.py | 1 + + demos/gtk-demo/demos/clipboard.py | 2 +- + demos/gtk-demo/demos/colorselector.py | 1 + + demos/gtk-demo/demos/combobox.py | 4 +- + demos/gtk-demo/demos/dialogs.py | 2 + + demos/gtk-demo/demos/drawingarea.py | 1 + + demos/gtk-demo/demos/expander.py | 4 +- + demos/gtk-demo/demos/images.py | 10 +++-- + demos/gtk-demo/demos/infobars.py | 2 + + demos/gtk-demo/demos/links.py | 2 + + demos/gtk-demo/demos/menus.py | 2 + + demos/gtk-demo/demos/pickers.py | 2 + + demos/gtk-demo/demos/pixbuf.py | 2 + + demos/gtk-demo/demos/printing.py | 5 ++- + demos/gtk-demo/demos/rotatedtext.py | 4 +- + demos/gtk-demo/demos/test.py | 1 + + demos/gtk-demo/gtk-demo.py | 9 ++-- + examples/cairo-demo.py | 57 + ++++++++++++++---------- + examples/option.py | 1 - + examples/properties.py | 1 + + examples/signal.py | 4 ++ + gi/__init__.py | 2 + + gi/_glib/option.py | 4 +- + gi/_gobject/__init__.py | 1 + + gi/_gobject/propertyhelper.py | 5 ++- + gi/module.py | 3 ++ + gi/overrides/GIMarshallingTests.py | 2 + + gi/overrides/GLib.py | 12 +++-- + gi/overrides/Gdk.py | 9 ++++ + gi/overrides/Gio.py | 4 ++ + gi/overrides/Gtk.py | 56 + ++++++++++++++++++++--- + gi/overrides/Pango.py | 2 + + gi/overrides/__init__.py | 5 ++- + gi/pygtkcompat.py | 16 +++++-- + gi/types.py | 4 ++ + tests/test_everything.py | 30 +++++++++---- + tests/test_gdbus.py | 1 + + tests/test_gi.py | 30 +++++++------ + tests/test_gobject.py | 3 +- + tests/test_mainloop.py | 1 + + tests/test_option.py | 1 + + tests/test_overrides.py | 55 + ++++++++++++----------- + tests/test_properties.py | 11 ++++- + tests/test_signal.py | 32 ++++++++++++- + tests/test_source.py | 1 + + tests/test_subprocess.py | 1 + + tests/test_thread.py | 1 + + tests/test_uris.py | 1 + + tests/testmodule.py | 1 + + 58 files changed, 326 insertions(+), 111 deletions(-) + +commit 917275d4aa81db39ccaca34fa514032fb80a3187 +Author: Johan Dahlin +Date: Thu Mar 22 10:33:29 2012 -0300 + + PEP8: Remove spaces around = for keyword arguments + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/appwindow.py | 8 ++++---- + demos/gtk-demo/demos/colorselector.py | 4 ++-- + demos/gtk-demo/gtk-demo.py | 24 ++++++++++++------------ + examples/option.py | 4 ++-- + gi/_glib/option.py | 2 +- + gi/overrides/Gtk.py | 2 +- + tests/test_gi.py | 26 +++++++++++++------------- + tests/test_option.py | 2 +- + tests/test_overrides.py | 8 ++++---- + 9 files changed, 40 insertions(+), 40 deletions(-) + +commit 0c85656f95d3cb31becff10bbee7faae7b0b875b +Author: Johan Dahlin +Date: Thu Mar 22 10:28:28 2012 -0300 + + PEP8: Remove trailing ; + + https://bugzilla.gnome.org/show_bug.cgi?id=672627 + + demos/gtk-demo/demos/appwindow.py | 4 ++-- + demos/gtk-demo/demos/dialogs.py | 30 +++++++++++++++--------------- + demos/gtk-demo/demos/links.py | 2 +- + demos/gtk-demo/demos/pixbuf.py | 2 +- + demos/gtk-demo/demos/printing.py | 8 ++++---- + gi/overrides/Gtk.py | 4 ++-- + tests/test_everything.py | 22 +++++++++++----------- + tests/test_gi.py | 2 +- + tests/test_overrides.py | 8 ++++---- + 9 files changed, 41 insertions(+), 41 deletions(-) + +commit 32cc594ab6dfbd4843f3db5ec8338d31ad5df6c6 +Author: Johan Dahlin +Date: Thu Mar 22 10:24:40 2012 -0300 + + Remove all tabs and fix indentation + + By running the whole source tree via the indent.py script found + in the Python distribution. + + demos/gtk-demo/demos/Entry/search_entry.py | 4 +- + demos/gtk-demo/demos/Icon View/iconviewedit.py | 41 +++---- + demos/gtk-demo/demos/Tree View/liststore.py | 8 +- + demos/gtk-demo/demos/appwindow.py | 18 +-- + demos/gtk-demo/demos/dialogs.py | 26 ++--- + demos/gtk-demo/demos/expander.py | 6 +- + demos/gtk-demo/demos/images.py | 2 +- + demos/gtk-demo/demos/links.py | 2 +- + demos/gtk-demo/demos/rotatedtext.py | 20 ++-- + gi/_glib/option.py | 2 +- + gi/_gobject/constants.py | 1 - + gi/importer.py | 1 - + gi/module.py | 10 +- + gi/overrides/GLib.py | 11 +- + gi/overrides/Gdk.py | 30 ++--- + gi/overrides/Gio.py | 4 +- + gi/overrides/Gtk.py | 150 + ++++++++++++------------- + gi/overrides/Pango.py | 1 - + gi/overrides/__init__.py | 10 +- + gi/pygtkcompat.py | 2 +- + tests/compathelper.py | 2 +- + tests/runtests.py | 19 ++-- + tests/test_everything.py | 22 ++-- + tests/test_gdbus.py | 11 +- + tests/test_gi.py | 38 +++---- + tests/test_gobject.py | 2 +- + tests/test_interface.py | 1 - + tests/test_option.py | 1 - + tests/test_overrides.py | 78 ++++++------- + tests/test_properties.py | 2 +- + tests/test_uris.py | 1 - + 31 files changed, 255 insertions(+), 271 deletions(-) + +commit c375e3136f0f48eb8a6717c0053155db088b329d +Author: Martin Pitt +Date: Thu Mar 22 10:32:43 2012 +0100 + + tests: Replace deprecated Python API + + failIf → assertFalse, failUnless → assertTrue + + Caught by the previous commit of making deprecations fatal. + + tests/test_option.py | 10 +++---- + tests/test_overrides.py | 66 + +++++++++++++++++++++++------------------------ + tests/test_properties.py | 14 +++++----- + tests/test_pygtkcompat.py | 18 ++++++------- + tests/test_signal.py | 4 +-- + 5 files changed, 56 insertions(+), 56 deletions(-) + +commit 32525e565cc48454cdacbc44ad3fd751b81cb7e3 +Author: Martin Pitt +Date: Thu Mar 22 10:31:22 2012 +0100 + + Fail tests if they use or encounter deprecations + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 65762243a34af014950527c323a51a29d40fb3e1 +Author: Martin Pitt +Date: Thu Mar 22 10:15:16 2012 +0100 + + Do not run tests in two phases any more + + As we dropped the static bindings a while ago, there is no need any + more to run + the tests in two phases (static/GI). Now just run them all in one go, + simplifying tests/Makefile.am. + + As this changes the order of the tests, defining $GSETTINGS_SCHEMA_DIR + now + needs to happen even further, so move it from tests/test_overrides.py + to + tests/runtests.py. + + tests/Makefile.am | 33 ++++++++++++--------------------- + tests/runtests.py | 7 +++++++ + tests/test_overrides.py | 6 ------ + 3 files changed, 19 insertions(+), 27 deletions(-) + +commit 3b4ae83a0ece8e3aed1de5452e2acd32841e629a +Author: Martin Pitt +Date: Thu Mar 22 09:58:21 2012 +0100 + + test_overrides: Find local gsettings schema with current glib + + With current glib, gsettings now fails to find the gschemas.compiled + during the + tests. Move the setting of $GSETTINGS_SCHEMA_DIR before the module + import, + which makes this work again. + + tests/test_overrides.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 927f7877ffa5e16c4cabcecbc05656ee0ec6a167 +Author: Paolo Borelli +Date: Wed Mar 21 21:09:24 2012 +0100 + + Add GtkComboBoxEntry compatibility + + This widget has been removed in Gtk+ 3, add a small wrapper to the + compat module to make at least basic pygtk programs that use it work. + + https://bugzilla.gnome.org/show_bug.cgi?id=672589 + + gi/pygtkcompat.py | 19 +++++++++++++++++++ + tests/test_pygtkcompat.py | 22 ++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +commit b322d6a1f6d44bace4eefb98558cfe94a73a727c +Author: Johan Dahlin +Date: Wed Mar 21 16:01:35 2012 -0300 + + Correct review comments from Martin + + https://bugzilla.gnome.org/show_bug.cgi?id=672578 + + tests/test_everything.py | 4 ++-- + tests/test_pygtkcompat.py | 18 ++++++++++++++++++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +commit c8bc6ae10cfe8b2eff4204ec2175907a6eb0585a +Author: Johan Dahlin +Date: Wed Mar 21 14:45:53 2012 -0300 + + Correct pyflakes warnings/errors + + And add a target to make check that runs pyflakes. + + https://bugzilla.gnome.org/show_bug.cgi?id=672578 + + demos/gtk-demo/demos/Entry/entry_buffer.py | 2 +- + demos/gtk-demo/demos/Entry/entry_completion.py | 2 +- + demos/gtk-demo/demos/Entry/search_entry.py | 12 +- + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 2 +- + demos/gtk-demo/demos/Icon View/iconviewedit.py | 2 +- + demos/gtk-demo/demos/Tree View/liststore.py | 3 +- + demos/gtk-demo/demos/appwindow.py | 13 +- + demos/gtk-demo/demos/assistant.py | 4 +- + demos/gtk-demo/demos/builder.py | 4 +- + demos/gtk-demo/demos/button_box.py | 2 +- + demos/gtk-demo/demos/clipboard.py | 2 +- + demos/gtk-demo/demos/colorselector.py | 2 +- + demos/gtk-demo/demos/combobox.py | 4 +- + demos/gtk-demo/demos/dialogs.py | 4 +- + demos/gtk-demo/demos/drawingarea.py | 2 +- + demos/gtk-demo/demos/expander.py | 4 +- + demos/gtk-demo/demos/images.py | 8 +- + demos/gtk-demo/demos/infobars.py | 2 +- + demos/gtk-demo/demos/links.py | 2 +- + demos/gtk-demo/demos/menus.py | 5 +- + demos/gtk-demo/demos/pickers.py | 2 +- + demos/gtk-demo/demos/pixbuf.py | 2 +- + demos/gtk-demo/demos/printing.py | 3 +- + demos/gtk-demo/demos/rotatedtext.py | 6 +- + demos/gtk-demo/gtk-demo.py | 9 +- + examples/cairo-demo.py | 2 +- + gi/__init__.py | 4 + + gi/_glib/__init__.py | 101 ++++++++++- + gi/_glib/option.py | 1 + + gi/_gobject/__init__.py | 203 + ++++++++++++++++++++--- + gi/_gobject/constants.py | 2 - + gi/_gobject/propertyhelper.py | 4 +- + gi/importer.py | 2 +- + gi/module.py | 1 - + gi/overrides/Gtk.py | 1 - + gi/overrides/__init__.py | 1 - + gi/pygtkcompat.py | 2 + + gi/types.py | 3 + + tests/Makefile.am | 5 + + tests/test_everything.py | 6 +- + tests/test_gi.py | 8 +- + tests/test_option.py | 10 +- + tests/test_overrides.py | 30 ++-- + tests/test_properties.py | 12 +- + tests/test_pygtkcompat.py | 4 - + tests/test_signal.py | 4 +- + tests/test_source.py | 6 +- + 47 files changed, 377 insertions(+), 138 deletions(-) + +commit 39650906559fcc39b4be406fa7e25c4788d349a3 +Author: Martin Pitt +Date: Wed Mar 21 16:59:33 2012 +0100 + + Make tests fail on CRITICAL logs, too, and apply to all tests + + Instead of setting warnings/criticals to fatal in individual test + modules, do + it in runtests.py, so that it applies to all tests. + + We currently have some tests which are known to generate CRITICALs + (now marked + with FIXME), and some WARNINGs (as they test behaviour with known-bad + values). + For these, warnings/criticals are now explicitly permitted. + + tests/runtests.py | 1 + + tests/test_gi.py | 7 ++++++- + tests/test_overrides.py | 14 +++++++------- + tests/test_properties.py | 36 +++++++++++++++++++++--------------- + 4 files changed, 35 insertions(+), 23 deletions(-) + +commit efcb4b0b32c4dda06c3eeec83802fc0f302f0d27 +Author: Alberto Mardegan +Date: Tue Mar 20 14:55:07 2012 +0400 + + Support marshalling GI_TYPE_TAG_INTERFACE + + Marshalling of interfaces got broken with commit + 7746d2188ac4933c2c9011d84525d1e62fc18953. + + Also, do not abort on unsupported types, but log a critical failure + and + continue. + + https://bugzilla.gnome.org/show_bug.cgi?id=668903 + + gi/pygi-marshal-from-py.c | 3 ++- + gi/pygi-marshal-to-py.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +commit 8d85d6639778ec6364235071d272d67e7aae49ae +Author: Martin Pitt +Date: Wed Mar 21 14:34:36 2012 +0100 + + Fix warnings on None values in added tree/list store rows + + Commit bf8c95836e1c changed the List/TreeStore overrides to use + insert_with_valuesv(), but supplied all columns instead of just + those which are + not None. With this, None values cause warnings like + + (runtests.py:12375): Gtk-WARNING **: + /build/buildd/gtk+3.0-3.3.20/./gtk/gtkliststore.c:851: Unable to + convert from (null) to gboolean + + Update the tests to make warnings fatal, to catch this better. + + Change _convert_row() to skip the None entries and return the list + of not-None + columns, and use the latter instead of a simple range(n_columns). This + matches + the behaviour before bf8c95836e1c, where columns with None values + were skipped + as well. + + https://bugzilla.gnome.org/show_bug.cgi?id=672463 + + gi/overrides/Gtk.py | 26 ++++++++++++++------------ + tests/test_overrides.py | 5 +++++ + 2 files changed, 19 insertions(+), 12 deletions(-) + +commit 38aecc481741fd3a319a76a0ec8bf5329a483876 +Author: Martin Pitt +Date: Wed Mar 21 15:21:02 2012 +0100 + + pygtkcompat test: Properly clean up PixbufLoader + + Tests currently give + + (runtests.py:15072): GdkPixbuf-WARNING **: GdkPixbufLoader finalized + without calling gdk_pixbuf_loader_close() - this is not allowed. You + must explicitly end the data stream to the loader before dropping + the last reference. + + Fix this by calling close(). + + tests/test_pygtkcompat.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 5e0e5e72a4436badd09f0aa07f62960afcdca8c6 +Author: Martin Pitt +Date: Mon Mar 19 16:58:22 2012 +0100 + + post-release bump + + Use 3.1.93 for now, this will most likely become 3.2.0 as it is. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 88924e399d7ccf7af2e9a78720e0c508cd6080d8 +Author: Martin Pitt +Date: Mon Mar 19 16:41:17 2012 +0100 + + Release 3.1.92 + + NEWS | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +commit b41e6139befb984c0b78bcefe2630ab1393b4b40 +Author: Martin Pitt +Date: Mon Mar 19 16:14:54 2012 +0100 + + README: Update current maintainers + + Also update Martin's email address. + + README | 10 ++++++---- + pygobject.doap | 2 +- + 2 files changed, 7 insertions(+), 5 deletions(-) + +commit 45e27ba7e447552057a2950fc768c63ff2e6612e +Author: Martin Pitt +Date: Mon Mar 19 16:11:22 2012 +0100 + + Bump version to 3.1.92, in sync with GNOME + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 77d358f8c5f524259249ea686899e3a4da05562e +Author: Johan Dahlin +Date: Mon Mar 19 11:54:07 2012 -0300 + + Correct Gtk.TreePath.__iter__ to work with Python 3 + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1f18bcb37bdc42368ad9a07c7f348f736c2f665d +Author: Martin Pitt +Date: Mon Mar 19 15:54:13 2012 +0100 + + Fix pygtkcompat.py to work with Python 3 + + gi/pygtkcompat.py | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +commit 96a9f92da801989464fbcedf6d849819f6dbea64 +Author: Martin Pitt +Date: Mon Mar 19 15:32:22 2012 +0100 + + Fix test_everything.TestSignals.test_object_param_signal test case + + The callback gets two arguments, not one. This short-circuited + the actual + assertions. Fix the arguments and update the refcount check, as it + is not + exactly two at the moment. + + tests/test_everything.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit ba00afb1e50759b2b321f16e05a15946053cdafa +Author: Johan Dahlin +Date: Mon Mar 19 10:58:09 2012 -0300 + + pygtkcompat: Remove first argument for get_origin() + + gi/pygtkcompat.py | 5 +++++ + tests/test_pygtkcompat.py | 5 +++++ + 2 files changed, 10 insertions(+) + +commit 65499246a862ce6a82bc3b0cc74fe8ff82dde687 +Author: Johan Dahlin +Date: Fri Mar 16 16:08:44 2012 -0300 + + GtkViewport: Add a default values for the adjustment constructor + parameters + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 10 ++++++++++ + tests/test_overrides.py | 11 +++++++++++ + 2 files changed, 21 insertions(+) + +commit 43c761d9f35252dcb58b9cf2278016d841eea4ec +Author: Johan Dahlin +Date: Fri Mar 16 16:08:23 2012 -0300 + + GtkIconSet: Add a default value for the pixbuf constructor parameter + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 11 +++++++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 17 insertions(+) + +commit 116d3712251b1b8aa2d4f4a9e40e22f5b9fcbe4f +Author: Johan Dahlin +Date: Fri Mar 16 16:07:30 2012 -0300 + + PangoLayout: Add a default value for set_markup() + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Pango.py | 3 +++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 7 insertions(+) + +commit a3ca47b086b7fcf084282be788c5d737dde847ac +Author: Johan Dahlin +Date: Fri Mar 16 16:06:37 2012 -0300 + + Gtk[HV]Scrollbar: Add a default value for the adjustment constructor + parameter + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 15 +++++++++++++++ + tests/test_overrides.py | 14 ++++++++++++++ + 2 files changed, 29 insertions(+) + +commit 458dab08c78cb730dd95bcd67af20a0d73a3af2f +Author: Johan Dahlin +Date: Fri Mar 16 16:06:12 2012 -0300 + + GtkToolButton: Add a default value for the stock_id constructor + parameter + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 10 ++++++++++ + tests/test_overrides.py | 9 ++++++++- + 2 files changed, 18 insertions(+), 1 deletion(-) + +commit 2f7789a5a1f55ec38c5ff0f96bc5c9023679a333 +Author: Johan Dahlin +Date: Fri Mar 16 16:05:55 2012 -0300 + + GtkIconView: Add a default value for the model constructor parameter + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 11 +++++++++++ + 2 files changed, 14 insertions(+) + +commit 2dd9dadd1bd92c3324e9de209ba8205a9d4106d6 +Author: Johan Dahlin +Date: Thu Mar 15 15:22:46 2012 -0300 + + Add a default value for column in Gtk.TreeView.get_cell_area() + + https://bugzilla.gnome.org/show_bug.cgi?id=672260 + + gi/overrides/Gtk.py | 5 +++++ + tests/test_overrides.py | 3 +++ + 2 files changed, 8 insertions(+) + +commit bf8c95836e1cc1e1629937cbc69ea3027fb82746 +Author: Martin Pitt +Date: Thu Mar 15 09:48:10 2012 +0100 + + Atomic inserts in Gtk.{List,Tree}Store overrides + + Gtk.{List,Tree}Store's overrides provide append(), insert() + etc. methods which + take an optional data row array. If this is given, use + insert_with_valuesv() + instead of creating a new iter and then filling it with data. The + latter sent a + row-added signal, at which time the row was still empty, and a + subsequent + row-changed signal. With this we only get a single row-added + signal with + complete row data. + + Note that this does not change insert_{before,after}(), as there is no + counterpart of insert_with_valuesv() which takes a TreeIter instead + of a + position. For those you will still get two signals, and have to deal + with None + values. + + https://bugzilla.gnome.org/show_bug.cgi?id=671610 + + gi/overrides/Gtk.py | 81 + ++++++++++++++++++++++++++++++------------------- + tests/test_overrides.py | 74 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 124 insertions(+), 31 deletions(-) + +commit f7db4eaf8148f2dd8bf1718152a1dcae509470c7 +Author: Martin Pitt +Date: Sun Mar 18 16:07:26 2012 +0100 + + Fix Gtk.Button constructor to accept use_stock parameter + + Thanks to kalanzun@googlemail.com! + + https://bugzilla.gnome.org/show_bug.cgi?id=672318 + + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 4 +--- + tests/test_overrides.py | 6 ++++++ + 2 files changed, 7 insertions(+), 3 deletions(-) + +commit 466337cf2fd091738eeab12c10d250a9d0827284 +Author: Johan Dahlin +Date: Fri Mar 16 16:55:47 2012 -0300 + + Correct bad rebase, remove duplicate Window + + gi/overrides/Gtk.py | 7 ------- + 1 file changed, 7 deletions(-) + +commit c60d5ee3c88bd8e1c68ea97f079947cf79d5bb7d +Author: Johan Dahlin +Date: Thu Mar 15 15:42:28 2012 -0300 + + Add a PyGTK compatibility layer + + This module tries quite a bit harder to maintain compatibility + with PyGTK, module names, enums, flags and some API. + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/Makefile.am | 3 +- + gi/pygtkcompat.py | 421 + ++++++++++++++++++++++++++++++++++++++++++++++ + tests/Makefile.am | 3 +- + tests/test_pygtkcompat.py | 77 +++++++++ + 4 files changed, 502 insertions(+), 2 deletions(-) + +commit 680a2e04ac4f80ad16e820d3f753519477c988aa +Author: Johan Dahlin +Date: Wed Mar 14 15:20:53 2012 -0300 + + Add bw-compatible arguments to Gtk.Adjustment + + The argument used to be called page/step_incr, if they + are found map them to the existing properties for extra + compatibility. + + https://bugzilla.gnome.org/show_bug.cgi?id=672087 + + gi/overrides/Gtk.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit fbd21ee7176bc1b70547ea464b512c8ffd674187 +Author: Johan Dahlin +Date: Wed Mar 14 17:13:04 2012 -0300 + + GtkTreePath: make it iterable + + https://bugzilla.gnome.org/show_bug.cgi?id=672093 + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 2 ++ + 2 files changed, 5 insertions(+) + +commit a7b08cb75541612c78d123b1d968be7874e3c481 +Author: Johan Dahlin +Date: Wed Mar 14 13:32:31 2012 -0300 + + Add a default argument to TreeModelFilter.set_visible_func() + + https://bugzilla.gnome.org/show_bug.cgi?id=672081 + + gi/overrides/Gtk.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit 02950cabb38b1b3c9378c42c069eefdbccbce17d +Author: Johan Dahlin +Date: Wed Mar 14 13:31:41 2012 -0300 + + Add a default argument to Gtk.TreeView.set_cursor + + And also make sure that the path is a Gtk.TreePath. + + https://bugzilla.gnome.org/show_bug.cgi?id=672081 + + gi/overrides/Gtk.py | 4 ++++ + tests/test_overrides.py | 10 ++++++++++ + 2 files changed, 14 insertions(+) + +commit 7245bd0ae3f6243c79fa8543a0ed1e50e5015844 +Author: Johan Dahlin +Date: Wed Mar 14 13:31:06 2012 -0300 + + Add a default argument to Pango.Context.get_metrics() + + https://bugzilla.gnome.org/show_bug.cgi?id=672081 + + gi/overrides/Pango.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit bc1fd8814df6c1e85b586d0fb943c89f7e2b78b5 +Author: Martin Pitt +Date: Fri Mar 16 13:27:56 2012 +0100 + + Fix double-freeing GValues in arrays + + When marshalling a GValue array to C, the GValue items are copied + into a C + GValue array, not a C GValue pointer + array. _pygi_marshal_from_py_array() + already calls the cleanup_func for the original item; + _pygi_marshal_cleanup_from_py_array() must not do it again, as this + would try + to g_slice_free the array item. + + https://bugzilla.gnome.org/show_bug.cgi?id=672224 + + gi/pygi-marshal-from-py.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit a906b7d1947ba905f959d3f738eb6c29b02f96e7 +Author: Simon Feltman +Date: Fri Mar 16 00:29:31 2012 -0700 + + Renamed "property" class to "Property" + + Renamed to match the rest of the class names in GObject and also + not clobber the builtin python property. + + Keep the old "property" identifier for backwards compatibility + for now. + + https://bugzilla.gnome.org/show_bug.cgi?id=672168 + + Signed-off-by: Martin Pitt + + examples/properties.py | 6 +-- + gi/_gobject/__init__.py | 7 ++-- + gi/_gobject/propertyhelper.py | 12 +++--- + tests/test_interface.py | 4 +- + tests/test_properties.py | 94 + +++++++++++++++++++++---------------------- + 5 files changed, 62 insertions(+), 61 deletions(-) + +commit d7d28d717e38c0546529b09b8b571a5cc631c5b5 +Author: Martin Pitt +Date: Wed Mar 14 22:52:47 2012 +0100 + + Fix Python to C marshalling of GValue arrays + + For GValues we cannot just copy the GValue memory in + _pygi_marshal_from_py_array(), as the from_py_cleanup() function + clears and + releases the GValue and with it its v_pointer. Use g_value_copy() + to copy by + value instead. + + This uncovered another bug in _pygi_marshal_cleanup_from_py_array(): + It always + assumed that C arrays contained pointers, but this is not the case + for GValue + arrays: these are actual struct arrays, not struct pointer arrays + (cf. their + construction in _pygi_marshal_from_py_array()). Check if an array + contains + pointers or values and compute the correct array item pointer for + both cases. + + Also add a corresponding test case for marshalling GValue arrays + from C back to + Python, which works fine. + + https://bugzilla.gnome.org/show_bug.cgi?id=672065 + + gi/pygi-marshal-cleanup.c | 19 ++++++++++++++----- + gi/pygi-marshal-from-py.c | 13 ++++++++++++- + tests/test_gi.py | 8 ++++++++ + 3 files changed, 34 insertions(+), 6 deletions(-) + +commit 27ac9c1de6487035b18ef4511c155d251cb6d39d +Author: Johan Dahlin +Date: Fri Mar 16 09:59:57 2012 +0100 + + Correct the Gtk.Window hierarchy + + We need to make sure that all Gtk.Dialog subclasses inherit from + the overridden Window class. For that to be done automaticly we need + to create the Window class before the Dialog class. + + Now when it's inherited properly we need to avoid calling the Window + constructor twice as it passes in a construct-only parameter. So add + **kwargs to the Window constructor to allow us to pass in any kind + of GObject property to it and refactor the Dialog subclasses to pass + in all properties to the same constructor. + + Also adds a bunch of tests to make sure that the hiearchy is correct. + + https://bugzilla.gnome.org/show_bug.cgi?id=672158 + + Signed-off-by: Martin Pitt + + gi/overrides/Gtk.py | 56 + ++++++++++++++++++++++++------------------------- + tests/test_overrides.py | 35 +++++++++++++++++++++++++++++-- + 2 files changed, 61 insertions(+), 30 deletions(-) + +commit 77ab27ab8a580d98f76730f075e083e1e870f55e +Author: simon +Date: Tue Mar 13 01:41:53 2012 -0700 + + Renamed getter/setter instance attributes to fget/fset respectively. + + The python 'property' class allows for decoration of methods using + .getter and .setter. These were added as methods to the + GObject.property + class to match that of the python property class and allow for + decoratored + setter methods. + + In addition, __call__ was added to allow an instantiated decorator + with + args to also decorate a method: + + class C(GObject.GObject): + _value = 0 + @GObject.property(type=int, default=0) + def propInt(self): + return self._value + @propInt.setter + def propInt(self, value): + self._value = value + + https://bugzilla.gnome.org/show_bug.cgi?id=586181 + + Signed-off-by: Martin Pitt + + gi/_gobject/__init__.py | 10 ++++---- + gi/_gobject/propertyhelper.py | 59 + +++++++++++++++++++++++++++++++------------ + tests/test_properties.py | 41 ++++++++++++++++++++++++++++++ + 3 files changed, 89 insertions(+), 21 deletions(-) + +commit 174a61fb3149c07dab5cc35e64825922cdefcb95 +Author: Johan Dahlin +Date: Tue Mar 13 17:10:13 2012 -0300 + + Add Gtk.Arrow/Gtk.Window constructor override + + Adds argument that makes them compatible with PyGTK. + + https://bugzilla.gnome.org/show_bug.cgi?id=672045 + + gi/overrides/Gtk.py | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +commit 7746d2188ac4933c2c9011d84525d1e62fc18953 +Author: Michel Dänzer +Date: Fri Mar 9 12:26:53 2012 +0100 + + Fix marshalling to/from Python to work on big endian machines. + + https://bugzilla.gnome.org/show_bug.cgi?id=668903 + + Signed-off-by: Martin Pitt + + gi/pygi-argument.c | 25 ++++++++++++++++--------- + gi/pygi-marshal-from-py.c | 32 +++++++++++++++++++++++++------- + gi/pygi-marshal-to-py.c | 19 +++++++++++++++++++ + 3 files changed, 60 insertions(+), 16 deletions(-) + +commit 0591cc6f160ae6e9d8c3970934ae105ef340d7d3 +Author: Michel Dänzer +Date: Thu Mar 8 12:21:28 2012 +0100 + + Use gi_cclosure_marshal_generic instead of duplicating it. + + Bump gobject-introspection dependency to ensure that we have the + corresponding + changes in g-i. + + https://bugzilla.gnome.org/show_bug.cgi?id=668903 + + Signed-off-by: Michel Dänzer + Signed-off-by: Martin Pitt + + configure.ac | 3 +- + gi/_gobject/Makefile.am | 7 +- + gi/_gobject/ffi-marshaller.c | 194 + ------------------------------------------- + gi/_gobject/ffi-marshaller.h | 31 ------- + gi/_gobject/gobjectmodule.c | 12 +-- + 5 files changed, 4 insertions(+), 243 deletions(-) + +commit 8ca828825a2c47080055c5f986979aac8da9a93f +Author: René Stadler +Date: Mon Mar 5 21:10:55 2012 +0100 + + Override Gtk.TreeView.get_visible_range to fix return + + Just like IconView. + + https://bugzilla.gnome.org/show_bug.cgi?id=671409 + + gi/overrides/Gtk.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 4824ceaa77b59788325a2c1ee0f994d4e74d7a1c +Author: Paolo Borelli +Date: Sun Mar 4 16:41:18 2012 +0100 + + Plug memory leak in _is_union_member + + When we found the member, unref the objects before breaking out of the + loop. + + gi/pygi-marshal-from-py.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +commit c6ae29ac157978a61b11cc2de9e8485d8a175105 +Author: Sebastian Pölsterl +Date: Tue Feb 21 15:37:18 2012 +0100 + + tests: Split TestInterfaces into separate tests + + tests/test_gi.py | 36 +++++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 17 deletions(-) + +commit de3299818ae5fdf1c7abbe05a36bfd5cdface7b8 +Author: Sebastian Pölsterl +Date: Mon Feb 20 19:37:32 2012 +0100 + + Post release version bump to 3.1.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fd020e783c0dacea3320225b4ddd57d6a0fce7ea +Author: Sebastian Pölsterl +Date: Mon Feb 20 19:33:56 2012 +0100 + + Prepare 3.1.1 release + + NEWS | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +commit 99485d96811667ef7a7a393b68b7361733157d61 +Author: Sebastian Pölsterl +Date: Sat Feb 18 00:38:05 2012 +0100 + + Don't use C99 style + + gi/pygi-cache.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 0739c39f6282d95fc17ee406fa1151d074b0450d +Author: Martin Pitt +Date: Thu Feb 16 16:42:53 2012 +0100 + + Add test for GPtrArray with transfer full + + This complements the already existing test for a "transfer container" + return + array. We can't verify the internal refcount as these arrays get + marshalled + internally, but at least we can verify that it does not crash due to + double-free. + + tests/test_everything.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit 087a104f66793a981a0c02f1c7ab9cc1cf659da3 +Author: Martin Pitt +Date: Wed Feb 15 13:36:39 2012 +0100 + + Drop obsolete g_thread_init() + + Not necessary any more since glib 2.24, and we depend on 2.31. + + gi/_glib/pyglib.c | 3 --- + 1 file changed, 3 deletions(-) + +commit 66fb610e45912a7def29e5848577d280ef55643a +Author: Martin Pitt +Date: Wed Feb 15 13:35:33 2012 +0100 + + Fix deprecated g_source_get_current_time() + + Use g_get_real_time() instead as recommended by the + documentation. This also + simplifies the code. + + gi/_glib/pygsource.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit 18342edded05d3d9cccf648ed92bc1cac95c51eb +Author: Martin Pitt +Date: Wed Feb 15 13:31:23 2012 +0100 + + Fix deprecated g_value_[gs]et_char() + + Replace with _schar(). We depend on glib >= 2.31 already. + + gi/_gobject/ffi-marshaller.c | 2 +- + gi/_gobject/pygtype.c | 6 +++--- + gi/pygi-argument.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +commit 3dfb8dcbe7cf09dc170433fc48d3273c6ea9448e +Author: Simon Schampijer +Date: Thu Feb 2 19:06:01 2012 +0100 + + Make pygiconvert.sh correctly convert gtk.gdk.x11_* + + Looking at the gir file gtk.gdk.x11_* should get converted to + GdkX11.x11_*. Fixing pygiconvert.sh to do so. + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3af5016978df598d5fd1c225cc49bb2c04dc4e35 +Author: Sebastian Pölsterl +Date: Fri Feb 10 13:29:41 2012 +0100 + + Raise required glib version to 2.31 because of g_value_(get|set)_schar + + Commit ee62df4d2fc0cc63c2f29d3ad9b47b875dbd5f89 introduced both calls + + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 50c3b1bad3ea79750649f4b48fce0adbfaba5268 +Author: Dieter Verfaillie +Date: Fri Feb 10 09:28:36 2012 +0100 + + Fix cset_first typo + + https://bugzilla.gnome.org/show_bug.cgi?id=649267 + + gi/_gobject/pygparamspec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6ab542fb3ec1031922ba65664d77bbaac0df453e +Author: Bastian Winkler +Date: Mon Nov 14 14:41:08 2011 +0100 + + pygi-convert: Handle Clutter and Cogl + + https://bugzilla.gnome.org/show_bug.cgi?id=664496 + + pygi-convert.sh | 76 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 76 insertions(+) + +commit 4aeb27efc43e131de5d0bc0f60dca7c1d34c3d45 +Author: Cédric Krier +Date: Fri Feb 10 09:04:18 2012 +0100 + + Provide access to gpointer struct values + + https://bugzilla.gnome.org/show_bug.cgi?id=668356 + + Signed-off-by: Martin Pitt + + gi/pygi-argument.c | 3 ++- + gi/pygi-info.c | 13 +++++++++++++ + tests/test_everything.py | 21 +++++++++++++++++++++ + 3 files changed, 36 insertions(+), 1 deletion(-) + +commit 5c0b20cc1a261cb7430a5251dffe60da698033b5 +Author: Paolo Borelli +Date: Thu Feb 9 18:15:42 2012 +0100 + + Add some GType tests + + Use what was recently added in g-i + + tests/test_gi.py | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +commit ea7778f6f37a6fc38f88d89d4b6cae8be0ed9753 +Author: Paolo Borelli +Date: Thu Feb 9 18:14:52 2012 +0100 + + Split GStrv and array variant tests in their own classes + + Also tidy up the spacing a bit + + tests/test_gi.py | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +commit db7f9be319d3cf52aef300fbac60cabb7ff57276 +Author: Paolo Borelli +Date: Wed Feb 8 22:23:30 2012 +0100 + + Add unit test for builder's connect_after + + tests/test_overrides.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 671f9b0dd73ac41a84caf9d1f04cec351bc01b47 +Author: Ryan Lortie +Date: Wed Feb 8 16:06:22 2012 -0500 + + fix GtkBuilder signal connection 'after' logic + + All GtkBuilder signals are presently being connected 'after', ignoring + what is specified in the builder XML. This is due to an obvious logic + error. + + https://bugzilla.gnome.org/show_bug.cgi?id=669705 + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1d23d8006be98b77a0134fddd23b76df05e489fa +Author: Patrick Welche +Date: Tue Feb 7 11:49:58 2012 +0000 + + test(1) uses '=' to test if strings are identical + + https://bugzilla.gnome.org/show_bug.cgi?id=669598 + + m4/python.m4 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 945fd18e531c2131440af93dcd89f6c63abbfd7c +Author: Ryan Lortie +Date: Tue Feb 7 13:42:19 2012 -0500 + + pygspawn: improve error checking + + gspawn 'argv' and 'envp' parameters expect sequences of strings. This + is enforced by checking that the passed argument is a sequence + and that + each item returned from it is a string. + + We do now, however, verify that each item can be successfully + taken from + the sequence. 'os.environ' is an example of an object that passes + PySequence_Check() but fails to return objects from PySequence_ITEM(). + + Add a simple NULL check to avoid the crash. + + https://bugzilla.gnome.org/show_bug.cgi?id=669594 + + gi/_glib/pygspawn.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8fc969c45d6d720400dc6c9ef391d0ca93f14b5a +Author: Sebastian Pölsterl +Date: Mon Feb 6 19:15:53 2012 +0100 + + Post release version bump to 3.1.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f76b2fe6d37be76bf129ee2adee90b2cc0eee56e +Author: Sebastian Pölsterl +Date: Mon Feb 6 19:11:52 2012 +0100 + + Prepare 3.1.0 release + + NEWS | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +commit c09d0dffc5a570d5ae4df1ae07b2e5594c3ca1bf +Author: Sebastian Pölsterl +Date: Mon Feb 6 19:04:41 2012 +0100 + + Updated DOAP file to only include people currently actively working + on the project + + Removed obsolete MAINTAINERS file + + MAINTAINERS | 19 ------------------- + pygobject.doap | 44 +++++++++++++++----------------------------- + 2 files changed, 15 insertions(+), 48 deletions(-) + +commit 0285e107be581c4d594127dc06cd05df1f02fb3f +Author: Sebastian Pölsterl +Date: Mon Feb 6 18:57:01 2012 +0100 + + Revert "Convert all strings to utf-8 encoding when retrieving from + TreeModel" + + This reverts commit 654711d0f940d7480d0f1cdb25a3dc9996f7a706. + + Due to this commit breaking backwards compatability, we decided to + revert this change + + gi/overrides/Gtk.py | 15 --------------- + tests/compathelper.py | 2 -- + tests/test_overrides.py | 31 +------------------------------ + 3 files changed, 1 insertion(+), 47 deletions(-) + +commit 0e921cd26ed5a6e3bc6ef5f553e8b22b862d72a6 +Author: Sebastian Pölsterl +Date: Sun Feb 5 13:47:10 2012 +0100 + + tests: Fixed issues with python3 + + tests/test_gi.py | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +commit ee62df4d2fc0cc63c2f29d3ad9b47b875dbd5f89 +Author: Sebastian Pölsterl +Date: Sun Feb 5 11:59:51 2012 +0100 + + Properly distinguish between different integer types for properties + + https://bugzilla.gnome.org/show_bug.cgi?id=664150 + + gi/pygi-property.c | 48 ++++++++++++++++++++++++++++++++++++++---- + tests/test_gi.py | 62 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 106 insertions(+), 4 deletions(-) + +commit c329bf2aee8d75ce452638db75e09197ff2b9b65 +Author: Sebastian Pölsterl +Date: Sun Feb 5 11:46:21 2012 +0100 + + Distinguish between GArray and GPtrArray when cleaning up + + This fixes a crash in test_gi.TestGPtrArray and makes sure + memory is free'd correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=669393 + + gi/pygi-marshal-cleanup.c | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +commit 4ea37c606f67df843788261b2c8acd6bac4c1e0c +Author: Paolo Borelli +Date: Sun Feb 5 18:51:53 2012 +0100 + + Add null_gerror_callback unit test + + This models the case where the callback is successful and does not set + an error. + + https://bugzilla.gnome.org/show_bug.cgi?id=669415 + + tests/test_everything.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit a41984780ee49dcf02c718ca1be87bba747472e5 +Author: Martin Pitt +Date: Mon Feb 6 09:34:28 2012 +0100 + + pyglib_error_check: Re-add missing NULL check + + Commit adcfe96d49b09bc accidentally dropped the check if *error is + NULL, i. e. + any error is actually set. Due to that, pyglib_error_check() + always returned + TRUE. Reintroduce the check. + + Thanks to Alberto Mardegan for spotting this! + + https://bugzilla.gnome.org/show_bug.cgi?id=669415 + + gi/_glib/pyglib.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 2c797c17913999379e277788d5e4cce8d68cebb0 +Author: Michael Culbertson +Date: Sat Feb 4 16:11:34 2012 +0100 + + Add tests/runtests-windows.py to source tarball + + https://bugzilla.gnome.org/show_bug.cgi?id=663288 + + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit d6a899cdf70e978534326155e3fad75a705f4b20 +Author: Sebastian Pölsterl +Date: Sat Feb 4 15:55:55 2012 +0100 + + Don't issue a depreciation warning for GtkDialog's NO_SEPARATOR flag, + even when unused + + https://bugzilla.gnome.org/show_bug.cgi?id=665553 + + gi/overrides/Gtk.py | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit 534ec71c575a279ff1c05da20a8858bb1145b4d0 +Author: Nirbheek Chauhan +Date: Sat Feb 4 15:42:36 2012 +0100 + + Fix bool() operations on GLib.Variant objects + + Defines __nonzero__ (python2) and __bool__ (python3) for GLib.Variant + + Also adds some tests for boolean comparisons. + + https://bugzilla.gnome.org/show_bug.cgi?id=647723 + + gi/overrides/GLib.py | 18 ++++++++++++++++++ + tests/test_overrides.py | 45 + +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 63 insertions(+) + +commit 8d6a127df5dd1e5f26faeba8f977074b4496b24f +Author: Nirbheek Chauhan +Date: Sat Feb 4 15:41:08 2012 +0100 + + Fix hash() and __eq__() for GLib.Variant objects + + Define __hash__, __eq__, __ne__ for GLib.Variant so that objects can + be used in sets, dicts, and can be compared using == and != easily. + + Also adds some tests for this. + + https://bugzilla.gnome.org/show_bug.cgi?id=647725 + + gi/overrides/GLib.py | 23 ++++++++++++++++++++ + tests/test_overrides.py | 56 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 79 insertions(+) + +commit f82404034be042bf2026bbb7f1e33b11d6e17a6f +Author: Martin Pitt +Date: Wed Jan 25 07:01:06 2012 +0100 + + Fix method names of callback tests + + Change test_everything.TestCallbacks.* test names from camelCase + to the + standard PEP-8 underscore_style. This is now consistent with all + other test + case names. + + tests/test_everything.py | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +commit e37ee78fbf0aa72159a40da4165a26bea065faf1 +Author: Will Thompson +Date: Mon Jan 23 13:10:30 2012 +0000 + + Cairo: add missing braces around array-of-struct definition + + This triggered a -Wmissing-braces warning. + + https://bugzilla.gnome.org/show_bug.cgi?id=668497 + + gi/pygi-foreign-cairo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit db24865d6b60351d72f5b8f47103d6d0a6c63b2e +Author: Will Thompson +Date: Mon Jan 23 13:06:41 2012 +0000 + + g_instance_init: cast to PyGObject * as needed + + This squashes a compiler warning. + + https://bugzilla.gnome.org/show_bug.cgi?id=668497 + + gi/_gobject/gobjectmodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a8408cfd68cd5e7cdb0b8a83e107d9a0d828e4bd +Author: Will Thompson +Date: Mon Jan 23 13:01:27 2012 +0000 + + Fix a few set-but-not-used warnings. + + In a couple of cases, the variable in question was set to a value + spelled out again later in the function. + + The 'sequence_cache' variable is re-declared five lines below. + + The return value of 'read' was previously completely ignored. The + 'gssize ret' variable was in fact added to squash an unused-result + warning. + + https://bugzilla.gnome.org/show_bug.cgi?id=668497 + + gi/_glib/pygiochannel.c | 2 +- + gi/_glib/pygmainloop.c | 3 +-- + gi/_gobject/pygobject.c | 2 +- + gi/pygi-marshal-cleanup.c | 2 -- + 4 files changed, 3 insertions(+), 6 deletions(-) + +commit 29a30490ed51e347e8f57d2bf9af69400734eee8 +Author: Stefano Facchini +Date: Thu Jan 19 18:09:07 2012 +0100 + + pygmainloop: allow for extra arguments in 'quit' method + + To allow for the common syntax: + + object.connect('signal-name', main_loop.quit) + + https://bugzilla.gnome.org/show_bug.cgi?id=668288 + + gi/_glib/pygmainloop.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 557a61c12c01137a0d7c679c4b053973df09d445 +Author: Alexandre Rostovtsev +Date: Mon Dec 26 00:44:56 2011 -0500 + + Fix bytearray test compatibility with python3 + + https://bugs.gentoo.org/show_bug.cgi?id=321879 + + https://bugzilla.gnome.org/show_bug.cgi?id=666852 + + tests/test_gi.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d69e5b3c7bdb9113382fd125c256b12bff4c24d2 +Author: Alberto Mardegan +Date: Mon Jan 23 12:37:26 2012 +0200 + + Respect transfer-type when demarshalling GErrors + + The marshaller previously ignored "transfer full" on GError* + arguments, causing + crashes due to double-freeing them. This causes the + testCallbackUserdata() test + case to crash after the previous GError/GHashTable marshalling fix. + + https://bugzilla.gnome.org/show_bug.cgi?id=666270 + + gi/pygi-argument.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +commit 77f32d9110bfeb6dad8457f565b4c70b5998fef6 +Author: Alberto Mardegan +Date: Thu Dec 15 16:12:01 2011 +0200 + + Support GHashTable and GError as callback/closure arguments + + Marshalling of these types from C is already implemented, let's + take it + into use for calbacks and closures too. + + Add corresponding test cases. + + https://bugzilla.gnome.org/show_bug.cgi?id=666270 + + Signed-off-by: Martin Pitt + + gi/pygi-closure.c | 2 ++ + tests/test_everything.py | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 37 insertions(+) + +commit 4b9dc03d0e49e9a1f4bf0f2df503bdff00d13a2b +Author: Will Thompson +Date: Mon Jan 23 13:56:02 2012 +0000 + + Don't leak when marshalling GErrors to C + + Python-land GLib.GErrors are supposed to have three attributes: + "message", "domain" and "code". If those attributes are missing, + or they + have the wrong types, the C GError is filled in with a message + describing the error. The present-but-ill-typed code paths did not + DECREF the ill-typed values. + + https://bugzilla.gnome.org/show_bug.cgi?id=666098 + + gi/_glib/pyglib.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit adcfe96d49b09bcc550653d73de196610fd5144d +Author: Will Thompson +Date: Fri Jan 20 16:20:10 2012 +0000 + + Support functions which return GError + + GStreamer has the following method: + + void gst_message_parse_error ( + GstMessage *message, + GError **error, + gchar **debug_message); + + With this patch, we marshal the GError out parameter as a + GObject.GError + exception, but return it rather than throwing it. The test cases cover + two variations on the theme of the function above (one with (transfer + full), as in GStreamer, and another with (transfer none)) as well as a + function with return type GError *. + + https://bugzilla.gnome.org/show_bug.cgi?id=666098 + + gi/_glib/pyglib.c | 46 + +++++++++++++++++++++++++++++++++++----------- + gi/_glib/pyglib.h | 1 + + gi/pygi-marshal-to-py.c | 16 +++++++++++++--- + tests/test_gi.py | 32 ++++++++++++++++++++++++++++++++ + 4 files changed, 81 insertions(+), 14 deletions(-) + +commit 09f003729eac9d553a208c343c2a14d253b77d9a +Author: Alberto Mardegan +Date: Mon Jan 23 12:42:21 2012 +0200 + + Fix indentation of _pygi_argument_to_object() + + Side issue in https://bugzilla.gnome.org/show_bug.cgi?id=666270 + + Signed-off-by: Martin Pitt + + gi/pygi-argument.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +commit c71c010be01d706f90bc200194325fd82f4071b2 +Author: Paolo Borelli +Date: Sat Jan 14 14:24:23 2012 +0100 + + Avoid C99 syntax. + + gi/gimodule.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +commit c299d058c22385ececaec64c872d1dd1bc1ae17a +Author: Paolo Borelli +Date: Fri Jan 6 13:39:31 2012 +0100 + + Connect to first action of a radio group. + + gi/overrides/Gtk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit dee2f179037902a3883bd0e61ff1c350e1fd8a4f +Author: Paolo Borelli +Date: Wed Jan 4 16:40:51 2012 +0100 + + Use g_slist_free_full in pygi-closure. + + gi/pygi-closure.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 2bee4207ab6f07dc9c0952affe72f0e304cfb624 +Author: Paolo Borelli +Date: Wed Jan 4 15:24:13 2012 +0100 + + Avoid O(n^2) behavior when marshalling lists + + Appending requires walking the list every time: just prepend and + reverse + the list at the end. + + https://bugzilla.gnome.org/show_bug.cgi?id=667261 + + gi/pygi-marshal-from-py.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit d68455e99b1a9ebba31209b17a11317b1958678b +Author: Paolo Borelli +Date: Tue Jan 3 16:57:40 2012 +0100 + + Handle NULL as a valid case of a char** array + + Treat NULL as an empty array and add the corresponding testcase + + gi/pygi-marshal-to-py.c | 9 +++++---- + tests/test_gi.py | 3 +++ + 2 files changed, 8 insertions(+), 4 deletions(-) + +commit e3451b8e6018bb76e9992fb6af24a71725de5cfd +Author: Tomeu Vizoso +Date: Fri Dec 23 12:01:43 2011 +0100 + + Branching, bump version to 3.1.0 + + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8d1a36cc73f5f4df091ecb289c8a7b38ec2ab605 +Author: Tomeu Vizoso +Date: Mon Dec 12 18:35:30 2011 +0100 + + Add notes about branching to HACKING + + HACKING | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 00030bc6f0fb961c716ed692144cd8e4bb9be7d0 +Author: Sebastian Pölsterl +Date: Sat Dec 10 12:51:45 2011 +0100 + + Fixed bug where GObject.property did not respect minimum and maximum + values + + https://bugzilla.gnome.org/show_bug.cgi?id=664864 + + gi/_gobject/propertyhelper.py | 2 +- + tests/test_properties.py | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 1 deletion(-) + +commit 7b78abc6c399abd0daa4c11c644d107e1bb7b452 +Author: Tomeu Vizoso +Date: Mon Dec 12 17:00:24 2011 +0100 + + Remove mention of removed option --enable-docs + + HACKING | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4cba52f5b5e79b7b6212cb0795e8976a9da9f21d +Author: Tomeu Vizoso +Date: Mon Dec 12 17:00:03 2011 +0100 + + Fix sebp's name in NEWS + + NEWS | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8c95981d0ba224a577f87998030c384b3dae3d80 +Author: Tomeu Vizoso +Date: Mon Dec 12 16:20:09 2011 +0100 + + Release 3.0.3 + + NEWS | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 58e47fd28c5d75bb78042c8f9eb5aae84de9c64d +Author: Tomeu Vizoso +Date: Mon Dec 12 16:16:44 2011 +0100 + + Pre-release version bump + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 884468d4816fc976c0c0c72651e7f81d13f3f78b +Author: Manuel Quiñones +Date: Thu Dec 1 11:50:38 2011 -0300 + + Convert all modifier constants to Gdk.ModifierType + + Signed-off-by: Manuel Quiñones + + pygi-convert.sh | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit 654711d0f940d7480d0f1cdb25a3dc9996f7a706 +Author: Sebastian Pölsterl +Date: Tue Nov 8 12:38:12 2011 +0100 + + Convert all strings to utf-8 encoding when retrieving from TreeModel + + https://bugzilla.gnome.org/show_bug.cgi?id=663610 + + gi/overrides/Gtk.py | 15 +++++++++++++++ + tests/compathelper.py | 2 ++ + tests/test_overrides.py | 31 ++++++++++++++++++++++++++++++- + 3 files changed, 47 insertions(+), 1 deletion(-) + +commit 4f637212f13b197a95c824967a58496b9e3b877c +Author: John (J5) Palmieri +Date: Wed Nov 2 14:51:24 2011 -0400 + + add test for bytearray variants + + tests/test_gi.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 20ca3f129d6cc662285cce8c732b55596016aefa +Author: John (J5) Palmieri +Date: Wed Nov 2 14:50:42 2011 -0400 + + handle NULL arrays correctly for each array type + + gi/pygi-marshal-to-py.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +commit ce2f780bffe44b1d4de617dcbce4b90c58b03c18 +Author: John (J5) Palmieri +Date: Wed Nov 2 14:17:21 2011 -0400 + + Revert "Revert "Fix array termination and size calculation"" + + This reverts commit cfda820e8d9604c5ef2ad1161c22b20080d5daf4. + + gi/pygi-marshal-from-py.c | 6 +++++- + gi/pygi-marshal-to-py.c | 8 +++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +commit 832f16f96815adc22cc3acbeb3fa969631795a29 +Author: Owen W. Taylor +Date: Sun Oct 30 18:08:57 2011 -0400 + + pygmainloop: avoid lockups if multiple glib.MainLoop exist + + If multiple glib.MainLoop() sources exist, then we will add multiple + watches, and when python writes a byte to the wakeup pipe, all of the + sources will try to read it; only one will succeed and the others + will block. Set both ends of the pipe nonblocking to avoid this. + + https://bugzilla.gnome.org/show_bug.cgi?id=663068 + + gi/_glib/pygmainloop.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 2fd3aa9d4ca0906a5e609845ee500ba72e358f94 +Author: Tomeu Vizoso +Date: Sat Oct 29 15:08:03 2011 +0200 + + Properly chain up to the class that implements a given vfunc. + + https://bugzilla.gnome.org/show_bug.cgi?id=662994 + + gi/types.py | 22 +++++++++++++--------- + tests/test_gi.py | 20 ++++++++++---------- + 2 files changed, 23 insertions(+), 19 deletions(-) + +commit cfda820e8d9604c5ef2ad1161c22b20080d5daf4 +Author: Tomeu Vizoso +Date: Wed Nov 2 14:54:21 2011 +0100 + + Revert "Fix array termination and size calculation" + + This reverts commit eef35b2df8023ffff2d195ee16c084f5cfcb6ba3. + + gi/pygi-marshal-from-py.c | 6 +----- + gi/pygi-marshal-to-py.c | 8 +------- + 2 files changed, 2 insertions(+), 12 deletions(-) + +commit eef35b2df8023ffff2d195ee16c084f5cfcb6ba3 +Author: Holger Berndt +Date: Sun Oct 30 16:36:32 2011 +0100 + + Fix array termination and size calculation + + When creating an array of element type uint8 and setting it directly + with + memcpy(), make sure that zero-termination is respected. + + When calculating the length of a zero-terminated array of type uint8, + fall back to strlen() instead of g_strv_length(). + + https://bugzilla.gnome.org/show_bug.cgi?id=662550 + + gi/pygi-marshal-from-py.c | 6 +++++- + gi/pygi-marshal-to-py.c | 8 +++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +commit 4c1d9f01b8fa6702f73b290180f934250e179caa +Author: Daniel Drake +Date: Sun Oct 30 09:20:45 2011 +0000 + + pygi-convert: fix for Pango.Alignment + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit e3abd76096cc9f335681c7225f452c286b9c59e2 +Author: Daniel Drake +Date: Sun Oct 30 07:06:57 2011 +0000 + + pygi-convert: fix for Gtk.Orientation + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 52b82c5f78ef3755388457fa9440c36ccd2dfbbf +Author: Martin Pitt +Date: Thu Oct 27 07:16:24 2011 +0200 + + Add tests for calling closures + + Add checks for correct handling of closure calls. + Regress.test_closure_one_arg() is working fine and should continue + to do so. + Regress.test_closure_variant() is known to not work yet, so mark + this as EXFAIL + for now. (See https://bugzilla.gnome.org/show_bug.cgi?id=656554) + + tests/test_everything.py | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +commit c7aa0e79dfb4c1092c51ae1464b8414083b4f3fc +Author: Mikkel Kamstrup Erlandsen +Date: Tue Oct 4 12:28:26 2011 +0200 + + fix marshaling of arrays of GVariants + + Add unit tests for marshaling of arrays of variants with all + transfer modes. Requires latest gobject-introspection. + + Plug potential leaks of GArray data members + + Fix calling of wrong cleanup_from_py for arrays + + Simplify and fix logic for cleaning up arrays both in from_py() + and to_py() code paths. + + https://bugzilla.gnome.org/show_bug.cgi?id=638915 + + Signed-off-by: Martin Pitt + + gi/pygi-cache.c | 2 +- + gi/pygi-marshal-cleanup.c | 81 + ++++++++++++++++++++++++++++++----------------- + gi/pygi-marshal-from-py.c | 10 ++++-- + gi/pygi-marshal-to-py.c | 13 ++++++-- + tests/test_gi.py | 14 +++++++- + 5 files changed, 85 insertions(+), 35 deletions(-) + +commit c2ec4d8eb46ae2e6ee4372b2a4f9d5df0e5d82f3 +Author: Ignacio Casal Quinteiro +Date: Sat Oct 22 00:20:57 2011 +0200 + + Release 3.0.2 + + NEWS | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 5c24760b797e985721f7fe51d52252e4dd54a417 +Author: Martin Pitt +Date: Fri Oct 21 17:31:41 2011 +0200 + + Fix "Returns: (skip)" method calls without (out) arguments + + When we have a method call with a skipped return value, but no + other out + arguments, we previously returned NULL to Python, which causes + "SystemError: + error return without exception set". Return None instead. + + https://bugzilla.gnome.org/show_bug.cgi?id=662383 + + gi/pygi-invoke.c | 10 ++++++++++ + tests/test_everything.py | 8 ++++++++ + 2 files changed, 18 insertions(+) + +commit 585222915dc98b0e375de3db4771466278a32e81 +Author: John (J5) Palmieri +Date: Tue Oct 18 00:39:16 2011 -0400 + + Do union member checks for unions that are parameters + + * before we were only doing checks if the union was an instance + + https://bugzilla.gnome.org/show_bug.cgi?id=661673 + + gi/pygi-marshal-from-py.c | 121 + ++++++++++++++++++++++++++-------------------- + 1 file changed, 68 insertions(+), 53 deletions(-) + +commit 8deaec6b9abd87f02060c9feec773d4693e89028 +Author: Martin Pitt +Date: Wed Oct 19 14:35:11 2011 +0200 + + Gdk overrides: Unbreak for Gdk-2.0 + + Fix regression from commit 31db3ed: Gdk 2.0 did not yet have + atom_intern(), so + only do this for Gdk >= 3.0. + + https://launchpad.net/bugs/875399 + + gi/overrides/Gdk.py | 95 + +++++++++++++++++++++++++++-------------------------- + 1 file changed, 48 insertions(+), 47 deletions(-) + +commit f395fb131caf7ca550acd17138d8061926ef4f92 +Author: John (J5) Palmieri +Date: Fri Oct 14 17:19:45 2011 -0400 + + unit test for checking ref count of object param in signals + + https://bugzilla.gnome.org/show_bug.cgi?id=661359 + + tests/test_everything.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 611f58b99851328653af4930f188c33eccaa9f6f +Author: John (J5) Palmieri +Date: Fri Oct 14 16:42:32 2011 -0400 + + when converting an object with transfer none, make sure the wrapper + owns a ref + + https://bugzilla.gnome.org/show_bug.cgi?id=661359 + + gi/pygi-argument.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 0f1eb9fa0e7aa5e7c22dabc709c0dfb469e404f1 +Author: Timo Vanwynsberghe +Date: Tue Oct 4 11:13:43 2011 +0200 + + Allow GBoxed types as property + + Add the GBoxed type as valid type to the gobject property helper + https://bugzilla.gnome.org/show_bug.cgi?id=660798 + + gi/_gobject/propertyhelper.py | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit bef8d385117dd0295c9ba7567710d76fc2bb729a +Author: Ignacio Casal Quinteiro +Date: Mon Oct 10 11:24:42 2011 +0200 + + Add tests for boxed properties. + + tests/test_properties.py | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +commit 77123ffeb1585837033848f4d5a90cfa63fdaee0 +Author: Ignacio Casal Quinteiro +Date: Fri Sep 30 20:21:07 2011 +0200 + + Post release bump version + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f5ccfec0a1bc4c999bfa49d75383ea06d3a068c4 +Author: Ignacio Casal Quinteiro +Date: Fri Sep 30 20:19:46 2011 +0200 + + Release 3.0.1 + + NEWS | 5 +++++ + configure.ac | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit 56ac9339eb1d6950623dc4d8c3b9972874e7fa86 +Author: John (J5) Palmieri +Date: Thu Sep 22 19:03:20 2011 -0400 + + when checking instances union members are same type as parent + + * this is so we can support sending Gdk.Event members in place of + the Event union into methods + * we only support this if the union member has a type of GI_INTERFACE + for now + + https://bugzilla.gnome.org/show_bug.cgi?id=659879 + + gi/pygi-marshal-from-py.c | 60 + +++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 56 insertions(+), 4 deletions(-) + +commit 311a4f8035a95b41bc3c0a836c32b7a5bf2d9959 +Author: John (J5) Palmieri +Date: Wed Sep 21 21:50:48 2011 -0400 + + add a floating flag to pygobjects + + * this allows us to correctly refcount when custom gobjects are + instantiated + via g_object_new + + gi/_gobject/gobjectmodule.c | 5 +++++ + gi/_gobject/pygobject-private.h | 3 +++ + gi/_gobject/pygobject.c | 27 ++++++++++++++++++++++++++- + gi/_gobject/pygobject.h | 3 ++- + 4 files changed, 36 insertions(+), 2 deletions(-) + +commit d2d29ae5845217254b9336fd8629f369cb119b25 +Author: John (J5) Palmieri +Date: Wed Sep 21 21:13:22 2011 -0400 + + Revert "Fix refcount bug by not creating python wrapper during + gobject init stage" + + This reverts commit f6fa5dd8f39af1b8a52d7600d257400b0983e8c5. + + gi/_gobject/gobjectmodule.c | 32 +++++++++++++++++--------------- + 1 file changed, 17 insertions(+), 15 deletions(-) + +commit a24c10b779f2a1b0425d56d03d59c393389cad98 +Author: John (J5) Palmieri +Date: Wed Sep 21 21:10:00 2011 -0400 + + make sure to commit the NEWS file + + NEWS | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 2eed2940c9be099fb6305288d895265e6b35d3d2 +Author: John (J5) Palmieri +Date: Mon Sep 19 13:19:57 2011 -0400 + + prep for 3.0 release + + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit fbd58b70c2c3c1128f95a87eb4cc8313b6a401b8 +Author: John (J5) Palmieri +Date: Fri Sep 16 14:19:15 2011 -0400 + + up version required of gobject-introspection to 1.29.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 225f21117b6b3546989abe22538c784291e86b2a +Author: John (J5) Palmieri +Date: Fri Sep 16 12:26:10 2011 -0400 + + fix most warnings + + * remove some unused vars + * correctly cast vars + * handle deprecated enums in switch statments by using default: + * unused wanrings still remain in some places + + gi/pygi-argument.c | 2 +- + gi/pygi-cache.c | 7 ++----- + gi/pygi-info.c | 6 ++++++ + gi/pygi-invoke.c | 2 +- + gi/pygi-marshal-from-py.c | 17 +++++++++-------- + gi/pygi-marshal-to-py.c | 3 +-- + 6 files changed, 20 insertions(+), 17 deletions(-) + +commit 9a70f01288e1b049206d25d67938907f1b38a490 +Author: John (J5) Palmieri +Date: Fri Sep 16 12:24:38 2011 -0400 + + post release bump + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3ec4020205e909ee4400650434f9ae7b89c2bde8 +Author: John (J5) Palmieri +Date: Thu Sep 15 18:12:01 2011 -0400 + + edit HACKING file to show correct tag format + + HACKING | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2e864fd05bc0adf48df9f65ab72785ebb1d0d3f0 +Author: John (J5) Palmieri +Date: Thu Sep 15 18:10:33 2011 -0400 + + update NEWS file to prep for release + + NEWS | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +commit 0da687fa699aba4f42c42a924d6754e2bd47df50 +Author: John (J5) Palmieri +Date: Thu Sep 15 17:59:31 2011 -0400 + + fix typo s/lenth/length + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0e4861abaff64d8e7e8d1aeedf9dd1e80de8aab2 +Author: John (J5) Palmieri +Date: Thu Sep 15 17:48:58 2011 -0400 + + fix typo in docstring + + gi/_gobject/propertyhelper.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e7fcc326d64def610e5a1003cf6c7ca97023814d +Author: John (J5) Palmieri +Date: Thu Sep 15 17:46:46 2011 -0400 + + do not pass in len(str) to the length argument of + gtk_test_buffer_insert* apis + + * in python 3 len(str) returns the number of characters while + the length + parameter is expecting the number of bytes. It also excepts -1 + for null + terminated string. Since all of our strings are null terminated, + just + set length to that. + + gi/overrides/Gtk.py | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit 6f380153afb3390f7da9f4b8befb1c4ee224da17 +Author: Dieter Verfaillie +Date: Mon Sep 12 21:07:20 2011 +0200 + + Switch tarball compression format to tar.xz only. + + See + http://mail.gnome.org/archives/gnome-announce-list/2011-September/msg00031.html + for more information. + + https://bugzilla.gnome.org/show_bug.cgi?id=659140 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 11c45ac6dcb6ffad766d03bfc77f45a6d703a90d +Author: Dieter Verfaillie +Date: Thu Sep 15 14:18:57 2011 +0200 + + Remove pygtk_version attribute from internal gi._gobject module. + + This used to be provided for backwards compatibility with older PyGTK + versions. As PyGObject3 no longer provides support for static bindings + like PyGTK, the pygtk_version attribute has become obsolete. + + https://bugzilla.gnome.org/show_bug.cgi?id=659142 + + gi/_gobject/gobjectmodule.c | 4 ---- + gi/_gobject/pygobject.h | 2 -- + 2 files changed, 6 deletions(-) + +commit 7e48fd6dfd86b7082c3fd35d25d9693c56c9665a +Author: John (J5) Palmieri +Date: Thu Sep 15 15:52:18 2011 -0400 + + remove overridesdir from the .pc file and add it to the gi module + + * having the variable in the .pc file caused issues parallel + installing + for different versions of python + * putting it into the module allows us to give the correct directory + based on which version of python you run the script from + * access the var as such: + import gi + installdir = gi._overridesdir + + gi/__init__.py | 2 ++ + pygobject-3.0.pc.in | 10 +++++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit beea7072a5a989be47a755ac46647380d4dbd6b4 +Author: John (J5) Palmieri +Date: Thu Sep 15 00:11:09 2011 -0400 + + fix tests to correctly construct a dummy Gtk.TargetEntry + + * structs are sometimes a pain in gi. Simply constructing them + using the + the standard constructor (e.g. Gtk.TargetEntry()) will malloc + the struct + but not correctly initialize the fields which can cause a crash. + * tests didn't crash before because they were sending in bogus + data that + somehow did not trigger the issue + * now with the C struct array marshallers doing the right thing, + the incorrect + use of TargetEntry was causing a crash + + https://bugzilla.gnome.org/show_bug.cgi?id=627236 + + tests/test_overrides.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 46ba7f04ef3df08e07ddda5c10f0c98bec5fa183 +Author: John (J5) Palmieri +Date: Thu Sep 15 00:08:31 2011 -0400 + + we now assume that C arrays of structs are flat so memcpy them + when marshalling + + * there is no way in GI to tell if a C array is flat or an array + of pointers + so we assume that all arrays of simple structs and gvalues are + flat and + all arrays of objects and boxed structs are pointer arrays. + * this will be removed once GI gets the ability to annotate level + of indirection + for arrays + https://bugzilla.gnome.org/show_bug.cgi?id=627236 + + gi/pygi-marshal-from-py.c | 35 ++++++++++++++++++++++++++++++++--- + tests/test_gi.py | 29 +++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 3 deletions(-) + +commit e30a41592baa942188574e5c9f99572963e2e387 +Author: John (J5) Palmieri +Date: Thu Sep 15 00:02:34 2011 -0400 + + only update the arg counts once if child arg comes before parent arg + + * if the child arg comes before the parent arg we need to update the + argument counts and take the child arg out of the marshalling lists + since it is handled by the parent + * when two parents reference the same child arg as is the case with + two arrays which have a single length argument we only want + to update + the count once + * to do this we introduce the PYGI_META_ARG_CHILD_NEEDS_UPDATE + meta type + and only do the count update if this is set + * APIs should keep in mind that this take extra processing so + child args + should really come after their parents + + https://bugzilla.gnome.org/show_bug.cgi?id=627236 + + gi/pygi-cache.c | 30 ++++++++++++++++++++---------- + gi/pygi-cache.h | 9 +++++++-- + 2 files changed, 27 insertions(+), 12 deletions(-) + +commit f6fa5dd8f39af1b8a52d7600d257400b0983e8c5 +Author: John (J5) Palmieri +Date: Wed Sep 14 20:26:15 2011 -0400 + + Fix refcount bug by not creating python wrapper during gobject + init stage + + * This only applys to python subclasses of GObject which are + instantiated + using GObject.new + * Because we were creating the wrapper when the gobject is + initialized + and then again calling pygobject_new_full the wrapper would get + ref'ed twice. + * we could not simply Py_DECREF the wrapper due to the fact that + non-subclassed objects (e.g. GObject.Object) instantiated via + new do not run the same initialization code and would not have the + extra ref + * solution was to simply not create the wrapper during initialization + because if it doesn't exist when pygobject_new_full is called + it gets created and registered there + * move the call to __init__ into pyg_object_new + + https://bugzilla.gnome.org/show_bug.cgi?id=657403 + + gi/_gobject/gobjectmodule.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +commit 61b64a65beee9011f8e4ed20f0a83e6630ba154f +Author: John (J5) Palmieri +Date: Tue Sep 13 18:08:04 2011 -0400 + + don't destroy just created wrapper when object is created via + g_object_new + + https://bugzilla.gnome.org/show_bug.cgi?id=657403 + + gi/_gobject/gobjectmodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 93e12cc2eb7e7f2c18971da86e9c9452d3f566b7 +Author: Steve Frécinaux +Date: Fri Aug 26 11:22:09 2011 +0200 + + Remove deprecated API from pygobject.h + + https://bugzilla.gnome.org/show_bug.cgi?id=657416 + + gi/_gobject/pygobject.h | 19 +------------------ + 1 file changed, 1 insertion(+), 18 deletions(-) + +commit e1c71092af6e2cffa36248519adfceac1874051d +Author: Marcin Owsiany +Date: Wed Aug 31 09:43:28 2011 +0100 + + Convert gtk.TRUE/FALSE to Python True/False. + + https://bugzilla.gnome.org/show_bug.cgi?id=657785 + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 3ace5c2e2268285a5dcb39889fcb2a71bc1063bd +Author: Steve Frécinaux +Date: Fri Sep 2 08:37:15 2011 +0200 + + Drop legacy __gobject_init__ method of GObject.Object. + + This method was used in gobject initialization at some point, but now + using GObject.__init__() is sufficient, so let's not keep this old + method around and let people misuse it. + + https://bugzilla.gnome.org/show_bug.cgi?id=658032 + + examples/signal.py | 2 -- + gi/_gobject/pygobject.c | 11 ----------- + 2 files changed, 13 deletions(-) + +commit fcd457d1d1d8a813acb2ebfe5ee0e9aab2c9c88c +Author: Dieter Verfaillie +Date: Tue Sep 13 12:05:30 2011 +0200 + + AM_CHECK_PYTHON_LIBS does not work for lib64 + + But on Windows, Python extension modules need to be explicitly + linked to libpython. + + https://bugzilla.gnome.org/show_bug.cgi?id=658856 + + configure.ac | 4 +++- + gi/Makefile.am | 9 ++++++--- + gi/_glib/Makefile.am | 10 ++++++++-- + gi/_gobject/Makefile.am | 8 +++++++- + 4 files changed, 24 insertions(+), 7 deletions(-) + +commit 863c087911203a8f3ebaa8e77622a3437a7cd320 +Author: Dieter Verfaillie +Date: Mon Sep 12 23:03:05 2011 +0200 + + Remove common_ldflags from Makefile.am as it is no longer used. + + https://bugzilla.gnome.org/show_bug.cgi?id=658856 + + Makefile.am | 6 ------ + 1 file changed, 6 deletions(-) + +commit 24b920f9922e367bdb8b3e56c2f61e0c8f5cdb66 +Author: John (J5) Palmieri +Date: Tue Sep 13 16:20:48 2011 -0400 + + cast params for PyObject_IsInstance to suppress warnings + + gi/_gobject/pygobject-private.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 861369ec59b17f67151813dc2e87c6e86126b954 +Author: John (J5) Palmieri +Date: Tue Sep 13 16:04:31 2011 -0400 + + check if object is actually a PyGFlag before trying to access g_type + + * we are lucky this bit of code worked for as long as it did but when + checking if an object is a PyGFlag we can't just rely on looking + at the g_type field because if a regular gobject is passed in + as is the case when you compare a long to a gflag, the gobject + will not have a g_type field. Accessing a non-existant field + could at best give you a false positive and at worse read + memory beyond the bounds of the actual structure passed in + + gi/_gobject/pygobject-private.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit eea93e89fb064253bd8903c8b453daf4b3c87c2c +Author: John (J5) Palmieri +Date: Tue Sep 13 16:03:02 2011 -0400 + + fix regression - add instance type checks since Py3 no longer does + this for us + + gi/pygi-marshal-from-py.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +commit a4e4318b50a24a688e32579273fbcfa51d1b422a +Author: John (J5) Palmieri +Date: Fri Sep 2 18:39:51 2011 -0400 + + refactor in/out marshalling to be to_py/from_py + + * in/out make sense from a C perspective but when you get to the + python layers it makes more sense to label them as to_py and + from_py to denote which way we are marshalling + * this helps clear up the difference between callbacks which + call into python and invoked functions which call into C + * in the callback case we marshal in values to Python objects + and out values to C types but in the invoke case we do the + reverse. Dealing with to_py/from_py makes the code much more + resuable and consistant + + https://bugzilla.gnome.org/show_bug.cgi?id=658362 + + gi/Makefile.am | 8 +- + gi/pygi-cache.c | 673 ++++++++++----------- + gi/pygi-cache.h | 62 +- + gi/pygi-invoke.c | 144 ++--- + gi/pygi-marshal-cleanup.c | 168 +++--- + gi/pygi-marshal-cleanup.h | 128 ++-- + gi/pygi-marshal-from-py.c | 1412 + +++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-from-py.h | 186 ++++++ + gi/pygi-marshal-in.c | 1412 + --------------------------------------------- + gi/pygi-marshal-in.h | 186 ------ + gi/pygi-marshal-out.c | 768 ------------------------ + gi/pygi-marshal-out.h | 144 ----- + gi/pygi-marshal-to-py.c | 768 ++++++++++++++++++++++++ + gi/pygi-marshal-to-py.h | 144 +++++ + 14 files changed, 3122 insertions(+), 3081 deletions(-) + +commit 45b0fcff9e948c65a3903c32a3957802034c5e47 +Author: Dieter Verfaillie +Date: Fri Sep 9 16:50:25 2011 +0200 + + Examples: fix cairo-demo.py imports + + examples/cairo-demo.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 3ca19fc13e6024fd04851e6f269020a92b09fa17 +Author: Dieter Verfaillie +Date: Fri Sep 9 15:08:27 2011 +0200 + + Fix paths and add missing overridesdir variable used in uninstalled + pkgconfig file + + https://bugzilla.gnome.org/show_bug.cgi?id=658654 + + pygobject-3.0-uninstalled.pc.in | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 6e773175b9d2f46b3df5075ec952a8c5aff3c607 +Author: Dieter Verfaillie +Date: Fri Sep 9 15:08:04 2011 +0200 + + Remove no longer used variables from pkgconfig files + + https://bugzilla.gnome.org/show_bug.cgi?id=658654 + + pygobject-3.0-uninstalled.pc.in | 6 ------ + pygobject-3.0.pc.in | 5 +---- + 2 files changed, 1 insertion(+), 10 deletions(-) + +commit 81d388780311311d8dc4a027a59d114edf9a00fc +Author: Dieter Verfaillie +Date: Fri Sep 9 14:57:58 2011 +0200 + + docs/Makefile.am and m4/python.m4: Python3 portability fixes + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + docs/Makefile.am | 2 +- + m4/python.m4 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 7e692ee061406e48e4862b98a0829650b1d6d585 +Author: Dieter Verfaillie +Date: Fri Sep 9 14:57:46 2011 +0200 + + Refactor and clean Makefile.am files + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + Makefile.am | 2 - + gi/Makefile.am | 81 +++++++++++++++++++++++-------------- + gi/_glib/Makefile.am | 100 + ++++++++++++++++++++++++++++++---------------- + gi/_gobject/Makefile.am | 85 ++++++++++++++++++++------------------- + gi/overrides/Makefile.am | 4 +- + gi/repository/Makefile.am | 4 +- + 6 files changed, 162 insertions(+), 114 deletions(-) + +commit 3dd59b07d1f4a93ee1f65d6a64e1afb6f5e84232 +Author: Dieter Verfaillie +Date: Fri Sep 9 14:57:36 2011 +0200 + + Remove all PLATFORM_VERSION = 2.0 traces + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + gi/Makefile.am | 2 -- + gi/overrides/Makefile.am | 1 - + gi/repository/Makefile.am | 1 - + 3 files changed, 4 deletions(-) + +commit db1e484bfa157967de55ee2e0e18a82b8e388b61 +Author: Dieter Verfaillie +Date: Fri Sep 9 14:57:25 2011 +0200 + + Remove gi/tests/ directory as all the tests now live in tests/ + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + gi/tests/Makefile.am | 24 ------------------------ + gi/tests/runtests.py | 21 --------------------- + 2 files changed, 45 deletions(-) + +commit b0ecbf00138ef1147e478ebf3c66f0e9b3f85dfc +Author: Dieter Verfaillie +Date: Fri Sep 9 14:55:25 2011 +0200 + + autogen.sh: Use autoreconf instead of a custom script and honor + ACLOCAL_FLAGS + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + Makefile.am | 2 +- + autogen.sh | 95 + +++++++------------------------------------------------------ + 2 files changed, 12 insertions(+), 85 deletions(-) + +commit 4671f5397003f376f00830e3fd1c214de594619f +Author: Dieter Verfaillie +Date: Fri Sep 9 14:55:01 2011 +0200 + + use improved python.m4 macros to search for Python headers and libs + + https://bugzilla.gnome.org/show_bug.cgi?id=658652 + + configure.ac | 3 ++- + m4/python.m4 | 47 +++++++++++++++++++++++++++++++++++++---------- + 2 files changed, 39 insertions(+), 11 deletions(-) + +commit 2c9fd09da196d35db968bff4ae63fcce2d891e69 +Author: Javier Jardón +Date: Fri Sep 9 15:38:22 2011 +0100 + + Make maintiner mode enabled by default + + See + http://blogs.gnome.org/desrt/2011/09/08/am_maintainer_mode-is-not-cool/ + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b24dcb415406668931e02a1f669ef9861bb3a660 +Author: Dieter Verfaillie +Date: Wed Aug 24 09:58:10 2011 +0200 + + Disable documentation for now since they are completely wrong for GI. + + https://bugzilla.gnome.org/show_bug.cgi?id=657054 + + Makefile.am | 2 +- + configure.ac | 25 ------------------------- + 2 files changed, 1 insertion(+), 26 deletions(-) + +commit ecea2358a379c8ff44dff2f8f9c30a9092af1681 +Author: Dieter Verfaillie +Date: Wed Sep 7 10:38:28 2011 +0200 + + Fix documentation installation directory + + https://bugzilla.gnome.org/show_bug.cgi?id=657054 + + docs/Makefile.am | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 8d3125c8ce9890c70400dd8a3ac273b590fe6a31 +Author: Dieter Verfaillie +Date: Tue Sep 6 22:22:11 2011 +0200 + + Remove distutils based build system. + + The only reason this might be brought back to life again is when + the whole stack can be built with Visual Studio (including + gobject-introspection) again. Building with MinGW/MSYS can now + be done with the usual autogen.sh/configure/make/make install dance. + + https://bugzilla.gnome.org/show_bug.cgi?id=657054 + + MANIFEST.in | 7 - + Makefile.am | 25 +-- + README.win32 | 21 -- + dsextras.py | 509 + ----------------------------------------------- + pygobject_postinstall.py | 9 - + setup.py | 351 -------------------------------- + 6 files changed, 7 insertions(+), 915 deletions(-) + +commit b82d916635aa0b732840548088a3fcfcb2e41bc4 +Author: Dieter Verfaillie +Date: Wed Sep 7 10:40:36 2011 +0200 + + [gtk-demo] Fix syntax highlighter encoding issue + + With Python 3, Gtk.TextBuffer.get_text returns a str (not bytes), with + Python 2 however we get a str (not unicode). So with Python 2 the + tokenizer returned bogus data when ran over a demo that contains real + UTF-8 codepoints (like rotatedtext.py for example). + + This patch thus fixes the "Gtk-CRITICAL **: + gtk_text_iter_set_line_offset: + assertion `char_on_line <= chars_in_line` failed" assertions when + selecting + the rotated text demo in the treeview. + + demos/gtk-demo/gtk-demo.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 31db3ed3d233bd495c3a2f99b3fa51031bfa30c6 +Author: Ignacio Casal Quinteiro +Date: Tue Sep 6 22:13:54 2011 +0200 + + overrides: add constants for atoms + + gi/overrides/Gdk.py | 49 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +commit 81861bc2d664eb38d46e5c38ff755d436f040f63 +Author: Steve Frécinaux +Date: Wed Aug 31 14:18:56 2011 +0200 + + Drop pygobject_construct() from public API. + + These functions were introduced in 2005 because python objects + could not + "just" be instantiated using g_object_new(), but this is not true + anymore since the introduction of new-style constructors. Hence + this API + has no reason to be there anymore. + + Nowadays, people who want to construct GObjects defined in python + should + just use g_object_new(). + + https://bugzilla.gnome.org/show_bug.cgi?id=657814 + + gi/_gobject/gobjectmodule.c | 118 + +++++++++------------------------------- + gi/_gobject/pygobject-private.h | 3 - + gi/_gobject/pygobject.h | 8 --- + 3 files changed, 26 insertions(+), 103 deletions(-) + +commit c4c55a98ccf9e39ed0d10ed49b66a76dc7d7c509 +Author: Ignacio Casal Quinteiro +Date: Wed Aug 31 18:00:44 2011 +0200 + + post release version bump + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ac5a0f46242abdd3cd98ec5f9f2bf8e5b05f3845 +Author: Ignacio Casal Quinteiro +Date: Wed Aug 31 17:58:37 2011 +0200 + + Release 2.90.3 + + NEWS | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit 429569abddada5a3bad554de707ddf35b349936e +Author: John (J5) Palmieri +Date: Thu Aug 25 13:57:53 2011 -0400 + + support skip annotation for return values + + * this is used for things like skiping gboolean returns that are + useful is C but useless in python + + * cleans up after skipped returns that are also marked transfer + full + https://bugzilla.gnome.org/show_bug.cgi?id=650135 + + gi/pygi-cache.c | 1 + + gi/pygi-cache.h | 1 + + gi/pygi-invoke.c | 48 + ++++++++++++++++++++++++++++++------------------ + tests/test_everything.py | 8 ++++++++ + 4 files changed, 40 insertions(+), 18 deletions(-) + +commit 7a234b185b131f3eb6a6e8a8c717ddf4d508b15e +Author: Xavier Claessens +Date: Tue Aug 2 12:05:12 2011 +0200 + + Test GPtrArray regression + + tests/test_everything.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 42fc9fa437102c882844a0e70a081ab08de92658 +Author: Steve Frécinaux +Date: Fri Aug 26 10:53:43 2011 +0200 + + Drop support for old constructor style. + + Bindings don't write their own constructors anymore, and the old style + has been deprecated for ages, so let's just drop them now and make + pygobject simpler. + + https://bugzilla.gnome.org/show_bug.cgi?id=657413 + + gi/_gobject/gobjectmodule.c | 20 -------------------- + gi/_gobject/pygobject-private.h | 1 - + gi/_gobject/pygobject.c | 1 - + gi/_gobject/pygobject.h | 2 -- + gi/gimodule.c | 28 ---------------------------- + gi/types.py | 2 -- + tests/testhelpermodule.c | 5 ----- + 7 files changed, 59 deletions(-) + +commit 3961a405e1bddef22e1a5a0c7aa3ae55e4ec09ad +Author: Steve Frécinaux +Date: Fri Aug 26 10:45:59 2011 +0200 + + Drop support for sink functions. + + Sink functions were meant to deal with floating references in a custom + way. They are not useful anymore with the dynamic bindings. + + https://bugzilla.gnome.org/show_bug.cgi?id=642233 + + gi/_gobject/gobjectmodule.c | 1 - + gi/_gobject/pygobject.c | 53 ---------------------------------------- + gi/_gobject/pygobject.h | 4 --- + tests/test-floating.c | 59 + +++++++-------------------------------------- + tests/test-floating.h | 42 +++++++++----------------------- + tests/test_gobject.py | 13 +++------- + tests/testhelpermodule.c | 32 +++++++----------------- + 7 files changed, 32 insertions(+), 172 deletions(-) + +commit 631d8ef879a13492945a3e30b3df9863a4ba2f44 +Author: Mike Gorse +Date: Wed Aug 24 17:30:09 2011 -0500 + + Reinstate copying of in-line structs in arrays + + For arrays of in-line, non-boxed structures with (transfer full), + _pygi_marshal_free_out_array eventually gets called and frees + the array + data, so we should copy it (IE, BGO#653588). + + https://bugzilla.gnome.org/show_bug.cgi?id=657120 + + gi/pygi-marshal-out.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit f38511f251602e18551c04617cc2e2d42e812e1e +Author: John (J5) Palmieri +Date: Tue Aug 23 14:18:43 2011 -0400 + + fix inline struct array handling + + * we now assume any non-boxed structs are inline in an array since + there is + no way to check in GI and this is the most common use for an + array of + non-boxed structs + + https://bugzilla.gnome.org/show_bug.cgi?id=657120 + + gi/pygi-marshal-out.c | 23 +++++++++-------------- + tests/test_gi.py | 8 ++++++++ + 2 files changed, 17 insertions(+), 14 deletions(-) + +commit d92846a5446b0dd2e69c813f56224a1966ab1a33 +Author: Dieter Verfaillie +Date: Tue Aug 23 11:30:41 2011 +0200 + + [gtk-demo] printing.py: set print and error dialog transient parent + + demos/gtk-demo/demos/printing.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 1aebc1565752840075027b9452fe2a67217bf53b +Author: Dieter Verfaillie +Date: Tue Aug 23 11:28:05 2011 +0200 + + [gtk-demo] printing.py: exit Gtk mainloop when done and correctly + handle printing errors + + demos/gtk-demo/demos/printing.py | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 1f9e4486c5b84209ce0038887738fc16a4ef7da3 +Author: Dieter Verfaillie +Date: Tue Aug 23 08:05:43 2011 +0200 + + [gtk-demo] show "activated" demo's in italic font in the TreeView + + demos/gtk-demo/gtk-demo.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 971d063f7a36e13ef6621db7002b00af52f6292a +Author: Dieter Verfaillie +Date: Mon Aug 22 14:52:28 2011 +0200 + + [gtk-demo] source colorizer: Python3 does not have the BACKQUOTE + token, so simply remove it + + demos/gtk-demo/gtk-demo.py | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +commit c2979a37d6d505095b6e55789150a6498d95819d +Author: Dieter Verfaillie +Date: Mon Aug 22 14:22:18 2011 +0200 + + [gtk-demo] In Python3, GLib.file_get_contents returns a bytes object + but Gtk.TextBuffer.insert expects a string. + + Fixed by using codes.open() as hinted in + http://docs.python.org/dev/howto/pyporting.html#text-files + section "If pre-2.6 compatibility is needed" (because configure.ac + is still happy with Python 2.5.2). + + demos/gtk-demo/gtk-demo.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 9ea56535f35abbea4cd977dea4c89247e4b01694 +Author: Dieter Verfaillie +Date: Mon Aug 22 12:30:24 2011 +0200 + + [gtk-demo] images.py: fix 'Insensitive 'button mnenomic + + demos/gtk-demo/demos/images.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7829dae1cdb8697a19c2b5e158ef0e08f6c2558b +Author: Dieter Verfaillie +Date: Mon Aug 22 10:38:04 2011 +0200 + + [gtk-demo] printing.py: fix Pango.EllipsizeType > Pango.EllipsizeMode + & get_pixel_size + + demos/gtk-demo/demos/printing.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 07f0274301d77d9bf62b49a14b059d9a52afb445 +Author: Dieter Verfaillie +Date: Mon Aug 22 10:37:08 2011 +0200 + + [gtk-demo] printing.py: fix text file loading + + demos/gtk-demo/demos/printing.py | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +commit 135148a4c35aac1d132b0b8fa3adbf1fdcdb3a24 +Author: Dieter Verfaillie +Date: Mon Aug 22 10:20:35 2011 +0200 + + [gtk-demo] pixbuf.py: fix image loading + + demos/gtk-demo/demos/pixbuf.py | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +commit a93cae2c80e30a408f86e7e6c4d15a538011a189 +Author: Dieter Verfaillie +Date: Mon Aug 22 10:10:02 2011 +0200 + + [gtk-demo] images.py: fix logo loading + + demos/gtk-demo/demos/images.py | 70 + +++++++++++++++++------------------------- + 1 file changed, 29 insertions(+), 41 deletions(-) + +commit eddc0824e0e4c156fca5de05bdeb600c534d4b24 +Author: Dieter Verfaillie +Date: Wed Aug 24 12:19:21 2011 +0200 + + [gtk-demo] appwindow.py: set AboutDialog parent + + demos/gtk-demo/demos/appwindow.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit 7fe10a5b33148b1f029f3d34f76b7f880c1c2e7a +Author: Dieter Verfaillie +Date: Mon Aug 22 07:58:25 2011 +0200 + + [gtk-demo] appwindow.py: fix logo loading + + demos/gtk-demo/demos/appwindow.py | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +commit 62fda288c1c37167c589e8e9d49ed625f770a98a +Author: Dieter Verfaillie +Date: Mon Aug 22 07:57:31 2011 +0200 + + [gtk-demo] appwindow.py: fix callback signatures + + demos/gtk-demo/demos/appwindow.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 87e9ab4d3a0aac4f4710aa0f8af0a1736f781ad9 +Author: Dieter Verfaillie +Date: Mon Aug 22 07:48:28 2011 +0200 + + [gtk-demo] fix glib vs GLib usage + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 2 +- + demos/gtk-demo/demos/appwindow.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit d29cad6976a80862e1fc590d3e7d190e8a234866 +Author: Dieter Verfaillie +Date: Wed Aug 24 12:19:02 2011 +0200 + + [gtk-demo] iconviewedit.py: fix for Gdk.color_parse API breakage + caused by improved GDK overrides + + demos/gtk-demo/demos/Icon View/iconviewedit.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit f29d3a85a275a39e8481484779264b0dea1160ab +Author: Dieter Verfaillie +Date: Mon Aug 22 07:25:32 2011 +0200 + + [gtk-demo] optimize source colorizer by only preparing iters for + known colorized tokens + + demos/gtk-demo/gtk-demo.py | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +commit ecd1eb00b19733da3f2e3d7935792378f34cab19 +Author: Dieter Verfaillie +Date: Fri Aug 19 18:31:20 2011 +0200 + + [gtk-demo] small formatting fixes + + demos/gtk-demo/demos/Entry/entry_buffer.py | 1 + + demos/gtk-demo/demos/Entry/entry_completion.py | 1 + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 8 ++++---- + demos/gtk-demo/demos/assistant.py | 1 + + demos/gtk-demo/demos/builder.py | 4 +++- + demos/gtk-demo/demos/button_box.py | 1 + + demos/gtk-demo/demos/clipboard.py | 1 + + demos/gtk-demo/demos/colorselector.py | 1 + + demos/gtk-demo/demos/combobox.py | 1 + + demos/gtk-demo/demos/drawingarea.py | 4 +++- + demos/gtk-demo/demos/test.py | 2 ++ + 11 files changed, 19 insertions(+), 6 deletions(-) + +commit c42cb4da399ff5732f4ca732b85134de796a60fa +Author: Dieter Verfaillie +Date: Fri Aug 19 18:30:50 2011 +0200 + + [gtk-demo] remove "is_fully_bound" from demos + + demos/gtk-demo/demos/Entry/entry_buffer.py | 2 -- + demos/gtk-demo/demos/Entry/entry_completion.py | 2 -- + demos/gtk-demo/demos/appwindow.py | 3 --- + demos/gtk-demo/demos/assistant.py | 2 -- + demos/gtk-demo/demos/builder.py | 2 -- + demos/gtk-demo/demos/button_box.py | 2 -- + demos/gtk-demo/demos/clipboard.py | 2 -- + demos/gtk-demo/demos/colorselector.py | 2 -- + demos/gtk-demo/demos/combobox.py | 2 -- + demos/gtk-demo/demos/drawingarea.py | 2 -- + demos/gtk-demo/demos/test.py | 1 - + 11 files changed, 22 deletions(-) + +commit cad6a62c63f455f0b1315465a9cd71c0f02b12a5 +Author: Dieter Verfaillie +Date: Fri Aug 19 18:26:31 2011 +0200 + + [gtk-demo] add source colorizer loosely based on PyGTK's pygtk-demo + and GTK+'s gtk-demo code + + demos/gtk-demo/gtk-demo.py | 116 + +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 101 insertions(+), 15 deletions(-) + +commit 250c36f4a8352ff1b31c1c85b156d3e803d4b8ef +Author: Dieter Verfaillie +Date: Fri Aug 19 15:08:15 2011 +0200 + + [gtk-demo] remove C-isms + + demos/gtk-demo/gtk-demo.py | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +commit cf35fe8e259e786d0fa21b08b1f5c64c9bb0a84e +Author: Dieter Verfaillie +Date: Fri Aug 19 14:54:39 2011 +0200 + + [gtk-demo] fix text on info tab to be more like GTK+'s gtk-demo + + demos/gtk-demo/gtk-demo.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 241827208e25c72a990d8edd95a3b879470d6409 +Author: Dieter Verfaillie +Date: Fri Aug 19 14:40:56 2011 +0200 + + [gtk-demo] remove duplicate storage of demos by only storing them + in a TreeStore subclass + + This also moves demos loading code into the TreeStore subclass and + demo loading code into the Demo class + + demos/gtk-demo/gtk-demo.py | 151 + +++++++++++++++++++++------------------------ + 1 file changed, 70 insertions(+), 81 deletions(-) + +commit 58797c355a08a35375988881a17958bb42ad54bb +Author: Dieter Verfaillie +Date: Fri Aug 19 14:40:00 2011 +0200 + + [gtk-demo] make GtkDemoApp a Gtk.Window subclass and adapt main() + to demonstrate the GLib.MainLoop + + demos/gtk-demo/gtk-demo.py | 43 + ++++++++++++++++++++++++++----------------- + 1 file changed, 26 insertions(+), 17 deletions(-) + +commit 1e4fc1ea54527cff78f6c633db39e9a0bd3c64d2 +Author: Dieter Verfaillie +Date: Fri Aug 19 11:46:17 2011 +0200 + + [gtk-demo] correctly load demo code when cwd != demos/gtk-demo/ + + demos/gtk-demo/gtk-demo.py | 39 +++++++++++++++++++++++---------------- + 1 file changed, 23 insertions(+), 16 deletions(-) + +commit 6ffc999fbd4c9990fb5bde53ddd46d139b53245e +Author: Dieter Verfaillie +Date: Fri Aug 19 11:02:35 2011 +0200 + + [gtk-demo] drawingarea: fix labels + + demos/gtk-demo/demos/drawingarea.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 9fd3986affe11cbc5a816adcccdc56d0592f3618 +Author: Dieter Verfaillie +Date: Fri Aug 19 09:57:31 2011 +0200 + + [gtk-demo] fix imports + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 6 ++++-- + demos/gtk-demo/demos/appwindow.py | 9 ++++++--- + demos/gtk-demo/gtk-demo.py | 8 ++++---- + 3 files changed, 14 insertions(+), 9 deletions(-) + +commit 9f314babfdee3b82799e00ea003972b0bbe6a8d5 +Author: Dieter Verfaillie +Date: Fri Aug 19 10:07:14 2011 +0200 + + [gtk-demo] fix shebang + + demos/gtk-demo/gtk-demo.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 01142060ae7d71a8a1f7d3e9bbc6f52e65f01c8d +Author: Sebastian Pölsterl +Date: Fri Aug 19 12:27:04 2011 +0200 + + Added support for __setitem__ to TreeModel and support for slices + to TreeModelRow + + https://bugzilla.gnome.org/show_bug.cgi?id=656891 + + gi/overrides/Gtk.py | 26 ++++++++++++++++++++-- + tests/test_overrides.py | 57 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 81 insertions(+), 2 deletions(-) + +commit d6da96c65b2ed3cda238886990a624fbc31f6987 +Author: Olav Vitters +Date: Wed Aug 24 16:31:12 2011 +0200 + + Convert ACCEL_* constants into Gtk.AccelFlags. + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 0841d41698302abb5d987849a5874252564ed428 +Author: Olav Vitters +Date: Wed Aug 24 16:22:17 2011 +0200 + + Convert TREE_VIEW_DROP_* constants into Gtk.TreeViewDropPosition + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 37b0d0f9dc3d485829cae6e50da369fdea91a2d1 +Author: John (J5) Palmieri +Date: Thu Aug 18 14:06:32 2011 -0400 + + post commit version bump + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e51efc50835a14e0418cc27cc928c52d1aa6a3cf +Author: John (J5) Palmieri +Date: Thu Aug 18 14:02:30 2011 -0400 + + release 2.90.2 + + NEWS | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 74c727b53fcf64f465ee77b5a1ea04a69ca90968 +Author: John (J5) Palmieri +Date: Thu Aug 18 13:50:51 2011 -0400 + + remove tests that were removed from gi + + tests/test_gi.py | 11 ----------- + 1 file changed, 11 deletions(-) + +commit 11ea24dd30d8eeca11c8433c6bd75b06e52ae1ef +Author: John (J5) Palmieri +Date: Thu Aug 18 13:48:57 2011 -0400 + + don't calculate item_size using is_pointer + + * is_pointer is poorly defined and cacluating item_size for + arrays causes a crash in the tests because of this + * disregaurd is_pointer when cacluating item sizes + + gi/pygi-info.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +commit 493b4a21dd162d78cf572b548b58ba6a9ff22971 +Author: Timo Vanwynsberghe +Date: Wed Jul 6 01:50:31 2011 +0200 + + Updated signal example to use GObject introspection + + https://bugzilla.gnome.org/show_bug.cgi?id=654162 + + examples/signal.py | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +commit 0332010e704e253380e993874eab9dd122e59a7e +Author: Timo Vanwynsberghe +Date: Wed Jul 6 01:54:50 2011 +0200 + + Updated properties example to use GObject introspection + + https://bugzilla.gnome.org/show_bug.cgi?id=654162 + + examples/properties.py | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit c39f4555ebd703651eca6f978ed9870655b737f0 +Author: Martin Pitt +Date: Fri Aug 12 22:55:02 2011 +0200 + + Add override for GLib.Variant.split_signature() + + This is useful for e. g. iterating over method parameters which are + passed as a + single Variant. In particular we will need it for automatically + generating + introspection XML for exported DBus server objects. + + gi/overrides/GLib.py | 50 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 22 ++++++++++++++++++++++ + 2 files changed, 72 insertions(+) + +commit 735f98d83c1c19df7457aa32a378e8c80cf2831f +Author: Timo Vanwynsberghe +Date: Mon Aug 15 18:58:31 2011 +0200 + + [pygi-convert.sh] Handle the import of pygtk and require Gtk 3.0 + + https://bugzilla.gnome.org/show_bug.cgi?id=654001 + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit d0a96a0a75f2bc969522abce2d326ef440cf143a +Author: Ignacio Casal Quinteiro +Date: Mon Aug 15 13:12:49 2011 +0200 + + Install pygobject.h again. + + This is needed by libpeas. + + gi/_gobject/Makefile.am | 5 ++++- + pygobject-3.0-uninstalled.pc.in | 4 ++-- + pygobject-3.0.pc.in | 6 +++--- + 3 files changed, 9 insertions(+), 6 deletions(-) + +commit 081dc2eb03b677eac9f08d3ad05deecc7c51554c +Author: John (J5) Palmieri +Date: Sun Aug 14 11:20:15 2011 -0400 + + update the doap file + + pygobject.doap | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +commit 762a36d2343bc39a502507d600fd1b9db9649dae +Author: John (J5) Palmieri +Date: Sun Aug 14 11:13:25 2011 -0400 + + prerelease bump + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d3f85a61ec4b1a1d04838f73dc8d862258150048 +Author: John (J5) Palmieri +Date: Sun Aug 14 10:13:37 2011 -0400 + + get things ready for release + + NEWS | 194 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 194 insertions(+) + +commit ffd057649380d4249c1c52e1225e3646f3994bc6 +Author: John (J5) Palmieri +Date: Sun Aug 14 05:26:18 2011 -0400 + + pass exta keywords to the Box constructor + + gi/overrides/Gtk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit cadbd4142bd0045368b5123d4b0a1876bdd5d798 +Author: John (J5) Palmieri +Date: Sat Aug 13 11:03:07 2011 -0400 + + add (Tree|List)Store set method override + + gi/overrides/Gtk.py | 50 ++++++++++++++++++++++++ + tests/test_overrides.py | 102 + ++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 149 insertions(+), 3 deletions(-) + +commit 9ee9b22bd95e44bd2eca26e7bf3b0a9a988700c5 +Author: John (J5) Palmieri +Date: Sat Aug 13 09:19:29 2011 -0400 + + add test for object arrays + + tests/test_everything.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit c9d9ffd0380878792cbdb13dec4e53be897e5fbc +Author: John (J5) Palmieri +Date: Sat Aug 13 08:46:18 2011 -0400 + + only support C pointer arrays for structs and objects + + * There is no way to know if an array of structs or objects are + pointer arrays + or flat arrays. Since pointer arrays are the most useful and + prevelant + it has been decided to only support those arrays + + gi/pygi-marshal-out.c | 2 +- + tests/test_gi.py | 8 -------- + 2 files changed, 1 insertion(+), 9 deletions(-) + +commit b12379de1790b72d51883bf7b63c892639a892e7 +Author: John (J5) Palmieri +Date: Sat Aug 13 06:31:52 2011 -0400 + + revert Gtk.Window override because it causes issues with subclasses + + gi/overrides/Gtk.py | 9 --------- + 1 file changed, 9 deletions(-) + +commit 3e64a62d6d7f9e9d2820aad54187ef9c34710a1f +Author: Jonathan Matthew +Date: Thu Apr 7 21:05:32 2011 +1000 + + take GIL in _pygi_invoke_closure_free (bug #647016) + + gi/pygi-closure.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit f8de9b8615f5dc30f492781d792aef5fc1e9ab73 +Author: Johan Dahlin +Date: Mon Jun 27 00:41:24 2011 -0300 + + Add a default parameter to GtkTreeModel.filter_new + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gtk.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 583d0b3c6b53712128d7c2d5f075000a2a76ae5f +Author: Johan Dahlin +Date: Mon Jun 27 00:40:12 2011 -0300 + + Add vbox/action_area properties + + Accessing vbox/action_area directly creates segmentation fault, + avoid that by mapping the fields to their getters for PyGTK + API compatibility + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gtk.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 017fdfc1dd06259006719e02ffa48883cee01ffd +Author: Johan Dahlin +Date: Mon Jun 27 00:39:41 2011 -0300 + + Add a couple of constructors + + This is for PyGTK compatibility, so that gtk.HBox(True, 2) etc + works. + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gtk.py | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +commit af8bc9d5cdba48a7ee728ccb7ea9039df3ecceba +Author: Johan Dahlin +Date: Mon Jun 27 00:38:30 2011 -0300 + + Do not always pass in user_data to callbacks. + + This keeps API compatibility with PyGTK and avoids sending + in user_data if it's None. + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gtk.py | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +commit 7914d814350af1a18bdeda64f049c8e9a68d1d18 +Author: Johan Dahlin +Date: Mon Jun 27 00:38:20 2011 -0300 + + Add a default detail value for Widget.render_icon + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gtk.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 5b1c875269b7979caae97e84919a690a34d92f29 +Author: Johan Dahlin +Date: Mon Jun 27 00:36:20 2011 -0300 + + Add an override for Gdk.color_parse() + + Change Gdk.color_parse() to not return a tuple, instead just + return the created color or None if it wasn't possible to parse + the name into a color. + + This keeps compatibility with PyGTK but breaks the current API. + + https://bugzilla.gnome.org/show_bug.cgi?id=653462 + + gi/overrides/Gdk.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 187a2932bbf1e724f759ff3ed3392fc7341c6aa8 +Author: Laszlo Pandy +Date: Mon Aug 8 12:06:18 2011 +0200 + + Support function calling with keyword arguments in invoke. + + https://bugzilla.gnome.org/show_bug.cgi?id=625596 + + gi/pygi-cache.c | 39 ++++++++++++ + gi/pygi-cache.h | 4 ++ + gi/pygi-invoke.c | 162 + +++++++++++++++++++++++++++++++++++++++++++++-- + gi/types.py | 12 ++-- + tests/test_everything.py | 2 +- + tests/test_gi.py | 58 +++++++++++++++++ + 6 files changed, 265 insertions(+), 12 deletions(-) + +commit e5df32ffbf37481dbb6a70c4d4e7b7b9778c5549 +Author: John (J5) Palmieri +Date: Sat Aug 13 04:13:28 2011 -0400 + + remove references to deprecated GI_INFO_TYPE_ERROR_DOMAIN + + gi/pygi-info.c | 5 ----- + 1 file changed, 5 deletions(-) + +commit 745001178fc72be5626c7211366d694f41162987 +Author: Martin Pitt +Date: Thu Aug 11 15:11:42 2011 +0200 + + Fix gobject vs. gi.repository warning + + Check the warning earlier and fix the operator, so that it actually + works. Also + update the warning to explain how to fix the problem. + + gi/_gobject/__init__.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 25d2d05cba05414cd4551e0e06f6286a9b97a509 +Author: John (J5) Palmieri +Date: Fri Jul 22 15:46:31 2011 -0400 + + make GObject and GLib able to take overrides + + * derive directly from DynamicModule instead of InterfaceModule + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/importer.py | 11 +++--- + gi/module.py | 118 + ++++++++++++++++++++++++++++----------------------------- + 2 files changed, 64 insertions(+), 65 deletions(-) + +commit 698b2284e29c0f699198cf6a22eeb0e399daba6e +Author: John (J5) Palmieri +Date: Fri Jul 22 15:45:09 2011 -0400 + + avoid dependency issue by importing the internal gobject + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/__init__.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7b068ebe59884ebd9aeb4425dc80cdff73a66fb1 +Author: John (J5) Palmieri +Date: Fri Jul 22 14:13:02 2011 -0400 + + fix tests to use the new GLib module + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + tests/test_mainloop.py | 7 +++---- + tests/test_option.py | 3 ++- + tests/test_source.py | 24 +++++++++++------------- + tests/test_subprocess.py | 12 +++++------- + tests/test_thread.py | 10 ++++------ + tests/test_uris.py | 4 ++-- + 6 files changed, 27 insertions(+), 33 deletions(-) + +commit 191ef79315f8a5641699536fde58da18e23ef904 +Author: John (J5) Palmieri +Date: Fri Jul 22 14:11:53 2011 -0400 + + add DynamicGLibModule which works like DynamicGObjectModule + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/importer.py | 7 +++++-- + gi/module.py | 32 +++++++++++++++++++++++++++++--- + 2 files changed, 34 insertions(+), 5 deletions(-) + +commit fbd4a8263260c187211799454c08b1e55e2cb998 +Author: John (J5) Palmieri +Date: Fri Jul 22 12:27:41 2011 -0400 + + refactor, add objects and types to the correct internal module + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/_glib/pygiochannel.c | 38 +++++++++++++++++++------------------- + gi/_glib/pygmaincontext.c | 2 +- + gi/_glib/pygmainloop.c | 4 ++-- + gi/_glib/pygoptioncontext.c | 4 ++-- + gi/_glib/pygoptiongroup.c | 4 ++-- + gi/_glib/pygsource.c | 14 +++++++------- + gi/_glib/pygspawn.c | 14 +++++++------- + 7 files changed, 40 insertions(+), 40 deletions(-) + +commit 7431b49a161df9178c55b814d3adff992ac2d722 +Author: John (J5) Palmieri +Date: Fri Jul 22 12:26:32 2011 -0400 + + rename the pyglib shared library so we don't load the old one + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/Makefile.am | 2 +- + gi/_glib/Makefile.am | 10 +++++----- + gi/_gobject/Makefile.am | 2 +- + 3 files changed, 7 insertions(+), 7 deletions(-) + +commit b8700451acd4a19b59b64fc8641fca748d2189e2 +Author: John (J5) Palmieri +Date: Fri Jul 22 11:20:09 2011 -0400 + + refactor tests to only use PyGObject 3 syntax + + * for PyGObject 3 we want to discourage the use of legacy + interfaces + * Using interfaces like from gi.repository import GObject makes + sure that the internal _gobject module is loaded and not + PyGObject 2's gobject module which would cause the application + to not work correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + tests/runtests-windows.py | 4 +- + tests/test_gdbus.py | 12 ++--- + tests/test_gi.py | 4 +- + tests/test_gobject.py | 31 ++++++------ + tests/test_interface.py | 16 +++--- + tests/test_mainloop.py | 3 +- + tests/test_overrides.py | 8 +-- + tests/test_properties.py | 124 + +++++++++++++++++++++++----------------------- + tests/test_signal.py | 98 ++++++++++++++++++------------------ + tests/test_source.py | 5 +- + tests/test_subprocess.py | 3 +- + tests/test_thread.py | 5 +- + tests/test_unknown.py | 8 +-- + tests/testhelpermodule.c | 2 +- + tests/testmodule.py | 10 ++-- + 15 files changed, 169 insertions(+), 164 deletions(-) + +commit c980dae21468fe073cc8782608148c346bb90ad7 +Author: John (J5) Palmieri +Date: Fri Jul 22 11:16:00 2011 -0400 + + refactor the internal _glib module to import correct modules + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/_glib/__init__.py | 3 ++- + gi/_glib/glibmodule.c | 10 +++++----- + gi/_glib/option.py | 4 ++-- + gi/_glib/pyglib.c | 18 +++++++++--------- + 4 files changed, 18 insertions(+), 17 deletions(-) + +commit 65ac35cca8d24f4c133991e1c6ac02f49416a9a4 +Author: John (J5) Palmieri +Date: Fri Jul 22 11:10:46 2011 -0400 + + refactor to use the new internal _glib and _gobject modules + + * use relative imports instead of aboslute + * fix the C imports to import the internal _gobject libs + * add a check to see if the PyGObject 2 gobject module + was already imported + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/_gobject/__init__.py | 20 +++++++++++++------- + gi/_gobject/constants.py | 3 +-- + gi/_gobject/gobjectmodule.c | 2 +- + gi/_gobject/propertyhelper.py | 11 +++++------ + gi/_gobject/pygobject.c | 16 ++++++++-------- + gi/_gobject/pygobject.h | 2 +- + 6 files changed, 29 insertions(+), 25 deletions(-) + +commit 59ed1289f76bc287443b3974710ea0da3e2cc8cc +Author: John (J5) Palmieri +Date: Fri Jul 22 11:07:10 2011 -0400 + + refactor gi module to import and use internal _gobject module + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + gi/importer.py | 2 -- + gi/module.py | 31 ++++++++++++++++--------------- + gi/overrides/Gtk.py | 2 +- + gi/overrides/__init__.py | 6 +++--- + gi/pygobject-external.h | 2 +- + gi/types.py | 12 ++++++------ + 6 files changed, 27 insertions(+), 28 deletions(-) + +commit 6b9d738d78c6ac45d49f00402c89356887555069 +Author: John (J5) Palmieri +Date: Fri Jul 22 11:02:49 2011 -0400 + + move the static bits internal to gi and refactor build files + + * the glib module now becomes the gi._glib module + * the gobject module now becomes the gi._gobject module + * we do this so we can install in parallel with PyGObject 2 + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + Makefile.am | 2 +- + configure.ac | 6 +- + gi/Makefile.am | 8 +- + gi/_glib/Makefile.am | 58 + + gi/_glib/__init__.py | 25 + + gi/_glib/glibmodule.c | 969 ++++++++++++++ + gi/_glib/option.py | 358 ++++++ + gi/_glib/pygiochannel.c | 764 ++++++++++++ + gi/_glib/pygiochannel.h | 29 + + gi/_glib/pyglib-private.h | 49 + + gi/_glib/pyglib-python-compat.h | 245 ++++ + gi/_glib/pyglib.c | 633 ++++++++++ + gi/_glib/pyglib.h | 83 ++ + gi/_glib/pygmaincontext.c | 126 ++ + gi/_glib/pygmaincontext.h | 40 + + gi/_glib/pygmainloop.c | 360 ++++++ + gi/_glib/pygmainloop.h | 36 + + gi/_glib/pygoptioncontext.c | 337 +++++ + gi/_glib/pygoptioncontext.h | 39 + + gi/_glib/pygoptiongroup.c | 298 +++++ + gi/_glib/pygoptiongroup.h | 42 + + gi/_glib/pygsource.c | 725 +++++++++++ + gi/_glib/pygsource.h | 39 + + gi/_glib/pygspawn.c | 264 ++++ + gi/_glib/pygspawn.h | 32 + + gi/_gobject/Makefile.am | 71 ++ + gi/_gobject/__init__.py | 117 ++ + gi/_gobject/constants.py | 83 ++ + gi/_gobject/ffi-marshaller.c | 194 +++ + gi/_gobject/ffi-marshaller.h | 31 + + gi/_gobject/gobjectmodule.c | 2638 + +++++++++++++++++++++++++++++++++++++++ + gi/_gobject/propertyhelper.py | 312 +++++ + gi/_gobject/pygboxed.c | 234 ++++ + gi/_gobject/pygboxed.h | 27 + + gi/_gobject/pygenum.c | 366 ++++++ + gi/_gobject/pygenum.h | 27 + + gi/_gobject/pygflags.c | 485 +++++++ + gi/_gobject/pygflags.h | 27 + + gi/_gobject/pyginterface.c | 122 ++ + gi/_gobject/pyginterface.h | 40 + + gi/_gobject/pygobject-private.h | 241 ++++ + gi/_gobject/pygobject.c | 2397 + +++++++++++++++++++++++++++++++++++ + gi/_gobject/pygobject.h | 667 ++++++++++ + gi/_gobject/pygparamspec.c | 404 ++++++ + gi/_gobject/pygparamspec.h | 31 + + gi/_gobject/pygpointer.c | 198 +++ + gi/_gobject/pygpointer.h | 27 + + gi/_gobject/pygtype.c | 1844 +++++++++++++++++++++++++++ + gi/_gobject/pygtype.h | 28 + + glib/Makefile.am | 61 - + glib/__init__.py | 25 - + glib/glibmodule.c | 969 -------------- + glib/option.py | 358 ------ + glib/pygiochannel.c | 764 ------------ + glib/pygiochannel.h | 29 - + glib/pyglib-private.h | 49 - + glib/pyglib-python-compat.h | 245 ---- + glib/pyglib.c | 633 ---------- + glib/pyglib.h | 83 -- + glib/pygmaincontext.c | 126 -- + glib/pygmaincontext.h | 40 - + glib/pygmainloop.c | 360 ------ + glib/pygmainloop.h | 36 - + glib/pygoptioncontext.c | 337 ----- + glib/pygoptioncontext.h | 39 - + glib/pygoptiongroup.c | 298 ----- + glib/pygoptiongroup.h | 42 - + glib/pygsource.c | 725 ----------- + glib/pygsource.h | 39 - + glib/pygspawn.c | 264 ---- + glib/pygspawn.h | 32 - + gobject/Makefile.am | 73 -- + gobject/__init__.py | 117 -- + gobject/constants.py | 83 -- + gobject/ffi-marshaller.c | 194 --- + gobject/ffi-marshaller.h | 31 - + gobject/gobjectmodule.c | 2638 + --------------------------------------- + gobject/propertyhelper.py | 312 ----- + gobject/pygboxed.c | 234 ---- + gobject/pygboxed.h | 27 - + gobject/pygenum.c | 366 ------ + gobject/pygenum.h | 27 - + gobject/pygflags.c | 485 ------- + gobject/pygflags.h | 27 - + gobject/pyginterface.c | 122 -- + gobject/pyginterface.h | 40 - + gobject/pygobject-private.h | 241 ---- + gobject/pygobject.c | 2397 + ----------------------------------- + gobject/pygobject.h | 667 ---------- + gobject/pygparamspec.c | 404 ------ + gobject/pygparamspec.h | 31 - + gobject/pygpointer.c | 198 --- + gobject/pygpointer.h | 27 - + gobject/pygtype.c | 1844 --------------------------- + gobject/pygtype.h | 28 - + tests/Makefile.am | 2 +- + 96 files changed, 16172 insertions(+), 16175 deletions(-) + +commit f0d2ddcf7e61c36f79a9adf8ccc53bf3db9349d3 +Author: John (J5) Palmieri +Date: Mon Jul 18 18:46:31 2011 -0400 + + remove pygtk.py + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + Makefile.am | 5 ---- + pygtk.py | 95 + ------------------------------------------------------------- + 2 files changed, 100 deletions(-) + +commit 75e9f7d80d9224c05e6063b88479f1baee48c489 +Author: John (J5) Palmieri +Date: Mon Jul 18 18:41:41 2011 -0400 + + introspection is no longer optional + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + Makefile.am | 8 +------- + configure.ac | 43 +++++++++++++++++-------------------------- + gi/pygi.h | 37 ------------------------------------- + gobject/Makefile.am | 5 +---- + tests/Makefile.am | 7 +------ + 5 files changed, 20 insertions(+), 80 deletions(-) + +commit d862168d6a82edd59547d39f5b0ab8279b1e511c +Author: John (J5) Palmieri +Date: Mon Jul 18 18:28:50 2011 -0400 + + up platform version to 3.0 + + https://bugzilla.gnome.org/show_bug.cgi?id=642048 + + Makefile.am | 2 +- + configure.ac | 4 ++-- + pygobject-2.0-uninstalled.pc.in | 18 ------------------ + pygobject-2.0.pc.in | 22 ---------------------- + pygobject-3.0-uninstalled.pc.in | 18 ++++++++++++++++++ + pygobject-3.0.pc.in | 22 ++++++++++++++++++++++ + 6 files changed, 43 insertions(+), 43 deletions(-) + +commit 5189b360ccddbbaee267ce857968fbf1aafdd07a +Author: Martin Pitt +Date: Thu Aug 11 09:53:15 2011 +0200 + + [gi] Handle GVariants from callback return values + + Callbacks still use GIArgument, add missing GVariant support for + return types. + + gi/pygi-argument.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 18a240cc492d2e5ebe2709a0d7155e27c8ff9e63 +Author: Martin Pitt +Date: Wed Aug 10 14:11:10 2011 +0200 + + Handle GVariants for callback arguments + + Callbacks still use GIArgument, add missing GVariant support. This + is the + equivalent of what commit 9d5604220bd56 did for pygi_marshall_*(). + + gi/pygi-argument.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit aa820d6ce2fee83e61e3e9de7c6b7d2452e2847d +Author: Laszlo Pandy +Date: Mon Aug 8 01:58:10 2011 +0200 + + [gi] Fix crash: check return value of + _invoke_state_init_from_callable_cache() before continuing. + + gi/pygi-invoke.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit eaad9f3c71cedfe28ff2d2bb05ea6c64e323715f +Author: Laszlo Pandy +Date: Fri Aug 5 21:03:33 2011 +0200 + + [gi] Pass gtype as first parameter to vfuncs (instead of using + kwargs). + + gi/pygi-invoke.c | 32 ++++++++++++++++++-------------- + gi/types.py | 2 +- + 2 files changed, 19 insertions(+), 15 deletions(-) + +commit 76edfd0d5776f61c92c84fd9fb8dcc246c580e93 +Author: John (J5) Palmieri +Date: Mon Jul 18 18:21:51 2011 -0400 + + remove codegen + + Makefile.am | 2 +- + codegen/Makefile.am | 33 - + codegen/README.defs | 351 -------- + codegen/__init__.py | 16 - + codegen/argtypes.py | 1043 ----------------------- + codegen/code-coverage.py | 44 - + codegen/codegen.py | 1722 + -------------------------------------- + codegen/createdefs.py | 17 - + codegen/definitions.py | 575 ------------- + codegen/defsconvert.py | 132 --- + codegen/defsgen.py | 737 ---------------- + codegen/defsparser.py | 153 ---- + codegen/docextract.py | 461 ---------- + codegen/docextract_to_xml.py | 142 ---- + codegen/docgen.py | 766 ----------------- + codegen/h2def.py | 631 -------------- + codegen/mergedefs.py | 26 - + codegen/missingdefs.py | 17 - + codegen/mkskel.py | 89 -- + codegen/override.py | 285 ------- + codegen/pygobject-codegen-2.0.in | 11 - + codegen/reversewrapper.py | 912 -------------------- + codegen/scanvirtuals.py | 54 -- + codegen/scmexpr.py | 143 ---- + configure.ac | 5 - + pygobject-2.0-uninstalled.pc.in | 1 - + pygobject-2.0.pc.in | 1 - + 27 files changed, 1 insertion(+), 8368 deletions(-) + +commit bf284c7c47c3e52ab4d8700327a170903e9ebad2 +Author: John (J5) Palmieri +Date: Mon Jul 18 11:04:58 2011 -0400 + + remove some left over ifdefs to complete merge of the invoke-rewrite + branch + + gi/pygi-cache.h | 2 -- + gi/pygi-info.c | 2 -- + gi/pygi-private.h | 5 +---- + gi/pygi.h | 2 -- + 4 files changed, 1 insertion(+), 10 deletions(-) + +commit 8c653ec3033fab47c4bb4071b5732a349357141f +Author: John (J5) Palmieri +Date: Mon Jul 18 10:59:45 2011 -0400 + + rename pygi-invoke-ng to pygi-invoke + + gi/Makefile.am | 3 +- + gi/pygi-invoke-ng.c | 464 + ---------------------------------------------------- + gi/pygi-invoke.c | 464 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 466 insertions(+), 465 deletions(-) + +commit 62d59fa2c2b31d7a3cac8996d58234d4b13bb19f +Author: John (J5) Palmieri +Date: Mon Jul 18 10:56:36 2011 -0400 + + make invoke-ng the only invoker + + configure.ac | 11 - + gi/Makefile.am | 10 +- + gi/pygi-invoke.c | 1030 + ------------------------------------------------------ + 3 files changed, 1 insertion(+), 1050 deletions(-) + +commit 2937cfe5bb7122dd3783c7919294d6a34a3dfc05 +Merge: 519e556 917ea2d +Author: John (J5) Palmieri +Date: Mon Jul 18 10:45:18 2011 -0400 + + Merge branch 'master' into invoke-rewrite + +commit 519e556dc1e5874e1668bad93043fb9258c7ee79 +Merge: bab7e88 38cca3c +Author: John (J5) Palmieri +Date: Mon Jul 18 10:37:20 2011 -0400 + + Merge branch 'master' into invoke-rewrite + +commit bab7e88251bffcd360186c6dedc26be8eb077084 +Author: John (J5) Palmieri +Date: Mon Jul 18 10:35:10 2011 -0400 + + split the marshalling routines into two source files + + * update copy and paste copyright info to list the correct owner + + gi/Makefile.am | 6 +- + gi/pygi-cache.c | 3 +- + gi/pygi-marshal-in.c | 1412 ++++++++++++++++++++++++++++++++ + gi/pygi-marshal-in.h | 186 +++++ + gi/pygi-marshal-out.c | 767 ++++++++++++++++++ + gi/pygi-marshal-out.h | 144 ++++ + gi/pygi-marshal.c | 2145 + ------------------------------------------------- + gi/pygi-marshal.h | 303 ------- + 8 files changed, 2515 insertions(+), 2451 deletions(-) + +commit 917ea2dfa2d097e563233145003a66b3e4423287 +Author: Martin Pitt +Date: Thu Jul 14 11:21:10 2011 +0200 + + Ship tests/te_ST@nouppera in release tarballs for tests to succeed + + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit e024e832ab9c82d3e299cc6e1cb427de44f2d16e +Author: John (J5) Palmieri +Date: Wed Jul 13 15:43:02 2011 -0400 + + [invoke] break out caller_allocates allocating into its own function + + gi/pygi-invoke-ng.c | 78 + +++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 49 insertions(+), 29 deletions(-) + +commit fc8b8ce768ac780f7ed9edc63b70dd35194153c0 +Author: John (J5) Palmieri +Date: Wed Jul 13 15:42:26 2011 -0400 + + [invoke] missed a bit when removing constructor_class usage + + gi/pygi-invoke-ng.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c94bcf4ae7e36f90c356c89712b00609f9f849bd +Author: John (J5) Palmieri +Date: Wed Jul 13 15:16:17 2011 -0400 + + [invoke] don't hold on to the constructor class, just add a TODO + + gi/pygi-invoke-ng.c | 11 +++++------ + gi/pygi-invoke-state-struct.h | 1 - + 2 files changed, 5 insertions(+), 7 deletions(-) + +commit c11d3195f324ea41e86e3da7ff99b55425c2faec +Author: Martin Pitt +Date: Wed Jul 13 10:40:25 2011 +0200 + + [gi] Port test_properties from static gio to GI Gio + + As we ripped out the static gio bindings a while ago, this test case + was using + the system installed gio bindings with Python 2, and now fails + completely with + Python 3. Rewrite it to use gi.repository.Gio. + + tests/test_properties.py | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +commit 8f89ff24fcac627ce15ca93038711fded1a7c5ed +Author: Martin Pitt +Date: Wed Jul 13 08:42:22 2011 +0200 + + [python3] Fix maketrans import + + Python3 moved the maketrans() function from the string module to a + str method. + This unbreaks gi/module.py for Python 3 again. + + gi/module.py | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +commit 20aea4b052126fa0bface3e6e0dccfd77f9505b1 +Author: John (J5) Palmieri +Date: Fri Jul 8 14:39:22 2011 -0400 + + [caching] remove all inline compiler flags + + gi/pygi-cache.c | 96 + ++++++++++++++++++++++++++++----------------------------- + 1 file changed, 48 insertions(+), 48 deletions(-) + +commit bf7bb79b66ad406063fb443e7452d830c55986ef +Author: John (J5) Palmieri +Date: Fri Jul 8 14:35:20 2011 -0400 + + [caching] refactor function names to be less confusing + + gi/pygi-cache.c | 307 + +++++++++++++++++++++++++++----------------------------- + 1 file changed, 150 insertions(+), 157 deletions(-) + +commit c167a9345b01c070bd5a84b4a4b3a53baf9e217d +Author: John (J5) Palmieri +Date: Fri Jul 8 11:24:09 2011 -0400 + + [overrides] deprecate the use of type keyword MessageDialog + constructor + + * pygtk used type to determine the "type" of message dialog to + display but we + use the proper property name "message_type" since we should not be + overriding a reserved word + * to keep compat with pygtk we check the kwds hash for the key + 'type' and + assign it to message_type while throwing a deprecation warning + * also add a deprication warning when trying to use the depricated + NO_SEPARATOR + flag + + gi/overrides/Gtk.py | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +commit 367e4ededd4a45125157050bcc9e4e685fd4a82d +Author: Martin Pitt +Date: Fri Jul 8 10:15:53 2011 +0200 + + gdbus tests: Fix hang if test case fails + + In the TestGDBusClient.test_native_calls_async() test case, the main + loop was + never quit when the call failed. + + tests/test_gdbus.py | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 11b578400cbf9f7c270b662a5e8953ccd466e5ef +Author: John (J5) Palmieri +Date: Thu Jul 7 19:30:11 2011 -0400 + + use an enum instead of booleans to denote function type + + gi/pygi-cache.c | 85 + ++++++++++++++++++++++++++++++----------------------- + gi/pygi-cache.h | 18 +++++++++--- + gi/pygi-invoke-ng.c | 8 ++--- + 3 files changed, 67 insertions(+), 44 deletions(-) + +commit 10e31005baec26f61c0f8fca2b5c0337b0be6c70 +Author: John (J5) Palmieri +Date: Thu Jul 7 15:18:03 2011 -0400 + + rename aux arguments to child arguments to make their purpose clearer + + gi/pygi-cache.c | 64 + ++++++++++++++++++++++++++--------------------------- + gi/pygi-cache.h | 29 ++++++++++++++++-------- + gi/pygi-invoke-ng.c | 10 ++++----- + gi/pygi-marshal.c | 12 +++++----- + 4 files changed, 63 insertions(+), 52 deletions(-) + +commit b4ad91c40f713ebdc278ce40b011e4adf9ddbbd7 +Author: Timo Vanwynsberghe +Date: Thu Jul 7 10:59:08 2011 +0200 + + Fixed the cairo example + + https://bugzilla.gnome.org/show_bug.cgi?id=653844 + + examples/cairo-demo.py | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit a606bab1ddc605167f2e9dc7c46c8f929fdce23b +Author: Adam Dingle +Date: Tue Jul 5 14:28:20 2011 -0700 + + Add override binding for Gtk.ListStore.prepend(). + + https://bugzilla.gnome.org/show_bug.cgi?id=654056 + + gi/overrides/Gtk.py | 8 ++++++++ + tests/test_overrides.py | 13 ++++++++++++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +commit fc5c869486c7f6929e285ea7a86623ec41ecd9bd +Author: Martin Pitt +Date: Thu Jul 7 13:39:19 2011 +0200 + + Fix crash in Gtk.TextIter overrides + + With commit 17cd0fb3 Gtk.TextIter.{forward,backward}_search() + returns undefined + pointers when the search was unsuccessful. Actually check the + "success" return + value; if it is False return None, just like PyGTK used to. + + Thanks to Michael Vogt for discovering this and writing the test case! + + Test case: + + -------------- 8< ----------------- + from gi.repository import Gtk + + win = Gtk.Window.new(Gtk.WindowType.TOPLEVEL) + textview = Gtk.TextView() + buffer = textview.get_buffer() + buffer.set_text("hello world") + win.add(textview) + + win.show_all() + + iter = buffer.get_start_iter() + end = buffer.get_end_iter() + ret = iter.forward_search("foo", + Gtk.TextSearchFlags.VISIBLE_ONLY, + end) + print "this is my return value" + print ret + print "now I crash" + print ret[0].get_offset() + + Gtk.main() + -------------- 8< ----------------- + + gi/overrides/Gtk.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit 5c04fc5b2ca7e262c052426d5863d69d0c4a24da +Author: John (J5) Palmieri +Date: Tue Jul 5 15:57:23 2011 -0400 + + use gssize instead of int for arg indexes + + gi/pygi-cache.c | 24 ++++++++++++------------ + gi/pygi-cache.h | 6 +++--- + gi/pygi-invoke-ng.c | 6 +++--- + gi/pygi-marshal-cleanup.c | 6 +++--- + 4 files changed, 21 insertions(+), 21 deletions(-) + +commit ecc09749c34cd4eabf47cc722d768b042dc0be9f +Author: John (J5) Palmieri +Date: Tue Jul 5 14:17:30 2011 -0400 + + [cache] remove refrence to default value as it is not implemented yet + + gi/pygi-cache.h | 1 - + 1 file changed, 1 deletion(-) + +commit 433e0fb259047d8c81e5949a31abb5e0feefd27b +Author: Sebastian Pölsterl +Date: Thu May 12 18:53:06 2011 +0200 + + Handle arguments that are flags correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=647581 + + gi/pygi-argument.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 38cca3c14e79fbc383e3fc65a120bee03714b99f +Author: John (J5) Palmieri +Date: Fri Jul 1 05:19:15 2011 -0400 + + correctly initialize the _gi_cairo_functions array to be zero filled + + gi/pygi-foreign-cairo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9ae43fdbcc547eb1e3c61bf9545da40555b2e2c6 +Author: John (J5) Palmieri +Date: Fri Jul 1 05:19:15 2011 -0400 + + correctly initialize the _gi_cairo_functions array to be zero filled + + gi/pygi-foreign-cairo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d3ee40b36b1718e6fb4544dbe07e291138ea1eb9 +Author: John (J5) Palmieri +Date: Wed Jun 29 18:14:40 2011 -0400 + + pass in the address of the gerror, not the gerror itself + + gi/pygi-argument.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 49dc98eb9339ea64355cd752ca000c79da56f3a2 +Author: John (J5) Palmieri +Date: Wed Jun 29 18:01:44 2011 -0400 + + [gi] handle marshalling gerrors arguments for signals + + gi/pygi-argument.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +commit db9419fcef628e9ffee10591156007ea9c0bc1f0 +Author: John (J5) Palmieri +Date: Wed Jun 29 12:12:29 2011 -0400 + + [gi-invoke-ng] fix NULL check to check before we access the cache + struct + + gi/pygi-cache.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 9027e1a20fd06df5c26edcec1893ef0814ec938a +Author: John (J5) Palmieri +Date: Tue Jun 28 18:21:55 2011 -0400 + + [gi-tests] add test for PyGObject->PyObject TreeModel storage + + * make sure we can store a custom GObject as a PyObject inside of + a TreeModel + + tests/test_overrides.py | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +commit b6842e4b2a28733e143d4022864041ca82e91f7a +Author: John (J5) Palmieri +Date: Tue Jun 28 18:13:38 2011 -0400 + + [gtk-overrides] special case TreeModel columns of PYGOBJECT types + + * box the PYGOBJECT in a GValue so we can store PyGObjects in a + TreeModel row + + gi/overrides/Gtk.py | 7 ++++--- + gobject/pygtype.c | 7 ++++--- + 2 files changed, 8 insertions(+), 6 deletions(-) + +commit 7fc9d45860210fd9d333fd3769c6cf93a6a20eb6 +Author: John (J5) Palmieri +Date: Tue Jun 28 17:32:29 2011 -0400 + + [gi-invoke-ng] copy structs when transfer is full for array + + gi/pygi-marshal.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +commit 8d60c0bc7b327aa757a8727f1146f02cc0b78af8 +Author: John (J5) Palmieri +Date: Tue Jun 28 13:54:48 2011 -0400 + + [gtk-override] print warning if user imports Gtk 2.0 + + * this is needed because people file bugs not realizing they are + importing 2.0 + which is not supported + + gi/overrides/Gtk.py | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit 7c589c0c1de1a786e00685afd5292b6fb1f93ed3 +Author: John (J5) Palmieri +Date: Tue Jun 28 13:08:49 2011 -0400 + + [gtk-overrides] allow the message_type keyword to be used for + MessageDialogs + + * for pygtk compat we use the type keyword for message type but + we prefer + the use of message_type because it is more descriptive and does + not clash + with a python reserved word + * if you passed message_type into a MessageDialog constructor you + would get + an error because we also convert type to message_type when + calling the + parent constructor + * this patch looks to see if message_type was passed in as a + keyword and + assigns it to type while removing message_type from the keywords + dict + to avoid name clashing + + gi/overrides/Gtk.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 2aa12267bee91aa696633a0cea2a0accae09250a +Author: Johan Dahlin +Date: Mon Jun 27 10:56:20 2011 -0300 + + Add support for enums in gobject.property + + https://bugzilla.gnome.org/show_bug.cgi?id=653488 + + gobject/propertyhelper.py | 23 ++++++++++++++++------- + tests/test_properties.py | 40 ++++++++++++++++++++++++++++++++++++---- + 2 files changed, 52 insertions(+), 11 deletions(-) + +commit dc62e67b447ef526a6f2d1aa8648ad101d95024b +Author: Johan Dahlin +Date: Mon Jun 27 10:56:20 2011 -0300 + + Add support for enums in gobject.property + + https://bugzilla.gnome.org/show_bug.cgi?id=653488 + + gobject/propertyhelper.py | 23 ++++++++++++++++------- + tests/test_properties.py | 40 ++++++++++++++++++++++++++++++++++++---- + 2 files changed, 52 insertions(+), 11 deletions(-) + +commit 50cfccb5801c1b9a0a42ffe2826cd245f21fd88d +Author: John (J5) Palmieri +Date: Fri Jun 24 14:17:24 2011 -0400 + + [gi-invoke-ng] use g_slice for allocating GValues that are caller + allocated + + gi/pygi-invoke-ng.c | 2 ++ + gi/pygi-marshal-cleanup.c | 2 ++ + 2 files changed, 4 insertions(+) + +commit eff65cd2ce490296865441c3c78b7846f380459c +Author: John (J5) Palmieri +Date: Fri Jun 24 11:49:05 2011 -0400 + + [gi-invoke-ng] Convert Overflow errors to ValueErrors when marshalling + integers + + gi/pygi-marshal.c | 56 + +++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 44 insertions(+), 12 deletions(-) + +commit 05ed688d54e3ff04e961b60d0b5d3ed0b97c771d +Author: John (J5) Palmieri +Date: Wed Jun 22 12:26:39 2011 -0400 + + [gi-invoke-ng] only cache caller allocates for interfaces as some + API are broken + + gi/pygi-cache.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 4fd957a5de364c0588168dee15e1e61d4f12e173 +Author: John (J5) Palmieri +Date: Fri Jun 17 17:07:56 2011 -0400 + + [gi-invoke-ng] handle in pointer array marshalling + + gi/pygi-marshal.c | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +commit df3911ad2ce83af9bf9679ed1b221847b23ba2de +Author: Alex Eftimie +Date: Fri Jun 10 08:44:04 2011 +0300 + + Adding GPtrArray tests + + tests/test_gi.py | 43 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +commit e32c2be53175014399d89e1e85c9afc6e53c94be +Author: John (J5) Palmieri +Date: Fri Jun 17 11:32:28 2011 -0400 + + [gi-invoke-ng] fix array element offset calculations + + * use pointer arithmetic to calculate based on element size instead of + relying on the size of GIArgument + * special case GPtrArrays + + gi/pygi-marshal.c | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +commit 6e8dc28cb261cafbfed40fc0797a0dd5f91f497b +Author: John (J5) Palmieri +Date: Wed Jun 15 12:46:03 2011 -0400 + + [gi] don't clean up arguments that weren't yet processed during in + arg failure + + gi/pygi-marshal-cleanup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit af7c93ea98b7f492eef265e58c8b3c878805524f +Author: John (J5) Palmieri +Date: Wed Jun 15 12:06:47 2011 -0400 + + [gi-overrides] use new instead of init when constructing a + GLib.VariantBuilder + + * init is now skipped in the gir + + gi/overrides/GLib.py | 18 ++++++++---------- + tests/test_overrides.py | 6 ++---- + 2 files changed, 10 insertions(+), 14 deletions(-) + +commit c6112307f29f9a850e6e9efa5f55d5d4a363c6b0 +Author: John (J5) Palmieri +Date: Wed Jun 15 11:42:45 2011 -0400 + + [gi-invoke-ng] actual code to import overrides + + gi/pygi-cache.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 902575d857beffb14e56821ea8a52f705385f6bb +Author: John (J5) Palmieri +Date: Wed Jun 15 11:25:10 2011 -0400 + + [gi-invoke-ng] import pytypes so we get overrides + + gi/pygi-marshal.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 9d5604220bd56ae2708e9b74122c14208e0a30b4 +Author: John (J5) Palmieri +Date: Tue Jun 14 16:13:37 2011 -0400 + + [gi-invoke-ng] handle gvariants now that they are not foreign + + gi/pygi-marshal.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit c1f5651062687e800a52b5d8d16c88c0acde2934 +Author: John (J5) Palmieri +Date: Tue Jun 14 16:12:43 2011 -0400 + + [gi-invoke-ng] do not try to clean up NULL arguments + + gi/pygi-marshal-cleanup.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +commit fbf5382fbc1aed49ed491d2255d616a1643a45fc +Merge: 499b68d 1491f62 +Author: John (J5) Palmieri +Date: Mon Jun 13 17:28:23 2011 -0400 + + Merge branch 'master' into invoke-rewrite + +commit 499b68d6c9040cffc6e43dc87789d68446564a92 +Merge: 4c9bced 426c710 +Author: John (J5) Palmieri +Date: Mon Jun 13 17:26:37 2011 -0400 + + Merge branch 'master' into invoke-rewrite + +commit 1491f6225b9906bd369b5a42e6369ab6884736b7 +Author: Ignacio Casal Quinteiro +Date: Fri Jun 10 14:01:32 2011 +0200 + + closure: avoid double free crash + + gi/pygi-closure.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +commit 929f4236f2b8601e7960a4a7b0a860d976ad83c6 +Author: Jason Siefken +Date: Fri Jun 3 23:11:17 2011 -0700 + + Added __eq__ method for Gdk.Color and Gdk.RGBA + + Call Gdk.Color.equal and Gdk.RGBA.equal when + == equality testing is used. + + gi/overrides/Gdk.py | 6 ++++++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 10 insertions(+) + +commit dff5961ba229c7c34bd7b0a18a446b56bbe39e3a +Author: Ignacio Casal Quinteiro +Date: Wed Jun 8 19:13:48 2011 +0200 + + closure: Check the out arg is not null. Fixes bug #651812 + + gi/pygi-closure.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit d7d178206bfbb0858556fcfd6c9ca8eefda3fdf5 +Author: Tomeu Vizoso +Date: Wed Jun 8 09:47:20 2011 +0200 + + Use constants instead of literals + + tests/test_overrides.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit fe386a0ad548a23e30e9cb947bfa2198fb48ef29 +Author: Tomeu Vizoso +Date: Mon Jun 6 19:07:22 2011 +0200 + + GVariant has now a GType, take that into account + + https://bugzilla.gnome.org/show_bug.cgi?id=647509 + + gi/pygi-argument.c | 8 ++++---- + gi/pygi-invoke.c | 20 +++++++++++++------- + 2 files changed, 17 insertions(+), 11 deletions(-) + +commit bd7b8d96a7420522c1fdc127ef8cfb7d6e8a1b31 +Author: Tomeu Vizoso +Date: Mon Jun 6 19:05:07 2011 +0200 + + GVariantType is a boxed struct + + https://bugzilla.gnome.org/show_bug.cgi?id=647509 + + gi/gimodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2d73012e5dbcc45a5782a6c119dfb272c14b5a61 +Author: Tomeu Vizoso +Date: Mon Jun 6 17:38:21 2011 +0200 + + Use _gi.Struct to wrap fundamentals + + https://bugzilla.gnome.org/show_bug.cgi?id=647509 + + gi/module.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit d82e6c8d1d9f2fc48fdcc15b7d2a97e4f24cf3bf +Author: Tomeu Vizoso +Date: Mon Jun 6 17:24:28 2011 +0200 + + Merge gi/HACKING into /HACKING + + HACKING | 16 ++++++++++++++++ + gi/HACKING | 26 -------------------------- + 2 files changed, 16 insertions(+), 26 deletions(-) + +commit 92aca4416a7930e5870b8d1a4016bae8140462ee +Author: Daniel Drake +Date: Fri Jun 3 16:59:15 2011 +0100 + + Fix GC-related crash during PyGObject deallocation + + Python-2.7.1's GC source has the following comment: + + /* Python's cyclic gc should never see an incoming refcount + * of 0: if something decref'ed to 0, it should have been + * deallocated immediately at that time. + * Possible cause (if the assert triggers): a tp_dealloc + * routine left a gc-aware object tracked during its teardown + * phase, and did something-- or allowed something to + happen -- + * that called back into Python. gc can trigger then, and may + * see the still-tracked dying object. Before this assert + * was added, such mistakes went on to allow gc to try to + * delete the object again. In a debug build, that caused + * a mysterious segfault, when _Py_ForgetReference tried + * to remove the object from the doubly-linked list of all + * objects a second time. In a release build, an actual + * double deallocation occurred, which leads to corruption + * of the allocator's internal bookkeeping pointers. That's + * so serious that maybe this should be a release-build + * check instead of an assert? + */ + + As shown in a backtrace at + https://bugzilla.redhat.com/show_bug.cgi?id=640972 , pygobject + is making + this exact mistake. Before untracking its object, pygobject_dealloc + calls PyObject_ClearWeakRefs() which can call back into python, create + new allocations, and trigger the GC. + + This is causing Sugar (based on pygobject2 + pygtk2 static bindings) + to + crash on a regular basis while interacting with widgets or launching + applications. + + Fix this by untracking the object early. Also fix the same issue + spotted + in the GSource wrapper. + + Thanks to Bernie Innocenti for initial diagnosis. + + glib/pygsource.c | 6 ++++-- + gobject/pygobject.c | 8 +++++++- + 2 files changed, 11 insertions(+), 3 deletions(-) + +commit 4c9bcedb4e11ad66a4b86174e2425c7afcafc473 +Author: John (J5) Palmieri +Date: Tue May 31 16:59:41 2011 -0400 + + [gi-invoke-ng] enable invoke-ng by default + + configure.ac | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 2e4cfb85a55ff205e263591d573ee5ecf0ffff3e +Author: John (J5) Palmieri +Date: Tue May 31 16:37:21 2011 -0400 + + [gi-invoke-ng] add code to clean up when input values fail to marshal + + gi/pygi-marshal-cleanup.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +commit 508b1b6ca1b143f1e123a3ddb83e8ce146758dfc +Author: John (J5) Palmieri +Date: Tue May 31 16:01:03 2011 -0400 + + [gi-invoke-ng] add hash cleanup routines + + gi/pygi-cache.c | 2 ++ + gi/pygi-marshal-cleanup.c | 64 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-cleanup.h | 10 ++++++-- + 3 files changed, 74 insertions(+), 2 deletions(-) + +commit 1954c75b94a74259b4e5d28f5ff8d76aa4610832 +Author: John (J5) Palmieri +Date: Tue May 31 14:47:30 2011 -0400 + + [gi-invoke-ng] handle arrays with transfers of GI_TRANSFER_CONTAINER + + gi/pygi-marshal-cleanup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit b626c46b4a95602c7bf1278c2a39aacb7f5027d9 +Author: John (J5) Palmieri +Date: Tue May 31 14:40:49 2011 -0400 + + [gi-invoke-ng] add list cleanup routines + + gi/pygi-cache.c | 8 ++--- + gi/pygi-marshal-cleanup.c | 84 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-cleanup.h | 8 +++++ + 3 files changed, 96 insertions(+), 4 deletions(-) + +commit 2e542c327cd52c1f77af28905557dd25c64175d8 +Author: John (J5) Palmieri +Date: Thu May 26 16:10:13 2011 -0400 + + indentation fix + + gi/pygi-marshal.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 601aec11c49e821fe97dd30a2187fe3c75844712 +Author: John (J5) Palmieri +Date: Thu May 26 16:09:38 2011 -0400 + + [gi-invoke-ng] add out array cleanup + + gi/pygi-cache.c | 2 +- + gi/pygi-marshal-cleanup.c | 24 ++++++++++++++++++++++++ + gi/pygi-marshal.c | 37 +++++++++++++++++++++++++++++++------ + 3 files changed, 56 insertions(+), 7 deletions(-) + +commit e9ad4428b769f8c9ace1cdc973c684de84fb1a5e +Author: John (J5) Palmieri +Date: Thu May 26 13:22:38 2011 -0400 + + [gi-invoke-ng] do not allocate null terminator for garray + + * We are simply setting our own array so we don't want any allocate + null byte + + gi/pygi-marshal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a986b2b8e5ee37f2a330f5aabc85c73ebb0de508 +Author: John (J5) Palmieri +Date: Thu May 26 13:21:55 2011 -0400 + + [gi-invoke-ng] add array cleanup for in arrays + + gi/pygi-cache.c | 2 +- + gi/pygi-marshal-cleanup.c | 72 + ++++++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-marshal-cleanup.h | 9 ++++++ + gi/pygi-marshal.c | 13 +++++++-- + 4 files changed, 91 insertions(+), 5 deletions(-) + +commit 990c60805c8ef718eb29e2e1b24f057552c6159e +Author: John (J5) Palmieri +Date: Mon May 23 17:06:30 2011 -0400 + + [gi-invoke-ng] remove remaining bits of the invoke stage state machine + + gi/pygi-invoke-ng.c | 7 +------ + gi/pygi-invoke-state-struct.h | 14 -------------- + 2 files changed, 1 insertion(+), 20 deletions(-) + +commit dbbcf4a0e76fb572d85843ee31c3798df5cd5cc5 +Author: John (J5) Palmieri +Date: Mon May 23 16:59:57 2011 -0400 + + [gi-invoke-ng] revamp cleanup framework to be orthogonal to cache + setup + + * cleanup now has symmetry with setup so there are now in and out + cleanups + for each type that needs to be cleaned up + * no longer use state machine but instead call different cleanup + functions at + different stages of invoke, making it easier to understand what + happens at + each stage + + gi/pygi-cache.c | 19 ++- + gi/pygi-cache.h | 7 +- + gi/pygi-invoke-ng.c | 10 +- + gi/pygi-invoke-state-struct.h | 2 + + gi/pygi-marshal-cleanup.c | 301 + +++++++++++++++++------------------------- + gi/pygi-marshal-cleanup.h | 45 ++++--- + gi/pygi-marshal.c | 15 +-- + 7 files changed, 174 insertions(+), 225 deletions(-) + +commit 198714dc4585f7463f38929f1ca4e4b60a27dadb +Author: John (J5) Palmieri +Date: Thu May 12 17:29:20 2011 -0400 + + [gi-invoke-ng] stub out a cleaner way of cleaning up after ourselves + + * The state machine concept of cleaning up was getting a bit messy. + It was like we took a big bowl of spaghetti code and dumped it. + * Now we call specific cleanup functions at the point of failure (or + successful completion of a marshalling stage) + + gi/pygi-invoke-ng.c | 59 +++++++++++++++++++++++++++++++------- + gi/pygi-marshal-cleanup.c | 72 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-cleanup.h | 14 +++++++++ + 3 files changed, 135 insertions(+), 10 deletions(-) + +commit c1389dadbf35afee3f28d90ef637efd8c1f071a5 +Author: José Alburquerque +Date: Thu May 12 11:53:40 2011 -0400 + + Doc Extractor: Correct the logic of the --no-since option. + + * codegen/docextract.py (process_final_sections): If the + --no-since + option has been specified and a "Since:" is encountered during the + processing of the final sections, simply don't append the + "Since: ..." + instead of reading the next line. This preserves the logical + flow of + processing. + + codegen/docextract.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 303d8e8ab9e60cb554de7fc0e8592cd9b2c50843 +Author: José Alburquerque +Date: Mon May 9 17:32:09 2011 -0400 + + Doc Extractor: Add a --no-since option. + + * codegen/docextract.py: + * codegen/docextract_to_xml.py: Modified so that if a --no-since + option is specified at the command line, the "Since: ..." portion + of + the gtkdoc function block is omitted. This is useful for C++ + modules + such as gstreamermm where this information would not be useful + as long + as the C API is still unstable. + + codegen/docextract.py | 15 ++++++++++++++- + codegen/docextract_to_xml.py | 9 ++++++--- + 2 files changed, 20 insertions(+), 4 deletions(-) + +commit 4f615c6e300d6f2d7551b640efa301060206ab58 +Author: John (J5) Palmieri +Date: Thu May 5 14:04:34 2011 -0400 + + [gi-invoke-ng] tweek cleanup routines + + gi/pygi-cache.c | 5 +++ + gi/pygi-marshal-cleanup.c | 87 + +++++++++++++++++++++++++++++++++++------------ + gi/pygi-marshal-cleanup.h | 6 ++-- + gi/pygi-marshal.c | 11 ++---- + 4 files changed, 76 insertions(+), 33 deletions(-) + +commit 63c7f17c224821cb7136d06e8ef87eab7291848d +Author: Martin Pitt +Date: Mon May 2 15:49:52 2011 +0200 + + Fix symbol names to be locale independent + + We currently use upper() to present enum values, which are usually + defined in + lower case in the typelib, in upper cases. However, upper() is locale + dependent, so that e. g. in tr_TR.UTF-8, "invalid" becomes "iNVALiD" + because Turkish has some extra variants of "i". + + Use a local ASCII-only translate() call instead to avoid this. Thanks + to Nils + Philippsen for the idea! + + This also adds a test locale "te_ST@nouppera" which defines + toupper('a') == 'a'. + Run the Enum tests under this locale to reproduce the bug and verify + the fix. + + https://bugzilla.gnome.org/show_bug.cgi?id=649165 + + gi/module.py | 9 ++++++++- + tests/te_ST@nouppera | 50 + ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gi.py | 30 ++++++++++++++++++++++++++++++ + 3 files changed, 88 insertions(+), 1 deletion(-) + +commit b5e150da76c3d4de1a75f58d03c3a761e9005a63 +Author: Martin Pitt +Date: Wed May 4 08:35:27 2011 +0200 + + [gi] pygi-convert.sh: Convert gtk.gdk.CROSSHAIR + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit fcc5ea201ab25da6db94ea8a37364a1d3c4d7c65 +Author: John (J5) Palmieri +Date: Fri Apr 29 17:41:08 2011 -0400 + + [gi-invoke-ng] handle filename cleanup with the utf8 cleanup function + + gi/pygi-cache.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit dbe8c4fabc8ac19415a3be0e854d3a54c2317e0b +Author: John (J5) Palmieri +Date: Fri Apr 29 17:40:13 2011 -0400 + + [gi-invoke-ng] handle caller allocates cleanup + + gi/pygi-invoke-ng.c | 5 ++- + gi/pygi-marshal-cleanup.c | 104 + ++++++++++++++++++++++++++++++++++++---------- + gi/pygi-marshal-cleanup.h | 7 ++-- + 3 files changed, 90 insertions(+), 26 deletions(-) + +commit cdbf57f3b1f041a06cf545a5557424f701ed1ec7 +Author: John (J5) Palmieri +Date: Thu Apr 28 19:16:02 2011 -0400 + + [gi-invoke-ng] refactor the cleanup code and add utf8 cleanup as + initial test + + gi/pygi-cache.c | 15 ++----------- + gi/pygi-invoke-ng.c | 8 +++---- + gi/pygi-invoke-state-struct.h | 2 ++ + gi/pygi-marshal-cleanup.c | 51 + ++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-marshal-cleanup.h | 3 +++ + 5 files changed, 60 insertions(+), 19 deletions(-) + +commit d1f1f4ccc55f9ecab73b7c0ee78762c4039b2c79 +Author: John (J5) Palmieri +Date: Wed Apr 27 15:47:19 2011 -0400 + + use PyCapsule when importing pycairo/require pycairo 1.10.0 for + python3 builds + + * PyCObject is deprecated and pycairo 1.10.0 is first release to + fix this issue + + configure.ac | 15 +++++++++++---- + gi/pygi-foreign-cairo.c | 2 +- + 2 files changed, 12 insertions(+), 5 deletions(-) + +commit 83b7823a510b0b391560c6deaf9d15d8303c7b14 +Author: Ignacio Casal Quinteiro +Date: Thu Apr 21 16:52:20 2011 +0200 + + [python3] fix build. PYcairo_IMPORT doesn't exists anymore + + gi/pygi-foreign-cairo.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 3e933784df423757e591d703614cb700adb0bbe0 +Author: Sebastian Pölsterl +Date: Mon Apr 18 18:36:25 2011 +0200 + + Updated DOAP file + + pygobject.doap | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 399d06b4b20685eb38acfd7e43226e06737ab7d2 +Author: Sebastian Pölsterl +Date: Sat Apr 16 16:02:05 2011 +0200 + + [gi] Don't create variant twice + + gi/overrides/GLib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8d8a84ea23d28d25851c5870f261c020d762cef4 +Author: Sebastian Pölsterl +Date: Fri Apr 15 16:14:43 2011 +0200 + + pygi-convert.sh: Make sure the uppercase GObject module is imported + instead of the lowercase + + https://bugzilla.gnome.org/show_bug.cgi?id=647736 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 3b51d6426d0f59b2dd7e0dcdcded4bed43d6b9d8 +Author: Sebastian Pölsterl +Date: Fri Apr 15 15:58:53 2011 +0200 + + [gi] Removed hack to avoid using GLib.Variant.new_variant. + + The bug in the annotations of GLib is fixed now. + https://bugzilla.gnome.org/show_bug.cgi?id=639952 + https://bugzilla.gnome.org/show_bug.cgi?id=647796 + + gi/overrides/GLib.py | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +commit bb4dce14ba666969815d4e56adbc38f0ac4f7ff7 +Author: Sebastian Pölsterl +Date: Fri Apr 15 15:58:31 2011 +0200 + + [gi] Added additional test case for GVariant handling + + tests/test_overrides.py | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 138df2778543409752e229a09828a805f68a420d +Author: Sebastian Pölsterl +Date: Mon Apr 11 18:34:31 2011 +0200 + + [gi] Added support for GVariant arguments + + This is required in order for the "g-signal" signal of GDBusProxy + to work properly and thus to properly receive DBus signals with any + type of argument. + + https://bugzilla.gnome.org/show_bug.cgi?id=647477 + + gi/pygi-argument.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 985f239d891c7697d76ccecb797b189669ae6ee1 +Author: John (J5) Palmieri +Date: Tue Mar 22 18:46:28 2011 -0400 + + fix static ABI for setting string gvalues from python objects + + * the static bindings used to be able to set a string gvalue to + any python + object that implemented __str__, for instance when setting a + treemodel column + * this restores that code while still keeping unicode and python 3 + compatability + + gobject/pygtype.c | 28 +++++++++++++++++++--------- + tests/test_properties.py | 8 ++++++++ + 2 files changed, 27 insertions(+), 9 deletions(-) + +commit 58cfc3cd1152b4448b56a6ff597f954d8450b83e +Author: Dieter Verfaillie +Date: Tue Mar 22 20:47:51 2011 +0100 + + dsextras.py: ensure eol characters are preserved when writing template + files (so \n does not become \r\n) + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 629d267478982c426ba61a639d5c9603fed856e6 +Author: Dieter Verfaillie +Date: Tue Mar 22 11:35:44 2011 +0100 + + dsextras.py: remove \r as wel as \n character + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 426c7109d4c0dbf0d56cc075f97f33b3451f79a8 +Author: John (J5) Palmieri +Date: Wed Apr 27 15:47:19 2011 -0400 + + use PyCapsule when importing pycairo/require pycairo 1.10.0 for + python3 builds + + * PyCObject is deprecated and pycairo 1.10.0 is first release to + fix this issue + + configure.ac | 15 +++++++++++---- + gi/pygi-foreign-cairo.c | 2 +- + 2 files changed, 12 insertions(+), 5 deletions(-) + +commit 4e5833d0c2fe548617e5ea510f05920fd0caf73b +Author: Ignacio Casal Quinteiro +Date: Thu Apr 21 16:52:20 2011 +0200 + + [python3] fix build. PYcairo_IMPORT doesn't exists anymore + + gi/pygi-foreign-cairo.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 91ec337359720839862d3f5a8a0ea98f760a0752 +Author: Sebastian Pölsterl +Date: Mon Apr 18 18:36:25 2011 +0200 + + Updated DOAP file + + pygobject.doap | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 05c766044c83340c44564d0097514bfc1d1d9df7 +Author: Sebastian Pölsterl +Date: Sat Apr 16 16:02:05 2011 +0200 + + [gi] Don't create variant twice + + gi/overrides/GLib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit eb8f212e3687af30407cf01fcdfbf530257bcddb +Author: Sebastian Pölsterl +Date: Fri Apr 15 16:14:43 2011 +0200 + + pygi-convert.sh: Make sure the uppercase GObject module is imported + instead of the lowercase + + https://bugzilla.gnome.org/show_bug.cgi?id=647736 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit af31729573de24161ee90563e5738187c749783c +Author: Sebastian Pölsterl +Date: Fri Apr 15 15:58:53 2011 +0200 + + [gi] Removed hack to avoid using GLib.Variant.new_variant. + + The bug in the annotations of GLib is fixed now. + https://bugzilla.gnome.org/show_bug.cgi?id=639952 + https://bugzilla.gnome.org/show_bug.cgi?id=647796 + + gi/overrides/GLib.py | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +commit 070f6688be4afb926656038dcceac4c8b8ed97c7 +Author: Sebastian Pölsterl +Date: Fri Apr 15 15:58:31 2011 +0200 + + [gi] Added additional test case for GVariant handling + + tests/test_overrides.py | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 65aa040e86d94ee6bb227a2bce09668b60208027 +Author: John (J5) Palmieri +Date: Tue Apr 12 14:51:35 2011 -0400 + + [gi-invoke-ng] fix prototype + + gi/pygi-cache.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 12aa4e6376366ca9d758434f6544c9c70a1e5df8 +Author: John (J5) Palmieri +Date: Tue Apr 12 14:48:16 2011 -0400 + + [gi-invoke-ng] create new framework for cleaning up args + + * we now have a state machine so we know what point in the marshalling + process + we are and which args need to be cleaned up + * call the cleanup functions after invoking the gi callable, after + marshalling + the out parameters and at any time an error occures + + gi/Makefile.am | 4 ++- + gi/pygi-cache.c | 25 +++++++------ + gi/pygi-cache.h | 5 ++- + gi/pygi-invoke-ng.c | 34 ++++++++++++++---- + gi/pygi-invoke-state-struct.h | 13 +++++++ + gi/pygi-marshal-cleanup.c | 81 + +++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-marshal-cleanup.h | 43 +++++++++++++++++++++++ + gi/pygi-marshal.c | 1 + + 8 files changed, 187 insertions(+), 19 deletions(-) + +commit 0463295cd046bd6382ad9dc71ea1518858d63c5f +Author: Sebastian Pölsterl +Date: Mon Apr 11 18:34:31 2011 +0200 + + [gi] Added support for GVariant arguments + + This is required in order for the "g-signal" signal of GDBusProxy + to work properly and thus to properly receive DBus signals with any + type of argument. + + https://bugzilla.gnome.org/show_bug.cgi?id=647477 + + gi/pygi-argument.c | 2 ++ + 1 file changed, 2 insertions(+) + +commit 1d64c3d3db2ec17b9a48df55271f712db6c07060 +Author: John (J5) Palmieri +Date: Wed Mar 30 16:40:31 2011 -0400 + + [gi-invoke-ng] fix marshal header that is no longer part of + pygi-arguments.h + + gi/pygi-marshal.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 3580cd1c7222022ebeef3476f9e609c8045f12a3 +Author: John (J5) Palmieri +Date: Wed Mar 30 15:53:13 2011 -0400 + + [gi-invoke-ng] code style space fixes + + gi/pygi-cache.c | 420 +++++++++++++++++++------------------- + gi/pygi-invoke-ng.c | 145 +++++++------- + gi/pygi-marshal.c | 565 + ++++++++++++++++++++++++++-------------------------- + 3 files changed, 566 insertions(+), 564 deletions(-) + +commit 81662fcd09f112bfffcdc5b7f01a5537b84cd9d4 +Author: John (J5) Palmieri +Date: Tue Mar 29 16:54:44 2011 -0400 + + [gi-invoke-ng] don't decref value taken from a dict as it is borrowed + + gi/pygi-invoke-ng.c | 1 - + 1 file changed, 1 deletion(-) + +commit a456fc0adc1f8a0754bf59cde8924f905bfc7dc1 +Author: John (J5) Palmieri +Date: Tue Mar 29 15:23:06 2011 -0400 + + [gi-invoke-ng] return None when appropriate so we don't crash + + gi/pygi-marshal.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +commit e8c8c37e5587dc7ff62519df336988a12e6f5d0a +Author: John (J5) Palmieri +Date: Tue Mar 29 15:21:41 2011 -0400 + + [gi-invoke-ng] fix aux value caching + + gi/pygi-cache.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +commit 4e4c1847c713a4eb4ab34d04488e94dac24d9167 +Author: John (J5) Palmieri +Date: Mon Mar 28 20:25:46 2011 -0400 + + [gi-invoke-ng] backport handling flags with no gtype + + gi/pygi-marshal.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +commit fd76423e655b3711e1ffbf9b61ea4e2c94040234 +Author: John (J5) Palmieri +Date: Mon Mar 28 18:32:00 2011 -0400 + + [gi-invoke-ng] backport raw gvalue handling + + gi/pygi-marshal.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +commit 507b5051c83f70ceae79e0fa693c86e5cbb9f442 +Author: John (J5) Palmieri +Date: Mon Mar 28 18:30:31 2011 -0400 + + [gi-invoke-ng] marshal instances seperately since they differ slightly + from other args + + gi/pygi-cache.c | 2 +- + gi/pygi-marshal.c | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+), 1 deletion(-) + +commit 726a27c0e74ace3ff23d9cc4d393ae53e57f1fac +Author: John (J5) Palmieri +Date: Mon Mar 28 18:26:09 2011 -0400 + + [gi-invoke-ng] refactor FunctionCache to be more generic CallableCache + + gi/pygi-cache.c | 392 + +++++++++++++++++++++++++++------------------------- + gi/pygi-cache.h | 12 +- + gi/pygi-info.c | 2 +- + gi/pygi-invoke-ng.c | 40 +++--- + gi/pygi-marshal.c | 140 +++++++++---------- + gi/pygi-marshal.h | 159 +++++++++------------ + gi/pygi.h | 2 +- + 7 files changed, 362 insertions(+), 385 deletions(-) + +commit 3d5d9ff5c18a850650992bdd52e8e4c722b23396 +Author: John (J5) Palmieri +Date: Mon Mar 28 15:01:12 2011 -0400 + + [gi-invoke-rewrite] backport glib error handling + + gi/pygi-invoke-ng.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +commit 37b14b28a5f2aec16ac7f321efbf07e1403e9531 +Author: John (J5) Palmieri +Date: Fri Mar 25 18:48:42 2011 -0400 + + [gi-invoke-ng] backport closure passing from invoke + + gi/pygi-marshal.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +commit cf7f97eabc9c49773c2916929b8c43ef453d0652 +Author: John (J5) Palmieri +Date: Fri Mar 25 18:47:36 2011 -0400 + + [gi-invoke-ng] handle vfuncs and fix cosntrutors + + gi/pygi-cache.c | 9 +++++++ + gi/pygi-cache.h | 2 ++ + gi/pygi-invoke-ng.c | 56 + ++++++++++++++++++++++++++++++++----------- + gi/pygi-invoke-state-struct.h | 2 ++ + 4 files changed, 55 insertions(+), 14 deletions(-) + +commit af2ce400fcf771ee6c9bc01aecfb59467be5a0ce +Author: John (J5) Palmieri +Date: Fri Mar 25 18:39:06 2011 -0400 + + [gi-invoke-ng] handle foreign types correctly + + gi/pygi-cache.c | 22 ++++++---------------- + gi/pygi-marshal.c | 3 +++ + 2 files changed, 9 insertions(+), 16 deletions(-) + +commit 482553ae5d863ca523be3bd1eededa5d02a4f87e +Author: John (J5) Palmieri +Date: Fri Mar 25 13:14:01 2011 -0400 + + [gi] remove the class parameter from the argument list of constructors + + * constructors pass in their class to be constructed. Since we + use GI + and g_object_new to do the construction we ignore this for now but + keep it around in the state for future use. + + gi/pygi-invoke-ng.c | 46 + +++++++++++++++++++++++++++++++++++++------ + gi/pygi-invoke-state-struct.h | 1 + + 2 files changed, 41 insertions(+), 6 deletions(-) + +commit 0534eb0e843cdf09611143da184052f7e549e4dc +Author: John (J5) Palmieri +Date: Tue Mar 22 18:46:28 2011 -0400 + + fix static ABI for setting string gvalues from python objects + + * the static bindings used to be able to set a string gvalue to + any python + object that implemented __str__, for instance when setting a + treemodel column + * this restores that code while still keeping unicode and python 3 + compatability + + gobject/pygtype.c | 28 +++++++++++++++++++--------- + tests/test_properties.py | 8 ++++++++ + 2 files changed, 27 insertions(+), 9 deletions(-) + +commit 5f0e130026a663a57ed1317e0fa0e1f78f9e6e0a +Author: Dieter Verfaillie +Date: Tue Mar 22 20:47:51 2011 +0100 + + dsextras.py: ensure eol characters are preserved when writing template + files (so \n does not become \r\n) + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 62a6274105003ef386ddfe9ef38e8afa8c43d124 +Author: Dieter Verfaillie +Date: Tue Mar 22 11:35:44 2011 +0100 + + dsextras.py: remove \r as wel as \n character + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 86c436978c933f6ebe17627abe98325ce66f6baa +Author: John (J5) Palmieri +Date: Tue Mar 22 16:13:58 2011 -0400 + + [gi] make new invoke-ng codepath compile correctly + + configure.ac | 4 + + gi/Makefile.am | 5 +- + gi/pygi-cache.c | 2 +- + gi/pygi-invoke-ng.c | 841 ---------------------- + gi/pygi-marshal.c | 1962 + +-------------------------------------------------- + gi/pygi-private.h | 4 +- + 6 files changed, 9 insertions(+), 2809 deletions(-) + +commit 35619fec43f4df85edf5456f3fc9733b16f2ba90 +Author: John (J5) Palmieri +Date: Tue Mar 22 15:40:02 2011 -0400 + + [gi] conditionalize invoke code paths + + configure.ac | 7 +++++++ + gi/Makefile.am | 20 +++++++++++++++----- + gi/pygi-cache.h | 2 ++ + gi/pygi-info.c | 4 +++- + gi/pygi-private.h | 9 +++++++-- + gi/pygi.h | 4 +++- + 6 files changed, 37 insertions(+), 9 deletions(-) + +commit 83c51bd2bb6ca24ce610c04cff1527bcd2689d90 +Author: John (J5) Palmieri +Date: Tue Mar 22 15:37:24 2011 -0400 + + [gi] revert back to the type.py from master + + gi/types.py | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +commit cb30d00d1c92e73d9bfb08cc7b600a5aa70f2fc0 +Author: John (J5) Palmieri +Date: Tue Mar 22 14:46:29 2011 -0400 + + [gi] revert pygi-argument.h and move the invoke-ng code to + pygi-marshal.h + + gi/pygi-argument.h | 268 +----------------------------------------- + gi/pygi-marshal.h | 336 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 337 insertions(+), 267 deletions(-) + +commit 17cb714cfdaf45b6d7dd627b0189bd24e6578f74 +Merge: 7332a1b 01596a9 +Author: John (J5) Palmieri +Date: Tue Mar 22 13:34:36 2011 -0400 + + Merge branch 'master' into invoke-rewrite + + Conflicts: + gi/Makefile.am + gi/pygi-argument.c + gi/pygi-foreign-cairo.c + gi/pygi-foreign-gvariant.c + gi/pygi-foreign-gvariant.h + gi/pygi-foreign.c + gi/pygi-foreign.h + gi/pygi-private.h + gi/pygi.h + +commit 01596a9b7cc0ceef3904da5b96939140ee0732fd +Author: John (J5) Palmieri +Date: Tue Mar 22 13:20:54 2011 -0400 + + [gi] foreign types now take interface infos instead of type infos + + * this is a prep for the invoke-rewrite branch + * when marshalling foreign structs we may not have the type info but + we will always have the interface info to pass + * this simplifies the code because we were simply converting the + type info back to an interface info anyway so there is less + refcounting to keep track of + * also fixes a bug where we were leaking PyNone ref counts + + gi/pygi-argument.c | 4 ++-- + gi/pygi-foreign-cairo.c | 16 ++++++++-------- + gi/pygi-foreign-gvariant.c | 12 ++++++------ + gi/pygi-foreign.c | 32 +++++++++++++------------------- + gi/pygi-foreign.h | 8 ++++---- + gi/pygi-invoke.c | 6 +++--- + gi/pygi.h | 12 ++++++------ + 7 files changed, 42 insertions(+), 48 deletions(-) + +commit fbabc1fdafa1dcbd1f6aaea7b821bd1c64a546ab +Author: Martin Pitt +Date: Tue Mar 22 15:04:01 2011 +0100 + + Fix GSchema tests for separate build tree + + When using a separate build tree, the compiled GSettings schema will + be in the + build tree, but as the test scripts are only in the source tree they + won't find + the compiled schema. Pass the build dir as environment variable and + prefer it + over test_overrides.py's directory. + + tests/Makefile.am | 3 ++- + tests/test_overrides.py | 4 +++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit 7332a1b99775519fdc5500cab6628b713e946a8c +Author: John (J5) Palmieri +Date: Mon Mar 21 19:03:29 2011 -0400 + + [gi] start of merge from master + + * move some of the modified files that will cause merge conflicts + to their + own, nonconflicting files + * copy the old files out of master + + gi/pygi-argument.c | 2101 +++------------------------ + gi/pygi-invoke-ng.c | 1179 ++++++++++++++++ + gi/pygi-invoke.c | 421 ++---- + gi/pygi-marshal.c | 3916 + +++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 5389 insertions(+), 2228 deletions(-) + +commit 62b49dae97441953452d097cb1751df14302547a +Author: John (J5) Palmieri +Date: Wed Mar 16 17:34:18 2011 -0400 + + [gi] marshal raw closures + + * before we were able to marshal python callables into methods + that took + GClosures but we had no way to take a GClosure returned from one + method and pass it to another - this enables that usecase + + https://bugzilla.gnome.org/show_bug.cgi?id=644757 + + gi/pygi-argument.c | 17 ++++++++++------- + tests/test_gi.py | 4 ++++ + 2 files changed, 14 insertions(+), 7 deletions(-) + +commit 1e70957c5470a0f4bceba38ca66a4e4274fdc8d8 +Author: John Stowers +Date: Sun Mar 6 23:41:01 2011 +1300 + + pygi-convert.sh add GObject.xxx and webkit + + https://bugzilla.gnome.org/show_bug.cgi?id=644347 + + pygi-convert.sh | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 2292673c96e7973a0732ca15bbd5b0bf7a9c7dcf +Author: John Stowers +Date: Sun Mar 6 23:41:30 2011 +1300 + + pygi-convert.sh remove gobject tests, GObject works now + + https://bugzilla.gnome.org/show_bug.cgi?id=644347 + + pygi-convert.sh | 28 ---------------------------- + 1 file changed, 28 deletions(-) + +commit d26e5cc45f277f6b7edb32aa416520bb53bff9c2 +Author: John (J5) Palmieri +Date: Fri Mar 11 14:09:02 2011 -0500 + + [gi-demos] add pickers demo + + demos/gtk-demo/demos/pickers.py | 74 + +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +commit b8d926a458ed7d7e92719e41b5bc1c36f68882b3 +Author: John (J5) Palmieri +Date: Thu Mar 10 18:12:50 2011 -0500 + + [gi-demos] add menu demo + + demos/gtk-demo/demos/menus.py | 122 + ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 122 insertions(+) + +commit 9baec8ed1c5d99c1677a75eaa1d38912f41f0b2d +Author: John (J5) Palmieri +Date: Wed Mar 9 13:02:50 2011 -0500 + + [gi-overrides] fix exception block so it works in Python 2.5 + + gi/overrides/Gio.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 5ac534ac3ceee3cc19fe2297e3cd009817ed726f +Author: Martin Pitt +Date: Mon Mar 21 13:19:58 2011 +0100 + + Revert "Deduce PYTHON_LIBS in addition to PYTHON_INCLUDES" + + This reverts commit fc7d7f7f153d57ff3866b7bfd5e6479d702cc4d9. + + This introduces additional libpython dependencies, which breaks + distributions + which support multiple Python versions, and also causes the python + interpreter + to be in memory twice in some cases. + + https://bugzilla.gnome.org/show_bug.cgi?id=620215 + + gi/Makefile.am | 4 +--- + glib/Makefile.am | 2 +- + m4/python.m4 | 7 ++----- + tests/Makefile.am | 2 +- + 4 files changed, 5 insertions(+), 10 deletions(-) + +commit cd01f8ce1373f28b1427dd847bef44f747f1e6b3 +Author: Dieter Verfaillie +Date: Fri Mar 18 17:06:08 2011 +0100 + + setup.py: fix user_access_control option + + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2da60baec4f43c41f43527cbfde4e21e0eea728c +Author: Martin Pitt +Date: Wed Mar 16 10:22:35 2011 +0100 + + [gi] Respect the MessageType for Gtk.MessageDialog + + Don't just ignore the type argument, actually pass it on. Thanks + to Tualatrix + Chou for spotting this! + + gi/overrides/Gtk.py | 1 + + 1 file changed, 1 insertion(+) + +commit 029a79d1af1e0998aa6bc88ce1c1f48ce0ccd2a0 +Author: Martin Pitt +Date: Tue Mar 15 10:22:39 2011 +0100 + + [gi] Do not require signature for D-BUS methods without arguments + + Calling methods on DBusProxy objects usually requires specifying + the signature + as first argument. However, if the D-BUS method does not take any + arguments, + specifying the empty '()' signature does not give any additional + information, + so allow the caller to just call the proxy method without any + arguments. + + Also ensure that passing a non-string signature raises a + comprehensible + exception, instead of crashing deep in the GVariant leaf constructor. + + https://bugzilla.gnome.org/show_bug.cgi?id=644260 + + gi/overrides/Gio.py | 16 +++++++++++++++- + tests/test_gdbus.py | 13 +++++++++++++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +commit 5bf66ce79267b25bcc80251f9170498fa1d765f6 +Author: John Stowers +Date: Sun Mar 6 23:05:33 2011 +1300 + + [gi-overrides] TreeViewColumn.set_cell_data_func func_data can be None + + https://bugzilla.gnome.org/show_bug.cgi?id=644343 + + gi/overrides/Gtk.py | 2 ++ + 1 file changed, 2 insertions(+) + +commit 8e4f86e17a1de533a93b0748fd8de3cbfa70ba62 +Author: John Stowers +Date: Sun Mar 6 17:48:04 2011 +1300 + + [gi-demos] dont try and run demos that represent directories + + demos/gtk-demo/gtk-demo.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 097e5efab29d3d2d91d0b9fc75bf00219e9b7810 +Author: John (J5) Palmieri +Date: Mon Mar 7 18:09:18 2011 -0500 + + [gi-demos] some python 3 compat fixes + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 6 ++++++ + demos/gtk-demo/demos/Tree View/liststore.py | 2 +- + demos/gtk-demo/demos/rotatedtext.py | 4 ++-- + demos/gtk-demo/gtk-demo.py | 4 ++-- + 4 files changed, 11 insertions(+), 5 deletions(-) + +commit fd5d5ef3abc947d3c6066eea6378514f87b7f0ce +Author: John (J5) Palmieri +Date: Tue Feb 22 15:07:40 2011 -0500 + + [gi-demos] add liststore demo + + demos/gtk-demo/demos/Tree View/__init__.py | 0 + demos/gtk-demo/demos/Tree View/liststore.py | 205 + ++++++++++++++++++++++++++++ + 2 files changed, 205 insertions(+) + +commit 09de5cf99474fc8a34b5f4a61cede1fb47353ebb +Author: John (J5) Palmieri +Date: Mon Mar 7 18:08:40 2011 -0500 + + [gi-demos] catch the correct error class + + demos/gtk-demo/demos/images.py | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +commit 7284d2d4622978fc9ddfd00f2714b3a572b7ab56 +Author: Steve Frécinaux +Date: Sun Mar 6 21:18:36 2011 +0100 + + Do not leak python references when using the gobject.property() + helper. + + Since this helper was storing plain references in a long-lived + dict, the + refcount for the instances would never drop to zero, and so they would + never get finalized. + + https://bugzilla.gnome.org/show_bug.cgi?id=644039 + + gobject/propertyhelper.py | 5 ++--- + tests/test_properties.py | 23 +++++++++++++++++++++++ + 2 files changed, 25 insertions(+), 3 deletions(-) + +commit 618dbb0ee15b47e5e7cb16a34ffce0937d7fa26d +Author: John (J5) Palmieri +Date: Fri Mar 4 12:25:49 2011 -0500 + + handle uchar as bytes, not strings in python 3 + + * This worked in Python2 because bytes and strings are equivilant + and the macro + PYGLIB_PyString_FromStringAndSize evaluated to a PyString + * In Python 3 PYGLIB_PyString_FromStringAndSize evaluates to + a PyUnicode + * PYGLIB_PyBytes_FromStringAndSize evaluates to a PyString in Python 2 + and a PyBytes object in Python 3 + + gobject/pygtype.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7e9483ff75b7a63ddda0fa9a9847f9f22ad71240 +Author: John (J5) Palmieri +Date: Fri Mar 4 12:24:35 2011 -0500 + + [gi-overrides] handle unichar gvalues when setting treemodels + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 6367bffa006e94dc667d7008fccad8d47d8d3646 +Author: John (J5) Palmieri +Date: Fri Mar 4 11:43:51 2011 -0500 + + [gi-overrides] special case python 2 keywords that crept in + + gi/overrides/Gtk.py | 6 +++++- + tests/test_overrides.py | 8 ++++---- + 2 files changed, 9 insertions(+), 5 deletions(-) + +commit 83b0f8a37d5f3236780d87a1ca466c5e44ae2bc0 +Author: John (J5) Palmieri +Date: Fri Mar 4 11:10:16 2011 -0500 + + check for the py3 _thread module in configure.ac if thread is + not found + + configure.ac | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 4645af87d3c587f535404867dab56608719e5c7b +Author: John (J5) Palmieri +Date: Fri Mar 4 00:39:23 2011 -0500 + + [gi-demos] add iconview demo + + demos/gtk-demo/demos/Icon View/iconviewbasics.py | 212 + +++++++++++++++++++++++ + 1 file changed, 212 insertions(+) + +commit 761dcb516a04f7a89b3c7d68e88fff23055e2a80 +Author: John (J5) Palmieri +Date: Thu Mar 3 18:39:16 2011 -0500 + + [gi] wrap the keyword argument in a dict so we don't break Python 2.5 + + * python < 2.6 does not allow sending in keyword litterals after + sending in + *args. You can only send in **kwds. + + gi/types.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f9604e90af12a1b9dbe7d7f311308e87cd0ed7dd +Author: John (J5) Palmieri +Date: Thu Mar 3 18:30:40 2011 -0500 + + [gi-demos] add the combobox with string ids section to the demos + + demos/gtk-demo/demos/combobox.py | 49 + +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 48 insertions(+), 1 deletion(-) + +commit b70f4daf071cf77a4561b57f5521eb928f66d1ce +Author: John (J5) Palmieri +Date: Thu Mar 3 16:47:51 2011 -0500 + + [gi-overrides] add an override for Gdk.RGBA + + gi/overrides/Gdk.py | 18 ++++++++++++++++++ + tests/test_overrides.py | 10 ++++++++++ + 2 files changed, 28 insertions(+) + +commit ee2b63f60f350332ed21927721ed9ddff3a8034e +Author: John (J5) Palmieri +Date: Thu Mar 3 16:10:17 2011 -0500 + + [gi-demos] fix up search-entry to reflect annotations fixed in Gtk+ + master + + demos/gtk-demo/demos/Entry/search_entry.py | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +commit cd046e4c355706ead5f512b810a2a48317f8c32e +Author: John (J5) Palmieri +Date: Wed Mar 2 18:13:43 2011 -0500 + + [gi-demos] add search entry demo + + demos/gtk-demo/demos/Entry/search_entry.py | 257 + +++++++++++++++++++++++++++++ + 1 file changed, 257 insertions(+) + +commit d5ddaa92e6349c2f52b67317326060973cb69661 +Author: John (J5) Palmieri +Date: Wed Mar 2 15:37:27 2011 -0500 + + [gi] wrap map in a list for Python 3 compat + + gi/types.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3e5ab72a2e1fa2d8c4c2864137c6251f264ff4af +Author: John (J5) Palmieri +Date: Tue Mar 1 14:52:00 2011 -0500 + + [gi-demos] fix up the validation combobox + + demos/gtk-demo/demos/combobox.py | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +commit 08af5f99f0838b3584f6a3b210d0a0304811e8ff +Author: John (J5) Palmieri +Date: Tue Mar 1 12:31:35 2011 -0500 + + add overridesdir variable in the .pc file for 3rd party overrides + + pygobject-2.0.pc.in | 1 + + 1 file changed, 1 insertion(+) + +commit 4a6b14a92a687a2311516b2c16c355216b5270a7 +Author: Dieter Verfaillie +Date: Fri Feb 11 17:14:11 2011 +0100 + + setup.py: Set bdist_wininst user-access-control property + + setup.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit ad3ab659b83cb985730e19a83651da319d4bcb9c +Author: Martin Pitt +Date: Wed Mar 2 16:29:00 2011 +0100 + + Fix uninitialized variable in gi.require_version() + + gi/__init__.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 6e7606ee8830f6f51b777f41f6df2f6ea1784e89 +Author: Martin Pitt +Date: Tue Mar 1 23:26:07 2011 +0100 + + Run tests with LC_MESSAGES="C" + + Some tests, such as tests/test_gdbus.py check parts of error messages + or other + visible strings. Ensure that these do not get translated in the + test suite. + + tests/runtests.py | 2 ++ + 1 file changed, 2 insertions(+) + +commit 0461e05174637ae02f34029b85ba217d5ae48c53 +Author: John (J5) Palmieri +Date: Mon Feb 28 18:21:43 2011 -0500 + + [gi-overrides] override Gtk.stock_lookup to not return success + + demos/gtk-demo/demos/combobox.py | 2 +- + gi/overrides/Gtk.py | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +commit 40decf3501823004a6e4d3acbbf204c4d4d0a7ec +Author: John (J5) Palmieri +Date: Mon Feb 28 14:16:00 2011 -0500 + + update NEWS to reflect changes in the 2.27.91 release (PYGOBJECT_2_28 + branch) + + NEWS | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +commit c2d5122b8e3cf51ec52418f90f1788895b842b6a +Author: John (J5) Palmieri +Date: Mon Feb 28 14:08:05 2011 -0500 + + [gi-tests] use Gdk.test_simulate_button instead of emitting event + ourselves + + * this function is available specifically so we can test events so + use this + instead of creating our own button press event + + tests/test_overrides.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 1be1a2ea2787dffeb71ab4a38233fb71e761bd21 +Author: Laszlo Pandy +Date: Thu Feb 24 19:30:32 2011 +0100 + + [gi-tests] tests for EventButton override. + + * John (J5) Palmieri - fixed up original patch so that we actually + emit the event instead of just creating a Gdk.ButtonEvent object + + https://bugzilla.gnome.org/show_bug.cgi?id=642554 + + tests/test_overrides.py | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +commit 99044a4860dd65c97f52b41b7cd3f216f4a97cd4 +Author: John (J5) Palmieri +Date: Wed Feb 23 18:43:27 2011 -0500 + + [gi-overrides] Add event methods to all event union members + + https://bugzilla.gnome.org/show_bug.cgi?id=642554 + + gi/overrides/Gdk.py | 70 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +commit 6e30c69d38fd382414eb820097c297a80be547ac +Author: John (J5) Palmieri +Date: Wed Feb 23 14:14:16 2011 -0500 + + [gi] check to see if object is a member of a union when validating + paramaters + + * union members are not subclasses of the union they belong to so + if an + inteface requires you pass a union but you pass one of its members + there will be a type error + * this patch checks to see if the type you are passing is a member + of the + union and passes the checks if it is + * this works in python 3 but in python 2 methods do their own + isinstance + check on the instance parameter (e.g. self) so we need to figure + out how to override that for union methods + (e.g. Gdk.Event.get_state) + + https://bugzilla.gnome.org/show_bug.cgi?id=642554 + + gi/pygi-argument.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +commit 525f21d1365c24488b768955362085bf82512dee +Author: Tomeu Vizoso +Date: Wed Feb 16 09:44:12 2011 +0100 + + Skip interfaces when checking for conflicts in the MRO + + https://bugzilla.gnome.org/show_bug.cgi?id=642437 + + gi/types.py | 40 ++++++++++++++++++++++++++++++++++++++++ + gobject/gobjectmodule.c | 9 +++++++-- + tests/test_gi.py | 16 ++++++++++++++++ + 3 files changed, 63 insertions(+), 2 deletions(-) + +commit da212024772a7a0c32f04f3589bfb24d2eb5706f +Author: Laszlo Pandy +Date: Thu Feb 24 18:46:15 2011 +0100 + + [gi] Remove DyanmicModule.load() to _load() to prevent overriding + GI attrs. + + gi/importer.py | 2 +- + gi/module.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 2ce6b58c7427cf67ba4f55731ba0a4c04703e495 +Author: Laszlo Pandy +Date: Wed Feb 23 12:05:03 2011 +0100 + + Test case with John's fix for crash with C arrays and a GError is set. + + I have added a test case, and made a few fixes to John's patch, + but the + solution is the same his. + + Workaround a bug when freeing C array types + + * This is a hack and there is really no way around it without + ripping out + the current array handling code which spans between pygi-invoke.c + and + pygi-argument.c and completely rewriting it. + * The is no time before our stable release + * This patch trades a segfault for a leak in the very unusual + case where + an error occures inside an interface that takes one or more C + arrays. Since + we wrap C arrays in GArrays internally but have to unwrap them + to send them + to the introspected C function, there is a period of time where + an error + can occure with the C array in an unknown state (some being true + C arrays + and others still wrapped in a GArray) + * This patch adds a c_arrays_are_wrapped state to signal that it + is safe to + free them. However since c_arrays_are_wrapped can only track + arrays + as a group, not individually, if it is set to FALSE we can + not assume + that every array is a pure C array, so instead we will simply + leak them + to avoid incorrectly freeing one and causing a segfault. + * This issue is fixed in the invoke rewrite branch as it treats + C arrays and + GArrays separately, however that branch is not yet ready to be + merged and + won't be until the next release. + + https://bugzilla.gnome.org/show_bug.cgi?id=642708 + + gi/pygi-invoke.c | 54 + ++++++++++++++++++++++++++++++++++++++++++++++++++---- + tests/test_gi.py | 9 +++++++++ + 2 files changed, 59 insertions(+), 4 deletions(-) + +commit 702a89beca92cab6b0142829b20281b9245f28b8 +Author: John (J5) Palmieri +Date: Wed Feb 23 15:11:59 2011 -0500 + + [gi-overrides] fix setting rows in treeview to accept None as a value + + * as done in PyGTK None indicates the column should not be set + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 18 +++++++++++++----- + 2 files changed, 16 insertions(+), 5 deletions(-) + +commit 498f0d9c903131aca5efe27ffaad7620e40f72ea +Author: Laszlo Pandy +Date: Wed Feb 23 14:23:19 2011 +0100 + + [gi] Add value_name for enum and flags from introspection + "c:identifier" (if attr is available). + + gi/gimodule.c | 22 ++++++++++++++++++---- + tests/test_gi.py | 36 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 4 deletions(-) + +commit 824aeb7fab17d6590e5babf2d1f64298f2d0e16b +Author: Laszlo Pandy +Date: Wed Feb 23 11:40:55 2011 +0100 + + Fix flags with multiple names for the same value. + + Flags constructs a dict __flags_values__ and uses it to cache + instances. However some flags in Glib such as G_IO_FLAG_MASK and + G_IO_FLAG_GET_MASK are aliases for the same int value, and will + override each other's place in the dictionary. + + The dict length check is not necessary. It only reduces the number + of duplicate instances we keep, because if an instance is not + found in the dict, a new one is created anyway. + + gobject/pygflags.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3afbebeee486e14fd3f48552368903eb78f6b10c +Author: Laszlo Pandy +Date: Tue Feb 22 21:37:33 2011 +0100 + + Don't force loading of DynamicModule until set in sys.modules + + This fixes Tomeu's previous commit, which removed lazy loading. + Forcing the loading of a module before it is installed in sys.modules + prevents some overrides from being registered (namely Gtk.main_quit). + + https://bugzilla.gnome.org/show_bug.cgi?id=642305 + + gi/importer.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2a9cbfb435b47dc646e2c6ffe630464b560229a6 +Author: John (J5) Palmieri +Date: Mon Feb 21 17:20:57 2011 -0500 + + use GValue support to marshal GtkTreeModel values correctly + + * needs patch from https://bugzilla.gnome.org/show_bug.cgi?id=642914 + + https://bugzilla.gnome.org/show_bug.cgi?id=642921 + + gi/overrides/Gtk.py | 37 ++++++++++++++++++--- + tests/test_overrides.py | 87 + +++++++++++++++++++++++++++++++++++++++++-------- + 2 files changed, 107 insertions(+), 17 deletions(-) + +commit 9e4ce7dc0f03ea407654c4af028122f57cbc4c5e +Author: John (J5) Palmieri +Date: Mon Feb 21 16:14:20 2011 -0500 + + [gi] pass raw GValues instead of trying to marshal them + + * Right now GValues are transparent to the user but this leave us no + way to describe fundimental types other than those supported + directly + by python (e.g. int, str, etc) + * If an interface is expecting a uint or other GValue type a user + can now use + the raw GValue interfaces and expect paramaters that take + GValues to + marshal them correctly e.g.: + value = GObject.Value() + value.int(GObject.TYPE_UINT) + value.set_uint(1234) + * The objective here is to not for users to use this API but for + overrides + to be able to utilize them. For instance in the TreeModel API + we can + get the expected type for a column and them create a GValue with + the correct + type so that he underlying python object is marshalled correctly. + + https://bugzilla.gnome.org/show_bug.cgi?id=642914 + + gi/pygi-argument.c | 24 ++++++++++++++++++------ + tests/test_gi.py | 9 ++++++++- + 2 files changed, 26 insertions(+), 7 deletions(-) + +commit b458f6f3424a04f6ceece09d443009372d70544c +Author: John (J5) Palmieri +Date: Sat Feb 19 19:42:41 2011 -0500 + + [gi-demos] add icon view edit and drag-and-drop demo + + demos/gtk-demo/demos/Icon View/__init__.py | 0 + demos/gtk-demo/demos/Icon View/iconviewedit.py | 101 + +++++++++++++++++++++++++ + 2 files changed, 101 insertions(+) + +commit 7b47289e25d1dd57ce15556ccfbb3ede1c4bfe8b +Author: John (J5) Palmieri +Date: Sat Feb 19 17:26:42 2011 -0500 + + [gi-demos] add info bars demo + + demos/gtk-demo/demos/infobars.py | 99 + ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 99 insertions(+) + +commit 76758efb6579752237a0dc4d56cf9518de6c6e55 +Author: Tomeu Vizoso +Date: Wed Feb 16 11:53:18 2011 +0100 + + Load typelibs at import time, add gi.require_version() + + also adds Repository.get_loaded_namespaces() + + https://bugzilla.gnome.org/show_bug.cgi?id=642305 + + gi/__init__.py | 29 ++++++++++++++++++++++++++++- + gi/importer.py | 1 + + gi/module.py | 21 ++++----------------- + gi/pygi-repository.c | 23 +++++++++++++++++++++++ + 4 files changed, 56 insertions(+), 18 deletions(-) + +commit 96f7d1aed732db09a74cd463ed894b7347dbcb15 +Author: Laszlo Pandy +Date: Sat Feb 19 23:11:25 2011 +0100 + + [gi] Register GType for non-GType enums and flags at runtime. + + Note: rebuild of gobject-introspection is required for new tests. + + Previously non-GType enums used a separate type implemented in + Python, and non-GType flags had no implementation at all. This + removes the separate type for enums, and registers a new GType at + runtime if there isn't one. + + This allows non-GType enums and flags to use the same Python type + as GType enums and flags. This removes duplication of code, and + make both kinds behave identically. + + https://bugzilla.gnome.org/show_bug.cgi?id=642607 + + gi/gimodule.c | 117 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/module.py | 24 ++++++----- + gi/pygi-info.c | 15 +++++++ + gi/types.py | 16 -------- + gobject/pygflags.c | 13 ++++-- + tests/test_gi.py | 35 ++++++++++++++++ + 6 files changed, 191 insertions(+), 29 deletions(-) + +commit 63a60bcc20e724f96ea8d565ee0cf13a228b72b9 +Author: Martin Pitt +Date: Tue Feb 8 15:38:21 2011 +0100 + + [gi] Add Pythonic gdbus method invocation + + Provide a wrapper for Gio.DBusProxy for calling D-Bus methods like + on a normal + Python object. This will handle the Python object <-> GVariant + conversion, and + optional keyword arguments for flags, timeout, and a result handler + for + asynchronous calls. + + Require specifying the input argument signature as the first argument + of each + method call. This ensures that the types of e. g. integers are + always correct, + and avoids having to do expensive D-Bus introspection for each call. + + https://bugzilla.gnome.org/show_bug.cgi?id=640181 + + gi/overrides/Gio.py | 99 + ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gdbus.py | 102 + ++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 199 insertions(+), 2 deletions(-) + +commit ed5cdbb6f52bdbd13521a814516b15687955d6f7 +Author: Laszlo Pandy +Date: Fri Feb 18 22:48:59 2011 +0100 + + Skip GError out parameters in Python closure. + + Python code should have never have to explicitely return a GError. + Once we are able to marshal exceptions the Python code should + throw an exception instead. Until then, set GError to NULL, and + don't complain if a Python function doesn't return an arg for it. + + https://bugzilla.gnome.org/show_bug.cgi?id=642715 + + gi/pygi-closure.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 5a5ee3877e22939a697772a7f0630ef8cae3d52f +Author: Laszlo Pandy +Date: Fri Feb 18 10:15:59 2011 +0100 + + Fix runtests.py to work with Python3 (print function syntax error). + + tests/runtests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit ad5d3fccff9433e2dadac89d731dac5cafb0eac3 +Author: John (J5) Palmieri +Date: Thu Feb 17 19:46:49 2011 -0500 + + [gi-demos] added rotate text demo + + * needs some Pango Attr fixes to be 100% done, See FIXME + + demos/gtk-demo/demos/rotatedtext.py | 196 + ++++++++++++++++++++++++++++++++++++ + 1 file changed, 196 insertions(+) + +commit 9ac11c3c3b1c0399c85ece57c0983ed60d419d7a +Author: John (J5) Palmieri +Date: Thu Feb 17 17:25:00 2011 -0500 + + [gi-demos] add images demo + + * needs annotation fix from GdkPixbuf for ImageLoader to work + + demos/gtk-demo/demos/images.py | 311 + +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 311 insertions(+) + +commit 13b06170b89b3468e6255be32af4833ffc675c9d +Author: John (J5) Palmieri +Date: Thu Feb 17 14:48:24 2011 -0500 + + [gi-demos] add pixbuf demo + + demos/gtk-demo/demos/pixbuf.py | 183 + +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 183 insertions(+) + +commit 7abcfd5b4db99bb0f50c5a47d346a2de3836f994 +Author: John (J5) Palmieri +Date: Thu Feb 17 14:47:12 2011 -0500 + + [gi-demos] remove fixmes from print demo, fixed in pango + + demos/gtk-demo/demos/printing.py | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +commit 9b13f49356da7d71c69b82da2a59d92f456a6913 +Author: John (J5) Palmieri +Date: Wed Feb 16 19:39:30 2011 -0500 + + [gi-demos] add printing demo + + * needs some annotations for pango before it is 100% useful + + demos/gtk-demo/demos/printing.py | 177 + +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 177 insertions(+) + +commit 6025b62ee662af347e48b6752e6d5be74b4a8215 +Author: John (J5) Palmieri +Date: Wed Feb 16 17:52:38 2011 -0500 + + [gi-overrides] add cursor overrides + + https://bugzilla.gnome.org/show_bug.cgi?id=635947 + + gi/overrides/Gdk.py | 41 +++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 23 +++++++++++++++++++++++ + 2 files changed, 64 insertions(+) + +commit 03c0aa498470037ef2aa6a8233198ff521f8d42f +Author: John (J5) Palmieri +Date: Wed Feb 16 16:18:24 2011 -0500 + + [gi-demos] add the links demo + + demos/gtk-demo/demos/links.py | 74 + +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +commit 79ecddf8d54b3f4f8b5ef05d302675152622c832 +Author: John (J5) Palmieri +Date: Wed Feb 16 15:48:40 2011 -0500 + + [gi-demos] add expander demo + + demos/gtk-demo/demos/expander.py | 60 + ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 60 insertions(+) + +commit 76cdb13ab872f91f8384d26b0f2932087a746117 +Author: John (J5) Palmieri +Date: Wed Feb 16 15:14:35 2011 -0500 + + [gi-overrides] use pop instead of del and add extra tests for + Gtk.Table kwargs + + gi/overrides/Gtk.py | 6 ++---- + tests/test_overrides.py | 8 ++++++++ + 2 files changed, 10 insertions(+), 4 deletions(-) + +commit 6ef83c049735689c42f085ca9d7b8e1f251c410f +Author: Laszlo Pandy +Date: Tue Feb 15 20:07:42 2011 +0100 + + [tests] Separate processes for GI and static binding tests. + + Importing and using both static gobject bindings and + introspection GObject bindings in the same process can cause + conflicts with types which otherwise wouldn't be there. + + This patch changes "make check" to call runtests.py twice -- once + for each set of tests. + + In the case of a test failure, runtests.py now sets the exit code + so that make does not continue. Otherwise you might miss the + failures from the first batch of tests in the scrollback. + + tests/Makefile.am | 19 +++++++++++-------- + tests/runtests.py | 4 +++- + 2 files changed, 14 insertions(+), 9 deletions(-) + +commit e0896b45f60f37097ec521f1bc38778383b78dd8 +Author: John (J5) Palmieri +Date: Tue Feb 15 14:47:10 2011 -0500 + + [gi-demos] add dialogs demo + + demos/gtk-demo/demos/dialogs.py | 153 + ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 153 insertions(+) + +commit 2dea743e82f6b18697950c34f116b2d0f1d6b1dd +Author: John (J5) Palmieri +Date: Tue Feb 15 14:46:41 2011 -0500 + + [gi-overrides] fix typo in GtkTable constructor + + gi/overrides/Gtk.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 9c277e1782c5a9d672d91fabf5289c5415891682 +Author: John (J5) Palmieri +Date: Tue Feb 15 13:26:38 2011 -0500 + + [gi-demos] keep popup menu from destroying itself by holding a ref + in app class + + demos/gtk-demo/demos/clipboard.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 18800c4db0e1faea38fd84f635d26a7ded5d10de +Author: John (J5) Palmieri +Date: Tue Feb 15 13:25:13 2011 -0500 + + [gi-overrides] add a Gtk.Menu override for the popup method + + gi/overrides/Gtk.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit ad93386ba9f73ef4c3826544b3868cf03c01225e +Author: John (J5) Palmieri +Date: Tue Feb 15 13:24:33 2011 -0500 + + [gi-demos] fix the about dialog in appwindow demo + + demos/gtk-demo/demos/appwindow.py | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +commit d0c45c80974f05b6adfd3bb01d785be268a53a98 +Author: John (J5) Palmieri +Date: Tue Feb 15 11:21:13 2011 -0500 + + [gi-demos] fix clipboard demo so DnD works + + * menu popups don't work because the API takes a callback without + a destroy + notify + + demos/gtk-demo/demos/clipboard.py | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +commit 02d0327508234ab2e3b7dc6de506d70e6fcaaa17 +Author: John (J5) Palmieri +Date: Tue Feb 15 10:18:53 2011 -0500 + + [gi-demos] fix clipboard demo to reflect new API + + demos/gtk-demo/demos/clipboard.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit aa006cad6990eff0cbb68fa9550e428f2bc96473 +Author: John (J5) Palmieri +Date: Mon Feb 14 18:17:20 2011 -0500 + + [gi-demo] Fix color dialog demo to run with new draw, style and + color apis + + demos/gtk-demo/demos/colorselector.py | 44 + ++++++++++++++--------------------- + 1 file changed, 17 insertions(+), 27 deletions(-) + +commit f94a96c53e9432ac085bd05acee7ebdd2803fbad +Author: John (J5) Palmieri +Date: Mon Feb 14 17:58:25 2011 -0500 + + [gi-demos] fix most of the combobox app + + * Still having some issues with filtering the ComboBoxText widget + + demos/gtk-demo/demos/combobox.py | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +commit 3606eb20ad1651af621bf1aa429ec102082565eb +Author: Laszlo Pandy +Date: Mon Feb 14 19:36:27 2011 +0100 + + Use PyGI type conversion (to fix foreign types) for signal callbacks. + + First attempt at patch to fix foreign types in signal callbacks. + Tests are not implemented yet. + + https://bugzilla.gnome.org/show_bug.cgi?id=637601 + + gi/Makefile.am | 2 + + gi/gimodule.c | 1 + + gi/pygi-argument.c | 91 ++++++++++++++++++ + gi/pygi-argument.h | 2 + + gi/pygi-private.h | 1 + + gi/pygi-signal-closure.c | 245 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-signal-closure.h | 46 +++++++++ + gi/pygi.h | 28 ++++++ + gobject/pygobject.c | 24 ++++- + 9 files changed, 436 insertions(+), 4 deletions(-) + +commit 2e39d5e8f96be2253acb2f34a0d0b5b9c9adb8ff +Author: John (J5) Palmieri +Date: Mon Feb 14 16:47:03 2011 -0500 + + [gi-demos] fix drawingarea app to use the new draw api + + demos/gtk-demo/demos/drawingarea.py | 144 + +++++++++++++----------------------- + 1 file changed, 50 insertions(+), 94 deletions(-) + +commit 8385afbbc5df295d9b7cd3b5d19c90faa1f7ea8e +Author: John (J5) Palmieri +Date: Mon Feb 14 16:43:35 2011 -0500 + + [gi-overrides] for Gtk 3 alias Gdk.Rectangle to cairo.RectangleInt + + * note this is the introspected gobject-cairo boxed type not the + static cairo + bindings + * we alias this so people do not get confused + + gi/overrides/Gdk.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit d491c369e049ab726f09002af0462391d5c2f3ec +Author: John (J5) Palmieri +Date: Mon Feb 14 15:07:11 2011 -0500 + + [gi-overrides] let user set the proper property names in Gtk.Table + + * the old override added a columns and rows parameters to the Table + constuctor + to be in sync with PyGtk. + * The GTK properties are n_columns and n_rows + * support both + + gi/overrides/Gtk.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 95bc2b2b025d659725d701c3b759c0c4d9681a36 +Author: John (J5) Palmieri +Date: Mon Feb 14 15:06:38 2011 -0500 + + [gi-demos] get appwindow demo working again + + demos/gtk-demo/demos/appwindow.py | 24 ++++-------------------- + 1 file changed, 4 insertions(+), 20 deletions(-) + +commit 015185f502c498c21cb108d3bb288c5b6dbf202f +Author: John (J5) Palmieri +Date: Mon Feb 14 15:05:44 2011 -0500 + + [gi-demos] fixed use of tree_iter_get + + demos/gtk-demo/gtk-demo.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0c20977e4598e5447dd07c069e91226efacb1160 +Author: Simon van der Linden +Date: Fri Feb 11 22:02:03 2011 +0100 + + Remove last GIO-related bits + + https://bugzilla.gnome.org/show_bug.cgi?id=638899 + + PKG-INFO.in | 2 +- + README | 3 +- + configure.ac | 3 -- + examples/gio/directory-async.py | 33 ------------------ + examples/gio/downloader.py | 77 + ----------------------------------------- + pygobject.doap | 2 +- + 6 files changed, 3 insertions(+), 117 deletions(-) + +commit e4ebbd7de5570af1abf41bdf9469d4ce3edd48cb +Author: Simon van der Linden +Date: Fri Feb 11 18:38:27 2011 +0100 + + Remove GIO documentation + + https://bugzilla.gnome.org/show_bug.cgi?id=638899 + + docs/Makefile.am | 82 +- + docs/reference/pygio-appinfo.xml | 894 ----- + docs/reference/pygio-applaunchcontext.xml | 194 -- + docs/reference/pygio-asyncresult.xml | 117 - + docs/reference/pygio-bufferedinputstream.xml | 461 --- + docs/reference/pygio-bufferedoutputstream.xml | 275 -- + docs/reference/pygio-cancellable.xml | 290 -- + docs/reference/pygio-classes.xml | 47 - + docs/reference/pygio-constants.xml | 1540 --------- + docs/reference/pygio-datainputstream.xml | 799 ----- + docs/reference/pygio-dataoutputstream.xml | 504 --- + docs/reference/pygio-drive.xml | 546 --- + docs/reference/pygio-emblem.xml | 232 -- + docs/reference/pygio-emblemedicon.xml | 160 - + docs/reference/pygio-file.xml | 4534 + ------------------------- + docs/reference/pygio-fileattributeinfo.xml | 73 - + docs/reference/pygio-fileenumerator.xml | 488 --- + docs/reference/pygio-fileicon.xml | 109 - + docs/reference/pygio-fileinfo.xml | 346 -- + docs/reference/pygio-fileinputstream.xml | 214 -- + docs/reference/pygio-filemonitor.xml | 128 - + docs/reference/pygio-fileoutputstream.xml | 257 -- + docs/reference/pygio-filterinputstream.xml | 152 - + docs/reference/pygio-filteroutputstream.xml | 152 - + docs/reference/pygio-functions.xml | 395 --- + docs/reference/pygio-icon.xml | 217 -- + docs/reference/pygio-inputstream.xml | 730 ---- + docs/reference/pygio-loadableicon.xml | 198 -- + docs/reference/pygio-memoryinputstream.xml | 151 - + docs/reference/pygio-memoryoutputstream.xml | 175 - + docs/reference/pygio-mount.xml | 962 ------ + docs/reference/pygio-mountoperation.xml | 726 ---- + docs/reference/pygio-outputstream.xml | 140 - + docs/reference/pygio-seekable.xml | 231 -- + docs/reference/pygio-simpleasyncresult.xml | 317 -- + docs/reference/pygio-themedicon.xml | 204 -- + docs/reference/pygio-unixinputstream.xml | 202 -- + docs/reference/pygio-unixoutputstream.xml | 202 -- + docs/reference/pygio-volume.xml | 718 ---- + docs/reference/pygio-volumemonitor.xml | 844 ----- + docs/reference/pygiounix-classes.xml | 13 - + docs/reference/pygobject-ref.xml | 2 - + 42 files changed, 1 insertion(+), 19020 deletions(-) + +commit abdebc7f6515f9658812c0355d8ad0892e5371e4 +Author: John (J5) Palmieri +Date: Fri Feb 11 11:05:04 2011 -0500 + + bump version to reflect the master branch moving towards pygobject 3.0 + + * added NEWS file from branch pygobject-2-28 + * bump to 2.90.1 + * this branch will drop support for the static binding + * use the pygobject-2-28 branch for static binding fixes + + NEWS | 289 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + configure.ac | 4 +- + 2 files changed, 291 insertions(+), 2 deletions(-) + +commit 16140237aa45b4f188923da9f95b9d2af971011b +Author: John (J5) Palmieri +Date: Thu Feb 10 16:46:08 2011 -0500 + + fix build to correctly use python-config + + autogen.sh | 3 +++ + configure.ac | 6 ------ + m4/python.m4 | 9 +++++---- + tests/runtests.py | 1 + + 4 files changed, 9 insertions(+), 10 deletions(-) + +commit c2079f415638ef892b1e51f25eaafa3e1621667f +Author: Simon van der Linden +Date: Thu Feb 10 22:26:00 2011 +0100 + + Add missing libraries to link against + + glib/Makefile.am | 2 +- + gobject/Makefile.am | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +commit 3cca62a9e7afd3d3d302c66f4fafe253f7743d4e +Author: Steve Frécinaux +Date: Wed Jan 19 15:00:56 2011 +0100 + + Make runtests.py able to run command-line provided test files + + With this patch we are now able to run ./runtests.py , which + is more friendly than defining an environment variable to run some + specific tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=639948 + + tests/runtests.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 14c4cf8e6edae893538680964380d543bde4a14d +Author: Martin Pitt +Date: Wed Feb 9 11:34:59 2011 +0100 + + Run test suite under dbus-launch + + When available, run the test suite in dbus-launch, so that the + GDBus tests + succeed even when building this in an environment without a running + session + D-BUS (such as distribution package builds). + + tests/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 0858f550e2b6f75e3f583f963f5952f5ddae4e0e +Author: Martin Pitt +Date: Tue Feb 8 15:46:36 2011 +0100 + + Fix test_gdbus.py to be Python3 friendly + + - TestCase.assert_() has been deprecated by assertTrue(). + - Exceptions don't have a message attribute any more, use str(e) + + tests/test_gdbus.py | 34 +++++++++++++++------------------- + 1 file changed, 15 insertions(+), 19 deletions(-) + +commit b7f32e4cca0cef201489b55653f96ac64a8f9ab9 +Author: Martin Pitt +Date: Sat Jan 29 12:20:50 2011 +0100 + + [gi] Provide comfortable GSettings API + + Make Gio.Settings behave like a dictionary, with transparent + conversion from/to + GVariants. Also provide a more comfortable constructor. + + https://bugzilla.gnome.org/show_bug.cgi?id=640838 + + gi/overrides/Gio.py | 54 +++++++++++++++++++++++++++++ + tests/org.gnome.test.gschema.xml | 9 +++++ + tests/test_overrides.py | 73 + ++++++++++++++++++++++++++++++++-------- + 3 files changed, 122 insertions(+), 14 deletions(-) + +commit 8dad0eaed60a9de26e9a729a48a1f6bc74be486e +Author: Laszlo Pandy +Date: Fri Feb 4 16:36:07 2011 +0100 + + Fix vfunc search bug when using GInterfaces and a do_* method. + + If a class inherits from a GInterface, as well as implements a do_* + method (which is not in a super class), all the base interfaces + will be searched for an __info__ attribute. GInterface doesn't + have one, causing an error on class creation. + + https://bugzilla.gnome.org/show_bug.cgi?id=641493 + + gi/types.py | 4 +++- + tests/test_gi.py | 8 ++++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +commit 2660be1f227be7a53092483bc9d8ead1bd1fb266 +Author: Laszlo Pandy +Date: Thu Feb 3 15:31:42 2011 +0100 + + [GI] Add tests for Gtk.Widget.drag_* methods. + + Previously all the drag_* methods were accessible as Gtk.drag_*. + Now that the (method) attribute has been included for these + methods in Gtk+, this test checks that they are included as class + methods when using pygobject introspection. + + https://bugzilla.gnome.org/show_bug.cgi?id=639945 + + tests/test_overrides.py | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +commit d57500537014b3da624be33b40401ba289fa22b8 +Author: John (J5) Palmieri +Date: Thu Feb 3 09:02:16 2011 -0500 + + [gi] make caller allocates work again + + gi/pygi-cache.c | 18 +++--------------- + gi/pygi-invoke.c | 37 ++++++++++++++++++++++++++++++++++--- + 2 files changed, 37 insertions(+), 18 deletions(-) + +commit 99d6e6c8d806e6f9e48c3c2380024fb3511d110a +Author: John (J5) Palmieri +Date: Wed Feb 2 19:27:40 2011 -0500 + + [gi] fix container object reffing + + gi/pygi-argument.c | 7 +++---- + gi/pygi-cache.c | 12 ++++-------- + 2 files changed, 7 insertions(+), 12 deletions(-) + +commit 09acaff29dfaabc77477cffca2c7137f68991e7f +Author: Ignacio Casal Quinteiro +Date: Wed Feb 2 21:00:48 2011 +0100 + + [python 3] use the right syntaxis to raise exceptions + + codegen/argtypes.py | 8 ++++---- + codegen/definitions.py | 14 +++++++------- + gi/overrides/Gtk.py | 2 +- + 3 files changed, 12 insertions(+), 12 deletions(-) + +commit 36094e5982d3e05d5662843b6d401f0974f5235f +Author: Ignacio Casal Quinteiro +Date: Wed Feb 2 20:50:12 2011 +0100 + + [gi] return PYGLIB_MODULE_ERROR_RETURN on error and use pygobject_init + + tests/testhelpermodule.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit c913c1789296310c2cf27554ce719d7f6e9c94cd +Author: Ignacio Casal Quinteiro +Date: Wed Feb 2 20:37:21 2011 +0100 + + [gi] return PYGLIB_MODULE_ERROR_RETURN on error + + This is to avoid some warnings when building with python 3 + + gi/gimodule.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 7bc4122897d9d05172a2bd5b56bded87e2afaec4 +Author: Steve Frécinaux +Date: Sat Jan 29 00:16:50 2011 +0100 + + Fix wrong refcount when calling introspected widget constructors + + Introspected widget constructors, like Gtk.Button.new(), can return + objects with a floating reference, which was then reffed by pygobject, + resulting in two references, despite the object is not owned by + anyone. + + This patch uses ref_sink() when pygobject takes its own reference, to + avoid adding that extra reference. Hence we now claim ownership on + objects returned by constructors with transfer=none (which is the case + for nearly all the widget constructors, despite the floating ref). + + https://bugzilla.gnome.org/show_bug.cgi?id=640868 + + gobject/pygobject.c | 4 +++- + tests/test_everything.py | 9 ++++++++- + 2 files changed, 11 insertions(+), 2 deletions(-) + +commit afeaaa126f7cd6556fb855ecd0facc174c0f946c +Author: Simon Schampijer +Date: Wed Jan 19 16:19:46 2011 +0100 + + Gdk.Window: Map the standard constructor to the *new* constructor + + Gdk.Window had to be made abstract + (see c4a36d875235e0bf1e52dbf2fa14d08bfc8bd4ec in gtk), + this override allows using the standard constructor + + This commit adds as well a testcase. + + https://bugzilla.gnome.org/show_bug.cgi?id=639936 + + gi/overrides/Gdk.py | 6 ++++++ + tests/test_overrides.py | 8 ++++++++ + 2 files changed, 14 insertions(+) + +commit 4a67f45880433905de33632fe0c32a13b44c0b33 +Author: John (J5) Palmieri +Date: Mon Jan 31 16:51:37 2011 -0500 + + [gi] handle hash being NULL + + gi/pygi-argument.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 2fbfe410f4b4394a2018ada0e538585c1bec23ae +Author: John (J5) Palmieri +Date: Mon Jan 31 16:50:52 2011 -0500 + + [gi] handle the situation where an aux arg comes before its parent + + gi/pygi-cache.c | 70 + ++++++++++++++++++++++++++++++++++++++++---------------- + gi/pygi-invoke.c | 2 +- + 2 files changed, 51 insertions(+), 21 deletions(-) + +commit 858669f92c9907dd70b4966d6a8521ed122225be +Author: Martin Pitt +Date: Mon Jan 31 17:38:52 2011 +0100 + + Ship tests/org.gnome.test.gschema.xml in dist tarballs + + tests/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 77d76df59606e470808085e977fb199cc76e8251 +Author: John (J5) Palmieri +Date: Sun Jan 30 18:21:24 2011 -0500 + + [gi] allow caching and marshalling of ghash out + + gi/pygi-argument.c | 155 + +++++++++++++++++++++++++++++++++++++++++++++++++---- + gi/pygi-cache.c | 27 ++++++---- + 2 files changed, 162 insertions(+), 20 deletions(-) + +commit bd66af67f248a3ca90d2fa2626605263c2392e16 +Author: John (J5) Palmieri +Date: Sun Jan 30 17:06:44 2011 -0500 + + [gi] whitespace fixes + + gi/pygi-cache.c | 60 + ++++++++++++++++++++++++++++----------------------------- + 1 file changed, 30 insertions(+), 30 deletions(-) + +commit 1cdbd4be9b015f792c2c02afa5ac7e24edbdae86 +Author: John (J5) Palmieri +Date: Sun Jan 30 17:04:13 2011 -0500 + + [gi] added ugly aux arg counters + + * we need to simplify the ffi invoke so we can simply reference args + at their position in the C parameter list + * this works for now but is fragile if new aux values are added in + the future + + gi/pygi-argument.c | 12 ++++++++-- + gi/pygi-cache.c | 66 + +++++++++++++++++++++++++++++++++++++----------------- + gi/pygi-cache.h | 2 ++ + gi/pygi-invoke.c | 12 +++++++--- + 4 files changed, 66 insertions(+), 26 deletions(-) + +commit c51447f4efde2ce4caf39c1ffac905ec428d1d64 +Author: John (J5) Palmieri +Date: Sun Jan 30 11:30:54 2011 -0500 + + [gi] make inout marshalling work + + * refactor cache generation so we can create caches and then fill + in their + values based on if they are in, out or inout + * in invoke we order the pointers based on their direction + + gi/pygi-cache.c | 1445 + ++++++++++++++++++++++++++---------------------------- + gi/pygi-invoke.c | 19 +- + 2 files changed, 711 insertions(+), 753 deletions(-) + +commit 2b185362de45f46ce0f0b8816499aef06ab1ad1e +Author: John (J5) Palmieri +Date: Sat Jan 29 13:49:36 2011 -0500 + + [gi] marshal arrays out + + gi/pygi-argument.c | 101 + +++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 99 insertions(+), 2 deletions(-) + +commit e62e7062d5cfd782eac64852f681c63e2776b8d4 +Author: John (J5) Palmieri +Date: Sat Jan 29 13:48:23 2011 -0500 + + [gi] fix sequence caching to support out + + gi/pygi-cache.c | 111 + ++++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 87 insertions(+), 24 deletions(-) + +commit 69207910209ebfe450df616aeb8fa4cc2e7eccf3 +Author: Martin Pitt +Date: Fri Jan 28 17:14:19 2011 +0100 + + [gi] Add GSettings tests + + Ryan Lortie proposed an override for more convenient GSettings access, + so let's + first make sure that the canonical GLib API works. + + tests/Makefile.am | 7 +++++-- + tests/org.gnome.test.gschema.xml | 16 ++++++++++++++++ + tests/test_overrides.py | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 52 insertions(+), 2 deletions(-) + +commit 488478a83640d50baee963337fcc870fec76b784 +Author: Martin Pitt +Date: Fri Jan 28 07:20:26 2011 +0100 + + [gi] Provide GtkTextBuffer.insert_with_tags_by_name() + + Provide an actual insert_with_tags_by_name() instead of overloading + insert_with_tags() to handle both types. This keeps the overrides + consistent + with the actual GTK API. + + gi/overrides/Gtk.py | 19 ++++++++++++++----- + tests/test_overrides.py | 4 ++-- + 2 files changed, 16 insertions(+), 7 deletions(-) + +commit dace1a553793fb7fb054b60760f02c9e5cf00b38 +Author: Martin Pitt +Date: Thu Jan 27 13:37:18 2011 +0100 + + [gi] Support tag names in GtkTextBuffer.insert_with_tags() + + Neither insert_with_tags() nor insert_with_tags_by_name() are + introspectable + due to using varargs. As both are useful, support both cases in + the override. + + gi/overrides/Gtk.py | 5 +++++ + tests/test_overrides.py | 9 +++++++++ + 2 files changed, 14 insertions(+) + +commit 91d34124b2a5128e93e13c7fee8693d5edc4e9bb +Author: Ignacio Casal Quinteiro +Date: Thu Jan 27 12:23:18 2011 +0100 + + Add MAINTAINERCLEANFILES + + This var behaves like .gitignore and allows us to skip some specific + files. + + Makefile.am | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +commit 8a98d26981ce68809a21c64cac4962e58c927905 +Author: Ignacio Casal Quinteiro +Date: Thu Jan 27 12:15:30 2011 +0100 + + Remove .gitignore files and use git.mk + + git.mk is a script maintained in pango. From time to time we must + check if it was updated and update it here. + + .gitignore | 46 ----------- + Makefile.am | 2 + + codegen/.gitignore | 2 - + codegen/Makefile.am | 2 + + docs/.gitignore | 7 -- + docs/Makefile.am | 2 + + examples/Makefile.am | 2 + + gi/.gitignore | 40 ---------- + gi/Makefile.am | 2 + + gi/overrides/Makefile.am | 2 + + gi/repository/Makefile.am | 2 + + gi/tests/Makefile.am | 2 + + git.mk | 200 + ++++++++++++++++++++++++++++++++++++++++++++++ + glib/Makefile.am | 2 + + gobject/.gitignore | 3 - + gobject/Makefile.am | 2 + + tests/.gitignore | 2 - + tests/Makefile.am | 2 + + 18 files changed, 222 insertions(+), 100 deletions(-) + +commit 331c42b63bc60a3b906fa21e1c0a7c1b9428f347 +Author: Martin Pitt +Date: Thu Jan 27 12:04:19 2011 +0100 + + pygi-convert.sh: Convert Pango.TabAlign.* + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit be1a2959fa0a3d8682e0e8aef389d73dacab0689 +Author: Martin Pitt +Date: Thu Jan 27 12:02:39 2011 +0100 + + pygi-convert.sh: Drop window -> get_window() conversion + + It is doing more harm than good for projects which use things like + self.window. + + pygi-convert.sh | 1 - + 1 file changed, 1 deletion(-) + +commit dd7deb4b658c56857c26b1a278a3d688f2ea6a2a +Author: Martin Pitt +Date: Thu Jan 27 11:58:26 2011 +0100 + + pygi-convert.sh: Don't convert self.window assignments + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 975341a26772966d4afc87a88a6a566d61237fa0 +Author: Steve Frécinaux +Date: Fri Jan 21 18:41:54 2011 +0100 + + Fix leaked python reference in python-defined subclasses + + https://bugzilla.gnome.org/show_bug.cgi?id=640184 + + gobject/gobjectmodule.c | 1 + + tests/test_gobject.py | 4 ++++ + 2 files changed, 5 insertions(+) + +commit a59e2d58bdb3f31a4f415dbe14b7d9988ac28ce3 +Author: Steve Frécinaux +Date: Fri Jan 21 15:54:43 2011 +0100 + + Add some tests for the number of python refs held at creation time + + https://bugzilla.gnome.org/show_bug.cgi?id=640184 + + tests/test_gobject.py | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +commit 7d70105eb324ea4b6a58c2d3fb3f2dda36e7ab33 +Author: Steve Frécinaux +Date: Fri Jan 21 17:24:49 2011 +0100 + + Factor out parameter marshalling from construction functions. + + https://bugzilla.gnome.org/show_bug.cgi?id=640197 + + gobject/gobjectmodule.c | 35 ++-------------------- + gobject/pygobject-private.h | 5 ++++ + gobject/pygobject.c | 71 + +++++++++++++++++++++++++++------------------ + 3 files changed, 50 insertions(+), 61 deletions(-) + +commit a3e0cfe8924887ecd1e07cedd2cfb999c853ac62 +Author: John (J5) Palmieri +Date: Wed Jan 26 15:34:24 2011 -0500 + + [gi] in python 3 an array of uint8 can be bytes but not string + + tests/test_gi.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 843553ea958eddec185bb660851a310dc050a14b +Author: John (J5) Palmieri +Date: Wed Jan 26 15:30:06 2011 -0500 + + [gi] fix Gio.FileEnumerator to reflect the Python 3 iter protocol + + gi/overrides/Gio.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 6ff357839feb39930a5f3175de3d0ed35f24d3f4 +Author: John (J5) Palmieri +Date: Wed Jan 26 15:17:03 2011 -0500 + + [gi] python 3 fixes + + Patches need to work in Python 3 - here are some of the issues I + fixed up. + Patch submitters should keep this in mind. When I note to only + use something + in tests it means that there is a compat module that is only available + to the + tests. Actuall code should either add the workaround to the top + of their + module or try not to have a distinction between things such as + unicode and + longs which no longer exist in Python 3 + + * use range instead of xrange - loss of performance in Python 2 but + Python 3 i + treats range similarly to python 2's xrange + * use dict.items() instead of dict.iteritems() - same as the xrange + issue + * callable does not exist in 3.x, use hasattr(obj, '__call__') or + + if sys.version_info > (3, 0): + def callable(obj): + return hasattr(obj, '__call__') + + * using unicode in tests is tricky, you can't use u'' even in + a versioned + conditional as python3's parser chokes on it. Do this in tests + (and only i + in tests): + + from compathelper import _unicode + unicode_string = _unicode('this is a unicode string') + + * exception caching changed in 2.7, instead of except Exception, + e we now use + except Exception as e. Do this to be compatible with older + versions: + + except Exception: + etype, e = sys.exc_info()[:2] + + * Unbound methods with an im_func attribute no longer exits in 3.x. + Unbound methods are now just functions so class.method in 3.x is + equivalent to class.method.im_func in 2.x. If you have to go this + low level do this: + + func = class1.method + if sys.version_info < (3,0): + func = func.im_func + + * all numbers are long in 3.x so 42L is invalid in 3.x. In tests (and + only in tests) do this: + + from compathelper import _long + l = _long(42) + + gi/overrides/GLib.py | 16 ++++++++-------- + gi/types.py | 5 ++++- + tests/compathelper.py | 19 +++++++++++++++++++ + tests/test_gdbus.py | 12 ++++++++---- + tests/test_gi.py | 19 ++++++++++++------- + tests/test_overrides.py | 8 +++++--- + 6 files changed, 56 insertions(+), 23 deletions(-) + +commit 832d662b9f90f5762bbf28b3cca73f947c1f83ce +Author: John (J5) Palmieri +Date: Wed Jan 26 14:00:08 2011 -0500 + + [gi] fix try/except blocks using depricated raise format + + gi/overrides/GLib.py | 4 ++-- + gi/overrides/Gdk.py | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit d3e30e240fed6ef1dd40fd29fd13dc2effc6c7b1 +Author: Martin Pitt +Date: Wed Jan 26 19:03:48 2011 +0100 + + [gi] Add docstring to GLib.Variant constructor + + gi/overrides/GLib.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 963cd52fec26f7a4fb34414f8ac6662932ede322 +Author: Martin Pitt +Date: Wed Jan 26 18:45:38 2011 +0100 + + [gi] update gdbus test cases for previous GVariant change + + tests/test_gdbus.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 27e3a6276ff5f2cdc03ddf69ee80d44c3bf2c094 +Author: Martin Pitt +Date: Wed Jan 26 18:39:17 2011 +0100 + + [gi] Accept only a single object in GLib.Variant constructor + + We previously allowed flat arguments for tuple signatures, e. g. + + GLib.Variant('(ii)', 1, 2) + + However, that's not how GVariant is supposed to work. Remove the + special case + to handle flat argument lists, and only accept a single value, i. e. + + GLib.Variant('(ii)', (1, 2)) + + Note that this breaks the current API, but as it is not used widely + yet, let's + better fix it now. + + Thanks to Ryan Lortie for pointing this out! + + gi/overrides/GLib.py | 25 ++++++++++--------------- + tests/test_overrides.py | 32 +++++++++++++------------------- + 2 files changed, 23 insertions(+), 34 deletions(-) + +commit b15e8e2c0c933d0f827a70280faf875ac383d81b +Author: Laszlo Pandy +Date: Wed Jan 26 00:40:49 2011 +0100 + + Speed up _setup_native_vfuncs() + + This changes _setup_native_vfuncs() to only install native + vfunc wrappers from the current class on the current class. + Native vfuncs will not be propogated up or down the class + hierarchy as this is unnecessary and wastes CPU and memory. + + Since the normal process in python to retrieve a method or + attribute recurses to the base classes if an attribute is not + found in the subclass, there is no need to setup all base class + virtual functions on a subclass. + + This patch removes the recursion in _setup_native_vfuncs() + and lets Python find them in the base classes like a normal + Python class would work. This significantly increases the speed + of any class which is or inherits from a C class which includes + virtual methods. + + https://bugzilla.gnome.org/show_bug.cgi?id=640629 + + gi/types.py | 26 +++++++++++++------------- + tests/test_gi.py | 13 +++++++++++++ + 2 files changed, 26 insertions(+), 13 deletions(-) + +commit 569d42ac2f50fb706ef289ff631db743483f40ee +Author: Laszlo Pandy +Date: Thu Jan 20 16:26:18 2011 +0100 + + Speed up class creation: rewrite _setup_vfuncs() to be much more + efficient. + + This patch rewrites the _setup_vfuncs() method to remove recursion and + make the running time linear in the number of virtual functions to + hook up + (ie. methods starting with "do_") instead of linear in the number of + virtual functions in the base class which could possibly be + overridden. + + Since most classes do not override all of the virtual functions in the + base class (and many override none), this runs much faster. + + It is possible to not recurse on all base classes because + non-interface + base classes will have the virtual function installed as an attribute. + Thus getattr() can be called, which recurses to the base classes much + faster than a custom implementation in Python. If the method cannot be + found with getattr(), all interface bases classes are searched + manually. + + The function is_function_in_classes() has been deleted. Because of the + above changes, it is not used anymore. + + https://bugzilla.gnome.org/show_bug.cgi?id=640073 + + gi/types.py | 104 + ++++++++++++++++++++++++++++++++++--------------------- + tests/test_gi.py | 13 +++++++ + 2 files changed, 77 insertions(+), 40 deletions(-) + +commit 8f4e6536f3c2edf38a45632d1c23eb7c6681c3be +Author: Sebastian Pölsterl +Date: Mon Jan 24 19:23:19 2011 +0100 + + pygi-convert.sh: Convert gtk.UI_MANAGER_* + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 1f473b5164407a178203eb8cc7f3c786e0d0e5c2 +Author: Sebastian Pölsterl +Date: Fri Jan 21 18:41:54 2011 +0100 + + pygi-convert.sh: Convert gdk.GRAB_* + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit f5d0b7b9d189f65503c0bf66d8bda4186ca3223a +Author: Ignacio Casal Quinteiro +Date: Fri Jan 21 16:45:07 2011 +0100 + + [gi] set the gtype GValue correctly + + gi/pygi-property.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit ce521011d7f6d7f082aaea76fa05c5af9f6e93f5 +Author: Ignacio Casal Quinteiro +Date: Fri Jan 21 16:20:23 2011 +0100 + + [gi] use the right argument type for callback + + gi/pygi-foreign-cairo.c | 8 ++++---- + gi/pygi-foreign-gvariant.c | 4 ++-- + gi/pygi-foreign-gvariant.h | 2 +- + gi/pygi-foreign.c | 2 +- + gi/pygi.h | 2 +- + 5 files changed, 9 insertions(+), 9 deletions(-) + +commit 9f101baaa63a75acf62f955cfc4b311ff0dd5464 +Author: John (J5) Palmieri +Date: Fri Jan 21 09:23:54 2011 -0500 + + [gi] marshal out flags and enum + + gi/pygi-argument.c | 14 +++++++++----- + gi/pygi-cache.c | 24 ++++++++++++------------ + 2 files changed, 21 insertions(+), 17 deletions(-) + +commit 4c93bdeae76830aa4029dfc86e32e6f277d5271d +Author: John (J5) Palmieri +Date: Fri Jan 21 08:18:37 2011 -0500 + + [gi] marshal unions + + gi/pygi-cache.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +commit a060287d1a6d190acb9d344f08fd5662e3296da5 +Author: Martin Pitt +Date: Fri Jan 21 11:00:27 2011 +0100 + + [gi] Add test cases for GDBus client operations + + tests/Makefile.am | 1 + + tests/test_gdbus.py | 94 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 95 insertions(+) + +commit e7699d9af41f8c374326b8a4ec0939ef1426e386 +Author: John (J5) Palmieri +Date: Fri Jan 21 04:28:15 2011 -0500 + + [gi] error out if the constructor returns NULL + + gi/pygi-invoke.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 58ff2b2c38c1004861083ca88633be76767229f0 +Author: John (J5) Palmieri +Date: Fri Jan 21 04:26:45 2011 -0500 + + [gi] throw error for caller allocates until we can write code to + support it + + gi/pygi-cache.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 5eb779439daa8bf1e86df689377dc10ef1430eab +Author: John (J5) Palmieri +Date: Fri Jan 21 04:26:11 2011 -0500 + + [gi] support struct out + + gi/pygi-argument.c | 30 ++++++++++++++++++++++++++---- + gi/pygi-cache.c | 15 ++------------- + 2 files changed, 28 insertions(+), 17 deletions(-) + +commit 3133dc595adf44279397d30712c0f8595f0e1acc +Author: John (J5) Palmieri +Date: Fri Jan 21 04:22:06 2011 -0500 + + [gi] move to using type_info and interface_info instead of arg_info + + * only arguments have arg_infos, not return types and instances so + type_info is much better to pass. In fact most API that took an + arg_info simply converted it to a type_info + * In the case of instances for methods we don't even have a type_info. + Since all instances are interfaces, we also attach the + interface_info + to the interface cache + + gi/pygi-argument.c | 20 ++++---------------- + gi/pygi-cache.c | 43 + ++++++++++++++++++++++++++++++++----------- + gi/pygi-cache.h | 4 +++- + gi/pygi-foreign-cairo.c | 24 ++++++++++++------------ + gi/pygi-foreign-gvariant.c | 11 +++++------ + gi/pygi-foreign-gvariant.h | 10 +++++----- + gi/pygi-foreign.c | 21 +++++++++------------ + gi/pygi-foreign.h | 6 +++--- + gi/pygi.h | 8 ++++---- + 9 files changed, 77 insertions(+), 70 deletions(-) + +commit e97e28048efb966ecc1a03277d36cbaa81b8db7d +Author: Martin Pitt +Date: Fri Jan 21 09:54:14 2011 +0100 + + [gi] Add Variant construction/unpack support for boxed Variants + + Construction uses a GVariantBuilder for now, as the new_variant() + constructor + currently does not work (see + https://bugzilla.gnome.org/show_bug.cgi?id=639952) + + gi/overrides/GLib.py | 18 +++++++++++++++++- + tests/test_overrides.py | 26 ++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+), 1 deletion(-) + +commit 71dd03261fc06b8180c14cd31b54d8e4b200be3a +Merge: bc29600 bd002c7 +Author: Dieter Verfaillie +Date: Fri Jan 21 09:33:16 2011 +0100 + + Merge branch 'windows-setup-fixes' + +commit bc29600a2a04c972ceab7ef8d3292e8633977591 +Author: Thomas Hindoe Paaboel Andersen +Date: Thu Jan 20 19:48:23 2011 +0100 + + pygi-convert.sh: GdkPixbuf methods + + GNOME bug #639880 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit d1b0fa501cc431baa530d96fb50f4c35590890ac +Author: Thomas Hindoe Paaboel Andersen +Date: Thu Jan 20 19:45:01 2011 +0100 + + pygi-convert.sh: Gdk.COLORSPACE_RGB + + GNOME bug #639880 + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 6d8ff4d5bdda5480089543869535cc3ee83da2f5 +Author: Martin Pitt +Date: Wed Jan 19 11:41:11 2011 +0100 + + [gi] Support nested objects and empty sequences in GLib.Variant + building + + The GVariant constructor (in the overrides) previously did not + support empty + arrays/dictionaries or nested structures. Rewrite the VariantCreator + class to + be fully recursive and determine the element types of + arrays/dictionaries. + + This now also allows you to use actual tuples as input values for + GVariant + tuple types. Taking values from the flat argument list is still + supported for + convenience, though. + + https://bugzilla.gnome.org/show_bug.cgi?id=639939 + + gi/overrides/GLib.py | 229 + ++++++++++++++++++++++++++---------------------- + tests/test_overrides.py | 159 +++++++++++++++++++++++++++++++-- + 2 files changed, 273 insertions(+), 115 deletions(-) + +commit ac095f5435f106e175fa3297cb273e63c85d2809 +Author: Tomeu Vizoso +Date: Thu Jan 20 15:55:45 2011 +0100 + + Uncomment test_gi.TestInterfaceClash + + tests/test_gi.py | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +commit 1239f3709ba257c404dda72b7067b77b19c240fa +Author: John (J5) Palmieri +Date: Thu Jan 20 09:05:02 2011 -0500 + + [gi] add support for enum and flags + + gi/pygi-argument.c | 121 + +++++++++++++++++++++++++++++++++++++++++------------ + gi/pygi-cache.c | 30 ++++++------- + 2 files changed, 111 insertions(+), 40 deletions(-) + +commit f0a0b6c2eda89622de2b1e5ebb6a48103ad72a42 +Author: Steve Frécinaux +Date: Thu Jan 20 14:14:15 2011 +0100 + + Fix reference leaks for GInitiallyUnowned objects + + References were leaked for GInitiallyUnowned objects which got their + wrappers created several times, because someone else holds reference + on it and it got out of python scope at some point. + + https://bugzilla.gnome.org/show_bug.cgi?id=639949 + + gobject/gobjectmodule.c | 2 ++ + gobject/pygobject.c | 14 +++++------ + tests/test-floating.c | 36 +++++++++++++++++++++++++++ + tests/test-floating.h | 21 ++++++++++++++++ + tests/test_gobject.py | 63 + ++++++++++++++++++++++++++++++++++++++++++++++++ + tests/testhelpermodule.c | 50 ++++++++++++++++++++++++++++++++++++++ + 6 files changed, 179 insertions(+), 7 deletions(-) + +commit cae2cf3d4fb049c94389bf8f84d7d97a544d7a3f +Author: Steve Frécinaux +Date: Wed Jan 19 16:57:57 2011 +0100 + + Add tests for refcount of a GObject owned by a library + + When the object is constructed, its refcount is 2 because the library + refs it once. It should remain around until we ask the library to + release its reference. + + https://bugzilla.gnome.org/show_bug.cgi?id=639949 + + tests/test-floating.c | 30 +++++++++++++++++++++++ + tests/test-floating.h | 20 ++++++++++++++++ + tests/test_gobject.py | 62 + ++++++++++++++++++++++++++++++++++++++++++++++++ + tests/testhelpermodule.c | 51 +++++++++++++++++++++++++++++++++++++++ + 4 files changed, 163 insertions(+) + +commit b6737b91938d527872eff1d645a205cacf94e15d +Author: Steve Frécinaux +Date: Wed Jan 19 14:52:41 2011 +0100 + + Add a test to check for regular object reference count + + https://bugzilla.gnome.org/show_bug.cgi?id=639949 + + tests/test_gobject.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +commit 2b0f1ede820414ef1cfd6b37569fcb946d2031fc +Author: Martin Pitt +Date: Thu Jan 20 14:15:52 2011 +0100 + + [gi] Update TreeView.enable_model_drag_{source,dest} to current GTK + + GTK master now landed a lot of annotation fixes which also correctly + marks the + array length argument of + Gtk.TreeView.enable_model_drag_{source,dest}(). Thus + drop the explicit array length argument from the call in the override. + + gi/overrides/Gtk.py | 2 -- + 1 file changed, 2 deletions(-) + +commit b59edf4f0f7cab44033f9d704d476e10ee0d0c0a +Author: Steve Frécinaux +Date: Wed Jan 19 18:04:10 2011 +0100 + + Fix a typo in a private symbol name. + + gobject/gobjectmodule.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 6447688e283a8fb22de3ab68cbc06e34ad23d198 +Author: Martin Pitt +Date: Thu Jan 20 11:49:08 2011 +0100 + + pygi-convert.sh: Convert glib.source_remove() + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 84ee8de4bc00a8f901926cc6386d73c12dbd0b0b +Author: Martin Pitt +Date: Thu Jan 20 11:42:34 2011 +0100 + + Fix typo in previous commit to actually convert glib.GError + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b238cb614338f46e6feb7935cca0a55c7a929418 +Author: Martin Pitt +Date: Thu Jan 20 11:40:14 2011 +0100 + + pygi-convert.sh: Move some glib bits which are better handled + by gobject + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 21c09a7ee294b59abb3eca6f64f13bf5c8a2fa0e +Author: Laszlo Pandy +Date: Wed Jan 19 12:00:02 2011 +0100 + + Modify override for Gtk.Adjustment to allow position or keyword + arguments in __init__(). + + Previously passing no arguments was not working, because the default + value for each parameter was None, and GObject.__init__() refuses to + allow None for integer properties. This patch does not pass None up + to GObject.__init__. Instead it does not pass the parameter at all, + and uses the class's default values. + + https://bugzilla.gnome.org/show_bug.cgi?id=639934 + + gi/overrides/Gtk.py | 14 ++++++++++++-- + tests/test_overrides.py | 34 +++++++++++++++++++++++++++------- + 2 files changed, 39 insertions(+), 9 deletions(-) + +commit d465e25297ad6589ff2cd0c00e11e8bd8ffe3f78 +Author: Martin Pitt +Date: Wed Jan 19 22:52:51 2011 +0100 + + [gi] Fix small typo in previous commit + + The GVariant signature of the self test had a trailing 'i'. The + current + GVariant builder doesn't mind, but the new implementation proposed + in bug + 639939 does. + + tests/test_overrides.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2b8e1d0531dcb8f57dc9f2fddf25970bee3daa90 +Author: Martin Pitt +Date: Wed Jan 19 20:18:19 2011 +0100 + + [gi] Add pythonic iterator and indexing for string GVariants + + This extends commit b1a98083c to also work for strings. + + gi/overrides/GLib.py | 8 +++++++- + tests/test_overrides.py | 13 +++++++++++++ + 2 files changed, 20 insertions(+), 1 deletion(-) + +commit 8efd14c87b35072cdd039bf223f8ced8f51be9bb +Author: John (J5) Palmieri +Date: Wed Jan 19 14:08:03 2011 -0500 + + [gi] return NULL if out_marshaller fails + + gi/pygi-invoke.c | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 5b1db41d60204c8021f47f43b85dac126c389c8d +Author: John (J5) Palmieri +Date: Wed Jan 19 13:57:54 2011 -0500 + + [gi] fix some transfer issues and test case failures + + gi/pygi-argument.c | 4 ++++ + gi/pygi-cache.c | 11 ++++++++--- + gi/pygi-invoke.c | 17 +++++++++-------- + 3 files changed, 21 insertions(+), 11 deletions(-) + +commit 7c2f48bb6d67ec9a1ee5ac03a5aee34b54c6ebdd +Author: Tomeu Vizoso +Date: Wed Jan 19 18:09:23 2011 +0100 + + Construct structs using default API constructor + + If the struct has something that looks like a default constructor, + use it instead of trying to directly allocate it, as it will fail + if the struct fields are not exposed. + + https://bugzilla.gnome.org/show_bug.cgi?id=627444 + + gi/pygi-info.c | 37 +++++++++++++++++++++++++++++++++++++ + gi/types.py | 7 +++++++ + 2 files changed, 44 insertions(+) + +commit db7300e173388d9557dcd2333781bfaa6b021605 +Author: Martin Pitt +Date: Wed Jan 19 18:54:39 2011 +0100 + + pygi-convert.sh: Migrate Gdk.Cursor constructor, and some cursor names + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 4c1d4faddf1c9cb233c484da3eadd8e31c231f70 +Author: Martin Pitt +Date: Wed Jan 19 18:43:29 2011 +0100 + + pygi-convert.sh: Handle .window attributes + + In general, convert them to .get_window(). For some of them, prefer + calling the + GtkWidget methods instead. + + pygi-convert.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit b1049b947d073fb569ba900a4d5c8519482d831e +Author: Tomeu Vizoso +Date: Wed Jan 19 17:35:09 2011 +0100 + + Also deal with foreign boxed structs + + cairo.Context has been boxed and our tests started failing + + https://bugzilla.gnome.org/show_bug.cgi?id=639967 + + gi/pygi-argument.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 25b69ae257a12b6dc97ed3f2f7ea54b166ddbba1 +Author: Laszlo Pandy +Date: Wed Jan 19 17:45:11 2011 +0100 + + [gi] Convert GErrors to GObject.GError exceptions, and throw them + upon returning from calling the C function. + + This changes gi to make use of pyglib_error_check() which already + exists in pyglib. + + The included tests make use of the other patch attached to this bug, + to check that the right exception is thrown from the new function + in GIMarshallingTests. + two Gtk C functions. + + https://bugzilla.gnome.org/show_bug.cgi?id=639834 + + gi/Makefile.am | 3 ++- + gi/pygi-invoke.c | 12 +++--------- + tests/test_gi.py | 10 ++++++++++ + 3 files changed, 15 insertions(+), 10 deletions(-) + +commit 18b84767db1d66e3d6f09067ab19ffd4b82539ca +Author: John (J5) Palmieri +Date: Wed Jan 19 12:05:45 2011 -0500 + + [gi] fix out marshalling for a couple of int types + + gi/pygi-argument.c | 2 +- + gi/pygi-cache.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit c5d7c730008275b2c585b2609fc2ff5e051cce47 +Author: John (J5) Palmieri +Date: Wed Jan 19 11:59:09 2011 -0500 + + [gi] fixed range checking and type conversion with unsigned and + large numbers + + gi/pygi-argument.c | 90 + +++++++++++++++++++++++++++++++++++++++++++++--------- + gi/pygi-cache.c | 2 +- + 2 files changed, 76 insertions(+), 16 deletions(-) + +commit e6fcafc6179e963cbae7774e7ee50415bde2c523 +Author: Martin Pitt +Date: Wed Jan 19 17:03:06 2011 +0100 + + pygi-convert.sh: Don't convert glib -> GLib for now + + This currently leads to a load of crashes, MemoryErrors, etc, as + GLib is not + very well introspectable, due to the low-level operations that + it performs. + + John Palmieri confirms that using the static "glib" binding is + preferred for + now, so disable the replacement rules. + + pygi-convert.sh | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +commit 167261d556eab0d2e448c7ed28eef540a024ba1d +Author: Tomeu Vizoso +Date: Wed Jan 19 16:47:08 2011 +0100 + + Link libregress.so to GIO_LIBS again + + configure.ac | 5 +++++ + 1 file changed, 5 insertions(+) + +commit d143afa6da4f5b5f47be8df11fa41d7b47ab1794 +Author: Laszlo Pandy +Date: Wed Jan 19 16:14:42 2011 +0100 + + Fix attributes 2BUTTON_PRESS and 3BUTTON_PRESS of Gdk.EventType. + + This puts an underscore in front of 2BUTTON_PRESS and 3BUTTON_PRESS + because in Python attributes starting with a numeral causes a + syntax error. + + gi/overrides/Gdk.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 4f5d20966d4a8c649e5fae584039621edab178f3 +Author: John (J5) Palmieri +Date: Wed Jan 19 10:02:40 2011 -0500 + + [gi] use correct format stings when setting errors + + gi/pygi-argument.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit 7f08fd5c33ee5c9907f5becbe2f21fb7122d6e19 +Author: John (J5) Palmieri +Date: Wed Jan 19 09:45:09 2011 -0500 + + [gi] allow marshalling strings as None + + gi/pygi-argument.c | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 093242a9e125998cd07bf66fc4b2880f532a2e4d +Author: John (J5) Palmieri +Date: Wed Jan 19 09:41:56 2011 -0500 + + [gi] make error messages more detailed + + gi/pygi-argument.c | 2 +- + gi/pygi-cache.c | 18 +++++++++--------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +commit f0b17605ed2eb917b350654b070984beb553eae3 +Author: John (J5) Palmieri +Date: Wed Jan 19 09:41:13 2011 -0500 + + [gi] allow marshalling None for hashes + + gi/pygi-argument.c | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 93f1b787ab8420300d1064c0237a0c2d8a2ac98f +Author: John (J5) Palmieri +Date: Wed Jan 19 09:40:37 2011 -0500 + + [gi] add marshalling to some out values + + gi/pygi-argument.c | 50 + +++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +commit 614b6ca7f45c4acbee088fe74fecf279ed50cc0c +Author: Sebastian Pölsterl +Date: Wed Jan 19 15:27:33 2011 +0100 + + [gi] Fixed typo in exception + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5f16df31b5a5a9f45f702eee48c3a18899ea3f71 +Author: John (J5) Palmieri +Date: Wed Jan 19 09:13:44 2011 -0500 + + [gi] fix marshalling structs + + gi/pygi-argument.c | 47 +++++++++++++++++++++++++++++++++++------------ + gi/pygi-foreign.c | 18 ++++++++++++------ + gi/pygi-foreign.h | 8 ++++---- + 3 files changed, 51 insertions(+), 22 deletions(-) + +commit b2189424f9dd6d3a4a5b9792f0d5843fc27657d1 +Author: Sebastian Pölsterl +Date: Wed Jan 19 15:12:25 2011 +0100 + + [gi] Enable handling of Gdk.EventType.2BUTTON_PRESS and 3BUTTON_PRESS + + gi/overrides/Gdk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 5eca5ff2c9509ec96158fe43b29f0fd951243efe +Author: Martin Pitt +Date: Wed Jan 19 14:54:57 2011 +0100 + + Revert "Fix Pango FontDescription override" + + According to + http://library.gnome.org/devel/pango/1.28/pango-Fonts.html#pango-font-description-new + the default constructor actually does take no arguments; we should + actually fix + the MemoryError. Add a test case for this. + + Remove the FIXME though, as pango_font_description_from_string() + is not a + FontDescription constructor, but a static factory method. + + Thanks to Paolo Borelli for pointing this out! + + This reverts commit 8878c57676091c08e66bc6cbe735d898cb420582. + + gi/overrides/Pango.py | 5 ++++- + tests/test_overrides.py | 5 +++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +commit 9e7b95b3676a1b502662523a9bd4ebe40ccb4845 +Author: Tony Young +Date: Thu Dec 16 23:39:33 2010 +0000 + + Python iterator interface support for GFileEnumerator. + + gi/overrides/Gio.py | 41 +++++++++++++++++++++++++++++++++++++++++ + gi/overrides/Makefile.am | 1 + + tests/test_overrides.py | 20 ++++++++++++++++++++ + 3 files changed, 62 insertions(+) + +commit bca5834fc8fa342149e0eec7b396877a2abe6d33 +Author: Tomeu Vizoso +Date: Fri Jan 7 12:10:37 2011 +0100 + + Remove gio static bindings + + https://bugzilla.gnome.org/show_bug.cgi?id=638899 + + Makefile.am | 2 +- + configure.ac | 25 - + gio/.gitignore | 3 - + gio/Makefile.am | 117 - + gio/__init__.py | 40 - + gio/gappinfo.override | 213 -- + gio/gapplaunchcontext.override | 99 - + gio/gbufferedinputstream.override | 70 - + gio/gcancellable.override | 38 - + gio/gdatainputstream.override | 250 -- + gio/gdrive.override | 347 -- + gio/gfile.override | 2215 ----------- + gio/gfileattribute.override | 153 - + gio/gfileenumerator.override | 184 - + gio/gfileinfo.override | 121 - + gio/gfileinputstream.override | 68 - + gio/gfileiostream.override | 68 - + gio/gfileoutputstream.override | 68 - + gio/gicon.override | 310 -- + gio/ginputstream.override | 344 -- + gio/gio-types.defs | 807 ---- + gio/gio.defs | 7465 + ------------------------------------- + gio/gio.override | 409 -- + gio/giomodule.c | 208 -- + gio/giostream.override | 68 - + gio/gmemoryinputstream.override | 91 - + gio/gmemoryoutputstream.override | 45 - + gio/gmount.override | 454 --- + gio/goutputstream.override | 292 -- + gio/gresolver.override | 312 -- + gio/gsocket.override | 575 --- + gio/gvolume.override | 237 -- + gio/gvolumemonitor.override | 94 - + gio/pygio-utils.c | 236 -- + gio/pygio-utils.h | 49 - + gio/unix-types.defs | 55 - + gio/unix.defs | 475 --- + gio/unix.override | 62 - + gio/unixmodule.c | 52 - + tests/Makefile.am | 9 - + tests/runtests-windows.py | 3 - + tests/test_gcancellable.py | 15 - + tests/test_gicon.py | 112 - + tests/test_gio.py | 1138 ------ + tests/test_gresolver.py | 68 - + tests/test_gsocket.py | 126 - + 46 files changed, 1 insertion(+), 18191 deletions(-) + +commit 6ab3d8d286573289cf8e41eee31eb806621f6f43 +Author: John (J5) Palmieri +Date: Wed Jan 19 07:56:16 2011 -0500 + + [gi] switch from using (*arg). to arg-> when referencing union + memebers + + gi/pygi-argument.c | 54 + +++++++++++++++++++++++++++--------------------------- + 1 file changed, 27 insertions(+), 27 deletions(-) + +commit 762ccb3d2620ea22023446b6ae79f3a111d8b56a +Author: John (J5) Palmieri +Date: Wed Jan 19 07:49:52 2011 -0500 + + [gi] return FALSE when setting errors in the marshaller + + gi/pygi-argument.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit cbaba6357937cbed3ebd34d2db1cdd59d37df118 +Author: John (J5) Palmieri +Date: Wed Jan 19 07:14:18 2011 -0500 + + [gi] do arg counting in new invoke + + gi/pygi-cache.c | 2 ++ + gi/pygi-cache.h | 14 ++++++++------ + gi/pygi-invoke-state-struct.h | 2 +- + gi/pygi-invoke.c | 20 +++++++++++++++++++- + 4 files changed, 30 insertions(+), 8 deletions(-) + +commit f45033858bed70d7defec3f71f26aa5b3999d680 +Author: John (J5) Palmieri +Date: Wed Jan 19 06:35:45 2011 -0500 + + [gi] set length for uint8 in arrays in new invoke marshaller + + gi/pygi-argument.c | 1 + + 1 file changed, 1 insertion(+) + +commit 09f7ca7e2378e6679002677ac3f4802f4cc7d9d5 +Author: Ignacio Casal Quinteiro +Date: Wed Jan 19 12:04:15 2011 +0100 + + [gi] set length when marshalling guint8 erases + + gi/pygi-argument.c | 1 + + tests/test_gi.py | 4 ++++ + 2 files changed, 5 insertions(+) + +commit 22eee43e50a150ace80694213fb87be9f0c72f51 +Author: Sebastian Pölsterl +Date: Wed Jan 19 10:27:47 2011 +0100 + + Convert Gdk.Pixbuf to GdkPixbuf.Pixbuf + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit a4b210d69c832629894090b7154ae194209b0c60 +Author: Arnaud Charlet +Date: Tue Jan 18 18:31:29 2011 +0100 + + Disable calls to PyGILState_* when threads are disabled + + Since threads may also be disabled in Python too, those symbols + may not + be resolved. + + https://bugzilla.gnome.org/show_bug.cgi?id=374603 + + glib/pyglib.c | 12 ++++++++++++ + gobject/pygobject-private.h | 6 ++++++ + 2 files changed, 18 insertions(+) + +commit 329afb6fb1b3c325a6a9de2b6aca91c64d51dd9f +Author: John (J5) Palmieri +Date: Tue Jan 18 12:31:57 2011 -0500 + + [gi] fix handling of garrays vs c arrays + + gi/pygi-argument.c | 9 +++++++-- + gi/pygi-cache.c | 2 ++ + gi/pygi-cache.h | 1 + + 3 files changed, 10 insertions(+), 2 deletions(-) + +commit a000627ec3904b9414ce375aec8d144fc0c26248 +Author: Martin Pitt +Date: Tue Jan 18 18:29:50 2011 +0100 + + pygi-convert.sh: Do not comment out set_cell_data_func() calls; + these should be ported properly + + pygi-convert.sh | 1 - + 1 file changed, 1 deletion(-) + +commit 99ff4610fb5ece2fc8d2f9eba13e661968adf3f0 +Author: Martin Pitt +Date: Tue Jan 18 18:26:01 2011 +0100 + + pygi-convert.sh: Fix match for adding missing imports + + pygi-convert.sh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 3aa95011fad67df20370e92bf25236a34d7d08d3 +Author: Martin Pitt +Date: Tue Jan 18 18:09:30 2011 +0100 + + pygi-convert.sh: Fix Gtk.Label handling to be idempotent + + As we are not replacing line by line, but the whole file at once, + this is a bit + hackish unfortunately. We can't use a match test or a lookahead/behind + assertion. + + pygi-convert.sh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit f66051380c0432bf142774542ade2144adcd455e +Author: John (J5) Palmieri +Date: Tue Jan 18 11:44:27 2011 -0500 + + [gi] use correct union memeber when marshalling floats + + gi/pygi-argument.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 36bc1c17e7d4189059337cc6a73c64edd819ec12 +Author: Laszlo Pandy +Date: Tue Jan 18 17:29:52 2011 +0100 + + Remove trailing whitespace from gi/overrides/Gtk.py + + gi/overrides/Gtk.py | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +commit 1006df1929a667716c25e74b35b8f14643358732 +Author: John (J5) Palmieri +Date: Tue Jan 18 11:24:06 2011 -0500 + + [gi] fix constructor invoking and add some support for interface + out values + + * constructors are now simplified and are treated like normal + static methods + which happen to return an instance + + gi/pygi-argument.c | 8 ++-- + gi/pygi-cache.c | 132 + +++++++++++++++++++++++++++++++++++++++++++++++++++-- + gi/pygi-invoke.c | 9 ++-- + gi/types.py | 21 +++------ + 4 files changed, 142 insertions(+), 28 deletions(-) + +commit 8878c57676091c08e66bc6cbe735d898cb420582 +Author: Martin Pitt +Date: Tue Jan 18 16:47:10 2011 +0100 + + Fix Pango FontDescription override + + Trying to call __new__() on a record crashes with a MemoryError, + so just call + the intended static factory method for a None argument as well + (which works + just fine now). + + gi/overrides/Pango.py | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit efbbe71634037fa100b17327389b883b259cca54 +Author: Martin Pitt +Date: Tue Jan 18 16:23:39 2011 +0100 + + tests: Respect existing $GI_TYPELIB_PATH + + This allows us to run the test suite against local typelibs. + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c96ca383350e5b9b079d9a86464922314939c006 +Author: John (J5) Palmieri +Date: Tue Jan 18 07:16:40 2011 -0500 + + [gi] fix aux value offsets for methods and element size crashers + + * if the callable is a method we need to add 1 to the aux index + for in values so we grab the right argument cache + * use _pygi_g_type_info_size instead of _pygi_g_type_tag_size to + support all types + + gi/pygi-cache.c | 42 ++++++++++++++++++++++++------------------ + 1 file changed, 24 insertions(+), 18 deletions(-) + +commit f56d85a7f39c2088bf9fd50b1b1e5b67c03104d3 +Merge: 84d6142 7d997b6 +Author: Sebastian Pölsterl +Date: Tue Jan 18 13:14:45 2011 +0100 + + Merge branch 'value' + +commit 7d997b6fe88343776c4d67a9f3437ba0c4122da0 +Author: Sebastian Pölsterl +Date: Tue Jan 18 13:12:36 2011 +0100 + + GTK overrides: Do type conversion to column types of ListStore and + TreeStore in set_value + + gi/overrides/Gtk.py | 28 ++++++++++++++++++---------- + tests/test_overrides.py | 12 +++++++++++- + 2 files changed, 29 insertions(+), 11 deletions(-) + +commit 84d6142c14a7ebfb7284d3db52e14d3393f93905 +Author: Steve Frécinaux +Date: Mon Jan 17 18:57:58 2011 +0100 + + Always register a new GType when a GObject class is subclassed + + This patch makes the GType <-> python mapping much more predictible, + and fixes the bug caused by overriding methods without specifying a + __gtype_name__ member in the subclass, and makes type_register useless + for real :-) + + It is still possible to provide an explicit __gtype_name__ member + in the + subclass as it allows having a predictible GType name, which is handy + for some of our tests. There is also an explicit special case for + overrides because we obviously do not want to register new GTypes for + those ones as it would clearly defeat the purpose of overrides. + + https://bugzilla.gnome.org/show_bug.cgi?id=543056 + + gobject/__init__.py | 6 +++--- + tests/test_gi.py | 21 ++------------------- + 2 files changed, 5 insertions(+), 22 deletions(-) + +commit 30750ccef31e6c864628f418fc00e8c573d29a1b +Author: Simon van der Linden +Date: Tue Jan 18 12:57:13 2011 +0100 + + Raise required versions of GLib and GObject-Introspection + + https://bugzilla.gnome.org/show_bug.cgi?id=612126 + + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 761e98d32729f5894f4c75a54c65ed11329dc9d5 +Author: Martin Pitt +Date: Tue Jan 18 12:52:32 2011 +0100 + + pygi-convert.sh: Handle keysyms + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit d62cdfa38a675c1daf3bc12d5cd769434eea5dc8 +Author: Martin Pitt +Date: Tue Jan 18 12:14:09 2011 +0100 + + GLib overrides: Add test case for array variant building + + tests/test_overrides.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 69a78307f3762e3f54d28d98514cec7d31ff20db +Author: Tomeu Vizoso +Date: Tue Jan 18 10:21:03 2011 +0100 + + Remove cairo.RectangleInt from the foreign module + + https://bugzilla.gnome.org/show_bug.cgi?id=639824 + + gi/pygi-foreign-cairo.c | 96 + ------------------------------------------------- + 1 file changed, 96 deletions(-) + +commit 017680c9a5e163021628bf29543598861a3b600a +Author: Tomeu Vizoso +Date: Tue Jan 18 10:20:25 2011 +0100 + + Dont try to guess the transfer if its a boxed + + https://bugzilla.gnome.org/show_bug.cgi?id=639823 + + gi/pygi-invoke.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 771ef76574690eb98926249f38661d741d1ebbb0 +Author: Ignacio Casal Quinteiro +Date: Tue Jan 18 12:02:01 2011 +0100 + + The tags can be Empty not None. + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b1a98083cdc50653e1d7bfb809bdf089f833df3d +Author: Martin Pitt +Date: Tue Jan 18 12:01:28 2011 +0100 + + Add Pythonic iterators and indexing to GVariant + + Add the usual set of iterators and index accessors to GLib.Variant + objects + which are containers. + + Add corresponding test cases. + + gi/overrides/GLib.py | 50 ++++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 55 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 105 insertions(+) + +commit ecb9f824c503c529d43e585b4cdb4c1c9ab14593 +Author: Martin Pitt +Date: Tue Jan 18 10:48:03 2011 +0100 + + Add GLib.Variant.unpack() + + This method decomposes a GLib.Variant into a native Python object, + i. e. the + counterpart of _VariantCreator. This makes it a lot nicer for + application + developers to use e. g. return values from gdbus calls. + + Add appropriate test case. + + gi/overrides/GLib.py | 45 + +++++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 33 ++++++++++++++++++++++++++++++++- + 2 files changed, 77 insertions(+), 1 deletion(-) + +commit 31c73dee34a52fd22b5ff3a23adce92cea5ddc3d +Author: Ignacio Casal Quinteiro +Date: Tue Jan 18 10:56:18 2011 +0100 + + Add override for gtk_text_buffer_insert_with_tags + + gi/overrides/Gtk.py | 12 ++++++++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 18 insertions(+) + +commit fc7d7f7f153d57ff3866b7bfd5e6479d702cc4d9 +Author: Simon van der Linden +Date: Mon Jan 17 14:35:14 2011 +0100 + + Deduce PYTHON_LIBS in addition to PYTHON_INCLUDES + + https://bugzilla.gnome.org/show_bug.cgi?id=620215 + + gi/Makefile.am | 6 ++++-- + gio/Makefile.am | 2 +- + glib/Makefile.am | 2 +- + m4/python.m4 | 7 +++++-- + tests/Makefile.am | 2 +- + 5 files changed, 12 insertions(+), 7 deletions(-) + +commit bceec758b27e6c396d17a79424633b5dc9116f54 +Author: Simon van der Linden +Date: Mon Jan 17 14:20:55 2011 +0100 + + Kill JD_CHECK_PYTHON_HEADERS + + Use AM_CHECK_PYTHON_HEADERS instead, which is identical. + + https://bugzilla.gnome.org/show_bug.cgi?id=620215 + + configure.ac | 2 +- + m4/python.m4 | 31 +------------------------------ + 2 files changed, 2 insertions(+), 31 deletions(-) + +commit e2dea065da94d17a915abe1ce4671b1dc48e02c0 +Author: Sebastian Pölsterl +Date: Mon Jan 17 19:09:27 2011 +0100 + + Revert "Override Gtk.Box.pack_start and pack_end to set default + values to be compliant with pygtk" + + This reverts commit a8c727b9c4195d8085a45661683a18614ae84485. + + Conflicts: + + gi/overrides/Gtk.py + + gi/overrides/Gtk.py | 10 ---------- + 1 file changed, 10 deletions(-) + +commit 4fbae9629adc166627de05bb0946b71485343d69 +Author: Sebastian Pölsterl +Date: Mon Jan 17 19:08:23 2011 +0100 + + Revert "Override Gtk.CellLayout.pack_start and pack_end to add + default values to be compliant with pygtk" + + This reverts commit 232841148f35684be83a2f47b5b18da4fb74f63a. + + gi/overrides/Gtk.py | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +commit c054f0aca67952876b3519bb75ddc62c5517f7cb +Author: Sebastian Pölsterl +Date: Mon Jan 17 19:08:06 2011 +0100 + + Revert "Override Gtk.TreeViewColumn.pack_start, pack_end and + set_cell_data_func to add default values to be compliant with pygtk" + + This reverts commit ed7e7a8f22b1481acf78c0c2e4c489dbad72f599. + + gi/overrides/Gtk.py | 9 --------- + 1 file changed, 9 deletions(-) + +commit 2d9534f347505573da46743b47318e08bf073aef +Author: Martin Pitt +Date: Mon Jan 17 18:54:10 2011 +0100 + + pygi-convert.sh: Handle gtk.combo_box_new_text() + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 0586a83212a9f9234fe00659ae744ab04e7ccc67 +Author: John (J5) Palmieri +Date: Mon Jan 17 12:31:03 2011 -0500 + + support callbacks + + gi/pygi-argument.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-- + gi/pygi-cache.c | 80 + +++++++++++++++++++++++++++++++++++++++++------------- + gi/pygi-cache.h | 13 +++++++-- + gi/pygi-invoke.c | 2 +- + 4 files changed, 138 insertions(+), 25 deletions(-) + +commit 914d3a0a29680f4d3aa0e1f8afdd625b017b013a +Author: Sebastian Pölsterl +Date: Mon Jan 17 16:57:53 2011 +0100 + + Override TreeSortable.set_sort_func and set_default_sort_func to + add default values to be pygtk compliant + + gi/overrides/Gtk.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit ed7e7a8f22b1481acf78c0c2e4c489dbad72f599 +Author: Sebastian Pölsterl +Date: Mon Jan 17 16:29:28 2011 +0100 + + Override Gtk.TreeViewColumn.pack_start, pack_end and + set_cell_data_func to add default values to be compliant with pygtk + + gi/overrides/Gtk.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 232841148f35684be83a2f47b5b18da4fb74f63a +Author: Sebastian Pölsterl +Date: Mon Jan 17 16:28:51 2011 +0100 + + Override Gtk.CellLayout.pack_start and pack_end to add default values + to be compliant with pygtk + + gi/overrides/Gtk.py | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +commit 1dec12826753756fcadefc8ef8c756fc902c320b +Author: Sebastian Pölsterl +Date: Mon Jan 17 15:54:32 2011 +0100 + + Override Gtk.Paned pack1 and pack2 to add default values to be + compliant with pygtk + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit a8c727b9c4195d8085a45661683a18614ae84485 +Author: Sebastian Pölsterl +Date: Mon Jan 17 15:46:25 2011 +0100 + + Override Gtk.Box.pack_start and pack_end to set default values to + be compliant with pygtk + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 7cc8ac35bb0d8dbf7d66f014f8cd7ff070b3acb8 +Author: Steve Frécinaux +Date: Wed Aug 4 00:30:05 2010 +0200 + + Handle GObject subclasses in the property helper. + + https://bugzilla.gnome.org/show_bug.cgi?id=625982 + + gobject/propertyhelper.py | 26 +++++++++++++------------- + tests/test_properties.py | 9 +++++++++ + 2 files changed, 22 insertions(+), 13 deletions(-) + +commit 7a0548dbfbdfe481f75315b6bc7824a9f1a8a87b +Author: Martin Pitt +Date: Mon Jan 17 17:52:15 2011 +0100 + + Fix handling of unicode for GtkTreeModels + + The code previously converted an unicode object into unicode, but + in Python 2.X + models actually have to specify 'str' (GTK expects a gchararray). So + encode to + UTF-8 instead to get what GTK expects. + + Add corresponding test case. + + gi/overrides/Gtk.py | 2 +- + tests/test_overrides.py | 12 +++++++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +commit 09c21c79fb6063c8451f53d4588363d2be7239f4 +Author: Laszlo Pandy +Date: Mon Jan 17 16:46:08 2011 +0100 + + In IntrospectionModule and DynamicModule classes, make all instance + attributes start with an underscore. + + This changes IntrospectionModule.version to _version and + DynamicModule.introspection_module to _introspection_module. + This is done to mark the attributes as private, and also avoid name + collisions with attributes from the typelib. + In Gstreamer, there is a function gst_version, which was previously + inaccessible because of IntrospectionModule.version overriding it. + + gi/module.py | 26 +++++++++++++------------- + gi/overrides/GIMarshallingTests.py | 2 +- + gi/overrides/GLib.py | 2 +- + gi/overrides/Gdk.py | 10 +++++----- + gi/overrides/Gtk.py | 2 +- + gi/overrides/Pango.py | 2 +- + gi/overrides/__init__.py | 2 +- + tests/test_everything.py | 2 +- + 8 files changed, 24 insertions(+), 24 deletions(-) + +commit 2c70beca9e76e4dc253453c556e6985ce59a3dd9 +Author: Laszlo Pandy +Date: Mon Jan 17 16:17:25 2011 +0100 + + Amend previous enum wrapping commit to remove redundant setting of + __info__ attribute. + + gi/module.py | 2 +- + gi/types.py | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit 6fbb6be5a5d0d9cd43e1504b8dda5aa75feb95ca +Author: Martin Pitt +Date: Mon Jan 17 16:16:45 2011 +0100 + + pygi-convert.sh: Handle GdkPixbuf.InterpType + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 66a5784f4ab5de5b6d8d51eb4ce869fa26f6a601 +Author: Laszlo Pandy +Date: Mon Jan 17 15:43:34 2011 +0100 + + Fix wrapping of enums: Create new Python type for each non-gtype enum. + + Previously non-gtype enums used the same class, which meant they + were all the same type. + This caused another problem that since they were all the same class, + attributes from different enums were available from each other. + + A new test case is created to check for this bug. It requires a new + enum from the GIMarshallingTests (updating gobject-introspection + will be required). + + gi/module.py | 2 +- + gi/types.py | 2 ++ + tests/test_gi.py | 10 ++++++++++ + 3 files changed, 13 insertions(+), 1 deletion(-) + +commit da50d5620a42046d4fc905bb28a0890d73533cb1 +Author: Tomeu Vizoso +Date: Mon Dec 13 18:03:51 2010 +0100 + + Use g_vfunc_info_invoke for chaining up in vfuncs + + https://bugzilla.gnome.org/show_bug.cgi?id=637165 + + gi/pygi-info.c | 4 ++-- + gi/pygi-invoke.c | 72 + +++++++++++++++++++++++++++++++++++++++++++------------- + gi/pygi-invoke.h | 3 ++- + gi/types.py | 28 +++++++++++++++++++++- + tests/test_gi.py | 5 ++-- + 5 files changed, 89 insertions(+), 23 deletions(-) + +commit 8ceef79c98a1c2e22ed8ab655ef1169f1763dd23 +Author: Simon van der Linden +Date: Fri Dec 31 18:38:04 2010 +0100 + + Move pyglib_{main_context, option_context, option_group}_new into + _PyGLib_API + + _PyG{MainContext, OptionContext, and OptionGroup_Type} were not + be initialized + when used inside the glib module, since pyglib_init is not called. + + pyglib.c is compiled as a stand-alone library loaded by the _glib + module that + declares the above-mentioned types. Hence, they cannot be accessed + by the + former. This patch moves the functions that need those symbols + into the + glib._glib module and exports them to the pyglib library through + _PyGLib_API. + + https://bugzilla.gnome.org/show_bug.cgi?id=636656 + + glib/glibmodule.c | 5 ++++- + glib/pyglib-private.h | 3 +++ + glib/pyglib.c | 48 + +++--------------------------------------------- + glib/pygmaincontext.c | 22 ++++++++++++++++++++++ + glib/pygmaincontext.h | 2 +- + glib/pygmainloop.c | 2 +- + glib/pygoptioncontext.c | 21 +++++++++++++++++++++ + glib/pygoptioncontext.h | 2 ++ + glib/pygoptiongroup.c | 26 ++++++++++++++++++++++++++ + glib/pygoptiongroup.h | 2 ++ + glib/pygsource.c | 2 +- + 11 files changed, 86 insertions(+), 49 deletions(-) + +commit 17caffe4eeefeaf33a56ececbc6c7454f60b9d76 +Author: Martin Pitt +Date: Mon Jan 17 14:51:26 2011 +0100 + + pygi-convert.sh: Handle Gdk.DragAction + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit aa390aa80f06ac83ec89e5c5ee143d21ace97917 +Author: Martin Pitt +Date: Mon Jan 17 14:46:58 2011 +0100 + + pygi-convert.sh: Generalize Gtk.Settings migration + + There are other GSettings.get_* functions like get_for_screen(). + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2e6d5bb49425e6087ca61765ecb72e7a760f2ab2 +Author: Martin Pitt +Date: Mon Jan 17 11:22:46 2011 +0100 + + pygi-convert.sh: Don't change the name of "glib" submodules + + This particular affects dbus.mainloop.glib.* + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3887b030fc19d25e0cd7b4ed504f4ed23363c3d6 +Author: Paolo Borelli +Date: Sun Jan 16 22:09:56 2011 +0100 + + Plug another memory leak + + Do not leak interface info in (g|s)_et_property. + + gi/pygi-property.c | 4 ++++ + 1 file changed, 4 insertions(+) + +commit a4950b4cbb3c7567a8586061bb361adb7d9afb98 +Author: Paolo Borelli +Date: Sun Jan 16 21:43:30 2011 +0100 + + Plug a small memory leak. + + Do not leak type_info in find_vfunc_info + + gi/gimodule.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +commit d0cbcc45366d40702c69cef207d3c0f361260c02 +Author: Paolo Borelli +Date: Sun Jan 16 12:16:31 2011 +0100 + + Override Table.attach() to behave like pygtk + + It is fairly common and even gtk itself still has attach_defaults. + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 7 insertions(+) + +commit 6409d659326bf3cefdf6051379e8bc2031f16733 +Author: Martin Pitt +Date: Sat Jan 15 11:20:23 2011 -0600 + + pygi-convert.sh: Convert Pango.WrapMode + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 6aaa6a38198e84a189ca1e8d26b1871d5b6bb711 +Author: Martin Pitt +Date: Sat Jan 15 11:17:09 2011 -0600 + + pygi-convert.sh: Don't change the name of "gtk" submodules + + Some projects have local modules like "myproject.ui.gtk". Avoid + changing those, + just change module names which start with "gtk" or "gdk". + + pygi-convert.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 9be0f1f2dfb89150faf1827ef482feea03645149 +Author: John (J5) Palmieri +Date: Thu Jan 13 23:56:19 2011 -0500 + + [gi] implement aux arg handling for array lengths + + gi/pygi-argument.c | 8 ++++++++ + gi/pygi-cache.c | 36 ++++++++++++++++++++++++++++-------- + gi/pygi-cache.h | 1 - + gi/pygi-invoke.c | 8 ++++++-- + 4 files changed, 42 insertions(+), 11 deletions(-) + +commit cfca2f0a53a5c29f543875ca4cb83a2e18d3bc72 +Author: John (J5) Palmieri +Date: Thu Jan 13 21:07:25 2011 -0500 + + [gi] marshal in hashes + + gi/pygi-argument.c | 93 ++++++++++++++++++++++++++++++++++++++-- + gi/pygi-cache.c | 122 + +++++++++++++++++++++++++++++++++++++---------------- + 2 files changed, 176 insertions(+), 39 deletions(-) + +commit c36fbf4918c8557a8e274a12004a412da3b22b2c +Author: Laszlo Pandy +Date: Tue Jan 11 21:41:47 2011 +0100 + + Fix the __dir__() methods on DynamicModule and IntrospectionModule + + Previously the __dir__() methods did not list all attributes. + A simple test case is included. It does not test to see if + every attribute is listed, it just tests a few of each kind: + - (wrapped) typelib attributes + - class attributes and methods + - instance attributes + + A set() is used to avoid returning duplicate attributes. + The test case checks for this as well. + + https://bugzilla.gnome.org/show_bug.cgi?id=639229 + + gi/module.py | 28 +++++++++++++++++++++------- + tests/test_everything.py | 18 ++++++++++++++++++ + 2 files changed, 39 insertions(+), 7 deletions(-) + +commit 1679e6af3f212e4d4644e048dc3c6177ed3fac6b +Author: Paolo Borelli +Date: Thu Jan 13 00:02:20 2011 +0100 + + pygi-convert.sh: handle ReliefStyle + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit e9166ba5d19f2b586f65a3b83a671a5afd486d8f +Author: John (J5) Palmieri +Date: Wed Jan 12 16:50:30 2011 -0500 + + [gi] support for GList and GSList in + + gi/pygi-argument.c | 122 + ++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 116 insertions(+), 6 deletions(-) + +commit 9baf3240fbac103823ad0feaaf1c82e46d276722 +Author: John (J5) Palmieri +Date: Wed Jan 12 16:24:17 2011 -0500 + + [gi] handle allow_none for all args + + gi/pygi-cache.c | 3 ++- + gi/pygi-cache.h | 1 + + gi/pygi-invoke.c | 7 +++++++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +commit d54d12c66226910952b0dc44c8d9514a7edaa6f2 +Author: John (J5) Palmieri +Date: Wed Jan 12 16:23:02 2011 -0500 + + [gi] fix marshalling fixed arrays + + * get the correct item_size and pass the GArray data not the GArray + + gi/pygi-argument.c | 39 ++++++++++++++++++++++----------------- + gi/pygi-cache.c | 3 ++- + 2 files changed, 24 insertions(+), 18 deletions(-) + +commit 3b0eff80d2ee35e0417476f0a170b9e178e3d1ee +Author: John (J5) Palmieri +Date: Tue Jan 11 17:20:43 2011 -0500 + + [gi] implement out arg handling + + gi/pygi-argument.c | 43 ++++++++++--------------------------- + gi/pygi-cache.c | 22 ++++++++++++++----- + gi/pygi-invoke-state-struct.h | 13 +++++++++++ + gi/pygi-invoke.c | 50 + +++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 89 insertions(+), 39 deletions(-) + +commit bd002c72675d35b5e60ab773181e7c36c30d2625 +Author: Dieter Verfaillie +Date: Tue Jan 11 22:21:18 2011 +0100 + + setup.py: fix the provides keyword argument + + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 59dac72d0fa8e1d68bbbc13d76c2747f1cb11857 +Author: Dieter Verfaillie +Date: Tue Jan 11 22:19:18 2011 +0100 + + setup.py: use the same spaces-less format for all setup() parameters + + setup.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit c5c149be171895d292852df364541f14f0ec423a +Author: John (J5) Palmieri +Date: Tue Jan 11 15:39:09 2011 -0500 + + [gi] implemented return marshalling and started on out marshalling + + gi/pygi-argument.c | 387 + ++++++++++++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-argument.h | 117 ++++++++++++++++ + gi/pygi-cache.c | 316 ++++++++++++++++++++++++++++++++++++++++++- + gi/pygi-cache.h | 8 +- + gi/pygi-invoke.c | 12 +- + 5 files changed, 829 insertions(+), 11 deletions(-) + +commit 4fcca8518774ab89607196dfc52037e3da30ac8a +Author: John (J5) Palmieri +Date: Tue Jan 11 13:49:58 2011 -0500 + + [gi] flesh out interface in marshalling a bit more + + gi/pygi-argument.c | 74 + ++++++++++++++++++++++++++++++++++++++++---------- + gi/pygi-cache.c | 79 + ++++++++++++++++++++++++++++++++++++++++++------------ + gi/pygi-cache.h | 1 + + 3 files changed, 123 insertions(+), 31 deletions(-) + +commit 4992dca9f5cea68d85eb2ed86105c9c6b8311d79 +Author: Laszlo Pandy +Date: Tue Jan 11 19:30:38 2011 +0100 + + Add a __repr__() method to DynamicModule. + + This patch adds a __repr__() method to DynamicModule so that modules + provide a + meaningful string with the typelib path included: + + >>> from gi.repository import Gtk + >>> Gtk + + + https://bugzilla.gnome.org/show_bug.cgi?id=639232 + + gi/module.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit 2ffaec59e7349c145a0e2a5edba2ffb7d8628369 +Author: Tomeu Vizoso +Date: Tue Jan 11 19:40:19 2011 +0100 + + Go back to using getattr() in DynamicModule.__getattr__ + + Breaks marshalling of some types + + gi/module.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 52a298cc0f05ceec96457f17f9a801e9838fb757 +Author: Laszlo Pandy +Date: Tue Jan 11 19:26:50 2011 +0100 + + Change __dir__() to report all the attributes that __getattr__ + supports + + Change DynamicModule.__dir__() to return the local class members as + well as the + typelib attributes. + + Change DynamicModule.__getattr__() to call + IntrospectionModule.__getattr__() + directly, so that it won't inadvertently return class attributes from + IntrospectionModule. + + https://bugzilla.gnome.org/show_bug.cgi?id=639229 + + gi/module.py | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +commit 369a75ba5fb64ff7a7c95d21f8bfe359e639e9ff +Author: John (J5) Palmieri +Date: Mon Jan 10 17:55:03 2011 -0500 + + [gi] add object and interface in marshalling + + * also remove the PyGIArgCleanup sinature as GDestroyNotify works + just fine + + gi/pygi-argument.c | 15 +++-- + gi/pygi-cache.c | 182 + ++++++++++++++++++++++++++++++++++++++++++++++++----- + gi/pygi-cache.h | 1 - + gi/pygi-invoke.c | 1 + + 4 files changed, 178 insertions(+), 21 deletions(-) + +commit 88531c58d0491a31dd319387237a03df5c9edc07 +Author: John (J5) Palmieri +Date: Mon Jan 10 15:33:56 2011 -0500 + + [gi] fix casting when marshaling a char to uint8 + + gi/pygi-argument.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 441da4a7346ca059630dbc820c5b46e4d0222f4b +Author: John (J5) Palmieri +Date: Mon Jan 10 15:07:16 2011 -0500 + + [gi] hook up invoke to the cache + + * We now can invoke with in values + * out, constructors and returns still don't work along with numerous + complex + in types + + gi/Makefile.am | 1 + + gi/pygi-argument.c | 60 +++++++++-------- + gi/pygi-argument.h | 60 ++++++++--------- + gi/pygi-cache.h | 6 +- + gi/pygi-invoke-state-struct.h | 26 ++++++++ + gi/pygi-invoke.c | 149 + ++++++++++++++++++++++++++++++++---------- + gi/pygi-invoke.h | 2 +- + gi/pygi-private.h | 1 + + 8 files changed, 208 insertions(+), 97 deletions(-) + +commit f32b1f494aa5d09b9b198f607722c819c6bbd808 +Author: John (J5) Palmieri +Date: Sun Jan 9 19:37:55 2011 -0500 + + hooked up caching stage and fixed segfaults + + * caching stage is hooked up but not used yet + * throws exceptions for everything that can not be cached yet + + gi/pygi-cache.c | 59 + +++++++++++++++++++++++++++++++++++++++++++------------- + gi/pygi-info.c | 3 +++ + gi/pygi-invoke.c | 5 +++++ + gi/pygi.h | 2 ++ + 4 files changed, 56 insertions(+), 13 deletions(-) + +commit c2bf1d4d9cf2e9f8e313528fe717f6279dad5da1 +Author: John (J5) Palmieri +Date: Sun Jan 9 18:05:31 2011 -0500 + + [gi] fix some function names + + gi/pygi-cache.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 2ec4230a5180f048c26c2e4234b2a098d42f030b +Author: John (J5) Palmieri +Date: Sun Jan 9 15:58:06 2011 -0500 + + [gi] refactor cache structs so they inherit from ArgCache + + gi/pygi-argument.c | 122 +++++++++---------- + gi/pygi-cache.c | 344 + +++++++++++++++++++++++++++++------------------------ + gi/pygi-cache.h | 50 ++++---- + 3 files changed, 273 insertions(+), 243 deletions(-) + +commit f4cdf0c0321285da015686fcb7115bd91bfd5c7c +Author: John (J5) Palmieri +Date: Sat Jan 8 20:45:11 2011 -0500 + + [gi]fix cache compile error - now compiles but cache still not + hooked up + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 100 +++++++++++++++--------------- + gi/pygi-argument.h | 174 + ++++++++++++++++++++++++++++++++++++++++++++--------- + gi/pygi-cache.c | 169 + +++++++++++++++++++++++++-------------------------- + gi/pygi-cache.h | 25 ++++---- + 5 files changed, 293 insertions(+), 177 deletions(-) + +commit 5f8f3044dd8085b2e8ce0bf70e9d52f05abf909d +Author: John (J5) Palmieri +Date: Sat Jan 8 19:10:29 2011 -0500 + + add sequence caching and array marshalling w/ item marshalling + + * simplify what we pass into the arg cache generators so we may + use them + for geneating marshalling caches for container items, not just + arguments + + gi/pygi-argument.c | 76 ++++++++++++++++- + gi/pygi-cache.c | 242 + ++++++++++++++++++++++------------------------------- + gi/pygi-cache.h | 4 +- + 3 files changed, 175 insertions(+), 147 deletions(-) + +commit 202a268db7f98f5a3c525c6e65ec4bff1917257e +Author: Emilio Pozuelo Monfort +Date: Sat Jan 8 02:19:52 2011 +0000 + + Bump the minimum gio dependency + + Needed for G_TYPE_CONVERTER_FLAGS and others. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c3aa36151fdef9ed9884d93114786bbe86387983 +Author: Tomeu Vizoso +Date: Fri Jan 7 12:58:11 2011 +0100 + + Add test for incorrect attributes in Gdk.Event + + tests/test_overrides.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 204b45c7e95eb50d9e3843127fb10e13b1b17fee +Author: Simon van der Linden +Date: Sun Jan 2 19:25:55 2011 +0100 + + Don't call getattr again in gi.overrides.Gdk.Event.__getattr__ + + __getattr__ is only called when the attribute is not found through + the normal + mechanism, so getattr must not be called again in __getattr__ + (which would + create an infinite loop). + + Another possibility would be to implement __getattribute__ instead, + which is + called in place of the normal mechanism. In that case, calling + getattr would be + needed for normal attributes. + + https://bugzilla.gnome.org/show_bug.cgi?id=638523 + + gi/overrides/Gdk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6cf298ca5565d0eb99824f050ff47407e50a5c01 +Author: Mike Gorse +Date: Fri Jan 7 09:08:31 2011 +0100 + + Release allocated array of arguments when handling closures + + https://bugzilla.gnome.org/show_bug.cgi?id=638847 + + gi/pygi-closure.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit 1be76d5e006efa24598ff7bf26153660dbe0a890 +Author: Mike Gorse +Date: Fri Jan 7 09:07:35 2011 +0100 + + Release GIValueInfo when checking an enum argument + + https://bugzilla.gnome.org/show_bug.cgi?id=638847 + + gi/pygi-argument.c | 1 + + 1 file changed, 1 insertion(+) + +commit 43849c51391fc9cd239697065c3d40fa02fb6783 +Author: John (J5) Palmieri +Date: Thu Jan 6 17:30:14 2011 -0500 + + whitespace fixes + + gi/pygi-cache.c | 24 ++++++++++++------------ + gi/pygi-cache.h | 42 +++++++++++++++++++++--------------------- + 2 files changed, 33 insertions(+), 33 deletions(-) + +commit 8b5b3d2bbbbdf5d26c83e9a6fe67121cbd77ebe1 +Author: John (J5) Palmieri +Date: Thu Jan 6 17:29:00 2011 -0500 + + add marshalling for basic types and add more skeleton code + + * still doesn't compile + + gi/pygi-argument.c | 708 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-argument.h | 35 ++- + gi/pygi-cache.c | 82 +++++-- + gi/pygi-cache.h | 41 +++- + 4 files changed, 832 insertions(+), 34 deletions(-) + +commit f554cf62848104d31518138ae85bc51acaafda67 +Author: John (J5) Palmieri +Date: Tue Jan 4 18:49:53 2011 -0500 + + first checkin of the new caching branch + + * this does not compile and is not hooked up to the build system + * lays out the caching data structures and some skeleton functions + + gi/pygi-cache.c | 480 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-cache.h | 104 ++++++++++++ + 2 files changed, 584 insertions(+) + +commit 8d5a7857876669f56bb03bf618bcfdcc290721c0 +Author: Eitan Isaacson +Date: Wed Dec 22 12:34:10 2010 -0800 + + Respect different type lengths when assigning out-argument pointers. + + https://bugzilla.gnome.org/show_bug.cgi?id=637832 + + gi/pygi-closure.c | 66 + ++++++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 56 insertions(+), 10 deletions(-) + +commit f14976ffabec28f6cafe1e37dc81d207a947d4ca +Author: Tomeu Vizoso +Date: Tue Dec 28 18:34:25 2010 +0100 + + Fix stupid name clash + + gi/module.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 01b2a193d403beb861eab524300b4f1af63157ce +Author: Tomeu Vizoso +Date: Tue Dec 28 13:49:18 2010 +0100 + + Add /usr/share to XDG_DATA_DIRS when running the tests + + tests/Makefile.am | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit efc186f692f9eac781cc47456be74a3da7f14dcd +Author: Tomeu Vizoso +Date: Tue Dec 28 13:25:34 2010 +0100 + + Comment out tests that require SRV lookups + + tests/test_gresolver.py | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit d2462cc1ab51d76fb4625c47c3d34de1d5d0dee8 +Author: Tomeu Vizoso +Date: Tue Dec 28 13:00:16 2010 +0100 + + Use suppresion file when running valgrind + + tests/Makefile.am | 2 +- + tests/python.supp | 387 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 388 insertions(+), 1 deletion(-) + +commit 0ee58113ecbea72784c52de928c041fc8fc88984 +Author: Ignacio Casal Quinteiro +Date: Thu Dec 23 00:10:41 2010 +0100 + + Fix warnings. + + gi/pygi-argument.c | 16 +++++++--------- + gi/pygi-foreign-cairo.c | 13 ++----------- + gio/gfile.override | 5 ++--- + glib/pyglib-python-compat.h | 3 +++ + glib/pyglib.c | 2 +- + glib/pygmainloop.c | 3 ++- + 6 files changed, 17 insertions(+), 25 deletions(-) + +commit 78ea84cd91392400ebac5a361ef8793bfe928fd0 +Author: Jesse van den Kieboom +Date: Sun Dec 19 23:10:57 2010 +0100 + + Allow comparing Gtk.TreePath to None + + https://bugzilla.gnome.org/show_bug.cgi?id=637615 + + gi/overrides/Gtk.py | 12 ++++++------ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 12 insertions(+), 6 deletions(-) + +commit 046cc5915286e042d1040271a90676b77632409e +Author: John (J5) Palmieri +Date: Thu Dec 16 15:41:10 2010 -0500 + + handle unicode objects in properties + + * There are still some cavets in Python 2: + - properties are returned as String objects with the unicode + code points + - you must add # coding=utf-8 to the top of your python file + or python + will error out if it sees embeded unicode charaters (such as when + supporting python 3 and python 2 from the same source) + + https://bugzilla.gnome.org/show_bug.cgi?id=620579 + + gobject/pygtype.c | 35 ++++++++++++++++++++++++++--------- + tests/test_properties.py | 16 ++++++++++++++++ + 2 files changed, 42 insertions(+), 9 deletions(-) + +commit 7aa783d5cd674f34da318f826bd5f4a0e09d24cb +Author: Dieter Verfaillie +Date: Tue Dec 14 12:29:54 2010 +0100 + + dsextras.py: check if gcc is there when platform is win32 and compiler + is mingw32 + + dsextras.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit cebf5f09a6c5018ced64f35e7747fc81b93b823e +Author: Dieter Verfaillie +Date: Tue Dec 14 12:29:01 2010 +0100 + + dsextras.py: be consistent in how distutils imports are done + + dsextras.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 35e590d48c78f2e76c47c2b4eaf0f7e8d1ed5c93 +Author: Dieter Verfaillie +Date: Tue Dec 14 12:25:07 2010 +0100 + + dsextras.py: add have_gcc() function + + dsextras.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 637c2c287cfb0e89365026531c651111f5593ac7 +Author: Dieter Verfaillie +Date: Tue Dec 14 12:24:41 2010 +0100 + + dsextras.py: use distutils.spawn.find_executable for have_pkgconfig() + + dsextras.py | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +commit 020d00bc0ce7b77006b4d4f42d63122d79bcbf89 +Author: Dieter Verfaillie +Date: Tue Dec 14 12:22:54 2010 +0100 + + setup.py: fix another case of use True/False instead of 1/0 + + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b03cc9e0d66d8caea3cd6a63db198c43de9267e9 +Author: Paolo Borelli +Date: Mon Dec 13 10:21:52 2010 +0100 + + pygi-convert.sh: improve GtkSourceView conversion + + pygi-convert.sh | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit fbc12cd7c09a67de9e28b7b0b28de9dc0e0e3418 +Author: Paolo Borelli +Date: Mon Dec 13 10:27:56 2010 +0100 + + pygi-convert.sh: Gtk.DialogFlags conversion + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 73e933d2429aea4d14e15350a538da1c5c3f71eb +Author: José Alburquerque +Date: Sun Dec 12 20:38:46 2010 -0500 + + Doc Extractor: Print the gtk-doc blocks sorted by function name. + + * codegen/docextract_to_xml.py: Print the xml of the gtk-doc + block in + alphabetical order according to the identifier (function name) + so that + the generation of xml files in the C++ bindings is deterministic. + Thanks to Krzesimir Nowak for suggesting this in a gtksourceviewmm + recent commit. + + codegen/docextract_to_xml.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit db7ffa75b007074cb6b33b547c6d8140da300a3e +Author: Paolo Borelli +Date: Mon Dec 13 00:17:26 2010 +0100 + + pygi-convert.sh: add more Gtk conversions and sort + + pygi-convert.sh | 50 ++++++++++++++++++++++++++------------------------ + 1 file changed, 26 insertions(+), 24 deletions(-) + +commit f4bfe73d0ccedf7f671d3acd6d9e262d5383b733 +Author: Paolo Borelli +Date: Mon Dec 13 00:01:40 2010 +0100 + + pygi-convert.sh: convert Atk + + pygi-convert.sh | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit e55ce3667eb1d352bf96f265bf018ffe8aea75f9 +Author: Paolo Borelli +Date: Sun Dec 12 23:48:48 2010 +0100 + + pygi-convert.sh: convert a few more Gio types + + pygi-convert.sh | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit acc9f84bc6e13d76c6516cefe393d4a4f868aa24 +Author: Paolo Borelli +Date: Sun Dec 12 14:19:00 2010 +0100 + + pygi-convert.sh: more GLib conversion + + pygi-convert.sh | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit c903390814bebdc62d530472f6f94feecc59b8b3 +Author: Paolo Borelli +Date: Sun Dec 12 14:00:34 2010 +0100 + + pygi-convert.sh: remove two cases handled by overrides + + pygi-convert.sh | 2 -- + 1 file changed, 2 deletions(-) + +commit d33c987e505ec8ddffa2b8cb5526f05b9b5f62be +Author: Paolo Borelli +Date: Sun Dec 12 13:38:56 2010 +0100 + + Override Gtk.ScrolledWindow constructor + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 7 +++++++ + 2 files changed, 14 insertions(+) + +commit 1c24bb089fcd69e3104ae72a0e7560a8c5a3f05b +Author: Paolo Borelli +Date: Sun Dec 12 12:32:39 2010 +0100 + + pygi-convert.sh: Fix 'find' syntax + + pygi-convert.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f0a1d6b6bb53d0fa2788d8b9027d737b0aef8dfc +Author: Paolo Borelli +Date: Sun Dec 12 12:29:38 2010 +0100 + + pygi-convert.sh: start handling Gio and GLib + + pygi-convert.sh | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 365bf3251af3498dc797a58cce071805451b49b1 +Author: Paolo Borelli +Date: Sat Dec 11 23:05:31 2010 +0100 + + pygi-convert.sh: convert Gdk.ScrollDirection. + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit bca603de0f217fb290189a0ea330f82961c46d5d +Author: Paolo Borelli +Date: Sat Dec 11 15:03:21 2010 +0100 + + Override Pango.Layout constructor. + + I must take a Pango.Context argument. Unfortumately the context is + not a + gobject property so we need to jump through some oops. + + gi/overrides/Pango.py | 13 +++++++++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 19 insertions(+) + +commit df233301802e3f7f9ce338cde015ca2a2fc648ab +Author: Paolo Borelli +Date: Sat Dec 11 14:18:53 2010 +0100 + + Remove Pango.FontDescription() conversion. + + It is now properly handled by an override. + + pygi-convert.sh | 1 - + 1 file changed, 1 deletion(-) + +commit d8abcc9463542af9cd43d71849d0ad4c183b570b +Author: Paolo Borelli +Date: Fri Dec 10 14:05:20 2010 +0100 + + Override GtkAction and GtkRadioAction constructors. + + gi/overrides/Gtk.py | 20 +++++++++++++++++--- + tests/test_overrides.py | 18 ++++++++++++++++++ + 2 files changed, 35 insertions(+), 3 deletions(-) + +commit 7924b18a99a0680c04aca46be4b64a7aa507dfe5 +Author: Dmitrijs Ledkovs +Date: Sat Dec 4 22:13:28 2010 +0000 + + Override Adjustment constructor to behave like pygtk + + https://bugzilla.gnome.org/show_bug.cgi?id=636486 + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 9 +++++++++ + 2 files changed, 16 insertions(+) + +commit e76352dd83c8706e68ad57d00d185da9afea99c4 +Author: John (J5) Palmieri +Date: Thu Dec 9 13:23:10 2010 -0500 + + add secondary_text apis to MessageDialog + + gi/overrides/Gtk.py | 8 ++++++++ + tests/test_overrides.py | 8 ++++++++ + 2 files changed, 16 insertions(+) + +commit de682b2d36c362140ab7d43c0743b01ec0865a74 +Author: John (J5) Palmieri +Date: Wed Dec 8 16:39:27 2010 -0500 + + [gi] get rid of some debug prints and fix error messages + + gi/overrides/Gtk.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit dbb16571803bf51f497768bf80944514f4290ee5 +Author: Paolo Borelli +Date: Wed Dec 8 18:25:15 2010 +0100 + + Fix demo for override changes. + + demos/gtk-demo/gtk-demo.py | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 2adcd95762944a4e27123093d3c8d080e49be1ea +Author: Paolo Borelli +Date: Wed Dec 8 18:06:01 2010 +0100 + + Override Pango.FontDescription. + + demos/gtk-demo/gtk-demo.py | 2 +- + gi/overrides/Makefile.am | 1 + + gi/overrides/Pango.py | 40 ++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 7 +++++++ + 4 files changed, 49 insertions(+), 1 deletion(-) + +commit 769da968c9187414d0420412d8fb8c833d12042a +Author: Tomeu Vizoso +Date: Wed Dec 8 17:38:11 2010 +0100 + + Stop checking that all vfuncs are implemented + + Because some methods are optionally implementable but g-i won't + tell us. + + https://bugzilla.gnome.org/show_bug.cgi?id=619606 + + gi/gimodule.c | 4 +++- + gi/types.py | 12 ++---------- + tests/test_gi.py | 10 ---------- + 3 files changed, 5 insertions(+), 21 deletions(-) + +commit 167a01c46b3fa0b3c8339502c875d32bd2bca974 +Author: Paolo Borelli +Date: Wed Dec 8 17:37:00 2010 +0100 + + Fix usage of TreeIter api that is now an override. + + demos/gtk-demo/gtk-demo.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit d2cfd6e9250d40de7c715ac74e299deddf137683 +Author: Paolo Borelli +Date: Wed Dec 8 17:34:54 2010 +0100 + + Fix Gtk.Label(label="Foo") + + Use 'label' as an argument name instead of 'str', otherwise we may + end up up with two 'label' in the kwds dict. Besides 'str' is a + reserved keyword. + + gi/overrides/Gtk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit c0c684c9bb4e2bc08d7cb6ac246705e8a3b77656 +Author: Paolo Borelli +Date: Wed Dec 8 14:16:39 2010 +0100 + + Fix typo when raising an exception + + gi/types.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 88c9a3ad49d9fcf779c3523672d8bf4767910301 +Author: Sebastian Pölsterl +Date: Wed Dec 8 10:46:27 2010 +0100 + + pygi-convert.sh: Added more conversions + + pygi-convert.sh | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit 4d8d96326b2cac91e6d75e6601b92e202d1918ff +Author: Paolo Borelli +Date: Tue Dec 7 20:39:15 2010 +0100 + + Override LinkButton constructor to make 'uri' mandatory + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 13 insertions(+) + +commit f4f7fb35af1b41598dc050f5df155a01c370a920 +Author: Dmitry Morozov +Date: Sat Dec 4 19:19:19 2010 +0600 + + Container should be iterable. + + gi/overrides/Gtk.py | 9 +++++++++ + tests/test_overrides.py | 6 +++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +commit d2ad05d6d8d53b941e0ad33fcb200f1245a2d308 +Author: Paolo Borelli +Date: Tue Dec 7 14:13:00 2010 +0100 + + No need to import Gdk + + gi/overrides/Gtk.py | 1 - + 1 file changed, 1 deletion(-) + +commit b6a40badf0b2b59e690ce818efb03c7c816b8a04 +Author: Paolo Borelli +Date: Tue Dec 7 14:07:53 2010 +0100 + + Remove semicolumns + + gi/overrides/Gtk.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +commit cdc9c26553bf47ea488676e7bdc5f8ab0a2c906b +Author: John (J5) Palmieri +Date: Mon Dec 6 16:05:30 2010 -0500 + + [gi] make sure Gtk.Button override passes all keywords to parent + constructor + + gi/overrides/Gtk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit cede81ad65db017e95543d8d35715751aa202fed +Author: Paolo Borelli +Date: Sun Dec 5 13:31:20 2010 +0100 + + Fix cut&paste error in the Label override + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 607c59b74ebbc1e39cb4121c870b689e1888c106 +Author: Paolo Borelli +Date: Sat Dec 4 16:03:27 2010 +0100 + + pygi-convert.sh: handle TextWindowType + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit dfeabe0b68938e27da2e65903983b5113dc422f1 +Author: Paolo Borelli +Date: Sat Dec 4 15:49:15 2010 +0100 + + Override Label constructor to behave like pygtk + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 4 ++++ + 2 files changed, 11 insertions(+) + +commit da4e045e5abbed2796cc4ed39df35a0dde2de31b +Author: Paolo Borelli +Date: Sat Dec 4 15:40:35 2010 +0100 + + Override GtkTable constructor to behave like pygtk + + gi/overrides/Gtk.py | 7 +++++++ + tests/test_overrides.py | 12 ++++++++++++ + 2 files changed, 19 insertions(+) + +commit 81452c23ab1befa59ff375692e582791432796a5 +Author: Paolo Borelli +Date: Sat Dec 4 12:59:43 2010 +0100 + + pygi-convert.sh: convert MovementStep + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 4d097eea94258eda0c328711491fd456cbd6741b +Author: Paolo Borelli +Date: Sat Dec 4 11:57:02 2010 +0100 + + Update Gdk overrides to work with latest Gtk+ 3 + + For now added consitionals on version == 2.0, but maybe at some + point we + shuld just clean up the old stuff. + + gi/overrides/Gdk.py | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +commit cda317195566711d66190145b545e26ed7226172 +Author: Johan Dahlin +Date: Thu Dec 2 23:47:40 2010 -0200 + + Gtk: add an override for Gtk.main_quit + + Override gtk.main_quit so that it can be used as a callback + to signals, most importantly to the destroy signal of a widget: + + widget.connect('destroy', gtk.main_quit) + + This is compatible with what PyGTK does. + + https://bugzilla.gnome.org/show_bug.cgi?id=636336 + + gi/overrides/Gtk.py | 5 ++++- + gi/overrides/__init__.py | 27 +++++++++++++++++++++++++-- + 2 files changed, 29 insertions(+), 3 deletions(-) + +commit 82689cbf53d92b1b951a459fe3de0e1d3a91791a +Author: John (J5) Palmieri +Date: Thu Dec 2 16:27:04 2010 -0500 + + [gi] handle subtypes when inserting into tree models + + * Often modules will give back basic types wrapped in a subtype. + This is the case with D-Bus where you may want to keep some of the + metadata around. More often than not, the developer is just looking + to use the basetype. + + * This override checks the column type and handles basic types such as + gchararrays, ints, longs, floats and doubles, converting them + to their + base types before sending them to the generic GI type marshaller. + + * More types may need to be supported but these are the common + cases where + apps break. + + https://bugzilla.gnome.org/show_bug.cgi?id=635172 + + gi/overrides/Gtk.py | 38 ++++++++++++++++++++++++++++++++++++-- + tests/test_overrides.py | 8 +++++++- + 2 files changed, 43 insertions(+), 3 deletions(-) + +commit 677490e9402bad7b7c2a832345ef54f7f0c5fc7f +Author: Paolo Borelli +Date: Fri Dec 3 23:39:50 2010 +0100 + + Override TreeSelection.select_path and TreeView.scroll_to_cell + + The "path" argument may also be a string or a tuple + + gi/overrides/Gtk.py | 10 ++++++++++ + tests/test_overrides.py | 29 +++++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+) + +commit dacfe618fa244445c979f1a5efa80c1f9a5a4ae9 +Author: Paolo Borelli +Date: Fri Dec 3 23:29:00 2010 +0100 + + Override TreePath.__new__ + + Instead of having a private _tree_path_from_string it is cleaner to + override __new__ and it will be useful for all the api that take a + TreePath or a string or a tuple. + + gi/overrides/Gtk.py | 33 +++++++++++++++------------------ + tests/test_overrides.py | 18 ++++++++++++++++++ + 2 files changed, 33 insertions(+), 18 deletions(-) + +commit 7a8af9e220ee48aa28f6b025c5dae324b14fe128 +Author: Paolo Borelli +Date: Sun Nov 28 13:02:30 2010 +0100 + + Override Container to behave like a sequence + + gi/overrides/Gtk.py | 6 ++++++ + tests/test_overrides.py | 11 +++++++++++ + 2 files changed, 17 insertions(+) + +commit 94e8befc935d4a6c7f766e34195e10fc3fb3b93a +Author: John (J5) Palmieri +Date: Tue Nov 30 16:57:05 2010 -0500 + + refactor Jonathan Matthew recurse vfunc patch so it applys and clean + up a bit + + * this patch does the recursion using the previous patche's support + functions + + gi/types.py | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 45 insertions(+), 10 deletions(-) + +commit 9c5aee4f06f92457f9ae987656c0c469f76d0ee8 +Author: Jonathan Matthew +Date: Thu Jul 22 23:19:51 2010 +1000 + + Recurse up through base classes when setting up vfuncs + + * this patch adds the support methods to do the recursion + + https://bugzilla.gnome.org/show_bug.cgi?id=625033 + + gi/gimodule.c | 130 + ++++++++++++++++++++++++++++++++++++++++--------------- + tests/test_gi.py | 37 ++++++++++++++++ + 2 files changed, 131 insertions(+), 36 deletions(-) + +commit 78358e1ab54d02317f397276adee03ecb2187588 +Author: John (J5) Palmieri +Date: Mon Nov 29 18:29:57 2010 -0500 + + add a profiling torture test for when we fix up invoke + + tests/test_everything.py | 67 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) + +commit 792e679c06df4357843fd310c7953a931172fc99 +Author: John (J5) Palmieri +Date: Mon Nov 29 16:41:38 2010 -0500 + + moved dynamic and base modules outside of gtk-2.0 directory + + * do not move header files yet as they are mostly used by static + bindings + * do not remove pygtk.pth and pygtk.py files yet - there is a debate + on moving + these back to pygtk but you might want to import gio static + bindings without + having to have pygtk installed + * I have not tested this with pygtk, committing it so we can find + out if it + causes any issues with legacy modules and code + + gi/Makefile.am | 2 +- + gi/overrides/Makefile.am | 2 +- + gi/repository/Makefile.am | 2 +- + glib/Makefile.am | 2 +- + gobject/Makefile.am | 2 +- + tests/test_gi.py | 2 -- + tests/test_overrides.py | 3 --- + 7 files changed, 5 insertions(+), 10 deletions(-) + +commit c587e1ace7429195ac6fd4db03d2f33e2af09838 +Author: John (J5) Palmieri +Date: Mon Nov 29 15:11:46 2010 -0500 + + add test for inout argument count + + tests/test_gi.py | 1 + + 1 file changed, 1 insertion(+) + +commit 5de88b4bcffdafcf8c7c20033cdf95dc690199ce +Author: John (J5) Palmieri +Date: Mon Nov 22 19:17:23 2010 -0500 + + [gi] add check for UNICHAR + + https://bugzilla.gnome.org/show_bug.cgi?id=623615 + + gi/pygi-argument.c | 27 ++++++++++++++++++++++++++- + tests/test_everything.py | 17 +++++++++++++++-- + 2 files changed, 41 insertions(+), 3 deletions(-) + +commit f129b3db2c78d3cce3614993fdd1619fb9eb9c79 +Author: Paolo Borelli +Date: Sun Nov 21 12:16:53 2010 +0100 + + Support gunichar + + https://bugzilla.gnome.org/show_bug.cgi?id=623615 + + gi/pygi-argument.c | 60 + ++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-info.c | 5 ++++ + tests/test_everything.py | 5 ++++ + 3 files changed, 70 insertions(+) + +commit fd2c0288eb67823fca1265348a27a9f8f147ae50 +Author: Paolo Borelli +Date: Sat Nov 27 23:01:42 2010 +0100 + + pygi-convert.sh: gtk.accel_map -> Gtk.AccelMap._ + + pygi-convert.sh | 1 + + 1 file changed, 1 insertion(+) + +commit 13d0ff1d9c129bb458e234b630ebe920b50e2e0f +Author: Paolo Borelli +Date: Sat Nov 27 22:34:13 2010 +0100 + + pygi-convert.sh: handle "from gtk import gdk" + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 63a97634031c3d159ad77fdaa1f6341d7656eb07 +Author: Paolo Borelli +Date: Sat Nov 27 22:23:24 2010 +0100 + + pygi-convert.sh: add some Pango special cases + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 57e42bf4230d1aa20a47e3b0df2e509602333892 +Author: Paolo Borelli +Date: Sat Nov 27 19:51:38 2010 +0100 + + Override TextIter (begins|ends|toggles)_tag() + + Make the tag argument optional. + + gi/overrides/Gtk.py | 9 +++++++++ + tests/test_overrides.py | 17 +++++++++++++++++ + 2 files changed, 26 insertions(+) + +commit 828b698e47ee819a60d24a772a3cc51ff9cd6601 +Author: Paolo Borelli +Date: Sat Nov 27 19:32:48 2010 +0100 + + Override TextBuffer.set_text() to make length optional + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 11 ++++++++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +commit bf55dc862755a57bb1b998702d284fc460e88a30 +Author: Paolo Borelli +Date: Sat Nov 27 16:46:40 2010 +0100 + + Override TextBuffer.create_mark() + + Override create_mark to make the left_gravity argument optional + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 3 +++ + 2 files changed, 6 insertions(+) + +commit 94c0e2f71636d055bdebe3ec378f3d339eea66c9 +Author: Paolo Borelli +Date: Sat Nov 27 16:10:33 2010 +0100 + + Fix TextBuffer.get_selection_bounds() override + + Fix the override and add unit test + + gi/overrides/Gtk.py | 8 +++++--- + tests/test_overrides.py | 7 +++++++ + 2 files changed, 12 insertions(+), 3 deletions(-) + +commit 0cd717e3926276540b9145e58a4a3368136b00de +Author: John (J5) Palmieri +Date: Mon Nov 22 18:35:09 2010 -0500 + + [gi] fix ActionGroup constructor to allow other keyword properties + to be set + + gi/overrides/Gtk.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 226777cdb70fc72d206664ffd8b6737f7239d23f +Author: John (J5) Palmieri +Date: Mon Nov 22 18:32:28 2010 -0500 + + [gi] require the name parameter when creatin a Gtk.ActionGroup + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 2 ++ + 2 files changed, 5 insertions(+) + +commit d0049fa9982d13b3553b05569fb0a227e48b6647 +Author: Paolo Borelli +Date: Sun Nov 21 15:20:58 2010 +0100 + + Override UIManager.insert_action_group + + https://bugzilla.gnome.org/show_bug.cgi?id=635437 + + gi/overrides/Gtk.py | 3 +++ + tests/test_overrides.py | 34 +++++++++++++++++++++------------- + 2 files changed, 24 insertions(+), 13 deletions(-) + +commit e1db544e46aeed984133896af34b671a6a5547df +Author: Paolo Borelli +Date: Sun Nov 21 23:03:25 2010 +0100 + + Override TreeModel.get() to return a tuple + + https://bugzilla.gnome.org/show_bug.cgi?id=635466 + + gi/overrides/Gtk.py | 15 +++++++++++++++ + tests/test_overrides.py | 6 ++++++ + 2 files changed, 21 insertions(+) + +commit a5e806ad8a8b279402ff7adb1c1cdc04f9f3da76 +Author: Paolo Borelli +Date: Sun Nov 21 21:57:40 2010 +0100 + + Make TreeSelection.get_selected_rows compatible with PyGtk + + https://bugzilla.gnome.org/show_bug.cgi?id=635464 + + gi/overrides/Gtk.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 1c537bc67107948c92b51ba6ba749747e84263e2 +Author: John (J5) Palmieri +Date: Mon Nov 22 15:04:00 2010 -0500 + + [gi] switch to using sequences/tuples when marshalling + cairo_rectangle_int_t + + * Upstream pycairo didn't want to add a new wrapper for + cairo_rectangle_int_t + * this works around that issue by using 4 element squences instead + which + should be accepted by pycairo for any API that takes a rect + + gi/pygi-foreign-cairo.c | 85 + +++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 64 insertions(+), 21 deletions(-) + +commit 4cede8f12321bed6c3b71813a62c01b61853ba69 +Author: John (J5) Palmieri +Date: Fri Nov 19 16:46:53 2010 -0500 + + [gi] overrides for treeview Drag and Drop + + https://bugzilla.gnome.org/show_bug.cgi?id=627367 + + gi/overrides/Gdk.py | 7 +++++++ + gi/overrides/Gtk.py | 25 +++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +commit 3fd51bb903724b752f72f49c7cb35652b819791d +Author: John (J5) Palmieri +Date: Fri Nov 19 16:44:32 2010 -0500 + + [gi] when encountering guint8 arrays treat them as byte arrays + + * In Python 2 this means returning a PyString object + * In Python 3 we return a PyBytes object + + https://bugzilla.gnome.org/show_bug.cgi?id=627367 + + gi/pygi-argument.c | 65 + ++++++++++++++++++++++++++++++++++++++++++++---------- + tests/test_gi.py | 6 +++-- + 2 files changed, 57 insertions(+), 14 deletions(-) + +commit 7ddb0f7fd8b1b9e8f691c6d42a83cb16c6561d26 +Author: Martin Pitt +Date: Fri Nov 19 18:19:38 2010 +0100 + + pygi-convert.sh: Add pynotify -> Notify + + pygi-convert.sh | 3 +++ + 1 file changed, 3 insertions(+) + +commit bf03d4db03a7739ac16ddc4e614441557ede554d +Author: Martin Pitt +Date: Fri Nov 19 09:08:07 2010 +0100 + + pygi-convert.sh: Remove sugar specifics, and allow command line + file list + + This script is generally useful for converting pygtk2 projects, + not just for + sugar. Remove the sugar specific bits, since they will just cause + errors. + + Also allow the user to specify the files to convert as command line + arguments. If not given, all *.py files will be processed. + + https://bugzilla.gnome.org/show_bug.cgi?id=635244 + + pygi-convert.sh | 25 +++++-------------------- + 1 file changed, 5 insertions(+), 20 deletions(-) + +commit 18f5d229d3a4b9520c1c456be2635c8e36015c12 +Author: Martin Pitt +Date: Fri Nov 19 09:00:35 2010 +0100 + + pygi-convert.sh: Cover Message and Buttons types + + https://bugzilla.gnome.org/show_bug.cgi?id=635244 + + pygi-convert.sh | 2 ++ + 1 file changed, 2 insertions(+) + +commit ef74273c2043944708515e59a654ebe4944b46ff +Author: John (J5) Palmieri +Date: Thu Nov 18 13:54:48 2010 -0500 + + [gi] fix actiongroup test since actions are hashed + + * when actions are listed they may not show up in the order they + were entered + since they reside in an unordered hash internally + + tests/test_overrides.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit 2c25886bf6710568d0646f82dce4770faa44c40d +Author: John (J5) Palmieri +Date: Wed Nov 17 14:38:09 2010 -0500 + + [gi] when converting to UTF-8 accept Python Unicode objects as input + (Python 2) + + https://bugzilla.gnome.org/show_bug.cgi?id=620579 + + gi/pygi-argument.c | 14 ++++++++++++-- + glib/pyglib-python-compat.h | 5 +++++ + tests/test_gi.py | 3 +++ + 3 files changed, 20 insertions(+), 2 deletions(-) + +commit 8c2d32c8205b971b4353e3d5d2ed1efa6ef0e06c +Author: Damien Caliste +Date: Fri Nov 12 10:20:32 2010 +0100 + + Correct a bug in the freeing of memory in pygi-invoke.c. + + When a method with inout arguments is called from Python with + a wrong number of arguments, the system crashs because of an + assertion fail. This patch corrects this behaviour. + + https://bugzilla.gnome.org/show_bug.cgi?id=634671 + + gi/pygi-invoke.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +commit d9bab3b185bb59bd29e3c3f6225f3636f58ec45e +Author: John (J5) Palmieri +Date: Wed Nov 10 14:11:56 2010 -0500 + + update news for release + + NEWS | 73 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +commit 1338a95339e21cc02b9df6d10166996c8b97a6bf +Author: Jonathan Matthew +Date: Tue Sep 28 13:44:13 2010 +1000 + + Implement richcompare for GIBaseInfo + + https://bugzilla.gnome.org/show_bug.cgi?id=625033 + + gi/pygi-info.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +commit 9ce3edf69824935aeca9e676eaa9782786c22a97 +Author: John (J5) Palmieri +Date: Tue Nov 9 22:57:41 2010 -0500 + + [gi] add the rectangle_int_t forign cairo type + + * the pycairo maintainer is not being responsive so you will need + the patch at + https://bugs.freedesktop.org/show_bug.cgi?id=31111 + * added conditionals, if the api doesn't exist in PyCairo we will + compile + without the forign structs + + gi/pygi-foreign-cairo.c | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 68b8211d8b014cf26ca7e9ab751fb3f61f228290 +Author: John (J5) Palmieri +Date: Mon Oct 25 18:28:36 2010 -0400 + + add a foreign type for cairo_rectangle_int_t and allow it to be + caller-allocated + + * this is needed because Gdk and Gtk switched from returning a + GdkRectangle + to a CairoRectangleInt structure + * the patch in https://bugs.freedesktop.org/show_bug.cgi?id=31111 + is required + for pycairo (however there is currently no patch for python 2) + * added fix for foreign types to allow them to be caller allocated + * in order for a type to be caller allocated it must be able to take + a NULL + and create an empty struct in foreign_struct_from_arg and it must + be able + to handle GI_TRANFER_EVERYTHING in foreign_struct_to_arg. + + https://bugzilla.gnome.org/show_bug.cgi?id=627545 + + gi/pygi-foreign-cairo.c | 57 + +++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-invoke.c | 15 +++++++++++-- + 2 files changed, 70 insertions(+), 2 deletions(-) + +commit ce8b948310220288e9eef904eef4ec8f4e24a376 +Author: John (J5) Palmieri +Date: Tue Nov 9 22:11:51 2010 -0500 + + [gi] add overrides to Gtk.Editable + + gi/overrides/Gtk.py | 17 +++++++++++++++++ + tests/test_overrides.py | 12 ++++++++++++ + 2 files changed, 29 insertions(+) + +commit 87dbc716f26cefc0e9427c3d6e8befe8eabd3d1e +Author: John (J5) Palmieri +Date: Tue Nov 9 21:12:54 2010 -0500 + + [gi] handle virtual invokers + + * right now we check to see if there is an method with the same name + as the virtual method and assume that is the invoker + * some invokers are named different so we now ask the VFuncInfo if + the vfunc has an invoker + * this is still not completly correct, gi needs to support telling + us which vfuncs must be overridden. + * this keeps the old way of checking vfuncs while adding the edge case + where vfunc is named differently from their invoker + + gi/pygi-info.c | 16 ++++++++++++++++ + gi/types.py | 2 +- + 2 files changed, 17 insertions(+), 1 deletion(-) + +commit 540e9f1f349ba3625e28b7673c92210eb8974098 +Author: John (J5) Palmieri +Date: Tue Nov 9 12:17:05 2010 -0500 + + add overrides for the insert* apis of list_store and tree_store + + * add set_row to tree_model as convinience method for both list and + tree stores + + https://bugzilla.gnome.org/show_bug.cgi?id=634423 + + gi/overrides/Gtk.py | 80 + ++++++++++++++++++++++++++++++++++++++----------- + tests/test_overrides.py | 53 +++++++++++++++++++++++++++++++- + 2 files changed, 114 insertions(+), 19 deletions(-) + +commit 0bcb58b9541d9ae52e1d96e6239e9dbe0698872a +Author: John (J5) Palmieri +Date: Fri Nov 5 13:56:12 2010 -0400 + + fix dialogs overrides which were relying on broken inheritance + behavior + + gi/overrides/Gtk.py | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +commit 89c104d17d79d7b935cd76101cba19d49390f7be +Author: John (J5) Palmieri +Date: Thu Nov 4 12:00:14 2010 -0400 + + Add a overrides registry so we can refrence overrides inside the + module + + * Overrides have a reentrancy issue when doing inheritance. If an + override + inherits from another override down the stack it won't see the + override + because the module is not finished loading and will inherit from the + non-overriden object instead. This causes type errors later. + * By adding the overrides to a registry outside of the module we + can order + registration and make the override available as soon as the class + is parsed, + not when the whole module is parsed. + + https://bugzilla.gnome.org/show_bug.cgi?id=633347 + + gi/module.py | 12 ++++++++++- + gi/overrides/GIMarshallingTests.py | 2 +- + gi/overrides/Gdk.py | 2 +- + gi/overrides/Gtk.py | 2 +- + gi/overrides/__init__.py | 43 + ++++++++++++++++++++++++++++++++++++++ + gi/types.py | 8 ------- + tests/test_overrides.py | 27 ++++++++++++++++++++++++ + 7 files changed, 84 insertions(+), 12 deletions(-) + +commit 878b8f630acd2146bee364054acd45cd33eea37a +Merge: cdacaa9 e317838 +Author: John Stowers +Date: Fri Nov 5 11:40:22 2010 +1300 + + Merge remote branch 'dieterv/setup-fixes-for-merge' + +commit e317838178fba5f0590fb8bd323f49602d564b53 +Author: Dieter Verfaillie +Date: Thu Nov 4 11:16:43 2010 +0100 + + setup.py: ease maintenance burden for tests installation + + setup.py | 23 +++-------------------- + 1 file changed, 3 insertions(+), 20 deletions(-) + +commit cdacaa9572893796e0f3aa3730d0191911cb29ee +Author: John (J5) Palmieri +Date: Wed Nov 3 09:51:09 2010 -0400 + + fix inheritence issues in overrides + + gi/overrides/Gtk.py | 79 + +++++++++++++++++++++++++++-------------------------- + 1 file changed, 40 insertions(+), 39 deletions(-) + +commit 3d5955767d81f45e796ab2af0707533375681774 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:38:56 2010 +0100 + + tests: add runtests-windows.py script + + Signed-off-by: Dieter Verfaillie + + tests/runtests-windows.py | 47 + +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +commit 8cb3f2e78161639c568110aad6a807dcf59f3ae8 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:35:52 2010 +0100 + + pygobject_postinstall.py: remove pygobject-2.0.pc treatment from + postinstall as pkg-config on windows figures out the correct prefix + at runtime + + Signed-off-by: Dieter Verfaillie + + pygobject_postinstall.py | 26 +++----------------------- + 1 file changed, 3 insertions(+), 23 deletions(-) + +commit 63167574df53eb481cc11b6a097b2bfe7d5747f5 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:34:38 2010 +0100 + + pygobject_postinstall.py: remove shortcut creation + + Signed-off-by: Dieter Verfaillie + + pygobject_postinstall.py | 35 +---------------------------------- + 1 file changed, 1 insertion(+), 34 deletions(-) + +commit f7b12611f94fd8c27fb67a03746c10149ce6e0ef +Author: Dieter Verfaillie +Date: Wed Nov 3 09:31:14 2010 +0100 + + setup.py: formatting cleanup, makes things readable + + Signed-off-by: Dieter Verfaillie + + setup.py | 56 ++++++++++++++++++++++++++------------------------------ + 1 file changed, 26 insertions(+), 30 deletions(-) + +commit a31b4196fbb4638a245430f2fdeafd7534b1d84d +Author: Dieter Verfaillie +Date: Wed Nov 3 09:28:36 2010 +0100 + + setup.py: build and install tests + + Signed-off-by: Dieter Verfaillie + + setup.py | 61 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +commit 7c3b0c20b83c05833d73c240690dce3daf43fde8 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:26:59 2010 +0100 + + setup.py: install documentation when available on build system + + Signed-off-by: Dieter Verfaillie + + setup.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 78533d851ee1314686f18cfa793613a9cf7d6686 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:25:56 2010 +0100 + + setup.py: install pygobject-codegen script + + Signed-off-by: Dieter Verfaillie + + setup.py | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +commit ad40688df533dda0b1f7be8ea37c542b8796a26b +Author: Dieter Verfaillie +Date: Wed Nov 3 09:24:45 2010 +0100 + + setup.py: install fixxref.py script + + Signed-off-by: Dieter Verfaillie + + setup.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit 21ddfc66e4e18c002a33154eb4ab81170ed71ecc +Author: Dieter Verfaillie +Date: Wed Nov 3 09:23:05 2010 +0100 + + setup.py: rearrange constants + + Signed-off-by: Dieter Verfaillie + + setup.py | 37 ++++++++++++++++++++----------------- + 1 file changed, 20 insertions(+), 17 deletions(-) + +commit 7d353d04892de67265bf693f591f37fd393de639 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:18:11 2010 +0100 + + setup.py: check python version and pkgconig availability before + anything else + + Signed-off-by: Dieter Verfaillie + + setup.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +commit 286364ed39953e942e24d5911519bcac2f90975a +Author: Dieter Verfaillie +Date: Wed Nov 3 09:05:59 2010 +0100 + + setup.py: simplify sys.platform != 'win32' detection and error + reporting + + Signed-off-by: Dieter Verfaillie + + setup.py | 29 +++++++++-------------------- + 1 file changed, 9 insertions(+), 20 deletions(-) + +commit 3f70f92904c123e6cc40929c0affd3f75d061828 +Author: Dieter Verfaillie +Date: Wed Nov 3 09:02:30 2010 +0100 + + setup.py: rearrange imports + + Signed-off-by: Dieter Verfaillie + + setup.py | 31 ++++++++++++++++++++++--------- + 1 file changed, 22 insertions(+), 9 deletions(-) + +commit 9aa54b65f729c0f3b0e96ab7ff797f87dad6a455 +Author: Dieter Verfaillie +Date: Wed Nov 3 08:58:00 2010 +0100 + + README.win32: update build instructions + + Signed-off-by: Dieter Verfaillie + + README.win32 | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +commit 5a33105f690ba84b2e4bb15d73d3467e92fa06e0 +Author: Dieter Verfaillie +Date: Wed Nov 3 07:59:18 2010 +0100 + + dsextras.py: formatting cleanup, makes things readable + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 148 + ++++++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 93 insertions(+), 55 deletions(-) + +commit d03503d0412d173acb383926ab3c2d640dad3e3f +Author: Dieter Verfaillie +Date: Wed Nov 3 07:00:40 2010 +0100 + + dsextras.py: add ggc4 to MSVC compatible struct packing comment + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8c62968e9f8467e24870b8c4f61112676eef4630 +Author: Dieter Verfaillie +Date: Wed Nov 3 06:56:32 2010 +0100 + + dsextras.py: use the pkgc_ functions instead of repeating pgk-config + incantations all over the place + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +commit b98277afc24886bbda400e0ad360992bffa77b7c +Author: Dieter Verfaillie +Date: Wed Nov 3 06:49:48 2010 +0100 + + dsextras.py: add pkgc_get_version and pkgc_get_defs_dir functions + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit a565558652ebc3fa49d7aea40d399b06bbe376c4 +Author: Dieter Verfaillie +Date: Wed Nov 3 06:45:05 2010 +0100 + + dsextras.py: PEP8: Comparisons to singletons like None should always + be done with 'is' or 'is not', never the equality operators. + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 4b1ff0c7f9953f925d2178069263cca67ca7db02 +Author: Dieter Verfaillie +Date: Wed Nov 3 06:44:21 2010 +0100 + + dsextras.py: use True/False instead of 1/0 + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +commit 819a21cea831c3892040390e9446b78a91d1cbbe +Author: Dieter Verfaillie +Date: Wed Nov 3 06:28:04 2010 +0100 + + dsextras.py: rearrange imports + + Signed-off-by: Dieter Verfaillie + + dsextras.py | 58 + +++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 31 insertions(+), 27 deletions(-) + +commit d20edbfdde2819f8d4fee8cb3170c126fcd31d5f +Author: Dieter Verfaillie +Date: Wed Nov 3 06:16:21 2010 +0100 + + Add distutils generated build/dist directories and eclipse + configuration files to .gitignore + + Signed-off-by: Dieter Verfaillie + + .gitignore | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 268d6ed2b0b1d266c612da4453b6117d9e14437e +Author: John (J5) Palmieri +Date: Thu Oct 28 15:32:28 2010 -0400 + + [gi] add tests for calling dir on a dynamic module + + tests/test_gi.py | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +commit f6386a6e0d225c83cdbe1add4c4d3ea51d3ec2f0 +Author: Deepankar Sharma +Date: Wed Oct 27 18:28:11 2010 -0400 + + [gi] dir() now works for modules + + https://bugzilla.gnome.org/show_bug.cgi?id=625093 + + gi/module.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 28ed01c34c503cfb4f14fe7af7912060ca70aba6 +Author: Simón Pena +Date: Mon Sep 20 23:10:14 2010 +0200 + + Don't check the inner type when comparing gpointers + + When using pyg_pointer_richcompare to compare two objects, + don't check their inner types. As we can't compare their private + fields, nor get a proper compare function, we can consider them + gpointers and compare them that way. + + https://bugzilla.gnome.org/show_bug.cgi?id=629552 + + gobject/pygpointer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1731f89e4b5a20c33976963e12a1f39a21d33fde +Author: John (J5) Palmieri +Date: Thu Oct 28 14:21:12 2010 -0400 + + Release GIL when calling into C functions + + Author: Daniel P. Berrange + + https://bugzilla.gnome.org/show_bug.cgi?id=629042 + + gi/pygi-invoke.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit 783e2e351ec7470bda6b441e51f387dd61543c4b +Author: José Aliste +Date: Fri Oct 15 14:30:10 2010 -0300 + + _gi.Repository : Implement missing info bindings. + + https://bugzilla.gnome.org/show_bug.cgi?id=632185 + + gi/pygi-info.c | 91 + +++++++++++++++++++++++++++++++++++++++++++++++++--------- + gi/pygi-info.h | 7 +++++ + 2 files changed, 84 insertions(+), 14 deletions(-) + +commit 2ca897273f52ae38f5e06e72c773a048e199eee5 +Author: John (J5) Palmieri +Date: Thu Oct 28 13:49:15 2010 -0400 + + include Python.h so that PY_VERSION_HEX gets defined + + gi/pygi-foreign-cairo.c | 1 + + 1 file changed, 1 insertion(+) + +commit 8b28b1d713df33931e255600ab98feda37a8e02a +Author: John (J5) Palmieri +Date: Thu Oct 28 13:47:34 2010 -0400 + + [gi] make overrides work for python 3.x protocols and alias for + python 2.x + + gi/overrides/Gtk.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +commit 3c09710d2f68af9c16ce39fd25656147656a486a +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:24:24 2010 +0200 + + Override Gtk.Widget.translate_coordinates to not return success value + + gi/overrides/Gtk.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +commit 9d4443b3de8c327d8645ddde0a7a6dc5b977d7b4 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:22:36 2010 +0200 + + Override Gtk.TreeViewColumn.cell_get_position to not return success + value + + gi/overrides/Gtk.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 6679d39ace06294e98f9d6fc911ed6fb27656010 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:21:36 2010 +0200 + + Override get_path_at_pos and get_dest_row_at_pos of Gtk.TreeView to + not return success value + + gi/overrides/Gtk.py | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 80b1b266fa68a5c67106871502017166628f71e4 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:20:38 2010 +0200 + + Override Gtk.TreeSortable.get_sort_column_id to not return success + value + + gi/overrides/Gtk.py | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit 17cd0fb3a2d2ca0c6109c41727ba0b8c42217cd5 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:19:20 2010 +0200 + + Override forward_search and backward_search of Gtk.TextIter to not + return success value + + gi/overrides/Gtk.py | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +commit 95c86fa31da3d2fe84db0e2b5bc2a6dc896c9223 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:18:09 2010 +0200 + + Override Gtk.TextBuffer.get_selection_bounds to not return success + value + + gi/overrides/Gtk.py | 5 +++++ + 1 file changed, 5 insertions(+) + +commit da6d87460b9392c29d025a7eed9249fb604204bc +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:17:04 2010 +0200 + + Override Gtk.RecentInfo.get_application_info to not return success + value + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 0ed2e8772bdc405b0d0c7e0b2803e0e141abcb6a +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:16:21 2010 +0200 + + Override Gtk.IMContext.get_surrounding to not return success value + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit b85b445f15421209c0b4adf676d7c8218d6437c5 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:15:24 2010 +0200 + + Override get_item_at_pos, get_visible_range, get_dest_item_at_pos + of Gtk.IconView to not return success value + + gi/overrides/Gtk.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit 684d716192d58c972083e579e909bcd97f8a5025 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:13:47 2010 +0200 + + Override Gtk.Container.get_focus_chain to not return success value + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit 8ec830c57fafbfe50d9619c6caba3cb95a00d688 +Author: Sebastian Pölsterl +Date: Sat Oct 23 14:12:44 2010 +0200 + + Override Gtk.ComboBox.get_active_iter to not return success value + + gi/overrides/Gtk.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit b483852904468722230903989e3451c7c6a24c0f +Author: John (J5) Palmieri +Date: Tue Oct 12 12:18:33 2010 -0400 + + [gi] make parameter check less strict when dealing with GValue params + + * Some GValue API can store a pointer to a python object for later + use but our parameter checking was too strict to allow this + * Add pyg_type_from_object_strict API which takes a strict boolean and + returns PY_TYPE_OBJECT if no other GType can be found + * Since we don't have enough info to genrically check GValue + parameters + use the less strict type guessing when encountering a GValue param + * Other API stays the same and continues to do strict testing + + https://bugzilla.gnome.org/show_bug.cgi?id=622987 + + gi/pygi-argument.c | 17 ++++++--------- + gobject/gobjectmodule.c | 4 ++-- + gobject/pygobject-private.h | 1 + + gobject/pygobject.h | 2 ++ + gobject/pygtype.c | 37 +++++++++++++++++++++++++++++---- + tests/test_gi.py | 1 - + tests/test_overrides.py | 50 + +++++++++++++++++++++++++++++++++++++++++---- + 7 files changed, 90 insertions(+), 22 deletions(-) + +commit 8c87d622dcc6d76a981edfc5818fe67bb2e114e2 +Author: John Stowers +Date: Fri Oct 22 13:28:31 2010 +1300 + + Shortcut removal is not needed on post-uninstall + + pygobject_postinstall.py | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +commit a3ed97fe6f80548801739fe6b72771b9eb6d93f7 +Author: John Stowers +Date: Thu Oct 21 13:25:35 2010 +1300 + + Disable shortcut creation in windows installer + + pygobject_postinstall.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a3d6212b0abccef58f05d454c091936776413d98 +Author: John (J5) Palmieri +Date: Thu Oct 7 11:43:27 2010 -0400 + + overrides for all subclasses of dialog + + https://bugzilla.gnome.org/show_bug.cgi?id=631634 + + gi/overrides/Gtk.py | 94 + +++++++++++++++++++++++++++++++++++++++++++++---- + tests/test_overrides.py | 64 ++++++++++++++++++++++++++++++++- + 2 files changed, 151 insertions(+), 7 deletions(-) + +commit a87e3ba64b54e6df0b5b96af47c34e3be790b58f +Author: Sebastian Pölsterl +Date: Thu Oct 7 19:37:53 2010 +0200 + + Make TreeModel behave like in GTK-2.x + + Moved stuff from __getitem__ to get_iter. + Added TreePath.__cmp__ + + get_iter_from_string throws ValueError. + iterchildren() does not return None. + + Adjusted tests to new TreeModel and added TestGtk.test_tree_model + method + + Added support for negative row and column indices + + Use rich comparison methods instead of __cmp__ + + Added TreeModel.__bool__/__nonzero__ + + Raise Error if tree path string is empty + + https://bugzilla.gnome.org/show_bug.cgi?id=631547 + + gi/overrides/Gtk.py | 195 + ++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 160 +++++++++++++++++++++++++++++++++++++-- + 2 files changed, 349 insertions(+), 6 deletions(-) + +commit acfcc29af727fb67d0dfbbcc7cc14963ef21f1ea +Author: John Stowers +Date: Sat Oct 16 18:59:25 2010 +1300 + + Correctly build GIO on windows + + setup.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 33b59fd7437009b6c3ed43412e171d2cc91ee317 +Author: John Stowers +Date: Sat Oct 16 18:17:28 2010 +1300 + + Require Python >= 2.6.0 for Windows build + + setup.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 544e0e4de4f5f97b0584eaf72ae8a081eca28ab6 +Author: John Stowers +Date: Sat Oct 16 17:41:01 2010 +1300 + + Fix depreciation warning in dsextras.py + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 239ff961778e4e1587404d8a70dfbe8630ab0623 +Author: John Stowers +Date: Sat Oct 16 17:34:50 2010 +1300 + + Fix build on windows + + gi/pygi-foreign.c | 5 ++++- + gi/pygi.h | 5 ++++- + setup.py | 4 ++-- + 3 files changed, 10 insertions(+), 4 deletions(-) + +commit 9a2f81d63012fef23fdde2b4d903bd69601c07c6 +Author: Michael Culbertson +Date: Sat Oct 16 17:08:11 2010 +1300 + + Support for GCC4 in Windows distutils build - bug 626548 + + dsextras.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 27367c8dc3a3a31fdd778505b319cd3f4afb9e27 +Author: John Stowers +Date: Fri Oct 15 09:39:02 2010 +1300 + + Remove obsolete comments in dsextras.py + + dsextras.py | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +commit b5f383f854fb8f72677828b029589320c59006d1 +Author: John Stowers +Date: Fri Oct 15 09:21:03 2010 +1300 + + Broken dsextras.py pkg-config check error message + + * Fixes bug 631962 + + dsextras.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e1981da105b574e273ae6500fc6d25caf6af6aae +Author: John (J5) Palmieri +Date: Tue Sep 28 15:31:03 2010 -0400 + + add compat functions for the deprecated PyCObject api + + * Moved to using the PyCapsule API for python >= 3 + * PyCObject is removed from Python 3.2 + * It has also been deprecated in 2.7 but since we use the API in + header files + which are consumed by static binding modules, appling this for + python 2.7 + causes crashes unless the modules are recompiled, breaking ABI. + It is safe + to rely on for 2.7 because it will never be removed and there is + talk of + undeprecating it upstream. + * There is no issues with static bindings under python 3 because + they are not + supported yet and most likely never will be. + * Even if PyCObject is brought back in 3.2, PyCapsule is a much + safer API + which adds a poorman's type check when unboxing. + + https://bugzilla.gnome.org/show_bug.cgi?id=630844 + + gi/gimodule.c | 2 +- + gi/pygi.h | 5 ++++- + glib/glibmodule.c | 2 +- + glib/pyglib-python-compat.h | 28 ++++++++++++++++++++++++++++ + glib/pyglib.c | 6 +++--- + glib/pygoptioncontext.c | 2 +- + gobject/gobjectmodule.c | 2 +- + gobject/pygobject.h | 6 ++++++ + gobject/pygtype.c | 10 +++++----- + 9 files changed, 50 insertions(+), 13 deletions(-) + +commit 03d2e2924e27a9d6cae89e5748f70e0a51be91c6 +Author: Damien Caliste +Date: Tue Sep 28 12:44:42 2010 +0200 + + Add __path__ attributes. + + Add an attribute __path__ to DynamicModule and IntrospectionModule, + using the path of the typelib. + + https://bugzilla.gnome.org/show_bug.cgi?id=630807 + + gi/module.py | 2 ++ + 1 file changed, 2 insertions(+) + +commit 28f9366c9cb382801bad080864f667c867daa3c7 +Author: Sebastian Pölsterl +Date: Sat Oct 9 17:40:40 2010 +0200 + + Override Gtk.TreeSelection.get_selected to not return success value. + + https://bugzilla.gnome.org/show_bug.cgi?id=631765 + + gi/overrides/Gtk.py | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +commit f01a7d9e8222663ce52100e061033f2745a5e7af +Author: Vincent Untz +Date: Thu Oct 7 09:42:24 2010 +0200 + + Make row optional in Gtk.TreeStore/ListStore.append override + + https://bugzilla.gnome.org/show_bug.cgi?id=631548 + + gi/overrides/Gtk.py | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +commit 1e1357f5fa1a034b0b707040d664ac46be6e23f7 +Author: John (J5) Palmieri +Date: Mon Oct 4 12:50:55 2010 -0400 + + Revert "add compat functions for the deprecated PyCObject api" + + This reverts commit f25e763d53e5cdd4de08e90b04aea4b4c4720ac0. + + I ment to commit another patch and ended up comitting both + + gi/gimodule.c | 2 +- + gi/pygi.h | 5 +---- + glib/glibmodule.c | 2 +- + glib/pyglib-python-compat.h | 19 ------------------- + glib/pyglib.c | 6 +++--- + glib/pygoptioncontext.c | 2 +- + gobject/gobjectmodule.c | 2 +- + gobject/pygobject.h | 6 ------ + gobject/pygtype.c | 10 +++++----- + 9 files changed, 13 insertions(+), 41 deletions(-) + +commit 97774cb149c5b03d5ef82a5af3f19e2ce4d79d0b +Author: John (J5) Palmieri +Date: Mon Oct 4 12:43:31 2010 -0400 + + return NULL instead of -1 which fixes crash when introspection is + turned off + + * see https://bugzilla.gnome.org/show_bug.cgi?id=631158 + + gi/pygi.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f25e763d53e5cdd4de08e90b04aea4b4c4720ac0 +Author: John (J5) Palmieri +Date: Tue Sep 28 15:31:03 2010 -0400 + + add compat functions for the deprecated PyCObject api + + * Moved to using the PyCapsule API for python >= 2.7 + + https://bugzilla.gnome.org/show_bug.cgi?id=630844 + + gi/gimodule.c | 2 +- + gi/pygi.h | 5 ++++- + glib/glibmodule.c | 2 +- + glib/pyglib-python-compat.h | 19 +++++++++++++++++++ + glib/pyglib.c | 6 +++--- + glib/pygoptioncontext.c | 2 +- + gobject/gobjectmodule.c | 2 +- + gobject/pygobject.h | 6 ++++++ + gobject/pygtype.c | 10 +++++----- + 9 files changed, 41 insertions(+), 13 deletions(-) + +commit 80b8ccd450fe4e3ea77b27e58bb63cabc2a2bb2b +Author: John (J5) Palmieri +Date: Tue Sep 28 15:28:16 2010 -0400 + + fix commit 7fe83108 which didn't use the compat functions for + string handling + + glib/glibmodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9562842907a9d94f6adae2c1bb20d6b1f189abda +Author: John (J5) Palmieri +Date: Tue Sep 28 13:15:57 2010 -0400 + + Python 3 fixes for dsextras and the python.m4 distribution files + + dsextras.py | 13 +++++++------ + m4/python.m4 | 4 ++-- + 2 files changed, 9 insertions(+), 8 deletions(-) + +commit 98f69957ee9e3037b0a05a037098e4d2133ca256 +Author: John (J5) Palmieri +Date: Mon Sep 27 14:01:31 2010 -0400 + + post release bump to 2.27.0 unstable + + * update hacking to fill in some holes in the release instructions + + HACKING | 6 ++++-- + configure.ac | 2 +- + 2 files changed, 5 insertions(+), 3 deletions(-) + +commit fd38010101411e6bc1ca9314657f418de660fa13 +Author: John (J5) Palmieri +Date: Mon Sep 27 12:03:10 2010 -0400 + + update NEWS for release + + NEWS | 93 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 93 insertions(+) + +commit 7072d56b6cba13da97a052c75d1ae0c2cc417fd1 +Author: Tomeu Vizoso +Date: Sun Sep 26 08:37:31 2010 +0200 + + Pre-release version bump 2.26.0 + + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit a549f429d2ced7a78d5baa5e2f28f6750b4788f2 +Author: John Stowers +Date: Fri Sep 24 22:44:03 2010 +1200 + + Wrap g_get_system_{config,data}_dirs () + + * Also tidy up g_get_{cache,config,data}_dir + to share common code + + glib/glibmodule.c | 68 + ++++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 50 insertions(+), 18 deletions(-) + +commit 328aca600714bdca89dfdb531c222ee561ede27e +Author: John (J5) Palmieri +Date: Fri Sep 24 12:16:22 2010 -0400 + + fixed make check and make dist + + tests/Makefile.am | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +commit 27023fd56148dd17b5576c1e81e0fe851d9b8727 +Author: John Stowers +Date: Fri Sep 24 21:20:53 2010 +1200 + + Disable GI tests when introspection disabled + + tests/Makefile.am | 2 ++ + 1 file changed, 2 insertions(+) + +commit 7fe831081cdd2e26f5d948326b9f89ea0694e752 +Author: Tomeu Vizoso +Date: Sat Jul 18 19:35:08 2009 +0200 + + Wrap g_uri_list_extract_uris. Fixes bug #584431 + + glib/glibmodule.c | 38 ++++++++++++++++++++++++++++++++++++++ + gobject/__init__.py | 2 +- + tests/Makefile.am | 3 ++- + tests/test_uris.py | 15 +++++++++++++++ + 4 files changed, 56 insertions(+), 2 deletions(-) + +commit d6721a59c294f2471142b8c32de2f647b7084bca +Author: Paul Bolle +Date: Thu Sep 23 15:38:40 2010 -0400 + + Fix a few uses of TRUE and FALSE in the docs + + docs/reference/pygio-mount.xml | 5 +++-- + docs/reference/pyglib-functions.xml | 18 +++++++++--------- + docs/reference/pyglib-maincontext.xml | 12 ++++++------ + docs/reference/pyglib-mainloop.xml | 6 +++--- + docs/reference/pygobject-functions.xml | 6 +++--- + docs/reference/pygobject.xml | 4 ++-- + 6 files changed, 26 insertions(+), 25 deletions(-) + +commit a08c9fffb4262ae678e17f90bbfb2d5f880cfad0 +Author: Damien Caliste +Date: Tue Sep 21 17:52:14 2010 +0200 + + pygi: always free the invocation_state struct + + In pygi-invoke.c, the invocation_state struct is never freed + in case of success. Thus, always call _free_invocation_state() + before leaving. + Modify _free_invocation_state to avoid double free in case of + caller-allocated GValue, once as a released argument in the + _process routine and another time in the _free as the special + case. So move all argument releasing code from the _process + routine to the _free one. + Modify the tests for the callback routines to return an integer + value as specified in the GIR file. + + Make check is as successful as before (already existing error + related to GVariant is still there). + + https://bugzilla.gnome.org/show_bug.cgi?id=630271 + + gi/pygi-invoke.c | 83 + +++++++++++++++++++++--------------------------- + tests/test_everything.py | 4 ++- + 2 files changed, 40 insertions(+), 47 deletions(-) + +commit 9714d765a34e246899f11b6792eea3aecce0b7ec +Author: Tomeu Vizoso +Date: Mon Sep 13 16:36:47 2010 +0200 + + Start implementing something equivalent to g_variant_new + + https://bugzilla.gnome.org/show_bug.cgi?id=629367 + + gi/gimodule.c | 20 +++++++ + gi/overrides/GLib.py | 131 + ++++++++++++++++++++++++++++++++++++++++++--- + gi/pygi-foreign-gvariant.c | 2 +- + tests/test_everything.py | 16 ------ + tests/test_overrides.py | 25 +++++++++ + 5 files changed, 170 insertions(+), 24 deletions(-) + +commit fc45abdd9b55ab63556798ab0f04715be79dba08 +Author: John (J5) Palmieri +Date: Thu Sep 23 10:49:36 2010 -0400 + + fixed typo - missing comma in glib.option module + + * https://bugzilla.gnome.org/show_bug.cgi?id=627449 + + glib/option.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4ed100f3183c6325dd04461484e877bb7d4131b1 +Author: John (J5) Palmieri +Date: Fri Sep 17 12:08:09 2010 -0400 + + add checks so we can compile under python 3 by setting PYTHON=python3 + + * compile for python 3 + * disables gio if compiling under python 3.x + * runs only pertinant tests + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + configure.ac | 32 +++++++++++++++++++++++++++++--- + tests/Makefile.am | 35 ++++++++++++++++++++--------------- + tests/runtests.py | 4 ++++ + 3 files changed, 53 insertions(+), 18 deletions(-) + +commit 269ff8564eeb597dc06c27e293354b7ff7a71a82 +Author: Tomeu Vizoso +Date: Fri Sep 17 15:50:47 2010 +0200 + + Rename static methods as functions + + In recent gobject-introspection releases, static methods have been + removed and placed as functions in the namespace level. In a future + releases it's planned to become static methods again but for now + let's fix the tests. + + tests/test_gi.py | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit 2da8da589644d6125101210712defb1272a8abb1 +Author: John (J5) Palmieri +Date: Thu Sep 9 13:52:14 2010 -0400 + + fix a couple of compiler warnings + + https://bugzilla.gnome.org/show_bug.cgi?id=629199 + + gi/pygi-argument.c | 4 ++-- + gi/pygi-struct.c | 2 +- + gobject/gobjectmodule.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +commit 6769a4704f0876ac3baacd4da03ff16d9f0906be +Author: John (J5) Palmieri +Date: Thu Sep 9 13:55:17 2010 -0400 + + remove unused code + + * we use richcompare now + + https://bugzilla.gnome.org/show_bug.cgi?id=629198 + + gobject/pygtype.c | 9 --------- + 1 file changed, 9 deletions(-) + +commit 98f54f9d33996baeaa8c8c1240310f5396d03a1d +Author: John (J5) Palmieri +Date: Tue Sep 14 14:10:49 2010 -0400 + + Check the type of the instance object + + * in python 2 methods were added to classes as unbound methods and + they would + check the instance type to make sure it was correct + * in python 3 for perfomance reasons methods are added to classes + as simple + functions which treat the instance as an untyped argument so + no checks + are made. + * this patch adds a type check so that the correct errors are + thrown in + python 3 (python 2 this just adds another layer of redundancy should + something change with type checking in the future) + * since GI handles regular args and the instance arg slightly + differently + we had to split out the interface checks in + _pygi_g_type_info_check_object + in order to not duplicate code + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-argument.c | 182 + ++++++++++++++++++++++++++++------------------------- + gi/pygi-argument.h | 2 + + gi/pygi-invoke.c | 14 +++++ + 3 files changed, 112 insertions(+), 86 deletions(-) + +commit 5d79498d38b147b66ae72c1481e397160491e8d6 +Author: John (J5) Palmieri +Date: Wed Sep 15 10:26:20 2010 -0400 + + include the correct pycairo version + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-foreign-cairo.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit b855562e5c0019cd7e4982fe00c467ede9e3926d +Author: John (J5) Palmieri +Date: Thu Sep 9 22:16:58 2010 -0400 + + Use PyMapping_Keys to determine if an object is a dict (py3k fix) + + * in Py3k PyMapping_Check returns true for sequences such as strings + and lists. Since we need to get the keys anyway, and it returns + NULL if this is not a dict, this is a much better test, even in + Py2 + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-argument.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +commit 0e72e28c6c5502c7db5103cf1299c9f0e6689fdd +Author: John (J5) Palmieri +Date: Thu Sep 9 18:44:11 2010 -0400 + + fix handling of UINT64 and INT64 arguments in py3k + + * decode to the right sized C long + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-argument.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +commit d5666d99a1c0396b7da0cb14f9f4ff8892da7e2e +Author: John (J5) Palmieri +Date: Thu Sep 9 17:35:10 2010 -0400 + + properly handle ulongs properties in py3k + + * If this is a PyLong object pull use AsUnsignedLong + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gobject/pygtype.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +commit 3d431c7dd0de97db10cb0c00c39d9c1837bed2f2 +Author: Tomeu Vizoso +Date: Fri Sep 17 12:14:56 2010 +0200 + + Specify encoding of tests/test_gi.py + + tests/test_gi.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit a808bdabb9fa6f4a9b9ce42e1cce05fb37403f0f +Author: John (J5) Palmieri +Date: Thu Sep 9 13:24:30 2010 -0400 + + use actual unicode in the tests on py3k, not the byte representation + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + tests/test_gi.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +commit 928f4485041d80d0c36ff2daeae4bcd09bd0bde4 +Author: John (J5) Palmieri +Date: Thu Sep 9 12:45:21 2010 -0400 + + s/METH_KEYWORDS/METH_VARARGS|METH_KEYWORDS/ when defining object + methods + + * in Py3k the METH_KEYWORDS flag by itself is invalid. A method + must be defined + with both the METH_VARARGS and METH_KEYWORDS flags. + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/pygiochannel.c | 30 +++++++++++++++--------------- + glib/pygsource.c | 4 ++-- + gobject/pygobject.c | 2 +- + 3 files changed, 18 insertions(+), 18 deletions(-) + +commit b5ee20afa4399c7689fbec8939fa20b927eeb782 +Author: John (J5) Palmieri +Date: Thu Sep 9 08:04:40 2010 -0400 + + fix subclassing PyLong by calling __new__ correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/pygspawn.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit a499b2f0d622b671bd154544f66b73f1278e66ed +Author: John (J5) Palmieri +Date: Thu Sep 9 07:56:44 2010 -0400 + + minor py3k fixups for python modules + + * add _basestring and _bytes and _callable wrappers + * use items instead of iteritems and range instead of xrange + + fix py3k modules + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/overrides/Gtk.py | 24 ++++++++++++++++-------- + glib/option.py | 16 ++++++++++++---- + 2 files changed, 28 insertions(+), 12 deletions(-) + +commit dec9001d26c97949e7b3578086cb35e98075c047 +Author: John (J5) Palmieri +Date: Thu Sep 9 07:36:04 2010 -0400 + + minor fixes in tests for py3k compat + + * add a _bytes wrapper for API that expects bytes in py3k but str + in py2 + * fix some more exception handling using sys.exc_info()[:2] + * use range instead of xrange, items instead of iteritems since py3k + dropped support for the different ways of accessing iterators + - this is less efficient in py2 but we plan to target py3k as the + primary platform + * use list(dict.items()) since py3k only returns iterables which + are not + indexable + * missed some _long wrapping + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + tests/compathelper.py | 18 ++++++++++++++++++ + tests/test_everything.py | 5 +++-- + tests/test_mainloop.py | 3 ++- + tests/test_option.py | 6 ++++-- + tests/test_overrides.py | 4 ++-- + tests/test_properties.py | 6 +++--- + 6 files changed, 32 insertions(+), 10 deletions(-) + +commit 09a0daeedf49eaf376c1288be5743b57fbc76d51 +Author: Colin Walters +Date: Thu Sep 9 16:25:51 2010 -0400 + + compilation: Fix syntax error + + gi/pygi-info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9f7afd6d5afd8c1a5f36bf1295814757b71c8cbc +Author: Tomeu Vizoso +Date: Thu Sep 9 22:17:00 2010 +0200 + + Add missing file + + gi/overrides/GLib.py | 48 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +commit 306b792ac97a458ddee59fb86d66453495117f3e +Author: Tomeu Vizoso +Date: Thu Jul 22 13:48:51 2010 +0100 + + Add override for GLib.Variant.new_tuple + + * gi/gimodule.c: Add _wrap_pyg_variant_new_tuple + * gi/overrides/GLib.py: Override Variant.new_tuple and + Variant.get_string + * gi/pygi-type.[hc]: split _pygi_type_import_by_name out from + _pygi_type_import_by_gi_info + * gi/types.py: Never override gobject.TYPE_NONE + * tests/test_everything.py: Add tests for GVariant tuples + + https://bugzilla.gnome.org/show_bug.cgi?id=625050 + + gi/gimodule.c | 38 ++++++++++++++++++++++++++++++++++++++ + gi/overrides/Makefile.am | 1 + + gi/pygi-type.c | 15 +++++++++------ + gi/pygi-type.h | 2 ++ + gi/types.py | 1 + + tests/test_everything.py | 9 +++++++++ + 6 files changed, 60 insertions(+), 6 deletions(-) + +commit 22e53aa2ed9cf6173a877b0af6928d5ab8da2f4f +Author: John (J5) Palmieri +Date: Wed Sep 8 13:08:48 2010 -0400 + + fix for changes in the gi test libraries + + tests/test_everything.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 246877074617b0e9c3b2ba2a5395a73e0ed9cd5d +Author: John (J5) Palmieri +Date: Wed Sep 8 13:08:07 2010 -0400 + + Gtk.DialogFlags.NO_SEPARATOR has been removed in Gtk 3.0 + + gi/overrides/Gtk.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit f92fc48e7e2ec50996e994ccb7d08a61e7374f22 +Author: John (J5) Palmieri +Date: Wed Sep 8 12:35:09 2010 -0400 + + no need to offset arg positions when is_method is true + + * The old GI libraries required we offset arg positions for the + missing + self argument. The new library fixes this so we don't have + to offset + anymore. + + https://bugzilla.gnome.org/show_bug.cgi?id=629087 + + gi/pygi-callbacks.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +commit 8c517de2d278bdef641c72b8f2919a3924290ec1 +Author: Tomeu Vizoso +Date: Fri Aug 20 14:54:35 2010 +0200 + + gi: Add support for more property types + + https://bugzilla.gnome.org/show_bug.cgi?id=627494 + + gi/pygi-property.c | 156 + ++++++++++++++++++++++++++++++++++++----------- + tests/test_everything.py | 34 +++++++++++ + 2 files changed, 154 insertions(+), 36 deletions(-) + +commit 6d183d1fff55d54569ba3e1f90a10284df74fd40 +Author: John (J5) Palmieri +Date: Fri Sep 3 12:04:16 2010 -0400 + + use PyObject_SetAttrString, not PyDict_SetItemString when setting + __gtype__ + + * When registering a gtype wrapper we used to set tp_dict + directly. This works + in python 2 but python 3 seems to handle attributes in a slightly + different + way where the tp_dict and attr get out of sync. By setting the attr + directly we avoid this issue. + * Note that there are many more places where we set __gtype__ + using tp_dict + however for objects which are not instantiated yet we have to + set tp_dict + directly. + * Since this one change fixes a lot of failed tests, for now we + ignore the + other places where we set __gtype__. If we run into more issues + dealing + with __gtype__ we can take a closer look later. + + https://bugzilla.gnome.org/show_bug.cgi?id=627878 + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gobject/gobjectmodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b7bf4269682a3335f5e0a52b46fa721af134d09a +Author: Tomeu Vizoso +Date: Wed Sep 1 11:03:40 2010 +0200 + + Rename GArgument to GIArgument + + gi/pygi-argument.c | 52 + +++++++++++++++++++++++----------------------- + gi/pygi-argument.h | 10 ++++----- + gi/pygi-closure.c | 34 +++++++++++++++--------------- + gi/pygi-foreign-cairo.c | 8 +++---- + gi/pygi-foreign-gvariant.c | 4 ++-- + gi/pygi-foreign-gvariant.h | 4 ++-- + gi/pygi-foreign.c | 12 +++++------ + gi/pygi-foreign.h | 8 +++---- + gi/pygi-info.c | 8 +++---- + gi/pygi-invoke.c | 28 ++++++++++++------------- + gi/pygi-property.c | 4 ++-- + gi/pygi.h | 16 +++++++------- + 12 files changed, 94 insertions(+), 94 deletions(-) + +commit 7197f85c9be2b03636639ac909ca2c3170653509 +Author: John (J5) Palmieri +Date: Wed Aug 18 10:29:19 2010 -0400 + + fix up tests so they run in py3k + + * add a compat helper that should only be used by tests + * fix long notation to use the compat helper instead + * add parens to print statements + * use compatable try/except pattern + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gobject/propertyhelper.py | 16 +++++++++++----- + tests/compathelper.py | 32 ++++++++++++++++++++++++++++++++ + tests/test_option.py | 7 ++++++- + tests/test_properties.py | 24 ++++++++++++++---------- + tests/test_signal.py | 14 +++++++------- + tests/test_source.py | 4 ++-- + 6 files changed, 72 insertions(+), 25 deletions(-) + +commit 720e614acdbcf734d4bcccc403e639b5a5bcae24 +Author: Colin Walters +Date: Fri Aug 20 10:58:48 2010 -0400 + + tests: Port to new introspection tests + + Everything is renamed "Regress", and both it and GIMarshallingTests + are now in source form, so we compile them. + + The scanner now adds "static methods" to objects, structs, and unions, + so update the test code to use those. + + In the tests, remove broken (inout) cases - the person writing these + tests misunderstood the semantics of (inout). It's not acceptable for + a C API to mutate e.g. a GSList* passed in, or unref an object. + + The invocation code needed to be updated for this - remove some + broken hacks. + + https://bugzilla.gnome.org/show_bug.cgi?id=627878 + + configure.ac | 5 +- + gi/pygi-argument.c | 9 +-- + gi/pygi-invoke.c | 147 + +++++---------------------------------------- + tests/Makefile.am | 42 ++++++++++++- + tests/test_everything.py | 6 +- + tests/test_gi.py | 151 + +++++++++-------------------------------------- + 6 files changed, 93 insertions(+), 267 deletions(-) + +commit f6c4d9e58c8f05cb2d82e158c9eb8480308565bd +Author: John (J5) Palmieri +Date: Fri Aug 20 10:43:58 2010 -0400 + + we need to specify tp_hash since we overide tp_richcompare + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gobject/pygenum.c | 1 + + gobject/pygflags.c | 1 + + 2 files changed, 2 insertions(+) + +commit c03e6b482548aee99362356807c804f8834fad2b +Author: John Ehresman +Date: Thu Apr 15 17:11:30 2010 -0400 + + working enum/flags/pid subclasses of long + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/pygspawn.c | 7 ++--- + gobject/pygenum.c | 61 ++++++++++++++++++++++++------------------- + gobject/pygflags.c | 76 + +++++++++++++++++++++++------------------------------- + 3 files changed, 71 insertions(+), 73 deletions(-) + +commit 0db676fd2296750a46ba0fb069e472da06ecc53a +Author: John (J5) Palmieri +Date: Wed Aug 18 11:03:32 2010 -0400 + + make vfuncs work in py3k + + * methods now export __func__ instead of im_func for getting the + function + out of a method closure + * however classes no longer return unbound methods in py3k and instead + return the actual function + * in python 2 we use im_func when getting the function from the + vfunc closure + * in py3k we simply assign vfunc to the function + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/types.py | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +commit 286dcd0c6455961d818ac7f05f80f82435abc1dc +Author: John (J5) Palmieri +Date: Tue Aug 17 15:43:42 2010 -0400 + + make cairo module compile in py3k + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/Makefile.am | 2 +- + gi/pygi-foreign-cairo.c | 17 +++++++---------- + 2 files changed, 8 insertions(+), 11 deletions(-) + +commit bda58ec34fc443fe1108afc8532bec50f6fd0b44 +Author: John (J5) Palmieri +Date: Tue Aug 17 02:33:45 2010 -0400 + + fix exceptions so they work in python 3.x + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/module.py | 2 +- + gi/types.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 427a3c8053feca35ccd746575760ac8a0ed50a12 +Author: John (J5) Palmieri +Date: Tue Aug 17 02:24:44 2010 -0400 + + make the gi module compile under 3.x + + * include the compat macros + * use GLIB_MODULE_START/END to define module + * add PyInit__gi to the exported symbols + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/Makefile.am | 2 +- + gi/gimodule.c | 24 +++++++++--------------- + 2 files changed, 10 insertions(+), 16 deletions(-) + +commit 1dee5dcd2b1747b4a4af438c0443d7930e4802db +Author: John (J5) Palmieri +Date: Tue Aug 17 02:14:14 2010 -0400 + + fix up testshelper module so it compiles in python 3.x + + * include the compat header + * fix up PyInts to be PYGLIB_Long + * Use PYGLIB_DEFINE_TYPE macros to define module objects + * Use PYGLIB_MODULE_START/END to define modules + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + tests/Makefile.am | 2 +- + tests/testhelpermodule.c | 221 + ++++++----------------------------------------- + 2 files changed, 28 insertions(+), 195 deletions(-) + +commit 1ff83a2ccb7301c8f675913f1c4f6118ea50b9c7 +Author: John (J5) Palmieri +Date: Mon Aug 16 21:14:27 2010 -0400 + + convert to using PYGLIB_DEFINE_TYPE for module objects + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-boxed.c | 43 ++----------- + gi/pygi-info.c | 171 + ++++++++++++++++++++------------------------------- + gi/pygi-repository.c | 39 +++--------- + gi/pygi-struct.c | 45 +++----------- + 4 files changed, 88 insertions(+), 210 deletions(-) + +commit 1efa2b12913b194d433c17014bc1077271a6ca32 +Author: John (J5) Palmieri +Date: Mon Aug 16 13:51:05 2010 -0400 + + some more p3k PyString and PyInt eradication in GI + + * add the glib dir to the includes list in the build + * make sure we include the compat macros + * add GLIB_PyBytes_FromString to compat macros + * add GLIB_PyNumber_Long to compat macros + * use RichCompare instead of Compare + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/Makefile.am | 2 +- + gi/pygi-argument.c | 96 + +++++++++++++++++++++++++++------------------ + gi/pygi-boxed.c | 1 + + gi/pygi-info.c | 13 +++--- + gi/pygi-private.h | 23 +++++++++++ + gi/pygi-repository.c | 8 ++-- + gi/pygi-struct.c | 1 + + glib/pyglib-python-compat.h | 6 +++ + 8 files changed, 103 insertions(+), 47 deletions(-) + +commit 6b902c66200c1684513a9ef31bdef3f2ff64e4fa +Author: Tomeu Vizoso +Date: Fri Aug 20 09:28:57 2010 +0200 + + pyglib: Fix typo (Leo Singer) + + https://bugzilla.gnome.org/show_bug.cgi?id=627408 + + glib/option.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 3cefffecc1317b6ad77a5ed936bfb990d16bf9d3 +Author: Gustavo Noronha Silva +Date: Thu Aug 19 18:45:05 2010 -0300 + + Add defines for size_t and ssize_t conversion functions + + These missing defines cause the resulting module to have unresolved + symbols, rendering it unusable. + + https://bugzilla.gnome.org/show_bug.cgi?id=627440 + + glib/pyglib-python-compat.h | 2 ++ + 1 file changed, 2 insertions(+) + +commit d45c7031876f355e15409f00f3e50e77d18f8f4b +Author: Colin Walters +Date: Thu Aug 19 17:50:35 2010 -0400 + + pyglib: Fix a compiler warning + + glib/pyglib.c | 1 + + 1 file changed, 1 insertion(+) + +commit 0fe6828ddce187ac1897a1f02ca1c5480796d5b9 +Author: Tomeu Vizoso +Date: Wed Aug 18 20:36:51 2010 +0200 + + Don't force gtk 2.0 + + pygi-convert.sh | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +commit ac59c18a4f2bfff47c862b763aaf1d1cf136a4f5 +Author: Steve Frécinaux +Date: Tue Aug 17 14:49:30 2010 +0200 + + Fix some ref leaks in hook_up_vfunc_implementation() + + https://bugzilla.gnome.org/show_bug.cgi?id=627143 + + gi/gimodule.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +commit 18ee0db673c2fa42244ab85950bbf4840edb674b +Author: John (J5) Palmieri +Date: Thu Aug 12 12:16:31 2010 -0400 + + handle strings correctly in gio + + gio/gappinfo.override | 5 +++++ + gio/pygio-utils.c | 42 +++++++++++++++++++++++++++++++++++------- + 2 files changed, 40 insertions(+), 7 deletions(-) + +commit 45ab0c03110c911b47519941dfd753326891b5e0 +Author: John (J5) Palmieri +Date: Wed Aug 11 16:13:59 2010 -0400 + + make giomodule compile under py3k + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gio/giomodule.c | 153 + +++++++++++++++++++++++++++++--------------------------- + 1 file changed, 78 insertions(+), 75 deletions(-) + +commit c52f8ed3ae8cb66a03b5695e980770c3f467f755 +Author: John (J5) Palmieri +Date: Wed Aug 11 16:04:48 2010 -0400 + + for py3k we need to do some more processing to get bytes from a + unicode string + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + gi/pygi-argument.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +commit de9eae4dfcce856a42cc5c569a5b9683c28d0eeb +Author: John (J5) Palmieri +Date: Wed Aug 11 15:03:55 2010 -0400 + + use Bytes instead of Unicode when reading io + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/pygiochannel.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +commit 5824ff98175b749dbcfa72d24b994230b6e05377 +Author: John (J5) Palmieri +Date: Mon Aug 9 15:16:51 2010 -0400 + + prefix compat macros with PYGLIB + + * refactor from John Ehresman py3k branch + * fix up some extranious PyString calls + * remove duplicate macros from pyglib.h that are in + pyglib-python-compat.h + * pygobject.h can't import pyglib-python-compat.h so add codepaths + for both Py3k and legacy code instead of using macros + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/glibmodule.c | 48 +++++----- + glib/pygiochannel.c | 46 +++++----- + glib/pyglib-python-compat.h | 153 +++++++++++++++++++++++-------- + glib/pyglib.c | 22 ++--- + glib/pyglib.h | 14 --- + glib/pygoptioncontext.c | 4 +- + glib/pygsource.c | 16 ++-- + glib/pygspawn.c | 32 +++---- + gobject/gobjectmodule.c | 216 + ++++++++++++++++++++++---------------------- + gobject/pygboxed.c | 2 +- + gobject/pygenum.c | 84 ++++++++--------- + gobject/pygflags.c | 122 ++++++++++++------------- + gobject/pygobject-private.h | 12 +-- + gobject/pygobject.c | 46 +++++----- + gobject/pygobject.h | 23 +++++ + gobject/pygparamspec.c | 24 ++--- + gobject/pygpointer.c | 2 +- + gobject/pygtype.c | 170 +++++++++++++++++----------------- + 18 files changed, 563 insertions(+), 473 deletions(-) + +commit 231e934cc01d061e81bb60d35127a133cd0e1793 +Author: John (J5) Palmieri +Date: Mon Aug 16 10:14:04 2010 +0200 + + Gtk.Button unit tests + + https://bugzilla.gnome.org/show_bug.cgi?id=622606 + + tests/test_overrides.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit f07cfde377e42686c6b80f56cac62338ee333e61 +Author: Johan Dahlin +Date: Mon Aug 16 10:08:38 2010 +0200 + + [Gtk] Add overrides for Button + + https://bugzilla.gnome.org/show_bug.cgi?id=622606 + + gi/overrides/Gtk.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +commit 65a06a7216163c7e65b32c5b5f3388faa7fda5d6 +Author: Simon van der Linden +Date: Thu Aug 12 16:18:58 2010 +0200 + + Make Cairo an optional dependency + + Add the --enable-cairo configure argument. + + https://bugzilla.gnome.org/show_bug.cgi?id=616732 + + configure.ac | 15 ++++++++++++--- + gi/Makefile.am | 20 ++++++++++++-------- + 2 files changed, 24 insertions(+), 11 deletions(-) + +commit b83507263231d9bf47f6c8450583e3d03f0a3b5b +Author: Tomeu Vizoso +Date: Mon Aug 16 09:55:35 2010 +0200 + + Don't import again PyGObject (John Ralls) + + https://bugzilla.gnome.org/show_bug.cgi?id=626996 + + gi/pygi.h | 1 + + 1 file changed, 1 insertion(+) + +commit 0dc3656070f496431829c6e8441ca17129c569f8 +Author: John (J5) Palmieri +Date: Mon Aug 9 16:11:55 2010 -0400 + + move to using richcompare slot instead of compare + + https://bugzilla.gnome.org/show_bug.cgi?id=615872 + + glib/pygiochannel.c | 18 +++++++---- + glib/pyglib.c | 85 + +++++++++++++++++++++++++++++++++++++++++++++++++ + glib/pyglib.h | 3 ++ + glib/pygmaincontext.c | 17 ++++++---- + glib/pygmainloop.c | 17 ++++++---- + glib/pygoptioncontext.c | 18 +++++++---- + glib/pygoptiongroup.c | 22 +++++++------ + gobject/pygboxed.c | 18 +++++++---- + gobject/pygobject.c | 44 ++++++++++++++++++------- + gobject/pygparamspec.c | 19 +++++++---- + gobject/pygpointer.c | 17 ++++++---- + gobject/pygtype.c | 26 +++++++++++---- + 12 files changed, 233 insertions(+), 71 deletions(-) + +commit b426e531dc53d4b50e572a2da19733479635e662 +Author: Simon van der Linden +Date: Thu Aug 12 18:09:33 2010 +0200 + + Replace autogen.sh by a newer version + + It pulls automake 1.10 or 1.11. + Greatly inspired from GLib's. + + https://bugzilla.gnome.org/show_bug.cgi?id=625661 + + autogen.sh | 506 + +++++++------------------------------------------------------ + 1 file changed, 58 insertions(+), 448 deletions(-) + +commit 769645e00d6d055a4cd802454dbfc1bbfcbee691 +Author: Simon van der Linden +Date: Thu Aug 12 14:11:55 2010 +0200 + + Fix some warnings + + pyglib.c: In function ‘pyglib_gerror_exception_check’: + pyglib.c:362: warning: format not a string literal and no format + arguments + pyglib.c:371: warning: format not a string literal and no format + arguments + + gio.override: In function 'pygio_notify_allocate_buffer': + gio.override:144:13: warning: format '%d' expects type 'int', but + argument 3 + has type 'gsize' + + https://bugzilla.gnome.org/show_bug.cgi?id=625437 + + gio/gio.override | 2 +- + glib/pyglib.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit e4c4cccb588b258dbcd21702e6cddcfe9ebe4ffc +Author: Simon van der Linden +Date: Thu Aug 12 11:09:37 2010 +0200 + + Fix caller-allocates emergency free. + + In the state, args, args[i], arg_infos[i], and arg_type_infos[i] + must not be + NULL in order to be able caller-allocates. This patch adds those + conditions. + + Moreover, the interface info needs to be freed afterwards. + + https://bugzilla.gnome.org/show_bug.cgi?id=626684 + + gi/pygi-invoke.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +commit 0ab967ca40ddcffc2834d4e656bb2010c6b9bdda +Author: Simon van der Linden +Date: Thu Aug 12 10:46:17 2010 +0200 + + Remove useless checks. + + No need to check for state->arg_infos, state->arg_type_infos, and + state->args_is_auxiliary to be NULL, they are always allocated. + + https://bugzilla.gnome.org/show_bug.cgi?id=626684 + + gi/pygi-invoke.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +commit e17be9cd288fee5d7cb174d9d577eb9279044c67 +Author: Tomeu Vizoso +Date: Tue Aug 10 17:40:16 2010 +0200 + + Call valgrind with G_SLICE=always-malloc G_DEBUG=gc-friendly + + tests/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8be59c37dd57acc51875c7189ca09d728b729013 +Author: Ignacio Casal Quinteiro +Date: Wed Aug 4 13:43:17 2010 +0200 + + Fix some warnings. + + gi/pygi-argument.c | 2 -- + gi/pygi-invoke.c | 2 +- + gi/pygi-struct.c | 1 - + 3 files changed, 1 insertion(+), 4 deletions(-) + +commit 529eca6054e9a7e2267f1529e317c2373932762f +Author: Simon van der Linden +Date: Fri Jul 30 22:39:40 2010 +0200 + + Add myself as a maintainer + + MAINTAINERS | 4 ++++ + 1 file changed, 4 insertions(+) + +commit caac75a6ed6f671b37e38a78e71b87906a00ac1b +Author: Tomeu Vizoso +Date: Fri Jul 30 14:14:16 2010 +0200 + + Properly allocate boxed structs that are (caller-allocates) + + * gi/pygi-boxed.[hc]: Refactor out the allocation of boxed structs + * gi/pygi-invoke.c: Don't use g_malloc0 for boxed structs that + are (caller-allocates) + * tests/test_overrides.py: Split the TreeView tests + + https://bugzilla.gnome.org/show_bug.cgi?id=625653 + + gi/pygi-boxed.c | 50 + ++++++++++++++++++++++++++++++++----------------- + gi/pygi-boxed.h | 10 ++++++---- + gi/pygi-invoke.c | 16 ++++++---------- + tests/test_overrides.py | 39 +++++++++++++++++++------------------- + 4 files changed, 64 insertions(+), 51 deletions(-) + +commit 99c7322898c00a576c7319ea0a7c808446253133 +Author: Toms Baugis +Date: Fri Jul 30 15:44:21 2010 +0200 + + override gdk.Event to return attribute from the proper event object + + https://bugzilla.gnome.org/show_bug.cgi?id=620593 + + gi/overrides/Gdk.py | 48 + ++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-invoke.c | 4 ---- + tests/test_overrides.py | 10 ++++++++++ + 3 files changed, 58 insertions(+), 4 deletions(-) + +commit 55814e722c2ae11310f346790c9221e4fad92b50 +Author: John (J5) Palmieri +Date: Fri Jul 30 06:30:48 2010 -0400 + + check if z# needs an int or Py_ssize_t + + https://bugzilla.gnome.org/show_bug.cgi?id=625438 + + gio/gio.override | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 477315465d0a6d84b51e146e86e254873bc564ff +Author: John (J5) Palmieri +Date: Fri Jul 30 06:43:06 2010 -0400 + + make sure we parse parameters to python object vars not glib vars + + * py_flags was already set up but due to a typo &flags was being + passed + instead + + https://bugzilla.gnome.org/show_bug.cgi?id=625438 + + gio/gfile.override | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit faa7d4eece7ddb698725098970c2478a3b45c4d5 +Author: Paul Bolle +Date: Fri Jul 30 10:56:01 2010 +0200 + + Make an example and a demo work out of the box + + cairo-demo.py and gtk-demo.py need the two (kind of) magic lines + regarding pygtk to work out of the box. So add those. + + Signed-off-by: Paul Bolle + + https://bugzilla.gnome.org/show_bug.cgi?id=625638 + + demos/gtk-demo/gtk-demo.py | 2 ++ + examples/cairo-demo.py | 2 ++ + 2 files changed, 4 insertions(+) + +commit c9da5782e6c633d9af43ee85075e9ee65db09780 +Author: John (J5) Palmieri +Date: Fri Jul 9 13:14:42 2010 -0400 + + make sure caller allocated structs are freed when they go out of scope + + * Move struct transfer checks from pygi-arguments to pygi-invoke + * add better warning if an unknown struct is fully transfered + * only free GValues we create in the invoke cleanup. All other + structs + get cleaned up when they go out of scope in python + * Fixes issues with caller allocated treeiters getting freed to early + * this is a fix to crashes in the current test suite when API's + returning + TreeIters were annotated as out caller-allocates so no new tests + are needed + + https://bugzilla.gnome.org/show_bug.cgi?id=623969 + + gi/pygi-argument.c | 13 +++++-------- + gi/pygi-invoke.c | 46 ++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 45 insertions(+), 14 deletions(-) + +commit e0a85305cd107aae5902e524afd074cd8c329927 +Author: Tomeu Vizoso +Date: Fri Jul 30 10:35:33 2010 +0200 + + Revert "override gdk.Event to return attribute from the proper + event object." + + Pushed by mistake, we still need testcases + + This reverts commit e7bb3954880568884ca66e7751ede689dc2f24f6. + + gi/overrides/Gdk.py | 44 -------------------------------------------- + 1 file changed, 44 deletions(-) + +commit 61ffb8d6d08fcfe638f71ea97ceac3a366e5536d +Author: Paul Bolle +Date: Thu Jul 29 22:55:28 2010 +0200 + + PyGI: properly quit cairo-demo + + Signed-off-by: Paul Bolle + + https://bugzilla.gnome.org/show_bug.cgi?id=625619 + + examples/cairo-demo.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e7bb3954880568884ca66e7751ede689dc2f24f6 +Author: Toms Baugis +Date: Tue Jul 27 21:37:16 2010 +0200 + + override gdk.Event to return attribute from the proper event object. + + https://bugzilla.gnome.org/show_bug.cgi?id=620593 + + gi/overrides/Gdk.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +commit 0a9f1da052fd33dcef81d0e267fc7972f02c7888 +Author: Simon van der Linden +Date: Wed Jul 28 14:56:00 2010 +0200 + + Clean and improve the test infrastructure + + To run select tests, use for instance: + % make check TEST_NAMES='test_everything test_gi.TestConstant' + + It works with check.gdb and check.valgrind too. + + https://bugzilla.gnome.org/show_bug.cgi?id=625488 + + Makefile.am | 5 ---- + tests/Makefile.am | 65 + +++++++++++++++++++++------------------------- + tests/common.py | 47 --------------------------------- + tests/runtests.py | 43 ++++++++++++------------------ + tests/test_gcancellable.py | 4 +-- + tests/test_gi.py | 3 --- + tests/test_gicon.py | 3 ++- + tests/test_gio.py | 3 ++- + tests/test_gobject.py | 3 ++- + tests/test_gresolver.py | 4 +-- + tests/test_gsocket.py | 4 ++- + tests/test_interface.py | 6 ++++- + tests/test_mainloop.py | 11 +++----- + tests/test_signal.py | 4 ++- + tests/test_source.py | 4 +-- + tests/test_subprocess.py | 5 +--- + tests/test_thread.py | 5 +++- + tests/test_unknown.py | 5 +++- + 18 files changed, 82 insertions(+), 142 deletions(-) + +commit 82f4cb5ebf5d992493b7a2f74cfd5f175e19eb76 +Author: Tomeu Vizoso +Date: Thu Jul 29 12:34:19 2010 +0200 + + Add some more transformations to pygi-convert.sh + + pygi-convert.sh | 37 +++++++++++++++++++++++++++++-------- + 1 file changed, 29 insertions(+), 8 deletions(-) + +commit de519adcd21947a0aef7932cdecb78cef200c85e +Author: Tomeu Vizoso +Date: Wed Jul 28 14:42:36 2010 +0200 + + Adapt to API changes: g_irepository_enumerate_versions + + gi/importer.py | 2 +- + gi/pygi-repository.c | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +commit 01cd9abb43f93f9a57a5a05b6dc9560614e666e3 +Author: Tomeu Vizoso +Date: Wed Jul 28 12:26:48 2010 +0200 + + Add GValue<->GArgument marshalling for some more types + + gi/pygi-property.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +commit ddffa70c3ee0e837070f390632bc692430f79171 +Author: Tomeu Vizoso +Date: Wed Jul 28 11:10:42 2010 +0200 + + Chain up with the non-introspection implementation for properties + if needed + + gobject/pygobject.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 045433a1f8167205dc8eae613dcb8835d02c8916 +Author: Tomeu Vizoso +Date: Wed Jul 28 10:59:49 2010 +0200 + + Improve error reporting for missing attributes in introspection + modules + + gi/module.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 6655a79b2f13fe417aefdf6aebab0f2d6162ba00 +Author: Tomeu Vizoso +Date: Tue Jul 27 21:52:49 2010 +0200 + + Implement getting and setting properties using introspection + information. + + This allows us to use information not present in GObject such as + transfer and element types. + + https://bugzilla.gnome.org/show_bug.cgi?id=620808 + + gi/Makefile.am | 2 + + gi/gimodule.c | 2 + + gi/pygi-argument.c | 2 + + gi/pygi-private.h | 1 + + gi/pygi-property.c | 226 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-property.h | 39 ++++++++ + gi/pygi.h | 41 +++++++++ + gobject/pygobject.c | 9 ++ + tests/test_everything.py | 19 ++++ + 9 files changed, 341 insertions(+) + +commit 85f4572b3ffbfa364ebb2e470eab759edc557b36 +Author: Tomeu Vizoso +Date: Tue Jul 27 21:32:41 2010 +0200 + + Readd Gdk.Rectangle override for Gtk-2.0 + + gi/overrides/Gdk.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit 2082ee35e2a33f52bf1e8ec49cb4a43398e91989 +Author: Tomeu Vizoso +Date: Tue Jul 27 18:25:27 2010 +0200 + + Allow specifying a version when loading a typelib + + * gi/importer.py: Defer loading the typelib until first usage. + * gi/module.py: Load the typelib in IntrospectionModule(). + * gi/overrides/*.py: Adapt to API change. + * gi/pygi-repository.c: Add wrappers for g_irepository_enumerate and + g_irepository_get_version. + + gi/importer.py | 26 ++++++----------- + gi/module.py | 58 + +++++++++++++++++++++++++------------- + gi/overrides/GIMarshallingTests.py | 2 +- + gi/overrides/Gdk.py | 2 +- + gi/overrides/Gtk.py | 2 +- + gi/pygi-repository.c | 56 + +++++++++++++++++++++++++++++++++++- + 6 files changed, 105 insertions(+), 41 deletions(-) + +commit 6d7ed6c322234c240b1063a1dfaadd17157432a9 +Author: Jonathan Matthew +Date: Tue Jul 13 20:27:28 2010 +1000 + + treat GFreeFunc as equivalent to GDestroyNotify when scanning + callbacks + + https://bugzilla.gnome.org/show_bug.cgi?id=624232 + + gi/pygi-callbacks.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 7e9cbd5601ad548b78d106bac1a1576d33b91c65 +Author: Simon van der Linden +Date: Mon Jul 26 17:00:23 2010 +0200 + + Don't use == to compare doubles, use <= and =>. + + This avoids inequality due to small precisions difference. + + https://bugzilla.gnome.org/show_bug.cgi?id=625326 + + tests/testhelpermodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 5ca2a41f16f4a5fcc3ab4d00bec46b077c7eb384 +Author: Tomeu Vizoso +Date: Thu Jul 8 11:36:12 2010 +0200 + + Allow passing ints as enum args + + https://bugzilla.gnome.org/show_bug.cgi?id=622584 + + gi/pygi-argument.c | 23 +++++++++++++++++++++-- + tests/test_gi.py | 6 ++++-- + 2 files changed, 25 insertions(+), 4 deletions(-) + +commit 890c3233f8a9f884b045a294bf0122bb3afcd54a +Author: Tomeu Vizoso +Date: Sun Jul 25 17:30:40 2010 +0100 + + Make error message less ambiguous + + https://bugzilla.gnome.org/show_bug.cgi?id=625095 + + gi/pygi-callbacks.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 1162e436273ff8e9e4e24bd8ba74615fd4624753 +Author: John (J5) Palmieri +Date: Thu Jun 24 10:07:12 2010 -0400 + + fix passing in type names as a GType and add gtype unit tests + + * a simple call to pyg_type_from_object covers all the bases + * added unit tests to check for correct GType value passing + * fixed up tree override tests to also check different ways of + passing GTypes + + https://bugzilla.gnome.org/show_bug.cgi?id=622605 + + gi/pygi-argument.c | 8 +------- + tests/test_everything.py | 27 +++++++++++++++++++++++++++ + tests/test_overrides.py | 6 ++---- + 3 files changed, 30 insertions(+), 11 deletions(-) + +commit 8becd32fc042445d62b885bac12dac326b2dc1fa +Author: Tomeu Vizoso +Date: Mon Jul 26 11:54:47 2010 +0200 + + Increase a bit verbosity of tests so people know which test failed + + tests/runtests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3b3c63514f311592e6769a373d37a2bde7ea6b38 +Author: Tomeu Vizoso +Date: Thu Jul 15 15:17:53 2010 +0200 + + Actually add the files for GVariant foreign structs + + gi/pygi-foreign-gvariant.c | 63 + ++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-foreign-gvariant.h | 41 ++++++++++++++++++++++++++++++ + 2 files changed, 104 insertions(+) + +commit e65275bc57f345c111eb12a6b4476ff1ddc3bc24 +Author: Tomeu Vizoso +Date: Thu Jul 15 13:31:33 2010 +0200 + + Add foreign struct support for GVariant + + * gi/pygi-invoke.c: Wrap foreign structs returned by constructors + * gi/pygi-foreign.c: Register foreign support for GVariant + * gi/pygi-struct.c: properly release foreign structs + * gi/pygi-argument.c, gi/pygi-foreign-cairo.c, gi/pygi.h: Adapt to + API changes + * tests/test_everything.py: Add basic tests for GVariant + + https://bugzilla.gnome.org/show_bug.cgi?id=619501 + + gi/Makefile.am | 2 + + gi/pygi-argument.c | 2 +- + gi/pygi-foreign-cairo.c | 16 +++---- + gi/pygi-foreign.c | 107 + +++++++++++++++++++++++++++++------------------ + gi/pygi-foreign.h | 7 ++-- + gi/pygi-invoke.c | 18 ++++---- + gi/pygi-struct.c | 10 ++++- + gi/pygi.h | 9 ++-- + tests/test_everything.py | 8 ++++ + 9 files changed, 110 insertions(+), 69 deletions(-) + +commit 3b3bd4da3fbc993fa7f7cfb46ed4e67671c94cc0 +Author: Tomeu Vizoso +Date: Mon Jul 12 11:19:06 2010 +0200 + + Add HACKING to MANIFEST.in + + MANIFEST.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 40bf08ff001b119c7daf709197005ef6480216c5 +Author: Tomeu Vizoso +Date: Mon Jul 12 11:18:04 2010 +0200 + + Add HACKING file with instructions for releasing + + HACKING | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +commit 3b9dffe7cc3820dfb84fd968fc604899601c5dc4 +Author: Tomeu Vizoso +Date: Mon Jul 12 11:09:58 2010 +0200 + + Post release version bump to 2.21.6 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 42a5a0897b38156ae010c396ea254abf502f35de +Author: Tomeu Vizoso +Date: Mon Jul 12 11:00:29 2010 +0200 + + Update NEWS and release PyGObject-2.21.5 + + NEWS | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +commit 5857f25c1c6e25b79e6134558bd7151bc6c30ef7 +Author: Tomeu Vizoso +Date: Mon Jul 12 11:00:20 2010 +0200 + + Pre-release version bump to 2.21.5 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e500adc3ac19ef6f436809e5a8828ac7e8db28f6 +Author: Florian Müllner +Date: Sat Jul 10 22:35:13 2010 +0200 + + Shut up some compiler warnings + + Remove unused variables, make sure variables are properly initialized. + + https://bugzilla.gnome.org/show_bug.cgi?id=624066 + + gi/pygi-callbacks.c | 1 - + gi/pygi-closure.c | 2 +- + gi/pygi-invoke.c | 1 - + 3 files changed, 1 insertion(+), 3 deletions(-) + +commit 2efa18afbcc2fac1c90958535b2f80e6e730ee56 +Author: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon Jul 12 10:31:42 2010 +0200 + + Adjust to API break in GObject-Introspection + + As of commit 5cb925b20, many type_tags for standard C types have + been removed - namely machine-dependent integer types and derived + types (size_t, time_t). + + Most removals are just synonyms of other types, so their removal + should not have too much impact, with the exception of time_t, + which was translated to a native datetime object before. + + Also remove time_t tests (Tomeu Vizoso). + + https://bugzilla.gnome.org/show_bug.cgi?id=624065 + + configure.ac | 2 +- + gi/importer.py | 7 +-- + gi/pygi-argument.c | 146 + ----------------------------------------------------- + gi/pygi-closure.c | 10 ---- + gi/pygi-info.c | 37 -------------- + tests/test_gi.py | 21 -------- + 6 files changed, 5 insertions(+), 218 deletions(-) + +commit 27a417c71f8c122e46c7472663bb25c17413f103 +Author: John (J5) Palmieri +Date: Thu Jul 8 16:01:25 2010 -0400 + + pass in the demo app so demos can use utility methods like requesting + file paths + + demos/gtk-demo/demos/Entry/entry_buffer.py | 2 +- + demos/gtk-demo/demos/Entry/entry_completion.py | 2 +- + demos/gtk-demo/demos/appwindow.py | 13 +++++++++++-- + demos/gtk-demo/demos/assistant.py | 2 +- + demos/gtk-demo/demos/builder.py | 14 ++++++++++---- + demos/gtk-demo/demos/button_box.py | 2 +- + demos/gtk-demo/demos/clipboard.py | 8 +------- + demos/gtk-demo/demos/colorselector.py | 2 +- + demos/gtk-demo/demos/combobox.py | 8 +++++--- + demos/gtk-demo/demos/drawingarea.py | 2 +- + demos/gtk-demo/demos/test.py | 2 +- + demos/gtk-demo/gtk-demo.py | 6 +++--- + 12 files changed, 37 insertions(+), 26 deletions(-) + +commit e7daae919c2c6ae35d3927f0006252aacd49ea86 +Author: John (J5) Palmieri +Date: Thu Jul 8 15:38:07 2010 -0400 + + demo fixes to keep up with Gtk+ + + * treeiter changes to reflect caller-allocate annotations + * fix some flag handling + * use get_indicies_with_depth instead of get_indices for paths + + demos/gtk-demo/demos/appwindow.py | 10 +++++++--- + demos/gtk-demo/demos/combobox.py | 24 ++++++++++++------------ + demos/gtk-demo/gtk-demo.py | 13 +++++-------- + 3 files changed, 24 insertions(+), 23 deletions(-) + +commit 3d9fd6391710cc33058394d6821e4d4e11f09b22 +Author: John (J5) Palmieri +Date: Thu Jul 8 12:54:43 2010 -0400 + + override test fixes for new GTK+ annotations + + tests/test_overrides.py | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +commit 7a400f8139b70ddfe7c949035e0851689951c647 +Author: Ignacio Casal Quinteiro +Date: Thu Jul 8 12:42:25 2010 +0200 + + Fix warning. + + gi/pygi-argument.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 39fd0a85a3de06b1b877d1125f91036409886373 +Author: John (J5) Palmieri +Date: Wed Jul 7 15:48:36 2010 -0400 + + fix up treeiter usage due to caller-allocates annotations in gtk+ + + * we still don't pass tests because the caller-allocates code path + does not + handle the case where the parameter is followed by a regular + in parameter + + gi/overrides/Gtk.py | 7 +++---- + tests/test_overrides.py | 21 +++++++++++---------- + 2 files changed, 14 insertions(+), 14 deletions(-) + +commit 4d970b75dc5c75c1bec04cb2954c9985b476070c +Author: John (J5) Palmieri +Date: Tue Jul 6 17:50:10 2010 -0400 + + add entry completion demo + + demos/gtk-demo/demos/Entry/entry_completion.py | 87 + ++++++++++++++++++++++++++ + 1 file changed, 87 insertions(+) + +commit f3531eaa1bfa4e01651d35cd587384d30a398ba8 +Author: John (J5) Palmieri +Date: Tue Jul 6 17:49:18 2010 -0400 + + string changes + + demos/gtk-demo/demos/Entry/entry_buffer.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit baf1e9bb550c7bf45e2ac0b70ba29c434ef1ccc6 +Author: John (J5) Palmieri +Date: Tue Jul 6 17:27:04 2010 -0400 + + add the Entry demo directory and the entry_buffer demo + + demos/gtk-demo/demos/Entry/__init__.py | 0 + demos/gtk-demo/demos/Entry/entry_buffer.py | 73 + ++++++++++++++++++++++++++++++ + 2 files changed, 73 insertions(+) + +commit f2b1d222120f055bec9339cca55c9cc90f538c00 +Author: John (J5) Palmieri +Date: Tue Jul 6 17:26:03 2010 -0400 + + fix loading of demo modules to support sub modules + + demos/gtk-demo/gtk-demo.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +commit 4f9390fb1892b13ab2ea00ed66c5000a40f09029 +Author: John (J5) Palmieri +Date: Tue Jul 6 15:56:34 2010 -0400 + + add the ability to have demos in sub catagories + + demos/gtk-demo/gtk-demo.py | 76 + ++++++++++++++++++++++++++++++++-------------- + 1 file changed, 54 insertions(+), 22 deletions(-) + +commit dc2249a3ecf339008351316217191d0551ccc588 +Author: Jose Aliste +Date: Mon Jul 5 14:36:59 2010 -0400 + + Add __name__ to DynamicModule class. + + Fixes bug #623486. + + gi/module.py | 1 + + 1 file changed, 1 insertion(+) + +commit 2357bca8d14539894b6bd0acfdc18d30b4bb4db6 +Author: Ignacio Casal Quinteiro +Date: Mon Jul 5 16:11:07 2010 +0200 + + Do not override GdkRectangle. + + This class was lately removed from gtk+ 3, so there is no need + to override + it anymore. + + gi/overrides/Gdk.py | 19 ------------------- + 1 file changed, 19 deletions(-) + +commit daca09dc2c2306d4fa82a68bbdd147d4b170a1e7 +Author: Philip Withnall +Date: Tue Jun 29 16:37:36 2010 +0100 + + Add override for TreeModel implementing __len__() + + Closes: bgo#622882 + + gi/overrides/Gtk.py | 11 +++++++++-- + tests/test_overrides.py | 5 +++++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +commit bb8adb7f02f0c5494df2cb6e535e44d23902e8f5 +Author: Tomeu Vizoso +Date: Tue Jun 29 11:27:13 2010 +0200 + + Update NEWS and release PyGObject-2.21.4 + + NEWS | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +commit 2d473ee17be4671244bb4a2a0953a21ccf2a0df6 +Author: Tomeu Vizoso +Date: Tue Jun 29 10:55:03 2010 +0200 + + Remove files from the makefiles + + gi/Makefile.am | 4 +--- + gobject/Makefile.am | 3 +-- + 2 files changed, 2 insertions(+), 5 deletions(-) + +commit 89827314fd183eac07443c8e9d275ca9d4ce59df +Author: Tomeu Vizoso +Date: Tue Jun 29 10:27:39 2010 +0200 + + Build the cairo shim as a python module so the _gi module stops + linking to it + + https://bugzilla.gnome.org/show_bug.cgi?id=623021 + + configure.ac | 2 + + gi/Makefile.am | 38 ++++++++++----- + gi/gimodule.c | 8 +--- + gi/pygi-argument.c | 10 +--- + gi/pygi-foreign-cairo.c | 56 ++++++++++++++++------ + gi/pygi-foreign-cairo.h | 55 --------------------- + gi/pygi-foreign.c | 125 + ++++++++++++++++++++++++++++-------------------- + gi/pygi-foreign.h | 31 ++++++------ + gi/pygi.h | 40 ++++++++++++++-- + 9 files changed, 196 insertions(+), 169 deletions(-) + +commit a6a90551311bc64f037cbd442e13f70c30060871 +Author: Tomeu Vizoso +Date: Mon Jun 28 14:20:43 2010 +0200 + + Remove pygi-external.h + + https://bugzilla.gnome.org/show_bug.cgi?id=623021 + + gi/gimodule.c | 8 +++--- + gi/pygi-type.c | 4 +-- + gi/pygi-type.h | 2 +- + gi/pygi.h | 54 ++++++++++++++++----------------------- + gobject/Makefile.am | 6 +++++ + gobject/pygboxed.c | 2 +- + gobject/pygenum.c | 2 +- + gobject/pygflags.c | 2 +- + gobject/pygi-external.h | 67 + ------------------------------------------------- + gobject/pygobject.c | 2 +- + gobject/pygpointer.c | 2 +- + 11 files changed, 40 insertions(+), 111 deletions(-) + +commit 8b3a3baacb45cb3f9112f7597607602fa89c6634 +Author: Tomeu Vizoso +Date: Fri Jun 25 13:54:57 2010 +0200 + + Revert "correctly handle floating objects in gtk" + + This reverts commit 60fdf4b8f738dd0f5c190bc18ddf010032d3c5ca. + + Conflicts: + + gi/gimodule.c + tests/test_everything.py + + gi/gimodule.c | 13 ------------- + tests/test_everything.py | 3 ++- + 2 files changed, 2 insertions(+), 14 deletions(-) + +commit 0f2a09d7eae63abb71723b7cd8fb290dcba33426 +Author: Tomeu Vizoso +Date: Fri Jun 25 13:49:04 2010 +0200 + + Make valgrind happy again + + * gi/pygi-argument.c, gi/pygi-info.c: Zero two GArgument instances. + * gi/pygi-invoke.c: workaround bgo#622711 and zero invocation_state. + + gi/pygi-argument.c | 1 + + gi/pygi-info.c | 2 ++ + gi/pygi-invoke.c | 8 ++++++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +commit 63afe55906c8637e913783e65b82b540b81bed65 +Author: John (J5) Palmieri +Date: Thu Jun 24 16:13:37 2010 -0400 + + add drawing area demo + + demos/gtk-demo/demos/drawingarea.py | 249 + ++++++++++++++++++++++++++++++++++++ + 1 file changed, 249 insertions(+) + +commit 8bba5f842393a284367cdd15f3d32a8c7745516a +Author: John (J5) Palmieri +Date: Thu Jun 24 14:11:00 2010 -0400 + + sort the demo list + + demos/gtk-demo/gtk-demo.py | 2 ++ + 1 file changed, 2 insertions(+) + +commit b9da82742701ed276b01dee39626cd71cbef8556 +Author: John (J5) Palmieri +Date: Thu Jun 24 13:56:18 2010 -0400 + + rename iter to treeiter so we aren't using a python reserved word + + demos/gtk-demo/gtk-demo.py | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit c93935621f2fb1ff5e8c424ae884bd684ea68e50 +Author: John (J5) Palmieri +Date: Thu Jun 24 13:47:54 2010 -0400 + + Fixup for change in buffer API + + * Part of buffer API dealing with TextIter now marked (out + caller-allocates) + + demos/gtk-demo/gtk-demo.py | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +commit 8d9516a593a515290109401a9db7aa259b5aa35c +Author: John (J5) Palmieri +Date: Wed Jun 23 17:04:33 2010 -0400 + + add ListStore, TreeStore and TreeViewColumn APIs + + * this is enough to support the gtk-demo.py shell + * TreeStore and ListStore allow passing in as an argument list + of either python or GLib types to the constructor as a description + of the columns in the model + * TreeStore and ListStore override the append method, allowing + the application developer to send in a list of column values + for one row in the model. Unlike the append in C which + just returns an iter that you can then add data to, + this append actualy appends data in one step + * TreeViewColumn overrides the constructor to allow the adding + of attributes and a cell renderer when constructing the + column + + https://bugzilla.gnome.org/show_bug.cgi?id=620405 + + gi/overrides/Gtk.py | 59 ++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 69 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 128 insertions(+) + +commit c305fbeb7bdb44623d5198f4a8f0a374d529fdf4 +Author: Johan Dahlin +Date: Wed Jun 23 14:34:28 2010 -0300 + + [gi] Add -I../gobject to cflags + + Since we're no longer pulling in pygobject cflags, + add this to be able to include pygobject.h + + gi/Makefile.am | 3 +++ + 1 file changed, 3 insertions(+) + +commit 53a093198851e3ba5abd1f6c3314737decd401d8 +Author: Ignacio Casal Quinteiro +Date: Wed Jun 23 18:09:19 2010 +0200 + + Add unit test for add_actions user data. + + tests/test_overrides.py | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +commit 7f829af620cba768de619dd9f228d5d2ebf7fee4 +Author: Paolo Borelli +Date: Wed Jun 23 18:06:46 2010 +0200 + + Pass user_data param when adding actions + + gi/overrides/Gtk.py | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit 8f537ccd62f41ebe0db3853e2ae08080666f598f +Author: John (J5) Palmieri +Date: Wed Jun 23 12:02:04 2010 -0400 + + add an exception type to the try/except block + + * we should always specify what exception types we are expecting + + gi/overrides/Gtk.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit f140a8ebf59347162b67b550bd6f62d2eafad29a +Author: Johan Dahlin +Date: Wed Jun 23 12:31:51 2010 -0300 + + Avoid duplicating required versions + + Avoid duplicating the version of all required packages. + Also remove cyclic dependency of pygobject + + https://bugzilla.gnome.org/show_bug.cgi?id=622503 + + configure.ac | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit e8bd25355fbe7de38a28b7a0583167a2c0ffc31f +Author: John (J5) Palmieri +Date: Tue Jun 22 15:03:08 2010 -0400 + + return PyList instead of PyTuple for array, return empty list for + NULL arrays + + * returns an empty list when a NULL array (empty array) is encountered + * fix tests to check for lists instead of tuples or None + * test the ability to send in both None and empty list for arrays + and lists + + gi/pygi-argument.c | 7 ++-- + tests/test_everything.py | 5 ++- + tests/test_gi.py | 84 + ++++++++++++++++++++++++------------------------ + 3 files changed, 49 insertions(+), 47 deletions(-) + +commit f312e6a49505eca07815146cfbdb0e48e5b3b8a8 +Author: Tomeu Vizoso +Date: Wed Jun 23 15:42:29 2010 +0200 + + Fix 'make distcheck' + + * Makefile.am: put the tests dir to the end + * g*/Makefile.am: build the .so when running make check + * tests/Makefile.am: Don't pass the src dir to runtests.py and + remove (hopefully) unneeded cruft. + * tests/common.py: Don't add the src dir to the python path + * tests/runtests.py: Don't pass the src dir to common.py + + Makefile.am | 4 +++- + gi/Makefile.am | 1 + + gio/Makefile.am | 1 + + glib/Makefile.am | 2 +- + gobject/Makefile.am | 1 + + tests/Makefile.am | 17 ++--------------- + tests/common.py | 3 +-- + tests/runtests.py | 12 +++++------- + 8 files changed, 15 insertions(+), 26 deletions(-) + +commit 5f82e7d2909cbbbecbf5dbee2342f516c0d1f371 +Author: Tomeu Vizoso +Date: Wed Jun 23 13:59:14 2010 +0200 + + Allow building pygobject without introspection support by providing + --disable-introspection to configure. + + Makefile.am | 6 +++++- + configure.ac | 15 ++++++++------- + gobject/pygi-external.h | 4 ++-- + tests/Makefile.am | 8 ++++++-- + tests/runtests.py | 21 +++++++-------------- + 5 files changed, 28 insertions(+), 26 deletions(-) + +commit cc3ea77318ee572673d2a044deca9001366b0f08 +Author: Tomeu Vizoso +Date: Wed Jun 23 12:26:51 2010 +0200 + + Make sure that sys.argv is a list and not a sequence. + + Because Python's optparse will try to do things on it that can + only be done with list. + + gi/overrides/Gtk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3d72b8248cc534a689dee5679a729b2fba56c528 +Author: Tomeu Vizoso +Date: Wed Jun 23 12:26:02 2010 +0200 + + Force loading the GObject typelib so we have available the wrappers + for base classes such as GInitiallyUnowned. + + gi/__init__.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit c7c94ef349c30597f2f10d90f74718d678ec7add +Author: John (J5) Palmieri +Date: Tue Jun 22 14:45:48 2010 -0400 + + we shouldn't g_array_free NULL pointers + + https://bugzilla.gnome.org/show_bug.cgi?id=622425 + + gi/pygi-info.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit fb1ee243493616d7a7e4f6924c574db39f5a423d +Merge: acf7b43 5f9cb91 +Author: Tomeu Vizoso +Date: Wed Jun 23 12:53:05 2010 +0200 + + Merge branch 'pygi' + +commit 5f9cb91c2b3851056d5e2d7ff1401d4ce2be7c1f +Author: John (J5) Palmieri +Date: Tue Jun 22 15:39:46 2010 -0400 + + remove unneeded TextIter creation in the tests + + tests/test_overrides.py | 3 --- + 1 file changed, 3 deletions(-) + +commit 53c355d2cc0894e7f551e9b4eb719b89188a978e +Author: John (J5) Palmieri +Date: Mon Jun 21 11:42:12 2010 -0400 + + add override for TextBuffer + + * TextBuffer.create_tag takes vargs which we can't bind yet so + change it + to except a keyword list of properties + * override the insert* methods so the developer does not have to + enter a length + - lengths are already encapsulated by a string in Python + + https://bugzilla.gnome.org/show_bug.cgi?id=620583 + + gi/overrides/Gtk.py | 51 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_overrides.py | 25 ++++++++++++++++++++++++ + 2 files changed, 76 insertions(+) + +commit 1d89a88b212c7411ad28e74eda80ae751de92e50 +Author: John (J5) Palmieri +Date: Tue Jun 22 12:46:39 2010 -0400 + + fix up some build issues + + * configure.ac: moved AM_PROG_CC_C_O below AM_PROG_CC_STDC because + autoconf + was complaining that AM_PROG_CC_STDC can't come after AM_PROC_CC_C_0 + * tests/Makefile.am: fix check-local target to use EXEC_NAME so + targets like + make check.gdb work + + configure.ac | 2 +- + tests/Makefile.am | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 4fe0d94c219deb69a2309693202309c53a0e5e69 +Author: John (J5) Palmieri +Date: Tue Jun 22 11:50:30 2010 -0400 + + make the overrides file git friendly by appending to __all__ after + each override + + * modifying the __all__ line for each override would confuse git as + each override needs to get seperate approval before comitting. + Because of + this commits would not always go in in the same order as they + are created. + Also different people working on the same file would start from + different + commit states. This caused conflicts when patches were merged. + * instead of modifying a single hard coded list we now append to + the list + after each override. This creates distinct blocks of changed text + which will not conflict + + gi/overrides/GIMarshallingTests.py | 10 ++++------ + gi/overrides/Gdk.py | 8 ++++---- + gi/overrides/Gtk.py | 7 +++++-- + 3 files changed, 13 insertions(+), 12 deletions(-) + +commit 49321b934603e1ec69fb04082c63902970907d2b +Author: Paolo Borelli +Date: Sun Jun 20 13:27:34 2010 +0200 + + Override Dialog constructor and add_buttons method + + gi/overrides/Gtk.py | 46 + +++++++++++++++++++++++++++++++++++++++++++++- + tests/test_overrides.py | 16 ++++++++++++++++ + 2 files changed, 61 insertions(+), 1 deletion(-) + +commit acf7b43a41ce814f0c57ce609a090826f04771db +Author: Tomeu Vizoso +Date: Mon Jun 21 18:17:38 2010 +0200 + + Post release version bump to 2.21.4 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a7fa8b80406227a06cf18f8675dbc1f471283829 +Author: Tomeu Vizoso +Date: Mon Jun 21 18:10:32 2010 +0200 + + Update NEWS and release PyGObject-2.21.3 + + NEWS | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 79acac7b86ec52cd3681d94d7f116314c3f00167 +Author: Ludovic L'Hours +Date: Tue Jul 21 16:28:34 2009 +0200 + + Proper handling of null-ok in virtual methods + + https://bugzilla.gnome.org/show_bug.cgi?id=589253 + + codegen/codegen.py | 2 ++ + codegen/reversewrapper.py | 18 +++++++++++++++--- + 2 files changed, 17 insertions(+), 3 deletions(-) + +commit 259a4b08f009aa01451caed20dbb6e68b402da2a +Author: Tomeu Vizoso +Date: Mon Jun 21 17:34:54 2010 +0200 + + Add *~ and *.orig to .gitignore + + .gitignore | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 00a85f6a844714d1715e2f67431747d1a4cdacb1 +Author: Tomeu Vizoso +Date: Mon Jun 21 17:33:56 2010 +0200 + + Fall back to use the floating references API in glib if there isn't + a sinkfunc defined. + + * tests/*: Add ref counting tests for floating objects + * gobject/gobjectmodule.c, gobject/pygobject.c: Fall back to + g_object_ref_sink + or g_object_ref if there isn't a sinkfunc defined. Make sure that + pygobject_sink gets called only once per GObject instance. + + https://bugzilla.gnome.org/show_bug.cgi?id=583909 + + gobject/gobjectmodule.c | 2 - + gobject/pygobject.c | 50 +++++++++++++--------- + gobject/pygobject.h | 1 + + tests/Makefile.am | 2 + + tests/test-floating.c | 95 +++++++++++++++++++++++++++++++++++++++++ + tests/test-floating.h | 60 ++++++++++++++++++++++++++ + tests/test_gobject.py | 19 ++++++++- + tests/testhelpermodule.c | 109 + +++++++++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 315 insertions(+), 23 deletions(-) + +commit e71238a699ae783fd1a59c8a76e3555d8066cf82 +Author: Tomeu Vizoso +Date: Mon Jun 21 13:06:13 2010 +0200 + + Revert "Drop sinkfuncs." + + This reverts commit 04627488220b4f2a16e11f8982af7866fea9f7eb. + + gobject/gobjectmodule.c | 3 ++- + gobject/pygobject.c | 42 ++++++++++++++++++++++++++++++++++-------- + gobject/pygobject.h | 1 - + 3 files changed, 36 insertions(+), 10 deletions(-) + +commit b2661054d6bde673484eab472e69ca021124528d +Author: Johan Dahlin +Date: Sun Jun 20 11:09:57 2010 -0300 + + Merge back pygi + + For reasons outlined at: + http://mail.gnome.org/archives/python-hackers-list/2010-June/msg00009.html + + Makefile.am | 14 +- + configure.ac | 29 +- + demos/gtk-demo/demos/__init__.py | 0 + demos/gtk-demo/demos/appwindow.py | 411 +++++ + demos/gtk-demo/demos/assistant.py | 134 ++ + demos/gtk-demo/demos/builder.py | 57 + + demos/gtk-demo/demos/button_box.py | 121 ++ + demos/gtk-demo/demos/clipboard.py | 238 +++ + demos/gtk-demo/demos/colorselector.py | 121 ++ + demos/gtk-demo/demos/combobox.py | 282 ++++ + demos/gtk-demo/demos/data/alphatest.png | Bin 0 -> + 26529 bytes + demos/gtk-demo/demos/data/apple-red.png | Bin 0 -> 3545 bytes + demos/gtk-demo/demos/data/background.jpg | Bin 0 -> + 22219 bytes + demos/gtk-demo/demos/data/demo.ui | 258 ++++ + demos/gtk-demo/demos/data/floppybuddy.gif | Bin 0 -> 5216 bytes + demos/gtk-demo/demos/data/gnome-applets.png | Bin 0 -> 3090 bytes + demos/gtk-demo/demos/data/gnome-calendar.png | Bin 0 -> 2755 bytes + demos/gtk-demo/demos/data/gnome-foot.png | Bin 0 -> 2916 bytes + demos/gtk-demo/demos/data/gnome-fs-directory.png | Bin 0 -> 2044 bytes + demos/gtk-demo/demos/data/gnome-fs-regular.png | Bin 0 -> 1795 bytes + demos/gtk-demo/demos/data/gnome-gimp.png | Bin 0 -> 3410 bytes + demos/gtk-demo/demos/data/gnome-gmush.png | Bin 0 -> 3244 bytes + demos/gtk-demo/demos/data/gnome-gsame.png | Bin 0 -> 4263 bytes + demos/gtk-demo/demos/data/gnu-keys.png | Bin 0 -> 3852 bytes + demos/gtk-demo/demos/data/gtk-logo-rgb.gif | Bin 0 -> 6427 bytes + demos/gtk-demo/demos/test.py | 14 + + demos/gtk-demo/gtk-demo.py | 266 ++++ + examples/Makefile.am | 2 +- + examples/cairo-demo.py | 121 ++ + gi/Makefile.am | 4 +- + gi/demos/gtk-demo/demos/__init__.py | 0 + gi/demos/gtk-demo/demos/appwindow.py | 411 ----- + gi/demos/gtk-demo/demos/assistant.py | 134 -- + gi/demos/gtk-demo/demos/builder.py | 57 - + gi/demos/gtk-demo/demos/button_box.py | 121 -- + gi/demos/gtk-demo/demos/clipboard.py | 238 --- + gi/demos/gtk-demo/demos/colorselector.py | 121 -- + gi/demos/gtk-demo/demos/combobox.py | 282 ---- + gi/demos/gtk-demo/demos/data/alphatest.png | Bin 26529 -> + 0 bytes + gi/demos/gtk-demo/demos/data/apple-red.png | Bin 3545 -> 0 bytes + gi/demos/gtk-demo/demos/data/background.jpg | Bin 22219 -> + 0 bytes + gi/demos/gtk-demo/demos/data/demo.ui | 258 ---- + gi/demos/gtk-demo/demos/data/floppybuddy.gif | Bin 5216 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-applets.png | Bin 3090 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-calendar.png | Bin 2755 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-foot.png | Bin 2916 -> 0 bytes + .../gtk-demo/demos/data/gnome-fs-directory.png | Bin 2044 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-fs-regular.png | Bin 1795 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-gimp.png | Bin 3410 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-gmush.png | Bin 3244 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnome-gsame.png | Bin 4263 -> 0 bytes + gi/demos/gtk-demo/demos/data/gnu-keys.png | Bin 3852 -> 0 bytes + gi/demos/gtk-demo/demos/data/gtk-logo-rgb.gif | Bin 6427 -> 0 bytes + gi/demos/gtk-demo/demos/test.py | 14 - + gi/demos/gtk-demo/gtk-demo.py | 266 ---- + gi/examples/Makefile.am | 2 - + gi/examples/cairo-demo.py | 121 -- + gi/tests/test_everything.py | 270 ---- + gi/tests/test_gi.py | 1624 + -------------------- + gi/tests/test_overrides.py | 132 -- + pygi-Makefile.am | 28 - + pygi-configure.ac | 60 - + pygi.doap | 34 - + pygobject.doap | 16 +- + tests/Makefile.am | 23 +- + tests/test_everything.py | 270 ++++ + tests/test_gi.py | 1624 + ++++++++++++++++++++ + tests/test_overrides.py | 132 ++ + 68 files changed, 4124 insertions(+), 4186 deletions(-) + +commit 597bd64319d7966045b5b8613ca6fc85668c3f56 +Merge: ec8d148 fa91dfd +Author: Johan Dahlin +Date: Sun Jun 20 10:53:46 2010 -0300 + + Merge branch 'pygi-merge' + +commit fa91dfd3ec79ecd03c9fb59b9363eab4a5b3ff2b +Author: Johan Dahlin +Date: Sun Jun 20 10:53:36 2010 -0300 + + Prepare pygi move + + .gitignore | 40 - + HACKING | 26 - + Makefile.am | 28 - + autogen.sh | 166 -- + configure.ac | 60 - + demos/gtk-demo/demos/__init__.py | 0 + demos/gtk-demo/demos/appwindow.py | 411 ----- + demos/gtk-demo/demos/assistant.py | 134 -- + demos/gtk-demo/demos/builder.py | 57 - + demos/gtk-demo/demos/button_box.py | 121 -- + demos/gtk-demo/demos/clipboard.py | 238 --- + demos/gtk-demo/demos/colorselector.py | 121 -- + demos/gtk-demo/demos/combobox.py | 282 ---- + demos/gtk-demo/demos/data/alphatest.png | Bin 26529 -> + 0 bytes + demos/gtk-demo/demos/data/apple-red.png | Bin 3545 -> 0 bytes + demos/gtk-demo/demos/data/background.jpg | Bin 22219 -> + 0 bytes + demos/gtk-demo/demos/data/demo.ui | 258 ---- + demos/gtk-demo/demos/data/floppybuddy.gif | Bin 5216 -> 0 bytes + demos/gtk-demo/demos/data/gnome-applets.png | Bin 3090 -> 0 bytes + demos/gtk-demo/demos/data/gnome-calendar.png | Bin 2755 -> 0 bytes + demos/gtk-demo/demos/data/gnome-foot.png | Bin 2916 -> 0 bytes + demos/gtk-demo/demos/data/gnome-fs-directory.png | Bin 2044 -> 0 bytes + demos/gtk-demo/demos/data/gnome-fs-regular.png | Bin 1795 -> 0 bytes + demos/gtk-demo/demos/data/gnome-gimp.png | Bin 3410 -> 0 bytes + demos/gtk-demo/demos/data/gnome-gmush.png | Bin 3244 -> 0 bytes + demos/gtk-demo/demos/data/gnome-gsame.png | Bin 4263 -> 0 bytes + demos/gtk-demo/demos/data/gnu-keys.png | Bin 3852 -> 0 bytes + demos/gtk-demo/demos/data/gtk-logo-rgb.gif | Bin 6427 -> 0 bytes + demos/gtk-demo/demos/test.py | 14 - + demos/gtk-demo/gtk-demo.py | 266 ---- + examples/Makefile.am | 2 - + examples/cairo-demo.py | 121 -- + gi/.gitignore | 40 + + gi/HACKING | 26 + + gi/demos/gtk-demo/demos/__init__.py | 0 + gi/demos/gtk-demo/demos/appwindow.py | 411 +++++ + gi/demos/gtk-demo/demos/assistant.py | 134 ++ + gi/demos/gtk-demo/demos/builder.py | 57 + + gi/demos/gtk-demo/demos/button_box.py | 121 ++ + gi/demos/gtk-demo/demos/clipboard.py | 238 +++ + gi/demos/gtk-demo/demos/colorselector.py | 121 ++ + gi/demos/gtk-demo/demos/combobox.py | 282 ++++ + gi/demos/gtk-demo/demos/data/alphatest.png | Bin 0 -> + 26529 bytes + gi/demos/gtk-demo/demos/data/apple-red.png | Bin 0 -> 3545 bytes + gi/demos/gtk-demo/demos/data/background.jpg | Bin 0 -> + 22219 bytes + gi/demos/gtk-demo/demos/data/demo.ui | 258 ++++ + gi/demos/gtk-demo/demos/data/floppybuddy.gif | Bin 0 -> 5216 bytes + gi/demos/gtk-demo/demos/data/gnome-applets.png | Bin 0 -> 3090 bytes + gi/demos/gtk-demo/demos/data/gnome-calendar.png | Bin 0 -> 2755 bytes + gi/demos/gtk-demo/demos/data/gnome-foot.png | Bin 0 -> 2916 bytes + .../gtk-demo/demos/data/gnome-fs-directory.png | Bin 0 -> 2044 bytes + gi/demos/gtk-demo/demos/data/gnome-fs-regular.png | Bin 0 -> 1795 bytes + gi/demos/gtk-demo/demos/data/gnome-gimp.png | Bin 0 -> 3410 bytes + gi/demos/gtk-demo/demos/data/gnome-gmush.png | Bin 0 -> 3244 bytes + gi/demos/gtk-demo/demos/data/gnome-gsame.png | Bin 0 -> 4263 bytes + gi/demos/gtk-demo/demos/data/gnu-keys.png | Bin 0 -> 3852 bytes + gi/demos/gtk-demo/demos/data/gtk-logo-rgb.gif | Bin 0 -> 6427 bytes + gi/demos/gtk-demo/demos/test.py | 14 + + gi/demos/gtk-demo/gtk-demo.py | 266 ++++ + gi/examples/Makefile.am | 2 + + gi/examples/cairo-demo.py | 121 ++ + gi/tests/Makefile.am | 22 + + gi/tests/runtests.py | 21 + + gi/tests/test_everything.py | 270 ++++ + gi/tests/test_gi.py | 1624 + ++++++++++++++++++++ + gi/tests/test_overrides.py | 132 ++ + pygi-Makefile.am | 28 + + pygi-configure.ac | 60 + + tests/Makefile.am | 22 - + tests/runtests.py | 21 - + tests/test_everything.py | 270 ---- + tests/test_gi.py | 1624 + -------------------- + tests/test_overrides.py | 132 -- + 73 files changed, 4248 insertions(+), 4414 deletions(-) + +commit ec8d148eccbb3714093f21b595ea77ae4c7c3bce +Author: Johan Dahlin +Date: Sun Jun 20 10:49:55 2010 -0300 + + [giounix] Make it possible to compile on glib 2.20 + + gio/unix.override | 2 ++ + 1 file changed, 2 insertions(+) + +commit 606018a2c551d890fc2bb987d99683f777598bda +Author: John (J5) Palmieri +Date: Mon Jun 7 16:32:29 2010 -0400 + + Don't free transfer full struct pointers because we can't do it safely + + * Most libraries which are sending back structs as transfer-full + are either annotated incorrectly or should be sending boxed types + * It is much better to throw a warning and leak memory than it is to + call free on an unknown struct pointer. Doing so may cause + a double free + * Specific case is gdk_atom_intern where a GdkAtom is not actually + a pointer + but an integer stuffed into a pointer type + + https://bugzilla.gnome.org/show_bug.cgi?id=620898 + + gi/pygi-argument.c | 9 ++++++++- + gi/pygi-invoke.c | 11 +++++++++-- + 2 files changed, 17 insertions(+), 3 deletions(-) + +commit 433ee2aa029a1482961f478252a06492bd3498e6 +Author: Sjoerd Simons +Date: Tue Jun 15 11:42:28 2010 +0200 + + Release the lock when potentially invoking Python code. + + * gobject/pygobject.c: Release GIL lock when retrieving properties + and when clearing a PyGObject. + + https://bugzilla.gnome.org/show_bug.cgi?id=530935 + + gobject/pygobject.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +commit aa1e82c7eb87620bd73e1edb486f5b9e0d49aa96 +Author: John (J5) Palmieri +Date: Mon Jun 14 18:36:57 2010 -0400 + + add combobox example + + demos/gtk-demo/demos/combobox.py | 282 + +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 282 insertions(+) + +commit a8668694da59c2dd959c875f13337e64ca22f7e9 +Author: John (J5) Palmieri +Date: Mon Jun 14 13:43:53 2010 -0400 + + fix leak in the allow None callbacks patch + + gi/pygi-callbacks.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 729072e73d65e7fd5b5197ebe5a8c53a449d0ec0 +Author: John (J5) Palmieri +Date: Mon Jun 7 17:12:09 2010 -0400 + + Allow passing None for callbacks which are annotated allow-none + + * Many callbacks are optional parameters yet we were asserting on + Py_None + * We now check to see if allow_none is set when setting up callbacks, + if it is set and py_function == Py_None, we set the closure to NULL + and return + * pygi-invoke.c now checks to see if the closure == NULL when setting + arguments + * if it is NULL there is no reason to set the the destroy notify + handler + so we skip that too + + https://bugzilla.gnome.org/show_bug.cgi?id=620906 + + gi/pygi-callbacks.c | 7 +++++++ + gi/pygi-invoke.c | 14 +++++++++++--- + tests/test_everything.py | 4 ++++ + 3 files changed, 22 insertions(+), 3 deletions(-) + +commit a3eb5c7de5836c37aa7ae01dbe98996ec2632c17 +Author: Paolo Borelli +Date: Mon Jun 14 19:06:45 2010 +0200 + + Fix to match latest gtk annotations + + demos/gtk-demo/demos/appwindow.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit 6306dd73cc74aa9202569eac0eaaa5f825c8dc59 +Author: John (J5) Palmieri +Date: Tue Jun 8 15:03:49 2010 -0400 + + fix variable member names in Gdk.Color override + + * override was using r, g, and b for the red, green, blue components + but + the struct specifies red, green, blue so we need to use those names + + https://bugzilla.gnome.org/show_bug.cgi?id=621007 + + gi/overrides/Gdk.py | 10 +++++----- + tests/test_overrides.py | 6 +++--- + 2 files changed, 8 insertions(+), 8 deletions(-) + +commit d182630e1128fef6f1c2aea28ccd8da4bddd2c8f +Author: Tomeu Vizoso +Date: Thu Jun 10 20:23:13 2010 +0200 + + Post release version bump to 2.21.3 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c4e64d5d264593051b9a3131e4985a58e8e76f8b +Author: Tomeu Vizoso +Date: Thu Jun 10 20:21:13 2010 +0200 + + Update NEWS and release PyGObject-2.21.2 + + NEWS | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +commit e0fe844d5fe8f7e26316f197444fd4143ed36adf +Author: Tomeu Vizoso +Date: Thu Jun 10 20:09:07 2010 +0200 + + Remove deleted files from the Makefile. + + test_conversion.py + test_enum.py + test_gtype.py + test_subtype.py + + tests/Makefile.am | 4 ---- + 1 file changed, 4 deletions(-) + +commit 495a301cb81c5e914bcef905999265604faa27fc +Author: Tomeu Vizoso +Date: Thu Jun 10 19:39:09 2010 +0200 + + Add myself to the maintainers list in the README + + README | 1 + + 1 file changed, 1 insertion(+) + +commit 04627488220b4f2a16e11f8982af7866fea9f7eb +Author: Tomeu Vizoso +Date: Thu Jun 10 19:24:31 2010 +0200 + + Drop sinkfuncs. + + * use g_object methods to sink floating refs instead of allowing + custom sink functions to be registered + * we now sink inside of pygobject_new_full to handle cases where + a library creates its own gobject via g_object_new and just + needs a python wrapper + - a previous patch had done the sink when creating the gobject, + since it needs to call pygobject_new_full to wrap the object, + this patch handles both cases (e.g. pygobject created object + and externally created gobject) + + https://bugzilla.gnome.org/show_bug.cgi?id=583909 + + gobject/gobjectmodule.c | 3 +-- + gobject/pygobject.c | 42 ++++++++---------------------------------- + gobject/pygobject.h | 1 + + 3 files changed, 10 insertions(+), 36 deletions(-) + +commit 07df124dc06cf506634e95d08397f50a2d07fce2 +Author: Steve Frécinaux +Date: Mon Jun 7 09:47:23 2010 +0200 + + Make the "wrong argument count" exception more explicit. + + Previously we had messages like this one: + TypeError: takes exactly 2 argument(s) (1 given) + + With this patch, they become like this: + TypeError: get_end_iter() takes exactly 2 argument(s) (1 given) + + It makes things much easier to debug when there are several pygi calls + on the same line. + + https://bugzilla.gnome.org/show_bug.cgi?id=620804 + + gi/pygi-invoke.c | 3 ++- + tests/test_everything.py | 6 ++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit b435319fe830a909cc4d414533b3b66574931e24 +Author: Steve Frécinaux +Date: Mon Jun 7 09:54:06 2010 +0200 + + Use bash explicitely in the pre-commit hook. + + The "builtin" command is not available in all sh flavours, so the + pre-commit hook is going to fail if you use dash or others instead of + bash as your default 'sh' alias. + + https://bugzilla.gnome.org/show_bug.cgi?id=620805 + + pre-commit.hook | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e9ee2916494eb7654004925c1ee1e94f99b14f1a +Author: John (J5) Palmieri +Date: Tue Jun 8 16:55:26 2010 -0400 + + colorselector demo + + demos/gtk-demo/demos/colorselector.py | 121 + ++++++++++++++++++++++++++++++++++ + 1 file changed, 121 insertions(+) + +commit ec598128de9e90dccab662ed2f5511c8d659e156 +Author: Tomeu Vizoso +Date: Tue Jun 8 15:48:33 2010 +0200 + + Update PyGObject dependency to 2.21.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 87774a17bd607724a56e18c2eb1ac71b04b7079d +Author: Tomeu Vizoso +Date: Tue Jun 8 10:40:39 2010 +0200 + + Add myself to maintainers + + MAINTAINERS | 4 ++++ + pygobject.doap | 7 +++++++ + 2 files changed, 11 insertions(+) + +commit 46c91a11d448e5e11d142d3362aff1483226bca4 +Author: Colin Walters +Date: Wed May 5 13:54:27 2010 -0400 + + Clear error if we failed the import + + Otherwise we leave the exception set which causes bizarre problems + later in unrelated code. + + https://bugzilla.redhat.com/show_bug.cgi?id=569885 + + https://bugzilla.gnome.org/show_bug.cgi?id=617796 + + gobject/pygi-external.h | 2 ++ + 1 file changed, 2 insertions(+) + +commit c1c41576d053cc1cdd8366d8cd1e59fff1c3a9c6 +Author: John (J5) Palmieri +Date: Mon Jun 7 17:19:30 2010 -0400 + + fix some typos and add a link to a patch which fixes a FIXME + + demos/gtk-demo/demos/clipboard.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit e7fabb5024d94a3166766e5fca740741bc50380a +Author: John (J5) Palmieri +Date: Mon Jun 7 16:21:42 2010 -0400 + + clipboard demo + + demos/gtk-demo/demos/clipboard.py | 235 + ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 235 insertions(+) + +commit e0f1dce5ec58d071759f886697501da6eeea549d +Author: John (J5) Palmieri +Date: Sun Jun 6 13:27:46 2010 -0400 + + set is_fully_bound to false + + demos/gtk-demo/demos/button_box.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 986db1c73746d3a8ad7d8d5141c7eed194e7b948 +Author: John (J5) Palmieri +Date: Sat Jun 5 23:53:36 2010 -0400 + + new button box demo + + demos/gtk-demo/demos/button_box.py | 121 + +++++++++++++++++++++++++++++++++++++ + 1 file changed, 121 insertions(+) + +commit e9f5f8a829121e59367bae690442150f144946ad +Author: John (J5) Palmieri +Date: Sat Jun 5 23:26:03 2010 -0400 + + set is_fully_bound to True fro builder example + + demos/gtk-demo/demos/builder.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d9968c3a4dea1d4a73a9376009cf486c80ea3da6 +Author: John (J5) Palmieri +Date: Sat Jun 5 23:24:36 2010 -0400 + + fix up formatting in demos + + demos/gtk-demo/demos/appwindow.py | 16 ++++++++-------- + demos/gtk-demo/demos/assistant.py | 24 ++++++++++++------------ + demos/gtk-demo/demos/builder.py | 2 +- + 3 files changed, 21 insertions(+), 21 deletions(-) + +commit ffca02536bafb55e8c3bce31cd992365207429f6 +Author: John (J5) Palmieri +Date: Sat Jun 5 14:54:47 2010 -0400 + + add the builder demo + + demos/gtk-demo/demos/builder.py | 57 + +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +commit a96dbafdf562a2ac6bde4df27919d3628689dbdb +Author: John (J5) Palmieri +Date: Fri Jun 4 17:48:24 2010 -0400 + + add assistant demo + + demos/gtk-demo/demos/assistant.py | 134 + ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 134 insertions(+) + +commit 7e1b8cf32f33d45603aaec76afb0d14be84ffd94 +Author: John (J5) Palmieri +Date: Fri Jun 4 16:56:46 2010 -0400 + + add formatting rules and copyright notice + + demos/gtk-demo/demos/appwindow.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit 03b99692b81631d397ab62dcd263341465bcee88 +Author: John (J5) Palmieri +Date: Fri Jun 4 16:26:54 2010 -0400 + + add the gtk-demo app along with a couple of demos + + * note there are still a couple of patches in bugzilla that are + needed for this + to run correctly: + - http://bugzilla-attachments.gnome.org/attachment.cgi?id=162682 + - http://bugzilla-attachments.gnome.org/attachment.cgi?id=162764 + + demos/gtk-demo/demos/__init__.py | 0 + demos/gtk-demo/demos/appwindow.py | 393 + +++++++++++++++++++++++ + demos/gtk-demo/demos/data/alphatest.png | Bin 0 -> 26529 bytes + demos/gtk-demo/demos/data/apple-red.png | Bin 0 -> 3545 bytes + demos/gtk-demo/demos/data/background.jpg | Bin 0 -> 22219 bytes + demos/gtk-demo/demos/data/demo.ui | 258 +++++++++++++++ + demos/gtk-demo/demos/data/floppybuddy.gif | Bin 0 -> 5216 bytes + demos/gtk-demo/demos/data/gnome-applets.png | Bin 0 -> 3090 bytes + demos/gtk-demo/demos/data/gnome-calendar.png | Bin 0 -> 2755 bytes + demos/gtk-demo/demos/data/gnome-foot.png | Bin 0 -> 2916 bytes + demos/gtk-demo/demos/data/gnome-fs-directory.png | Bin 0 -> 2044 bytes + demos/gtk-demo/demos/data/gnome-fs-regular.png | Bin 0 -> 1795 bytes + demos/gtk-demo/demos/data/gnome-gimp.png | Bin 0 -> 3410 bytes + demos/gtk-demo/demos/data/gnome-gmush.png | Bin 0 -> 3244 bytes + demos/gtk-demo/demos/data/gnome-gsame.png | Bin 0 -> 4263 bytes + demos/gtk-demo/demos/data/gnu-keys.png | Bin 0 -> 3852 bytes + demos/gtk-demo/demos/data/gtk-logo-rgb.gif | Bin 0 -> 6427 bytes + demos/gtk-demo/demos/test.py | 14 + + demos/gtk-demo/gtk-demo.py | 266 +++++++++++++++ + 19 files changed, 931 insertions(+) + +commit b3b1f029d8d16cf9bd74160009808147d07e3b3f +Author: Tomeu Vizoso +Date: Fri Jun 4 11:25:08 2010 +0200 + + Update gobject-introspection dependency to 0.6.14 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 45c4e46ae93bd83a0e3f3550df6c64ce96bbedb4 +Author: Tomeu Vizoso +Date: Fri Jun 4 11:23:41 2010 +0200 + + Post-release version bump to 0.6.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7a94270dac48b67aabc7dbad156cf1180db9cb5e +Author: Tomeu Vizoso +Date: Fri Jun 4 08:29:42 2010 +0200 + + Pre-release version bump 0.6.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1e42ee6eb25a07a5201f24ffeac18d298a98477e +Author: John (J5) Palmieri +Date: Fri May 28 10:03:11 2010 -0400 + + support for caller-allocates annotations for structs + + * out caller-allocates parameters expect an already constructed + structure + to be passed in by reference. It is then modified and the caller + uses the + modified value. We support this by using only one level of pointer + indirection. + * Only structs are considered to be caller-allocates parameters + even if + they are marked as such by GI. This is because the GI scanner + isn't smart + enough to correctly guess 100% of the time + * GValues are a special case of a caller-allocates parameter when + cleaning + up (e.g. g_value_unset is called). GValues make no sense in + a scripting + language. Developers should never deal with them. + + https://bugzilla.gnome.org/show_bug.cgi?id=620406 + + gi/pygi-invoke.c | 73 + +++++++++++++++++++++++++++++++++++++++++++++--- + tests/test_everything.py | 28 +++++++++++++++++++ + 2 files changed, 97 insertions(+), 4 deletions(-) + +commit c3f467e0ae99aa78c2fdb91b973a272d2fe970bd +Author: John (J5) Palmieri +Date: Wed Jun 2 14:14:16 2010 -0400 + + don't import gobject directly in the tests + + * use from gi.repository import GObject + + tests/test_overrides.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 46b5133fea4cd5db57a360b3cbe9ee923e27560c +Author: Tomeu Vizoso +Date: Tue Jun 1 14:28:57 2010 +0200 + + Wrap C arrays in structs as GArrays before converting to Python + + https://bugzilla.gnome.org/show_bug.cgi?id=620247 + + gi/pygi-info.c | 11 +++++++++++ + tests/test_gi.py | 17 +++++++++++++++++ + 2 files changed, 28 insertions(+) + +commit 5f0f9a9c9145a129a063b041424c3109a24d9ead +Author: Tomeu Vizoso +Date: Wed May 26 13:20:27 2010 +0200 + + Install pre-commit hook that checks the code changes for style + conformance + + autogen.sh | 7 +++++++ + pre-commit.hook | 39 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+) + +commit 1319da5b7f483e48a90b0b7489f77236ba26f479 +Author: Tomeu Vizoso +Date: Wed May 26 12:19:17 2010 +0200 + + Apply consistent whitespace formatting with: + + astyle -p -d -c -S -U -M60 + + This won't affect git blame nor git diff if the switch -w is used. + + gi/gimodule.c | 138 +++---- + gi/pygi-argument.c | 960 + ++++++++++++++++++++++++------------------------ + gi/pygi-boxed.c | 108 +++--- + gi/pygi-callbacks.c | 154 ++++---- + gi/pygi-callbacks.h | 8 +- + gi/pygi-closure.c | 270 +++++++------- + gi/pygi-closure.h | 18 +- + gi/pygi-foreign-cairo.c | 36 +- + gi/pygi-foreign-cairo.h | 36 +- + gi/pygi-foreign.c | 54 +-- + gi/pygi-foreign.h | 10 +- + gi/pygi-info.c | 646 ++++++++++++++++---------------- + gi/pygi-invoke.c | 380 +++++++++---------- + gi/pygi-repository.c | 114 +++--- + gi/pygi-struct.c | 88 ++--- + gi/pygi-type.c | 32 +- + gi/pygi.h | 20 +- + gi/pygobject-external.h | 14 +- + 18 files changed, 1544 insertions(+), 1542 deletions(-) + +commit 6156f15cb15b4c20e975527227135d49207c520a +Author: Tomeu Vizoso +Date: Tue May 25 14:08:51 2010 +0200 + + Prepend gi.repository to the __module__ attribute of wrapper classes. + + https://bugzilla.gnome.org/show_bug.cgi?id=619597 + + gi/module.py | 4 ++-- + tests/test_gi.py | 4 +++- + 2 files changed, 5 insertions(+), 3 deletions(-) + +commit 097b92983b7a322c58fecb1e691ba6ddf5035548 +Author: Tomeu Vizoso +Date: Tue May 25 14:17:13 2010 +0200 + + Correctly identify at creation time: + + * if the class is defined in python -> hook up vfuncs + * if the class wraps a type from a .typelib -> set atributes + * else (GLocalFile) -> do nothing + + https://bugzilla.gnome.org/show_bug.cgi?id=619604 + + gi/types.py | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +commit 686e10fcdb108af9758eb025a3447813c3513a93 +Author: Tomeu Vizoso +Date: Thu Apr 29 10:55:13 2010 +0200 + + Dont complain if another base has implemented the method + + https://bugzilla.gnome.org/show_bug.cgi?id=617153 + + gi/types.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 9f34d120845d936b04546a5cea599ec67e9181a7 +Author: John (J5) Palmieri +Date: Mon May 24 16:16:50 2010 -0400 + + fix up Builder override, add new override methods, and add unit tests + + * check for flags when connecting signals now that we get gi + GObject types + * override the add_from_string and add_objects_from string overrides + so + that you don't have to pass in the length of the buffer + * add test that loads objects from strings and connects them to + signals + + gi/overrides/Gtk.py | 19 +++++++++++-- + tests/test_overrides.py | 72 + ++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 86 insertions(+), 5 deletions(-) + +commit 1561d2977691f1cb8684f183a2e274c47960d931 +Author: Tomeu Vizoso +Date: Mon May 24 18:48:10 2010 +0200 + + Improve handling of subclasses without __gtype_name__ + + Gives a better message at type registration. + + https://bugzilla.gnome.org/show_bug.cgi?id=616849 + + gi/gimodule.c | 9 +++++++++ + tests/test_gi.py | 13 ++++++++++++- + 2 files changed, 21 insertions(+), 1 deletion(-) + +commit c9d44d4d46c3da3a445000b1db592baa9c378a92 +Author: Tomeu Vizoso +Date: Fri Apr 30 18:17:50 2010 +0200 + + Add support for GArray args + + https://bugzilla.gnome.org/show_bug.cgi?id=617054 + + gi/pygi-invoke.c | 11 +++++++---- + tests/test_gi.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 57 insertions(+), 4 deletions(-) + +commit c171579ee22681e1ee4ad33441c89f1053bdc3d1 +Author: John (J5) Palmieri +Date: Mon May 24 11:48:16 2010 -0400 + + check refcounting of callback userdata in unit tests + + tests/test_everything.py | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +commit 8eb809468fe3e1f8e4f92bd7f25d96f9cf802cd4 +Author: Tomeu Vizoso +Date: Sat May 22 15:12:37 2010 +0200 + + Add support for out args in callbacks + + This patch refactors argument marshalling for closures in + preparation for more complete support. + + Also fixes a bug in the memory management of user_data args. + + https://bugzilla.gnome.org/show_bug.cgi?id=617780 + + gi/pygi-closure.c | 335 + +++++++++++++++++++++++++++++++++++++++++------------- + tests/test_gi.py | 4 + + 2 files changed, 263 insertions(+), 76 deletions(-) + +commit 0df0c956bb2476392c9d81f0a243a7e84c067166 +Author: Tomeu Vizoso +Date: Sun May 23 10:59:27 2010 +0200 + + If None is passed to an interface which takes an object, convert it to + NULL + + * without this patch PyGI treats the None object as a PyGObject + and ends up + extracting garbage data causing a crash + * None's equivalent in C is NULL so we must provide a special case + where we + marshal the None as NULL + + https://bugzilla.gnome.org/show_bug.cgi?id=617880 + + gi/pygi-argument.c | 5 +++++ + tests/test_everything.py | 6 ++++++ + 2 files changed, 11 insertions(+) + +commit 60fdf4b8f738dd0f5c190bc18ddf010032d3c5ca +Author: John (J5) Palmieri +Date: Sat May 22 14:06:37 2010 +0200 + + correctly handle floating objects in gtk + + * this is a stopgap so we work with older pygobject libraries + * there is a patch at + https://bugzilla.gnome.org/show_bug.cgi?id=583909 + which adds the correct fix to pygobject + * once pygobject accepts the above patch this patch does not need to + be reverted because pygobject_register_sinkfunc becomes a noop + * add tests (Tomeu) + + https://bugzilla.gnome.org/show_bug.cgi?id=619007 + + gi/gimodule.c | 12 ++++++++++++ + tests/test_everything.py | 3 +++ + 2 files changed, 15 insertions(+) + +commit 4b369f8aca980fc6a582094d6648f40fe4af5e9f +Author: John (J5) Palmieri +Date: Sat May 22 13:21:30 2010 +0200 + + Return an empty list when a NULL GList and GSList is returned + + * In GTK a GList * and GSList set to NULL is equivilant to empty + list. All + GTK list methods can take a NULL and treat it as an empty list. e.g. + g_list_length(NULL) returns 0 + * PyGtk consitently returns empty list when a NULL is returned for + GList or + GSList return + * Many PyGtk apps do this: + for i in range(len(obj.get_list())): + ... + * If we were to continue to return None, they would have to add + a check + which is needlessly verbose and isn't very "pythonic" + + https://bugzilla.gnome.org/show_bug.cgi?id=619232 + + gi/pygi-argument.c | 6 ------ + tests/test_everything.py | 4 ++-- + 2 files changed, 2 insertions(+), 8 deletions(-) + +commit 71a2148b00dfdda99e0d961ae39b901608724e59 +Author: Steve Frécinaux +Date: Fri May 21 19:05:03 2010 +0200 + + Fix warning in configure. + + The warning is caused by the use of the construction 'CFLAGS+=' in a + sh version that doesn't understand it (in this case, 'dash'). + + https://bugzilla.gnome.org/show_bug.cgi?id=619311 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit aa0357e468eb91e0f3707346e9b32f312fbf51d3 +Author: Tomeu Vizoso +Date: Thu Apr 29 13:06:15 2010 +0200 + + GTypeInterface cannot be unrefed + + https://bugzilla.gnome.org/show_bug.cgi?id=617159 + + gi/gimodule.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit ab1aaff108d23aabd28c3634edfb67236eb55460 +Author: John (J5) Palmieri +Date: Sat May 22 13:09:48 2010 +0200 + + fix NULL array unit tests and fix crasher when sending None as + an array + + * Unit tests were wrong given the annotation for + test_array_int_null_in and + test_array_int_null_out: + + /** + * test_array_int_null_in: + * @arr: (array length=len) (allow-none): + * @len: length + */ + + -- and -- + + /** + * test_array_int_null_out: + * @arr: (out) (array length=len) (allow-none): + * @len: (out) : length + */ + + The (array length=len) annotation meant we don't pass in or + receive the len argument as this is handled under the hood + (Python's representation of an array, the list type, encapsulates + the length inside the type) + + * Fixing up the tests revealed a latent crasher bug when passing + None to an + interface that accepts an array. The fix was to check for NULL + and set + the length argument to 0 when invoking the bound method. + + https://bugzilla.gnome.org/show_bug.cgi?id=619235 + + gi/pygi-invoke.c | 6 +++++- + tests/test_everything.py | 4 ++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +commit e928ea9b1df9d87314ff8e93479530e26be9bd87 +Author: John (J5) Palmieri +Date: Fri May 14 14:57:27 2010 -0400 + + don't error out on methods with callbacks as return type + + * Right now we just throw an error which means API's like + gtk_about_dialog_set_url_hook aren't able to be called, + * this allows us to call such APIs while printing a warning, in + most cases + API such as this doesn't need to be used anymore and is a result of + early GTK development + + gi/pygi-argument.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +commit d963007aab123f4e53a944a66a935db2d22907c2 +Author: John (J5) Palmieri +Date: Mon May 17 11:54:34 2010 -0400 + + reset sys.argv to the return value of Gtk.init_check + + * applications which check command line arguments will error out if it + encounters a GTK command line switch such as --g-fatal-warnings. + * The Gtk.init* API reads these switches and returns a new argv with + the GTK + switches stripped out + * In C argv is modified in place but in Python we must set sys.argv + to the + new modified argument list + * fixes https://bugzilla.gnome.org/show_bug.cgi?id=618889 + + gi/overrides/Gtk.py | 1 + + 1 file changed, 1 insertion(+) + +commit 897420ed97cc4a7b8a806894df5e76ed72617614 +Author: John (J5) Palmieri +Date: Wed May 12 14:25:32 2010 -0400 + + add GtkUIManager and GtkActionGroup overrides + + * fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=618476 + + gi/overrides/Gtk.py | 167 + +++++++++++++++++++++++++++++++++++++++++++++++- + tests/test_overrides.py | 45 +++++++++++++ + 2 files changed, 211 insertions(+), 1 deletion(-) + +commit 865939d29c1e9d69dbe6b9cf89477b5516dbff1f +Author: Zach Goldberg +Date: Thu May 13 01:02:24 2010 -0400 + + Bump version for development to 0.5.2 (hopefully 0.6) + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2674a9546b0246d4a75d71cf1708df77dc0173f9 +Author: Tomeu Vizoso +Date: Wed May 5 15:54:39 2010 +0200 + + Fix overrides.Gdk.Color.__new__ args + + https://bugzilla.gnome.org/show_bug.cgi?id=617757 + + gi/overrides/Gdk.py | 2 +- + tests/Makefile.am | 3 ++- + tests/test_overrides.py | 22 ++++++++++++++++++++++ + 3 files changed, 25 insertions(+), 2 deletions(-) + +commit c20b9f632a35bada1320ccc10fb7d5b2c06b9a88 +Author: John (J5) Palmieri +Date: Thu Apr 29 14:55:33 2010 -0400 + + wrap GObject module so we can go through GI when requesting attrs + + * This gives us the best of both worlds. + - We remain backwards compatable with pygobject by checking for + existing + attrs in the gobject module + - If an attr does not exist we use the GI mechanism to look it up + so that + things like flags look the same whether exported from GObject, Gtk + or any GI managed library + + * add DynamicGObjectModule tests and make tests use the new module + - change import gobject to from gi.repository import GObject + + gi/importer.py | 6 ++-- + gi/module.py | 30 ++++++++++++++++ + tests/test_everything.py | 6 ++-- + tests/test_gi.py | 93 + ++++++++++++++++++++++++++---------------------- + 4 files changed, 87 insertions(+), 48 deletions(-) + +commit 64324a4c629432b2e688299b6edbfd5da4439a2a +Author: John (J5) Palmieri +Date: Fri Apr 30 14:11:55 2010 -0400 + + override Gdk.Drawable to add cairo_create convinience method + + gi/overrides/Gdk.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 17fa1289b1e2ed841dd5de09a2ec7c25d401886e +Author: Tomeu Vizoso +Date: Mon May 3 19:13:46 2010 +0200 + + Fix passing callbacks as constructor args + + https://bugzilla.gnome.org/show_bug.cgi?id=617551 + + gi/pygi-callbacks.c | 3 ++- + gi/pygi-callbacks.h | 1 + + gi/pygi-invoke.c | 7 +++++-- + tests/test_everything.py | 21 +++++++++++++++++++++ + 4 files changed, 29 insertions(+), 3 deletions(-) + +commit f9fff978d56ddf2c012b906169ae16abb7fdc2a5 +Author: Tomeu Vizoso +Date: Wed May 5 08:06:03 2010 +0200 + + Avoid freeing garbage + + gi/pygi-invoke.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 5e20c018ae09a936f5ff140df5d1c133c98e98ba +Author: Tomeu Vizoso +Date: Thu Apr 29 13:09:03 2010 +0200 + + Only hookup vfunc implementations for locally-defined methods + + https://bugzilla.gnome.org/show_bug.cgi?id=617160 + + gi/types.py | 10 +++++++++- + tests/test_gi.py | 10 ++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +commit 3e61e7d4450a2bb133c7f3862e0962a35339ce8d +Author: Tomeu Vizoso +Date: Mon May 3 18:35:13 2010 +0200 + + Fix passing GDestroyNotify + + https://bugzilla.gnome.org/show_bug.cgi?id=617542 + + gi/pygi-invoke.c | 3 ++- + tests/test_everything.py | 10 ++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +commit 9669acd0fad193013ef3505ae231588307f9834c +Author: Tomeu Vizoso +Date: Mon May 3 12:23:58 2010 +0200 + + Move invocation code to its own file + + https://bugzilla.gnome.org/show_bug.cgi?id=617107 + + gi/Makefile.am | 2 + + gi/pygi-info.c | 884 + ---------------------------------------------------- + gi/pygi-invoke.c | 909 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-invoke.h | 37 +++ + gi/pygi-private.h | 1 + + 5 files changed, 949 insertions(+), 884 deletions(-) + +commit 9b923a68dfde06fc2df6321b3f1e53f1c57b3666 +Author: John (J5) Palmieri +Date: Tue Apr 27 19:13:08 2010 -0400 + + Add the Gtk.Builder override + + gi/overrides/Gtk.py | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +commit 9fc6783406b8263ebd67ceae2730b4e86689b43e +Author: Tomeu Vizoso +Date: Fri Apr 30 15:00:52 2010 +0200 + + Fix GAsyncReadyCallback + + https://bugzilla.gnome.org/show_bug.cgi?id=616236 + + gi/pygi-closure.c | 8 +++++++- + tests/test_everything.py | 16 ++++++++++++++++ + 2 files changed, 23 insertions(+), 1 deletion(-) + +commit 5657ccaaec09e2a3194ea2e9a923724bcc66759e +Author: Tomeu Vizoso +Date: Thu Apr 29 18:32:50 2010 +0200 + + Add override for Gdk.Color + + https://bugzilla.gnome.org/show_bug.cgi?id=617162 + + gi/overrides/Gdk.py | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +commit 4410abd589a2f64cfbd7bbcb4013fae9e4aa734f +Author: John (J5) Palmieri +Date: Wed Apr 28 13:19:48 2010 -0400 + + make __all__ be a list of strings, fix override mechanism to use + it correctly + + * before we were adding classes to the __all__ module property but + the convention is to use the name of the class + * simplified the check to just check the name against __all__ + instead of trying to get the class and then checking the class + against None as well as in __all__ + * went through all the overrides and made __all__ be a list of strings + + gi/module.py | 9 ++++----- + gi/overrides/GIMarshallingTests.py | 2 +- + gi/overrides/Gdk.py | 2 +- + 3 files changed, 6 insertions(+), 7 deletions(-) + +commit 64fa8f936bad9a90628df446e690d67d947a0a22 +Author: Tomeu Vizoso +Date: Mon Apr 26 11:41:06 2010 +0200 + + One more step at refactoring _wrap_g_function_info_invoke + + https://bugzilla.gnome.org/show_bug.cgi?id=616357 + + gi/pygi-callbacks.c | 22 +- + gi/pygi-callbacks.h | 4 +- + gi/pygi-info.c | 582 + ++++++++++++++++++++++++++++++---------------------- + 3 files changed, 346 insertions(+), 262 deletions(-) + +commit 7fc5528273edae5ecdd5d8bdf0e5b898eec7a624 +Author: Zach Goldberg +Date: Tue Apr 20 23:23:38 2010 -0400 + + Step 1 of refactoring _wrap_g_function_info_invoke + + Original patch by David Malcom + + This patch bitrots *REALLY* fast. + + https://bugzilla.gnome.org/show_bug.cgi?id=616357 + + gi/pygi-info.c | 417 + +++++++++++++++++++++++++++++---------------------------- + 1 file changed, 214 insertions(+), 203 deletions(-) + +commit 1d9c6b6d76a3e27f66e6f0cfc7b16c5191e4fc22 +Author: Tomeu Vizoso +Date: Tue Apr 27 10:24:35 2010 +0200 + + Dont force subclasses to implement all virtual methods of their bases + + https://bugzilla.gnome.org/show_bug.cgi?id=616674 + + gi/types.py | 4 ++-- + tests/test_gi.py | 15 +++++++++++++++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +commit 8a0c48f4dd512797e5cf132f8ec6fb6d4d1e7aaa +Author: Zach Goldberg +Date: Sun Apr 25 15:09:08 2010 -0400 + + Correct the reference counting of userdata in closure handling + + Without this we lose references on every call and eventually end up + free'ing objects + while they are still in use. + + https://bugzilla.gnome.org/show_bug.cgi?id=616786 + + gi/pygi-closure.c | 3 +++ + tests/test_everything.py | 13 +++++++++++++ + 2 files changed, 16 insertions(+) + +commit 2b12049306bf57513c43d08017185468bf897a4a +Author: Zach Goldberg +Date: Tue Apr 20 22:57:14 2010 -0400 + + Change SCOPE_TYPE_INVALID handling to be a more verbose error. + + (Previous commit did not include the proper error message. I blame + git-bz) + + https://bugzilla.gnome.org/show_bug.cgi?id=616356 + + gi/pygi-closure.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8240320d0b67074ce91bdf7aadcf5951c5a8c45a +Author: Zach Goldberg +Date: Tue Apr 20 23:53:57 2010 -0400 + + Force out arguments to be initialized as NULL. Comes with a test. + + This fix was motivated by a real world library which had a transfer + full + utf8 out argument which sometimes was not set. We would leave + the pointer + dangling and try and free it at the end of invoke() and crash. + Library refused + to change their behavior so we're forced to take care of it on + our end. + + https://bugzilla.gnome.org/show_bug.cgi?id=616043 + + gi/pygi-info.c | 1 + + tests/test_gi.py | 3 +++ + 2 files changed, 4 insertions(+) + +commit 10e558ca283cdd06725bb0d24b5071ccbecc7d13 +Author: Zach Goldberg +Date: Tue Apr 20 22:57:14 2010 -0400 + + Change SCOPE_TYPE_INVALID handling to be a warning and not an error + + Be slightly nicer to library maintainers. It really isn't a fatal + condition + if we don't have a proper scope type, better to leave a good code + comment + and a warning than to cause their code to segv. + + https://bugzilla.gnome.org/show_bug.cgi?id=616356 + + gi/pygi-closure.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit d3b5fae9d609dbcd83deb0fa9102b24faf76787c +Author: Zach Goldberg +Date: Tue Apr 20 22:43:20 2010 -0400 + + Refactor implementation of scope call to allow for multiple calls + during lifetime of function invocation. + + https://bugzilla.gnome.org/show_bug.cgi?id=616343 + + gi/pygi-closure.c | 10 +++++----- + gi/pygi-info.c | 9 +++++++-- + tests/test_everything.py | 9 +++++++++ + 3 files changed, 21 insertions(+), 7 deletions(-) + +commit 3ba666b7ab9c393963922c272e7d87bff50a93f9 +Author: Tomeu Vizoso +Date: Sat Jan 2 16:31:55 2010 +0100 + + Add basic support for unions + + https://bugzilla.gnome.org/show_bug.cgi?id=603598 + + gi/module.py | 3 +- + gi/pygi-argument.c | 24 +++----------- + gi/pygi-boxed.c | 18 +++++++++-- + gi/pygi-info.c | 94 + ++++++++++++++++++++++++++++++++++++++++++++++++------ + gi/pygi-info.h | 1 + + tests/test_gi.py | 56 ++++++++++++++++++++++++++++++++ + 6 files changed, 165 insertions(+), 31 deletions(-) + +commit af9e4e086d160fe7fb24758ed81753e784b198a8 +Author: Simon van der Linden +Date: Fri Jan 22 22:16:32 2010 +0100 + + Bump required GLib version to 2.22 + + Since PyGObject now depends on GLib 2.22.4, there is no need to + keep PyGI + backward-compatible. + + configure.ac | 2 +- + gi/pygi-private.h | 20 -------------------- + 2 files changed, 1 insertion(+), 21 deletions(-) + +commit c0f40de5648e2ebc556c449342a0025ffce2e33b +Author: Tomeu Vizoso +Date: Sun Apr 18 11:50:14 2010 -0400 + + Refactor get_* methods in the *Info wrappers + + https://bugzilla.gnome.org/show_bug.cgi?id=616108 + + gi/pygi-info.c | 360 + +++++++++++++++++++++++++++------------------------------ + 1 file changed, 168 insertions(+), 192 deletions(-) + +commit 24bb89f1310dc2fc8ee6ddaf945342ebf80055cd +Author: Tomeu Vizoso +Date: Tue Apr 20 15:12:47 2010 +0200 + + Print any error messages raised inside _pygi_closure_handle + + https://bugzilla.gnome.org/show_bug.cgi?id=616279 + + gi/pygi-closure.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit d1ba23cdd05686ea721425f233371d573a2e9cce +Author: Tomeu Vizoso +Date: Thu Apr 22 19:57:17 2010 +0200 + + Rename variable with a very generic name + + gi/module.py | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +commit 391640b30ede50af3667b1019edb72bd79f2c68c +Author: Tomeu Vizoso +Date: Thu Apr 22 19:53:06 2010 +0200 + + Add support for enums without GType + + https://bugzilla.gnome.org/show_bug.cgi?id=616520 + + gi/module.py | 6 +++++- + gi/pygi-argument.c | 22 +++++++++++++++++++++- + gi/types.py | 14 ++++++++++++++ + tests/test_gi.py | 30 ++++++++++++++++++++++++++++-- + 4 files changed, 68 insertions(+), 4 deletions(-) + +commit 89704f60ddae0c81f1383d86491ef2785590a353 +Author: Zach Goldberg +Date: Tue Apr 20 22:20:42 2010 -0400 + + Bump version during development to 0.5.1 + + This follows what is, according to Colin Walters, + standard versioning practice. During development the + version in your config is the *next* version you will release, + not the version after. Thus after a release you make a new commit + bumping to the next development version. + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e203dc7c8f524c16aa52e15758dc3a2b09fbac75 +Author: John Ehresman +Date: Tue Apr 20 20:40:02 2010 -0400 + + Added missing , to keyword list of gio.GFile.set_attribute + + gio/gresolver.override | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0b222f01ac9ceea1d127083623ad532ecc75bf7e +Author: John Ehresman +Date: Tue Apr 20 20:37:12 2010 -0400 + + Fix arg conversion in gio.GFile.set_attribute + + gio/gfile.override | 232 + +++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 227 insertions(+), 5 deletions(-) + +commit a579ccc8bea90937bf970be3d461e2b650b0c7d6 +Author: John Ehresman +Date: Tue Apr 20 20:01:53 2010 -0400 + + Set constants under python 2.5 or before + + gobject/gobjectmodule.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit 11fa39a861abf679e01b5f0da97be93ae0adf0f0 +Author: José Alburquerque +Date: Sun Apr 18 20:22:21 2010 -0400 + + Doc Extractor: Use replacements that make sense for &...; + expressions. + + * codegen/docextract_to_xml.py: Use # and   respectively + for + # (#) and  . These are interpreted correctly in XML + and will + not make the parsing crash. + + codegen/docextract_to_xml.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 8dbc2cb016acef7b364804cd9bc8f0b1da37e84b +Author: Zach Goldberg +Date: Sun Apr 18 14:32:06 2010 -0400 + + Bump version for release 0.5.0 + + HACKING | 7 +++++++ + configure.ac | 4 ++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +commit 3293c91d90c5c497b45e42a527d7f79f7435823e +Author: Tomeu Vizoso +Date: Sun Apr 18 14:28:13 2010 -0400 + + One more missing file... + + examples/Makefile.am | 2 ++ + 1 file changed, 2 insertions(+) + +commit 1dc575af19fe985cc3fa3ec0cf18aeab1f43c16d +Author: Tomeu Vizoso +Date: Sun Apr 18 14:18:44 2010 -0400 + + Add more stuff to the tarballs + + Makefile.am | 8 +++++++- + configure.ac | 1 + + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit 8a9bb04755057e934b7f46c917af6ef281a2fedd +Author: Tomeu Vizoso +Date: Sun Apr 18 13:48:45 2010 -0400 + + Add one more missing file to tarballs + + gi/overrides/GIMarshallingTests.py | 0 + gi/overrides/Makefile.am | 1 + + 2 files changed, 1 insertion(+) + +commit 979e01852fc7f830ee91093accdc387fa535075f +Author: Tomeu Vizoso +Date: Sun Apr 18 13:45:29 2010 -0400 + + Add missing file to tarballs + + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +commit 8b70faa7a9a32b9ea8862f28a503e38f496cfd89 +Author: Tomeu Vizoso +Date: Sun Apr 18 13:11:11 2010 -0400 + + Implement vfuncs. + + https://bugzilla.gnome.org/show_bug.cgi?id=602736 + + gi/gimodule.c | 89 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-argument.c | 1 + + gi/pygi-callbacks.c | 3 +- + gi/pygi-closure.c | 4 +-- + gi/pygi-closure.h | 2 +- + gi/pygi-info.c | 86 + +++++++++++++++++++++++++++++++++++++++++++++++++-- + gi/pygi-info.h | 1 + + gi/types.py | 44 +++++++++++++++++--------- + tests/test_gi.py | 18 +++++++++++ + 9 files changed, 227 insertions(+), 21 deletions(-) + +commit e239faacb4798fe2d166233ca1a19a843a6225e3 +Author: Zach Goldberg +Date: Sun Apr 18 11:59:06 2010 -0400 + + Fix a typo in pygi-callbacks.c header + + gi/pygi-callbacks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 79aa416ae8632b123da61d79fb820d9e2704209c +Author: Zach Goldberg +Date: Sat Apr 17 12:00:05 2010 -0400 + + Implement nullable argument support, including tests + + https://bugzilla.gnome.org/show_bug.cgi?id=616035 + + gi/pygi-argument.c | 43 +++++++++++++++++++++++++++++++++++++------ + gi/pygi-argument.h | 3 ++- + gi/pygi-info.c | 19 +++++++++++++------ + tests/test_everything.py | 28 ++++++++++++++++++++++++++++ + 4 files changed, 80 insertions(+), 13 deletions(-) + +commit 7d533b8893bc4a8a82fd9708278fa1dce5d3551e +Author: Zach Goldberg +Date: Sat Apr 17 12:56:19 2010 -0400 + + Move some tests from test_gi to test_everything + + tests/test_everything.py | 60 + ++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gi.py | 62 + +----------------------------------------------- + 2 files changed, 61 insertions(+), 61 deletions(-) + +commit a90298cc9e6c0f336f887a71d80b1efd07ec2811 +Author: Tomeu Vizoso +Date: Sun Apr 18 10:44:35 2010 -0400 + + Update to latest version of the pygi-convert.sh script + + pygi-convert.sh | 193 + ++++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 137 insertions(+), 56 deletions(-) + +commit 34a39318c674737c6d64f2430456daef86ba1626 +Author: Colin Walters +Date: Sun Apr 18 10:40:44 2010 -0400 + + Add Tomeu's prototype script for converting pygtk to pygi + + pygi-convert.sh | 71 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 71 insertions(+) + +commit a3afdb5fd33de0bf11d63857a245a8f5edec242c +Author: Olav Vitters +Date: Sun Apr 18 13:01:58 2010 +0200 + + Fix doap file + + pygi.doap | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 0de73d0bba79f92af22f43693f3575c596712416 +Author: Zach Goldberg +Date: Sat Apr 17 16:01:31 2010 -0400 + + Add Zach Goldberg as a pygi maintainer + + pygi.doap | 5 +++++ + 1 file changed, 5 insertions(+) + +commit a0e22e36e8cf0c1e0da3c0ec48c821fdb5a07ccd +Author: Tomeu Vizoso +Date: Sat Apr 17 11:47:54 2010 -0400 + + Require PyCairo + + configure.ac | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +commit 2778f8a1bf6379a46beec6546c8efcb0fec2d7ad +Author: Tomeu Vizoso +Date: Sat Apr 17 11:40:14 2010 -0400 + + Add examples/cairo-demo.py + + examples/cairo-demo.py | 121 + +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 121 insertions(+) + +commit 610dd1eec87fab5c8c3badb4d104cba74477c745 +Author: Zach Goldberg +Date: Sat Apr 17 09:17:14 2010 -0400 + + Implementation callback support with scoping and basic argument + support. + + This patch was originally written by + Zach Goldberg with modifications and + review by Simon van der Linden and + Colin Walters . + + This impementation enforces the assumption that any one function + signature can only have one (callback, userdata, destronotify) tuple. + This allows us to move callback creation into the actual function + invoke pipeline and also to keep just one destroy notify callback + around, vastly simplifying the code. + + https://bugzilla.gnome.org/show_bug.cgi?id=603095 + + configure.ac | 2 + + gi/Makefile.am | 4 + + gi/pygi-argument.c | 12 ++- + gi/pygi-callbacks.c | 216 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-callbacks.h | 47 ++++++++++++ + gi/pygi-closure.c | 205 + +++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-closure.h | 57 ++++++++++++++ + gi/pygi-info.c | 49 ++++++++++-- + gi/pygi-private.h | 2 + + tests/test_gi.py | 64 +++++++++++++++- + 10 files changed, 648 insertions(+), 10 deletions(-) + +commit a34cb9f0038a6c89e5e6c5f7761d48a5a833044f +Author: Tomeu Vizoso +Date: Sat Apr 17 10:54:45 2010 -0400 + + Add support for foreign structs + + https://bugzilla.gnome.org/show_bug.cgi?id=603712 + + configure.ac | 6 +++ + gi/Makefile.am | 10 +++- + gi/gimodule.c | 7 +++ + gi/pygi-argument.c | 27 ++++++++++- + gi/pygi-foreign-cairo.c | 103 +++++++++++++++++++++++++++++++++++++++ + gi/pygi-foreign-cairo.h | 55 +++++++++++++++++++++ + gi/pygi-foreign.c | 123 + +++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-foreign.h | 52 ++++++++++++++++++++ + gi/pygi-private.h | 1 + + tests/test_everything.py | 48 ++++++++++++++++++ + 10 files changed, 428 insertions(+), 4 deletions(-) + +commit e73b6f6fe8b5f23a2a390ae0a6bbced593ded155 +Author: Tomeu Vizoso +Date: Fri Apr 16 14:35:13 2010 -0400 + + Allow creating structs with pointers + + https://bugzilla.gnome.org/show_bug.cgi?id=603537 + + gi/pygi-struct.c | 6 ------ + tests/test_gi.py | 3 ++- + 2 files changed, 2 insertions(+), 7 deletions(-) + +commit fc9ff02e53aacf9e77625c70985e99813544912a +Author: Tomeu Vizoso +Date: Fri Apr 16 10:40:40 2010 -0400 + + Add gdb and valgrind variants for the tests + + HACKING | 19 +++++++++++++++++++ + Makefile.am | 12 ++++++++++++ + tests/Makefile.am | 14 +++++++++++++- + 3 files changed, 44 insertions(+), 1 deletion(-) + +commit 695ac7bc5c60371a32538d690c7a15509f3c9637 +Author: John Stowers +Date: Fri Apr 16 14:36:11 2010 +1200 + + Add build docs for windows + + Makefile.am | 1 + + README.win32 | 24 ++++++++++++++++++++++++ + 2 files changed, 25 insertions(+) + +commit e580da87f0b2fd36cb5d8008fb2fb0c3b01f456a +Author: John Stowers +Date: Thu Apr 15 13:40:39 2010 +1200 + + Setup.py cosmetic tidy + + * Remove local doc install, point to website instead + * link to versioned docs + + pygobject_postinstall.py | 43 ++++++++++++++++++++++++++----------------- + setup.py | 39 ++++++++++++++------------------------- + 2 files changed, 40 insertions(+), 42 deletions(-) + +commit 69ecd506c83ddf180c6cc9a2a8dc753a02543959 +Author: John Stowers +Date: Sat Jul 25 14:12:30 2009 +1200 + + Fix crash when importing gio + + Only seems to be necessary on windows, but + no harm on linux as multiple calls to init + are OK + + gio/giomodule.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit 5d159a13d89587cba189a0ca3203ac003e2f1f2b +Author: John Stowers +Date: Thu Apr 15 22:52:48 2010 +1200 + + Bug 589671 - Dont use generate-constants + + This breaks the build using distutils, and it is + largely unneeded. Just add the G_XXX constants + to the module directly + + gobject/Makefile.am | 16 +-------- + gobject/constants.py | 83 + ++++++++++++++++++++++++++++++++++++++++++++ + gobject/constants.py.in | 50 -------------------------- + gobject/generate-constants.c | 44 ----------------------- + gobject/gobjectmodule.c | 35 +++++++++++++++++++ + setup.py | 2 +- + tests/runtests.py | 3 +- + 7 files changed, 121 insertions(+), 112 deletions(-) + +commit 6d7a3ab9ce352692d0faccbf106974d264fa953d +Author: John Stowers +Date: Thu Apr 15 22:49:17 2010 +1200 + + Bug 589671 - Fix setup.py for windows build + + * Building pyglib as a static private library + * Update to include new defs + * Modernise setup.py and add more util functions + to dsextras + + dsextras.py | 32 ++++++++++++++++--- + setup.py | 102 + +++++++++++++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 116 insertions(+), 18 deletions(-) + +commit d11ef47072acae5801ce25c68d1289e425eb9fc2 +Author: John Stowers +Date: Thu Apr 15 22:48:28 2010 +1200 + + Include pygsource.h + + glib/pygiochannel.c | 1 + + 1 file changed, 1 insertion(+) + +commit c5f6af4844c74354abc508d17969d9d45153acf2 +Author: Tomeu Vizoso +Date: Thu Apr 15 14:25:59 2010 -0400 + + Add metadata to the .doap file + + pygi.doap | 3 +++ + 1 file changed, 3 insertions(+) + +commit 81796cb77cbe6b9598a652bd63c047af93e747ee +Author: John (J5) Palmieri +Date: Wed Apr 14 12:01:43 2010 -0400 + + override that wasn't checked in - fixes some test cases + + gi/overrides/GIMarshallingTests.py | 69 + ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +commit de5d2ea1584b01af809346316c7fbd4955a9db1d +Author: Colin Walters +Date: Wed Apr 14 10:06:07 2010 -0400 + + [Makefile.am] Clean up CFLAGS handling, don't override all: target + + First, we should move the CFLAGS into AM_CFLAGS, otherwise the + per-target CFLAGS forces Automake to prefix object files, which + is unnecessary since we only have one target. + + More importantly, avoid overriding the all: target here; that's + owned by Automake. Use all-local instead to append things to + the end of the normal build. + + gi/Makefile.am | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +commit 5a47e96e3f580c973e6880dafa747f54c144c760 +Author: Tomeu Vizoso +Date: Tue Apr 13 19:15:49 2010 -0400 + + Use GIMarshallingTests (old TestGI) in gobject-introspection + + gi/overrides/TestGI.py | 69 -- + tests/Makefile.am | 40 - + tests/libtestgi.c | 2924 + ------------------------------------------------ + tests/libtestgi.h | 628 ----------- + tests/test_gi.py | 832 +++++++------- + 5 files changed, 416 insertions(+), 4077 deletions(-) + +commit 681832c3cd040433a488a400693b68f213bf7078 +Author: José Alburquerque +Date: Tue Apr 13 13:33:12 2010 -0400 + + codegen/docextract_to_xml.py: One more &...; replacement ( ). + + * codegen/docextract_to_xml.py: Replace   which also causes + errors with a regular space. + + codegen/docextract_to_xml.py | 1 + + 1 file changed, 1 insertion(+) + +commit bd4e7f2459e34957aaae59b9be807d6dff5ec1eb +Author: José Alburquerque +Date: Tue Apr 13 12:28:10 2010 -0400 + + codegen/docextract_to_xml.py: Replace some &..; that cause errors. + + * codegen/docextract_to_xml.py (escape_text): Replace some &..; + expressions that cause errors with more appropriate output. + + codegen/docextract_to_xml.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit f00b9ce91fc9c3aabd4af4132fc112d9e415e12e +Author: José Alburquerque +Date: Sun Apr 11 17:46:40 2010 -0400 + + codegen/docextract_to_xml.py: Handle C++ multi-line comments. + + * codegen/docextract_to_xml.py (escape_text): Translate '/*' + and '*/' + in text to '/ *' and '* /' respectively so that comment errors + don't + show up when the descriptions that include C++ code with C++ + multi-line comments are used in Doxygen blocks. + + codegen/docextract_to_xml.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +commit a2fcdecbb5e109da5568084d7acb2332af83b6f5 +Author: José Alburquerque +Date: Sun Apr 11 16:15:01 2010 -0400 + + codegen/docextract.py: Stop final section processing on first + match. + + * codegen/docextract.py (process_final_sections): Modify the final + section pattern matching for loop to stop on first match so + that it + doesn't match both a colon return ('Returns: ...') and a no colon + return ('Returns ...') which leads to annotation extraction + errors. + + codegen/docextract.py | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 825fd305f03b726665edca34963978ce27448182 +Author: José Alburquerque +Date: Sun Apr 11 15:45:09 2010 -0400 + + Update doc extraction tool to handle GObjectIntrospection + annotations. + + * codegen/docextract.py (FunctionDoc): Renamed class to GtkDoc. + (GtkDoc::annotations): Added a list field to store annotations + which + are 2-tuples of (name, value). + (GtkDoc::ret): Modified field to store the return description + along + with a list of annotations as described above. + (GtkDoc::params): Now holds a list of 3-tupples: name, + description and + annotations (as described above). + (GtkDoc::block_type): Add a field to tell if the comment block + is a + function block, signal block or property block. + (GtkDoc::set_type): + (GtkDoc::get_type): Add methods for setting/getting the block + type. + (GtkDoc::add_param): Modified to also accept a list of + annotations to + be added with the parameter. + (GtkDoc::add_annotation): + (GtkDoc::get_annotations): Added methods to add/get annotations + for + the comment block. + (GtkDoc::append_description): Renamed to append_to_description(). + (GtkDoc::get_param_description): Removed unused method. + (GtkDoc::get_description): Added method to get block description. + (GtkDoc::add_return): Added method to add a return accepting + the first + line of the description and its annotations. + (GtkDoc::append_return): Renamed to append_to_return(). + (Regular expressions): + - Made the names of the variables un-abbreviated. + + - Added 'since', 'deprecated' and 'rename to' regular + expressions. + + - Modified the return matching regular expression so that + it doesn't + match descriptions that begin with 'Returns ...'. + This improves + the docs of many function. + + - Added signal and property comment block identifier matching + regular + expressions in case those are useful. + + - Modified existing identifier matching regular expressions + (function, + signal, and property regular expressions) to properly parse + annotations. Also added a regular expression for extracting + annotations from the parameter and return descriptions. + + - Refined the function name matching regular expression to + only accept + identifiers that begin with a lowercase letter. This eliminates + 'SECTION:' matches. + + - Finally, grouped commonly related expressions like + return_pattern, + since_pattern, etc. into groups (in lists) so that matching + those + sections can be done using loops. + + (Parsing algorithm): Modified the algorithm to use a functional + approach to parsing. Extra methods like skip_to_comment() and + processs_params() have been added and used in the parse_file() + function to now process the comment blocks. + (parse_dir): Added file processing output to stderr. + * codegen/docextract_to_xml.py (usage): Added function to + print out + the usage. + (print_annotations): Added function to print the given list of + annotations. + (options): Added --with-signals (-i), with-properties (-p) and + --with-annotation (-a) to the existing --source-dir (-s) option. + + (algorithm): Now prints annotations, if specified. Also, prints + signals and properties correctly (using names like + Class::signal-one + for signals and Classs:property) with xml such as .... The return xml is slightly modified with + annotations but this would only be exhibited if annotation xml is + requested. + + codegen/docextract.py | 439 + ++++++++++++++++++++++++++++++++++--------- + codegen/docextract_to_xml.py | 87 ++++++--- + 2 files changed, 414 insertions(+), 112 deletions(-) + +commit 9fef1acb42cd900d4a814a7378f60bc189121785 +Author: Tomeu Vizoso +Date: Fri Apr 9 13:47:03 2010 +0200 + + Always create the .so link + + gi/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e9f7fd414e94595e40eb1ba0fc471ca69136d82f +Author: Paul Bolle +Date: Thu Apr 8 11:52:25 2010 +0200 + + Docs: replace gio.IO_ERROR_* with gio.ERROR_* + + Signed-off-by: Paul Bolle + + docs/reference/pygio-file.xml | 58 + ++++++++++++++++++------------------ + docs/reference/pygio-inputstream.xml | 22 +++++++------- + docs/reference/pygio-mount.xml | 10 +++---- + 3 files changed, 45 insertions(+), 45 deletions(-) + +commit 4cbd9941c5705970a9f7a429e236e1203d3155a1 +Author: Gian Mario Tagliaretti +Date: Mon Apr 5 18:10:42 2010 +0200 + + Bug 613341 - pygobject tests seem to require pygtk causing a circular + dependencies problem + + move tests that require pygtk to pygtk itself + + tests/test_conversion.py | 83 -------------- + tests/test_enum.py | 234 -------------------------------------- + tests/test_gtype.py | 112 ------------------ + tests/test_subtype.py | 289 + ----------------------------------------------- + 4 files changed, 718 deletions(-) + +commit ef0ceb266a45715ece58642fb0042e3376416755 +Author: Simon van der Linden +Date: Wed Feb 3 20:33:03 2010 +0100 + + Add modelines and copyright information to overrides modules + + gi/overrides/Gdk.py | 21 +++++++++++++++++++++ + gi/overrides/Gtk.py | 21 +++++++++++++++++++++ + gi/overrides/TestGI.py | 20 ++++++++++++++++++++ + 3 files changed, 62 insertions(+) + +commit 5106523a4b8378997a1e6cb0488398aa73e7d9d5 +Author: Simon van der Linden +Date: Wed Feb 3 20:29:55 2010 +0100 + + Fix and complete overrides tests + + Those tests were missing in the last commit + + https://bugzilla.gnome.org/show_bug.cgi?id=602830 + + gi/overrides/TestGI.py | 49 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gi.py | 8 +++++++- + 2 files changed, 56 insertions(+), 1 deletion(-) + +commit 23fc0f615d87994acafd9d39e92dd92b587fc2eb +Author: Simon van der Linden +Date: Thu Jan 21 17:30:51 2010 +0100 + + Don't raise an error in _pygi_import if pygi support is disabled + + http://bugzilla.gnome.org/show_bug.cgi?id=607674 + + gobject/pygboxed.c | 6 +----- + gobject/pygi-external.h | 1 - + gobject/pygobject.c | 6 +----- + gobject/pygpointer.c | 6 +----- + 4 files changed, 3 insertions(+), 16 deletions(-) + +commit aefac8c5f64bf059dd6652f8a843d17b34fa0854 +Author: Simon van der Linden +Date: Fri Jan 22 22:22:37 2010 +0100 + + Remove support for pointers to basic types as input-only argument + and return value + + There is no reason for an API to use such things, and + g_function_info_invoke + broke such features. + + https://bugzilla.gnome.org/show_bug.cgi?id=607759 + + gi/pygi-argument.c | 586 ++++------------------------------------------- + gi/pygi-argument.h | 1 - + gi/pygi-info.c | 8 +- + tests/libtestgi.c | 660 + ----------------------------------------------------- + tests/libtestgi.h | 86 ------- + tests/test_gi.py | 144 ------------ + 6 files changed, 47 insertions(+), 1438 deletions(-) + +commit eaf7cb8ebb7e34f9493ac83b2f04af4dcf45f40f +Author: Simon van der Linden +Date: Fri Jan 22 13:41:21 2010 +0100 + + Restore the overrides support + + Add a ModuleProxy in front of the DynamicModule when an overrides + module is + present. There is no need for an overrides module to be a class; + it can just be a module. + + Add an override decorator to override the wrapper of a registered + type. + + Adapt Gdk and Gtk accordingly. + + Add tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=602830 + + gi/importer.py | 40 +++++++------------- + gi/module.py | 43 ++++++++++++++------- + gi/overrides/Gdk.py | 42 +++++++++++++-------- + gi/overrides/Gtk.py | 16 ++++---- + gi/types.py | 6 +++ + tests/libtestgi.c | 105 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/libtestgi.h | 49 ++++++++++++++++++++++++ + tests/test_gi.py | 36 ++++++++++++++++++ + 8 files changed, 273 insertions(+), 64 deletions(-) + +commit 289d641775d1ea52d2a5379126b70b7fcee46683 +Author: Tomeu Vizoso +Date: Sun Jan 10 21:01:59 2010 +0100 + + Initialize PyGPollFD_Type.fd_obj to NULL + + https://bugzilla.gnome.org/show_bug.cgi?id=606582 + + gio/gcancellable.override | 1 + + 1 file changed, 1 insertion(+) + +commit b11cf2595987c1f0fc4ffd834f07c98b92aa2355 +Author: Simon van der Linden +Date: Fri Jan 8 21:10:28 2010 +0100 + + Initialize struct fields to 0 when allocating + + gi/pygi-struct.c | 2 +- + tests/test_gi.py | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit b4189be2b2d3c350fdf33e27309bee5a72e4f72a +Author: Simon van der Linden +Date: Fri Jan 8 20:33:44 2010 +0100 + + Don't set a default constructor for structures. + + Update tests accordingly. + + The reason for this change is that setting __new__ in the metaclass + doesn't let + one overrides it afterwards, in a subclass (in my experience, at + least, even + though it seems weird). + + https://bugzilla.gnome.org/show_bug.cgi?id=603536 + + gi/types.py | 35 +++++++---------------------------- + tests/libtestgi.c | 33 --------------------------------- + tests/libtestgi.h | 7 ------- + tests/test_gi.py | 21 ++++++++++----------- + 4 files changed, 17 insertions(+), 79 deletions(-) + +commit 4db68b958ea11bd2c3a88067cae03fd6bdd1d24b +Author: Simon van der Linden +Date: Tue Jan 5 13:36:44 2010 +0100 + + Suppress compilation warnings + + gi/pygi-argument.c | 3 ++- + gi/pygi-boxed.c | 2 -- + gi/pygobject-external.h | 2 +- + 3 files changed, 3 insertions(+), 4 deletions(-) + +commit 4e2efa91d101bf755739e1cca8eee41eb0ad20fd +Author: Gian Mario Tagliaretti +Date: Mon Jan 4 08:35:14 2010 +0100 + + Bug 605937 - pygobject: Makefile.am sets $TMPDIR, disrupting distcc + + Committed a patch from Kevin Pyle + + Makefile.am | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +commit 8ddcbca0e98e0b0c082170a2b2b6cfcbd7864b40 +Author: Simon van der Linden +Date: Fri Dec 11 22:24:30 2009 +0100 + + sys.path must be modified after pygtk is imported + + Otherwise, sys.path is overridden by pygtk and gi.repository is + loaded from the + system's default site-package directory. + + tests/runtests.py | 1 - + tests/test_gi.py | 3 +++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 284a1e1c0143c95d3007cf58e6c248b5d11fb4d1 +Author: Gian Mario Tagliaretti +Date: Sun Jan 3 11:02:57 2010 +0100 + + Wrap gio.Cancellable.make_pollfd() and add a test + + gio/Makefile.am | 1 + + gio/gcancellable.override | 37 +++++++++++++++++++++++++++++++++++++ + gio/gio.override | 3 +++ + tests/test_gcancellable.py | 15 +++++++++++++++ + 4 files changed, 56 insertions(+) + +commit 82d7bcbf37200ee2ef5892dd12bebd2f39965c56 +Author: Gian Mario Tagliaretti +Date: Sat Jan 2 23:15:56 2010 +0100 + + Make cancellable an optional parameter in many methods + + gio/gio.defs | 102 + +++++++++++++++++++++++++++++------------------------------ + 1 file changed, 51 insertions(+), 51 deletions(-) + +commit 49a078cd22d55dc33a03ecfda235d63955edc741 +Author: Gian Mario Tagliaretti +Date: Sat Jan 2 23:15:21 2010 +0100 + + Post release version bump to 2.21.2 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4f9f1f43ab4e2cfb204ffa0e257a34cfd95d84e2 +Author: Gian Mario Tagliaretti +Date: Sat Jan 2 22:58:36 2010 +0100 + + Update NEWS and release PyGObject-2.21.1 + + NEWS | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +commit c1f34be73bd186d7b4682dfef133da2c4229d213 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 20:25:35 2010 +0100 + + Wrap gio.Volume.eject_with_operation() + + gio/gvolume.override | 54 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit 9b76fbff6f6897aaf26ed4644c1f19efc2826917 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 20:22:21 2010 +0100 + + gio.Mount.unmount_with_operation() fix a copy/paste leftover + + gio/gmount.override | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 6f459786dd641cd49d81eba403d940620f961cab +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 20:21:05 2010 +0100 + + Wrap gio.Mount.eject_with_operation() + + gio/gmount.override | 54 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit d4b5d1b4839364e5676eb2da28f1d21db7e2552d +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 20:15:38 2010 +0100 + + Wrap gio.Mount.unmount_mountable_with_operation() + + gio/gmount.override | 54 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit e919d47c2430451b436cec955e9b99237f97028c +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 18:22:46 2010 +0100 + + Wrap File.unmount_mountable_with_operation() + + gio/gfile.override | 54 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit 5a614df9c5507d67f240462f7bf71b4cd411addf +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 18:14:11 2010 +0100 + + Wrap gio.File.stop_mountable() + + gio/gfile.override | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +commit 6af506647f36f2b825bc6556df5ee57fa7721906 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 18:10:49 2010 +0100 + + Wrap gio.File.start_mountable() + + gio/gfile.override | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +commit e700efc839fc0b651fc9794a1611190bffa80263 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 18:02:46 2010 +0100 + + Wrap gio.File.replace_readwrite_async() + + gio/gfile.override | 55 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +commit 92662f129fc728258fd5e34f53dcb081e3715017 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 17:00:26 2010 +0100 + + Wrap gio.File.poll_mountable() + + gio/gfile.override | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +commit 99902b786500948c3278779841e4db54223b9256 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 16:56:26 2010 +0100 + + Wrap gio.File.open_readwrite_async() + + gio/gfile.override | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +commit 8cff5d53183ae81364ac74a34a1d52e55e082eb4 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 16:50:15 2010 +0100 + + Wrap gio.File.eject_mountable_with_operation() + + gio/gfile.override | 54 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit ca436fe7785fd24b0f0e65f2f8c9fa6478277682 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 13:30:24 2010 +0100 + + Wrap gio.File.create_readwrite_async() and add a test + + gio/gfile.override | 51 + +++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gio.py | 24 ++++++++++++++++++++++++ + 2 files changed, 75 insertions(+) + +commit f72c5e451dfaeb01b3c3d9243fed2732d3620462 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 13:20:11 2010 +0100 + + Wrap gio.Drive.stop() + + gio/gdrive.override | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +commit 29043bade408338cefa13fb4b0c875aabd3ef05e +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 13:00:42 2010 +0100 + + Wrap gio.Drive.start() + + gio/gdrive.override | 52 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +commit dff374287bbecc8af782bbc726fad86c6c867754 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 12:45:29 2010 +0100 + + Add more remainders on missing methods of gio.Socket and related types + + gio/gsocket.override | 3 +++ + 1 file changed, 3 insertions(+) + +commit b8c7e996498bd72df551011af85ff05ef7335b4f +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 12:41:08 2010 +0100 + + Wrap gio.SocketListener.accept_socket_async|finish() and add a test + + gio/gsocket.override | 86 + +++++++++++++++++++++++++++++++++++++++++++++++++-- + tests/test_gsocket.py | 24 ++++++++++++++ + 2 files changed, 108 insertions(+), 2 deletions(-) + +commit a5ae2d5ba3db34967fe07a3cc97b75df2793988c +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 12:28:53 2010 +0100 + + Wrap gio.SocketListener.accept_finish() and add a test + + gio/gsocket.override | 44 ++++++++++++++++++++++++++++++++++++++++++-- + tests/test_gsocket.py | 24 ++++++++++++++++++++++++ + 2 files changed, 66 insertions(+), 2 deletions(-) + +commit a5ab26cc1bb3e9dd57e2fdb26ef5c02e8066d097 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 11:19:34 2010 +0100 + + Wrap gio.SocketListener.accept_async() + + gio/gsocket.override | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +commit c9496b29ef9ef232020a4044577d2947353953a5 +Author: Gian Mario Tagliaretti +Date: Fri Jan 1 11:14:35 2010 +0100 + + Wrap gio.SocketListener.accept_socket() and add a test + + gio/gsocket.override | 48 + +++++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gsocket.py | 13 +++++++++++++ + 2 files changed, 60 insertions(+), 1 deletion(-) + +commit 1aa5e301c49f11e1c5ef58de44b4b03f714d1a70 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 16:35:18 2009 +0100 + + Wrap gio.SocketListener.accept() and add a test + + gio/gsocket.override | 46 +++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gsocket.py | 13 +++++++++++++ + 2 files changed, 58 insertions(+), 1 deletion(-) + +commit aaedcf166c78baf5449ef59d0ade4a29077fedc7 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 16:25:33 2009 +0100 + + Make cancellable optional in gio.SocketClient.connect_to_host() + + gio/gio.defs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 3829d7667b19126fb74562b28d271e616b154c99 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 15:25:10 2009 +0100 + + Wrap gio.SocketListener.add_address() and add a test + + gio/gsocket.override | 57 + ++++++++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gsocket.py | 9 ++++++++ + 2 files changed, 65 insertions(+), 1 deletion(-) + +commit 5bec72f34ea75bc56158cae5c39d61a2a4e7e601 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 10:19:47 2009 +0100 + + Add more remainders on missing methods of gio.Socket and related types + + gio/gsocket.override | 8 ++++++++ + 1 file changed, 8 insertions(+) + +commit b08b20f2b1a57bcbf400d6fe8e87cf052bdb719d +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 10:16:18 2009 +0100 + + Wrap gio.SocketClient.connect_to_service_async() + + gio/gsocket.override | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +commit 116ea1bfe32946e67aa54eb8dc7b977e57f254c2 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 10:10:43 2009 +0100 + + Wrap gio.SocketClient.connect_to_host_async() + + gio/gsocket.override | 48 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +commit 9c930910505d5b9001b8cec17ff98fadeaa799e2 +Author: Gian Mario Tagliaretti +Date: Thu Dec 31 09:59:46 2009 +0100 + + Wrap gio.SocketClient.connect_async() + + gio/gsocket.override | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +commit dff024256295c15e49888ad9d5fef74a7746edd7 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 23:44:25 2009 +0100 + + Wrap gio.SocketAddressEnumerator.next_async() and add a test + + gio/gsocket.override | 42 ++++++++++++++++++++++++++++++++++++++++++ + tests/test_gsocket.py | 16 ++++++++++++++++ + 2 files changed, 58 insertions(+) + +commit e2330bd0d6cbc49b0ecb27b30e3b0593935ce229 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 23:43:14 2009 +0100 + + Add a missing object gio.InetSocketAddress new in GIO 2.22 + + gio/gio-types.defs | 7 +++++++ + gio/gio.defs | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + +commit 6040b33467ea381c6cb02f6a5efc0745fa8fa47b +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 22:54:47 2009 +0100 + + Make cancellable optional for gio.SocketAddressEnumerator.next() + + gio/gio.defs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit b19f59790b9de943d69b6c5e483928e0443c3d20 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 22:17:44 2009 +0100 + + Add a remainder of the Socket methods that needs manual wrapping still + + gio/gsocket.override | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 771a7c3fdef7b2e98e509293a8376a81c1282286 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 17:20:35 2009 +0100 + + Wrap gio.Socket.condition_wait() and add a test + + gio/gsocket.override | 27 +++++++++++++++++++++++++++ + tests/test_gsocket.py | 6 +++++- + 2 files changed, 32 insertions(+), 1 deletion(-) + +commit 50960656815b0897a5ebe5f011537b8dcbdc857e +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 16:21:49 2009 +0100 + + Wrap gio.Socket.condition_check() and add a test + + gio/Makefile.am | 1 + + gio/gio.override | 1 + + gio/gsocket.override | 41 +++++++++++++++++++++++++++++++++++++++++ + tests/test_gsocket.py | 21 +++++++++++++++++++++ + 4 files changed, 64 insertions(+) + +commit de7a359e81792ae8573ac944455ea289985449ed +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 14:07:52 2009 +0100 + + Wrap gio.Resolver.lookup_service_finish() and add a test + + gio/gresolver.override | 37 +++++++++++++++++++++++++++++++++++++ + tests/test_gresolver.py | 13 +++++++++++++ + 2 files changed, 50 insertions(+) + +commit 308421789ce849040d645077c41c80b6e2e65e83 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 14:00:22 2009 +0100 + + Wrap gio.Resolver.lookup_service_async() + + gio/gresolver.override | 48 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +commit 9d56ce775f56fff1b1ef3c75843c0583e39f75c3 +Author: Gian Mario Tagliaretti +Date: Wed Dec 30 11:11:32 2009 +0100 + + Wrap gio.Resolver.lookup_service() and add a test + + gio/gresolver.override | 42 ++++++++++++++++++++++++++++++++++++++++++ + tests/test_gresolver.py | 5 +++++ + 2 files changed, 47 insertions(+) + +commit 7fc71f490494dae73a5264869a97a9d30814930e +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 22:12:50 2009 +0100 + + Wrap gio.Resolver.lookup_by_address_async() and add a test + + gio/gresolver.override | 46 + ++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gresolver.py | 14 ++++++++++++++ + 2 files changed, 60 insertions(+) + +commit c91656dbe56f07d3ebbad5113467c22427cf212a +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 21:41:30 2009 +0100 + + Wrap gio.Resolver.lookup_by_name_finish() and add a test + + gio/gresolver.override | 82 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gresolver.py | 16 ++++++++-- + 2 files changed, 96 insertions(+), 2 deletions(-) + +commit 45b477342fa1c2435917c6d97745ad57665c4734 +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 17:15:44 2009 +0100 + + Wrap gio.Drive.eject_with_data() + + gio/gdrive.override | 54 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +commit 635227480f9659a1f91ab1ec12536d3ed012a976 +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 17:06:52 2009 +0100 + + Deprecate old gio.Drive methods + + gio/gdrive.override | 7 ++++++- + gio/gio.defs | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +commit 3c0cbc95af29b1e192ed4b5963e96e39c70b349c +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 13:51:54 2009 +0100 + + Small fix in the header + + gio/gdrive.override | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7589128515b79d836365247dc876538c6352da23 +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 12:40:50 2009 +0100 + + Wrap gio.Resolver.lookup_by_name() and add a couple of tests + + gio/Makefile.am | 1 + + gio/gio.override | 1 + + gio/gresolver.override | 57 + +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gresolver.py | 21 ++++++++++++++++++ + 4 files changed, 80 insertions(+) + +commit 604d2bf220b1fefa415baaedbdb2882dbaf9e07e +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 12:39:13 2009 +0100 + + Make cancellable an optional parameter in + gio.Resolver.lookup_by_address() + + gio/gio.defs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 00029145f4cd10759b37b38fb9f72435bf26b28b +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 10:15:14 2009 +0100 + + Strip g_ prefix for many other functions + + gio/gio.defs | 94 + ++++++++++++++++++++++++++++++------------------------------ + 1 file changed, 47 insertions(+), 47 deletions(-) + +commit 56d5dfc4fd862e32c19f944a0feb7a00a9154f06 +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 10:12:53 2009 +0100 + + Strip g_prefix from InetAddress functions + + gio/gio.defs | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 1d360301d51a587a36a59f5d62e354484bbd2b31 +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 10:03:59 2009 +0100 + + Fix function name gio.resolver_get_default() + + Strip the g_ prefix from function name + + gio/gio.defs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 0fe00109c4f6fc27cbaae9b0a24ecfac71355d2f +Author: Gian Mario Tagliaretti +Date: Tue Dec 29 09:54:05 2009 +0100 + + Wrap gio.FileIOStream.query_info_async() and add a test + + gio/Makefile.am | 1 + + gio/gfileiostream.override | 68 + ++++++++++++++++++++++++++++++++++++++++++++++ + gio/gio.override | 1 + + tests/test_gio.py | 18 ++++++++++++ + 4 files changed, 88 insertions(+) + +commit 86783c695f3641b9491962e8f95a4dcb91f4017c +Author: Tomeu Vizoso +Date: Tue Dec 29 13:08:29 2009 +0100 + + Register enums and flags in PyGI if needed + + https://bugzilla.gnome.org/show_bug.cgi?id=603534 + + gobject/pygenum.c | 20 ++++++++++++++------ + gobject/pygflags.c | 19 +++++++++++++------ + 2 files changed, 27 insertions(+), 12 deletions(-) + +commit b90c01cff5ff5cb2796182f2ffd7b5248eaeed6a +Author: Gian Mario Tagliaretti +Date: Mon Dec 28 22:41:54 2009 +0100 + + Wrap GIOStream.close_async() and add a test + + gio/Makefile.am | 1 + + gio/gio.override | 1 + + gio/giostream.override | 68 + ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/test_gio.py | 21 ++++++++++++++++ + 4 files changed, 91 insertions(+) + +commit 0bff01bcee73a0e0d18342331136119c4e8bf151 +Author: Gian Mario Tagliaretti +Date: Mon Dec 28 22:39:09 2009 +0100 + + Make cancellable an optional parameter in GFile.create_readwrite() + + gio/gio.defs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1cabd733cde269ce3164834933f4a226673ecb0b +Author: Gian Mario Tagliaretti +Date: Mon Dec 28 21:39:50 2009 +0100 + + Remove a duplicate entry in gio.defs + + gio/gio.defs | 9 --------- + 1 file changed, 9 deletions(-) + +commit 9ac372ad0bcfdec4bb1c96bc152246542a59a9b1 +Author: Gian Mario Tagliaretti +Date: Mon Dec 28 21:37:49 2009 +0100 + + Wrap gio.FileInfo.set_modification_time and add a test + + gio/gfileinfo.override | 33 ++++++++++++++++++++++++++++++++- + tests/test_gio.py | 7 ++++++- + 2 files changed, 38 insertions(+), 2 deletions(-) + +commit 7bc2673f92138b1804d8eba091942d14d8884f90 +Author: Gian Mario Tagliaretti +Date: Mon Dec 28 18:28:03 2009 +0100 + + Wrap gio.EmblemedIcon.get_emblems() and add a test + + gio/gicon.override | 14 ++++++++++++++ + tests/test_gicon.py | 7 +++++++ + 2 files changed, 21 insertions(+) + +commit 3d5056ad766d6856d8d6459fe9b377de2f0fd172 +Author: Gian Mario Tagliaretti +Date: Sat Dec 26 22:27:48 2009 +0100 + + Update Enums and Flags with new API + + gio/gio-types.defs | 153 + +++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 149 insertions(+), 4 deletions(-) + +commit 62a9d660a4a2d5fab1d57c6c96c984ff02d25ccd +Author: Gian Mario Tagliaretti +Date: Fri Dec 25 18:06:39 2009 +0100 + + Post release version bump to 2.21.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2bd92cba5b028f0f78c35ecb34e648e95248f9d3 +Author: Bastian Winkler +Date: Fri Aug 14 15:10:26 2009 +0200 + + Fix handling of uchar in pyg_value_from_pyobject + + Set the value by g_value_set_uchar and allow to use integer types + from python. + + gobject/pygtype.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +commit 828d0f042b59ea0319f33a23803c179af34ef2f1 +Author: Tomeu Vizoso +Date: Tue Dec 22 18:05:47 2009 +0100 + + Add Gtk.keysyms to overrides + + gi/overrides/Gtk.py | 2 + + gi/overrides/Makefile.am | 1 + + gi/overrides/keysyms.py | 1499 + ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1502 insertions(+) + +commit 24fa1224ff00b9da177e0bfaa1e14e1b899e4976 +Author: Tomeu Vizoso +Date: Wed Nov 25 10:33:56 2009 +0100 + + The array field 'length' starts to count from the C arg list, so + need to decrement when it's a method + + https://bugzilla.gnome.org/show_bug.cgi?id=602640 + + gi/pygi-argument.c | 11 +++++++++- + gi/pygi-argument.h | 3 ++- + gi/pygi-info.c | 14 +++++++++++-- + tests/libtestgi.c | 60 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/libtestgi.h | 4 ++++ + tests/test_gi.py | 15 ++++++++++++++ + 6 files changed, 103 insertions(+), 4 deletions(-) + +commit 867536c6734e606d045760837ed22583da06566e +Author: Gian Mario Tagliaretti +Date: Fri Dec 18 10:50:09 2009 +0100 + + Update NEWS and README, release pygobject 2.21.0 + + NEWS | 18 ++++++++++++++++++ + README | 6 +++--- + 2 files changed, 21 insertions(+), 3 deletions(-) + +commit f50fbd24fa61863aaefa4ae1e12e0b314ecd43ae +Author: Gian Mario Tagliaretti +Date: Fri Dec 18 10:31:48 2009 +0100 + + Add pygi-external.h into Makefile SOURCES + + gobject/Makefile.am | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 108c03b78f04b4bcfe066a6cb4d941e172bd32fe +Author: Gian Mario Tagliaretti +Date: Fri Dec 18 01:20:34 2009 +0100 + + Bug 598435 - No wrapping for g_find_program_in_path () + + glib/glibmodule.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +commit d3d5cb3a4a2c2cb2bd0c2571304d59e19bc08452 +Author: Gian Mario Tagliaretti +Date: Thu Dec 17 21:54:36 2009 +0100 + + Wrap new API added in GIO-UNIX 2.22 + + gio/unix-types.defs | 22 ++++++++++ + gio/unix.defs | 115 + +++++++++++++++++++++++++++++++++++++++++++++++++++- + gio/unix.override | 8 ++++ + 3 files changed, 144 insertions(+), 1 deletion(-) + +commit c87c8a81947a68507e8f3bcaf8e0e969b3e5331b +Author: Gian Mario Tagliaretti +Date: Thu Dec 17 21:52:11 2009 +0100 + + Bump required glib version to 2.22.4 + + I've committed a patch to glib which will be released in the stable + branch. + Without the patch the unix module will fail, so I'm forced to bump. + + configure.ac | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit b630c8d4b1e55938dac89729768c4a877b305215 +Author: Gian Mario Tagliaretti +Date: Thu Dec 17 02:24:45 2009 +0100 + + Properly define Connectable as interface type and not object type + + gio/gio-types.defs | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit e955b931b07113c7432f7a85f882f69f12d263ad +Author: Anderson Lizardo +Date: Mon Nov 30 22:01:25 2009 +0100 + + Depend on GLib 2.20 rather than 2.22 + + Backport g_array_get_element_size. + + https://bugzilla.gnome.org/show_bug.cgi?id=603411 + + configure.ac | 2 +- + gi/pygi-private.h | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+), 1 deletion(-) + +commit 542fdf6da4ad8f2d28d0d50152bd93cb4d8ee39a +Author: Tomeu Vizoso +Date: Sat Nov 28 18:48:19 2009 +0000 + + Use the limit constants from glib and interpret G_MAXUINT32 as + PyLong_FromLongLong + + https://bugzilla.gnome.org/show_bug.cgi?id=602384 + + gi/pygi-argument.c | 14 +++++++------- + tests/test_gi.py | 18 +++++++++--------- + 2 files changed, 16 insertions(+), 16 deletions(-) + +commit 38e89942d29f2a1dba47ab4a8d5edc84322707cd +Author: Simon van der Linden +Date: Mon Nov 30 00:10:56 2009 +0100 + + Suppress warnings about format conversion + + https://bugzilla.gnome.org/show_bug.cgi?id=603355 + + gobject/generate-constants.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +commit cfa7d005487e17e8f7c1ceb14282d3a5baadb736 +Author: Simon van der Linden +Date: Sat Nov 28 00:22:21 2009 +0100 + + Remove global checks for pointers and move them in type cases that + need them + + gi/pygi-argument.c | 516 + +++++++++++++++++++++++++++++++++++++++++++---------- + gi/pygi-info.c | 333 +++++++++++++++++----------------- + 2 files changed, 596 insertions(+), 253 deletions(-) + +commit d1ae73f3cf7cebdb74c9ec56b08928a2a53b9de6 +Author: Johan Dahlin +Date: Mon Nov 23 15:58:17 2009 -0200 + + Pythonify. Avoid ; and () around if statements + + https://bugzilla.gnome.org/show_bug.cgi?id=602830 + + gi/types.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit a8660621679c629fc81320a8ddf5bf2c7ee1f177 +Author: Johan Dahlin +Date: Tue Nov 24 10:36:18 2009 -0200 + + Remove trailing whitespace + + https://bugzilla.gnome.org/show_bug.cgi?id=602830 + + gi/module.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 66c34805223af9e63c7d61f21a3dbd7505a8f256 +Author: Tomeu Vizoso +Date: Mon Nov 30 10:03:34 2009 +0000 + + Set a default constructor for boxed structs that don't have one + + https://bugzilla.gnome.org/show_bug.cgi?id=602735 + + gi/Makefile.am | 2 + + gi/gimodule.c | 1 + + gi/module.py | 2 +- + gi/pygi-argument.c | 14 +++- + gi/pygi-boxed.c | 184 + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + gi/pygi-boxed.h | 40 ++++++++++++ + gi/pygi-info.c | 2 +- + gi/pygi-private.h | 1 + + gi/pygi.h | 6 ++ + gi/types.py | 18 ------ + tests/libtestgi.c | 72 ++++++++++----------- + tests/libtestgi.h | 18 +++--- + tests/test_gi.py | 47 ++++++++------ + 13 files changed, 321 insertions(+), 86 deletions(-) + +commit e7e2fccae36c28c7e9f288fcd4c90a001140e307 +Author: Tomeu Vizoso +Date: Mon Nov 30 10:53:57 2009 +0000 + + Revert "Use the limit constants from glib and interpret G_MAXUINT32 + as PyLong_FromLongLong" + + This reverts commit 05a2ed55f3e5d2620de8b3b6b0d99e928ef3b041. + + gi/pygi-argument.c | 14 +++++++------- + tests/test_gi.py | 18 +++++++++--------- + 2 files changed, 16 insertions(+), 16 deletions(-) + +commit 05a2ed55f3e5d2620de8b3b6b0d99e928ef3b041 +Author: Tomeu Vizoso +Date: Sat Nov 28 18:48:19 2009 +0000 + + Use the limit constants from glib and interpret G_MAXUINT32 as + PyLong_FromLongLong + + https://bugzilla.gnome.org/show_bug.cgi?id=602384 + + gi/pygi-argument.c | 14 +++++++------- + tests/test_gi.py | 18 +++++++++--------- + 2 files changed, 16 insertions(+), 16 deletions(-) + +commit e24d155dd7b4a5b9c25c054137d1370c369d3192 +Author: Tomeu Vizoso +Date: Sat Nov 28 18:45:54 2009 +0000 + + Add the missing limit constants from glibconfig.h + + https://bugzilla.gnome.org/show_bug.cgi?id=603244 + + gobject/generate-constants.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +commit 3a295cb7ffaaaf29c71b8833cf0ee5ec7ceaa909 +Author: Gian Mario Tagliaretti +Date: Sat Nov 28 18:48:49 2009 +0100 + + Fix bad name when rebuilding the unix source module + + gio/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit a8cbb6fb72dbe6630d1265b18095c9a96f496b86 +Author: Gian Mario Tagliaretti +Date: Sat Nov 28 18:47:26 2009 +0100 + + Wrap new API added in GIO 2.22 + + gio/gio-types.defs | 138 +++ + gio/gio.defs | 2444 + +++++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 2360 insertions(+), 222 deletions(-) + +commit 96f6c638709636d7e2ddf560b877879691da3314 +Author: Tomeu Vizoso +Date: Sat Nov 28 11:03:51 2009 +0000 + + A few tests about interfaces + + https://bugzilla.gnome.org/show_bug.cgi?id=601181 + + tests/libtestgi.c | 23 +++++++++++++++++++++++ + tests/libtestgi.h | 16 ++++++++++++++++ + tests/test_gi.py | 21 +++++++++++++++++++++ + 3 files changed, 60 insertions(+) + +commit 076ba3156c13375a75983cef7a409c8c8afea119 +Author: Simon van der Linden +Date: Thu Nov 26 23:50:54 2009 +0100 + + Fix members initialization in metaclasses + + In metaclasses, the test for the name of the class was wrong, since it + prevented one to create a subclass with the same name (especially + annoying for + overrides). Now, if a GType is available from the info, the fact + that it + doesn't have any wrapper yet means that the metaclass is creating + the base + class, which will be registerd just after its creation. This is + true for + objects, and for structures registered as boxed or pointer too. + + This patch includes a test for basic subclassing in Python. It + notably tests + that methods don't get overridden by the metaclass. + + gi/types.py | 5 +++-- + tests/test_gi.py | 19 +++++++++++++++++++ + 2 files changed, 22 insertions(+), 2 deletions(-) + +commit ac80e64c9f7d257865aa820753e52d56cf2871c8 +Author: Tomeu Vizoso +Date: Fri Nov 27 12:06:59 2009 +0000 + + Structs in arrays are not marshalled correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=602709 + + gi/pygi-argument.c | 29 ++++++++++++++++++++++++----- + tests/libtestgi.c | 23 ++++++++++++++++++++++- + tests/libtestgi.h | 7 +++++-- + tests/test_gi.py | 8 ++++++++ + 4 files changed, 59 insertions(+), 8 deletions(-) + +commit 4a373b8ad6ec137e911b92a3e745e0fd76541292 +Author: Simon van der Linden +Date: Wed Nov 25 16:53:55 2009 +0100 + + Use the right variable when looking up in sys.modules + + gi/importer.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit fc3dca018e85aee34ade79d104ebd8cdd1dd5968 +Author: Tomeu Vizoso +Date: Tue Nov 24 15:52:47 2009 +0100 + + Accept 0 as a valid value for flag and enum arguments + + https://bugzilla.gnome.org/show_bug.cgi?id=602638 + + gi/pygi-argument.c | 19 ++++++++++++++++++- + tests/libtestgi.c | 6 ++++++ + tests/libtestgi.h | 1 + + tests/test_gi.py | 1 + + 4 files changed, 26 insertions(+), 1 deletion(-) + +commit 33081c29a1c2fdec2b8bfe17ae0a72b8db7a8d84 +Author: Tomeu Vizoso +Date: Tue Nov 24 13:10:11 2009 +0100 + + Add stuff to .gitignore + + .gitignore | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 5c010fe673d9bd01c27c8d7d312064665275888c +Author: Simon van der Linden +Date: Mon Nov 23 22:39:12 2009 +0100 + + Remove the girepository module + + Makefile.am | 2 +- + configure.ac | 17 - + girepository/Makefile.am | 54 -- + girepository/__init__.py | 24 - + girepository/bank-argument.c | 379 ------------ + girepository/bank-info.c | 1194 + ------------------------------------ + girepository/bank-repository.c | 236 ------- + girepository/bank.c | 155 ----- + girepository/bank.h | 80 --- + girepository/btypes.py | 300 --------- + girepository/importer.py | 51 -- + girepository/module.py | 224 ------- + girepository/overrides/Gdk.py | 14 - + girepository/overrides/Gtk.py | 8 - + girepository/overrides/__init__.py | 0 + girepository/repository.py | 51 -- + tests/test_girepository.py | 386 ------------ + 17 files changed, 1 insertion(+), 3174 deletions(-) + +commit a644edf0515c26ed027522891ccf02aceac764e8 +Author: Johan Dahlin +Date: Mon Nov 23 15:32:16 2009 -0200 + + Create overridden modules in two passes + + This patch splits overridden module creation into two passes. The + first pass + creates the auto-generated module normally before the overridden + module is + attempted to be imported. The second pass imports the overridden + module and + replaces the auto-generated module with the overridden. This is + necessary + for the overridden modules to be able to access the auto-generated + ones. + + gi/importer.py | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +commit fad89e12a744b57e6348968f351d25d167de8248 +Author: Tomeu Vizoso +Date: Sun Nov 22 17:56:20 2009 +0100 + + Add support for Any arguments + + https://bugzilla.gnome.org/show_bug.cgi?id=601253 + + gi/pygi-argument.c | 20 ++++++++++++-------- + tests/libtestgi.c | 5 +++++ + tests/libtestgi.h | 5 +++++ + tests/test_gi.py | 5 +++++ + 4 files changed, 27 insertions(+), 8 deletions(-) + +commit 1dc62a998dd8d2a0a397f8309011a8d79cb56034 +Author: Tomeu Vizoso +Date: Sun Nov 22 17:25:04 2009 +0100 + + Register interfaces + + https://bugzilla.gnome.org/show_bug.cgi?id=601181 + + gi/gimodule.c | 33 +++++++++++++++++++++++++++++++++ + gi/types.py | 5 ++++- + 2 files changed, 37 insertions(+), 1 deletion(-) + +commit d67d5afb5115c1d8294415b2e1a82af2c737ba17 +Author: Paul Pogonyshev +Date: Sun Nov 22 18:23:02 2009 +0200 + + Ignore one more file. + + .gitignore | 1 + + 1 file changed, 1 insertion(+) + +commit 408b2186aea58a41ec26b9d0ca29ecd42df5ef7e +Author: Paul Pogonyshev +Date: Sun Nov 22 18:22:23 2009 +0200 + + Fix wrong minimum checking in float properties + + Bug #587637. Test the fix. + + gobject/propertyhelper.py | 5 +++-- + tests/test_properties.py | 6 ++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +commit 6ccf58afcf58e118903ced0135f0fe69b00e09ad +Author: Tomeu Vizoso +Date: Mon Oct 26 18:06:06 2009 +0000 + + Treat GI_INFO_TYPE_INTERFACE same as GI_INFO_TYPE_OBJECT + + gi/pygi-argument.c | 3 +++ + 1 file changed, 3 insertions(+) + +commit e6f730d6e1431e36bd5f6b503a1038617f8d1e7d +Author: Simon van der Linden +Date: Sat Nov 14 21:42:43 2009 +0100 + + Import pygtk properly to avoid failure on some setups + + tests/test_gi.py | 3 +++ + 1 file changed, 3 insertions(+) + +commit e604a89e9dc1a79687ef5fb94af7a2182be07dfb +Author: Alex Dedul +Date: Sat Nov 14 21:39:15 2009 +0100 + + Search for python-config-${VERSION} when python${VERSION}-config is + not found + + On Gentoo, notably, the config tool is named python-config-${VERSION}, + while on + Fedora and Ubuntu, it is named python${VERSION}-config. + + Signed-off-by: Simon van der Linden + + configure.ac | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +commit 4a887cfabb326cb99dc65073d592c03f59e2f141 +Author: Simon van der Linden +Date: Sat Nov 14 21:36:19 2009 +0100 + + Fix silent rules setup + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 602afea88c338a38327cd84e08703c5daa384ec6 +Author: Paul Pogonyshev +Date: Tue Nov 10 22:32:33 2009 +0200 + + Move threads_init() function from 'gobject' to 'glib' + + Retain in original place for backward compatibility, but remove it + from the docs. + + docs/reference/pygobject-functions.xml | 36 + +++++++--------------------------- + glib/glibmodule.c | 16 +++++++++++++++ + 2 files changed, 23 insertions(+), 29 deletions(-) + +commit 734755912fff11332dc0e96317b7d6b7c4014e6a +Author: Simon van der Linden +Date: Mon Nov 9 22:44:12 2009 +0100 + + Remove PyGObject patches since they've been merged to master + + ...pytype-aware-of-the-interface-enum-flags-.patch | 78 -------- + patches/0002-Fix-girpository-build-setup.patch | 186 + ------------------- + ...capabilities-to-import-wrappers-from-pygi.patch | 200 + --------------------- + ...ances-by-calling-tp_alloc-rather-than-PyO.patch | 29 --- + 4 files changed, 493 deletions(-) + +commit 6a69288941e65312fe82649ec72d2f21b2dc618f +Author: Simon van der Linden +Date: Sat Nov 7 23:42:07 2009 +0100 + + Create instances by calling tp_alloc rather than PyObject_NEW + + PyObject_NEW calls a generic allocator and should only be called by + tp_new, knowing + that the type's free function agrees. In pyg_boxed_new, we may + allocate + PyGBoxed subtypes, so the subtype's allocation function must be + called instead. + + gobject/pygboxed.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 000f7c36e667c6e078e3370769ea868e56a1b4ee +Author: Simon van der Linden +Date: Sat Nov 7 16:43:35 2009 +0100 + + Add capabilities to import wrappers from pygi + + At instance creation for boxed and pointers, at lookup for objects, + when the gtype has no wrapper yet, a wrapper may be imported from + pygi. + + The feature is turned on at configure time by --enable-pygi. + + Because we couldn't create a circular build dependency, PyGI's import + function and + API definition had to be copied in this tree. + + configure.ac | 8 ++++++ + gobject/pygboxed.c | 10 ++++++++ + gobject/pygi-external.h | 66 + +++++++++++++++++++++++++++++++++++++++++++++++++ + gobject/pygobject.c | 10 ++++++++ + gobject/pygpointer.c | 11 +++++++++ + 5 files changed, 105 insertions(+) + +commit fdfbc90dbc9e305646b62d73de506b5e0e99cc91 +Author: Simon van der Linden +Date: Sun Nov 8 20:03:58 2009 +0100 + + Update PyGObject patches + + A file, pygi-external.h, was missing in patch #3. + + ...capabilities-to-import-wrappers-from-pygi.patch | 74 + ++++++++++++++++++++-- + ...ances-by-calling-tp_alloc-rather-than-PyO.patch | 2 +- + 2 files changed, 69 insertions(+), 7 deletions(-) + +commit 8f53ca8a72f9958711765281dd5c5bdfb7042d7d +Author: Tomeu Vizoso +Date: Sun Nov 8 16:52:18 2009 +0100 + + Add myself to pygi.doap + + pygi.doap | 5 +++++ + 1 file changed, 5 insertions(+) + +commit 6f50d5102aec9288e1851f12e9d232b9c141d524 +Author: Simon van der Linden +Date: Sun Nov 8 15:40:51 2009 +0100 + + Add a doap file + + pygi.doap | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +commit ce673b9027868e6add4eeb438bc707eb40bfd046 +Author: Simon van der Linden +Date: Sun Nov 8 13:06:54 2009 +0100 + + Add PyGObject patches + + ...pytype-aware-of-the-interface-enum-flags-.patch | 78 +++++++++ + patches/0002-Fix-girpository-build-setup.patch | 186 + +++++++++++++++++++++ + ...capabilities-to-import-wrappers-from-pygi.patch | 138 +++++++++++++++ + ...ances-by-calling-tp_alloc-rather-than-PyO.patch | 29 ++++ + 4 files changed, 431 insertions(+) + +commit b24fd9633cabe1d95cde173a04e9a49833b06a26 +Author: Simon van der Linden +Date: Sun Nov 8 12:35:08 2009 +0100 + + Initial import + + .gitignore | 33 + + Makefile.am | 10 + + autogen.sh | 159 +++ + configure.ac | 53 + + gi/Makefile.am | 50 + + gi/__init__.py | 24 + + gi/gimodule.c | 144 ++ + gi/importer.py | 89 ++ + gi/module.py | 167 +++ + gi/overrides/Gdk.py | 21 + + gi/overrides/Gtk.py | 13 + + gi/overrides/Makefile.am | 10 + + gi/overrides/__init__.py | 0 + gi/pygi-argument.c | 1976 ++++++++++++++++++++++++++ + gi/pygi-argument.h | 65 + + gi/pygi-info.c | 2093 ++++++++++++++++++++++++++++ + gi/pygi-info.h | 64 + + gi/pygi-private.h | 55 + + gi/pygi-repository.c | 238 ++++ + gi/pygi-repository.h | 39 + + gi/pygi-struct.c | 175 +++ + gi/pygi-struct.h | 40 + + gi/pygi-type.c | 96 ++ + gi/pygi-type.h | 43 + + gi/pygi.h | 99 ++ + gi/pygobject-external.h | 83 ++ + gi/repository/Makefile.am | 8 + + gi/repository/__init__.py | 30 + + gi/types.py | 163 +++ + tests/Makefile.am | 48 + + tests/libtestgi.c | 3397 + +++++++++++++++++++++++++++++++++++++++++++++ + tests/libtestgi.h | 643 +++++++++ + tests/runtests.py | 22 + + tests/test_gi.py | 1416 +++++++++++++++++++ + 34 files changed, 11566 insertions(+) + +commit bfd3100a580b8bea9db25b8bb7443fb8c3dbe1cc +Author: Simon van der Linden +Date: Sat Nov 7 13:23:53 2009 +0100 + + Fix girpository build setup + + configure.ac | 21 ++++++----- + girepository/Makefile.am | 13 ++++--- + m4/introspection.m4 | 92 + ++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 111 insertions(+), 15 deletions(-) + +commit 421c03b1c5b69f90c778663df901b45ca3ee8ba5 +Author: Simon van der Linden +Date: Fri Nov 6 19:17:36 2009 +0100 + + Make GType.pytype aware of the interface, enum, flags, pointer and + boxed wrappers + + gobject/pygtype.c | 39 +++++++++++++++++++++++++++++++++------ + 1 file changed, 33 insertions(+), 6 deletions(-) + +commit a9c168c58cc6a449b51653417bf3f58bdd41457c +Author: Philippe Normad +Date: Wed Oct 21 18:01:16 2009 +0200 + + pygmainloop: fix use of PySignal_WakeUpFD API for nested loops + + Fixes bug #481569 + + glib/pygmainloop.c | 95 + ++++++++++++++++++++++++++++-------------------------- + 1 file changed, 50 insertions(+), 45 deletions(-) + +commit c6a5750379354c12e2599b3c73b4f9a23fd39114 +Author: Gian Mario Tagliaretti +Date: Fri Sep 25 20:12:21 2009 +0200 + + Post release version bump to 2.21.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 33920eb013628a5e22b7b32403fb965ae3210f47 +Author: Gian Mario Tagliaretti +Date: Wed Sep 23 21:52:04 2009 +0200 + + Update NEWS and release 2.20.0 + + NEWS | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 66b12f7d2f54143ea80b4f8aec863b26800363d6 +Author: Gian Mario Tagliaretti +Date: Wed Sep 23 21:51:43 2009 +0200 + + Bump version to 2.20.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7bf87338a026ac82f908aa5fddf2bfea2daf6617 +Author: Brian Cameron +Date: Wed Sep 23 12:11:50 2009 -0500 + + Updated uninstalled.pc file so that it contains the right paths for + defsdir files and codegen files. See bug #596023. + + pygobject-2.0-uninstalled.pc.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit d042402b7c649b2bed7f20038eb82518ec7cc9b3 +Author: Paul Pogonyshev +Date: Tue Sep 22 22:02:27 2009 +0300 + + Plug reference leak of GSource in pyg_main_loop_init() + + Bug #579406, second change. + + glib/pygmainloop.c | 1 + + 1 file changed, 1 insertion(+) + +commit 640be8109d066e85ed77c810830a5f73c750415b +Author: Frédéric Péters +Date: Sun Aug 30 16:46:02 2009 +0200 + + Specify programming language in .devhelp file + + This add a new language attribute (hardcoded to python) in the + .devhelp + file that is produced when using ref-html-style.xsl. + + docs/xsl/devhelp.xsl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit c888b5ca722fcad6a03de585606c677c2969ebd6 +Author: Paolo Borelli +Date: Thu Aug 13 21:32:07 2009 +0200 + + Allow to use automake 1.11 + + autogen.sh | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +commit 30deaba4bd1e199aab75cb346ee9237237807fbd +Author: Gian Mario Tagliaretti +Date: Tue Aug 11 22:19:50 2009 +0200 + + Update README + + README | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit af165d350d0d1bb493be5140bf84376d3da1e4d8 +Author: Gian Mario Tagliaretti +Date: Tue Aug 11 22:16:52 2009 +0200 + + Update AUTHORS + + AUTHORS | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +commit 5f9f87f276b97964b525a501d8584ea8b4d8bfd2 +Author: Gian Mario Tagliaretti +Date: Tue Aug 11 22:11:43 2009 +0200 + + Add myself and Paul as maintainers + + MAINTAINERS | 8 ++++++++ + pygobject.doap | 14 ++++++++++++++ + 2 files changed, 22 insertions(+) + +commit 3bfae47fbcb5523d91fb2d1ed7ea347eeddd1775 +Author: Gian Mario Tagliaretti +Date: Tue Aug 11 20:52:44 2009 +0200 + + Update NEWS release 2.19.0 + + NEWS | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +commit e82a1841f31ad54dd50569d0d45290713409e0bf +Author: John Finlay +Date: Tue Aug 11 00:04:31 2009 -0700 + + Add macros to help with Python list to/from GList/GSList conversions. + + gobject/pygobject.h | 242 + +++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 241 insertions(+), 1 deletion(-) + +commit f1fad96da2c531fbd3218923baa4fe806a2942d4 +Author: Gian Mario Tagliaretti +Date: Sat Aug 8 21:37:54 2009 +0200 + + Bug 590063 – GFileInfo.list_attributes should accept None/NULL + + gio/gfileinfo.override | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit b7907cf6ff6ccf8d38b5206f09f5c864c205e5de +Author: Johan Dahlin +Date: Fri Jul 24 14:30:37 2009 -0300 + + Remove myself as a maintainer + + MAINTAINERS | 4 ---- + pygobject.doap | 7 ------- + 2 files changed, 11 deletions(-) + +commit be6eb21320b4688bcfcd8cbea33f7be29a76f2a2 +Author: John Finlay +Date: Wed Jul 8 15:47:44 2009 -0700 + + * codegen/defsgen.py (clean_patterns): Strip out Windows + DLL API macros. + + codegen/defsgen.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 2214cad3529979e29342a7e1fdc2915b90ce9c10 +Author: Gian Mario Tagliaretti +Date: Tue Jun 23 21:18:23 2009 +0200 + + Fix the gio.unix namespace in docs + + docs/Makefile.am | 2 ++ + docs/reference/pygio-classes.xml | 2 -- + docs/reference/pygio-unixinputstream.xml | 26 +++++++++++++------------- + docs/reference/pygio-unixoutputstream.xml | 26 +++++++++++++------------- + docs/reference/pygiounix-classes.xml | 13 +++++++++++++ + docs/reference/pygobject-ref.xml | 1 + + 6 files changed, 42 insertions(+), 28 deletions(-) + +commit c0acaedfe7f4e488a490e07e3184f0709e1fadc2 +Author: Gian Mario Tagliaretti +Date: Mon Jun 22 23:13:36 2009 +0200 + + Add docs for gio functions (mostly for content types) + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-functions.xml | 395 + +++++++++++++++++++++++++++++++++++++ + 3 files changed, 398 insertions(+) + +commit ebddee47fb7f3e06f9e0a7a14b9532d5cf8a3881 +Author: Gian Mario Tagliaretti +Date: Sun Jun 21 18:35:56 2009 +0200 + + Add docs for gio.Unix[In|Out]putStream classes + + docs/Makefile.am | 4 + + docs/reference/pygio-classes.xml | 2 + + docs/reference/pygio-unixinputstream.xml | 202 + ++++++++++++++++++++++++++++++ + docs/reference/pygio-unixoutputstream.xml | 202 + ++++++++++++++++++++++++++++++ + 4 files changed, 410 insertions(+) + +commit 5b71e58117c85634d95d08449eb54079b246e5be +Author: Paul Pogonyshev +Date: Sun Jun 21 16:50:03 2009 +0300 + + Document that many functions got moved gobject -> glib + + docs/reference/pygobject-functions.xml | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit b270dc43f2cef5260b0bbc71356fd8e6a2b7f754 +Author: Gian Mario Tagliaretti +Date: Sat Jun 20 19:23:25 2009 +0200 + + Add docs for class gio.DataOutputStream + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-dataoutputstream.xml | 504 + ++++++++++++++++++++++++++++++ + 3 files changed, 507 insertions(+) + +commit 549313fc4886fa3deb31761de6f5400708165d86 +Author: Murray Cumming +Date: Thu Jun 18 18:48:37 2009 +0200 + + Allow h2def.py to work when there are tabs or multiple spaces after + the struct keyword. + + codegen/h2def.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 5c36ef20dca8cd1793f2d3e88949675299097f40 +Author: Gian Mario Tagliaretti +Date: Mon Jun 15 23:02:34 2009 +0200 + + Add dpcs for class gio.DataInputStream + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-constants.xml | 66 +++ + docs/reference/pygio-datainputstream.xml | 799 + +++++++++++++++++++++++++++++++ + 4 files changed, 868 insertions(+) + +commit a8b36c343c6850af929c1d5a930f923831b4e637 +Author: Theppitak Karoonboonyanan +Date: Mon Jun 15 23:25:01 2009 +0300 + + Fix build when builddir is not the same as srcdir + + Bug #585817. + + girepository/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9d9ae97b8a49836ec1f3b8d6529bafe1cc06d4d7 +Author: Paul Pogonyshev +Date: Mon Jun 15 23:19:47 2009 +0300 + + Make gio.Emblem constructor new-style + + Add optional 'origin' parameter. Expand gio.Emblem documentation and + mark gio.emblem_new_with_origin as sort-of-deprecated. + + docs/reference/pygio-emblem.xml | 51 + +++++++++++++++++++++++++++++++++++++++-- + gio/gio.defs | 5 ++-- + 2 files changed, 52 insertions(+), 4 deletions(-) + +commit 268e1681fd5b46e6412d3a8db84f3f1cb02fdbde +Author: Gian Mario Tagliaretti +Date: Sat Jun 13 14:44:47 2009 +0200 + + Add docs for gio.BufferedOutputStream class + + docs/Makefile.am | 96 ++++----- + docs/reference/pygio-bufferedoutputstream.xml | 275 + ++++++++++++++++++++++++++ + docs/reference/pygio-classes.xml | 1 + + 3 files changed, 325 insertions(+), 47 deletions(-) + +commit a6e25aaa7c8f27d62f2917b06728d7ccfcd46416 +Author: Gian Mario Tagliaretti +Date: Sat Jun 13 14:38:34 2009 +0200 + + Fix gio.BufferedInputStream docs + + Added the constructor reference and fixed a typo in properties header + + docs/reference/pygio-bufferedinputstream.xml | 34 + ++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +commit a9b13b60a5aad726d7d7dd7fdc5153b1561fb591 +Author: Gian Mario Tagliaretti +Date: Sat Jun 13 01:25:06 2009 +0200 + + Add docs for gio.BufferedInputStream + + docs/Makefile.am | 2 + + docs/reference/pygio-bufferedinputstream.xml | 431 + +++++++++++++++++++++++++++ + docs/reference/pygio-classes.xml | 1 + + 3 files changed, 434 insertions(+) + +commit 7766daa59b0e2b85413cee368bf2ebd2afe198e1 +Author: Paul Pogonyshev +Date: Sun May 31 18:25:47 2009 +0300 + + Cleanup GIO overrides to use Python function/method names + + Also move several gio.Mount overrides over from 'gio.override' to + existing 'gmount.override'. Part of bug #584289. + + gio/gfile.override | 20 ++--- + gio/gfileenumerator.override | 6 +- + gio/ginputstream.override | 2 +- + gio/gio.override | 204 + ------------------------------------------- + gio/gmount.override | 204 + +++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 218 insertions(+), 218 deletions(-) + +commit 07e9c18dc092f6546230168b6b69c1b3454e120a +Author: Paul Pogonyshev +Date: Sun May 31 18:56:55 2009 +0300 + + Make codegen report errors using Python function/method names + + Part of bug #584289. + + codegen/codegen.py | 9 +++++---- + codegen/definitions.py | 10 +++++++++- + 2 files changed, 14 insertions(+), 5 deletions(-) + +commit 235fde85d015382f2ba38b21968e82b3ac0b6612 +Author: Gian Mario Tagliaretti +Date: Fri Jun 12 00:12:17 2009 +0200 + + Fix object type in gio.BufferedInputStream_fill_async + + gio/gbufferedinputstream.override | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 407b0e909056f15960e6a4e549896d786ce0a0b2 +Author: Gian Mario Tagliaretti +Date: Tue Jun 9 00:08:21 2009 +0200 + + Wrap gio.BufferedInputStream.fill_async + + Wrap the method gio.BufferedInputStream.fill_async and add a test + + gio/Makefile.am | 1 + + gio/gbufferedinputstream.override | 70 + +++++++++++++++++++++++++++++++++++++++ + gio/gio.override | 1 + + tests/test_gio.py | 25 ++++++++++++++ + 4 files changed, 97 insertions(+) + +commit b7c96b41b287685fe57504e0add3a6f16e649975 +Author: Gian Mario Tagliaretti +Date: Mon Jun 8 15:42:40 2009 +0200 + + Add gio.BufferedOutputStream which was forgotten in the types + definition + + gio/gio-types.defs | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit 3666f75af4ef2c8e038116aee5afada59d59f689 +Author: Gian Mario Tagliaretti +Date: Mon Jun 8 14:20:02 2009 +0200 + + Add docs for gio.MemoryOutputStream + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-memoryoutputstream.xml | 175 + ++++++++++++++++++++++++++++ + 3 files changed, 178 insertions(+) + +commit 6eb5e3988cbddb4afb3d5747364d6eb80370bb78 +Author: Gian Mario Tagliaretti +Date: Mon Jun 8 13:30:15 2009 +0200 + + Split overrides for gio.MemoryOutputStream + + gio/Makefile.am | 1 + + gio/gio.override | 1 + + gio/gmemoryoutputstream.override | 45 + ++++++++++++++++++++++++++++++++++++++++ + gio/goutputstream.override | 24 --------------------- + 4 files changed, 47 insertions(+), 24 deletions(-) + +commit dfbdf23633a772e78b47b0e7b0c3e3b87855d9ff +Author: Gian Mario Tagliaretti +Date: Mon Jun 8 11:45:11 2009 +0200 + + Wrap gio.memory_input_stream_new_from_data + + Add the wrapper for gio.memory_input_stream_new_from_data including + docs and a test. + + docs/Makefile.am | 4 +- + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-memoryinputstream.xml | 151 + +++++++++++++++++++++++++++++ + gio/Makefile.am | 1 + + gio/ginputstream.override | 34 ------- + gio/gio.override | 1 + + gio/gmemoryinputstream.override | 91 +++++++++++++++++ + tests/test_gio.py | 4 + + 8 files changed, 252 insertions(+), 35 deletions(-) + +commit fcc3cb0e167789746a1a9db0cba54ea7a97c7259 +Author: Simon van der Linden +Date: Mon Jun 8 19:15:24 2009 +0200 + + Fixes whitespaces style issues with girepository. + + girepository/Makefile.am | 2 +- + girepository/bank-repository.c | 67 + +++++++++++++++++++++--------------------- + girepository/bank.h | 2 +- + girepository/btypes.py | 6 ++-- + girepository/module.py | 2 +- + 5 files changed, 39 insertions(+), 40 deletions(-) + +commit fb4b2c8cdad2853e6bfe9526529e3a3ab052c5e0 +Author: Simon van der Linden +Date: Fri Jun 5 19:03:59 2009 +0200 + + Removes the header but the modeline in test_girepository.py. + + tests/test_girepository.py | 26 +------------------------- + 1 file changed, 1 insertion(+), 25 deletions(-) + +commit abe4828f52c7eb3a08f5b592e7ced1e97a58ef5c +Author: Simon van der Linden +Date: Wed Jun 3 10:47:58 2009 +0200 + + Adds overrides modules from PyBank. + + girepository/Makefile.am | 3 +++ + girepository/importer.py | 3 +-- + girepository/overrides/Gdk.py | 14 ++++++++++++++ + girepository/overrides/Gtk.py | 8 ++++++++ + girepository/overrides/__init__.py | 0 + 5 files changed, 26 insertions(+), 2 deletions(-) + +commit c12964e6a3354d8063355225c94e6d21d621e08b +Author: Simon van der Linden +Date: Tue Jun 2 23:40:41 2009 +0200 + + Disables the tests that fail in tests/test_girepository.py. + + tests/test_girepository.py | 242 + ++++++++++++++++++++++++++++++++++----------- + 1 file changed, 182 insertions(+), 60 deletions(-) + +commit a4469a3f7d32a25156bae5e7aef9ec4ae5f6e140 +Author: Simon van der Linden +Date: Tue Jun 2 23:03:26 2009 +0200 + + Imports test_girepository.py from former PyBank's + everything_unittest.py. + + tests/test_girepository.py | 288 + +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 288 insertions(+) + +commit e4f2a5ef8734cf40cf8345d442612db1f6c62d5a +Author: Simon van der Linden +Date: Thu May 28 17:45:11 2009 +0200 + + Introduces the girepository module from the former PyBank. + + INSTALL | 69 +-- + Makefile.am | 2 +- + configure.ac | 12 + + girepository/Makefile.am | 52 ++ + girepository/__init__.py | 24 + + girepository/bank-argument.c | 379 +++++++++++++ + girepository/bank-info.c | 1194 + ++++++++++++++++++++++++++++++++++++++++ + girepository/bank-repository.c | 237 ++++++++ + girepository/bank.c | 155 ++++++ + girepository/bank.h | 80 +++ + girepository/btypes.py | 300 ++++++++++ + girepository/importer.py | 52 ++ + girepository/module.py | 224 ++++++++ + girepository/repository.py | 51 ++ + 14 files changed, 2799 insertions(+), 32 deletions(-) + +commit f5ab5046fe9b67ec5e8fc64679e1a3d01787af7e +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 18:28:22 2009 +0200 + + Fix the docs for gio.FilterOutputStream + + docs/reference/pygio-filteroutputstream.xml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit fded60d8376fc45d19bf6cd8be6b927cc3f2e8c6 +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 18:27:00 2009 +0200 + + Add gio.FilterOutputStream docs + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-filteroutputstream.xml | 152 + ++++++++++++++++++++++++++++ + 3 files changed, 155 insertions(+) + +commit e2c31f916967229b6547e68013628ce0082cf875 +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 13:29:59 2009 +0200 + + Add gio.FilterInputStream docs + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-filterinputstream.xml | 152 + +++++++++++++++++++++++++++++ + 3 files changed, 155 insertions(+) + +commit 49a467eee445bc75554db0374006722ac075194b +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 11:33:20 2009 +0200 + + Add API appeared in 2.20 but not marked as such in gio docs + + gio/gio.defs | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +commit 180c157f2a20b7d2dd9af05bfb5f515fd23870a0 +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 10:41:26 2009 +0200 + + Wrap gio.FileOutputStream.query_info_async + + Add the wrapper for gio.FileOutputStream.query_info_async + including docs and a test. + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-fileoutputstream.xml | 257 + ++++++++++++++++++++++++++++++ + gio/Makefile.am | 3 +- + gio/gfileoutputstream.override | 68 ++++++++ + gio/gio.override | 1 + + tests/test_gio.py | 27 ++++ + 7 files changed, 358 insertions(+), 1 deletion(-) + +commit 4673577d1f6c3d54423808dd575987092fb05ad2 +Author: Gian Mario Tagliaretti +Date: Tue Jun 2 10:17:41 2009 +0200 + + Fix gio.FileInputStream docs + + Add implemented interface section and remove a method description + + docs/reference/pygio-fileinputstream.xml | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +commit 1e1cad02879d514745b5233658654cbe944530a5 +Author: Gian Mario Tagliaretti +Date: Mon Jun 1 22:54:26 2009 +0200 + + Fix the method name + + gio/gfileinputstream.override | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +commit f605811afe8c91f121e89b6f9ec28c70b62f4110 +Author: Gian Mario Tagliaretti +Date: Mon Jun 1 22:40:56 2009 +0200 + + Wrap gio.FileInputStream.query_async + + Add the wrapper for gio.FileInputStream.query_async including docs and + a test. + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-fileinputstream.xml | 221 + +++++++++++++++++++++++++++++++ + gio/Makefile.am | 1 + + gio/gfileinputstream.override | 68 ++++++++++ + gio/gio.override | 1 + + tests/test_gio.py | 27 ++++ + 7 files changed, 321 insertions(+) + +commit 08623e54a426377c1504b5c364aabae5a17f8ad8 +Author: Paul Pogonyshev +Date: Sun May 31 17:43:16 2009 +0300 + + Install executable codegen parts with executing permissions + + Also add shebang where it was missing. Bug #583979. + + codegen/Makefile.am | 23 ++++++++++++----------- + codegen/code-coverage.py | 2 ++ + codegen/codegen.py | 2 ++ + codegen/createdefs.py | 0 + codegen/defsconvert.py | 2 ++ + codegen/defsgen.py | 0 + codegen/docgen.py | 0 + codegen/scmexpr.py | 0 + 8 files changed, 18 insertions(+), 11 deletions(-) + +commit 833d4da202bcfcb01a414f8aec4b751ec8e1ccb2 +Author: Paul Pogonyshev +Date: Sat May 30 16:57:49 2009 +0300 + + Wrap gio.DataInputStream.read_line_async and read_until_async + + Wrap the functions and their corresponding *_finish() functions. + Create 'gdatainputstream.override' for these and move two existing + functions there. Add unit tests. Re-enable synchronous read_line + unit test and adjust it for new official GIO behavior. Bug #584285. + + gio/Makefile.am | 1 + + gio/gdatainputstream.override | 250 + ++++++++++++++++++++++++++++++++++++++++++ + gio/ginputstream.override | 65 ----------- + gio/gio.defs | 4 +- + gio/gio.override | 1 + + tests/test_gio.py | 51 ++++++++- + 6 files changed, 300 insertions(+), 72 deletions(-) + +commit 2cb569c0ced49f9ed5ca83292d5f15c837066688 +Author: Paul Pogonyshev +Date: Sat May 30 17:24:15 2009 +0300 + + Fix gio.OutputStream.splice_async + + Bug #584290. + + gio/goutputstream.override | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit e43fa429f6b4019a432acb481bbc07c8201cc46d +Author: Paul Pogonyshev +Date: Wed May 27 21:19:27 2009 +0300 + + Code maintenance: ignore one more file created by unit tests + + tests/.gitignore | 1 + + 1 file changed, 1 insertion(+) + +commit 76e9dc74ac706a9207f9d31f887d6e38df2a678f +Author: Gian Mario Tagliaretti +Date: Mon May 25 20:20:38 2009 +0200 + + Update the docs with new 2.20 API + + docs/reference/pygio-appinfo.xml | 115 +++++++++++++++++++++++++++++ + docs/reference/pygio-icon.xml | 99 ++++++++++++++++++++++++- + docs/reference/pygio-mount.xml | 156 + +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 367 insertions(+), 3 deletions(-) + +commit 8e40d71ac23deb7d91789486ee8cad440a6be1dd +Author: Gian Mario Tagliaretti +Date: Mon May 25 01:33:08 2009 +0200 + + Add gio 2.20 API + + add the new API added in gio 2.20, some needs to be wrapped manually + + gio/gio.defs | 106 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + gio/unix.defs | 48 +++++++++++++++++++++----- + 2 files changed, 146 insertions(+), 8 deletions(-) + +commit 0d08df42514fba6abc896814abfee0d2d083c29e +Author: Gian Mario Tagliaretti +Date: Mon May 25 00:14:21 2009 +0200 + + Post release version bump 2.19.0 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit edfb09e3de7baf294b3beba84b4ecb94e1f16764 +Author: Gian Mario Tagliaretti +Date: Sun May 24 23:56:29 2009 +0200 + + Update NEWS, release 2.18.0 + + NEWS | 14 ++++++++++++++ + configure.ac | 4 ++-- + 2 files changed, 16 insertions(+), 2 deletions(-) + +commit e0648ea435e0b309cdd5bb0ebe56d4534efd26e4 +Author: Gian Mario Tagliaretti +Date: Sun May 24 22:18:40 2009 +0200 + + Add documentation for the gio.OutputStream class + + The docs for this class are not completed, missing methods + descriptions. + The index is complete though, it will be completed once all the + classes + are in place so we can ship a (almost) complete reference. + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 3 +- + docs/reference/pygio-outputstream.xml | 140 + ++++++++++++++++++++++++++++++++++ + 3 files changed, 144 insertions(+), 1 deletion(-) + +commit 11524cdf6472d9115a812ce431f6767aec5627bc +Author: Gian Mario Tagliaretti +Date: Sun May 24 22:12:04 2009 +0200 + + Wrap gio.OutputStream.splice_async() + + wrap gio.OutputStream.splice_async() and add a test. + + gio/goutputstream.override | 58 + +++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gio.py | 20 ++++++++++++++++ + 2 files changed, 77 insertions(+), 1 deletion(-) + +commit 82ad6b8c8ea4d6694126f5e0e67b826717e38f19 +Author: Emilio Pozuelo Monfort +Date: Sun May 24 22:55:16 2009 +0300 + + Add Python version into installed libpyglib name + + Do this now, while no-one (as far as we know) links to the library + besides PyGObject itself. Bug #550235. + + configure.ac | 2 ++ + gio/Makefile.am | 2 +- + glib/Makefile.am | 10 +++++----- + gobject/Makefile.am | 2 +- + 4 files changed, 9 insertions(+), 7 deletions(-) + +commit 59da8cd24ea390b6c983995833ec6b0e5d028b35 +Author: Gian Mario Tagliaretti +Date: Sun May 24 11:44:24 2009 +0200 + + Wrap gio.OutputStream.flush_async() + + wrap gio.OutputStream.flush_async() and add a test. + + gio/goutputstream.override | 47 + +++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gio.py | 11 +++++++++++ + 2 files changed, 57 insertions(+), 1 deletion(-) + +commit 84ab6178ed0033f69932df5bc73c86bdff80c953 +Author: Gian Mario Tagliaretti +Date: Sun May 17 17:29:37 2009 +0200 + + Add documentation for the gio.FileMonitor class + + The docs for this class are not completed, missing methods + descriptions. + The index is complete though, it will be completed once all the + classes + are in place so we can ship a (almost) complete reference. + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-filemonitor.xml | 128 + +++++++++++++++++++++++++++++++++++ + 3 files changed, 131 insertions(+) + +commit 629496a5617d30e4dfa494b05a62c85a6af77b9a +Author: Josselin Mouette +Date: Sun May 17 18:03:44 2009 +0300 + + Use 'Requires.private' for libffi in '.pc' files + + Correction for patch in bug #550231. + + pygobject-2.0-uninstalled.pc.in | 3 ++- + pygobject-2.0.pc.in | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +commit 90cd8b7c4a25cd2ecb751f8337b401c98538272b +Author: Gian Mario Tagliaretti +Date: Wed May 13 21:54:39 2009 +0200 + + Add wrapper for gio.FileAttributeMatcher + + added a boxed type for gio.FileAttributeMatcher which has been + forgotten while + wrapping the gio API. This should probably be done in gio itself. + + gio/gfileinfo.override | 24 ++++++++++++++++++++++-- + gio/gio-types.defs | 7 +++++++ + gio/gio.override | 2 ++ + 3 files changed, 31 insertions(+), 2 deletions(-) + +commit e707447d9313f2f2ecba395cfe3682d5a5e859f4 +Author: Paul Pogonyshev +Date: Wed May 13 22:06:25 2009 +0300 + + Mark relevant glib.IOChannel methods as METH_NOARGS + + Additionally fix glib.IOChannel.set_close_on_unref: was marked + METH_NOARGS but actually accepted arguments. Fixes bug #582427. + + glib/pygiochannel.c | 83 + +++++++++++++---------------------------------------- + 1 file changed, 20 insertions(+), 63 deletions(-) + +commit 002915e5f458fec5a89766a54e8119a70a80caa7 +Author: Gian Mario Tagliaretti +Date: Tue May 12 20:37:24 2009 +0200 + + Add documentation for the gio.FileInfo class + + The docs for this class are not completed, missing methods + descriptions. + The index is complete though, it will be completed once all the + classes + are in place so we can ship a (almost) complete reference. + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-fileinfo.xml | 346 + ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 349 insertions(+) + +commit 8cd25c871609580425c6c4c9e5bc6ec8d40862a1 +Author: Paul Pogonyshev +Date: Sat May 9 16:46:04 2009 +0300 + + Retire hand-written ChangeLog; autocreate from Git history + + Basically copied over from GLib source tree. + + ChangeLog | 3606 + --------------------------------------------------- + ChangeLog.pre-2.18 | 3608 + ++++++++++++++++++++++++++++++++++++++++++++++++++++ + Makefile.am | 32 + + 3 files changed, 3640 insertions(+), 3606 deletions(-) + +commit 23556bdbcf9cf06db866901fb822dd78a9043648 +Author: Gian Mario Tagliaretti +Date: Sat May 9 00:03:05 2009 +0200 + + Fix a bug in InputStream.skip_async + + use the count argument instead of buffer_size which is always zero + + gio/ginputstream.override | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit ed6b06315c17441b41c001d38537c904b8fe18de +Author: Gian Mario Tagliaretti +Date: Sat May 9 00:02:33 2009 +0200 + + Add docs for the gio.InputStream class + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-inputstream.xml | 730 + +++++++++++++++++++++++++++++++++++ + 3 files changed, 733 insertions(+) + +commit d58322b84d47da7905f95b43e9e0daf9f7c4b507 +Author: Gian Mario Tagliaretti +Date: Mon May 4 23:40:28 2009 +0200 + + Wrap gio.InputStream.skip_async() + + wrap gio.InputStream.skip_async() and add a test. + + gio/ginputstream.override | 50 + ++++++++++++++++++++++++++++++++++++++++++++++- + tests/test_gio.py | 20 +++++++++++++++++++ + 2 files changed, 69 insertions(+), 1 deletion(-) + +commit 2311187824d1b48a996ee2620fd3c9a63e3edd66 +Author: Siavash Safi +Date: Mon May 4 15:46:49 2009 +0430 + + Add -n --namespace option and the code to remove + dll API in headers, Added documentation + + Patch from bug #579275 + + ChangeLog | 8 ++++ + codegen/h2def.py | 133 + +++++++++++++++++++++++++++++++++++++++++++++---------- + 2 files changed, 117 insertions(+), 24 deletions(-) + +commit 442ec5bb997bb7dab55baeea6e54e79d3ce0d3c1 +Author: Paul Pogonyshev +Date: Sat May 2 23:54:52 2009 +0300 + + Properly mark glib.get_user_special_dir() as a keywords method + + Fixes bug #581082. + + glib/glibmodule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit f466dca880cc6ea68b9fe236943eea7a07d33520 +Author: Gian Mario Tagliaretti +Date: Sun May 3 11:03:25 2009 +0200 + + Add docs for the gio.LoadableIcon class + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-loadableicon.xml | 198 + ++++++++++++++++++++++++++++++++++ + 3 files changed, 201 insertions(+) + +commit eab4ebf7f6c82580b61205f34e1cfe535aeada60 +Author: Gian Mario Tagliaretti +Date: Sun May 3 01:21:55 2009 +0200 + + Add docs for the gio.ThemedIcon class + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-themedicon.xml | 204 + ++++++++++++++++++++++++++++++++++++ + 3 files changed, 207 insertions(+) + +commit 22d7de8b620055f14b30f9c3c99160c8b4ebe672 +Author: Gian Mario Tagliaretti +Date: Sat May 2 12:25:19 2009 +0200 + + post release version bump to 2.17.1 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 282ac3c76e1e3513bd76f819f320ec56aba15d9e +Author: Gian Mario Tagliaretti +Date: Fri May 1 23:40:31 2009 +0200 + + Fix the class title + + docs/reference/pygio-mountoperation.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d8b70dec1e5c09b73ae277f4f5b246315841fb8e +Author: Gian Mario Tagliaretti +Date: Fri May 1 22:24:33 2009 +0200 + + Add docs for the gio.MountOperation class + + docs/Makefile.am | 2 + + docs/reference/pygio-classes.xml | 1 + + docs/reference/pygio-constants.xml | 107 +++++ + docs/reference/pygio-mountoperation.xml | 726 + ++++++++++++++++++++++++++++++++ + 4 files changed, 836 insertions(+) + +commit fceea8e843e880f0469e454df23141e7dd2bc0cf +Author: Gian Mario Tagliaretti +Date: Thu Apr 30 22:13:06 2009 +0200 + + Update NEWS, release 2.17.0 + + NEWS | 93 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 93 insertions(+) + +commit 47389217d1a65a8e3f404d486c508cf5d3164756 +Author: Paul Pogonyshev +Date: Thu Apr 30 22:47:19 2009 +0300 + + Fix memory leak in gio.File.query_info_async() + + After the recent patch it would leak exception data if old argument + order was used. Properly decref the objects. + + gio/gfile.override | 4 ++++ + 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 58d720f..ea0b4ba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,13 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} AUTOMAKE_OPTIONS = 1.7 +# Limit PyFlakes and PEP8 to these directories. +pycheck_dirs = examples gi tests pygtkcompat + # Part of the gi subdirectory is handled with non-recursive make to avoid # py-compile getting confused between gi/types.py and Python's standard # types module. -SUBDIRS = examples gi tests pygtkcompat +SUBDIRS = . $(pycheck_dirs) PLATFORM_VERSION = 3.0 @@ -58,7 +61,11 @@ nobase_pyexec_PYTHON = \ gi/module.py \ gi/importer.py \ gi/pygtkcompat.py \ - gi/docstring.py + gi/docstring.py \ + gi/_constants.py \ + gi/_propertyhelper.py \ + gi/_signalhelper.py \ + gi/_option.py # if we build in a separate tree, we need to symlink the *.py files from the # source tree; Python does not accept the extensions and modules in different @@ -73,9 +80,11 @@ all-local: build_pylinks check-local: build_pylinks +if WITH_COMMON # pkg-config files pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pygobject-$(PLATFORM_VERSION).pc +endif # python pyexec_LTLIBRARIES = @@ -132,15 +141,15 @@ release-news: @echo "-------------- 8< -------------" @echo >> NEWS.tmp - @cat NEWS >> NEWS.tmp - @mv NEWS.tmp NEWS + @cat $(top_srcdir)/NEWS >> NEWS.tmp + @mv NEWS.tmp $(top_srcdir)/NEWS .PHONY: ChangeLog release-news ChangeLog: @echo Creating $@ @if test -d "$(srcdir)/.git"; then \ - (GIT_DIR=$(top_srcdir)/.git ./missing --run git log PYGOBJECT_2_17_0^^.. --stat) | fmt --split-only > $@.tmp \ + (GIT_DIR=$(top_srcdir)/.git $(top_srcdir)/missing --run git log PYGOBJECT_2_17_0^^.. --stat) | fmt --split-only > $@.tmp \ && mv -f $@.tmp $@ \ || ($(RM) $@.tmp; \ echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \ @@ -163,6 +172,22 @@ dist-hook: $(BUILT_EXTRA_DIST) if test -f $$f; then d=.; else d=$(srcdir); fi; \ rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done +# pycheck_subdirs = + +check-local: + @echo " CHECK Pyflakes" $(pycheck_dirs) + @if type pyflakes >/dev/null 2>&1; then \ + (cd $(abs_top_srcdir) && pyflakes $(pycheck_dirs) ); \ + else echo "skipped, pyflakes not installed"; \ + fi + @if test -z "$$SKIP_PEP8"; then \ + echo " CHECK PEP8"; \ + if type pep8 >/dev/null 2>&1; then \ + (cd $(abs_top_srcdir) && pep8 --ignore=E501,E123,E124 --repeat --show-source $(pycheck_dirs) ); \ + else echo "skipped, pep8 not installed"; \ + fi; \ + fi + check.gdb: cd tests && $(MAKE) check.gdb diff --git a/Makefile.in b/Makefile.in index d855563..7ba43dd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -343,10 +343,13 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = 1.7 +# Limit PyFlakes and PEP8 to these directories. +pycheck_dirs = examples gi tests pygtkcompat + # Part of the gi subdirectory is handled with non-recursive make to avoid # py-compile getting confused between gi/types.py and Python's standard # types module. -SUBDIRS = examples gi tests pygtkcompat +SUBDIRS = . $(pycheck_dirs) PLATFORM_VERSION = 3.0 CLEANFILES = \ `find "$(builddir)" -type f -name "*.pyc" -print` @@ -398,12 +401,16 @@ nobase_pyexec_PYTHON = \ gi/module.py \ gi/importer.py \ gi/pygtkcompat.py \ - gi/docstring.py + gi/docstring.py \ + gi/_constants.py \ + gi/_propertyhelper.py \ + gi/_signalhelper.py \ + gi/_option.py # pkg-config files -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = pygobject-$(PLATFORM_VERSION).pc +@WITH_COMMON_TRUE@pkgconfigdir = $(libdir)/pkgconfig +@WITH_COMMON_TRUE@pkgconfig_DATA = pygobject-$(PLATFORM_VERSION).pc # python pyexec_LTLIBRARIES = @@ -1098,15 +1105,15 @@ release-news: @echo "-------------- 8< -------------" @echo >> NEWS.tmp - @cat NEWS >> NEWS.tmp - @mv NEWS.tmp NEWS + @cat $(top_srcdir)/NEWS >> NEWS.tmp + @mv NEWS.tmp $(top_srcdir)/NEWS .PHONY: ChangeLog release-news ChangeLog: @echo Creating $@ @if test -d "$(srcdir)/.git"; then \ - (GIT_DIR=$(top_srcdir)/.git ./missing --run git log PYGOBJECT_2_17_0^^.. --stat) | fmt --split-only > $@.tmp \ + (GIT_DIR=$(top_srcdir)/.git $(top_srcdir)/missing --run git log PYGOBJECT_2_17_0^^.. --stat) | fmt --split-only > $@.tmp \ && mv -f $@.tmp $@ \ || ($(RM) $@.tmp; \ echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \ @@ -1128,6 +1135,22 @@ dist-hook: $(BUILT_EXTRA_DIST) if test -f $$f; then d=.; else d=$(srcdir); fi; \ rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done +# pycheck_subdirs = + +check-local: + @echo " CHECK Pyflakes" $(pycheck_dirs) + @if type pyflakes >/dev/null 2>&1; then \ + (cd $(abs_top_srcdir) && pyflakes $(pycheck_dirs) ); \ + else echo "skipped, pyflakes not installed"; \ + fi + @if test -z "$$SKIP_PEP8"; then \ + echo " CHECK PEP8"; \ + if type pep8 >/dev/null 2>&1; then \ + (cd $(abs_top_srcdir) && pep8 --ignore=E501,E123,E124 --repeat --show-source $(pycheck_dirs) ); \ + else echo "skipped, pep8 not installed"; \ + fi; \ + fi + check.gdb: cd tests && $(MAKE) check.gdb diff --git a/NEWS b/NEWS index 71dfc09..f1db3c9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,19 @@ +3.11.5 03-Feb-2014 + - cache refactoring: Move all cache marshalers into files based on type + (Simon Feltman) (#709700) + - tests: Add test for an owned boxed struct passed in a callback + (Mike Gorse) (#722899) + - build: Add --without-common configure option for package maintainers + (Patrick Welche) (#721646) + - demo: Add TreeModel interface implementation demonstration + (Simon Feltman) + - build: Set PLATFORM_VERSION again to 3.0 (Colin Walters) + - tests: Run PyFlakes and PEP8 only on SUBDIRS (Simon Feltman) + - Merge static PyGLib and PyGObject modules into PyGI + (Simon Feltman) (#712197) + - Add test for callback user data arguments with following arguments + (Martin Pitt) (#722104) + 3.11.4 13-Jan-2014 - overrides: Fix __repr__ for various Gdk structs (Simon Feltman) - Add enum and flags member methods (Simon Feltman) (#693099) diff --git a/PKG-INFO b/PKG-INFO index 0410ccb..eac9485 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: PyGObject -Version: 3.11.4 +Version: 3.11.5 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.11/pygobject-3.11.4.tar.gz +Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.11/pygobject-3.11.5.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 5ed8d6d..4d2e451 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1538,13 +1538,10 @@ int main () { unsigned int major, minor, micro; - char *tmp_version; fclose (fopen ("conf.glibtest", "w")); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = g_strdup("$min_glib_version"); - if (sscanf(tmp_version, "%u.%u.%u", &major, &minor, µ) != 3) { + if (sscanf("$min_glib_version", "%u.%u.%u", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_glib_version"); exit(1); } diff --git a/configure b/configure index 257ea24..726ef29 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.11.4. +# Generated by GNU Autoconf 2.69 for pygobject 3.11.5. # # Report bugs to . # @@ -591,8 +591,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pygobject' PACKAGE_TARNAME='pygobject' -PACKAGE_VERSION='3.11.4' -PACKAGE_STRING='pygobject 3.11.4' +PACKAGE_VERSION='3.11.5' +PACKAGE_STRING='pygobject 3.11.5' PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject' PACKAGE_URL='https://live.gnome.org/PyGObject/' @@ -648,6 +648,8 @@ CODE_COVERAGE_ENABLED_TRUE WARN_CFLAGS INTROSPECTION_COMPILER INTROSPECTION_SCANNER +WITH_COMMON_FALSE +WITH_COMMON_TRUE ENABLE_CAIRO_FALSE ENABLE_CAIRO_TRUE PYCAIRO_LIBS @@ -828,6 +830,7 @@ enable_thread enable_glibtest with_ffi enable_cairo +with_common enable_compile_warnings enable_iso_c enable_code_coverage @@ -1395,7 +1398,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.11.4 to adapt to many kinds of systems. +\`configure' configures pygobject 3.11.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1465,7 +1468,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pygobject 3.11.4:";; + short | recursive ) echo "Configuration of pygobject 3.11.5:";; esac cat <<\_ACEOF @@ -1503,6 +1506,8 @@ Optional Packages: program name is given; if not given, searches for a few standard names such as "python3" or "python2" --without-ffi Disable libffi support + --without-common For package maintainers: do not install Python + version independent files Some influential environment variables: CC C compiler command @@ -1600,7 +1605,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pygobject configure 3.11.4 +pygobject configure 3.11.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1878,7 +1883,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.11.4, which was +It was created by pygobject $as_me 3.11.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2242,9 +2247,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 11" >>confdefs.h PYGOBJECT_MINOR_VERSION=11 -$as_echo "#define PYGOBJECT_MICRO_VERSION 4" >>confdefs.h +$as_echo "#define PYGOBJECT_MICRO_VERSION 5" >>confdefs.h -PYGOBJECT_MICRO_VERSION=4 +PYGOBJECT_MICRO_VERSION=5 ac_config_headers="$ac_config_headers config.h" @@ -2755,7 +2760,7 @@ fi # Define the identity of the package. PACKAGE='pygobject' - VERSION='3.11.4' + VERSION='3.11.5' cat >>confdefs.h <<_ACEOF @@ -13402,13 +13407,10 @@ int main () { unsigned int major, minor, micro; - char *tmp_version; fclose (fopen ("conf.glibtest", "w")); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = g_strdup("$min_glib_version"); - if (sscanf(tmp_version, "%u.%u.%u", &major, &minor, µ) != 3) { + if (sscanf("$min_glib_version", "%u.%u.%u", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_glib_version"); exit(1); } @@ -14205,6 +14207,23 @@ else fi + +# Check whether --with-common was given. +if test "${with_common+set}" = set; then : + withval=$with_common; with_common=$enableval +else + with_common=yes +fi + + if test "$with_common" = "yes"; then + WITH_COMMON_TRUE= + WITH_COMMON_FALSE='#' +else + WITH_COMMON_TRUE='#' + WITH_COMMON_FALSE= +fi + + INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` @@ -14720,7 +14739,7 @@ fi CFLAGS="$CFLAGS $WARN_CFLAGS $CODE_COVERAGE_CFLAGS" LDFLAGS="$LDFLAGS $CODE_COVERAGE_CFLAGS" -ac_config_files="$ac_config_files Makefile pygobject-3.0.pc pygobject-3.0-uninstalled.pc gi/Makefile gi/repository/Makefile gi/overrides/Makefile gi/_glib/Makefile gi/_gobject/Makefile examples/Makefile tests/Makefile pygtkcompat/Makefile PKG-INFO" +ac_config_files="$ac_config_files Makefile pygobject-3.0.pc pygobject-3.0-uninstalled.pc gi/Makefile gi/repository/Makefile gi/overrides/Makefile gi/_gobject/Makefile examples/Makefile tests/Makefile pygtkcompat/Makefile PKG-INFO" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -14867,6 +14886,10 @@ if test -z "${ENABLE_CAIRO_TRUE}" && test -z "${ENABLE_CAIRO_FALSE}"; then as_fn_error $? "conditional \"ENABLE_CAIRO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${WITH_COMMON_TRUE}" && test -z "${WITH_COMMON_FALSE}"; then + as_fn_error $? "conditional \"WITH_COMMON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${CODE_COVERAGE_ENABLED_TRUE}" && test -z "${CODE_COVERAGE_ENABLED_FALSE}"; then as_fn_error $? "conditional \"CODE_COVERAGE_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15268,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.11.4, which was +This file was extended by pygobject $as_me 3.11.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15335,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.11.4 +pygobject config.status 3.11.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -15752,7 +15775,6 @@ do "gi/Makefile") CONFIG_FILES="$CONFIG_FILES gi/Makefile" ;; "gi/repository/Makefile") CONFIG_FILES="$CONFIG_FILES gi/repository/Makefile" ;; "gi/overrides/Makefile") CONFIG_FILES="$CONFIG_FILES gi/overrides/Makefile" ;; - "gi/_glib/Makefile") CONFIG_FILES="$CONFIG_FILES gi/_glib/Makefile" ;; "gi/_gobject/Makefile") CONFIG_FILES="$CONFIG_FILES gi/_gobject/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; diff --git a/configure.ac b/configure.ac index e85bedf..93305f9 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, 11) -m4_define(pygobject_micro_version, 4) +m4_define(pygobject_micro_version, 5) m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version) dnl versions of packages we require ... @@ -226,6 +226,13 @@ if test "$enable_cairo" != no; then fi AM_CONDITIONAL(ENABLE_CAIRO, test "$enable_cairo" = "yes") +AC_ARG_WITH(common, + AS_HELP_STRING([--without-common], + [For package maintainers: do not install Python version independent files]), + with_common=$enableval, + with_common=yes) +AM_CONDITIONAL(WITH_COMMON, test "$with_common" = "yes") + INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` @@ -268,7 +275,6 @@ AC_CONFIG_FILES( gi/Makefile gi/repository/Makefile gi/overrides/Makefile - gi/_glib/Makefile gi/_gobject/Makefile examples/Makefile tests/Makefile diff --git a/gi/Makefile.am b/gi/Makefile.am index aa91a46..b00d30a 100644 --- a/gi/Makefile.am +++ b/gi/Makefile.am @@ -1,7 +1,8 @@ +PLATFORM_VERSION = 3.0 + SUBDIRS = \ repository \ overrides \ - _glib \ _gobject extension_cppflags = \ @@ -24,11 +25,46 @@ extension_ldflags += \ -no-undefined endif +pkgincludedir = $(includedir)/pygobject-$(PLATFORM_VERSION) +if WITH_COMMON +pkginclude_HEADERS = pygobject.h +endif + pygidir = $(pyexecdir)/gi pygi_LTLIBRARIES = _gi.la _gi_la_SOURCES = \ + gobjectmodule.c \ + pygboxed.c \ + pygboxed.h \ + pygenum.c \ + pygenum.h \ + pygflags.c \ + pygflags.h \ + pyginterface.c \ + pyginterface.h \ + pygobject.c \ + pygobject.h \ + pygobject-private.h \ + pygparamspec.c \ + pygparamspec.h \ + pygpointer.c \ + pygpointer.h \ + pygtype.c \ + pygtype.h \ + glibmodule.c \ + pygoptioncontext.c \ + pygoptioncontext.h \ + pygoptiongroup.c \ + pygoptiongroup.h \ + pygspawn.c \ + pygspawn.h \ + pyglib.c \ + pyglib.h \ + pyglib-private.h \ + pyglib-python-compat.h \ + gimodule.c \ pygi-repository.c \ pygi-repository.h \ pygi-info.c \ @@ -56,28 +92,41 @@ _gi_la_SOURCES = \ pygi-signal-closure.c \ pygi-signal-closure.h \ pygobject-external.h \ - gimodule.c \ pygi-invoke.c \ pygi-invoke.h \ pygi-invoke-state-struct.h \ pygi-cache.h \ pygi-cache.c \ - pygi-marshal-from-py.c \ - pygi-marshal-from-py.h \ - pygi-marshal-to-py.c \ - pygi-marshal-to-py.h \ pygi-marshal-cleanup.c \ - pygi-marshal-cleanup.h + pygi-marshal-cleanup.h \ + pygi-basictype.c \ + pygi-basictype.h \ + pygi-list.c \ + pygi-list.h \ + pygi-array.c \ + pygi-array.h \ + pygi-error.c \ + pygi-error.h \ + pygi-object.c \ + pygi-object.h \ + pygi-value.c \ + pygi-value.h \ + pygi-enum-marshal.c \ + pygi-enum-marshal.h \ + pygi-struct-marshal.c \ + pygi-struct-marshal.h \ + pygi-hashtable.c \ + pygi-hashtable.h _gi_la_CFLAGS = \ + $(extension_cppflags) \ + $(GLIB_CFLAGS) \ $(GI_CFLAGS) _gi_la_CPPFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi/_gobject + $(extension_cppflags) _gi_la_LIBADD = \ $(extension_libadd) \ - $(GI_LIBS) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la + $(GLIB_LIBS) \ + $(GI_LIBS) _gi_la_LDFLAGS = \ $(extension_ldflags) \ -export-symbols-regex "init_gi|PyInit__gi" @@ -92,9 +141,7 @@ _gi_cairo_la_CFLAGS = \ $(GI_CFLAGS) \ $(PYCAIRO_CFLAGS) _gi_cairo_la_CPPFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi/_gobject + $(extension_cppflags) _gi_cairo_la_LIBADD = \ $(extension_libadd) \ $(GI_LIBS) \ diff --git a/gi/Makefile.in b/gi/Makefile.in index d4f89c7..0f6fa1f 100644 --- a/gi/Makefile.in +++ b/gi/Makefile.in @@ -15,6 +15,7 @@ @SET_MAKE@ + VPATH = @srcdir@ am__make_dryrun = \ { \ @@ -34,7 +35,6 @@ am__make_dryrun = \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd @@ -56,7 +56,8 @@ host_triplet = @host@ @ENABLE_CAIRO_TRUE@am__append_2 = _gi_cairo.la subdir = gi -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/libtool.m4 \ @@ -96,21 +97,30 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(pygidir)" +am__installdirs = "$(DESTDIR)$(pygidir)" "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(pygi_LTLIBRARIES) am__DEPENDENCIES_1 = @OS_WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) _gi_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la -am__gi_la_OBJECTS = _gi_la-pygi-repository.lo _gi_la-pygi-info.lo \ + $(am__DEPENDENCIES_1) +am__gi_la_OBJECTS = _gi_la-gobjectmodule.lo _gi_la-pygboxed.lo \ + _gi_la-pygenum.lo _gi_la-pygflags.lo _gi_la-pyginterface.lo \ + _gi_la-pygobject.lo _gi_la-pygparamspec.lo \ + _gi_la-pygpointer.lo _gi_la-pygtype.lo _gi_la-glibmodule.lo \ + _gi_la-pygoptioncontext.lo _gi_la-pygoptiongroup.lo \ + _gi_la-pygspawn.lo _gi_la-pyglib.lo _gi_la-gimodule.lo \ + _gi_la-pygi-repository.lo _gi_la-pygi-info.lo \ _gi_la-pygi-foreign.lo _gi_la-pygi-struct.lo \ _gi_la-pygi-source.lo _gi_la-pygi-argument.lo \ _gi_la-pygi-type.lo _gi_la-pygi-boxed.lo \ _gi_la-pygi-closure.lo _gi_la-pygi-ccallback.lo \ _gi_la-pygi-property.lo _gi_la-pygi-signal-closure.lo \ - _gi_la-gimodule.lo _gi_la-pygi-invoke.lo _gi_la-pygi-cache.lo \ - _gi_la-pygi-marshal-from-py.lo _gi_la-pygi-marshal-to-py.lo \ - _gi_la-pygi-marshal-cleanup.lo + _gi_la-pygi-invoke.lo _gi_la-pygi-cache.lo \ + _gi_la-pygi-marshal-cleanup.lo _gi_la-pygi-basictype.lo \ + _gi_la-pygi-list.lo _gi_la-pygi-array.lo _gi_la-pygi-error.lo \ + _gi_la-pygi-object.lo _gi_la-pygi-value.lo \ + _gi_la-pygi-enum-marshal.lo _gi_la-pygi-struct-marshal.lo \ + _gi_la-pygi-hashtable.lo _gi_la_OBJECTS = $(am__gi_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -166,6 +176,8 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__pkginclude_HEADERS_DIST = pygobject.h +HEADERS = $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -200,6 +212,7 @@ am__relativize = \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" +pkgincludedir = $(includedir)/pygobject-$(PLATFORM_VERSION) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ @@ -365,10 +378,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +PLATFORM_VERSION = 3.0 SUBDIRS = \ repository \ overrides \ - _glib \ _gobject extension_cppflags = \ @@ -384,9 +397,40 @@ extension_ldflags = -module -avoid-version -shrext $(PYTHON_SO) \ @OS_WIN32_TRUE@extension_libadd = \ @OS_WIN32_TRUE@ $(PYTHON_LIBS) +@WITH_COMMON_TRUE@pkginclude_HEADERS = pygobject.h pygidir = $(pyexecdir)/gi pygi_LTLIBRARIES = _gi.la $(am__append_2) _gi_la_SOURCES = \ + gobjectmodule.c \ + pygboxed.c \ + pygboxed.h \ + pygenum.c \ + pygenum.h \ + pygflags.c \ + pygflags.h \ + pyginterface.c \ + pyginterface.h \ + pygobject.c \ + pygobject.h \ + pygobject-private.h \ + pygparamspec.c \ + pygparamspec.h \ + pygpointer.c \ + pygpointer.h \ + pygtype.c \ + pygtype.h \ + glibmodule.c \ + pygoptioncontext.c \ + pygoptioncontext.h \ + pygoptiongroup.c \ + pygoptiongroup.h \ + pygspawn.c \ + pygspawn.h \ + pyglib.c \ + pyglib.h \ + pyglib-private.h \ + pyglib-python-compat.h \ + gimodule.c \ pygi-repository.c \ pygi-repository.h \ pygi-info.c \ @@ -414,31 +458,44 @@ _gi_la_SOURCES = \ pygi-signal-closure.c \ pygi-signal-closure.h \ pygobject-external.h \ - gimodule.c \ pygi-invoke.c \ pygi-invoke.h \ pygi-invoke-state-struct.h \ pygi-cache.h \ pygi-cache.c \ - pygi-marshal-from-py.c \ - pygi-marshal-from-py.h \ - pygi-marshal-to-py.c \ - pygi-marshal-to-py.h \ pygi-marshal-cleanup.c \ - pygi-marshal-cleanup.h + pygi-marshal-cleanup.h \ + pygi-basictype.c \ + pygi-basictype.h \ + pygi-list.c \ + pygi-list.h \ + pygi-array.c \ + pygi-array.h \ + pygi-error.c \ + pygi-error.h \ + pygi-object.c \ + pygi-object.h \ + pygi-value.c \ + pygi-value.h \ + pygi-enum-marshal.c \ + pygi-enum-marshal.h \ + pygi-struct-marshal.c \ + pygi-struct-marshal.h \ + pygi-hashtable.c \ + pygi-hashtable.h _gi_la_CFLAGS = \ + $(extension_cppflags) \ + $(GLIB_CFLAGS) \ $(GI_CFLAGS) _gi_la_CPPFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi/_gobject + $(extension_cppflags) _gi_la_LIBADD = \ $(extension_libadd) \ - $(GI_LIBS) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la + $(GLIB_LIBS) \ + $(GI_LIBS) _gi_la_LDFLAGS = \ $(extension_ldflags) \ @@ -452,9 +509,7 @@ _gi_cairo_la_CFLAGS = \ $(PYCAIRO_CFLAGS) _gi_cairo_la_CPPFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi/_gobject + $(extension_cppflags) _gi_cairo_la_LIBADD = \ $(extension_libadd) \ @@ -544,23 +599,44 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-gimodule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-glibmodule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-gobjectmodule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygboxed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygenum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygflags.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-argument.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-array.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-basictype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-boxed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-ccallback.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-closure.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-enum-marshal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-foreign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-hashtable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-invoke.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-list.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-marshal-cleanup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-marshal-from-py.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-marshal-to-py.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-object.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-property.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-repository.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-signal-closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-source.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-struct-marshal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-struct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-type.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-value.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pyginterface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pyglib.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygobject.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygoptioncontext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygoptiongroup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygparamspec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygpointer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygspawn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygtype.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -583,6 +659,111 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +_gi_la-gobjectmodule.lo: gobjectmodule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-gobjectmodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-gobjectmodule.Tpo -c -o _gi_la-gobjectmodule.lo `test -f 'gobjectmodule.c' || echo '$(srcdir)/'`gobjectmodule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-gobjectmodule.Tpo $(DEPDIR)/_gi_la-gobjectmodule.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gobjectmodule.c' object='_gi_la-gobjectmodule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-gobjectmodule.lo `test -f 'gobjectmodule.c' || echo '$(srcdir)/'`gobjectmodule.c + +_gi_la-pygboxed.lo: pygboxed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygboxed.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygboxed.Tpo -c -o _gi_la-pygboxed.lo `test -f 'pygboxed.c' || echo '$(srcdir)/'`pygboxed.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygboxed.Tpo $(DEPDIR)/_gi_la-pygboxed.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygboxed.c' object='_gi_la-pygboxed.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygboxed.lo `test -f 'pygboxed.c' || echo '$(srcdir)/'`pygboxed.c + +_gi_la-pygenum.lo: pygenum.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygenum.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygenum.Tpo -c -o _gi_la-pygenum.lo `test -f 'pygenum.c' || echo '$(srcdir)/'`pygenum.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygenum.Tpo $(DEPDIR)/_gi_la-pygenum.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygenum.c' object='_gi_la-pygenum.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygenum.lo `test -f 'pygenum.c' || echo '$(srcdir)/'`pygenum.c + +_gi_la-pygflags.lo: pygflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygflags.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygflags.Tpo -c -o _gi_la-pygflags.lo `test -f 'pygflags.c' || echo '$(srcdir)/'`pygflags.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygflags.Tpo $(DEPDIR)/_gi_la-pygflags.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygflags.c' object='_gi_la-pygflags.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygflags.lo `test -f 'pygflags.c' || echo '$(srcdir)/'`pygflags.c + +_gi_la-pyginterface.lo: pyginterface.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pyginterface.lo -MD -MP -MF $(DEPDIR)/_gi_la-pyginterface.Tpo -c -o _gi_la-pyginterface.lo `test -f 'pyginterface.c' || echo '$(srcdir)/'`pyginterface.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pyginterface.Tpo $(DEPDIR)/_gi_la-pyginterface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyginterface.c' object='_gi_la-pyginterface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pyginterface.lo `test -f 'pyginterface.c' || echo '$(srcdir)/'`pyginterface.c + +_gi_la-pygobject.lo: pygobject.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygobject.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygobject.Tpo -c -o _gi_la-pygobject.lo `test -f 'pygobject.c' || echo '$(srcdir)/'`pygobject.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygobject.Tpo $(DEPDIR)/_gi_la-pygobject.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygobject.c' object='_gi_la-pygobject.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygobject.lo `test -f 'pygobject.c' || echo '$(srcdir)/'`pygobject.c + +_gi_la-pygparamspec.lo: pygparamspec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygparamspec.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygparamspec.Tpo -c -o _gi_la-pygparamspec.lo `test -f 'pygparamspec.c' || echo '$(srcdir)/'`pygparamspec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygparamspec.Tpo $(DEPDIR)/_gi_la-pygparamspec.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygparamspec.c' object='_gi_la-pygparamspec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygparamspec.lo `test -f 'pygparamspec.c' || echo '$(srcdir)/'`pygparamspec.c + +_gi_la-pygpointer.lo: pygpointer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygpointer.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygpointer.Tpo -c -o _gi_la-pygpointer.lo `test -f 'pygpointer.c' || echo '$(srcdir)/'`pygpointer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygpointer.Tpo $(DEPDIR)/_gi_la-pygpointer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygpointer.c' object='_gi_la-pygpointer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygpointer.lo `test -f 'pygpointer.c' || echo '$(srcdir)/'`pygpointer.c + +_gi_la-pygtype.lo: pygtype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygtype.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygtype.Tpo -c -o _gi_la-pygtype.lo `test -f 'pygtype.c' || echo '$(srcdir)/'`pygtype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygtype.Tpo $(DEPDIR)/_gi_la-pygtype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygtype.c' object='_gi_la-pygtype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygtype.lo `test -f 'pygtype.c' || echo '$(srcdir)/'`pygtype.c + +_gi_la-glibmodule.lo: glibmodule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-glibmodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-glibmodule.Tpo -c -o _gi_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-glibmodule.Tpo $(DEPDIR)/_gi_la-glibmodule.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glibmodule.c' object='_gi_la-glibmodule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c + +_gi_la-pygoptioncontext.lo: pygoptioncontext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygoptioncontext.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygoptioncontext.Tpo -c -o _gi_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygoptioncontext.Tpo $(DEPDIR)/_gi_la-pygoptioncontext.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygoptioncontext.c' object='_gi_la-pygoptioncontext.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c + +_gi_la-pygoptiongroup.lo: pygoptiongroup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygoptiongroup.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygoptiongroup.Tpo -c -o _gi_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygoptiongroup.Tpo $(DEPDIR)/_gi_la-pygoptiongroup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygoptiongroup.c' object='_gi_la-pygoptiongroup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c + +_gi_la-pygspawn.lo: pygspawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygspawn.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygspawn.Tpo -c -o _gi_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygspawn.Tpo $(DEPDIR)/_gi_la-pygspawn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygspawn.c' object='_gi_la-pygspawn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c + +_gi_la-pyglib.lo: pyglib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pyglib.lo -MD -MP -MF $(DEPDIR)/_gi_la-pyglib.Tpo -c -o _gi_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pyglib.Tpo $(DEPDIR)/_gi_la-pyglib.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyglib.c' object='_gi_la-pyglib.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c + +_gi_la-gimodule.lo: gimodule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-gimodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-gimodule.Tpo -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-gimodule.Tpo $(DEPDIR)/_gi_la-gimodule.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gimodule.c' object='_gi_la-gimodule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c + _gi_la-pygi-repository.lo: pygi-repository.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-repository.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-repository.Tpo -c -o _gi_la-pygi-repository.lo `test -f 'pygi-repository.c' || echo '$(srcdir)/'`pygi-repository.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-repository.Tpo $(DEPDIR)/_gi_la-pygi-repository.Plo @@ -667,13 +848,6 @@ _gi_la-pygi-signal-closure.lo: pygi-signal-closure.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-signal-closure.lo `test -f 'pygi-signal-closure.c' || echo '$(srcdir)/'`pygi-signal-closure.c -_gi_la-gimodule.lo: gimodule.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-gimodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-gimodule.Tpo -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-gimodule.Tpo $(DEPDIR)/_gi_la-gimodule.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gimodule.c' object='_gi_la-gimodule.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c - _gi_la-pygi-invoke.lo: pygi-invoke.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-invoke.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-invoke.Tpo -c -o _gi_la-pygi-invoke.lo `test -f 'pygi-invoke.c' || echo '$(srcdir)/'`pygi-invoke.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-invoke.Tpo $(DEPDIR)/_gi_la-pygi-invoke.Plo @@ -688,20 +862,6 @@ _gi_la-pygi-cache.lo: pygi-cache.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-cache.lo `test -f 'pygi-cache.c' || echo '$(srcdir)/'`pygi-cache.c -_gi_la-pygi-marshal-from-py.lo: pygi-marshal-from-py.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-marshal-from-py.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-marshal-from-py.Tpo -c -o _gi_la-pygi-marshal-from-py.lo `test -f 'pygi-marshal-from-py.c' || echo '$(srcdir)/'`pygi-marshal-from-py.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-marshal-from-py.Tpo $(DEPDIR)/_gi_la-pygi-marshal-from-py.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-marshal-from-py.c' object='_gi_la-pygi-marshal-from-py.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-marshal-from-py.lo `test -f 'pygi-marshal-from-py.c' || echo '$(srcdir)/'`pygi-marshal-from-py.c - -_gi_la-pygi-marshal-to-py.lo: pygi-marshal-to-py.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-marshal-to-py.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-marshal-to-py.Tpo -c -o _gi_la-pygi-marshal-to-py.lo `test -f 'pygi-marshal-to-py.c' || echo '$(srcdir)/'`pygi-marshal-to-py.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-marshal-to-py.Tpo $(DEPDIR)/_gi_la-pygi-marshal-to-py.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-marshal-to-py.c' object='_gi_la-pygi-marshal-to-py.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-marshal-to-py.lo `test -f 'pygi-marshal-to-py.c' || echo '$(srcdir)/'`pygi-marshal-to-py.c - _gi_la-pygi-marshal-cleanup.lo: pygi-marshal-cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-marshal-cleanup.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-marshal-cleanup.Tpo -c -o _gi_la-pygi-marshal-cleanup.lo `test -f 'pygi-marshal-cleanup.c' || echo '$(srcdir)/'`pygi-marshal-cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-marshal-cleanup.Tpo $(DEPDIR)/_gi_la-pygi-marshal-cleanup.Plo @@ -709,6 +869,69 @@ _gi_la-pygi-marshal-cleanup.lo: pygi-marshal-cleanup.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-marshal-cleanup.lo `test -f 'pygi-marshal-cleanup.c' || echo '$(srcdir)/'`pygi-marshal-cleanup.c +_gi_la-pygi-basictype.lo: pygi-basictype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-basictype.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-basictype.Tpo -c -o _gi_la-pygi-basictype.lo `test -f 'pygi-basictype.c' || echo '$(srcdir)/'`pygi-basictype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-basictype.Tpo $(DEPDIR)/_gi_la-pygi-basictype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-basictype.c' object='_gi_la-pygi-basictype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-basictype.lo `test -f 'pygi-basictype.c' || echo '$(srcdir)/'`pygi-basictype.c + +_gi_la-pygi-list.lo: pygi-list.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-list.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-list.Tpo -c -o _gi_la-pygi-list.lo `test -f 'pygi-list.c' || echo '$(srcdir)/'`pygi-list.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-list.Tpo $(DEPDIR)/_gi_la-pygi-list.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-list.c' object='_gi_la-pygi-list.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-list.lo `test -f 'pygi-list.c' || echo '$(srcdir)/'`pygi-list.c + +_gi_la-pygi-array.lo: pygi-array.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-array.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-array.Tpo -c -o _gi_la-pygi-array.lo `test -f 'pygi-array.c' || echo '$(srcdir)/'`pygi-array.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-array.Tpo $(DEPDIR)/_gi_la-pygi-array.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-array.c' object='_gi_la-pygi-array.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-array.lo `test -f 'pygi-array.c' || echo '$(srcdir)/'`pygi-array.c + +_gi_la-pygi-error.lo: pygi-error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-error.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-error.Tpo -c -o _gi_la-pygi-error.lo `test -f 'pygi-error.c' || echo '$(srcdir)/'`pygi-error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-error.Tpo $(DEPDIR)/_gi_la-pygi-error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-error.c' object='_gi_la-pygi-error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-error.lo `test -f 'pygi-error.c' || echo '$(srcdir)/'`pygi-error.c + +_gi_la-pygi-object.lo: pygi-object.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-object.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-object.Tpo -c -o _gi_la-pygi-object.lo `test -f 'pygi-object.c' || echo '$(srcdir)/'`pygi-object.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-object.Tpo $(DEPDIR)/_gi_la-pygi-object.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-object.c' object='_gi_la-pygi-object.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-object.lo `test -f 'pygi-object.c' || echo '$(srcdir)/'`pygi-object.c + +_gi_la-pygi-value.lo: pygi-value.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-value.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-value.Tpo -c -o _gi_la-pygi-value.lo `test -f 'pygi-value.c' || echo '$(srcdir)/'`pygi-value.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-value.Tpo $(DEPDIR)/_gi_la-pygi-value.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-value.c' object='_gi_la-pygi-value.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-value.lo `test -f 'pygi-value.c' || echo '$(srcdir)/'`pygi-value.c + +_gi_la-pygi-enum-marshal.lo: pygi-enum-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-enum-marshal.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-enum-marshal.Tpo -c -o _gi_la-pygi-enum-marshal.lo `test -f 'pygi-enum-marshal.c' || echo '$(srcdir)/'`pygi-enum-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-enum-marshal.Tpo $(DEPDIR)/_gi_la-pygi-enum-marshal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-enum-marshal.c' object='_gi_la-pygi-enum-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-enum-marshal.lo `test -f 'pygi-enum-marshal.c' || echo '$(srcdir)/'`pygi-enum-marshal.c + +_gi_la-pygi-struct-marshal.lo: pygi-struct-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-struct-marshal.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-struct-marshal.Tpo -c -o _gi_la-pygi-struct-marshal.lo `test -f 'pygi-struct-marshal.c' || echo '$(srcdir)/'`pygi-struct-marshal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-struct-marshal.Tpo $(DEPDIR)/_gi_la-pygi-struct-marshal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-struct-marshal.c' object='_gi_la-pygi-struct-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-struct-marshal.lo `test -f 'pygi-struct-marshal.c' || echo '$(srcdir)/'`pygi-struct-marshal.c + +_gi_la-pygi-hashtable.lo: pygi-hashtable.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-hashtable.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-hashtable.Tpo -c -o _gi_la-pygi-hashtable.lo `test -f 'pygi-hashtable.c' || echo '$(srcdir)/'`pygi-hashtable.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-hashtable.Tpo $(DEPDIR)/_gi_la-pygi-hashtable.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygi-hashtable.c' object='_gi_la-pygi-hashtable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_la_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-hashtable.lo `test -f 'pygi-hashtable.c' || echo '$(srcdir)/'`pygi-hashtable.c + _gi_cairo_la-pygi-foreign-cairo.lo: pygi-foreign-cairo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_gi_cairo_la_CPPFLAGS) $(CPPFLAGS) $(_gi_cairo_la_CFLAGS) $(CFLAGS) -MT _gi_cairo_la-pygi-foreign-cairo.lo -MD -MP -MF $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Tpo -c -o _gi_cairo_la-pygi-foreign-cairo.lo `test -f 'pygi-foreign-cairo.c' || echo '$(srcdir)/'`pygi-foreign-cairo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Tpo $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Plo @@ -721,6 +944,27 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. @@ -915,10 +1159,10 @@ distdir: $(DISTFILES) check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive -all-am: Makefile $(LTLIBRARIES) all-local +all-am: Makefile $(LTLIBRARIES) $(HEADERS) all-local installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(pygidir)"; do \ + for dir in "$(DESTDIR)$(pygidir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -974,7 +1218,7 @@ info: info-recursive info-am: -install-data-am: install-pygiLTLIBRARIES +install-data-am: install-pkgincludeHEADERS install-pygiLTLIBRARIES install-dvi: install-dvi-recursive @@ -1020,7 +1264,7 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-pygiLTLIBRARIES +uninstall-am: uninstall-pkgincludeHEADERS uninstall-pygiLTLIBRARIES .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ ctags-recursive install-am install-strip tags-recursive @@ -1034,13 +1278,13 @@ uninstall-am: uninstall-pygiLTLIBRARIES install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am \ - install-pygiLTLIBRARIES install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-recursive uninstall uninstall-am \ - uninstall-pygiLTLIBRARIES + install-pdf-am install-pkgincludeHEADERS install-ps \ + install-ps-am install-pygiLTLIBRARIES install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-pkgincludeHEADERS uninstall-pygiLTLIBRARIES # This is to ensure we have a symlink to the .so in the diff --git a/gi/__init__.py b/gi/__init__.py index 0645d44..7c1a279 100644 --- a/gi/__init__.py +++ b/gi/__init__.py @@ -24,24 +24,27 @@ from __future__ import absolute_import from pkgutil import extend_path __path__ = extend_path(__path__, __name__) +import sys +import os + +# we can't have pygobject 2 loaded at the same time we load the internal _gobject +if 'gobject' in sys.modules: + raise ImportError('When using gi.repository you must not import static ' + 'modules like "gobject". Please change all occurrences ' + 'of "import gobject" to "from gi.repository import GObject".') + +from ._gi import _gobject from ._gi import _API from ._gi import Repository from ._gi import PyGIDeprecationWarning -# Force loading the GObject typelib so we have available the wrappers for -# base classes such as GInitiallyUnowned -import gi._gobject -gi # pyflakes - _API = _API # pyflakes PyGIDeprecationWarning = PyGIDeprecationWarning -import os - _versions = {} _overridesdir = os.path.join(os.path.dirname(__file__), 'overrides') -version_info = gi._gobject.pygobject_version[:] +version_info = _gobject.pygobject_version[:] __version__ = "{0}.{1}.{2}".format(*version_info) diff --git a/gi/_constants.py b/gi/_constants.py new file mode 100644 index 0000000..495c6e1 --- /dev/null +++ b/gi/_constants.py @@ -0,0 +1,49 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# pygobject - Python bindings for the GObject library +# Copyright (C) 2006-2007 Johan Dahlin +# +# gi/_constants.py: GObject type constants +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA + +from ._gi import _gobject + +TYPE_INVALID = _gobject.TYPE_INVALID +TYPE_NONE = _gobject.type_from_name('void') +TYPE_INTERFACE = _gobject.type_from_name('GInterface') +TYPE_CHAR = _gobject.type_from_name('gchar') +TYPE_UCHAR = _gobject.type_from_name('guchar') +TYPE_BOOLEAN = _gobject.type_from_name('gboolean') +TYPE_INT = _gobject.type_from_name('gint') +TYPE_UINT = _gobject.type_from_name('guint') +TYPE_LONG = _gobject.type_from_name('glong') +TYPE_ULONG = _gobject.type_from_name('gulong') +TYPE_INT64 = _gobject.type_from_name('gint64') +TYPE_UINT64 = _gobject.type_from_name('guint64') +TYPE_ENUM = _gobject.type_from_name('GEnum') +TYPE_FLAGS = _gobject.type_from_name('GFlags') +TYPE_FLOAT = _gobject.type_from_name('gfloat') +TYPE_DOUBLE = _gobject.type_from_name('gdouble') +TYPE_STRING = _gobject.type_from_name('gchararray') +TYPE_POINTER = _gobject.type_from_name('gpointer') +TYPE_BOXED = _gobject.type_from_name('GBoxed') +TYPE_PARAM = _gobject.type_from_name('GParam') +TYPE_OBJECT = _gobject.type_from_name('GObject') +TYPE_PYOBJECT = _gobject.type_from_name('PyObject') +TYPE_GTYPE = _gobject.type_from_name('GType') +TYPE_STRV = _gobject.type_from_name('GStrv') +TYPE_VARIANT = _gobject.type_from_name('GVariant') +TYPE_UNICHAR = TYPE_UINT diff --git a/gi/_glib/Makefile.am b/gi/_glib/Makefile.am deleted file mode 100644 index 774b7e1..0000000 --- a/gi/_glib/Makefile.am +++ /dev/null @@ -1,91 +0,0 @@ -AUTOMAKE_OPTIONS = 1.7 - -extension_cppflags = \ - $(PYTHON_INCLUDES) \ - -DPY_SSIZE_T_CLEAN - -extension_ldflags = \ - -module \ - -avoid-version \ - -shrext $(PYTHON_SO) - -if OS_WIN32 -# Windows requires Python modules to be explicitly linked to libpython. -# Extension modules are shared libaries (.dll), but need to be -# called .pyd for Python to load it as an extension module. -extension_libadd = \ - $(PYTHON_LIBS) - -extension_ldflags += \ - -no-undefined -endif - - -pyglibdir = $(pyexecdir)/gi/_glib - -pyglib_PYTHON = \ - __init__.py \ - option.py - -lib_LTLIBRARIES = libpyglib-gi-2.0-@PYTHON_BASENAME@.la - -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES = \ - pyglib.c \ - pyglib.h \ - pyglib-private.h \ - pyglib-python-compat.h -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CPPFLAGS = \ - $(extension_cppflags) -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CFLAGS = \ - $(GLIB_CFLAGS) -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LIBADD = \ - $(extension_libadd) \ - $(FFI_LIBS) \ - $(GLIB_LIBS) - -if OS_WIN32 -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LDFLAGS = \ - -no-undefined -endif - -pyglib_LTLIBRARIES = _glib.la - -_glib_la_SOURCES = \ - glibmodule.c \ - pygoptioncontext.c \ - pygoptioncontext.h \ - pygoptiongroup.c \ - pygoptiongroup.h \ - pygspawn.c \ - pygspawn.h -_glib_la_CFLAGS = \ - $(GLIB_CFLAGS) -_glib_la_CPPFLAGS = \ - $(extension_cppflags) -_glib_la_LIBADD = \ - $(extension_libadd) \ - $(GLIB_LIBS) \ - libpyglib-gi-2.0-@PYTHON_BASENAME@.la -_glib_la_LDFLAGS = \ - $(extension_ldflags) \ - -export-symbols-regex "_glib|PyInit__glib" - -if PLATFORM_WIN32 -_glib_la_CFLAGS += -DPLATFORM_WIN32 -endif - -# if we build in a separate tree, we need to symlink the *.py files from the -# source tree; Python does not accept the extensions and modules in different -# paths -build_pylinks: - for f in $(pyglib_PYTHON); do \ - [ -e $(builddir)/$$f ] || $(LN_S) $(srcdir)/$$f $(builddir)/$$f; \ - done - - -all: $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -check-local: $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -clean-local: - rm -f $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) -%$(PYTHON_SO): %.la - $(LN_S) -f .libs/$@ $@ diff --git a/gi/_glib/Makefile.in b/gi/_glib/Makefile.in deleted file mode 100644 index 2829376..0000000 --- a/gi/_glib/Makefile.in +++ /dev/null @@ -1,845 +0,0 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@OS_WIN32_TRUE@am__append_1 = \ -@OS_WIN32_TRUE@ -no-undefined - -@PLATFORM_WIN32_TRUE@am__append_2 = -DPLATFORM_WIN32 -subdir = gi/_glib -DIST_COMMON = $(pyglib_PYTHON) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ - $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/python.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyglibdir)" \ - "$(DESTDIR)$(pyglibdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) $(pyglib_LTLIBRARIES) -am__DEPENDENCIES_1 = -@OS_WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -_glib_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ - libpyglib-gi-2.0-@PYTHON_BASENAME@.la -am__glib_la_OBJECTS = _glib_la-glibmodule.lo \ - _glib_la-pygoptioncontext.lo _glib_la-pygoptiongroup.lo \ - _glib_la-pygspawn.lo -_glib_la_OBJECTS = $(am__glib_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -_glib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_glib_la_CFLAGS) \ - $(CFLAGS) $(_glib_la_LDFLAGS) $(LDFLAGS) -o $@ -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am_libpyglib_gi_2_0_@PYTHON_BASENAME@_la_OBJECTS = \ - libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_OBJECTS = \ - $(am_libpyglib_gi_2_0_@PYTHON_BASENAME@_la_OBJECTS) -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CFLAGS) \ - $(CFLAGS) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(_glib_la_SOURCES) \ - $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES) -DIST_SOURCES = $(_glib_la_SOURCES) \ - $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) -py_compile = $(top_srcdir)/py-compile -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CAIRO_CFLAGS = @CAIRO_CFLAGS@ -CAIRO_LIBS = @CAIRO_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIR = @DATADIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FFI_CFLAGS = @FFI_CFLAGS@ -FFI_LIBS = @FFI_LIBS@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GIO_CFLAGS = @GIO_CFLAGS@ -GIO_LIBS = @GIO_LIBS@ -GI_CFLAGS = @GI_CFLAGS@ -GI_DATADIR = @GI_DATADIR@ -GI_LIBS = @GI_LIBS@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GOBJECT_QUERY = @GOBJECT_QUERY@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBFFI_PC = @LIBFFI_PC@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PLATFORM = @PLATFORM@ -PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ -PYCAIRO_LIBS = @PYCAIRO_LIBS@ -PYGOBJECT_MAJOR_VERSION = @PYGOBJECT_MAJOR_VERSION@ -PYGOBJECT_MICRO_VERSION = @PYGOBJECT_MICRO_VERSION@ -PYGOBJECT_MINOR_VERSION = @PYGOBJECT_MINOR_VERSION@ -PYTHON = @PYTHON@ -PYTHON_BASENAME = @PYTHON_BASENAME@ -PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ -PYTHON_INCLUDES = @PYTHON_INCLUDES@ -PYTHON_LIBS = @PYTHON_LIBS@ -PYTHON_LIB_LOC = @PYTHON_LIB_LOC@ -PYTHON_PLATFORM = @PYTHON_PLATFORM@ -PYTHON_PREFIX = @PYTHON_PREFIX@ -PYTHON_SO = @PYTHON_SO@ -PYTHON_VERSION = @PYTHON_VERSION@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -THREADING_CFLAGS = @THREADING_CFLAGS@ -VERSION = @VERSION@ -WARN_CFLAGS = @WARN_CFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgpyexecdir = @pkgpyexecdir@ -pkgpythondir = @pkgpythondir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -pyexecdir = @pyexecdir@ -pythondir = @pythondir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = 1.7 -extension_cppflags = \ - $(PYTHON_INCLUDES) \ - -DPY_SSIZE_T_CLEAN - -extension_ldflags = -module -avoid-version -shrext $(PYTHON_SO) \ - $(am__append_1) - -# Windows requires Python modules to be explicitly linked to libpython. -# Extension modules are shared libaries (.dll), but need to be -# called .pyd for Python to load it as an extension module. -@OS_WIN32_TRUE@extension_libadd = \ -@OS_WIN32_TRUE@ $(PYTHON_LIBS) - -pyglibdir = $(pyexecdir)/gi/_glib -pyglib_PYTHON = \ - __init__.py \ - option.py - -lib_LTLIBRARIES = libpyglib-gi-2.0-@PYTHON_BASENAME@.la -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES = \ - pyglib.c \ - pyglib.h \ - pyglib-private.h \ - pyglib-python-compat.h - -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CPPFLAGS = \ - $(extension_cppflags) - -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CFLAGS = \ - $(GLIB_CFLAGS) - -libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LIBADD = \ - $(extension_libadd) \ - $(FFI_LIBS) \ - $(GLIB_LIBS) - -@OS_WIN32_TRUE@libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LDFLAGS = \ -@OS_WIN32_TRUE@ -no-undefined - -pyglib_LTLIBRARIES = _glib.la -_glib_la_SOURCES = \ - glibmodule.c \ - pygoptioncontext.c \ - pygoptioncontext.h \ - pygoptiongroup.c \ - pygoptiongroup.h \ - pygspawn.c \ - pygspawn.h - -_glib_la_CFLAGS = $(GLIB_CFLAGS) $(am__append_2) -_glib_la_CPPFLAGS = \ - $(extension_cppflags) - -_glib_la_LIBADD = \ - $(extension_libadd) \ - $(GLIB_LIBS) \ - libpyglib-gi-2.0-@PYTHON_BASENAME@.la - -_glib_la_LDFLAGS = \ - $(extension_ldflags) \ - -export-symbols-regex "_glib|PyInit__glib" - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign gi/_glib/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign gi/_glib/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -install-pyglibLTLIBRARIES: $(pyglib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(pyglib_LTLIBRARIES)'; test -n "$(pyglibdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(pyglibdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pyglibdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pyglibdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pyglibdir)"; \ - } - -uninstall-pyglibLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(pyglib_LTLIBRARIES)'; test -n "$(pyglibdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pyglibdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pyglibdir)/$$f"; \ - done - -clean-pyglibLTLIBRARIES: - -test -z "$(pyglib_LTLIBRARIES)" || rm -f $(pyglib_LTLIBRARIES) - @list='$(pyglib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -_glib.la: $(_glib_la_OBJECTS) $(_glib_la_DEPENDENCIES) $(EXTRA__glib_la_DEPENDENCIES) - $(AM_V_CCLD)$(_glib_la_LINK) -rpath $(pyglibdir) $(_glib_la_OBJECTS) $(_glib_la_LIBADD) $(LIBS) -libpyglib-gi-2.0-@PYTHON_BASENAME@.la: $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_OBJECTS) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_DEPENDENCIES) $(EXTRA_libpyglib_gi_2_0_@PYTHON_BASENAME@_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LINK) -rpath $(libdir) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_OBJECTS) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-glibmodule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygoptioncontext.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygoptiongroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygspawn.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -_glib_la-glibmodule.lo: glibmodule.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-glibmodule.lo -MD -MP -MF $(DEPDIR)/_glib_la-glibmodule.Tpo -c -o _glib_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_glib_la-glibmodule.Tpo $(DEPDIR)/_glib_la-glibmodule.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glibmodule.c' object='_glib_la-glibmodule.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c - -_glib_la-pygoptioncontext.lo: pygoptioncontext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygoptioncontext.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygoptioncontext.Tpo -c -o _glib_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_glib_la-pygoptioncontext.Tpo $(DEPDIR)/_glib_la-pygoptioncontext.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygoptioncontext.c' object='_glib_la-pygoptioncontext.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c - -_glib_la-pygoptiongroup.lo: pygoptiongroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygoptiongroup.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygoptiongroup.Tpo -c -o _glib_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_glib_la-pygoptiongroup.Tpo $(DEPDIR)/_glib_la-pygoptiongroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygoptiongroup.c' object='_glib_la-pygoptiongroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c - -_glib_la-pygspawn.lo: pygspawn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygspawn.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygspawn.Tpo -c -o _glib_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_glib_la-pygspawn.Tpo $(DEPDIR)/_glib_la-pygspawn.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygspawn.c' object='_glib_la-pygspawn.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(_glib_la_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c - -libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo: pyglib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CPPFLAGS) $(CPPFLAGS) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CFLAGS) $(CFLAGS) -MT libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo -MD -MP -MF $(DEPDIR)/libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.Tpo -c -o libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.Tpo $(DEPDIR)/libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyglib.c' object='libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CPPFLAGS) $(CPPFLAGS) $(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_CFLAGS) $(CFLAGS) -c -o libpyglib_gi_2_0_@PYTHON_BASENAME@_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pyglibPYTHON: $(pyglib_PYTHON) - @$(NORMAL_INSTALL) - @list='$(pyglib_PYTHON)'; dlist=; list2=; test -n "$(pyglibdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pyglibdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pyglibdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ - if test -f $$b$$p; then \ - $(am__strip_dir) \ - dlist="$$dlist $$f"; \ - list2="$$list2 $$b$$p"; \ - else :; fi; \ - done; \ - for file in $$list2; do echo $$file; done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pyglibdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pyglibdir)" || exit $$?; \ - done || exit $$?; \ - if test -n "$$dlist"; then \ - if test -z "$(DESTDIR)"; then \ - $(am__py_compile) --basedir "$(pyglibdir)" $$dlist; \ - else \ - $(am__py_compile) --destdir "$(DESTDIR)" \ - --basedir "$(pyglibdir)" $$dlist; \ - fi; \ - else :; fi - -uninstall-pyglibPYTHON: - @$(NORMAL_UNINSTALL) - @list='$(pyglib_PYTHON)'; test -n "$(pyglibdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - dir='$(DESTDIR)$(pyglibdir)'; \ - filesc=`echo "$$files" | sed 's|$$|c|'`; \ - fileso=`echo "$$files" | sed 's|$$|o|'`; \ - st=0; \ - for files in "$$files" "$$filesc" "$$fileso"; do \ - $(am__uninstall_files_from_dir) || st=$$?; \ - done; \ - exit $$st - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local -check: check-am -all-am: Makefile $(LTLIBRARIES) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyglibdir)" "$(DESTDIR)$(pyglibdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ - clean-pyglibLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-pyglibLTLIBRARIES install-pyglibPYTHON - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libLTLIBRARIES uninstall-pyglibLTLIBRARIES \ - uninstall-pyglibPYTHON - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ - clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ - clean-pyglibLTLIBRARIES ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-pyglibLTLIBRARIES install-pyglibPYTHON \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-libLTLIBRARIES uninstall-pyglibLTLIBRARIES \ - uninstall-pyglibPYTHON - - -# if we build in a separate tree, we need to symlink the *.py files from the -# source tree; Python does not accept the extensions and modules in different -# paths -build_pylinks: - for f in $(pyglib_PYTHON); do \ - [ -e $(builddir)/$$f ] || $(LN_S) $(srcdir)/$$f $(builddir)/$$f; \ - done - -all: $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -check-local: $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -clean-local: - rm -f $(pyglib_LTLIBRARIES:.la=$(PYTHON_SO)) -%$(PYTHON_SO): %.la - $(LN_S) -f .libs/$@ $@ - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/gi/_glib/__init__.py b/gi/_glib/__init__.py deleted file mode 100644 index 0b9df9a..0000000 --- a/gi/_glib/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- Mode: Python; py-indent-offset: 4 -*- -# pygobject - Python bindings for the GObject library -# Copyright (C) 2006-2012 Johan Dahlin -# -# glib/__init__.py: initialisation file for glib module -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -from . import _glib - -# Internal API -_PyGLib_API = _glib._PyGLib_API diff --git a/gi/_glib/glibmodule.c b/gi/_glib/glibmodule.c deleted file mode 100644 index d08d4fb..0000000 --- a/gi/_glib/glibmodule.c +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * glibmodule.c: wrapper for the glib library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include "pyglib.h" -#include "pyglib-private.h" -#include "pygoptioncontext.h" -#include "pygoptiongroup.h" -#include "pygspawn.h" - -/* ---------------- glib module functions -------------------- */ - -static PyMethodDef _glib_functions[] = { - { "spawn_async", - (PyCFunction)pyglib_spawn_async, METH_VARARGS|METH_KEYWORDS, - "spawn_async(argv, envp=None, working_directory=None,\n" - " flags=0, child_setup=None, user_data=None,\n" - " standard_input=None, standard_output=None,\n" - " standard_error=None) -> (pid, stdin, stdout, stderr)\n" - "Execute a child program asynchronously within a glib.MainLoop()\n" - "See the reference manual for a complete reference." }, - { NULL, NULL, 0 } -}; - -/* ----------------- glib module initialisation -------------- */ - -static struct _PyGLib_Functions pyglib_api = { - FALSE, /* threads_enabled */ - NULL, /* gerror_exception */ - NULL, /* block_threads */ - NULL, /* unblock_threads */ - NULL, /* pyg_main_context_new */ - pyg_option_context_new, - pyg_option_group_new, -}; - -static void -pyglib_register_api(PyObject *d) -{ - PyObject *o; - - /* for addon libraries ... */ - PyDict_SetItemString(d, "_PyGLib_API", - o=PYGLIB_CPointer_WrapPointer(&pyglib_api,"gi._glib._PyGLib_API")); - Py_DECREF(o); - - pyglib_init_internal(o); -} - -static void -pyglib_register_error(PyObject *d) -{ - PyObject *dict; - PyObject *gerror_class; - dict = PyDict_New(); - /* This is a hack to work around the deprecation warning of - * BaseException.message in Python 2.6+. - * GError has also an "message" attribute. - */ - PyDict_SetItemString(dict, "message", Py_None); - gerror_class = PyErr_NewException("gi._glib.GError", PyExc_RuntimeError, dict); - Py_DECREF(dict); - - PyDict_SetItemString(d, "GError", gerror_class); - pyglib_api.gerror_exception = gerror_class; -} - -PYGLIB_MODULE_START(_glib, "_glib") -{ - PyObject *d = PyModule_GetDict(module); - - pyglib_register_api(d); - pyglib_register_error(d); - pyglib_spawn_register_types(d); - pyglib_option_context_register_types(d); - pyglib_option_group_register_types(d); -} -PYGLIB_MODULE_END diff --git a/gi/_glib/option.py b/gi/_glib/option.py deleted file mode 100644 index 54e802f..0000000 --- a/gi/_glib/option.py +++ /dev/null @@ -1,363 +0,0 @@ -# -*- Mode: Python -*- -# pygobject - Python bindings for the GObject library -# Copyright (C) 2006 Johannes Hoelzl -# -# glib/option.py: GOption command line parser -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -"""GOption command line parser - -Extends optparse to use the GOptionGroup, GOptionEntry and GOptionContext -objects. So it is possible to use the gtk, gnome_program and gstreamer command -line groups and contexts. - -Use this interface instead of the raw wrappers of GOptionContext and -GOptionGroup in glib. -""" - -import sys -import optparse -from optparse import OptParseError, OptionError, OptionValueError, \ - BadOptionError, OptionConflictError -from ..module import get_introspection_module - -if sys.version_info >= (3, 0): - _basestring = str - _bytes = lambda s: s.encode() -else: - _basestring = basestring - _bytes = str - -from gi._glib import _glib -GLib = get_introspection_module('GLib') - -OPTION_CONTEXT_ERROR_QUARK = GLib.quark_to_string(GLib.option_error_quark()) - -__all__ = [ - "OptParseError", - "OptionError", - "OptionValueError", - "BadOptionError", - "OptionConflictError", - "Option", - "OptionGroup", - "OptionParser", - "make_option", -] - - -class Option(optparse.Option): - """Represents a command line option - - To use the extended possibilities of the GOption API Option - (and make_option) are extended with new types and attributes. - - Types: - filename The supplied arguments are read as filename, GOption - parses this type in with the GLib filename encoding. - - Attributes: - optional_arg This does not need a arguement, but it can be supplied. - hidden The help list does not show this option - in_main This option apears in the main group, this should only - be used for backwards compatibility. - - Use Option.REMAINING as option name to get all positional arguments. - - NOTE: Every argument to an option is passed as utf-8 coded string, the only - exception are options which use the 'filename' type, its arguments - are passed as strings in the GLib filename encoding. - - For further help, see optparse.Option. - """ - TYPES = optparse.Option.TYPES + ( - 'filename', - ) - - ATTRS = optparse.Option.ATTRS + [ - 'hidden', - 'in_main', - 'optional_arg', - ] - - REMAINING = '--' + GLib.OPTION_REMAINING - - def __init__(self, *args, **kwargs): - optparse.Option.__init__(self, *args, **kwargs) - if not self._long_opts: - raise ValueError("%s at least one long option name.") - - if len(self._long_opts) < len(self._short_opts): - raise ValueError( - "%s at least more long option names than short option names.") - - if not self.help: - raise ValueError("%s needs a help message.", self._long_opts[0]) - - def _set_opt_string(self, opts): - if self.REMAINING in opts: - self._long_opts.append(self.REMAINING) - optparse.Option._set_opt_string(self, opts) - if len(self._short_opts) > len(self._long_opts): - raise OptionError("goption.Option needs more long option names " - "than short option names") - - def _to_goptionentries(self): - flags = 0 - - if self.hidden: - flags |= GLib.OptionFlags.HIDDEN - - if self.in_main: - flags |= GLib.OptionFlags.IN_MAIN - - if self.takes_value(): - if self.optional_arg: - flags |= GLib.OptionFlags.OPTIONAL_ARG - else: - flags |= GLib.OptionFlags.NO_ARG - - if self.type == 'filename': - flags |= GLib.OptionFlags.FILENAME - - for (long_name, short_name) in zip(self._long_opts, self._short_opts): - yield (long_name[2:], _bytes(short_name[1]), flags, self.help, self.metavar) - - for long_name in self._long_opts[len(self._short_opts):]: - yield (long_name[2:], _bytes('\0'), flags, self.help, self.metavar) - - -class OptionGroup(optparse.OptionGroup): - """A group of command line options. - - Arguements: - name: The groups name, used to create the - --help-{name} option - description: Shown as title of the groups help view - help_description: Shown as help to the --help-{name} option - option_list: The options used in this group, must be option.Option() - defaults: A dicitionary of default values - translation_domain: Sets the translation domain for gettext(). - - NOTE: This OptionGroup does not exactly map the optparse.OptionGroup - interface. There is no parser object to supply, but it is possible - to set default values and option_lists. Also the default values and - values are not shared with the OptionParser. - - To pass a OptionGroup into a function which expects a GOptionGroup (e.g. - gnome_program_init() ). OptionGroup.get_option_group() can be used. - - For further help, see optparse.OptionGroup. - """ - def __init__(self, name, description, help_description="", - option_list=None, defaults=None, - translation_domain=None): - optparse.OptionContainer.__init__(self, Option, 'error', description) - self.name = name - self.parser = None - self.help_description = help_description - if defaults: - self.defaults = defaults - - self.values = None - - self.translation_domain = translation_domain - - if option_list: - for option in option_list: - self.add_option(option) - - def _create_option_list(self): - self.option_list = [] - self._create_option_mappings() - - def _to_goptiongroup(self, parser): - def callback(option_name, option_value, group): - if option_name.startswith('--'): - opt = self._long_opt[option_name] - else: - opt = self._short_opt[option_name] - - try: - opt.process(option_name, option_value, self.values, parser) - except OptionValueError: - error = sys.exc_info()[1] - gerror = _glib.GError(str(error)) - gerror.domain = OPTION_CONTEXT_ERROR_QUARK - gerror.code = GLib.OptionError.BAD_VALUE - gerror.message = str(error) - raise gerror - - group = _glib.OptionGroup(self.name, self.description, - self.help_description, callback) - if self.translation_domain: - group.set_translation_domain(self.translation_domain) - - entries = [] - for option in self.option_list: - entries.extend(option._to_goptionentries()) - - group.add_entries(entries) - - return group - - def get_option_group(self, parser=None): - """ Returns the corresponding GOptionGroup object. - - Can be used as parameter for gnome_program_init(), gtk_init(). - """ - self.set_values_to_defaults() - return self._to_goptiongroup(parser) - - def set_values_to_defaults(self): - for option in self.option_list: - default = self.defaults.get(option.dest) - if isinstance(default, _basestring): - opt_str = option.get_opt_string() - self.defaults[option.dest] = option.check_value( - opt_str, default) - self.values = optparse.Values(self.defaults) - - -class OptionParser(optparse.OptionParser): - """Command line parser with GOption support. - - NOTE: The OptionParser interface is not the exactly the same as the - optparse.OptionParser interface. Especially the usage parameter - is only used to show the metavar of the arguements. - - Attribues: - help_enabled: The --help, --help-all and --help-{group} - options are enabled (default). - ignore_unknown_options: Do not throw a exception when a option is not - knwon, the option will be in the result list. - - OptionParser.add_option_group() does not only accept OptionGroup instances - but also glib.OptionGroup, which is returned by gtk_get_option_group(). - - Only glib.option.OptionGroup and glib.option.Option instances should - be passed as groups and options. - - For further help, see optparse.OptionParser. - """ - - def __init__(self, *args, **kwargs): - if 'option_class' not in kwargs: - kwargs['option_class'] = Option - self.help_enabled = kwargs.pop('help_enabled', True) - self.ignore_unknown_options = kwargs.pop('ignore_unknown_options', - False) - optparse.OptionParser.__init__(self, add_help_option=False, - *args, **kwargs) - - def set_usage(self, usage): - if usage is None: - self.usage = '' - elif usage.startswith("%prog"): - self.usage = usage[len("%prog"):] - else: - self.usage = usage - - def _to_goptioncontext(self, values): - if self.description: - parameter_string = self.usage + " - " + self.description - else: - parameter_string = self.usage - context = _glib.OptionContext(parameter_string) - context.set_help_enabled(self.help_enabled) - context.set_ignore_unknown_options(self.ignore_unknown_options) - - for option_group in self.option_groups: - if isinstance(option_group, _glib.OptionGroup): - g_group = option_group - else: - g_group = option_group.get_option_group(self) - context.add_group(g_group) - - def callback(option_name, option_value, group): - if option_name.startswith('--'): - opt = self._long_opt[option_name] - else: - opt = self._short_opt[option_name] - opt.process(option_name, option_value, values, self) - - main_group = _glib.OptionGroup(None, None, None, callback) - main_entries = [] - for option in self.option_list: - main_entries.extend(option._to_goptionentries()) - main_group.add_entries(main_entries) - context.set_main_group(main_group) - - return context - - def add_option_group(self, *args, **kwargs): - if isinstance(args[0], _basestring): - optparse.OptionParser.add_option_group(self, - OptionGroup(self, *args, **kwargs)) - return - elif len(args) == 1 and not kwargs: - if isinstance(args[0], OptionGroup): - if not args[0].parser: - args[0].parser = self - if args[0].parser is not self: - raise ValueError("invalid OptionGroup (wrong parser)") - if isinstance(args[0], _glib.OptionGroup): - self.option_groups.append(args[0]) - return - optparse.OptionParser.add_option_group(self, *args, **kwargs) - - def _get_all_options(self): - options = self.option_list[:] - for group in self.option_groups: - if isinstance(group, optparse.OptionGroup): - options.extend(group.option_list) - return options - - def _process_args(self, largs, rargs, values): - context = self._to_goptioncontext(values) - - # _process_args() returns the remaining parameters in rargs. - # The prepended program name is used to all g_set_prgname() - # The program name is cut away so it doesn't appear in the result. - rargs[:] = context.parse([sys.argv[0]] + rargs)[1:] - - def parse_args(self, args=None, values=None): - old_args = args or [] - try: - options, args = optparse.OptionParser.parse_args( - self, args, values) - except _glib.GError: - error = sys.exc_info()[1] - if error.domain != OPTION_CONTEXT_ERROR_QUARK: - raise - if error.code == GLib.OptionError.BAD_VALUE: - raise OptionValueError(error.message) - elif error.code == GLib.OptionError.UNKNOWN_OPTION: - raise BadOptionError(error.message) - elif error.code == GLib.OptionError.FAILED: - raise OptParseError(error.message) - else: - raise - - for group in self.option_groups: - for key, value in group.values.__dict__.items(): - options.ensure_value(key, value) - - args = args[2:-len(old_args)] - return options, args - -make_option = Option diff --git a/gi/_glib/pyglib-private.h b/gi/_glib/pyglib-private.h deleted file mode 100644 index 183184f..0000000 --- a/gi/_glib/pyglib-private.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGLIB_PRIVATE_H__ -#define __PYGLIB_PRIVATE_H__ - -#include -#include - -#include - -G_BEGIN_DECLS - -struct _PyGLib_Functions { - gboolean threads_enabled; - PyObject *gerror_exception; - PyGLibThreadBlockFunc block_threads; - PyGLibThreadBlockFunc unblock_threads; - PyObject* (*main_context_new)(GMainContext *context); - PyObject* (*option_context_new)(GOptionContext *context); - PyObject* (*option_group_new)(GOptionGroup *group); -}; - -gboolean _pyglib_handler_marshal(gpointer user_data); -void _pyglib_destroy_notify(gpointer user_data); - -G_END_DECLS - -#endif /* __PYGLIB_PRIVATE_H__ */ - - diff --git a/gi/_glib/pyglib-python-compat.h b/gi/_glib/pyglib-python-compat.h deleted file mode 100644 index 844bc55..0000000 --- a/gi/_glib/pyglib-python-compat.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGLIB_PYTHON_COMPAT_H__ -#define __PYGLIB_PYTHON_COMPAT_H__ - -# define PYGLIB_CPointer_Check PyCapsule_CheckExact -# define PYGLIB_CPointer_WrapPointer(ptr, typename) \ - PyCapsule_New(ptr, typename, NULL) -# define PYGLIB_CPointer_GetPointer(obj, typename) \ - PyCapsule_GetPointer(obj, typename) -# define PYGLIB_CPointer_Import(module, symbol) \ - PyCapsule_Import(##module##.##symbol##, FALSE) - -#if PY_VERSION_HEX < 0x03000000 - -#define PYGLIB_INIT_FUNCTION(modname, fullpkgname, functions) \ -static int _pyglib_init_##modname(PyObject *module); \ -void init##modname(void) \ -{ \ - PyObject *module = Py_InitModule(fullpkgname, functions); \ - _pyglib_init_##modname(module); \ -} \ -static int _pyglib_init_##modname(PyObject *module) - -#else - -#define PYGLIB_INIT_FUNCTION(modname, fullpkgname, functions) \ -static struct PyModuleDef _##modname##module = { \ - PyModuleDef_HEAD_INIT, \ - fullpkgname, \ - NULL, \ - -1, \ - functions, \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -static int _pyglib_init_##modname(PyObject *module); \ -PyObject *PyInit_##modname(void) \ -{ \ - PyObject *module = PyModule_Create(&_##modname##module); \ - if (module == NULL) \ - return NULL; \ - if (_pyglib_init_##modname(module) != 0 ) {\ - Py_DECREF(module); \ - return NULL; \ - } \ - return module; \ -} \ -static int _pyglib_init_##modname(PyObject *module) - -#endif - -/* Compilation on Python 2.x */ -#if PY_VERSION_HEX < 0x03000000 -#define PYGLIB_MODULE_ERROR_RETURN - -#define RO READONLY - -#define PYGLIB_PyBaseString_Check(ob) (PyString_Check(ob) || PyUnicode_Check(ob)) - -#define PYGLIB_PyUnicode_Check PyString_Check -#define PYGLIB_PyUnicode_AsString PyString_AsString -#define PYGLIB_PyUnicode_AsStringAndSize PyString_AsStringAndSize -#define PYGLIB_PyUnicode_FromString PyString_FromString -#define PYGLIB_PyUnicode_FromStringAndSize PyString_FromStringAndSize -#define PYGLIB_PyUnicode_FromFormat PyString_FromFormat -#define PYGLIB_PyUnicode_AS_STRING PyString_AS_STRING -#define PYGLIB_PyUnicode_GET_SIZE PyString_GET_SIZE -#define PYGLIB_PyUnicode_Type PyString_Type -#define PYGLIB_PyUnicode_InternFromString PyString_InternFromString -#define PYGLIB_PyUnicode_InternInPlace PyString_InternInPlace - -#define PYGLIB_PyBytes_FromString PyString_FromString -#define PYGLIB_PyBytes_FromStringAndSize PyString_FromStringAndSize -#define PYGLIB_PyBytes_Resize _PyString_Resize -#define PYGLIB_PyBytes_AsString PyString_AsString -#define PYGLIB_PyBytes_Size PyString_Size -#define PYGLIB_PyBytes_Check PyString_Check - -#define PYGLIB_PyLong_Check PyInt_Check -#define PYGLIB_PyLong_FromLong PyInt_FromLong -#define PYGLIB_PyLong_FromSsize_t PyInt_FromSsize_t -#define PYGLIB_PyLong_FromSize_t PyInt_FromSize_t -#define PYGLIB_PyLong_AsLong PyInt_AsLong -#define PYGLIB_PyLongObject PyIntObject -#define PYGLIB_PyLong_Type PyInt_Type -#define PYGLIB_PyLong_AS_LONG PyInt_AS_LONG -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) - -/* Python 2.7 lacks a PyInt_FromUnsignedLong function; use signed longs, and - * rely on PyInt_AsUnsignedLong() to interpret them correctly */ -#define PYGLIB_PyLong_FromUnsignedLong PyInt_FromLong -#define PYGLIB_PyLong_AsUnsignedLong(o) PyInt_AsUnsignedLongMask((PyObject*)(o)) - -#define PYGLIB_PyNumber_Long PyNumber_Int - -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(base, size) \ - PyObject_HEAD_INIT(base) \ - size, -#endif - -#define PYGLIB_MODULE_START(symbol, modname) \ -DL_EXPORT(void) init##symbol(void); \ -DL_EXPORT(void) init##symbol(void) \ -{ \ - PyObject *module; \ - module = Py_InitModule(modname, symbol##_functions); -#define PYGLIB_MODULE_END } -#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \ -PyTypeObject symbol = { \ - PyObject_HEAD_INIT(NULL) \ - 0, \ - typename, \ - sizeof(csymbol), \ - 0, \ -}; -#define PYGLIB_REGISTER_TYPE(d, type, name) \ - if (!type.tp_alloc) \ - type.tp_alloc = PyType_GenericAlloc; \ - if (!type.tp_new) \ - type.tp_new = PyType_GenericNew; \ - if (PyType_Ready(&type)) \ - return; \ - PyDict_SetItemString(d, name, (PyObject *)&type); - -#else - -#define PYGLIB_MODULE_ERROR_RETURN 0 - -#define PYGLIB_MODULE_START(symbol, modname) \ - static struct PyModuleDef _##symbol##module = { \ - PyModuleDef_HEAD_INIT, \ - modname, \ - NULL, \ - -1, \ - symbol##_functions, \ - NULL, \ - NULL, \ - NULL, \ - NULL \ -}; \ -PyMODINIT_FUNC PyInit_##symbol(void); \ -PyMODINIT_FUNC PyInit_##symbol(void) \ -{ \ - PyObject *module; \ - module = PyModule_Create(&_##symbol##module); -#define PYGLIB_MODULE_END return module; } -#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \ -PyTypeObject symbol = { \ - PyVarObject_HEAD_INIT(NULL, 0) \ - typename, \ - sizeof(csymbol) \ -}; -#define PYGLIB_REGISTER_TYPE(d, type, name) \ - if (!type.tp_alloc) \ - type.tp_alloc = PyType_GenericAlloc; \ - if (!type.tp_new) \ - type.tp_new = PyType_GenericNew; \ - if (PyType_Ready(&type)) \ - return; \ - PyDict_SetItemString(d, name, (PyObject *)&type); - -#define PYGLIB_PyBaseString_Check PyUnicode_Check - -#define PYGLIB_PyUnicode_Check PyUnicode_Check -#define PYGLIB_PyUnicode_AsString _PyUnicode_AsString -#define PYGLIB_PyUnicode_AsStringAndSize(obj, buf, size) \ - (((*(buf) = _PyUnicode_AsStringAndSize(obj, size)) != NULL) ? 0 : -1) -#define PYGLIB_PyUnicode_FromString PyUnicode_FromString -#define PYGLIB_PyUnicode_FromStringAndSize PyUnicode_FromStringAndSize -#define PYGLIB_PyUnicode_FromFormat PyUnicode_FromFormat -#define PYGLIB_PyUnicode_GET_SIZE PyUnicode_GET_SIZE -#define PYGLIB_PyUnicode_Resize PyUnicode_Resize -#define PYGLIB_PyUnicode_Type PyUnicode_Type -#define PYGLIB_PyUnicode_InternFromString PyUnicode_InternFromString -#define PYGLIB_PyUnicode_InternInPlace PyUnicode_InternInPlace - -#define PYGLIB_PyLong_Check PyLong_Check -#define PYGLIB_PyLong_FromLong PyLong_FromLong -#define PYGLIB_PyLong_FromSize_t PyLong_FromSize_t -#define PYGLIB_PyLong_AsLong PyLong_AsLong -#define PYGLIB_PyLong_AS_LONG(o) PyLong_AS_LONG((PyObject*)(o)) -#define PYGLIB_PyLongObject PyLongObject -#define PYGLIB_PyLong_Type PyLong_Type - -#define PYGLIB_PyLong_FromUnsignedLong PyLong_FromUnsignedLong -#define PYGLIB_PyLong_AsUnsignedLong(o) PyLong_AsUnsignedLongMask((PyObject*)(o)) - -#define PYGLIB_PyBytes_FromString PyBytes_FromString -#define PYGLIB_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -#define PYGLIB_PyBytes_Resize(o, len) _PyBytes_Resize(o, len) -#define PYGLIB_PyBytes_AsString PyBytes_AsString -#define PYGLIB_PyBytes_Size PyBytes_Size -#define PYGLIB_PyBytes_Check PyBytes_Check - -#define PYGLIB_PyNumber_Long PyNumber_Long - -#endif - -#endif /* __PYGLIB_PYTHON_COMPAT_H__ */ diff --git a/gi/_glib/pyglib.c b/gi/_glib/pyglib.c deleted file mode 100644 index 9753a52..0000000 --- a/gi/_glib/pyglib.c +++ /dev/null @@ -1,475 +0,0 @@ -/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include "pyglib.h" -#include "pyglib-private.h" -#include "pygoptioncontext.h" -#include "pygoptiongroup.h" - -static struct _PyGLib_Functions *_PyGLib_API; -static PyObject *exception_table = NULL; - -void -pyglib_init(void) -{ - PyObject *glib, *cobject; - - glib = PyImport_ImportModule("gi._glib"); - if (!glib) { - if (PyErr_Occurred()) { - PyObject *type, *value, *traceback; - PyObject *py_orig_exc; - PyErr_Fetch(&type, &value, &traceback); - py_orig_exc = PyObject_Repr(value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - PyErr_Format(PyExc_ImportError, - "could not import gi._glib (error was: %s)", - PYGLIB_PyUnicode_AsString(py_orig_exc)); - Py_DECREF(py_orig_exc); - } else { - PyErr_SetString(PyExc_ImportError, - "could not import gi._glib (no error given)"); - } - return; - } - - cobject = PyObject_GetAttrString(glib, "_PyGLib_API"); - if (cobject && PYGLIB_CPointer_Check(cobject)) - _PyGLib_API = (struct _PyGLib_Functions *) PYGLIB_CPointer_GetPointer(cobject, "gi._glib._PyGLib_API"); - else { - PyErr_SetString(PyExc_ImportError, - "could not import gi._glib (could not find _PyGLib_API object)"); - Py_DECREF(glib); - return; - } -} - -void -pyglib_init_internal(PyObject *api) -{ - _PyGLib_API = (struct _PyGLib_Functions *) PYGLIB_CPointer_GetPointer(api, "gi._glib._PyGLib_API"); -} - -/** - * pyglib_error_marshal: - * @error: a pointer to the GError. - * - * Checks to see if @error has been set. If @error has been set, then a - * GLib.GError Python exception object is returned (but not raised). - * - * Returns: a GLib.GError Python exception object, or NULL. - */ -PyObject * -pyglib_error_marshal (GError **error) -{ - PyGILState_STATE state; - PyObject *exc_type; - PyObject *exc_instance; - PyObject *d; - - g_return_val_if_fail(error != NULL, NULL); - - if (*error == NULL) - return NULL; - - state = pyglib_gil_state_ensure(); - - exc_type = _PyGLib_API->gerror_exception; - if (exception_table != NULL) - { - PyObject *item; - item = PyDict_GetItem(exception_table, PYGLIB_PyLong_FromLong((*error)->domain)); - if (item != NULL) - exc_type = item; - } - - exc_instance = PyObject_CallFunction(exc_type, "z", (*error)->message); - - if ((*error)->domain) { - PyObject_SetAttrString(exc_instance, "domain", - d=PYGLIB_PyUnicode_FromString(g_quark_to_string((*error)->domain))); - Py_DECREF(d); - } - else - PyObject_SetAttrString(exc_instance, "domain", Py_None); - - PyObject_SetAttrString(exc_instance, "code", - d=PYGLIB_PyLong_FromLong((*error)->code)); - Py_DECREF(d); - - if ((*error)->message) { - PyObject_SetAttrString(exc_instance, "message", - d=PYGLIB_PyUnicode_FromString((*error)->message)); - Py_DECREF(d); - } else { - PyObject_SetAttrString(exc_instance, "message", Py_None); - } - - pyglib_gil_state_release(state); - - return exc_instance; -} - -/** - * pyglib_error_check: - * @error: a pointer to the GError. - * - * Checks to see if the GError has been set. If the error has been - * set, then the glib.GError Python exception will be raised, and - * the GError cleared. - * - * Returns: True if an error was set. - */ -gboolean -pyglib_error_check(GError **error) -{ - PyGILState_STATE state; - PyObject *exc_instance; - - g_return_val_if_fail(error != NULL, FALSE); - if (*error == NULL) - return FALSE; - - state = pyglib_gil_state_ensure(); - - exc_instance = pyglib_error_marshal (error); - PyErr_SetObject(_PyGLib_API->gerror_exception, exc_instance); - Py_DECREF(exc_instance); - g_clear_error(error); - - pyglib_gil_state_release(state); - - return TRUE; -} - -/** - * pyglib_gerror_exception_check: - * @error: a standard GLib GError ** output parameter - * - * Checks to see if a GError exception has been raised, and if so - * translates the python exception to a standard GLib GError. If the - * raised exception is not a GError then PyErr_Print() is called. - * - * Returns: 0 if no exception has been raised, -1 if it is a - * valid glib.GError, -2 otherwise. - */ -gboolean -pyglib_gerror_exception_check(GError **error) -{ - PyObject *type, *value, *traceback; - PyObject *py_message, *py_domain, *py_code; - const char *bad_gerror_message; - - PyErr_Fetch(&type, &value, &traceback); - if (type == NULL) - return 0; - PyErr_NormalizeException(&type, &value, &traceback); - if (value == NULL) { - PyErr_Restore(type, value, traceback); - PyErr_Print(); - return -2; - } - if (!value || - !PyErr_GivenExceptionMatches(type, - (PyObject *) _PyGLib_API->gerror_exception)) { - PyErr_Restore(type, value, traceback); - PyErr_Print(); - return -2; - } - Py_DECREF(type); - Py_XDECREF(traceback); - - py_message = PyObject_GetAttrString(value, "message"); - if (!py_message || !PYGLIB_PyUnicode_Check(py_message)) { - bad_gerror_message = "gi._glib.GError instances must have a 'message' string attribute"; - Py_XDECREF(py_message); - goto bad_gerror; - } - - py_domain = PyObject_GetAttrString(value, "domain"); - if (!py_domain || !PYGLIB_PyUnicode_Check(py_domain)) { - bad_gerror_message = "gi._glib.GError instances must have a 'domain' string attribute"; - Py_DECREF(py_message); - Py_XDECREF(py_domain); - goto bad_gerror; - } - - py_code = PyObject_GetAttrString(value, "code"); - if (!py_code || !PYGLIB_PyLong_Check(py_code)) { - bad_gerror_message = "gi._glib.GError instances must have a 'code' int attribute"; - Py_DECREF(py_message); - Py_DECREF(py_domain); - Py_XDECREF(py_code); - goto bad_gerror; - } - - g_set_error(error, g_quark_from_string(PYGLIB_PyUnicode_AsString(py_domain)), - PYGLIB_PyLong_AsLong(py_code), "%s", PYGLIB_PyUnicode_AsString(py_message)); - - Py_DECREF(py_message); - Py_DECREF(py_code); - Py_DECREF(py_domain); - return -1; - -bad_gerror: - Py_DECREF(value); - g_set_error(error, g_quark_from_static_string("pyglib"), 0, "%s", bad_gerror_message); - PyErr_SetString(PyExc_ValueError, bad_gerror_message); - PyErr_Print(); - return -2; -} - -/** - * pyglib_register_exception_for_domain: - * @name: name of the exception - * @error_domain: error domain - * - * Registers a new glib.GError exception subclass called #name for - * a specific #domain. This exception will be raised when a GError - * of the same domain is passed in to pyglib_error_check(). - * - * Returns: the new exception - */ -PyObject * -pyglib_register_exception_for_domain(gchar *name, - gint error_domain) -{ - PyObject *exception; - - exception = PyErr_NewException(name, _PyGLib_API->gerror_exception, NULL); - - if (exception_table == NULL) - exception_table = PyDict_New(); - - PyDict_SetItem(exception_table, - PYGLIB_PyLong_FromLong(error_domain), - exception); - - return exception; -} - -/** - * pyg_option_group_transfer_group: - * @group: a GOptionGroup wrapper - * - * This is used to transfer the GOptionGroup to a GOptionContext. After this - * is called, the calle must handle the release of the GOptionGroup. - * - * When #NULL is returned, the GOptionGroup was already transfered. - * - * Returns: Either #NULL or the wrapped GOptionGroup. - */ -GOptionGroup * -pyglib_option_group_transfer_group(PyObject *obj) -{ - PyGOptionGroup *self = (PyGOptionGroup*)obj; - - if (self->is_in_context) - return NULL; - - self->is_in_context = TRUE; - - /* Here we increase the reference count of the PyGOptionGroup, because now - * the GOptionContext holds an reference to us (it is the userdata passed - * to g_option_group_new(). - * - * The GOptionGroup is freed with the GOptionContext. - * - * We set it here because if we would do this in the init method we would - * hold two references and the PyGOptionGroup would never be freed. - */ - Py_INCREF(self); - - return self->group; -} - -/** - * pyglib_option_group_new: - * @group: a GOptionGroup - * - * The returned GOptionGroup can't be used to set any hooks, translation domains - * or add entries. It's only intend is, to use for GOptionContext.add_group(). - * - * Returns: the GOptionGroup wrapper. - */ -PyObject * -pyglib_option_group_new (GOptionGroup *group) -{ - return _PyGLib_API->option_group_new(group); -} - -/** - * pyglib_option_context_new: - * @context: a GOptionContext - * - * Returns: A new GOptionContext wrapper. - */ -PyObject * -pyglib_option_context_new (GOptionContext *context) -{ - return _PyGLib_API->option_context_new(context); -} - - -/****** Private *****/ - -/** - * _pyglib_destroy_notify: - * @user_data: a PyObject pointer. - * - * A function that can be used as a GDestroyNotify callback that will - * call Py_DECREF on the data. - */ -void -_pyglib_destroy_notify(gpointer user_data) -{ - PyObject *obj = (PyObject *)user_data; - PyGILState_STATE state; - - g_return_if_fail (_PyGLib_API != NULL); - - state = pyglib_gil_state_ensure(); - Py_DECREF(obj); - pyglib_gil_state_release(state); -} - -gboolean -_pyglib_handler_marshal(gpointer user_data) -{ - PyObject *tuple, *ret; - gboolean res; - PyGILState_STATE state; - - g_return_val_if_fail(user_data != NULL, FALSE); - - state = pyglib_gil_state_ensure(); - - tuple = (PyObject *)user_data; - ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), - PyTuple_GetItem(tuple, 1)); - if (!ret) { - PyErr_Print(); - res = FALSE; - } else { - res = PyObject_IsTrue(ret); - Py_DECREF(ret); - } - - pyglib_gil_state_release(state); - - return res; -} - -PyObject* -_pyglib_generic_ptr_richcompare(void* a, void *b, int op) -{ - PyObject *res; - - switch (op) { - - case Py_EQ: - res = (a == b) ? Py_True : Py_False; - break; - - case Py_NE: - res = (a != b) ? Py_True : Py_False; - break; - - case Py_LT: - res = (a < b) ? Py_True : Py_False; - break; - - case Py_LE: - res = (a <= b) ? Py_True : Py_False; - break; - - case Py_GT: - res = (a > b) ? Py_True : Py_False; - break; - - case Py_GE: - res = (a >= b) ? Py_True : Py_False; - break; - - default: - res = Py_NotImplemented; - break; - } - - Py_INCREF(res); - return res; -} - -PyObject* -_pyglib_generic_long_richcompare(long a, long b, int op) -{ - PyObject *res; - - switch (op) { - - case Py_EQ: - res = (a == b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - case Py_NE: - res = (a != b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - - case Py_LT: - res = (a < b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - case Py_LE: - res = (a <= b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - case Py_GT: - res = (a > b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - case Py_GE: - res = (a >= b) ? Py_True : Py_False; - Py_INCREF(res); - break; - - default: - res = Py_NotImplemented; - Py_INCREF(res); - break; - } - - return res; -} - diff --git a/gi/_glib/pyglib.h b/gi/_glib/pyglib.h deleted file mode 100644 index 1c62f1d..0000000 --- a/gi/_glib/pyglib.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGLIB_H__ -#define __PYGLIB_H__ - -#include - -#include - -G_BEGIN_DECLS - -typedef void (*PyGLibThreadsEnabledFunc) (void); -typedef void (*PyGLibThreadBlockFunc) (void); - -void pyglib_init(void); -void pyglib_init_internal(PyObject *api); - -#ifdef DISABLE_THREADING -# define pyglib_gil_state_ensure() PyGILState_LOCKED -# define pyglib_gil_state_release(state) state -#else -# define pyglib_gil_state_ensure PyGILState_Ensure -# define pyglib_gil_state_release PyGILState_Release -#endif - -/* Deprecated, only available for API compatibility. */ -#define pyg_set_thread_block_funcs(a, b) -#define pyglib_block_threads() -#define pyglib_unblock_threads() - -gboolean pyglib_error_check(GError **error); -PyObject *pyglib_error_marshal (GError **error); -gboolean pyglib_gerror_exception_check(GError **error); -PyObject *pyglib_register_exception_for_domain(gchar *name, - gint error_domain); -PyObject * pyglib_option_context_new(GOptionContext *context); -PyObject * pyglib_option_group_new(GOptionGroup *group); -GOptionGroup * pyglib_option_group_transfer_group(PyObject *self); - -/* Private: for gobject <-> glib interaction only. */ -PyObject* _pyglib_generic_ptr_richcompare(void* a, void *b, int op); -PyObject* _pyglib_generic_long_richcompare(long a, long b, int op); - - -#define PYGLIB_REGISTER_TYPE(d, type, name) \ - if (!type.tp_alloc) \ - type.tp_alloc = PyType_GenericAlloc; \ - if (!type.tp_new) \ - type.tp_new = PyType_GenericNew; \ - if (PyType_Ready(&type)) \ - return; \ - PyDict_SetItemString(d, name, (PyObject *)&type); - - -G_END_DECLS - -#endif /* __PYGLIB_H__ */ - diff --git a/gi/_glib/pygoptioncontext.c b/gi/_glib/pygoptioncontext.c deleted file mode 100644 index 8ecbff8..0000000 --- a/gi/_glib/pygoptioncontext.c +++ /dev/null @@ -1,337 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 2006 Johannes Hoelzl - * - * pygoptioncontext.c: GOptionContext wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pyglib-private.h" -#include "pygoptioncontext.h" - -PYGLIB_DEFINE_TYPE("gi._glib.OptionContext", PyGOptionContext_Type, PyGOptionContext) - -/** - * pyg_option_context_new: - * @context: a GOptionContext - * - * Returns: A new GOptionContext wrapper. - */ -PyObject * -pyg_option_context_new (GOptionContext *context) -{ - PyGOptionContext *self; - - self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext, &PyGOptionContext_Type); - if (self == NULL) - return NULL; - - self->context = context; - self->main_group = NULL; - - return (PyObject *)self; -} - -static int -pyg_option_context_init(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - char *parameter_string; - - if (!PyArg_ParseTuple(args, "s:gi._glib.GOptionContext.__init__", - ¶meter_string)) - return -1; - - self->context = g_option_context_new(parameter_string); - return 0; -} - -static void -pyg_option_context_dealloc(PyGOptionContext *self) -{ - Py_CLEAR(self->main_group); - - if (self->context != NULL) - { - GOptionContext *tmp = self->context; - self->context = NULL; - g_option_context_free(tmp); - } - - PyObject_Del(self); -} - -static PyObject * -pyg_option_context_parse(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "argv", NULL }; - PyObject *arg; - PyObject *new_argv, *argv; - Py_ssize_t argv_length, pos; - gint argv_length_int; - char **argv_content, **original; - GError *error = NULL; - gboolean result; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.parse", - kwlist, &argv)) - return NULL; - - if (!PyList_Check(argv)) - { - PyErr_SetString(PyExc_TypeError, - "GOptionContext.parse expects a list of strings."); - return NULL; - } - - argv_length = PyList_Size(argv); - if (argv_length == -1) - { - PyErr_SetString(PyExc_TypeError, - "GOptionContext.parse expects a list of strings."); - return NULL; - } - - argv_content = g_new(char*, argv_length + 1); - argv_content[argv_length] = NULL; - for (pos = 0; pos < argv_length; pos++) - { - arg = PyList_GetItem(argv, pos); - argv_content[pos] = g_strdup(PYGLIB_PyUnicode_AsString(arg)); - if (argv_content[pos] == NULL) - { - g_strfreev(argv_content); - return NULL; - } - } - original = g_strdupv(argv_content); - - g_assert(argv_length <= G_MAXINT); - argv_length_int = argv_length; - Py_BEGIN_ALLOW_THREADS; - result = g_option_context_parse(self->context, &argv_length_int, &argv_content, - &error); - Py_END_ALLOW_THREADS; - argv_length = argv_length_int; - - if (!result) - { - g_strfreev(argv_content); - g_strfreev(original); - pyglib_error_check(&error); - return NULL; - } - - new_argv = PyList_New(g_strv_length(argv_content)); - for (pos = 0; pos < argv_length; pos++) - { - arg = PYGLIB_PyUnicode_FromString(argv_content[pos]); - PyList_SetItem(new_argv, pos, arg); - } - - g_strfreev(original); - g_strfreev(argv_content); - return new_argv; -} - -static PyObject * -pyg_option_context_set_help_enabled(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "help_enable", NULL }; - - PyObject *help_enabled; - if (! PyArg_ParseTupleAndKeywords(args, kwargs, - "O:GOptionContext.set_help_enabled", - kwlist, &help_enabled)) - return NULL; - - g_option_context_set_help_enabled(self->context, PyObject_IsTrue(help_enabled)); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg_option_context_get_help_enabled(PyGOptionContext *self) -{ - return PyBool_FromLong(g_option_context_get_help_enabled(self->context)); -} - -static PyObject * -pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "ignore_unknown_options", NULL }; - PyObject *ignore_unknown_options; - - if (! PyArg_ParseTupleAndKeywords(args, kwargs, - "O:GOptionContext.set_ignore_unknown_options", - kwlist, &ignore_unknown_options)) - return NULL; - - g_option_context_set_ignore_unknown_options(self->context, - PyObject_IsTrue(ignore_unknown_options)); - - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self) -{ - return PyBool_FromLong( - g_option_context_get_ignore_unknown_options(self->context)); -} - -static PyObject * -pyg_option_context_set_main_group(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "group", NULL }; - GOptionGroup *g_group; - PyObject *group; - - if (! PyArg_ParseTupleAndKeywords(args, kwargs, - "O:GOptionContext.set_main_group", - kwlist, &group)) - return NULL; - - if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { - PyErr_SetString(PyExc_TypeError, - "GOptionContext.set_main_group expects a GOptionGroup."); - return NULL; - } - - g_group = pyglib_option_group_transfer_group(group); - if (g_group == NULL) - { - PyErr_SetString(PyExc_RuntimeError, - "Group is already in a OptionContext."); - return NULL; - } - - g_option_context_set_main_group(self->context, g_group); - - Py_INCREF(group); - self->main_group = (PyGOptionGroup*) group; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg_option_context_get_main_group(PyGOptionContext *self) -{ - if (self->main_group == NULL) - { - Py_INCREF(Py_None); - return Py_None; - } - Py_INCREF(self->main_group); - return (PyObject*) self->main_group; -} - -static PyObject * -pyg_option_context_add_group(PyGOptionContext *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "group", NULL }; - GOptionGroup *g_group; - PyObject *group; - - if (! PyArg_ParseTupleAndKeywords(args, kwargs, - "O:GOptionContext.add_group", - kwlist, &group)) - return NULL; - - if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { - PyErr_SetString(PyExc_TypeError, - "GOptionContext.add_group expects a GOptionGroup."); - return NULL; - } - - g_group = pyglib_option_group_transfer_group(group); - if (g_group == NULL) - { - PyErr_SetString(PyExc_RuntimeError, - "Group is already in a OptionContext."); - return NULL; - } - Py_INCREF(group); - - g_option_context_add_group(self->context, g_group); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -pyg_option_context_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGOptionContext_Type) - return _pyglib_generic_ptr_richcompare(((PyGOptionContext*)self)->context, - ((PyGOptionContext*)other)->context, - op); - else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - -static PyObject * -pyg_option_get_context(PyGOptionContext *self) -{ - return PYGLIB_CPointer_WrapPointer(self->context, "goption.context"); -} - -static PyMethodDef pyg_option_context_methods[] = { - { "parse", (PyCFunction)pyg_option_context_parse, METH_VARARGS | METH_KEYWORDS }, - { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_VARARGS | METH_KEYWORDS }, - { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS }, - { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_VARARGS | METH_KEYWORDS }, - { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS }, - { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_VARARGS | METH_KEYWORDS }, - { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS }, - { "add_group", (PyCFunction)pyg_option_context_add_group, METH_VARARGS | METH_KEYWORDS }, - { "_get_context", (PyCFunction)pyg_option_get_context, METH_NOARGS }, - { NULL, NULL, 0 }, -}; - -void -pyglib_option_context_register_types(PyObject *d) -{ - PyGOptionContext_Type.tp_dealloc = (destructor)pyg_option_context_dealloc; - PyGOptionContext_Type.tp_richcompare = pyg_option_context_richcompare; - PyGOptionContext_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGOptionContext_Type.tp_methods = pyg_option_context_methods; - PyGOptionContext_Type.tp_init = (initproc)pyg_option_context_init; - PYGLIB_REGISTER_TYPE(d, PyGOptionContext_Type, "OptionContext"); -} diff --git a/gi/_glib/pygoptioncontext.h b/gi/_glib/pygoptioncontext.h deleted file mode 100644 index efe5ffa..0000000 --- a/gi/_glib/pygoptioncontext.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYG_OPTIONCONTEXT_H__ -#define __PYG_OPTIONCONTEXT_H__ - -#include "pygoptiongroup.h" - -extern PyTypeObject PyGOptionContext_Type; - -typedef struct { - PyObject_HEAD - PyGOptionGroup *main_group; - GOptionContext *context; -} PyGOptionContext; - -PyObject* pyg_option_context_new(GOptionContext *context); - -void pyglib_option_context_register_types(PyObject *d); - -#endif /* __PYG_OPTIONCONTEXT_H__ */ diff --git a/gi/_glib/pygoptiongroup.c b/gi/_glib/pygoptiongroup.c deleted file mode 100644 index 2990342..0000000 --- a/gi/_glib/pygoptiongroup.c +++ /dev/null @@ -1,298 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygobject - Python bindings for the GLib, GObject and GIO - * Copyright (C) 2006 Johannes Hoelzl - * - * pygoptiongroup.c: GOptionContext and GOptionGroup wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pyglib-private.h" -#include "pygoptiongroup.h" - -PYGLIB_DEFINE_TYPE("gi._glib.OptionGroup", PyGOptionGroup_Type, PyGOptionGroup) - -/** - * pyg_option_group_new: - * @group: a GOptionGroup - * - * The returned GOptionGroup can't be used to set any hooks, translation domains - * or add entries. It's only intend is, to use for GOptionContext.add_group(). - * - * Returns: the GOptionGroup wrapper. - */ -PyObject * -pyg_option_group_new (GOptionGroup *group) -{ - PyGOptionGroup *self; - - self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup, - &PyGOptionGroup_Type); - if (self == NULL) - return NULL; - - self->group = group; - self->other_owner = TRUE; - self->is_in_context = FALSE; - - return (PyObject *)self; -} - -static gboolean -check_if_owned(PyGOptionGroup *self) -{ - if (self->other_owner) - { - PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by " - "gi._glib.OptionGroup(), so operation is not possible."); - return TRUE; - } - return FALSE; -} - -static void -destroy_g_group(PyGOptionGroup *self) -{ - PyGILState_STATE state; - state = pyglib_gil_state_ensure(); - - self->group = NULL; - Py_CLEAR(self->callback); - g_slist_foreach(self->strings, (GFunc) g_free, NULL); - g_slist_free(self->strings); - self->strings = NULL; - - if (self->is_in_context) - { - Py_DECREF(self); - } - - pyglib_gil_state_release(state); -} - -static int -pyg_option_group_init(PyGOptionGroup *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "name", "description", "help_description", - "callback", NULL }; - char *name, *description, *help_description; - PyObject *callback; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zzzO:GOptionGroup.__init__", - kwlist, &name, &description, - &help_description, &callback)) - return -1; - - self->group = g_option_group_new(name, description, help_description, - self, (GDestroyNotify) destroy_g_group); - self->other_owner = FALSE; - self->is_in_context = FALSE; - - Py_INCREF(callback); - self->callback = callback; - - return 0; -} - -static void -pyg_option_group_dealloc(PyGOptionGroup *self) -{ - if (!self->other_owner && !self->is_in_context) - { - GOptionGroup *tmp = self->group; - self->group = NULL; - if (tmp) - g_option_group_free(tmp); - } - - PyObject_Del(self); -} - -static gboolean -arg_func(const gchar *option_name, - const gchar *value, - PyGOptionGroup *self, - GError **error) -{ - PyObject *ret; - PyGILState_STATE state; - gboolean no_error; - - state = pyglib_gil_state_ensure(); - - if (value == NULL) - ret = PyObject_CallFunction(self->callback, "sOO", - option_name, Py_None, self); - else - ret = PyObject_CallFunction(self->callback, "ssO", - option_name, value, self); - - if (ret != NULL) - { - Py_DECREF(ret); - no_error = TRUE; - } else - no_error = pyglib_gerror_exception_check(error) != -1; - - pyglib_gil_state_release(state); - return no_error; -} - -static PyObject * -pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "entries", NULL }; - gssize entry_count, pos; - PyObject *entry_tuple, *list; - GOptionEntry *entries; - - if (check_if_owned(self)) - return NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionGroup.add_entries", - kwlist, &list)) - return NULL; - - if (!PyList_Check(list)) - { - PyErr_SetString(PyExc_TypeError, - "GOptionGroup.add_entries expected a list of entries"); - return NULL; - } - - entry_count = PyList_Size(list); - if (entry_count == -1) - { - PyErr_SetString(PyExc_TypeError, - "GOptionGroup.add_entries expected a list of entries"); - return NULL; - } - - entries = g_new0(GOptionEntry, entry_count + 1); - for (pos = 0; pos < entry_count; pos++) - { - gchar *long_name, *description, *arg_description; - entry_tuple = PyList_GetItem(list, pos); - if (!PyTuple_Check(entry_tuple)) - { - PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries " - "expected a list of entries"); - g_free(entries); - return NULL; - } - if (!PyArg_ParseTuple(entry_tuple, "scisz", - &long_name, - &(entries[pos].short_name), - &(entries[pos].flags), - &description, - &arg_description)) - { - PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries " - "expected a list of entries"); - g_free(entries); - return NULL; - } - long_name = g_strdup(long_name); - self->strings = g_slist_prepend(self->strings, long_name); - entries[pos].long_name = long_name; - - description = g_strdup(description); - self->strings = g_slist_prepend(self->strings, description); - entries[pos].description = description; - - arg_description = g_strdup(arg_description); - self->strings = g_slist_prepend(self->strings, arg_description); - entries[pos].arg_description = arg_description; - - entries[pos].arg = G_OPTION_ARG_CALLBACK; - entries[pos].arg_data = arg_func; - } - - g_option_group_add_entries(self->group, entries); - - g_free(entries); - - Py_INCREF(Py_None); - return Py_None; -} - - -static PyObject * -pyg_option_group_set_translation_domain(PyGOptionGroup *self, - PyObject *args, - PyObject *kwargs) -{ - static char *kwlist[] = { "domain", NULL }; - char *domain; - - if (check_if_owned(self)) - return NULL; - - if (self->group == NULL) - { - PyErr_SetString(PyExc_RuntimeError, - "The corresponding GOptionGroup was already freed, " - "probably through the release of GOptionContext"); - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "z:GOptionGroup.set_translate_domain", - kwlist, &domain)) - return NULL; - - g_option_group_set_translation_domain(self->group, domain); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -pyg_option_group_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other) && - Py_TYPE(self) == &PyGOptionGroup_Type) { - return _pyglib_generic_ptr_richcompare(((PyGOptionGroup*)self)->group, - ((PyGOptionGroup*)other)->group, - op); - } else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - -static PyMethodDef pyg_option_group_methods[] = { - { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_VARARGS | METH_KEYWORDS }, - { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS | METH_KEYWORDS }, - { NULL, NULL, 0 }, -}; - -void -pyglib_option_group_register_types(PyObject *d) -{ - PyGOptionGroup_Type.tp_dealloc = (destructor)pyg_option_group_dealloc; - PyGOptionGroup_Type.tp_richcompare = pyg_option_group_richcompare; - PyGOptionGroup_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGOptionGroup_Type.tp_methods = pyg_option_group_methods; - PyGOptionGroup_Type.tp_init = (initproc)pyg_option_group_init; - PYGLIB_REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup"); -} diff --git a/gi/_glib/pygoptiongroup.h b/gi/_glib/pygoptiongroup.h deleted file mode 100644 index 872b9c6..0000000 --- a/gi/_glib/pygoptiongroup.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYG_OPTIONGROUP_H__ -#define __PYG_OPTIONGROUP_H__ - -extern PyTypeObject PyGOptionGroup_Type; - -typedef struct { - PyObject_HEAD - GOptionGroup *group; - gboolean other_owner, is_in_context; - PyObject *callback; - GSList *strings; /* all strings added with the entries, are freed on - GOptionGroup.destroy() */ -} PyGOptionGroup; - -PyObject* pyg_option_group_new(GOptionGroup *group); - -void pyglib_option_group_register_types(PyObject *d); - -#endif /* __PYG_OPTIONGROUP_H__ */ - - diff --git a/gi/_glib/pygspawn.c b/gi/_glib/pygspawn.c deleted file mode 100644 index 72746b8..0000000 --- a/gi/_glib/pygspawn.c +++ /dev/null @@ -1,259 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * pygspawn.c: wrapper for the glib library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#include -#include - -#include "pyglib.h" -#include "pyglib-private.h" - -#include "pygspawn.h" - -struct _PyGChildSetupData { - PyObject *func; - PyObject *data; -}; - -PYGLIB_DEFINE_TYPE("gi._glib.Pid", PyGPid_Type, PYGLIB_PyLongObject) - -static PyObject * -pyg_pid_close(PyObject *self, PyObject *args, PyObject *kwargs) -{ - g_spawn_close_pid(PYGLIB_PyLong_AsLong(self)); - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef pyg_pid_methods[] = { - { "close", (PyCFunction)pyg_pid_close, METH_NOARGS }, - { NULL, NULL, 0 } -}; - -static void -pyg_pid_free(PyObject *gpid) -{ - g_spawn_close_pid((GPid) PYGLIB_PyLong_AsLong(gpid)); - PYGLIB_PyLong_Type.tp_free((void *) gpid); -} - -static int -pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyErr_SetString(PyExc_TypeError, "gi._glib.Pid cannot be manually instantiated"); - return -1; -} - -PyObject * -pyg_pid_new(GPid pid) -{ - return PyObject_CallMethod((PyObject*)&PyGPid_Type, "__new__", "Oi", - &PyGPid_Type, pid); -} - -static void -_pyg_spawn_async_callback(gpointer user_data) -{ - struct _PyGChildSetupData *data; - PyObject *retval; - PyGILState_STATE gil; - - data = (struct _PyGChildSetupData *) user_data; - gil = pyglib_gil_state_ensure(); - if (data->data) - retval = PyObject_CallFunction(data->func, "O", data->data); - else - retval = PyObject_CallFunction(data->func, NULL); - if (retval) - Py_DECREF(retval); - else - PyErr_Print(); - Py_DECREF(data->func); - Py_XDECREF(data->data); - g_slice_free(struct _PyGChildSetupData, data); - pyglib_gil_state_release(gil); -} - -PyObject * -pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "argv", "envp", "working_directory", "flags", - "child_setup", "user_data", "standard_input", - "standard_output", "standard_error", NULL }; - PyObject *pyargv, *pyenvp = NULL; - char **argv, **envp = NULL; - PyObject *func = Py_None, *user_data = NULL; - char *working_directory = NULL; - int flags = 0, _stdin = -1, _stdout = -1, _stderr = -1; - PyObject *pystdin = NULL, *pystdout = NULL, *pystderr = NULL; - gint *standard_input, *standard_output, *standard_error; - struct _PyGChildSetupData *callback_data = NULL; - GError *error = NULL; - GPid child_pid = -1; - Py_ssize_t len, i; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsiOOOOO:gi._glib.spawn_async", - kwlist, - &pyargv, &pyenvp, &working_directory, &flags, - &func, &user_data, - &pystdin, &pystdout, &pystderr)) - return NULL; - - if (pystdin && PyObject_IsTrue(pystdin)) - standard_input = &_stdin; - else - standard_input = NULL; - - if (pystdout && PyObject_IsTrue(pystdout)) - standard_output = &_stdout; - else - standard_output = NULL; - - if (pystderr && PyObject_IsTrue(pystderr)) - standard_error = &_stderr; - else - standard_error = NULL; - - /* parse argv */ - if (!PySequence_Check(pyargv)) { - PyErr_SetString(PyExc_TypeError, - "gi._glib.spawn_async: " - "first argument must be a sequence of strings"); - return NULL; - } - len = PySequence_Length(pyargv); - argv = g_new0(char *, len + 1); - for (i = 0; i < len; ++i) { - PyObject *tmp = PySequence_ITEM(pyargv, i); - if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) { - PyErr_SetString(PyExc_TypeError, - "gi._glib.spawn_async: " - "first argument must be a sequence of strings"); - g_free(argv); - Py_XDECREF(tmp); - return NULL; - } - argv[i] = PYGLIB_PyUnicode_AsString(tmp); - Py_DECREF(tmp); - } - - /* parse envp */ - if (pyenvp) { - if (!PySequence_Check(pyenvp)) { - PyErr_SetString(PyExc_TypeError, - "gi._glib.spawn_async: " - "second argument must be a sequence of strings"); - g_free(argv); - return NULL; - } - len = PySequence_Length(pyenvp); - envp = g_new0(char *, len + 1); - for (i = 0; i < len; ++i) { - PyObject *tmp = PySequence_ITEM(pyenvp, i); - if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) { - PyErr_SetString(PyExc_TypeError, - "gi._glib.spawn_async: " - "second argument must be a sequence of strings"); - g_free(envp); - Py_XDECREF(tmp); - g_free(argv); - return NULL; - } - envp[i] = PYGLIB_PyUnicode_AsString(tmp); - Py_DECREF(tmp); - } - } - - if (func != Py_None) { - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, "child_setup parameter must be callable or None"); - g_free(argv); - if (envp) - g_free(envp); - return NULL; - } - callback_data = g_slice_new(struct _PyGChildSetupData); - callback_data->func = func; - callback_data->data = user_data; - Py_INCREF(callback_data->func); - if (callback_data->data) - Py_INCREF(callback_data->data); - } - - if (!g_spawn_async_with_pipes(working_directory, argv, envp, flags, - (func != Py_None ? _pyg_spawn_async_callback : NULL), - callback_data, &child_pid, - standard_input, - standard_output, - standard_error, - &error)) - - - { - g_free(argv); - if (envp) g_free(envp); - if (callback_data) { - Py_DECREF(callback_data->func); - Py_XDECREF(callback_data->data); - g_slice_free(struct _PyGChildSetupData, callback_data); - } - pyglib_error_check(&error); - return NULL; - } - g_free(argv); - if (envp) g_free(envp); - - if (standard_input) - pystdin = PYGLIB_PyLong_FromLong(*standard_input); - else { - Py_INCREF(Py_None); - pystdin = Py_None; - } - - if (standard_output) - pystdout = PYGLIB_PyLong_FromLong(*standard_output); - else { - Py_INCREF(Py_None); - pystdout = Py_None; - } - - if (standard_error) - pystderr = PYGLIB_PyLong_FromLong(*standard_error); - else { - Py_INCREF(Py_None); - pystderr = Py_None; - } - - return Py_BuildValue("NNNN", pyg_pid_new(child_pid), pystdin, pystdout, pystderr); -} - -void -pyglib_spawn_register_types(PyObject *d) -{ - PyGPid_Type.tp_base = &PYGLIB_PyLong_Type; - PyGPid_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGPid_Type.tp_methods = pyg_pid_methods; - PyGPid_Type.tp_init = pyg_pid_tp_init; - PyGPid_Type.tp_free = (freefunc)pyg_pid_free; - PyGPid_Type.tp_new = PYGLIB_PyLong_Type.tp_new; - PYGLIB_REGISTER_TYPE(d, PyGPid_Type, "Pid"); -} diff --git a/gi/_glib/pygspawn.h b/gi/_glib/pygspawn.h deleted file mode 100644 index 2e8dd3c..0000000 --- a/gi/_glib/pygspawn.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pyglib - Python bindings for GLib toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYG_PID_H__ -#define __PYG_PID_H__ - -PyObject * pyg_pid_new(GPid pid); -void pyglib_spawn_register_types(PyObject *d); - -PyObject * pyglib_spawn_async(PyObject *self, PyObject *args, PyObject *kwargs); - - -#endif /* __PYG_PID_H__ */ - diff --git a/gi/_gobject/Makefile.am b/gi/_gobject/Makefile.am index 5059ea7..37068b8 100644 --- a/gi/_gobject/Makefile.am +++ b/gi/_gobject/Makefile.am @@ -1,74 +1,10 @@ AUTOMAKE_OPTIONS = 1.7 PLATFORM_VERSION = 3.0 -pkgincludedir = $(includedir)/pygobject-$(PLATFORM_VERSION) -pkginclude_HEADERS = pygobject.h - -extension_cppflags = \ - $(PYTHON_INCLUDES) \ - -DPY_SSIZE_T_CLEAN - -extension_ldflags = \ - -module \ - -avoid-version \ - -shrext $(PYTHON_SO) - -if OS_WIN32 -# Windows requires Python modules to be explicitly linked to libpython. -# Extension modules are shared libaries (.dll), but need to be -# called .pyd for Python to load it as an extension module. -extension_libadd = \ - $(PYTHON_LIBS) - -extension_ldflags += \ - -no-undefined -endif - pygobjectdir = $(pyexecdir)/gi/_gobject pygobject_PYTHON = \ - __init__.py \ - constants.py \ - propertyhelper.py \ - signalhelper.py - -pygobject_LTLIBRARIES = _gobject.la - -_gobject_la_SOURCES = \ - gobjectmodule.c \ - pygboxed.c \ - pygboxed.h \ - pygenum.c \ - pygenum.h \ - pygflags.c \ - pygflags.h \ - pyginterface.c \ - pyginterface.h \ - pygobject.c \ - pygobject.h \ - pygobject-private.h \ - pygparamspec.c \ - pygparamspec.h \ - pygpointer.c \ - pygpointer.h \ - pygtype.c \ - pygtype.h -_gobject_la_CFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi \ - $(GLIB_CFLAGS) \ - $(GI_CFLAGS) -_gi_la_CPPFLAGS = \ - $(extension_cppflags) -_gobject_la_LIBADD = \ - $(extension_libadd) \ - $(GLIB_LIBS) \ - $(GI_LIBS) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la -_gobject_la_LDFLAGS = \ - $(extension_ldflags) \ - -export-symbols-regex "_gobject|PyInit__gobject" + __init__.py # if we build in a separate tree, we need to symlink the *.py files from the # source tree; Python does not accept the extensions and modules in different @@ -79,9 +15,5 @@ build_pylinks: done -all: $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -check-local: $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -clean-local: - rm -f $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) -%$(PYTHON_SO): %.la - $(LN_S) -f .libs/$@ $@ +all: build_pylinks +check-local: build_pylinks diff --git a/gi/_gobject/Makefile.in b/gi/_gobject/Makefile.in index ce28f0e..39c07e3 100644 --- a/gi/_gobject/Makefile.in +++ b/gi/_gobject/Makefile.in @@ -14,8 +14,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - - VPATH = @srcdir@ am__make_dryrun = \ { \ @@ -35,6 +33,7 @@ am__make_dryrun = \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd @@ -51,12 +50,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@OS_WIN32_TRUE@am__append_1 = \ -@OS_WIN32_TRUE@ -no-undefined - subdir = gi/_gobject -DIST_COMMON = $(pkginclude_HEADERS) $(pygobject_PYTHON) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(pygobject_PYTHON) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/libtool.m4 \ @@ -69,6 +65,19 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -96,66 +105,10 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(pygobjectdir)" \ - "$(DESTDIR)$(pygobjectdir)" "$(DESTDIR)$(pkgincludedir)" -LTLIBRARIES = $(pygobject_LTLIBRARIES) -am__DEPENDENCIES_1 = -@OS_WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -_gobject_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la -am__gobject_la_OBJECTS = _gobject_la-gobjectmodule.lo \ - _gobject_la-pygboxed.lo _gobject_la-pygenum.lo \ - _gobject_la-pygflags.lo _gobject_la-pyginterface.lo \ - _gobject_la-pygobject.lo _gobject_la-pygparamspec.lo \ - _gobject_la-pygpointer.lo _gobject_la-pygtype.lo -_gobject_la_OBJECTS = $(am__gobject_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -_gobject_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_gobject_la_CFLAGS) \ - $(CFLAGS) $(_gobject_la_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(_gobject_la_SOURCES) -DIST_SOURCES = $(_gobject_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) +am__installdirs = "$(DESTDIR)$(pygobjectdir)" py_compile = $(top_srcdir)/py-compile -HEADERS = $(pkginclude_HEADERS) -ETAGS = etags -CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkgincludedir = $(includedir)/pygobject-$(PLATFORM_VERSION) ACLOCAL = @ACLOCAL@ ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ AMTAR = @AMTAR@ @@ -323,72 +276,13 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = 1.7 PLATFORM_VERSION = 3.0 -pkginclude_HEADERS = pygobject.h -extension_cppflags = \ - $(PYTHON_INCLUDES) \ - -DPY_SSIZE_T_CLEAN - -extension_ldflags = -module -avoid-version -shrext $(PYTHON_SO) \ - $(am__append_1) - -# Windows requires Python modules to be explicitly linked to libpython. -# Extension modules are shared libaries (.dll), but need to be -# called .pyd for Python to load it as an extension module. -@OS_WIN32_TRUE@extension_libadd = \ -@OS_WIN32_TRUE@ $(PYTHON_LIBS) - pygobjectdir = $(pyexecdir)/gi/_gobject pygobject_PYTHON = \ - __init__.py \ - constants.py \ - propertyhelper.py \ - signalhelper.py - -pygobject_LTLIBRARIES = _gobject.la -_gobject_la_SOURCES = \ - gobjectmodule.c \ - pygboxed.c \ - pygboxed.h \ - pygenum.c \ - pygenum.h \ - pygflags.c \ - pygflags.h \ - pyginterface.c \ - pyginterface.h \ - pygobject.c \ - pygobject.h \ - pygobject-private.h \ - pygparamspec.c \ - pygparamspec.h \ - pygpointer.c \ - pygpointer.h \ - pygtype.c \ - pygtype.h - -_gobject_la_CFLAGS = \ - $(extension_cppflags) \ - -I$(top_srcdir)/gi/_glib \ - -I$(top_srcdir)/gi \ - $(GLIB_CFLAGS) \ - $(GI_CFLAGS) - -_gi_la_CPPFLAGS = \ - $(extension_cppflags) - -_gobject_la_LIBADD = \ - $(extension_libadd) \ - $(GLIB_LIBS) \ - $(GI_LIBS) \ - $(top_builddir)/gi/_glib/libpyglib-gi-2.0-@PYTHON_BASENAME@.la - -_gobject_la_LDFLAGS = \ - $(extension_ldflags) \ - -export-symbols-regex "_gobject|PyInit__gobject" + __init__.py all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -419,140 +313,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-pygobjectLTLIBRARIES: $(pygobject_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(pygobject_LTLIBRARIES)'; test -n "$(pygobjectdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(pygobjectdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pygobjectdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pygobjectdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pygobjectdir)"; \ - } - -uninstall-pygobjectLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(pygobject_LTLIBRARIES)'; test -n "$(pygobjectdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pygobjectdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pygobjectdir)/$$f"; \ - done - -clean-pygobjectLTLIBRARIES: - -test -z "$(pygobject_LTLIBRARIES)" || rm -f $(pygobject_LTLIBRARIES) - @list='$(pygobject_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -_gobject.la: $(_gobject_la_OBJECTS) $(_gobject_la_DEPENDENCIES) $(EXTRA__gobject_la_DEPENDENCIES) - $(AM_V_CCLD)$(_gobject_la_LINK) -rpath $(pygobjectdir) $(_gobject_la_OBJECTS) $(_gobject_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-gobjectmodule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygboxed.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygenum.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygflags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pyginterface.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygobject.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygparamspec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygpointer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gobject_la-pygtype.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -_gobject_la-gobjectmodule.lo: gobjectmodule.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-gobjectmodule.lo -MD -MP -MF $(DEPDIR)/_gobject_la-gobjectmodule.Tpo -c -o _gobject_la-gobjectmodule.lo `test -f 'gobjectmodule.c' || echo '$(srcdir)/'`gobjectmodule.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-gobjectmodule.Tpo $(DEPDIR)/_gobject_la-gobjectmodule.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gobjectmodule.c' object='_gobject_la-gobjectmodule.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-gobjectmodule.lo `test -f 'gobjectmodule.c' || echo '$(srcdir)/'`gobjectmodule.c - -_gobject_la-pygboxed.lo: pygboxed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygboxed.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygboxed.Tpo -c -o _gobject_la-pygboxed.lo `test -f 'pygboxed.c' || echo '$(srcdir)/'`pygboxed.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygboxed.Tpo $(DEPDIR)/_gobject_la-pygboxed.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygboxed.c' object='_gobject_la-pygboxed.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygboxed.lo `test -f 'pygboxed.c' || echo '$(srcdir)/'`pygboxed.c - -_gobject_la-pygenum.lo: pygenum.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygenum.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygenum.Tpo -c -o _gobject_la-pygenum.lo `test -f 'pygenum.c' || echo '$(srcdir)/'`pygenum.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygenum.Tpo $(DEPDIR)/_gobject_la-pygenum.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygenum.c' object='_gobject_la-pygenum.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygenum.lo `test -f 'pygenum.c' || echo '$(srcdir)/'`pygenum.c - -_gobject_la-pygflags.lo: pygflags.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygflags.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygflags.Tpo -c -o _gobject_la-pygflags.lo `test -f 'pygflags.c' || echo '$(srcdir)/'`pygflags.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygflags.Tpo $(DEPDIR)/_gobject_la-pygflags.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygflags.c' object='_gobject_la-pygflags.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygflags.lo `test -f 'pygflags.c' || echo '$(srcdir)/'`pygflags.c - -_gobject_la-pyginterface.lo: pyginterface.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pyginterface.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pyginterface.Tpo -c -o _gobject_la-pyginterface.lo `test -f 'pyginterface.c' || echo '$(srcdir)/'`pyginterface.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pyginterface.Tpo $(DEPDIR)/_gobject_la-pyginterface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyginterface.c' object='_gobject_la-pyginterface.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pyginterface.lo `test -f 'pyginterface.c' || echo '$(srcdir)/'`pyginterface.c - -_gobject_la-pygobject.lo: pygobject.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygobject.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygobject.Tpo -c -o _gobject_la-pygobject.lo `test -f 'pygobject.c' || echo '$(srcdir)/'`pygobject.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygobject.Tpo $(DEPDIR)/_gobject_la-pygobject.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygobject.c' object='_gobject_la-pygobject.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygobject.lo `test -f 'pygobject.c' || echo '$(srcdir)/'`pygobject.c - -_gobject_la-pygparamspec.lo: pygparamspec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygparamspec.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygparamspec.Tpo -c -o _gobject_la-pygparamspec.lo `test -f 'pygparamspec.c' || echo '$(srcdir)/'`pygparamspec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygparamspec.Tpo $(DEPDIR)/_gobject_la-pygparamspec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygparamspec.c' object='_gobject_la-pygparamspec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygparamspec.lo `test -f 'pygparamspec.c' || echo '$(srcdir)/'`pygparamspec.c - -_gobject_la-pygpointer.lo: pygpointer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygpointer.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygpointer.Tpo -c -o _gobject_la-pygpointer.lo `test -f 'pygpointer.c' || echo '$(srcdir)/'`pygpointer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygpointer.Tpo $(DEPDIR)/_gobject_la-pygpointer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygpointer.c' object='_gobject_la-pygpointer.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygpointer.lo `test -f 'pygpointer.c' || echo '$(srcdir)/'`pygpointer.c - -_gobject_la-pygtype.lo: pygtype.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -MT _gobject_la-pygtype.lo -MD -MP -MF $(DEPDIR)/_gobject_la-pygtype.Tpo -c -o _gobject_la-pygtype.lo `test -f 'pygtype.c' || echo '$(srcdir)/'`pygtype.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gobject_la-pygtype.Tpo $(DEPDIR)/_gobject_la-pygtype.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pygtype.c' object='_gobject_la-pygtype.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gobject_la_CFLAGS) $(CFLAGS) -c -o _gobject_la-pygtype.lo `test -f 'pygtype.c' || echo '$(srcdir)/'`pygtype.c mostlyclean-libtool: -rm -f *.lo @@ -601,79 +361,12 @@ uninstall-pygobjectPYTHON: $(am__uninstall_files_from_dir) || st=$$?; \ done; \ exit $$st -install-pkgincludeHEADERS: $(pkginclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ - done - -uninstall-pkgincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique tags: TAGS +TAGS: -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +CTAGS: + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -708,9 +401,9 @@ distdir: $(DISTFILES) check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-am: Makefile installdirs: - for dir in "$(DESTDIR)$(pygobjectdir)" "$(DESTDIR)$(pygobjectdir)" "$(DESTDIR)$(pkgincludedir)"; do \ + for dir in "$(DESTDIR)$(pygobjectdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -745,14 +438,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-local \ - clean-pygobjectLTLIBRARIES mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -766,8 +456,7 @@ info: info-am info-am: -install-data-am: install-pkgincludeHEADERS \ - install-pygobjectLTLIBRARIES install-pygobjectPYTHON +install-data-am: install-pygobjectPYTHON install-dvi: install-dvi-am @@ -796,14 +485,12 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -813,27 +500,22 @@ ps: ps-am ps-am: -uninstall-am: uninstall-pkgincludeHEADERS \ - uninstall-pygobjectLTLIBRARIES uninstall-pygobjectPYTHON +uninstall-am: uninstall-pygobjectPYTHON .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ - clean-generic clean-libtool clean-local \ - clean-pygobjectLTLIBRARIES ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-pkgincludeHEADERS install-ps \ - install-ps-am install-pygobjectLTLIBRARIES \ +.PHONY: all all-am check check-am check-local clean clean-generic \ + clean-libtool distclean distclean-generic distclean-libtool \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ install-pygobjectPYTHON install-strip installcheck \ installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-pkgincludeHEADERS \ - uninstall-pygobjectLTLIBRARIES uninstall-pygobjectPYTHON + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-pygobjectPYTHON # if we build in a separate tree, we need to symlink the *.py files from the @@ -844,12 +526,8 @@ build_pylinks: [ -e $(builddir)/$$f ] || $(LN_S) $(srcdir)/$$f $(builddir)/$$f; \ done -all: $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -check-local: $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) build_pylinks -clean-local: - rm -f $(pygobject_LTLIBRARIES:.la=$(PYTHON_SO)) -%$(PYTHON_SO): %.la - $(LN_S) -f .libs/$@ $@ +all: build_pylinks +check-local: build_pylinks # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/gi/_gobject/__init__.py b/gi/_gobject/__init__.py index d3ea0e0..dd5217d 100644 --- a/gi/_gobject/__init__.py +++ b/gi/_gobject/__init__.py @@ -19,42 +19,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 # USA -# this can go when things are a little further along - -import sys - -# we can't have pygobject 2 loaded at the same time we load the internal _gobject -if 'gobject' in sys.modules: - raise ImportError('When using gi.repository you must not import static modules like "gobject". Please change all occurrences of "import gobject" to "from gi.repository import GObject".') - -from . import _gobject -from . import propertyhelper -from . import signalhelper - -GObject = _gobject.GObject -GType = _gobject.GType -_PyGObject_API = _gobject._PyGObject_API -pygobject_version = _gobject.pygobject_version - - -class GObjectMeta(type): - "Metaclass for automatically registering GObject classes" - def __init__(cls, name, bases, dict_): - type.__init__(cls, name, bases, dict_) - propertyhelper.install_properties(cls) - signalhelper.install_signals(cls) - cls._type_register(cls.__dict__) - - def _type_register(cls, namespace): - ## don't register the class if already registered - if '__gtype__' in namespace: - return - - # Do not register a new GType for the overrides, as this would sort of - # defeat the purpose of overrides... - if cls.__module__.startswith('gi.overrides.'): - return - - _gobject.type_register(cls, namespace.get('__gtype_name__')) - -_gobject._install_metaclass(GObjectMeta) +# Needed for compatibility with "pygobject.h" +import gi._gi +_PyGObject_API = gi._gi._gobject._PyGObject_API +pygobject_version = gi._gi._gobject.pygobject_version diff --git a/gi/_gobject/constants.py b/gi/_gobject/constants.py deleted file mode 100644 index 9565a66..0000000 --- a/gi/_gobject/constants.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- Mode: Python; py-indent-offset: 4 -*- -# pygobject - Python bindings for the GObject library -# Copyright (C) 2006-2007 Johan Dahlin -# -# gobject/constants.py: GObject type constants -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -from . import _gobject - -TYPE_INVALID = _gobject.TYPE_INVALID -TYPE_NONE = _gobject.type_from_name('void') -TYPE_INTERFACE = _gobject.type_from_name('GInterface') -TYPE_CHAR = _gobject.type_from_name('gchar') -TYPE_UCHAR = _gobject.type_from_name('guchar') -TYPE_BOOLEAN = _gobject.type_from_name('gboolean') -TYPE_INT = _gobject.type_from_name('gint') -TYPE_UINT = _gobject.type_from_name('guint') -TYPE_LONG = _gobject.type_from_name('glong') -TYPE_ULONG = _gobject.type_from_name('gulong') -TYPE_INT64 = _gobject.type_from_name('gint64') -TYPE_UINT64 = _gobject.type_from_name('guint64') -TYPE_ENUM = _gobject.type_from_name('GEnum') -TYPE_FLAGS = _gobject.type_from_name('GFlags') -TYPE_FLOAT = _gobject.type_from_name('gfloat') -TYPE_DOUBLE = _gobject.type_from_name('gdouble') -TYPE_STRING = _gobject.type_from_name('gchararray') -TYPE_POINTER = _gobject.type_from_name('gpointer') -TYPE_BOXED = _gobject.type_from_name('GBoxed') -TYPE_PARAM = _gobject.type_from_name('GParam') -TYPE_OBJECT = _gobject.type_from_name('GObject') -TYPE_PYOBJECT = _gobject.type_from_name('PyObject') -TYPE_GTYPE = _gobject.type_from_name('GType') -TYPE_STRV = _gobject.type_from_name('GStrv') -TYPE_VARIANT = _gobject.type_from_name('GVariant') -TYPE_UNICHAR = TYPE_UINT diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c deleted file mode 100644 index e982107..0000000 --- a/gi/_gobject/gobjectmodule.c +++ /dev/null @@ -1,2213 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * gobjectmodule.c: wrapper for the gobject library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include "pygobject-private.h" -#include "pygboxed.h" -#include "pygenum.h" -#include "pygflags.h" -#include "pyginterface.h" -#include "pygparamspec.h" -#include "pygpointer.h" -#include "pygtype.h" - -static GHashTable *log_handlers = NULL; -static gboolean log_handlers_disabled = FALSE; - -static void pyg_flags_add_constants(PyObject *module, GType flags_type, - const gchar *strip_prefix); - - -/* -------------- GDK threading hooks ---------------------------- */ - -/** - * pyg_set_thread_block_funcs: - * Deprecated, only available for ABI compatibility. - */ -static void -_pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func, - PyGThreadBlockFunc unblock_threads_func) -{ - PyGILState_STATE state = pyglib_gil_state_ensure (); - PyErr_Warn (PyExc_DeprecationWarning, - "Using pyg_set_thread_block_funcs is not longer needed. " - "PyGObject always uses Py_BLOCK/UNBLOCK_THREADS."); - pyglib_gil_state_release (state); -} - -/** - * pyg_destroy_notify: - * @user_data: a PyObject pointer. - * - * A function that can be used as a GDestroyNotify callback that will - * call Py_DECREF on the data. - */ -void -pyg_destroy_notify(gpointer user_data) -{ - PyObject *obj = (PyObject *)user_data; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - Py_DECREF(obj); - pyglib_gil_state_release(state); -} - - -/* ---------------- gobject module functions -------------------- */ - -static PyObject * -pyg_type_name (PyObject *self, PyObject *args) -{ - PyObject *gtype; - GType type; - const gchar *name; - -#if 0 - if (PyErr_Warn(PyExc_DeprecationWarning, - "gobject.type_name is deprecated; " - "use GType.name instead")) - return NULL; -#endif - - if (!PyArg_ParseTuple(args, "O:gobject.type_name", >ype)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - name = g_type_name(type); - if (name) - return PYGLIB_PyUnicode_FromString(name); - PyErr_SetString(PyExc_RuntimeError, "unknown typecode"); - return NULL; -} - -static PyObject * -pyg_type_from_name (PyObject *self, PyObject *args) -{ - const gchar *name; - GType type; - PyObject *repr = NULL; -#if 0 - if (PyErr_Warn(PyExc_DeprecationWarning, - "gobject.type_from_name is deprecated; " - "use GType.from_name instead")) - return NULL; -#endif - if (!PyArg_ParseTuple(args, "s:gobject.type_from_name", &name)) - return NULL; - type = g_type_from_name(name); - if (type != 0) - return pyg_type_wrapper_new(type); - repr = PyObject_Repr((PyObject*)self); - PyErr_Format(PyExc_RuntimeError, "%s: unknown type name: %s", - PYGLIB_PyUnicode_AsString(repr), - name); - Py_DECREF(repr); - return NULL; -} - -static PyObject * -pyg_type_is_a (PyObject *self, PyObject *args) -{ - PyObject *gtype, *gparent; - GType type, parent; -#if 0 - if (PyErr_Warn(PyExc_DeprecationWarning, - "gobject.type_is_a is deprecated; " - "use GType.is_a instead")) - return NULL; -#endif - if (!PyArg_ParseTuple(args, "OO:gobject.type_is_a", >ype, &gparent)) - return NULL; - if ((type = pyg_type_from_object(gtype)) == 0) - return NULL; - if ((parent = pyg_type_from_object(gparent)) == 0) - return NULL; - return PyBool_FromLong(g_type_is_a(type, parent)); -} - -static void -pyg_object_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) -{ - PyObject *object_wrapper, *retval; - PyObject *py_pspec, *py_value; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - - object_wrapper = pygobject_new(object); - - if (object_wrapper == NULL) { - pyglib_gil_state_release(state); - return; - } - - py_pspec = pyg_param_spec_new(pspec); - py_value = pyg_value_as_pyobject (value, TRUE); - - retval = PyObject_CallMethod(object_wrapper, "do_set_property", - "OO", py_pspec, py_value); - if (retval) { - Py_DECREF(retval); - } else { - PyErr_Print(); - } - - Py_DECREF(object_wrapper); - Py_DECREF(py_pspec); - Py_DECREF(py_value); - - pyglib_gil_state_release(state); -} - -static void -pyg_object_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) -{ - PyObject *object_wrapper, *retval; - PyObject *py_pspec; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - - object_wrapper = pygobject_new(object); - - if (object_wrapper == NULL) { - pyglib_gil_state_release(state); - return; - } - - py_pspec = pyg_param_spec_new(pspec); - retval = PyObject_CallMethod(object_wrapper, "do_get_property", - "O", py_pspec); - if (retval == NULL || pyg_value_from_pyobject(value, retval) < 0) { - PyErr_Print(); - } - Py_DECREF(object_wrapper); - Py_DECREF(py_pspec); - Py_XDECREF(retval); - - pyglib_gil_state_release(state); -} - -typedef struct _PyGSignalAccumulatorData { - PyObject *callable; - PyObject *user_data; -} PyGSignalAccumulatorData; - -static gboolean -_pyg_signal_accumulator(GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer _data) -{ - PyObject *py_ihint, *py_return_accu, *py_handler_return, *py_detail; - PyObject *py_retval; - gboolean retval = FALSE; - PyGSignalAccumulatorData *data = _data; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - if (ihint->detail) - py_detail = PYGLIB_PyUnicode_FromString(g_quark_to_string(ihint->detail)); - else { - Py_INCREF(Py_None); - py_detail = Py_None; - } - - py_ihint = Py_BuildValue("lNi", (long int) ihint->signal_id, - py_detail, ihint->run_type); - py_handler_return = pyg_value_as_pyobject(handler_return, TRUE); - py_return_accu = pyg_value_as_pyobject(return_accu, FALSE); - if (data->user_data) - py_retval = PyObject_CallFunction(data->callable, "NNNO", py_ihint, - py_return_accu, py_handler_return, - data->user_data); - else - py_retval = PyObject_CallFunction(data->callable, "NNN", py_ihint, - py_return_accu, py_handler_return); - if (!py_retval) - PyErr_Print(); - else { - if (!PyTuple_Check(py_retval) || PyTuple_Size(py_retval) != 2) { - PyErr_SetString(PyExc_TypeError, "accumulator function must return" - " a (bool, object) tuple"); - PyErr_Print(); - } else { - retval = PyObject_IsTrue(PyTuple_GET_ITEM(py_retval, 0)); - if (pyg_value_from_pyobject(return_accu, PyTuple_GET_ITEM(py_retval, 1))) { - PyErr_Print(); - } - } - Py_DECREF(py_retval); - } - pyglib_gil_state_release(state); - return retval; -} - -static gboolean -create_signal (GType instance_type, const gchar *signal_name, PyObject *tuple) -{ - GSignalFlags signal_flags; - PyObject *py_return_type, *py_param_types; - GType return_type; - guint n_params, i; - GType *param_types; - guint signal_id; - GSignalAccumulator accumulator = NULL; - PyGSignalAccumulatorData *accum_data = NULL; - PyObject *py_accum = NULL, *py_accum_data = NULL; - - if (!PyArg_ParseTuple(tuple, "iOO|OO", &signal_flags, &py_return_type, - &py_param_types, &py_accum, &py_accum_data)) - { - gchar buf[128]; - - PyErr_Clear(); - g_snprintf(buf, sizeof(buf), - "value for __gsignals__['%s'] not in correct format", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - - if (py_accum && py_accum != Py_None && !PyCallable_Check(py_accum)) - { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "accumulator for __gsignals__['%s'] must be callable", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - - return_type = pyg_type_from_object(py_return_type); - if (!return_type) - return FALSE; - if (!PySequence_Check(py_param_types)) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "third element of __gsignals__['%s'] tuple must be a sequence", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - n_params = PySequence_Length(py_param_types); - param_types = g_new(GType, n_params); - for (i = 0; i < n_params; i++) { - PyObject *item = PySequence_GetItem(py_param_types, i); - - param_types[i] = pyg_type_from_object(item); - if (param_types[i] == 0) { - Py_DECREF(item); - g_free(param_types); - return FALSE; - } - Py_DECREF(item); - } - - if (py_accum != NULL && py_accum != Py_None) { - accum_data = g_new(PyGSignalAccumulatorData, 1); - accum_data->callable = py_accum; - Py_INCREF(py_accum); - accum_data->user_data = py_accum_data; - Py_XINCREF(py_accum_data); - accumulator = _pyg_signal_accumulator; - } - - signal_id = g_signal_newv(signal_name, instance_type, signal_flags, - pyg_signal_class_closure_get(), - accumulator, accum_data, - gi_cclosure_marshal_generic, - return_type, n_params, param_types); - g_free(param_types); - - if (signal_id == 0) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "could not create signal for %s", - signal_name); - PyErr_SetString(PyExc_RuntimeError, buf); - return FALSE; - } - return TRUE; -} - -static gboolean -override_signal(GType instance_type, const gchar *signal_name) -{ - guint signal_id; - - signal_id = g_signal_lookup(signal_name, instance_type); - if (!signal_id) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "could not look up %s", signal_name); - PyErr_SetString(PyExc_TypeError, buf); - return FALSE; - } - g_signal_override_class_closure(signal_id, instance_type, - pyg_signal_class_closure_get()); - return TRUE; -} - -static PyObject * -add_signals (GObjectClass *klass, PyObject *signals) -{ - gboolean ret = TRUE; - Py_ssize_t pos = 0; - PyObject *key, *value, *overridden_signals = NULL; - GType instance_type = G_OBJECT_CLASS_TYPE (klass); - - overridden_signals = PyDict_New(); - while (PyDict_Next(signals, &pos, &key, &value)) { - const gchar *signal_name; - gchar *signal_name_canon, *c; - - if (!PYGLIB_PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "__gsignals__ keys must be strings"); - ret = FALSE; - break; - } - signal_name = PYGLIB_PyUnicode_AsString (key); - - if (value == Py_None || - (PYGLIB_PyUnicode_Check(value) && - !strcmp(PYGLIB_PyUnicode_AsString(value), "override"))) - { - /* canonicalize signal name, replacing '-' with '_' */ - signal_name_canon = g_strdup(signal_name); - for (c = signal_name_canon; *c; ++c) - if (*c == '-') - *c = '_'; - if (PyDict_SetItemString(overridden_signals, - signal_name_canon, key)) { - g_free(signal_name_canon); - ret = FALSE; - break; - } - g_free(signal_name_canon); - - ret = override_signal(instance_type, signal_name); - } else { - ret = create_signal(instance_type, signal_name, value); - } - - if (!ret) - break; - } - if (ret) - return overridden_signals; - else { - Py_XDECREF(overridden_signals); - return NULL; - } -} - -static GParamSpec * -create_property (const gchar *prop_name, - GType prop_type, - const gchar *nick, - const gchar *blurb, - PyObject *args, - GParamFlags flags) -{ - GParamSpec *pspec = NULL; - - switch (G_TYPE_FUNDAMENTAL(prop_type)) { - case G_TYPE_CHAR: - { - gchar minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_char (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UCHAR: - { - gchar minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_uchar (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_BOOLEAN: - { - gboolean default_value; - - if (!PyArg_ParseTuple(args, "i", &default_value)) - return NULL; - pspec = g_param_spec_boolean (prop_name, nick, blurb, - default_value, flags); - } - break; - case G_TYPE_INT: - { - gint minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "iii", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_int (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UINT: - { - guint minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "III", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_uint (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_LONG: - { - glong minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "lll", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_long (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_ULONG: - { - gulong minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "kkk", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_ulong (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_INT64: - { - gint64 minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "LLL", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_int64 (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_UINT64: - { - guint64 minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "KKK", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_uint64 (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_ENUM: - { - gint default_value; - PyObject *pydefault; - - if (!PyArg_ParseTuple(args, "O", &pydefault)) - return NULL; - - if (pyg_enum_get_value(prop_type, pydefault, - (gint *)&default_value)) - return NULL; - - pspec = g_param_spec_enum (prop_name, nick, blurb, - prop_type, default_value, flags); - } - break; - case G_TYPE_FLAGS: - { - guint default_value; - PyObject *pydefault; - - if (!PyArg_ParseTuple(args, "O", &pydefault)) - return NULL; - - if (pyg_flags_get_value(prop_type, pydefault, - &default_value)) - return NULL; - - pspec = g_param_spec_flags (prop_name, nick, blurb, - prop_type, default_value, flags); - } - break; - case G_TYPE_FLOAT: - { - gfloat minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "fff", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_float (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_DOUBLE: - { - gdouble minimum, maximum, default_value; - - if (!PyArg_ParseTuple(args, "ddd", &minimum, &maximum, - &default_value)) - return NULL; - pspec = g_param_spec_double (prop_name, nick, blurb, minimum, - maximum, default_value, flags); - } - break; - case G_TYPE_STRING: - { - const gchar *default_value; - - if (!PyArg_ParseTuple(args, "z", &default_value)) - return NULL; - pspec = g_param_spec_string (prop_name, nick, blurb, - default_value, flags); - } - break; - case G_TYPE_PARAM: - if (!PyArg_ParseTuple(args, "")) - return NULL; - pspec = g_param_spec_param (prop_name, nick, blurb, prop_type, flags); - break; - case G_TYPE_BOXED: - if (!PyArg_ParseTuple(args, "")) - return NULL; - pspec = g_param_spec_boxed (prop_name, nick, blurb, prop_type, flags); - break; - case G_TYPE_POINTER: - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (prop_type == G_TYPE_GTYPE) - pspec = g_param_spec_gtype (prop_name, nick, blurb, G_TYPE_NONE, flags); - else - pspec = g_param_spec_pointer (prop_name, nick, blurb, flags); - break; - case G_TYPE_OBJECT: - case G_TYPE_INTERFACE: - if (!PyArg_ParseTuple(args, "")) - return NULL; - pspec = g_param_spec_object (prop_name, nick, blurb, prop_type, flags); - break; - case G_TYPE_VARIANT: - { - PyObject *pydefault; - GVariant *default_value = NULL; - - if (!PyArg_ParseTuple(args, "O", &pydefault)) - return NULL; - if (pydefault != Py_None) - default_value = pyg_boxed_get (pydefault, GVariant); - pspec = g_param_spec_variant (prop_name, nick, blurb, G_VARIANT_TYPE_ANY, default_value, flags); - } - break; - default: - /* unhandled pspec type ... */ - break; - } - - if (!pspec) { - char buf[128]; - - g_snprintf(buf, sizeof(buf), "could not create param spec for type %s", - g_type_name(prop_type)); - PyErr_SetString(PyExc_TypeError, buf); - return NULL; - } - - return pspec; -} - -static GParamSpec * -pyg_param_spec_from_object (PyObject *tuple) -{ - gint val_length; - const gchar *prop_name; - GType prop_type; - const gchar *nick, *blurb; - PyObject *slice, *item, *py_prop_type; - GParamSpec *pspec; - - val_length = PyTuple_Size(tuple); - if (val_length < 4) { - PyErr_SetString(PyExc_TypeError, - "paramspec tuples must be at least 4 elements long"); - return NULL; - } - - slice = PySequence_GetSlice(tuple, 0, 4); - if (!slice) { - return NULL; - } - - if (!PyArg_ParseTuple(slice, "sOzz", &prop_name, &py_prop_type, &nick, &blurb)) { - Py_DECREF(slice); - return NULL; - } - - Py_DECREF(slice); - - prop_type = pyg_type_from_object(py_prop_type); - if (!prop_type) { - return NULL; - } - - item = PyTuple_GetItem(tuple, val_length-1); - if (!PYGLIB_PyLong_Check(item)) { - PyErr_SetString(PyExc_TypeError, - "last element in tuple must be an int"); - return NULL; - } - - /* slice is the extra items in the tuple */ - slice = PySequence_GetSlice(tuple, 4, val_length-1); - pspec = create_property(prop_name, prop_type, - nick, blurb, slice, - PYGLIB_PyLong_AsLong(item)); - - return pspec; -} - -static gboolean -add_properties (GObjectClass *klass, PyObject *properties) -{ - gboolean ret = TRUE; - Py_ssize_t pos = 0; - PyObject *key, *value; - - while (PyDict_Next(properties, &pos, &key, &value)) { - const gchar *prop_name; - GType prop_type; - const gchar *nick, *blurb; - GParamFlags flags; - gint val_length; - PyObject *slice, *item, *py_prop_type; - GParamSpec *pspec; - - /* values are of format (type,nick,blurb, type_specific_args, flags) */ - - if (!PYGLIB_PyUnicode_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ keys must be strings"); - ret = FALSE; - break; - } - prop_name = PYGLIB_PyUnicode_AsString (key); - - if (!PyTuple_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ values must be tuples"); - ret = FALSE; - break; - } - val_length = PyTuple_Size(value); - if (val_length < 4) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ values must be at least 4 elements long"); - ret = FALSE; - break; - } - - slice = PySequence_GetSlice(value, 0, 3); - if (!slice) { - ret = FALSE; - break; - } - if (!PyArg_ParseTuple(slice, "Ozz", &py_prop_type, &nick, &blurb)) { - Py_DECREF(slice); - ret = FALSE; - break; - } - Py_DECREF(slice); - prop_type = pyg_type_from_object(py_prop_type); - if (!prop_type) { - ret = FALSE; - break; - } - item = PyTuple_GetItem(value, val_length-1); - if (!PYGLIB_PyLong_Check(item)) { - PyErr_SetString(PyExc_TypeError, - "last element in __gproperties__ value tuple must be an int"); - ret = FALSE; - break; - } - flags = PYGLIB_PyLong_AsLong(item); - - /* slice is the extra items in the tuple */ - slice = PySequence_GetSlice(value, 3, val_length-1); - pspec = create_property(prop_name, prop_type, nick, blurb, - slice, flags); - Py_DECREF(slice); - - if (pspec) { - g_object_class_install_property(klass, 1, pspec); - } else { - PyObject *type, *value, *traceback; - ret = FALSE; - PyErr_Fetch(&type, &value, &traceback); - if (PYGLIB_PyUnicode_Check(value)) { - char msg[256]; - g_snprintf(msg, 256, - "%s (while registering property '%s' for GType '%s')", - PYGLIB_PyUnicode_AsString(value), - prop_name, G_OBJECT_CLASS_NAME(klass)); - Py_DECREF(value); - value = PYGLIB_PyUnicode_FromString(msg); - } - PyErr_Restore(type, value, traceback); - break; - } - } - - return ret; -} - -static void -pyg_object_class_init(GObjectClass *class, PyObject *py_class) -{ - PyObject *gproperties, *gsignals, *overridden_signals; - PyObject *class_dict = ((PyTypeObject*) py_class)->tp_dict; - - class->set_property = pyg_object_set_property; - class->get_property = pyg_object_get_property; - - /* install signals */ - /* we look this up in the instance dictionary, so we don't - * accidentally get a parent type's __gsignals__ attribute. */ - gsignals = PyDict_GetItemString(class_dict, "__gsignals__"); - if (gsignals) { - if (!PyDict_Check(gsignals)) { - PyErr_SetString(PyExc_TypeError, - "__gsignals__ attribute not a dict!"); - return; - } - if (!(overridden_signals = add_signals(class, gsignals))) { - return; - } - if (PyDict_SetItemString(class_dict, "__gsignals__", - overridden_signals)) { - return; - } - Py_DECREF(overridden_signals); - - PyDict_DelItemString(class_dict, "__gsignals__"); - } else { - PyErr_Clear(); - } - - /* install properties */ - /* we look this up in the instance dictionary, so we don't - * accidentally get a parent type's __gproperties__ attribute. */ - gproperties = PyDict_GetItemString(class_dict, "__gproperties__"); - if (gproperties) { - if (!PyDict_Check(gproperties)) { - PyErr_SetString(PyExc_TypeError, - "__gproperties__ attribute not a dict!"); - return; - } - if (!add_properties(class, gproperties)) { - return; - } - PyDict_DelItemString(class_dict, "__gproperties__"); - /* Borrowed reference. Py_DECREF(gproperties); */ - } else { - PyErr_Clear(); - } -} - -static void -pyg_register_class_init(GType gtype, PyGClassInitFunc class_init) -{ - GSList *list; - - list = g_type_get_qdata(gtype, pygobject_class_init_key); - list = g_slist_prepend(list, class_init); - g_type_set_qdata(gtype, pygobject_class_init_key, list); -} - -static int -pyg_run_class_init(GType gtype, gpointer gclass, PyTypeObject *pyclass) -{ - GSList *list; - PyGClassInitFunc class_init; - GType parent_type; - int rv; - - parent_type = g_type_parent(gtype); - if (parent_type) { - rv = pyg_run_class_init(parent_type, gclass, pyclass); - if (rv) - return rv; - } - - list = g_type_get_qdata(gtype, pygobject_class_init_key); - for (; list; list = list->next) { - class_init = list->data; - rv = class_init(gclass, pyclass); - if (rv) - return rv; - } - - return 0; -} - -static PyObject * -_wrap_pyg_type_register(PyObject *self, PyObject *args) -{ - PyTypeObject *class; - char *type_name = NULL; - - if (!PyArg_ParseTuple(args, "O!|z:gobject.type_register", - &PyType_Type, &class, &type_name)) - return NULL; - if (!PyType_IsSubtype(class, &PyGObject_Type)) { - PyErr_SetString(PyExc_TypeError, - "argument must be a GObject subclass"); - return NULL; - } - - /* Check if type already registered */ - if (pyg_type_from_object((PyObject *) class) == - pyg_type_from_object((PyObject *) class->tp_base)) - { - if (pyg_type_register(class, type_name)) - return NULL; - } - - Py_INCREF(class); - return (PyObject *) class; -} - -static char * -get_type_name_for_class(PyTypeObject *class) -{ - gint i, name_serial; - char name_serial_str[16]; - PyObject *module; - char *type_name = NULL; - - /* make name for new GType */ - name_serial = 1; - /* give up after 1000 tries, just in case.. */ - while (name_serial < 1000) - { - g_free(type_name); - snprintf(name_serial_str, 16, "-v%i", name_serial); - module = PyObject_GetAttrString((PyObject *)class, "__module__"); - if (module && PYGLIB_PyUnicode_Check(module)) { - type_name = g_strconcat(PYGLIB_PyUnicode_AsString(module), ".", - class->tp_name, - name_serial > 1 ? name_serial_str : NULL, - NULL); - Py_DECREF(module); - } else { - if (module) - Py_DECREF(module); - else - PyErr_Clear(); - type_name = g_strconcat(class->tp_name, - name_serial > 1 ? name_serial_str : NULL, - NULL); - } - /* convert '.' in type name to '+', which isn't banned (grumble) */ - for (i = 0; type_name[i] != '\0'; i++) - if (type_name[i] == '.') - type_name[i] = '+'; - if (g_type_from_name(type_name) == 0) - break; /* we now have a unique name */ - ++name_serial; - } - - return type_name; -} - - -static GPrivate pygobject_construction_wrapper; - -static inline void -pygobject_init_wrapper_set(PyObject *wrapper) -{ - g_private_set(&pygobject_construction_wrapper, wrapper); -} - -static inline PyObject * -pygobject_init_wrapper_get(void) -{ - return (PyObject *) g_private_get(&pygobject_construction_wrapper); -} - -int -pygobject_constructv(PyGObject *self, - guint n_parameters, - GParameter *parameters) -{ - GObject *obj; - - g_assert (self->obj == NULL); - pygobject_init_wrapper_set((PyObject *) self); - obj = g_object_newv(pyg_type_from_object((PyObject *) self), - n_parameters, parameters); - - if (g_object_is_floating (obj)) - self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING; - pygobject_sink (obj); - - pygobject_init_wrapper_set(NULL); - self->obj = obj; - pygobject_register_wrapper((PyObject *) self); - - return 0; -} - -static void -pygobject__g_instance_init(GTypeInstance *instance, - gpointer g_class) -{ - GObject *object = (GObject *) instance; - PyObject *wrapper, *args, *kwargs; - - wrapper = g_object_get_qdata(object, pygobject_wrapper_key); - if (wrapper == NULL) { - wrapper = pygobject_init_wrapper_get(); - if (wrapper && ((PyGObject *) wrapper)->obj == NULL) { - ((PyGObject *) wrapper)->obj = object; - pygobject_register_wrapper(wrapper); - } - } - pygobject_init_wrapper_set(NULL); - if (wrapper == NULL) { - /* this looks like a python object created through - * g_object_new -> we have no python wrapper, so create it - * now */ - PyGILState_STATE state; - state = pyglib_gil_state_ensure(); - wrapper = pygobject_new_full(object, - /*steal=*/ FALSE, - g_class); - - /* float the wrapper ref here because we are going to orphan it - * so we don't destroy the wrapper. The next call to pygobject_new_full - * will take the ref */ - pygobject_ref_float ((PyGObject *) wrapper); - args = PyTuple_New(0); - kwargs = PyDict_New(); - if (Py_TYPE(wrapper)->tp_init(wrapper, args, kwargs)) - PyErr_Print(); - - Py_DECREF(args); - Py_DECREF(kwargs); - pyglib_gil_state_release(state); - } -} - - -/* This implementation is bad, see bug 566571 for an example why. - * Instead of scanning explicitly declared bases for interfaces, we - * should automatically initialize all implemented interfaces to - * prevent bugs like that one. However, this will lead to - * performance degradation as each virtual method in derived classes - * will round-trip through do_*() stuff, *even* if it is not - * overriden. We need to teach codegen to retain parent method - * instead of setting virtual to *_proxy_do_*() if corresponding - * do_*() is not overriden. Ok, that was a messy explanation. - */ -static void -pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, - PyObject *bases, - GType *parent_interfaces, guint n_parent_interfaces) -{ - int i; - - if (!bases) { - g_warning("type has no bases"); - return; - } - - for (i = 0; i < PyTuple_GET_SIZE(bases); ++i) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - GType itype; - const GInterfaceInfo *iinfo; - GInterfaceInfo iinfo_copy; - - /* 'base' can also be a PyClassObject, see bug #566571. */ - if (!PyType_Check(base)) - continue; - - if (!PyType_IsSubtype((PyTypeObject*) base, &PyGInterface_Type)) - continue; - - itype = pyg_type_from_object(base); - - /* Happens for _implementations_ of an interface. */ - if (!G_TYPE_IS_INTERFACE(itype)) - continue; - - iinfo = pyg_lookup_interface_info(itype); - if (!iinfo) { - gchar *error; - error = g_strdup_printf("Interface type %s " - "has no Python implementation support", - ((PyTypeObject *) base)->tp_name); - PyErr_Warn(PyExc_RuntimeWarning, error); - g_free(error); - continue; - } - - iinfo_copy = *iinfo; - iinfo_copy.interface_data = class; - g_type_add_interface_static(instance_type, itype, &iinfo_copy); - } -} - -int -pyg_type_register(PyTypeObject *class, const char *type_name) -{ - PyObject *gtype; - GType parent_type, instance_type; - GType *parent_interfaces; - guint n_parent_interfaces; - GTypeQuery query; - gpointer gclass; - GTypeInfo type_info = { - 0, /* class_size */ - - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - - (GClassInitFunc) pyg_object_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - - 0, /* instance_size */ - 0, /* n_preallocs */ - (GInstanceInitFunc) pygobject__g_instance_init - }; - gchar *new_type_name; - - /* find the GType of the parent */ - parent_type = pyg_type_from_object((PyObject *)class); - if (!parent_type) - return -1; - - parent_interfaces = g_type_interfaces(parent_type, &n_parent_interfaces); - - if (type_name) - /* care is taken below not to free this */ - new_type_name = (gchar *) type_name; - else - new_type_name = get_type_name_for_class(class); - - /* set class_data that will be passed to the class_init function. */ - type_info.class_data = class; - - /* fill in missing values of GTypeInfo struct */ - g_type_query(parent_type, &query); - type_info.class_size = query.class_size; - type_info.instance_size = query.instance_size; - - /* create new typecode */ - instance_type = g_type_register_static(parent_type, new_type_name, - &type_info, 0); - if (instance_type == 0) { - PyErr_Format(PyExc_RuntimeError, - "could not create new GType: %s (subclass of %s)", - new_type_name, - g_type_name(parent_type)); - - if (type_name == NULL) - g_free(new_type_name); - - return -1; - } - - if (type_name == NULL) - g_free(new_type_name); - - /* store pointer to the class with the GType */ - Py_INCREF(class); - g_type_set_qdata(instance_type, g_quark_from_string("PyGObject::class"), - class); - - /* Mark this GType as a custom python type */ - g_type_set_qdata(instance_type, pygobject_custom_key, - GINT_TO_POINTER (1)); - - /* set new value of __gtype__ on class */ - gtype = pyg_type_wrapper_new(instance_type); - PyObject_SetAttrString((PyObject *)class, "__gtype__", gtype); - Py_DECREF(gtype); - - /* if no __doc__, set it to the auto doc descriptor */ - if (PyDict_GetItemString(class->tp_dict, "__doc__") == NULL) { - PyDict_SetItemString(class->tp_dict, "__doc__", - pyg_object_descr_doc_get()); - } - - /* - * Note, all interfaces need to be registered before the first - * g_type_class_ref(), see bug #686149. - * - * See also comment above pyg_type_add_interfaces(). - */ - pyg_type_add_interfaces(class, instance_type, class->tp_bases, - parent_interfaces, n_parent_interfaces); - - - gclass = g_type_class_ref(instance_type); - if (PyErr_Occurred() != NULL) { - g_type_class_unref(gclass); - g_free(parent_interfaces); - return -1; - } - - if (pyg_run_class_init(instance_type, gclass, class)) { - g_type_class_unref(gclass); - g_free(parent_interfaces); - return -1; - } - g_type_class_unref(gclass); - g_free(parent_interfaces); - - if (PyErr_Occurred() != NULL) - return -1; - return 0; -} - -static PyObject * -pyg_signal_new(PyObject *self, PyObject *args) -{ - gchar *signal_name; - PyObject *py_type; - GSignalFlags signal_flags; - GType return_type; - PyObject *py_return_type, *py_param_types; - - GType instance_type = 0; - Py_ssize_t n_params, i; - GType *param_types; - - guint signal_id; - - if (!PyArg_ParseTuple(args, "sOiOO:gobject.signal_new", &signal_name, - &py_type, &signal_flags, &py_return_type, - &py_param_types)) - return NULL; - - instance_type = pyg_type_from_object(py_type); - if (!instance_type) - return NULL; - if (!(G_TYPE_IS_INSTANTIATABLE(instance_type) || G_TYPE_IS_INTERFACE(instance_type))) { - PyErr_SetString(PyExc_TypeError, - "argument 2 must be an object type or interface type"); - return NULL; - } - - return_type = pyg_type_from_object(py_return_type); - if (!return_type) - return NULL; - - if (!PySequence_Check(py_param_types)) { - PyErr_SetString(PyExc_TypeError, - "argument 5 must be a sequence of GType codes"); - return NULL; - } - n_params = PySequence_Length(py_param_types); - param_types = g_new(GType, n_params); - for (i = 0; i < n_params; i++) { - PyObject *item = PySequence_GetItem(py_param_types, i); - - param_types[i] = pyg_type_from_object(item); - if (param_types[i] == 0) { - PyErr_Clear(); - Py_DECREF(item); - PyErr_SetString(PyExc_TypeError, - "argument 5 must be a sequence of GType codes"); - g_free(param_types); - return NULL; - } - Py_DECREF(item); - } - - signal_id = g_signal_newv(signal_name, instance_type, signal_flags, - pyg_signal_class_closure_get(), - (GSignalAccumulator)0, NULL, - (GSignalCMarshaller)0, - return_type, n_params, param_types); - g_free(param_types); - if (signal_id != 0) - return PYGLIB_PyLong_FromLong(signal_id); - PyErr_SetString(PyExc_RuntimeError, "could not create signal"); - return NULL; -} - -static PyObject * -pyg_signal_query (PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist1[] = { "name", "type", NULL }; - static char *kwlist2[] = { "signal_id", NULL }; - PyObject *py_query, *params_list, *py_itype; - GObjectClass *class = NULL; - GType itype; - gchar *signal_name; - guint i; - GSignalQuery query; - guint id; - gpointer iface = NULL; - - if (PyArg_ParseTupleAndKeywords(args, kwargs, "sO:gobject.signal_query", - kwlist1, &signal_name, &py_itype)) { - if ((itype = pyg_type_from_object(py_itype)) == 0) - return NULL; - - if (G_TYPE_IS_INSTANTIATABLE(itype)) { - class = g_type_class_ref(itype); - if (!class) { - PyErr_SetString(PyExc_RuntimeError, - "could not get a reference to type class"); - return NULL; - } - } else if (!G_TYPE_IS_INTERFACE(itype)) { - PyErr_SetString(PyExc_TypeError, - "type must be instantiable or an interface"); - return NULL; - } else { - iface = g_type_default_interface_ref(itype); - } - id = g_signal_lookup(signal_name, itype); - } else { - PyErr_Clear(); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "i:gobject.signal_query", - kwlist2, &id)) { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, - "Usage: one of:\n" - " gobject.signal_query(name, type)\n" - " gobject.signal_query(signal_id)"); - - return NULL; - } - } - - g_signal_query(id, &query); - - if (query.signal_id == 0) { - Py_INCREF(Py_None); - py_query = Py_None; - goto done; - } - py_query = PyTuple_New(6); - if (py_query == NULL) { - goto done; - } - params_list = PyTuple_New(query.n_params); - if (params_list == NULL) { - Py_DECREF(py_query); - py_query = NULL; - goto done; - } - - PyTuple_SET_ITEM(py_query, 0, PYGLIB_PyLong_FromLong(query.signal_id)); - PyTuple_SET_ITEM(py_query, 1, PYGLIB_PyUnicode_FromString(query.signal_name)); - PyTuple_SET_ITEM(py_query, 2, pyg_type_wrapper_new(query.itype)); - PyTuple_SET_ITEM(py_query, 3, PYGLIB_PyLong_FromLong(query.signal_flags)); - PyTuple_SET_ITEM(py_query, 4, pyg_type_wrapper_new(query.return_type)); - for (i = 0; i < query.n_params; i++) { - PyTuple_SET_ITEM(params_list, i, - pyg_type_wrapper_new(query.param_types[i])); - } - PyTuple_SET_ITEM(py_query, 5, params_list); - - done: - if (class) - g_type_class_unref(class); - if (iface) - g_type_default_interface_unref(iface); - - return py_query; -} - -static PyObject * -pyg_object_class_list_properties (PyObject *self, PyObject *args) -{ - GParamSpec **specs; - PyObject *py_itype, *list; - GType itype; - GObjectClass *class = NULL; - gpointer iface = NULL; - guint nprops; - guint i; - - if (!PyArg_ParseTuple(args, "O:gobject.list_properties", - &py_itype)) - return NULL; - if ((itype = pyg_type_from_object(py_itype)) == 0) - return NULL; - - if (G_TYPE_IS_INTERFACE(itype)) { - iface = g_type_default_interface_ref(itype); - if (!iface) { - PyErr_SetString(PyExc_RuntimeError, - "could not get a reference to interface type"); - return NULL; - } - specs = g_object_interface_list_properties(iface, &nprops); - } else if (g_type_is_a(itype, G_TYPE_OBJECT)) { - class = g_type_class_ref(itype); - if (!class) { - PyErr_SetString(PyExc_RuntimeError, - "could not get a reference to type class"); - return NULL; - } - specs = g_object_class_list_properties(class, &nprops); - } else { - PyErr_SetString(PyExc_TypeError, - "type must be derived from GObject or an interface"); - return NULL; - } - - list = PyTuple_New(nprops); - if (list == NULL) { - g_free(specs); - g_type_class_unref(class); - return NULL; - } - for (i = 0; i < nprops; i++) { - PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i])); - } - g_free(specs); - if (class) - g_type_class_unref(class); - else - g_type_default_interface_unref(iface); - - return list; -} - -static PyObject * -pyg_object_new (PyGObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *pytype; - GType type; - GObject *obj = NULL; - GObjectClass *class; - guint n_params = 0, i; - GParameter *params = NULL; - - if (!PyArg_ParseTuple (args, "O:gobject.new", &pytype)) { - return NULL; - } - - if ((type = pyg_type_from_object (pytype)) == 0) - return NULL; - - if (G_TYPE_IS_ABSTRACT(type)) { - PyErr_Format(PyExc_TypeError, "cannot create instance of abstract " - "(non-instantiable) type `%s'", g_type_name(type)); - return NULL; - } - - if ((class = g_type_class_ref (type)) == NULL) { - PyErr_SetString(PyExc_TypeError, - "could not get a reference to type class"); - return NULL; - } - - if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms)) - goto cleanup; - - obj = g_object_newv(type, n_params, params); - if (!obj) - PyErr_SetString (PyExc_RuntimeError, "could not create object"); - - cleanup: - for (i = 0; i < n_params; i++) { - g_free((gchar *) params[i].name); - g_value_unset(¶ms[i].value); - } - g_free(params); - g_type_class_unref(class); - - if (obj) { - pygobject_sink (obj); - self = (PyGObject *) pygobject_new((GObject *)obj); - g_object_unref(obj); - } else - self = NULL; - - return (PyObject *) self; -} - -gboolean -pyg_handler_marshal(gpointer user_data) -{ - PyObject *tuple, *ret; - gboolean res; - PyGILState_STATE state; - - g_return_val_if_fail(user_data != NULL, FALSE); - - state = pyglib_gil_state_ensure(); - - tuple = (PyObject *)user_data; - ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), - PyTuple_GetItem(tuple, 1)); - if (!ret) { - PyErr_Print(); - res = FALSE; - } else { - res = PyObject_IsTrue(ret); - Py_DECREF(ret); - } - - pyglib_gil_state_release(state); - - return res; -} - -static int -pygobject_gil_state_ensure (void) -{ - return pyglib_gil_state_ensure (); -} - -static void -pygobject_gil_state_release (int flag) -{ - pyglib_gil_state_release(flag); -} - -/* Only for backwards compatibility */ -static int -pygobject_enable_threads(void) -{ - return 0; -} - -static PyObject * -pyg_signal_accumulator_true_handled(PyObject *unused, PyObject *args) -{ - PyErr_SetString(PyExc_TypeError, - "signal_accumulator_true_handled can only" - " be used as accumulator argument when registering signals"); - return NULL; -} - -static gboolean -marshal_emission_hook(GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer user_data) -{ - PyGILState_STATE state; - gboolean retval = FALSE; - PyObject *func, *args; - PyObject *retobj; - PyObject *params; - guint i; - - state = pyglib_gil_state_ensure(); - - /* construct Python tuple for the parameter values */ - params = PyTuple_New(n_param_values); - - for (i = 0; i < n_param_values; i++) { - PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); - - /* error condition */ - if (!item) { - goto out; - } - PyTuple_SetItem(params, i, item); - } - - args = (PyObject *)user_data; - func = PyTuple_GetItem(args, 0); - args = PySequence_Concat(params, PyTuple_GetItem(args, 1)); - Py_DECREF(params); - - /* params passed to function may have extra arguments */ - - retobj = PyObject_CallObject(func, args); - Py_DECREF(args); - if (retobj == NULL) { - PyErr_Print(); - } - - retval = (retobj == Py_True ? TRUE : FALSE); - Py_XDECREF(retobj); -out: - pyglib_gil_state_release(state); - return retval; -} - -static PyObject * -pyg_add_emission_hook(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *data, *repr; - gchar *name; - gulong hook_id; - guint sigid; - Py_ssize_t len; - GQuark detail = 0; - GType gtype; - PyObject *pygtype; - - len = PyTuple_Size(args); - if (len < 3) { - PyErr_SetString(PyExc_TypeError, - "gobject.add_emission_hook requires at least 3 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 3); - if (!PyArg_ParseTuple(first, "OsO:add_emission_hook", - &pygtype, &name, &callback)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - - if ((gtype = pyg_type_from_object(pygtype)) == 0) { - return NULL; - } - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "third argument must be callable"); - return NULL; - } - - if (!g_signal_parse_name(name, gtype, &sigid, &detail, TRUE)) { - repr = PyObject_Repr((PyObject*)self); - PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", - PYGLIB_PyUnicode_AsString(repr), - name); - Py_DECREF(repr); - return NULL; - } - extra_args = PySequence_GetSlice(args, 3, len); - if (extra_args == NULL) - return NULL; - - data = Py_BuildValue("(ON)", callback, extra_args); - if (data == NULL) - return NULL; - - hook_id = g_signal_add_emission_hook(sigid, detail, - marshal_emission_hook, - data, - (GDestroyNotify)pyg_destroy_notify); - - return PyLong_FromUnsignedLong(hook_id); -} - -static PyObject * -pyg__install_metaclass(PyObject *dummy, PyTypeObject *metaclass) -{ - Py_INCREF(metaclass); - PyGObject_MetaType = metaclass; - Py_INCREF(metaclass); - - Py_TYPE(&PyGObject_Type) = metaclass; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg__gvalue_get(PyObject *module, PyObject *pygvalue) -{ - if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) { - PyErr_SetString (PyExc_TypeError, "Expected GValue argument."); - return NULL; - } - - return pyg_value_as_pyobject (pyg_boxed_get(pygvalue, GValue), - /*copy_boxed=*/ TRUE); -} - -static PyObject * -pyg__gvalue_set(PyObject *module, PyObject *args) -{ - PyObject *pygvalue; - PyObject *pyobject; - - if (!PyArg_ParseTuple (args, "OO:_gobject._gvalue_set", - &pygvalue, &pyobject)) - return NULL; - - if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) { - PyErr_SetString (PyExc_TypeError, "Expected GValue argument."); - return NULL; - } - - if (pyg_value_from_pyobject_with_error (pyg_boxed_get (pygvalue, GValue), - pyobject) == -1) - return NULL; - - Py_RETURN_NONE; -} - -static PyMethodDef _gobject_functions[] = { - { "type_name", pyg_type_name, METH_VARARGS }, - { "type_from_name", pyg_type_from_name, METH_VARARGS }, - { "type_is_a", pyg_type_is_a, METH_VARARGS }, - { "type_register", _wrap_pyg_type_register, METH_VARARGS }, - { "signal_new", pyg_signal_new, METH_VARARGS }, - { "signal_query", - (PyCFunction)pyg_signal_query, METH_VARARGS|METH_KEYWORDS }, - { "list_properties", - pyg_object_class_list_properties, METH_VARARGS }, - { "new", - (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS }, - { "signal_accumulator_true_handled", - (PyCFunction)pyg_signal_accumulator_true_handled, METH_VARARGS }, - { "add_emission_hook", - (PyCFunction)pyg_add_emission_hook, METH_VARARGS }, - { "_install_metaclass", - (PyCFunction)pyg__install_metaclass, METH_O }, - { "_gvalue_get", - (PyCFunction)pyg__gvalue_get, METH_O }, - { "_gvalue_set", - (PyCFunction)pyg__gvalue_set, METH_VARARGS }, - - { NULL, NULL, 0 } -}; - - -/* ----------------- Constant extraction ------------------------ */ - -/** - * pyg_constant_strip_prefix: - * @name: the constant name. - * @strip_prefix: the prefix to strip. - * - * Advances the pointer @name by strlen(@strip_prefix) characters. If - * the resulting name does not start with a letter or underscore, the - * @name pointer will be rewound. This is to ensure that the - * resulting name is a valid identifier. Hence the returned string is - * a pointer into the string @name. - * - * Returns: the stripped constant name. - */ -const gchar * -pyg_constant_strip_prefix(const gchar *name, const gchar *strip_prefix) -{ - gint prefix_len; - guint i; - - prefix_len = strlen(strip_prefix); - - /* Check so name starts with strip_prefix, if it doesn't: - * return the rest of the part which doesn't match - */ - for (i = 0; i < prefix_len; i++) { - if (name[i] != strip_prefix[i] && name[i] != '_') { - return &name[i]; - } - } - - /* strip off prefix from value name, while keeping it a valid - * identifier */ - for (i = prefix_len; i >= 0; i--) { - if (g_ascii_isalpha(name[i]) || name[i] == '_') { - return &name[i]; - } - } - return name; -} - -/** - * pyg_enum_add_constants: - * @module: a Python module - * @enum_type: the GType of the enumeration. - * @strip_prefix: the prefix to strip from the constant names. - * - * Adds constants to the given Python module for each value name of - * the enumeration. A prefix will be stripped from each enum name. - */ -static void -pyg_enum_add_constants(PyObject *module, GType enum_type, - const gchar *strip_prefix) -{ - GEnumClass *eclass; - guint i; - - if (!G_TYPE_IS_ENUM(enum_type)) { - if (G_TYPE_IS_FLAGS(enum_type)) /* See bug #136204 */ - pyg_flags_add_constants(module, enum_type, strip_prefix); - else - g_warning("`%s' is not an enum type", g_type_name(enum_type)); - return; - } - g_return_if_fail (strip_prefix != NULL); - - eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); - - for (i = 0; i < eclass->n_values; i++) { - const gchar *name = eclass->values[i].value_name; - gint value = eclass->values[i].value; - - PyModule_AddIntConstant(module, - (char*) pyg_constant_strip_prefix(name, strip_prefix), - (long) value); - } - - g_type_class_unref(eclass); -} - -/** - * pyg_flags_add_constants: - * @module: a Python module - * @flags_type: the GType of the flags type. - * @strip_prefix: the prefix to strip from the constant names. - * - * Adds constants to the given Python module for each value name of - * the flags set. A prefix will be stripped from each flag name. - */ -static void -pyg_flags_add_constants(PyObject *module, GType flags_type, - const gchar *strip_prefix) -{ - GFlagsClass *fclass; - guint i; - - if (!G_TYPE_IS_FLAGS(flags_type)) { - if (G_TYPE_IS_ENUM(flags_type)) /* See bug #136204 */ - pyg_enum_add_constants(module, flags_type, strip_prefix); - else - g_warning("`%s' is not an flags type", g_type_name(flags_type)); - return; - } - g_return_if_fail (strip_prefix != NULL); - - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - - for (i = 0; i < fclass->n_values; i++) { - const gchar *name = fclass->values[i].value_name; - guint value = fclass->values[i].value; - - PyModule_AddIntConstant(module, - (char*) pyg_constant_strip_prefix(name, strip_prefix), - (long) value); - } - - g_type_class_unref(fclass); -} - -/** - * pyg_error_check: - * @error: a pointer to the GError. - * - * Checks to see if the GError has been set. If the error has been - * set, then the gobject.GError Python exception will be raised, and - * the GError cleared. - * - * Returns: True if an error was set. - * - * Deprecated: Since 2.16, use pyglib_error_check instead. - */ -gboolean -pyg_error_check(GError **error) -{ -#if 0 - if (PyErr_Warn(PyExc_DeprecationWarning, - "pyg_error_check is deprecated, use " - "pyglib_error_check instead")) - return NULL; -#endif - return pyglib_error_check(error); -} - -/** - * pyg_gerror_exception_check: - * @error: a standard GLib GError ** output parameter - * - * Checks to see if a GError exception has been raised, and if so - * translates the python exception to a standard GLib GError. If the - * raised exception is not a GError then PyErr_Print() is called. - * - * Returns: 0 if no exception has been raised, -1 if it is a - * valid gobject.GError, -2 otherwise. - * - * Deprecated: Since 2.16, use pyglib_gerror_exception_check instead. - */ -gboolean -pyg_gerror_exception_check(GError **error) -{ -#if 0 - if (PyErr_Warn(PyExc_DeprecationWarning, - "pyg_gerror_exception_check is deprecated, use " - "pyglib_gerror_exception_check instead")) - return NULL; -#endif - return pyglib_gerror_exception_check(error); -} - -/** - * pyg_parse_constructor_args: helper function for PyGObject constructors - * @obj_type: GType of the GObject, for parameter introspection - * @arg_names: %NULL-terminated array of constructor argument names - * @prop_names: %NULL-terminated array of property names, with direct - * correspondence to @arg_names - * @params: GParameter array where parameters will be placed; length - * of this array must be at least equal to the number of - * arguments/properties - * @nparams: output parameter to contain actual number of arguments found - * @py_args: array of PyObject* containing the actual constructor arguments - * - * Parses an array of PyObject's and creates a GParameter array - * - * Return value: %TRUE if all is successful, otherwise %FALSE and - * python exception set. - **/ -static gboolean -pyg_parse_constructor_args(GType obj_type, - char **arg_names, - char **prop_names, - GParameter *params, - guint *nparams, - PyObject **py_args) -{ - guint arg_i, param_i; - GObjectClass *oclass; - - oclass = g_type_class_ref(obj_type); - g_return_val_if_fail(oclass, FALSE); - - for (param_i = arg_i = 0; arg_names[arg_i]; ++arg_i) { - GParamSpec *spec; - if (!py_args[arg_i]) - continue; - spec = g_object_class_find_property(oclass, prop_names[arg_i]); - params[param_i].name = prop_names[arg_i]; - g_value_init(¶ms[param_i].value, spec->value_type); - if (pyg_value_from_pyobject(¶ms[param_i].value, py_args[arg_i]) == -1) { - int i; - PyErr_Format(PyExc_TypeError, "could not convert parameter '%s' of type '%s'", - arg_names[arg_i], g_type_name(spec->value_type)); - g_type_class_unref(oclass); - for (i = 0; i < param_i; ++i) - g_value_unset(¶ms[i].value); - return FALSE; - } - ++param_i; - } - g_type_class_unref(oclass); - *nparams = param_i; - return TRUE; -} - -PyObject * -pyg_integer_richcompare(PyObject *v, PyObject *w, int op) -{ - PyObject *result; - gboolean t; - - switch (op) { - case Py_EQ: t = PYGLIB_PyLong_AS_LONG(v) == PYGLIB_PyLong_AS_LONG(w); break; - case Py_NE: t = PYGLIB_PyLong_AS_LONG(v) != PYGLIB_PyLong_AS_LONG(w); break; - case Py_LE: t = PYGLIB_PyLong_AS_LONG(v) <= PYGLIB_PyLong_AS_LONG(w); break; - case Py_GE: t = PYGLIB_PyLong_AS_LONG(v) >= PYGLIB_PyLong_AS_LONG(w); break; - case Py_LT: t = PYGLIB_PyLong_AS_LONG(v) < PYGLIB_PyLong_AS_LONG(w); break; - case Py_GT: t = PYGLIB_PyLong_AS_LONG(v) > PYGLIB_PyLong_AS_LONG(w); break; - default: g_assert_not_reached(); - } - - result = t ? Py_True : Py_False; - Py_INCREF(result); - return result; -} - -static void -_log_func(const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer user_data) -{ - if (G_LIKELY(Py_IsInitialized())) - { - PyGILState_STATE state; - PyObject* warning = user_data; - - state = pyglib_gil_state_ensure(); - PyErr_Warn(warning, (char *) message); - pyglib_gil_state_release(state); - } else - g_log_default_handler(log_domain, log_level, message, user_data); -} - -static void -add_warning_redirection(const char *domain, - PyObject *warning) -{ - g_return_if_fail(domain != NULL); - g_return_if_fail(warning != NULL); - - if (!log_handlers_disabled) - { - guint handler; - gpointer old_handler; - - if (!log_handlers) - log_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - - if ((old_handler = g_hash_table_lookup(log_handlers, domain))) - g_log_remove_handler(domain, GPOINTER_TO_UINT(old_handler)); - - handler = g_log_set_handler(domain, G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING, - _log_func, warning); - g_hash_table_insert(log_handlers, g_strdup(domain), GUINT_TO_POINTER(handler)); - } -} - -static void -remove_handler(gpointer domain, - gpointer handler, - gpointer unused) -{ - g_log_remove_handler(domain, GPOINTER_TO_UINT(handler)); -} - -static void -disable_warning_redirections(void) -{ - log_handlers_disabled = TRUE; - - if (log_handlers) - { - g_hash_table_foreach(log_handlers, remove_handler, NULL); - g_hash_table_destroy(log_handlers); - log_handlers = NULL; - } -} - -/* ----------------- gobject module initialisation -------------- */ - -struct _PyGObject_Functions pygobject_api_functions = { - pygobject_register_class, - pygobject_register_wrapper, - pygobject_lookup_class, - pygobject_new, - - pyg_closure_new, - pygobject_watch_closure, - pyg_destroy_notify, - - pyg_type_from_object, - pyg_type_wrapper_new, - pyg_enum_get_value, - pyg_flags_get_value, - pyg_register_gtype_custom, - pyg_value_from_pyobject, - pyg_value_as_pyobject, - - pyg_register_interface, - - &PyGBoxed_Type, - pyg_register_boxed, - pyg_boxed_new, - - &PyGPointer_Type, - pyg_register_pointer, - pyg_pointer_new, - - pyg_enum_add_constants, - pyg_flags_add_constants, - - pyg_constant_strip_prefix, - - pyg_error_check, - - _pyg_set_thread_block_funcs, - (PyGThreadBlockFunc)0, /* block_threads */ - (PyGThreadBlockFunc)0, /* unblock_threads */ - - &PyGParamSpec_Type, - pyg_param_spec_new, - pyg_param_spec_from_object, - - pyg_pyobj_to_unichar_conv, - pyg_parse_constructor_args, - pyg_param_gvalue_as_pyobject, - pyg_param_gvalue_from_pyobject, - - &PyGEnum_Type, - pyg_enum_add, - pyg_enum_from_gtype, - - &PyGFlags_Type, - pyg_flags_add, - pyg_flags_from_gtype, - - /* threads_enabled */ -#ifdef DISABLE_THREADING - FALSE, -#else - TRUE, -#endif - - pygobject_enable_threads, - pygobject_gil_state_ensure, - pygobject_gil_state_release, - pyg_register_class_init, - pyg_register_interface_info, - - pyg_closure_set_exception_handler, - - add_warning_redirection, - disable_warning_redirections, - - NULL, /* previously type_register_custom */ - - pyg_gerror_exception_check, - - pyglib_option_group_new, - pyg_type_from_object_strict, - - pygobject_new_full, - &PyGObject_Type, - - pyg_value_from_pyobject_with_error -}; - -/* for addon libraries ... */ -static void -pygobject_register_api(PyObject *d) -{ - PyObject *api; - - api = PYGLIB_CPointer_WrapPointer(&pygobject_api_functions, "gobject._PyGObject_API"); - PyDict_SetItemString(d, "_PyGObject_API", api); - Py_DECREF(api); -} - -/* some constants */ -static void -pygobject_register_constants(PyObject *m) -{ - /* PyFloat_ return a new ref, and add object takes the ref */ - PyModule_AddObject(m, "G_MINFLOAT", PyFloat_FromDouble(G_MINFLOAT)); - PyModule_AddObject(m, "G_MAXFLOAT", PyFloat_FromDouble(G_MAXFLOAT)); - PyModule_AddObject(m, "G_MINDOUBLE", PyFloat_FromDouble(G_MINDOUBLE)); - PyModule_AddObject(m, "G_MAXDOUBLE", PyFloat_FromDouble(G_MAXDOUBLE)); - PyModule_AddIntConstant(m, "G_MINSHORT", G_MINSHORT); - PyModule_AddIntConstant(m, "G_MAXSHORT", G_MAXSHORT); - PyModule_AddIntConstant(m, "G_MAXUSHORT", G_MAXUSHORT); - PyModule_AddIntConstant(m, "G_MININT", G_MININT); - PyModule_AddIntConstant(m, "G_MAXINT", G_MAXINT); - PyModule_AddObject(m, "G_MAXUINT", PyLong_FromUnsignedLong(G_MAXUINT)); - PyModule_AddObject(m, "G_MINLONG", PyLong_FromLong(G_MINLONG)); - PyModule_AddObject(m, "G_MAXLONG", PyLong_FromLong(G_MAXLONG)); - PyModule_AddObject(m, "G_MAXULONG", PyLong_FromUnsignedLong(G_MAXULONG)); - PyModule_AddObject(m, "G_MAXSIZE", PyLong_FromSize_t(G_MAXSIZE)); - PyModule_AddObject(m, "G_MAXSSIZE", PyLong_FromSsize_t(G_MAXSSIZE)); - PyModule_AddObject(m, "G_MINSSIZE", PyLong_FromSsize_t(G_MINSSIZE)); - PyModule_AddObject(m, "G_MINOFFSET", PyLong_FromLongLong(G_MINOFFSET)); - PyModule_AddObject(m, "G_MAXOFFSET", PyLong_FromLongLong(G_MAXOFFSET)); - - PyModule_AddIntConstant(m, "SIGNAL_RUN_FIRST", G_SIGNAL_RUN_FIRST); - PyModule_AddIntConstant(m, "PARAM_READWRITE", G_PARAM_READWRITE); - - /* The rest of the types are set in __init__.py */ - PyModule_AddObject(m, "TYPE_INVALID", pyg_type_wrapper_new(G_TYPE_INVALID)); - PyModule_AddObject(m, "TYPE_GSTRING", pyg_type_wrapper_new(G_TYPE_GSTRING)); -} - -/* features */ -static void -pygobject_register_features(PyObject *d) -{ - PyObject *features; - - features = PyDict_New(); - PyDict_SetItemString(features, "generic-c-marshaller", Py_True); - PyDict_SetItemString(d, "features", features); - Py_DECREF(features); -} - -static void -pygobject_register_version_tuples(PyObject *d) -{ - PyObject *tuple; - - /* pygobject version */ - tuple = Py_BuildValue ("(iii)", - PYGOBJECT_MAJOR_VERSION, - PYGOBJECT_MINOR_VERSION, - PYGOBJECT_MICRO_VERSION); - PyDict_SetItemString(d, "pygobject_version", tuple); -} - -static void -pygobject_register_warnings(PyObject *d) -{ - PyObject *warning; - - warning = PyErr_NewException("gobject.Warning", PyExc_Warning, NULL); - PyDict_SetItemString(d, "Warning", warning); - add_warning_redirection("GLib", warning); - add_warning_redirection("GLib-GObject", warning); - add_warning_redirection("GThread", warning); -} - - -PYGLIB_MODULE_START(_gobject, "_gobject") -{ - PyObject *d; - - pyglib_init(); - - d = PyModule_GetDict(module); - pygobject_register_api(d); - pygobject_register_constants(module); - pygobject_register_features(d); - pygobject_register_version_tuples(d); - pygobject_register_warnings(d); - pygobject_type_register_types(d); - pygobject_object_register_types(d); - pygobject_interface_register_types(d); - pygobject_paramspec_register_types(d); - pygobject_boxed_register_types(d); - pygobject_pointer_register_types(d); - pygobject_enum_register_types(d); - pygobject_flags_register_types(d); -} -PYGLIB_MODULE_END diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py deleted file mode 100644 index c9400df..0000000 --- a/gi/_gobject/propertyhelper.py +++ /dev/null @@ -1,411 +0,0 @@ -# -*- Mode: Python; py-indent-offset: 4 -*- -# pygobject - Python bindings for the GObject library -# Copyright (C) 2007 Johan Dahlin -# -# gobject/propertyhelper.py: GObject property wrapper/helper -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -import sys - -from . import _gobject - -from .constants import \ - TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, \ - TYPE_BOOLEAN, TYPE_INT, TYPE_UINT, TYPE_LONG, \ - TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, TYPE_FLAGS, \ - TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \ - TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \ - TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT -from ._gobject import \ - G_MAXFLOAT, G_MAXDOUBLE, \ - G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \ - G_MAXULONG - -if sys.version_info >= (3, 0): - _basestring = str - _long = int -else: - _basestring = basestring - _long = long - - -class Property(object): - """ - Creates a new property which in conjunction with GObject subclass will - create a property proxy: - - class MyObject(GObject.GObject): - ... prop = GObject.Property(type=str) - - obj = MyObject() - obj.prop = 'value' - - obj.prop # now is 'value' - - The API is similar to the builtin property: - - class AnotherObject(GObject.GObject): - @GObject.Property - def prop(self): - '''Read only property.''' - return ... - - @GObject.Property(type=int) - def propInt(self): - '''Read-write integer property.''' - return ... - - @propInt.setter - def propInt(self, value): - ... - """ - _type_from_pytype_lookup = { - # Put long_ first in case long_ and int are the same so int clobbers long_ - _long: TYPE_LONG, - int: TYPE_INT, - bool: TYPE_BOOLEAN, - float: TYPE_DOUBLE, - str: TYPE_STRING, - object: TYPE_PYOBJECT, - } - - _min_value_lookup = { - TYPE_UINT: 0, - TYPE_ULONG: 0, - TYPE_UINT64: 0, - # Remember that G_MINFLOAT and G_MINDOUBLE are something different. - TYPE_FLOAT: -G_MAXFLOAT, - TYPE_DOUBLE: -G_MAXDOUBLE, - TYPE_INT: G_MININT, - TYPE_LONG: G_MINLONG, - TYPE_INT64: -2 ** 63, - } - - _max_value_lookup = { - TYPE_UINT: G_MAXUINT, - TYPE_ULONG: G_MAXULONG, - TYPE_INT64: 2 ** 63 - 1, - TYPE_UINT64: 2 ** 64 - 1, - TYPE_FLOAT: G_MAXFLOAT, - TYPE_DOUBLE: G_MAXDOUBLE, - TYPE_INT: G_MAXINT, - TYPE_LONG: G_MAXLONG, - } - - _default_lookup = { - TYPE_INT: 0, - TYPE_UINT: 0, - TYPE_LONG: 0, - TYPE_ULONG: 0, - TYPE_INT64: 0, - TYPE_UINT64: 0, - TYPE_STRING: '', - TYPE_FLOAT: 0.0, - TYPE_DOUBLE: 0.0, - } - - class __metaclass__(type): - def __repr__(self): - return "" - - def __init__(self, getter=None, setter=None, type=None, default=None, - nick='', blurb='', flags=_gobject.PARAM_READWRITE, - minimum=None, maximum=None): - """ - @param getter: getter to get the value of the property - @type getter: callable - @param setter: setter to set the value of the property - @type setter: callable - @param type: type of property - @type type: type - @param default: default value - @param nick: short description - @type nick: string - @param blurb: long description - @type blurb: string - @param flags: parameter flags, one of: - - gobject.PARAM_READABLE - - gobject.PARAM_READWRITE - - gobject.PARAM_WRITABLE - - gobject.PARAM_CONSTRUCT - - gobject.PARAM_CONSTRUCT_ONLY - - gobject.PARAM_LAX_VALIDATION - @keyword minimum: minimum allowed value (int, float, long only) - @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) - self.default = self._get_default(default) - self._check_default() - - if not isinstance(nick, _basestring): - raise TypeError("nick must be a string") - self.nick = nick - - if not isinstance(blurb, _basestring): - raise TypeError("blurb must be a string") - self.blurb = blurb - # Always clobber __doc__ with blurb even if blurb is empty because - # we don't want the lengthy Property class documentation showing up - # on instances. - self.__doc__ = blurb - self.flags = flags - - # Call after setting blurb for potential __doc__ usage. - if getter and not setter: - setter = self._readonly_setter - elif setter and not getter: - getter = self._writeonly_getter - elif not setter and not getter: - getter = self._default_getter - setter = self._default_setter - self.getter(getter) - # 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(): - raise TypeError( - "Minimum for type %s cannot be lower than %d" % - (self.type, self._get_minimum())) - else: - minimum = self._get_minimum() - self.minimum = minimum - if maximum is not None: - if maximum > self._get_maximum(): - raise TypeError( - "Maximum for type %s cannot be higher than %d" % - (self.type, self._get_maximum())) - else: - maximum = self._get_maximum() - self.maximum = maximum - - self._exc = None - - def __repr__(self): - return '' % ( - self.name or '(uninitialized)', - _gobject.type_name(self.type)) - - def __get__(self, instance, klass): - if instance is None: - return self - - self._exc = None - value = instance.get_property(self.name) - if self._exc: - exc = self._exc - self._exc = None - raise exc - - return value - - def __set__(self, instance, value): - if instance is None: - raise TypeError - - self._exc = None - instance.set_property(self.name, value) - if self._exc: - exc = self._exc - self._exc = None - raise exc - - def __call__(self, fget): - """Allows application of the getter along with init arguments.""" - return self.getter(fget) - - def getter(self, fget): - """Set the getter function to fget. For use as a decorator.""" - if fget.__doc__: - # Always clobber docstring and blurb with the getter docstring. - self.blurb = fget.__doc__ - self.__doc__ = fget.__doc__ - self.fget = fget - return self - - 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_): - if type_ in self._type_from_pytype_lookup: - return self._type_from_pytype_lookup[type_] - elif (isinstance(type_, type) and - issubclass(type_, (_gobject.GObject, - _gobject.GEnum, - _gobject.GFlags, - _gobject.GBoxed, - _gobject.GInterface))): - return type_.__gtype__ - elif type_ in (TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, - TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG, - TYPE_ULONG, TYPE_INT64, TYPE_UINT64, - TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER, - TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING, - TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT): - return type_ - else: - raise TypeError("Unsupported type: %r" % (type_,)) - - def _get_default(self, default): - if default is not None: - return default - return self._default_lookup.get(self.type, None) - - def _check_default(self): - ptype = self.type - default = self.default - if (ptype == TYPE_BOOLEAN and (default not in (True, False))): - raise TypeError( - "default must be True or False, not %r" % (default,)) - elif ptype == TYPE_PYOBJECT: - if default is not None: - raise TypeError("object types does not have default values") - elif ptype == TYPE_GTYPE: - if default is not None: - raise TypeError("GType types does not have default values") - elif _gobject.type_is_a(ptype, TYPE_ENUM): - if default is None: - raise TypeError("enum properties needs a default value") - elif not _gobject.type_is_a(default, ptype): - raise TypeError("enum value %s must be an instance of %r" % - (default, ptype)) - elif _gobject.type_is_a(ptype, TYPE_FLAGS): - if not _gobject.type_is_a(default, ptype): - raise TypeError("flags value %s must be an instance of %r" % - (default, ptype)) - elif _gobject.type_is_a(ptype, TYPE_STRV) and default is not None: - if not isinstance(default, list): - raise TypeError("Strv value %s must be a list" % repr(default)) - for val in default: - if type(val) not in (str, bytes): - raise TypeError("Strv value %s must contain only strings" % str(default)) - elif _gobject.type_is_a(ptype, TYPE_VARIANT) and default is not None: - if not hasattr(default, '__gtype__') or not _gobject.type_is_a(default, TYPE_VARIANT): - raise TypeError("variant value %s must be an instance of %r" % - (default, ptype)) - - def _get_minimum(self): - return self._min_value_lookup.get(self.type, None) - - def _get_maximum(self): - return self._max_value_lookup.get(self.type, None) - - # - # Getter and Setter - # - - def _default_setter(self, instance, value): - setattr(instance, '_property_helper_' + self.name, value) - - def _default_getter(self, instance): - return getattr(instance, '_property_helper_' + self.name, self.default) - - def _readonly_setter(self, instance, value): - self._exc = TypeError("%s property of %s is read-only" % ( - self.name, type(instance).__name__)) - - def _writeonly_getter(self, instance): - self._exc = TypeError("%s property of %s is write-only" % ( - self.name, type(instance).__name__)) - - # - # Public API - # - - def get_pspec_args(self): - ptype = self.type - if ptype in (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, - TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE): - args = self.minimum, self.maximum, self.default - elif (ptype == TYPE_STRING or ptype == TYPE_BOOLEAN or - ptype.is_a(TYPE_ENUM) or ptype.is_a(TYPE_FLAGS) or - ptype.is_a(TYPE_VARIANT)): - args = (self.default,) - elif ptype in (TYPE_PYOBJECT, TYPE_GTYPE): - args = () - elif ptype.is_a(TYPE_OBJECT) or ptype.is_a(TYPE_BOXED): - args = () - else: - raise NotImplementedError(ptype) - - return (self.type, self.nick, self.blurb) + args + (self.flags,) - - -def install_properties(cls): - """ - Scans the given class for instances of Property and merges them - into the classes __gproperties__ dict if it exists or adds it if not. - """ - gproperties = cls.__dict__.get('__gproperties__', {}) - - props = [] - for name, prop in cls.__dict__.items(): - if isinstance(prop, Property): # not same as the built-in - # 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: - return - - cls.__gproperties__ = gproperties - - if 'do_get_property' in cls.__dict__ or 'do_set_property' in cls.__dict__: - for prop in props: - if prop.fget != prop._default_getter or prop.fset != prop._default_setter: - raise TypeError( - "GObject subclass %r defines do_get/set_property" - " and it also uses a property with a custom setter" - " or getter. This is not allowed" % - (cls.__name__,)) - - def obj_get_property(self, pspec): - name = pspec.name.replace('-', '_') - prop = getattr(cls, name, None) - if prop: - return prop.fget(self) - cls.do_get_property = obj_get_property - - def obj_set_property(self, pspec, value): - name = pspec.name.replace('-', '_') - prop = getattr(cls, name, None) - if prop: - prop.fset(self, value) - cls.do_set_property = obj_set_property diff --git a/gi/_gobject/pygboxed.c b/gi/_gobject/pygboxed.c deleted file mode 100644 index 541e77b..0000000 --- a/gi/_gobject/pygboxed.c +++ /dev/null @@ -1,235 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * pygboxed.c: wrapper for GBoxed - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pygobject-private.h" -#include "pygboxed.h" - -#include "pygi.h" - -GQuark pygboxed_type_key; -GQuark pygboxed_marshal_key; - -PYGLIB_DEFINE_TYPE("gobject.GBoxed", PyGBoxed_Type, PyGBoxed); - -static void -pyg_boxed_dealloc(PyGBoxed *self) -{ - if (self->free_on_dealloc && self->boxed) { - PyGILState_STATE state = pyglib_gil_state_ensure(); - g_boxed_free(self->gtype, self->boxed); - pyglib_gil_state_release(state); - } - - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject* -pyg_boxed_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other) && - PyObject_IsInstance(self, (PyObject*)&PyGBoxed_Type)) - return _pyglib_generic_ptr_richcompare(((PyGBoxed*)self)->boxed, - ((PyGBoxed*)other)->boxed, - op); - else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - - -static long -pyg_boxed_hash(PyGBoxed *self) -{ - return (long)self->boxed; -} - -static PyObject * -pyg_boxed_repr(PyGBoxed *self) -{ - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "<%s at 0x%lx>", g_type_name(self->gtype), - (long)self->boxed); - return PYGLIB_PyUnicode_FromString(buf); -} - -static int -pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs) -{ - gchar buf[512]; - - if (!PyArg_ParseTuple(args, ":GBoxed.__init__")) - return -1; - - self->boxed = NULL; - self->gtype = 0; - self->free_on_dealloc = FALSE; - - g_snprintf(buf, sizeof(buf), "%s can not be constructed", - Py_TYPE(self)->tp_name); - PyErr_SetString(PyExc_NotImplementedError, buf); - return -1; -} - -static void -pyg_boxed_free(PyObject *op) -{ - PyObject_FREE(op); -} - -static PyObject * -pyg_boxed_copy(PyGBoxed *self) -{ - return pyg_boxed_new (self->gtype, self->boxed, TRUE, TRUE); -} - - - -static PyMethodDef pygboxed_methods[] = { - { "copy", (PyCFunction) pyg_boxed_copy, METH_NOARGS }, - { NULL, NULL, 0 } -}; - - -/** - * pyg_register_boxed: - * @dict: the module dictionary to store the wrapper class. - * @class_name: the Python name for the wrapper class. - * @boxed_type: the GType of the boxed type being wrapped. - * @type: the wrapper class. - * - * Registers a wrapper for a boxed type. The wrapper class will be a - * subclass of gobject.GBoxed, and a reference to the wrapper class - * will be stored in the provided module dictionary. - */ -void -pyg_register_boxed(PyObject *dict, const gchar *class_name, - GType boxed_type, PyTypeObject *type) -{ - PyObject *o; - - g_return_if_fail(dict != NULL); - g_return_if_fail(class_name != NULL); - g_return_if_fail(boxed_type != 0); - - if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc; - - Py_TYPE(type) = &PyType_Type; - type->tp_base = &PyGBoxed_Type; - - if (PyType_Ready(type) < 0) { - g_warning("could not get type `%s' ready", type->tp_name); - return; - } - - PyDict_SetItemString(type->tp_dict, "__gtype__", - o=pyg_type_wrapper_new(boxed_type)); - Py_DECREF(o); - - g_type_set_qdata(boxed_type, pygboxed_type_key, type); - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); -} - -/** - * pyg_boxed_new: - * @boxed_type: the GType of the boxed value. - * @boxed: the boxed value. - * @copy_boxed: whether the new boxed wrapper should hold a copy of the value. - * @own_ref: whether the boxed wrapper should own the boxed value. - * - * Creates a wrapper for a boxed value. If @copy_boxed is set to - * True, the wrapper will hold a copy of the value, instead of the - * value itself. If @own_ref is True, then the value held by the - * wrapper will be freed when the wrapper is deallocated. If - * @copy_boxed is True, then @own_ref must also be True. - * - * Returns: the boxed wrapper. - */ -PyObject * -pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, - gboolean own_ref) -{ - PyGILState_STATE state; - PyGBoxed *self; - PyTypeObject *tp; - - g_return_val_if_fail(boxed_type != 0, NULL); - g_return_val_if_fail(!copy_boxed || (copy_boxed && own_ref), NULL); - - state = pyglib_gil_state_ensure(); - - if (!boxed) { - Py_INCREF(Py_None); - pyglib_gil_state_release(state); - return Py_None; - } - - tp = g_type_get_qdata(boxed_type, pygboxed_type_key); - - if (!tp) - tp = (PyTypeObject *)pygi_type_import_by_g_type(boxed_type); - - if (!tp) - tp = (PyTypeObject *)&PyGBoxed_Type; /* fallback */ - - self = (PyGBoxed *)tp->tp_alloc(tp, 0); - - if (self == NULL) { - pyglib_gil_state_release(state); - return NULL; - } - - if (copy_boxed) - boxed = g_boxed_copy(boxed_type, boxed); - self->boxed = boxed; - self->gtype = boxed_type; - self->free_on_dealloc = own_ref; - - pyglib_gil_state_release(state); - - return (PyObject *)self; -} - -void -pygobject_boxed_register_types(PyObject *d) -{ - pygboxed_type_key = g_quark_from_static_string("PyGBoxed::class"); - pygboxed_marshal_key = g_quark_from_static_string("PyGBoxed::marshal"); - - PyGBoxed_Type.tp_dealloc = (destructor)pyg_boxed_dealloc; - PyGBoxed_Type.tp_richcompare = pyg_boxed_richcompare; - PyGBoxed_Type.tp_repr = (reprfunc)pyg_boxed_repr; - PyGBoxed_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGBoxed_Type.tp_methods = pygboxed_methods; - PyGBoxed_Type.tp_init = (initproc)pyg_boxed_init; - PyGBoxed_Type.tp_free = (freefunc)pyg_boxed_free; - PyGBoxed_Type.tp_hash = (hashfunc)pyg_boxed_hash; - - PYGOBJECT_REGISTER_GTYPE(d, PyGBoxed_Type, "GBoxed", G_TYPE_BOXED); -} diff --git a/gi/_gobject/pygboxed.h b/gi/_gobject/pygboxed.h deleted file mode 100644 index 8433b9d..0000000 --- a/gi/_gobject/pygboxed.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_BOXED_H__ -#define __PYGOBJECT_BOXED_H__ - -void pygobject_boxed_register_types(PyObject *d); - -#endif /* __PYGOBJECT_BOXED_H__ */ diff --git a/gi/_gobject/pygenum.c b/gi/_gobject/pygenum.c deleted file mode 100644 index 89e3a06..0000000 --- a/gi/_gobject/pygenum.c +++ /dev/null @@ -1,371 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * Copyright (C) 2004 Johan Dahlin - * - * pygenum.c: GEnum wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pygobject-private.h" -#include "pygi.h" - -#include "pygenum.h" - -GQuark pygenum_class_key; - -PYGLIB_DEFINE_TYPE("gobject.GEnum", PyGEnum_Type, PyGEnum); - -static PyObject * -pyg_enum_val_new(PyObject* subclass, GType gtype, PyObject *intval) -{ - PyObject *args, *item; - args = Py_BuildValue("(O)", intval); - item = (&PYGLIB_PyLong_Type)->tp_new((PyTypeObject*)subclass, args, NULL); - Py_DECREF(args); - if (!item) - return NULL; - ((PyGEnum*)item)->gtype = gtype; - - return item; -} - -static PyObject * -pyg_enum_richcompare(PyGEnum *self, PyObject *other, int op) -{ - static char warning[256]; - - if (!PYGLIB_PyLong_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (PyObject_TypeCheck(other, &PyGEnum_Type) && ((PyGEnum*)other)->gtype != self->gtype) { - g_snprintf(warning, sizeof(warning), "comparing different enum types: %s and %s", - g_type_name(self->gtype), g_type_name(((PyGEnum*)other)->gtype)); - if (PyErr_Warn(PyExc_Warning, warning)) - return NULL; - } - - return pyg_integer_richcompare((PyObject *)self, other, op); -} - -static PyObject * -pyg_enum_repr(PyGEnum *self) -{ - GEnumClass *enum_class; - const char *value; - guint index; - static char tmp[256]; - long l; - - enum_class = g_type_class_ref(self->gtype); - g_assert(G_IS_ENUM_CLASS(enum_class)); - - l = PYGLIB_PyLong_AS_LONG(self); - for (index = 0; index < enum_class->n_values; index++) - if (l == enum_class->values[index].value) - break; - - value = enum_class->values[index].value_name; - if (value) - sprintf(tmp, "", value, g_type_name(self->gtype)); - else - sprintf(tmp, "", PYGLIB_PyLong_AS_LONG(self), g_type_name(self->gtype)); - - g_type_class_unref(enum_class); - - return PYGLIB_PyUnicode_FromString(tmp); -} - -static PyObject * -pyg_enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "value", NULL }; - long value; - PyObject *pytc, *values, *ret, *intvalue; - GType gtype; - GEnumClass *eclass; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "l", kwlist, &value)) - return NULL; - - pytc = PyObject_GetAttrString((PyObject *)type, "__gtype__"); - if (!pytc) - return NULL; - - if (!PyObject_TypeCheck(pytc, &PyGTypeWrapper_Type)) { - Py_DECREF(pytc); - PyErr_SetString(PyExc_TypeError, - "__gtype__ attribute not a typecode"); - return NULL; - } - - gtype = pyg_type_from_object(pytc); - Py_DECREF(pytc); - - eclass = G_ENUM_CLASS(g_type_class_ref(gtype)); - - /* A check that 0 < value < eclass->n_values was here but got - * removed: enumeration values do not need to be consequitive, - * e.g. GtkPathPriorityType values are not. - */ - - values = PyObject_GetAttrString((PyObject *)type, "__enum_values__"); - if (!values) { - g_type_class_unref(eclass); - return NULL; - } - - /* Note that size of __enum_values__ dictionary can easily be less - * than 'n_values'. This happens if some values of the enum are - * numerically equal, e.g. gtk.ANCHOR_N == gtk.ANCHOR_NORTH. - * Johan said that "In retrospect, using a dictionary to store the - * values might not have been that good", but we need to keep - * backward compatibility. - */ - if (!PyDict_Check(values) || PyDict_Size(values) > eclass->n_values) { - PyErr_SetString(PyExc_TypeError, "__enum_values__ badly formed"); - Py_DECREF(values); - g_type_class_unref(eclass); - return NULL; - } - - g_type_class_unref(eclass); - - intvalue = PYGLIB_PyLong_FromLong(value); - ret = PyDict_GetItem(values, intvalue); - Py_DECREF(intvalue); - Py_DECREF(values); - if (ret) - Py_INCREF(ret); - else - PyErr_Format(PyExc_ValueError, "invalid enum value: %ld", value); - - return ret; -} - -PyObject* -pyg_enum_from_gtype (GType gtype, int value) -{ - PyObject *pyclass, *values, *retval, *intvalue; - - g_return_val_if_fail(gtype != G_TYPE_INVALID, NULL); - - /* Get a wrapper class by: - * 1. check for one attached to the gtype - * 2. lookup one in a typelib - * 3. creating a new one - */ - pyclass = (PyObject*)g_type_get_qdata(gtype, pygenum_class_key); - if (!pyclass) - pyclass = pygi_type_import_by_g_type(gtype); - if (!pyclass) - pyclass = pyg_enum_add(NULL, g_type_name(gtype), NULL, gtype); - if (!pyclass) - return PYGLIB_PyLong_FromLong(value); - - values = PyDict_GetItemString(((PyTypeObject *)pyclass)->tp_dict, - "__enum_values__"); - intvalue = PYGLIB_PyLong_FromLong(value); - retval = PyDict_GetItem(values, intvalue); - if (retval) { - Py_INCREF(retval); - } - else { - PyErr_Clear(); - retval = pyg_enum_val_new(pyclass, gtype, intvalue); - } - Py_DECREF(intvalue); - - return retval; -} - -/* - * pyg_enum_add - * Dynamically create a class derived from PyGEnum based on the given GType. - */ -PyObject * -pyg_enum_add (PyObject * module, - const char * typename, - const char * strip_prefix, - GType gtype) -{ - PyGILState_STATE state; - PyObject *instance_dict, *stub, *values, *o; - GEnumClass *eclass; - int i; - - g_return_val_if_fail(typename != NULL, NULL); - 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; - } - - state = pyglib_gil_state_ensure(); - - /* Create a new type derived from GEnum. This is the same as: - * >>> stub = type(typename, (GEnum,), {}) - */ - instance_dict = PyDict_New(); - stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", - typename, (PyObject *)&PyGEnum_Type, - instance_dict); - Py_DECREF(instance_dict); - if (!stub) { - PyErr_SetString(PyExc_RuntimeError, "can't create const"); - pyglib_gil_state_release(state); - return NULL; - } - - ((PyTypeObject *)stub)->tp_flags &= ~Py_TPFLAGS_BASETYPE; - ((PyTypeObject *)stub)->tp_new = pyg_enum_new; - - if (module) - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, - "__module__", - PYGLIB_PyUnicode_FromString(PyModule_GetName(module))); - - g_type_set_qdata(gtype, pygenum_class_key, stub); - - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, "__gtype__", o); - Py_DECREF(o); - - if (module) { - /* Add it to the module name space */ - PyModule_AddObject(module, (char*)typename, stub); - Py_INCREF(stub); - } - - /* Register enum values */ - eclass = G_ENUM_CLASS(g_type_class_ref(gtype)); - - values = PyDict_New(); - for (i = 0; i < eclass->n_values; i++) { - PyObject *item, *intval; - - intval = PYGLIB_PyLong_FromLong(eclass->values[i].value); - item = pyg_enum_val_new(stub, gtype, intval); - PyDict_SetItem(values, intval, item); - Py_DECREF(intval); - - if (module) { - char *prefix; - - prefix = g_strdup(pyg_constant_strip_prefix(eclass->values[i].value_name, strip_prefix)); - PyModule_AddObject(module, prefix, item); - g_free(prefix); - - Py_INCREF(item); - } - } - - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, - "__enum_values__", values); - Py_DECREF(values); - - g_type_class_unref(eclass); - - pyglib_gil_state_release(state); - return stub; -} - -static PyObject * -pyg_enum_reduce(PyObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":GEnum.__reduce__")) - return NULL; - - return Py_BuildValue("(O(i)O)", Py_TYPE(self), PYGLIB_PyLong_AsLong(self), - PyObject_GetAttrString(self, "__dict__")); -} - -static PyObject * -pyg_enum_get_value_name(PyGEnum *self, void *closure) -{ - GEnumClass *enum_class; - GEnumValue *enum_value; - PyObject *retval; - - enum_class = g_type_class_ref(self->gtype); - g_assert(G_IS_ENUM_CLASS(enum_class)); - - enum_value = g_enum_get_value(enum_class, PYGLIB_PyLong_AS_LONG(self)); - - retval = PYGLIB_PyUnicode_FromString(enum_value->value_name); - g_type_class_unref(enum_class); - - return retval; -} - -static PyObject * -pyg_enum_get_value_nick(PyGEnum *self, void *closure) -{ - GEnumClass *enum_class; - GEnumValue *enum_value; - PyObject *retval; - - enum_class = g_type_class_ref(self->gtype); - g_assert(G_IS_ENUM_CLASS(enum_class)); - - enum_value = g_enum_get_value(enum_class, PYGLIB_PyLong_AS_LONG(self)); - - retval = PYGLIB_PyUnicode_FromString(enum_value->value_nick); - g_type_class_unref(enum_class); - - return retval; -} - - -static PyMethodDef pyg_enum_methods[] = { - { "__reduce__", (PyCFunction)pyg_enum_reduce, METH_VARARGS }, - { NULL, NULL, 0 } -}; - -static PyGetSetDef pyg_enum_getsets[] = { - { "value_name", (getter)pyg_enum_get_value_name, (setter)0 }, - { "value_nick", (getter)pyg_enum_get_value_nick, (setter)0 }, - { NULL, 0, 0 } -}; - -void -pygobject_enum_register_types(PyObject *d) -{ - pygenum_class_key = g_quark_from_static_string("PyGEnum::class"); - - PyGEnum_Type.tp_base = &PYGLIB_PyLong_Type; -#if PY_VERSION_HEX < 0x03000000 - PyGEnum_Type.tp_new = pyg_enum_new; -#else - PyGEnum_Type.tp_new = PyLong_Type.tp_new; - PyGEnum_Type.tp_hash = PyLong_Type.tp_hash; -#endif - PyGEnum_Type.tp_repr = (reprfunc)pyg_enum_repr; - PyGEnum_Type.tp_str = (reprfunc)pyg_enum_repr; - PyGEnum_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGEnum_Type.tp_richcompare = (richcmpfunc)pyg_enum_richcompare; - PyGEnum_Type.tp_methods = pyg_enum_methods; - PyGEnum_Type.tp_getset = pyg_enum_getsets; - PYGOBJECT_REGISTER_GTYPE(d, PyGEnum_Type, "GEnum", G_TYPE_ENUM); -} diff --git a/gi/_gobject/pygenum.h b/gi/_gobject/pygenum.h deleted file mode 100644 index 0558831..0000000 --- a/gi/_gobject/pygenum.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_ENUM_H__ -#define __PYGOBJECT_ENUM_H__ - -void pygobject_enum_register_types(PyObject *d); - -#endif /* __PYGOBJECT_ENUM_H__ */ diff --git a/gi/_gobject/pygflags.c b/gi/_gobject/pygflags.c deleted file mode 100644 index bdeaae7..0000000 --- a/gi/_gobject/pygflags.c +++ /dev/null @@ -1,497 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * Copyright (C) 2004 Johan Dahlin - * - * pygflags.c: GFlags wrapper - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pygobject-private.h" -#include "pygflags.h" - -#include "pygi.h" - -GQuark pygflags_class_key; - -PYGLIB_DEFINE_TYPE("gobject.GFlags", PyGFlags_Type, PyGFlags); - -static PyObject * -pyg_flags_val_new(PyObject* subclass, GType gtype, PyObject *intval) -{ - PyObject *args, *item; - args = Py_BuildValue("(O)", intval); - g_assert(PyObject_IsSubclass(subclass, (PyObject*) &PyGFlags_Type)); - item = PYGLIB_PyLong_Type.tp_new((PyTypeObject*)subclass, args, NULL); - Py_DECREF(args); - if (!item) - return NULL; - ((PyGFlags*)item)->gtype = gtype; - - return item; -} - -static PyObject * -pyg_flags_richcompare(PyGFlags *self, PyObject *other, int op) -{ - static char warning[256]; - - if (!PYGLIB_PyLong_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (PyObject_TypeCheck(other, &PyGFlags_Type) && ((PyGFlags*)other)->gtype != self->gtype) { - g_snprintf(warning, sizeof(warning), "comparing different flags types: %s and %s", - g_type_name(self->gtype), g_type_name(((PyGFlags*)other)->gtype)); - if (PyErr_Warn(PyExc_Warning, warning)) - return NULL; - } - - return pyg_integer_richcompare((PyObject *)self, other, op); -} - -static char * -generate_repr(GType gtype, guint value) -{ - GFlagsClass *flags_class; - char *retval = NULL, *tmp; - int i; - - flags_class = g_type_class_ref(gtype); - g_assert(G_IS_FLAGS_CLASS(flags_class)); - - for (i = 0; i < flags_class->n_values; i++) { - /* Some types (eg GstElementState in GStreamer 0.8) has flags with 0 values, - * we're just ignore them for now otherwise they'll always show up - */ - if (flags_class->values[i].value == 0) - continue; - - if ((value & flags_class->values[i].value) == flags_class->values[i].value) { - if (retval) { - tmp = g_strdup_printf("%s | %s", retval, flags_class->values[i].value_name); - g_free(retval); - retval = tmp; - } else { - retval = g_strdup_printf("%s", flags_class->values[i].value_name); - } - } - } - - g_type_class_unref(flags_class); - - return retval; -} - -static PyObject * -pyg_flags_repr(PyGFlags *self) -{ - char *tmp, *retval; - PyObject *pyretval; - - tmp = generate_repr(self->gtype, PYGLIB_PyLong_AsUnsignedLong(self)); - - if (tmp) - retval = g_strdup_printf("", tmp, - g_type_name(self->gtype)); - else - retval = g_strdup_printf("", PYGLIB_PyLong_AsUnsignedLong(self), - g_type_name(self->gtype)); - g_free(tmp); - - pyretval = PYGLIB_PyUnicode_FromString(retval); - g_free(retval); - - return pyretval; -} - -static PyObject * -pyg_flags_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "value", NULL }; - gulong value; - PyObject *pytc, *values, *ret, *pyint; - GType gtype; - GFlagsClass *eclass; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "k", kwlist, &value)) - return NULL; - - pytc = PyObject_GetAttrString((PyObject *)type, "__gtype__"); - if (!pytc) - return NULL; - - if (!PyObject_TypeCheck(pytc, &PyGTypeWrapper_Type)) { - Py_DECREF(pytc); - PyErr_SetString(PyExc_TypeError, - "__gtype__ attribute not a typecode"); - return NULL; - } - - gtype = pyg_type_from_object(pytc); - Py_DECREF(pytc); - - eclass = G_FLAGS_CLASS(g_type_class_ref(gtype)); - - values = PyObject_GetAttrString((PyObject *)type, "__flags_values__"); - if (!values) { - g_type_class_unref(eclass); - return NULL; - } - - if (!PyDict_Check(values)) { - PyErr_SetString(PyExc_TypeError, "__flags_values__ badly formed"); - Py_DECREF(values); - g_type_class_unref(eclass); - return NULL; - } - - g_type_class_unref(eclass); - - pyint = PYGLIB_PyLong_FromUnsignedLong(value); - ret = PyDict_GetItem(values, pyint); - if (!ret) { - PyErr_Clear(); - - ret = pyg_flags_val_new((PyObject *)type, gtype, pyint); - g_assert(ret != NULL); - } else { - Py_INCREF(ret); - } - - Py_DECREF(pyint); - Py_DECREF(values); - - return ret; -} - -PyObject* -pyg_flags_from_gtype (GType gtype, guint value) -{ - PyObject *pyclass, *values, *retval, *pyint; - - if (PyErr_Occurred()) - return PYGLIB_PyLong_FromUnsignedLong(0); - - g_return_val_if_fail(gtype != G_TYPE_INVALID, NULL); - - /* Get a wrapper class by: - * 1. check for one attached to the gtype - * 2. lookup one in a typelib - * 3. creating a new one - */ - pyclass = (PyObject*)g_type_get_qdata(gtype, pygflags_class_key); - if (!pyclass) - pyclass = pygi_type_import_by_g_type(gtype); - if (!pyclass) - pyclass = pyg_flags_add(NULL, g_type_name(gtype), NULL, gtype); - if (!pyclass) - return PYGLIB_PyLong_FromUnsignedLong(value); - - values = PyDict_GetItemString(((PyTypeObject *)pyclass)->tp_dict, - "__flags_values__"); - pyint = PYGLIB_PyLong_FromUnsignedLong(value); - retval = PyDict_GetItem(values, pyint); - if (!retval) { - PyErr_Clear(); - - retval = pyg_flags_val_new(pyclass, gtype, pyint); - g_assert(retval != NULL); - } else { - Py_INCREF(retval); - } - Py_DECREF(pyint); - - return retval; -} - -/* - * pyg_flags_add - * Dynamically create a class derived from PyGFlags based on the given GType. - */ -PyObject * -pyg_flags_add (PyObject * module, - const char * typename, - const char * strip_prefix, - GType gtype) -{ - PyGILState_STATE state; - PyObject *instance_dict, *stub, *values, *o; - GFlagsClass *eclass; - int i; - - g_return_val_if_fail(typename != NULL, NULL); - if (!g_type_is_a(gtype, G_TYPE_FLAGS)) { - g_warning("Trying to register gtype '%s' as flags when in fact it is of type '%s'", - g_type_name(gtype), g_type_name(G_TYPE_FUNDAMENTAL(gtype))); - return NULL; - } - - state = pyglib_gil_state_ensure(); - - /* Create a new type derived from GFlags. This is the same as: - * >>> stub = type(typename, (GFlags,), {}) - */ - instance_dict = PyDict_New(); - stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", - typename, (PyObject *)&PyGFlags_Type, - instance_dict); - Py_DECREF(instance_dict); - if (!stub) { - PyErr_SetString(PyExc_RuntimeError, "can't create GFlags subtype"); - pyglib_gil_state_release(state); - return NULL; - } - - ((PyTypeObject *)stub)->tp_flags &= ~Py_TPFLAGS_BASETYPE; - ((PyTypeObject *)stub)->tp_new = pyg_flags_new; - - if (module) { - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, - "__module__", - PYGLIB_PyUnicode_FromString(PyModule_GetName(module))); - - /* Add it to the module name space */ - PyModule_AddObject(module, (char*)typename, stub); - Py_INCREF(stub); - } - g_type_set_qdata(gtype, pygflags_class_key, stub); - - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, "__gtype__", o); - Py_DECREF(o); - - /* Register flag values */ - eclass = G_FLAGS_CLASS(g_type_class_ref(gtype)); - - values = PyDict_New(); - for (i = 0; i < eclass->n_values; i++) { - PyObject *item, *intval; - - intval = PYGLIB_PyLong_FromUnsignedLong(eclass->values[i].value); - g_assert(PyErr_Occurred() == NULL); - item = pyg_flags_val_new(stub, gtype, intval); - PyDict_SetItem(values, intval, item); - Py_DECREF(intval); - - if (module) { - char *prefix; - - prefix = g_strdup(pyg_constant_strip_prefix(eclass->values[i].value_name, strip_prefix)); - Py_INCREF(item); - PyModule_AddObject(module, prefix, item); - g_free(prefix); - } - Py_DECREF(item); - } - - PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, - "__flags_values__", values); - Py_DECREF(values); - - g_type_class_unref(eclass); - - pyglib_gil_state_release(state); - - return stub; -} - -static PyObject * -pyg_flags_and(PyGFlags *a, PyGFlags *b) -{ - if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) - return PYGLIB_PyLong_Type.tp_as_number->nb_and((PyObject*)a, - (PyObject*)b); - - return pyg_flags_from_gtype(a->gtype, - PYGLIB_PyLong_AsUnsignedLong(a) & PYGLIB_PyLong_AsUnsignedLong(b)); -} - -static PyObject * -pyg_flags_or(PyGFlags *a, PyGFlags *b) -{ - if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) - return PYGLIB_PyLong_Type.tp_as_number->nb_or((PyObject*)a, - (PyObject*)b); - - return pyg_flags_from_gtype(a->gtype, PYGLIB_PyLong_AsUnsignedLong(a) | PYGLIB_PyLong_AsUnsignedLong(b)); -} - -static PyObject * -pyg_flags_xor(PyGFlags *a, PyGFlags *b) -{ - if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) - return PYGLIB_PyLong_Type.tp_as_number->nb_xor((PyObject*)a, - (PyObject*)b); - - return pyg_flags_from_gtype(a->gtype, - PYGLIB_PyLong_AsUnsignedLong(a) ^ PYGLIB_PyLong_AsUnsignedLong(b)); - -} - -static PyObject * -pyg_flags_warn (PyObject *self, PyObject *args) -{ - if (PyErr_Warn(PyExc_Warning, "unsupported arithmetic operation for flags type")) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pyg_flags_get_first_value_name(PyGFlags *self, void *closure) -{ - GFlagsClass *flags_class; - GFlagsValue *flags_value; - PyObject *retval; - - flags_class = g_type_class_ref(self->gtype); - g_assert(G_IS_FLAGS_CLASS(flags_class)); - flags_value = g_flags_get_first_value(flags_class, PYGLIB_PyLong_AsUnsignedLong(self)); - if (flags_value) - retval = PYGLIB_PyUnicode_FromString(flags_value->value_name); - else { - retval = Py_None; - Py_INCREF(Py_None); - } - g_type_class_unref(flags_class); - - return retval; -} - -static PyObject * -pyg_flags_get_first_value_nick(PyGFlags *self, void *closure) -{ - GFlagsClass *flags_class; - GFlagsValue *flags_value; - PyObject *retval; - - flags_class = g_type_class_ref(self->gtype); - g_assert(G_IS_FLAGS_CLASS(flags_class)); - - flags_value = g_flags_get_first_value(flags_class, PYGLIB_PyLong_AsUnsignedLong(self)); - if (flags_value) - retval = PYGLIB_PyUnicode_FromString(flags_value->value_nick); - else { - retval = Py_None; - Py_INCREF(Py_None); - } - g_type_class_unref(flags_class); - - return retval; -} - -static PyObject * -pyg_flags_get_value_names(PyGFlags *self, void *closure) -{ - GFlagsClass *flags_class; - PyObject *retval; - int i; - - flags_class = g_type_class_ref(self->gtype); - g_assert(G_IS_FLAGS_CLASS(flags_class)); - - retval = PyList_New(0); - for (i = 0; i < flags_class->n_values; i++) - if ((PYGLIB_PyLong_AsUnsignedLong(self) & flags_class->values[i].value) == flags_class->values[i].value) - PyList_Append(retval, PYGLIB_PyUnicode_FromString(flags_class->values[i].value_name)); - - g_type_class_unref(flags_class); - - return retval; -} - -static PyObject * -pyg_flags_get_value_nicks(PyGFlags *self, void *closure) -{ - GFlagsClass *flags_class; - PyObject *retval; - int i; - - flags_class = g_type_class_ref(self->gtype); - g_assert(G_IS_FLAGS_CLASS(flags_class)); - - retval = PyList_New(0); - for (i = 0; i < flags_class->n_values; i++) - if ((PYGLIB_PyLong_AsUnsignedLong(self) & flags_class->values[i].value) == flags_class->values[i].value) { - PyObject *py_nick = PYGLIB_PyUnicode_FromString(flags_class->values[i].value_nick); - PyList_Append(retval, py_nick); - Py_DECREF (py_nick); - } - - g_type_class_unref(flags_class); - - return retval; -} - -static PyGetSetDef pyg_flags_getsets[] = { - { "first_value_name", (getter)pyg_flags_get_first_value_name, (setter)0 }, - { "first_value_nick", (getter)pyg_flags_get_first_value_nick, (setter)0 }, - { "value_names", (getter)pyg_flags_get_value_names, (setter)0 }, - { "value_nicks", (getter)pyg_flags_get_value_nicks, (setter)0 }, - { NULL, 0, 0 } -}; - -static PyNumberMethods pyg_flags_as_number = { - (binaryfunc)pyg_flags_warn, /* nb_add */ - (binaryfunc)pyg_flags_warn, /* nb_subtract */ - (binaryfunc)pyg_flags_warn, /* nb_multiply */ - (binaryfunc)pyg_flags_warn, /* nb_divide */ - (binaryfunc)pyg_flags_warn, /* nb_remainder */ -#if PY_VERSION_HEX < 0x03000000 - (binaryfunc)pyg_flags_warn, /* nb_divmod */ -#endif - (ternaryfunc)pyg_flags_warn, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_nonzero */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - (binaryfunc)pyg_flags_and, /* nb_and */ - (binaryfunc)pyg_flags_xor, /* nb_xor */ - (binaryfunc)pyg_flags_or, /* nb_or */ -}; - -void -pygobject_flags_register_types(PyObject *d) -{ - pygflags_class_key = g_quark_from_static_string("PyGFlags::class"); - - PyGFlags_Type.tp_base = &PYGLIB_PyLong_Type; -#if PY_VERSION_HEX < 0x03000000 - PyGFlags_Type.tp_new = pyg_flags_new; -#else - PyGFlags_Type.tp_new = PyLong_Type.tp_new; - PyGFlags_Type.tp_hash = PyLong_Type.tp_hash; -#endif - PyGFlags_Type.tp_repr = (reprfunc)pyg_flags_repr; - PyGFlags_Type.tp_as_number = &pyg_flags_as_number; - PyGFlags_Type.tp_str = (reprfunc)pyg_flags_repr; - PyGFlags_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGFlags_Type.tp_richcompare = (richcmpfunc)pyg_flags_richcompare; - PyGFlags_Type.tp_getset = pyg_flags_getsets; - PYGOBJECT_REGISTER_GTYPE(d, PyGFlags_Type, "GFlags", G_TYPE_FLAGS); -} diff --git a/gi/_gobject/pygflags.h b/gi/_gobject/pygflags.h deleted file mode 100644 index e93265c..0000000 --- a/gi/_gobject/pygflags.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_FLAGS_H__ -#define __PYGOBJECT_FLAGS_H__ - -void pygobject_flags_register_types(PyObject *d); - -#endif /* __PYGOBJECT_FLAGS_H__ */ diff --git a/gi/_gobject/pyginterface.c b/gi/_gobject/pyginterface.c deleted file mode 100644 index eb76ba0..0000000 --- a/gi/_gobject/pyginterface.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * pyginterface.c: wrapper for the gobject library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pyglib.h" -#include "pygobject-private.h" - -#include "pyginterface.h" - -GQuark pyginterface_type_key; -GQuark pyginterface_info_key; - -PYGLIB_DEFINE_TYPE("gobject.GInterface", PyGInterface_Type, PyObject) - -static int -pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - gchar buf[512]; - - if (!PyArg_ParseTuple(args, ":GInterface.__init__")) - return -1; - - g_snprintf(buf, sizeof(buf), "%s can not be constructed", - Py_TYPE(self)->tp_name); - PyErr_SetString(PyExc_NotImplementedError, buf); - return -1; -} - -static void -pyg_interface_free(PyObject *op) -{ - PyObject_FREE(op); -} - -/** - * pyg_register_interface: - * @dict: a module dictionary. - * @class_name: the class name for the wrapper class. - * @gtype: the GType of the interface. - * @type: the wrapper class for the interface. - * - * Registers a Python class as the wrapper for a GInterface. As a - * convenience it will also place a reference to the wrapper class in - * the provided module dictionary. - */ -void -pyg_register_interface(PyObject *dict, const gchar *class_name, - GType gtype, PyTypeObject *type) -{ - PyObject *o; - - Py_TYPE(type) = &PyType_Type; - type->tp_base = &PyGInterface_Type; - - if (PyType_Ready(type) < 0) { - g_warning("could not ready `%s'", type->tp_name); - return; - } - - if (gtype) { - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(type->tp_dict, "__gtype__", o); - Py_DECREF(o); - } - - g_type_set_qdata(gtype, pyginterface_type_key, type); - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); - -} - -void -pyg_register_interface_info(GType gtype, const GInterfaceInfo *info) -{ - g_type_set_qdata(gtype, pyginterface_info_key, (gpointer) info); -} - -const GInterfaceInfo * -pyg_lookup_interface_info(GType gtype) -{ - return g_type_get_qdata(gtype, pyginterface_info_key); -} - -void -pygobject_interface_register_types(PyObject *d) -{ - pyginterface_type_key = g_quark_from_static_string("PyGInterface::type"); - pyginterface_info_key = g_quark_from_static_string("PyGInterface::info"); - - PyGInterface_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGInterface_Type.tp_init = (initproc)pyg_interface_init; - PyGInterface_Type.tp_free = (freefunc)pyg_interface_free; - - PYGOBJECT_REGISTER_GTYPE(d, PyGInterface_Type, "GInterface", G_TYPE_INTERFACE) - - PyDict_SetItemString(PyGInterface_Type.tp_dict, "__doc__", - pyg_object_descr_doc_get()); - PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gdoc__", - pyg_object_descr_doc_get()); - -} diff --git a/gi/_gobject/pyginterface.h b/gi/_gobject/pyginterface.h deleted file mode 100644 index 0f390c2..0000000 --- a/gi/_gobject/pyginterface.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * pyginterface.c: wrapper for the gobject library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_INTERFACE_H__ -#define __PYGOBJECT_INTERFACE_H__ - -extern GQuark pyginterface_type_key; -extern GQuark pyginterface_info_key; - -extern PyTypeObject PyGInterface_Type; - -void pyg_register_interface(PyObject *dict, - const gchar *class_name, - GType gtype, - PyTypeObject *type); -const GInterfaceInfo * pyg_lookup_interface_info(GType gtype); -void pyg_register_interface_info(GType gtype, const - GInterfaceInfo *info); -void pygobject_interface_register_types(PyObject *d); - -#endif /* __PYGOBJECT_INTERFACE_H__ */ diff --git a/gi/_gobject/pygobject-private.h b/gi/_gobject/pygobject-private.h deleted file mode 100644 index 294b0f6..0000000 --- a/gi/_gobject/pygobject-private.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef _PYGOBJECT_PRIVATE_H_ -#define _PYGOBJECT_PRIVATE_H_ - -#ifdef _PYGOBJECT_H_ -# error "include pygobject.h or pygobject-private.h, but not both" -#endif - -#define _INSIDE_PYGOBJECT_ -#include "pygobject.h" - -#include "pyglib-python-compat.h" - -#define PYGOBJECT_REGISTER_GTYPE(d, type, name, gtype) \ - { \ - PyObject *o; \ - PYGLIB_REGISTER_TYPE(d, type, name); \ - PyDict_SetItemString(type.tp_dict, "__gtype__", \ - o=pyg_type_wrapper_new(gtype)); \ - Py_DECREF(o); \ -} - -/* from gobjectmodule.c */ -extern struct _PyGObject_Functions pygobject_api_functions; - - -#ifndef Py_CLEAR /* since Python 2.4 */ -# define Py_CLEAR(op) \ - do { \ - if (op) { \ - PyObject *tmp = (PyObject *)(op); \ - (op) = NULL; \ - Py_DECREF(tmp); \ - } \ - } while (0) -#endif - -extern GType PY_TYPE_OBJECT; - -extern GQuark pygboxed_type_key; -extern GQuark pygboxed_marshal_key; -extern GQuark pygenum_class_key; -extern GQuark pygflags_class_key; -extern GQuark pyginterface_type_key; -extern GQuark pyginterface_info_key; -extern GQuark pygobject_class_init_key; -extern GQuark pygobject_class_key; -extern GQuark pygobject_wrapper_key; -extern GQuark pygpointer_class_key; -extern GQuark pygobject_has_updated_constructor_key; -extern GQuark pygobject_instance_data_key; -extern GQuark pygobject_custom_key; - -void pygobject_data_free (PyGObjectData *data); -void pyg_destroy_notify (gpointer user_data); -gboolean pyg_handler_marshal (gpointer user_data); -gboolean pyg_error_check (GError **error); -int pygobject_constructv (PyGObject *self, - guint n_parameters, - GParameter *parameters); - -PyObject *pyg_integer_richcompare(PyObject *v, - PyObject *w, - int op); - -gboolean pyg_gerror_exception_check(GError **error); - -void pygobject_ref_float(PyGObject *self); -void pygobject_ref_sink(PyGObject *self); - -/* from pygtype.h */ -extern PyTypeObject PyGTypeWrapper_Type; - -PyObject *pyg_type_wrapper_new (GType type); -GType pyg_type_from_object_strict (PyObject *obj, gboolean strict); -GType pyg_type_from_object (PyObject *obj); - -gint pyg_enum_get_value (GType enum_type, PyObject *obj, gint *val); -gint pyg_flags_get_value (GType flag_type, PyObject *obj, guint *val); -int pyg_pyobj_to_unichar_conv (PyObject* py_obj, void* ptr); - -typedef PyObject *(* fromvaluefunc)(const GValue *value); -typedef int (*tovaluefunc)(GValue *value, PyObject *obj); - -void pyg_register_gtype_custom(GType gtype, - fromvaluefunc from_func, - tovaluefunc to_func); -int pyg_value_from_pyobject(GValue *value, PyObject *obj); -int pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj); -PyObject *pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed); -int pyg_param_gvalue_from_pyobject(GValue* value, - PyObject* py_obj, - const GParamSpec* pspec); -PyObject *pyg_param_gvalue_as_pyobject(const GValue* gvalue, - gboolean copy_boxed, - const GParamSpec* pspec); - -GClosure *pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data); -void pyg_closure_set_exception_handler(GClosure *closure, - PyClosureExceptionHandler handler); -GClosure *pyg_signal_class_closure_get(void); -GClosure *gclosure_from_pyfunc(PyGObject *object, PyObject *func); - -PyObject *pyg_object_descr_doc_get(void); -void pygobject_object_register_types(PyObject *d); - -extern PyTypeObject *PyGObject_MetaType; - -/* from pygobject.h */ -extern PyTypeObject PyGObject_Type; -extern PyTypeObject PyGProps_Type; -extern PyTypeObject PyGPropsDescr_Type; -extern PyTypeObject PyGPropsIter_Type; - - /* Data that belongs to the GObject instance, not the Python wrapper */ -struct _PyGObjectData { - PyTypeObject *type; /* wrapper type for this instance */ - GSList *closures; -}; - -void pygobject_register_class (PyObject *dict, - const gchar *type_name, - GType gtype, PyTypeObject *type, - PyObject *bases); -void pygobject_register_wrapper (PyObject *self); -PyObject * pygobject_new (GObject *obj); -PyObject * pygobject_new_full (GObject *obj, gboolean steal, gpointer g_class); -void pygobject_sink (GObject *obj); -PyTypeObject *pygobject_lookup_class (GType gtype); -void pygobject_watch_closure (PyObject *self, GClosure *closure); -int pyg_type_register (PyTypeObject *class, - const gchar *type_name); - -/* from pygboxed.c */ -extern PyTypeObject PyGBoxed_Type; - -void pyg_register_boxed (PyObject *dict, const gchar *class_name, - GType boxed_type, PyTypeObject *type); -PyObject * pyg_boxed_new (GType boxed_type, gpointer boxed, - gboolean copy_boxed, gboolean own_ref); - -extern PyTypeObject PyGPointer_Type; - -void pyg_register_pointer (PyObject *dict, const gchar *class_name, - GType pointer_type, PyTypeObject *type); -PyObject * pyg_pointer_new (GType pointer_type, gpointer pointer); - -const gchar * pyg_constant_strip_prefix(const gchar *name, const gchar *strip_prefix); - -/* pygflags */ -typedef struct { - PYGLIB_PyLongObject parent; - int zero_pad; /* must always be 0 */ - GType gtype; -} PyGFlags; - -extern PyTypeObject PyGFlags_Type; - -#define PyGFlags_Check(x) (PyObject_IsInstance((PyObject *)x, (PyObject *)&PyGFlags_Type) && g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_FLAGS)) - -extern PyObject * pyg_flags_add (PyObject * module, - const char * type_name, - const char * strip_prefix, - GType gtype); -extern PyObject * pyg_flags_from_gtype (GType gtype, - guint value); - -/* pygenum */ -#define PyGEnum_Check(x) (PyObject_IsInstance((PyObject *)x, (PyObject *)&PyGEnum_Type) && g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_ENUM)) - -typedef struct { - PYGLIB_PyLongObject parent; - int zero_pad; /* must always be 0 */ - GType gtype; -} PyGEnum; - -extern PyTypeObject PyGEnum_Type; - -extern PyObject * pyg_enum_add (PyObject * module, - const char * type_name, - const char * strip_prefix, - GType gtype); -extern PyObject * pyg_enum_from_gtype (GType gtype, - int value); - -/* pygtype.c */ -extern gboolean pyg_gtype_is_custom (GType gtype); - -/* pygobject.c */ -extern PyTypeObject PyGObjectWeakRef_Type; - -static inline PyGObjectData * -pyg_object_peek_inst_data(GObject *obj) -{ - return ((PyGObjectData *) - g_object_get_qdata(obj, pygobject_instance_data_key)); -} - -gboolean pygobject_prepare_construct_properties (GObjectClass *class, - PyObject *kwargs, - guint *n_params, - GParameter **params); - - -#endif diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c deleted file mode 100644 index 129f29a..0000000 --- a/gi/_gobject/pygobject.c +++ /dev/null @@ -1,2473 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * pygobject.c: wrapper for the GObject type. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pygobject-private.h" -#include "pyginterface.h" -#include "pygparamspec.h" - -#include "pygi.h" - - -static void pygobject_dealloc(PyGObject *self); -static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg); -static int pygobject_clear(PyGObject *self); -static PyObject * pyg_type_get_bases(GType gtype); -static inline int pygobject_clear(PyGObject *self); -static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data); -static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj); -static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, - gboolean check_for_present); -static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset, - gboolean check_for_present); -GType PY_TYPE_OBJECT = 0; -GQuark pygobject_custom_key; -GQuark pygobject_class_key; -GQuark pygobject_class_init_key; -GQuark pygobject_wrapper_key; -GQuark pygobject_has_updated_constructor_key; -GQuark pygobject_instance_data_key; - -/* Copied from glib. gobject uses hyphens in property names, but in Python - * we can only represent hyphens as underscores. Convert underscores to - * hyphens for glib compatibility. */ -static void -canonicalize_key (gchar *key) -{ - gchar *p; - - for (p = key; *p != 0; p++) - { - gchar c = *p; - - if (c != '-' && - (c < '0' || c > '9') && - (c < 'A' || c > 'Z') && - (c < 'a' || c > 'z')) - *p = '-'; - } -} - -/* -------------- class <-> wrapper manipulation --------------- */ - -void -pygobject_data_free(PyGObjectData *data) -{ - /* This function may be called after the python interpreter has already - * been shut down. If this happens, we cannot do any python calls, so just - * free the memory. */ - PyGILState_STATE state; - PyThreadState *_save = NULL; - - GSList *closures, *tmp; - - if (Py_IsInitialized()) { - state = pyglib_gil_state_ensure(); - Py_DECREF(data->type); - /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside - * a branch. */ - Py_UNBLOCK_THREADS; /* Modifies _save */ - } - - tmp = closures = data->closures; -#ifndef NDEBUG - data->closures = NULL; - data->type = NULL; -#endif - while (tmp) { - GClosure *closure = tmp->data; - - /* we get next item first, because the current link gets - * invalidated by pygobject_unwatch_closure */ - tmp = tmp->next; - g_closure_invalidate(closure); - } - - if (data->closures != NULL) - g_warning("invalidated all closures, but data->closures != NULL !"); - - g_free(data); - - if (Py_IsInitialized()) { - Py_BLOCK_THREADS; /* Restores _save */ - pyglib_gil_state_release(state); - } -} - -static inline PyGObjectData * -pygobject_data_new(void) -{ - PyGObjectData *data; - data = g_new0(PyGObjectData, 1); - return data; -} - -static inline PyGObjectData * -pygobject_get_inst_data(PyGObject *self) -{ - PyGObjectData *inst_data; - - if (G_UNLIKELY(!self->obj)) - return NULL; - inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key); - if (inst_data == NULL) - { - inst_data = pygobject_data_new(); - - inst_data->type = Py_TYPE(self); - Py_INCREF((PyObject *) inst_data->type); - - g_object_set_qdata_full(self->obj, pygobject_instance_data_key, - inst_data, (GDestroyNotify) pygobject_data_free); - } - return inst_data; -} - - -PyTypeObject *PyGObject_MetaType = NULL; - -/** - * pygobject_sink: - * @obj: a GObject - * - * As Python handles reference counting for us, the "floating - * reference" code in GTK is not all that useful. In fact, it can - * cause leaks. This function should be called to remove the floating - * references on objects on construction. - **/ -void -pygobject_sink(GObject *obj) -{ - /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink(). - * - if the object is new and owned by someone else, its ref has been sunk and - * we need to keep the one from that someone and add our own "fresh ref" - * - if the object is not and owned by nobody, its ref is floating and we need - * to transform it into a regular ref. - */ - if (G_IS_INITIALLY_UNOWNED(obj)) { - g_object_ref_sink(obj); - } -} - -typedef struct { - PyObject_HEAD - GParamSpec **props; - guint n_props; - guint index; -} PyGPropsIter; - -PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter); - -static void -pyg_props_iter_dealloc(PyGPropsIter *self) -{ - g_free(self->props); - PyObject_Del((PyObject*) self); -} - -static PyObject* -pygobject_props_iter_next(PyGPropsIter *iter) -{ - if (iter->index < iter->n_props) - return pyg_param_spec_new(iter->props[iter->index++]); - else { - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } -} - -typedef struct { - PyObject_HEAD - /* a reference to the object containing the properties */ - PyGObject *pygobject; - GType gtype; -} PyGProps; - -static void -PyGProps_dealloc(PyGProps* self) -{ - PyGObject *tmp; - - PyObject_GC_UnTrack((PyObject*)self); - - tmp = self->pygobject; - self->pygobject = NULL; - Py_XDECREF(tmp); - - PyObject_GC_Del((PyObject*)self); -} - -static PyObject* -build_parameter_list(GObjectClass *class) -{ - GParamSpec **props; - guint n_props = 0, i; - PyObject *prop_str; - PyObject *props_list; - - props = g_object_class_list_properties(class, &n_props); - props_list = PyList_New(n_props); - for (i = 0; i < n_props; i++) { - char *name; - name = g_strdup(g_param_spec_get_name(props[i])); - /* hyphens cannot belong in identifiers */ - g_strdelimit(name, "-", '_'); - prop_str = PYGLIB_PyUnicode_FromString(name); - - PyList_SetItem(props_list, i, prop_str); - g_free(name); - } - - if (props) - g_free(props); - - return props_list; -} - - -static PyObject* -PyGProps_getattro(PyGProps *self, PyObject *attr) -{ - char *attr_name, *property_name; - GObjectClass *class; - GParamSpec *pspec; - GValue value = { 0, }; - PyObject *ret; - - attr_name = PYGLIB_PyUnicode_AsString(attr); - if (!attr_name) { - PyErr_Clear(); - return PyObject_GenericGetAttr((PyObject *)self, attr); - } - - class = g_type_class_ref(self->gtype); - - /* g_object_class_find_property recurses through the class hierarchy, - * so the resulting pspec tells us the owner_type that owns the property - * we're dealing with. */ - property_name = g_strdup(attr_name); - canonicalize_key(property_name); - pspec = g_object_class_find_property(class, property_name); - g_free(property_name); - g_type_class_unref(class); - - if (!pspec) { - return PyObject_GenericGetAttr((PyObject *)self, attr); - } - - if (!(pspec->flags & G_PARAM_READABLE)) { - PyErr_Format(PyExc_TypeError, - "property '%s' is not readable", attr_name); - return NULL; - } - - if (!self->pygobject) { - /* If we're doing it without an instance, return a GParamSpec */ - return pyg_param_spec_new(pspec); - } - - if (!pyg_gtype_is_custom (pspec->owner_type)) { - /* The GType is not implemented at the Python level: see if we can - * read the property value via gi. */ - ret = pygi_get_property_value (self->pygobject, pspec); - if (ret) - return ret; - } - - /* The GType is implemented in Python, or we failed to read it via gi: - * do a straightforward read. */ - Py_BEGIN_ALLOW_THREADS; - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - g_object_get_property(self->pygobject->obj, pspec->name, &value); - Py_END_ALLOW_THREADS; - - ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); - g_value_unset(&value); - - return ret; -} - -static gboolean -set_property_from_pspec(GObject *obj, - GParamSpec *pspec, - PyObject *pvalue) -{ - GValue value = { 0, }; - - if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) { - PyErr_Format(PyExc_TypeError, - "property '%s' can only be set in constructor", - pspec->name); - return FALSE; - } - - if (!(pspec->flags & G_PARAM_WRITABLE)) { - PyErr_Format(PyExc_TypeError, - "property '%s' is not writable", pspec->name); - return FALSE; - } - - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) { - PyObject *pvalue_str = PyObject_Str(pvalue); - PyErr_Format(PyExc_TypeError, - "could not convert '%s' to type '%s' when setting property '%s.%s'", - PYGLIB_PyUnicode_AsString(pvalue_str), - g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)), - G_OBJECT_TYPE_NAME(obj), - pspec->name); - Py_DECREF(pvalue_str); - return FALSE; - } - - Py_BEGIN_ALLOW_THREADS; - g_object_set_property(obj, pspec->name, &value); - g_value_unset(&value); - Py_END_ALLOW_THREADS; - - return TRUE; -} - -PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps); - -static int -PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue) -{ - GParamSpec *pspec; - char *attr_name, *property_name; - GObject *obj; - int ret = -1; - - if (pvalue == NULL) { - PyErr_SetString(PyExc_TypeError, "properties cannot be " - "deleted"); - return -1; - } - - attr_name = PYGLIB_PyUnicode_AsString(attr); - if (!attr_name) { - PyErr_Clear(); - return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue); - } - - if (!self->pygobject) { - PyErr_SetString(PyExc_TypeError, - "cannot set GOject properties without an instance"); - return -1; - } - - obj = self->pygobject->obj; - - property_name = g_strdup(attr_name); - canonicalize_key(property_name); - - /* g_object_class_find_property recurses through the class hierarchy, - * so the resulting pspec tells us the owner_type that owns the property - * we're dealing with. */ - pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), - property_name); - g_free(property_name); - if (!pspec) { - return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue); - } - if (!pyg_gtype_is_custom (pspec->owner_type)) { - /* This GType is not implemented in Python: see if we can set the - * property via gi. */ - ret = pygi_set_property_value (self->pygobject, pspec, pvalue); - if (ret == 0) - return 0; - else if (ret == -1 && PyErr_Occurred()) - return -1; - } - - /* This GType is implemented in Python, or we failed to set it via gi: - * do a straightforward set. */ - if (!set_property_from_pspec(obj, pspec, pvalue)) - return -1; - - return 0; -} - -static int -pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg) -{ - if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0) - return -1; - return 0; -} - -static PyObject* -pygobject_props_get_iter(PyGProps *self) -{ - PyGPropsIter *iter; - GObjectClass *class; - - iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type); - class = g_type_class_ref(self->gtype); - iter->props = g_object_class_list_properties(class, &iter->n_props); - iter->index = 0; - g_type_class_unref(class); - return (PyObject *) iter; -} - -static PyObject* -pygobject_props_dir(PyGProps *self) -{ - PyObject *ret; - GObjectClass *class; - - class = g_type_class_ref (self->gtype); - ret = build_parameter_list (class); - g_type_class_unref (class); - - return ret; -} - -static PyMethodDef pygobject_props_methods[] = { - { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS}, - { NULL, NULL, 0} -}; - - -static Py_ssize_t -PyGProps_length(PyGProps *self) -{ - GObjectClass *class; - GParamSpec **props; - guint n_props; - - class = g_type_class_ref(self->gtype); - props = g_object_class_list_properties(class, &n_props); - g_type_class_unref(class); - g_free(props); - - return (Py_ssize_t)n_props; -} - -static PySequenceMethods _PyGProps_as_sequence = { - (lenfunc) PyGProps_length, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject); - -static PyObject * -pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type) -{ - PyGProps *gprops; - - gprops = PyObject_GC_New(PyGProps, &PyGProps_Type); - if (obj == NULL || obj == Py_None) { - gprops->pygobject = NULL; - gprops->gtype = pyg_type_from_object(type); - } else { - if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) { - PyErr_SetString(PyExc_TypeError, "cannot use GObject property" - " descriptor on non-GObject instances"); - return NULL; - } - Py_INCREF(obj); - gprops->pygobject = (PyGObject *) obj; - gprops->gtype = pyg_type_from_object(obj); - } - return (PyObject *) gprops; -} - -/** - * pygobject_register_class: - * @dict: the module dictionary. A reference to the type will be stored here. - * @type_name: not used ? - * @gtype: the GType of the GObject subclass. - * @type: the Python type object for this wrapper. - * @static_bases: a tuple of Python type objects that are the bases of - * this type - * - * This function is used to register a Python type as the wrapper for - * a particular GObject subclass. It will also insert a reference to - * the wrapper class into the module dictionary passed as a reference, - * which simplifies initialisation. - */ -void -pygobject_register_class(PyObject *dict, const gchar *type_name, - GType gtype, PyTypeObject *type, - PyObject *static_bases) -{ - PyObject *o; - const char *class_name, *s; - PyObject *runtime_bases; - PyObject *bases_list, *bases, *mod_name; - int i; - - class_name = type->tp_name; - s = strrchr(class_name, '.'); - if (s != NULL) - class_name = s + 1; - - runtime_bases = pyg_type_get_bases(gtype); - if (static_bases) { - PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0); - bases_list = PySequence_List(static_bases); - /* we start at index 1 because we want to skip the primary - * base, otherwise we might get MRO conflict */ - for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i) - { - PyObject *base = PyTuple_GET_ITEM(runtime_bases, i); - int contains = PySequence_Contains(bases_list, base); - if (contains < 0) - PyErr_Print(); - else if (!contains) { - if (!PySequence_Contains(py_parent_type->tp_mro, base)) { -#if 0 - g_message("Adding missing base %s to type %s", - ((PyTypeObject *)base)->tp_name, type->tp_name); -#endif - PyList_Append(bases_list, base); - } - } - } - bases = PySequence_Tuple(bases_list); - Py_DECREF(bases_list); - Py_DECREF(runtime_bases); - } else - bases = runtime_bases; - - Py_TYPE(type) = PyGObject_MetaType; - type->tp_bases = bases; - if (G_LIKELY(bases)) { - type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0); - Py_INCREF(type->tp_base); - } - - pygobject_inherit_slots(type, bases, TRUE); - - if (PyType_Ready(type) < 0) { - g_warning ("couldn't make the type `%s' ready", type->tp_name); - return; - } - - /* Set type.__module__ to the name of the module, - * otherwise it'll default to 'gobject', see #376099 - */ - s = strrchr(type->tp_name, '.'); - if (s != NULL) { - mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name)); - PyDict_SetItemString(type->tp_dict, "__module__", mod_name); - Py_DECREF(mod_name); - } - - if (gtype) { - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(type->tp_dict, "__gtype__", o); - Py_DECREF(o); - - /* stash a pointer to the python class with the GType */ - Py_INCREF(type); - g_type_set_qdata(gtype, pygobject_class_key, type); - } - - /* set up __doc__ descriptor on type */ - PyDict_SetItemString(type->tp_dict, "__doc__", - pyg_object_descr_doc_get()); - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); -} - -static void -pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref) -{ - PyGObject *self; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - - /* Avoid thread safety problems by using qdata for wrapper retrieval - * instead of the user data argument. - * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223 - */ - self = (PyGObject *)g_object_get_qdata (object, pygobject_wrapper_key); - if (self) { - if (is_last_ref) - Py_DECREF(self); - else - Py_INCREF(self); - } - - pyglib_gil_state_release(state); -} - - /* Called when the inst_dict is first created; switches the - reference counting strategy to start using toggle ref to keep the - wrapper alive while the GObject lives. In contrast, while - inst_dict was NULL the python wrapper is allowed to die at - will and is recreated on demand. */ -static inline void -pygobject_switch_to_toggle_ref(PyGObject *self) -{ - g_assert(self->obj->ref_count >= 1); - - if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF) - return; /* already using toggle ref */ - self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF; - /* Note that add_toggle_ref will never immediately call back into - pyg_toggle_notify */ - Py_INCREF((PyObject *) self); - g_object_add_toggle_ref(self->obj, pyg_toggle_notify, NULL); - g_object_unref(self->obj); -} - -/* Called when an custom gobject is initalized via g_object_new instead of - its constructor. The next time the wrapper is access via - pygobject_new_full it will sink the floating reference instead of - adding a new reference and causing a leak */ - -void -pygobject_ref_float(PyGObject *self) -{ - /* should only be floated once */ - g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)); - - self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF; -} - -/* Called by gobject_new_full, if the floating flag is set remove it, otherwise - ref the pyobject */ -void -pygobject_ref_sink(PyGObject *self) -{ - if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF) - self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF; - else - Py_INCREF ( (PyObject *) self); -} - -/** - * pygobject_register_wrapper: - * @self: the wrapper instance - * - * In the constructor of PyGTK wrappers, this function should be - * called after setting the obj member. It will tie the wrapper - * instance to the GObject so that the same wrapper instance will - * always be used for this GObject instance. - */ -void -pygobject_register_wrapper(PyObject *self) -{ - PyGObject *gself; - - g_return_if_fail(self != NULL); - g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type)); - - gself = (PyGObject *)self; - - g_assert(gself->obj->ref_count >= 1); - /* save wrapper pointer so we can access it later */ - g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL); - if (gself->inst_dict) - pygobject_switch_to_toggle_ref(gself); -} - -static PyObject * -pyg_type_get_bases(GType gtype) -{ - GType *interfaces, parent_type, interface_type; - guint n_interfaces; - PyTypeObject *py_parent_type, *py_interface_type; - PyObject *bases; - int i; - - if (G_UNLIKELY(gtype == G_TYPE_OBJECT)) - return NULL; - - /* Lookup the parent type */ - parent_type = g_type_parent(gtype); - py_parent_type = pygobject_lookup_class(parent_type); - interfaces = g_type_interfaces(gtype, &n_interfaces); - bases = PyTuple_New(n_interfaces + 1); - /* We will always put the parent at the first position in bases */ - Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */ - PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type); - - /* And traverse interfaces */ - if (n_interfaces) { - for (i = 0; i < n_interfaces; i++) { - interface_type = interfaces[i]; - py_interface_type = pygobject_lookup_class(interface_type); - Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */ - PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type); - } - } - g_free(interfaces); - return bases; -} - -/** - * pygobject_new_with_interfaces - * @gtype: the GType of the GObject subclass. - * - * Creates a new PyTypeObject from the given GType with interfaces attached in - * bases. - * - * Returns: a PyTypeObject for the new type or NULL if it couldn't be created - */ -static PyTypeObject * -pygobject_new_with_interfaces(GType gtype) -{ - PyGILState_STATE state; - PyObject *o; - PyTypeObject *type; - PyObject *dict; - PyTypeObject *py_parent_type; - PyObject *bases; - PyObject *modules, *module; - gchar *type_name, *mod_name, *gtype_name; - - state = pyglib_gil_state_ensure(); - - bases = pyg_type_get_bases(gtype); - py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0); - - dict = PyDict_New(); - - o = pyg_type_wrapper_new(gtype); - PyDict_SetItemString(dict, "__gtype__", o); - Py_DECREF(o); - - /* set up __doc__ descriptor on type */ - PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get()); - - /* generate the pygtk module name and extract the base type name */ - gtype_name = (gchar*)g_type_name(gtype); - if (g_str_has_prefix(gtype_name, "Gtk")) { - mod_name = "gtk"; - gtype_name += 3; - type_name = g_strconcat(mod_name, ".", gtype_name, NULL); - } else if (g_str_has_prefix(gtype_name, "Gdk")) { - mod_name = "gtk.gdk"; - gtype_name += 3; - type_name = g_strconcat(mod_name, ".", gtype_name, NULL); - } else if (g_str_has_prefix(gtype_name, "Atk")) { - mod_name = "atk"; - gtype_name += 3; - type_name = g_strconcat(mod_name, ".", gtype_name, NULL); - } else if (g_str_has_prefix(gtype_name, "Pango")) { - mod_name = "pango"; - gtype_name += 5; - type_name = g_strconcat(mod_name, ".", gtype_name, NULL); - } else { - mod_name = "__main__"; - type_name = g_strconcat(mod_name, ".", gtype_name, NULL); - } - - type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type), - "sNN", type_name, bases, dict); - g_free(type_name); - - if (type == NULL) { - PyErr_Print(); - pyglib_gil_state_release(state); - return NULL; - } - - /* Workaround python tp_(get|set)attr slot inheritance bug. - * Fixes bug #144135. */ - if (!type->tp_getattr && py_parent_type->tp_getattr) { - type->tp_getattro = NULL; - type->tp_getattr = py_parent_type->tp_getattr; - } - if (!type->tp_setattr && py_parent_type->tp_setattr) { - type->tp_setattro = NULL; - type->tp_setattr = py_parent_type->tp_setattr; - } - /* override more python stupid hacks behind our back */ - type->tp_dealloc = py_parent_type->tp_dealloc; - type->tp_alloc = py_parent_type->tp_alloc; - type->tp_free = py_parent_type->tp_free; - type->tp_traverse = py_parent_type->tp_traverse; - type->tp_clear = py_parent_type->tp_clear; - - pygobject_inherit_slots(type, bases, FALSE); - - if (PyType_Ready(type) < 0) { - g_warning ("couldn't make the type `%s' ready", type->tp_name); - pyglib_gil_state_release(state); - return NULL; - } - /* insert type name in module dict */ - modules = PyImport_GetModuleDict(); - if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) { - if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0) - PyErr_Clear(); - } - - /* stash a pointer to the python class with the GType */ - Py_INCREF(type); - g_type_set_qdata(gtype, pygobject_class_key, type); - - pyglib_gil_state_release(state); - - return type; -} - -/* Pick appropriate value for given slot (at slot_offset inside - * PyTypeObject structure). It must be a pointer, e.g. a pointer to a - * function. We use the following heuristic: - * - * - Scan all types listed as bases of the type. - * - If for exactly one base type slot value is non-NULL and - * different from that of 'object' and 'GObject', set current type - * slot into that value. - * - Otherwise (if there is more than one such base type or none at - * all) don't touch it and live with Python default. - * - * The intention here is to propagate slot from custom wrappers to - * wrappers created at runtime when appropriate. We prefer to be on - * the safe side, so if there is potential collision (more than one - * custom slot value), we discard custom overrides altogether. - * - * When registering type with pygobject_register_class(), i.e. a type - * that has been manually created (likely with Codegen help), - * `check_for_present' should be set to TRUE. In this case, the - * function will never overwrite any non-NULL slots already present in - * the type. If `check_for_present' is FALSE, such non-NULL slots are - * though to be set by Python interpreter and so will be overwritten - * if heuristic above says so. - */ -static void -pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present) -{ - static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare), -#if PY_VERSION_HEX < 0x03000000 - offsetof(PyTypeObject, tp_compare), -#endif - offsetof(PyTypeObject, tp_richcompare), - offsetof(PyTypeObject, tp_hash), - offsetof(PyTypeObject, tp_iter), - offsetof(PyTypeObject, tp_repr), - offsetof(PyTypeObject, tp_str), - offsetof(PyTypeObject, tp_print) }; - int i; - - /* Happens when registering gobject.GObject itself, at least. */ - if (!bases) - return; - - for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i) - pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present); -} - -static void -pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset, - gboolean check_for_present) -{ -#define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset)) - - void *found_slot = NULL; - int num_bases = PyTuple_Size(bases); - int i; - - if (check_for_present && TYPE_SLOT(type) != NULL) { - /* We are requested to check if there is any custom slot value - * in this type already and there actually is. Don't - * overwrite it. - */ - return; - } - - for (i = 0; i < num_bases; ++i) { - PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i); - void *slot = TYPE_SLOT(base_type); - - if (slot == NULL) - continue; - if (slot == TYPE_SLOT(&PyGObject_Type) || - slot == TYPE_SLOT(&PyBaseObject_Type)) - continue; - - if (found_slot != NULL && found_slot != slot) { - /* We have a conflict: more than one base use different - * custom slots. To be on the safe side, we bail out. - */ - return; - } - - found_slot = slot; - } - - /* Only perform the final assignment if at least one base has a - * custom value. Otherwise just leave this type's slot untouched. - */ - if (found_slot != NULL) - TYPE_SLOT(type) = found_slot; - -#undef TYPE_SLOT -} - -/** - * pygobject_lookup_class: - * @gtype: the GType of the GObject subclass. - * - * This function looks up the wrapper class used to represent - * instances of a GObject represented by @gtype. If no wrapper class - * or interface has been registered for the given GType, then a new - * type will be created. - * - * Returns: The wrapper class for the GObject or NULL if the - * GType has no registered type and a new type couldn't be created - */ -PyTypeObject * -pygobject_lookup_class(GType gtype) -{ - PyTypeObject *py_type; - - if (gtype == G_TYPE_INTERFACE) - return &PyGInterface_Type; - - py_type = g_type_get_qdata(gtype, pygobject_class_key); - if (py_type == NULL) { - py_type = g_type_get_qdata(gtype, pyginterface_type_key); - - if (py_type == NULL) - py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype); - - if (py_type == NULL) { - py_type = pygobject_new_with_interfaces(gtype); - g_type_set_qdata(gtype, pyginterface_type_key, py_type); - } - } - - return py_type; -} - -/** - * pygobject_new_full: - * @obj: a GObject instance. - * @steal: whether to steal a ref from the GObject or add (sink) a new one. - * @g_class: the GObjectClass - * - * This function gets a reference to a wrapper for the given GObject - * instance. If a wrapper has already been created, a new reference - * to that wrapper will be returned. Otherwise, a wrapper instance - * will be created. - * - * Returns: a reference to the wrapper for the GObject. - */ -PyObject * -pygobject_new_full(GObject *obj, gboolean steal, gpointer g_class) -{ - PyGObject *self; - - if (obj == NULL) { - Py_RETURN_NONE; - } - - /* If the GObject already has a PyObject wrapper stashed in its qdata, re-use it. - */ - self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key); - if (self != NULL) { - /* Note the use of "pygobject_ref_sink" here only deals with PyObject - * wrapper ref counts and has nothing to do with GObject. - */ - pygobject_ref_sink(self); - - /* If steal is true, we also want to decref the incoming GObjects which - * already have a Python wrapper because the wrapper is already holding a - * strong reference. - */ - if (steal) - g_object_unref (obj); - - } else { - /* create wrapper */ - PyGObjectData *inst_data = pyg_object_peek_inst_data(obj); - PyTypeObject *tp; - if (inst_data) - tp = inst_data->type; - else { - if (g_class) - tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class)); - else - tp = pygobject_lookup_class(G_OBJECT_TYPE(obj)); - } - g_assert(tp != NULL); - - /* need to bump type refcount if created with - pygobject_new_with_interfaces(). fixes bug #141042 */ - if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(tp); - self = PyObject_GC_New(PyGObject, tp); - if (self == NULL) - return NULL; - self->inst_dict = NULL; - self->weakreflist = NULL; - self->private_flags.flags = 0; - self->obj = obj; - - /* If we are not stealing a ref or the object is floating, - * add a regular ref or sink the object. */ - if (g_object_is_floating (obj)) - self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING; - if (!steal || self->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) - g_object_ref_sink (obj); - - pygobject_register_wrapper((PyObject *)self); - PyObject_GC_Track((PyObject *)self); - } - - return (PyObject *)self; -} - - -PyObject * -pygobject_new(GObject *obj) -{ - return pygobject_new_full(obj, - /*steal=*/FALSE, - NULL); -} - -static void -pygobject_unwatch_closure(gpointer data, GClosure *closure) -{ - PyGObjectData *inst_data = data; - - inst_data->closures = g_slist_remove (inst_data->closures, closure); -} - -/** - * pygobject_watch_closure: - * @self: a GObject wrapper instance - * @closure: a GClosure to watch - * - * Adds a closure to the list of watched closures for the wrapper. - * The closure must be one returned by pyg_closure_new(). When the - * cycle GC traverses the wrapper instance, it will enumerate the - * references to Python objects stored in watched closures. If the - * cycle GC tells the wrapper to clear itself, the watched closures - * will be invalidated. - */ -void -pygobject_watch_closure(PyObject *self, GClosure *closure) -{ - PyGObject *gself; - PyGObjectData *data; - - g_return_if_fail(self != NULL); - g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type)); - g_return_if_fail(closure != NULL); - - gself = (PyGObject *)self; - data = pygobject_get_inst_data(gself); - g_return_if_fail(g_slist_find(data->closures, closure) == NULL); - data->closures = g_slist_prepend(data->closures, closure); - g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure); -} - - -/* -------------- PyGObject behaviour ----------------- */ - -PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject); - -static void -pygobject_dealloc(PyGObject *self) -{ - /* Untrack must be done first. This is because followup calls such as - * ClearWeakRefs could call into Python and cause new allocations to - * happen, which could in turn could trigger the garbage collector, - * which would then get confused as it is tracking this half-deallocated - * object. */ - PyObject_GC_UnTrack((PyObject *)self); - - PyObject_ClearWeakRefs((PyObject *)self); - /* this forces inst_data->type to be updated, which could prove - * important if a new wrapper has to be created and it is of a - * unregistered type */ - pygobject_get_inst_data(self); - pygobject_clear(self); - /* the following causes problems with subclassed types */ - /* Py_TYPE(self)->tp_free((PyObject *)self); */ - PyObject_GC_Del(self); -} - -static PyObject* -pygobject_richcompare(PyObject *self, PyObject *other, int op) -{ - int isinst; - - isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type); - if (isinst == -1) - return NULL; - if (!isinst) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type); - if (isinst == -1) - return NULL; - if (!isinst) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj, - ((PyGObject*)other)->obj, - op); -} - -static long -pygobject_hash(PyGObject *self) -{ - return (long)self->obj; -} - -static PyObject * -pygobject_repr(PyGObject *self) -{ - gchar buf[256]; - - g_snprintf(buf, sizeof(buf), - "<%s object at 0x%lx (%s at 0x%lx)>", - Py_TYPE(self)->tp_name, - (long)self, - self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized", - (long)self->obj); - return PYGLIB_PyUnicode_FromString(buf); -} - - -static int -pygobject_traverse(PyGObject *self, visitproc visit, void *arg) -{ - int ret = 0; - GSList *tmp; - PyGObjectData *data = pygobject_get_inst_data(self); - - if (self->inst_dict) ret = visit(self->inst_dict, arg); - if (ret != 0) return ret; - - if (data) { - - for (tmp = data->closures; tmp != NULL; tmp = tmp->next) { - PyGClosure *closure = tmp->data; - - if (closure->callback) ret = visit(closure->callback, arg); - if (ret != 0) return ret; - - if (closure->extra_args) ret = visit(closure->extra_args, arg); - if (ret != 0) return ret; - - if (closure->swap_data) ret = visit(closure->swap_data, arg); - if (ret != 0) return ret; - } - } - return ret; -} - -static inline int -pygobject_clear(PyGObject *self) -{ - if (self->obj) { - g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL); - if (self->inst_dict) { - g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, NULL); - self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF; - } else { - Py_BEGIN_ALLOW_THREADS; - g_object_unref(self->obj); - Py_END_ALLOW_THREADS; - } - self->obj = NULL; - } - Py_CLEAR(self->inst_dict); - return 0; -} - -static void -pygobject_free(PyObject *op) -{ - PyObject_GC_Del(op); -} - -gboolean -pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs, - guint *n_params, GParameter **params) -{ - *n_params = 0; - *params = NULL; - - if (kwargs) { - Py_ssize_t pos = 0; - PyObject *key; - PyObject *value; - - *params = g_new0(GParameter, PyDict_Size(kwargs)); - while (PyDict_Next(kwargs, &pos, &key, &value)) { - GParamSpec *pspec; - GParameter *param = &(*params)[*n_params]; - const gchar *key_str = PYGLIB_PyUnicode_AsString(key); - - pspec = g_object_class_find_property(class, key_str); - if (!pspec) { - PyErr_Format(PyExc_TypeError, - "gobject `%s' doesn't support property `%s'", - G_OBJECT_CLASS_NAME(class), key_str); - return FALSE; - } - g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) { - PyErr_Format(PyExc_TypeError, - "could not convert value for property `%s' from %s to %s", - key_str, Py_TYPE(value)->tp_name, - g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec))); - return FALSE; - } - param->name = g_strdup(key_str); - ++(*n_params); - } - } - return TRUE; -} - -/* ---------------- PyGObject methods ----------------- */ - -static int -pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - GType object_type; - guint n_params = 0, i; - GParameter *params = NULL; - GObjectClass *class; - - /* Only do GObject creation and property setting if the GObject hasn't - * already been created. The case where self->obj already exists can occur - * when C constructors are called directly (Gtk.Button.new_with_label) - * and we are simply wrapping the result with a PyGObject. - * In these cases we want to ignore any keyword arguments passed along - * to __init__ and simply return. - * - * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810 - */ - if (self->obj != NULL) - return 0; - - if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL)) - return -1; - - object_type = pyg_type_from_object((PyObject *)self); - if (!object_type) - return -1; - - if (G_TYPE_IS_ABSTRACT(object_type)) { - PyErr_Format(PyExc_TypeError, "cannot create instance of abstract " - "(non-instantiable) type `%s'", g_type_name(object_type)); - return -1; - } - - if ((class = g_type_class_ref (object_type)) == NULL) { - PyErr_SetString(PyExc_TypeError, - "could not get a reference to type class"); - return -1; - } - - if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms)) - goto cleanup; - - if (pygobject_constructv(self, n_params, params)) - PyErr_SetString(PyExc_RuntimeError, "could not create object"); - - cleanup: - for (i = 0; i < n_params; i++) { - g_free((gchar *) params[i].name); - g_value_unset(¶ms[i].value); - } - g_free(params); - g_type_class_unref(class); - - return (self->obj) ? 0 : -1; -} - -#define CHECK_GOBJECT(self) \ - if (!G_IS_OBJECT(self->obj)) { \ - PyErr_Format(PyExc_TypeError, \ - "object at %p of type %s is not initialized", \ - self, Py_TYPE(self)->tp_name); \ - return NULL; \ - } - -static PyObject * -pygobject_get_property(PyGObject *self, PyObject *args) -{ - gchar *param_name; - GParamSpec *pspec; - GValue value = { 0, }; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name)) - return NULL; - - CHECK_GOBJECT(self); - - pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), - param_name); - if (!pspec) { - PyErr_Format(PyExc_TypeError, - "object of type `%s' does not have property `%s'", - g_type_name(G_OBJECT_TYPE(self->obj)), param_name); - return NULL; - } - if (!(pspec->flags & G_PARAM_READABLE)) { - PyErr_Format(PyExc_TypeError, "property %s is not readable", - param_name); - return NULL; - } - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - Py_BEGIN_ALLOW_THREADS; - g_object_get_property(self->obj, param_name, &value); - Py_END_ALLOW_THREADS; - - ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); - g_value_unset(&value); - return ret; -} - -static PyObject * -pygobject_get_properties(PyGObject *self, PyObject *args) -{ - GObjectClass *class; - int len, i; - PyObject *tuple; - - if ((len = PyTuple_Size(args)) < 1) { - PyErr_SetString(PyExc_TypeError, "requires at least one argument"); - return NULL; - } - - tuple = PyTuple_New(len); - class = G_OBJECT_GET_CLASS(self->obj); - for (i = 0; i < len; i++) { - PyObject *py_property = PyTuple_GetItem(args, i); - gchar *property_name; - GParamSpec *pspec; - GValue value = { 0 }; - PyObject *item; - - if (!PYGLIB_PyUnicode_Check(py_property)) { - PyErr_SetString(PyExc_TypeError, - "Expected string argument for property."); - return NULL; - } - - property_name = PYGLIB_PyUnicode_AsString(py_property); - - pspec = g_object_class_find_property(class, - property_name); - if (!pspec) { - PyErr_Format(PyExc_TypeError, - "object of type `%s' does not have property `%s'", - g_type_name(G_OBJECT_TYPE(self->obj)), property_name); - return NULL; - } - if (!(pspec->flags & G_PARAM_READABLE)) { - PyErr_Format(PyExc_TypeError, "property %s is not readable", - property_name); - return NULL; - } - g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); - - Py_BEGIN_ALLOW_THREADS; - g_object_get_property(self->obj, property_name, &value); - Py_END_ALLOW_THREADS; - - item = pyg_value_as_pyobject(&value, TRUE); - PyTuple_SetItem(tuple, i, item); - - g_value_unset(&value); - } - - return tuple; -} - -static PyObject * -pygobject_set_property(PyGObject *self, PyObject *args) -{ - gchar *param_name; - GParamSpec *pspec; - PyObject *pvalue; - int ret = -1; - - if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name, - &pvalue)) - return NULL; - - CHECK_GOBJECT(self); - - pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), - param_name); - if (!pspec) { - PyErr_Format(PyExc_TypeError, - "object of type `%s' does not have property `%s'", - g_type_name(G_OBJECT_TYPE(self->obj)), param_name); - return NULL; - } - - ret = pygi_set_property_value (self, pspec, pvalue); - if (ret == 0) - goto done; - else if (PyErr_Occurred()) - return NULL; - - if (!set_property_from_pspec(self->obj, pspec, pvalue)) - return NULL; - -done: - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs) -{ - GObjectClass *class; - Py_ssize_t pos; - PyObject *value; - PyObject *key; - PyObject *result = NULL; - - CHECK_GOBJECT(self); - - class = G_OBJECT_GET_CLASS(self->obj); - - g_object_freeze_notify (G_OBJECT(self->obj)); - pos = 0; - - while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) { - gchar *key_str = PYGLIB_PyUnicode_AsString(key); - GParamSpec *pspec; - int ret = -1; - - pspec = g_object_class_find_property(class, key_str); - if (!pspec) { - gchar buf[512]; - - g_snprintf(buf, sizeof(buf), - "object `%s' doesn't support property `%s'", - g_type_name(G_OBJECT_TYPE(self->obj)), key_str); - PyErr_SetString(PyExc_TypeError, buf); - goto exit; - } - - ret = pygi_set_property_value (self, pspec, value); - if (ret != 0) { - /* Non-zero return code means that either an error occured ...*/ - if (PyErr_Occurred()) - goto exit; - - /* ... or the property couldn't be found , so let's try the default - * call. */ - if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value)) - goto exit; - } - } - - result = Py_None; - - exit: - g_object_thaw_notify (G_OBJECT(self->obj)); - Py_XINCREF(result); - return result; -} - -/* custom closure for gobject bindings */ -static void -pygbinding_closure_invalidate(gpointer data, GClosure *closure) -{ - PyGClosure *pc = (PyGClosure *)closure; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - Py_XDECREF(pc->callback); - Py_XDECREF(pc->extra_args); - pyglib_gil_state_release(state); - - pc->callback = NULL; - pc->extra_args = NULL; -} - -static void -pygbinding_marshal (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - PyGILState_STATE state; - PyGClosure *pc = (PyGClosure *)closure; - PyObject *params, *ret; - GValue *out_value; - - state = pyglib_gil_state_ensure(); - - /* construct Python tuple for the parameter values */ - params = PyTuple_New(2); - PyTuple_SetItem (params, 0, pyg_value_as_pyobject(¶m_values[0], FALSE)); - PyTuple_SetItem (params, 1, pyg_value_as_pyobject(¶m_values[1], FALSE)); - - /* params passed to function may have extra arguments */ - if (pc->extra_args) { - PyObject *tuple = params; - params = PySequence_Concat(tuple, pc->extra_args); - Py_DECREF(tuple); - } - ret = PyObject_CallObject(pc->callback, params); - if (!ret) { - PyErr_Print (); - goto out; - } else if (ret == Py_None) { - g_value_set_boolean (return_value, FALSE); - goto out; - } - - out_value = g_value_get_boxed (¶m_values[2]); - if (pyg_value_from_pyobject (out_value, ret) != 0) { - PyErr_SetString (PyExc_ValueError, "can't convert value"); - PyErr_Print (); - g_value_set_boolean (return_value, FALSE); - } else { - g_value_set_boolean (return_value, TRUE); - } - - Py_DECREF(ret); - -out: - Py_DECREF(params); - pyglib_gil_state_release(state); -} - -static GClosure * -pygbinding_closure_new (PyObject *callback, PyObject *extra_args) -{ - GClosure *closure; - - g_return_val_if_fail(callback != NULL, NULL); - closure = g_closure_new_simple(sizeof(PyGClosure), NULL); - g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate); - g_closure_set_marshal(closure, pygbinding_marshal); - Py_INCREF(callback); - ((PyGClosure *)closure)->callback = callback; - if (extra_args && extra_args != Py_None) { - Py_INCREF(extra_args); - if (!PyTuple_Check(extra_args)) { - PyObject *tmp = PyTuple_New(1); - PyTuple_SetItem(tmp, 0, extra_args); - extra_args = tmp; - } - ((PyGClosure *)closure)->extra_args = extra_args; - } - return closure; -} - -static PyObject * -pygobject_bind_property(PyGObject *self, PyObject *args) -{ - gchar *source_name, *target_name; - gchar *source_canon, *target_canon; - PyObject *target, *source_repr, *target_repr; - PyObject *transform_to, *transform_from, *user_data = NULL; - GBinding *binding; - GBindingFlags flags = G_BINDING_DEFAULT; - GClosure *to_closure = NULL, *from_closure = NULL; - - transform_from = NULL; - transform_to = NULL; - - if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property", - &source_name, &target, &target_name, &flags, - &transform_to, &transform_from, &user_data)) - return NULL; - - CHECK_GOBJECT(self); - if (!PyObject_TypeCheck(target, &PyGObject_Type)) { - PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject"); - return NULL; - } - - if (transform_to && transform_to != Py_None) { - if (!PyCallable_Check (transform_to)) { - PyErr_SetString (PyExc_TypeError, - "transform_to must be callable or None"); - return NULL; - } - to_closure = pygbinding_closure_new (transform_to, user_data); - } - - if (transform_from && transform_from != Py_None) { - if (!PyCallable_Check (transform_from)) { - PyErr_SetString (PyExc_TypeError, - "transform_from must be callable or None"); - return NULL; - } - from_closure = pygbinding_closure_new (transform_from, user_data); - } - - /* Canonicalize underscores to hyphens. Note the results must be freed. */ - source_canon = g_strdelimit(g_strdup(source_name), "_", '-'); - target_canon = g_strdelimit(g_strdup(target_name), "_", '-'); - - binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon, - pygobject_get(target), target_canon, - flags, to_closure, from_closure); - g_free(source_canon); - g_free(target_canon); - source_canon = target_canon = NULL; - - if (binding == NULL) { - source_repr = PyObject_Repr((PyObject*)self); - target_repr = PyObject_Repr(target); - PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s", - PYGLIB_PyUnicode_AsString(source_repr), source_name, - PYGLIB_PyUnicode_AsString(target_repr), target_name); - Py_DECREF(source_repr); - Py_DECREF(target_repr); - return NULL; - } - - return pygobject_new (G_OBJECT (binding)); -} - -static PyObject * -connect_helper(PyGObject *self, gchar *name, PyObject *callback, PyObject *extra_args, PyObject *object, gboolean after) -{ - guint sigid; - GQuark detail = 0; - GClosure *closure = NULL; - gulong handlerid; - GSignalQuery query_info; - - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &sigid, &detail, TRUE)) { - PyObject *repr = PyObject_Repr((PyObject*)self); - PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", - PYGLIB_PyUnicode_AsString(repr), - name); - Py_DECREF(repr); - return NULL; - } - - g_signal_query (sigid, &query_info); - if (!pyg_gtype_is_custom (query_info.itype)) { - /* The signal is implemented by a non-Python class, probably - * something in the gi repository. */ - closure = pygi_signal_closure_new (self, query_info.itype, - query_info.signal_name, callback, - extra_args, object); - } - - if (!closure) { - /* The signal is either implemented at the Python level, or it comes - * from a foreign class that we don't have introspection data for. */ - closure = pyg_closure_new (callback, extra_args, object); - } - - pygobject_watch_closure((PyObject *)self, closure); - handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, - closure, after); - return PyLong_FromUnsignedLong(handlerid); -} - -static PyObject * -pygobject_connect(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *ret; - gchar *name; - guint len; - - len = PyTuple_Size(args); - if (len < 2) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect requires at least 2 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 2); - if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - - CHECK_GOBJECT(self); - - extra_args = PySequence_GetSlice(args, 2, len); - if (extra_args == NULL) - return NULL; - - ret = connect_helper(self, name, callback, extra_args, NULL, FALSE); - Py_DECREF(extra_args); - return ret; -} - -static PyObject * -pygobject_connect_after(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *ret; - gchar *name; - Py_ssize_t len; - - len = PyTuple_Size(args); - if (len < 2) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_after requires at least 2 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 2); - if (!PyArg_ParseTuple(first, "sO:GObject.connect_after", - &name, &callback)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - - CHECK_GOBJECT(self); - - extra_args = PySequence_GetSlice(args, 2, len); - if (extra_args == NULL) - return NULL; - - ret = connect_helper(self, name, callback, extra_args, NULL, TRUE); - Py_DECREF(extra_args); - return ret; -} - -static PyObject * -pygobject_connect_object(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *object, *ret; - gchar *name; - Py_ssize_t len; - - len = PyTuple_Size(args); - if (len < 3) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_object requires at least 3 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 3); - if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object", - &name, &callback, &object)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - - CHECK_GOBJECT(self); - - extra_args = PySequence_GetSlice(args, 3, len); - if (extra_args == NULL) - return NULL; - - ret = connect_helper(self, name, callback, extra_args, object, FALSE); - Py_DECREF(extra_args); - return ret; -} - -static PyObject * -pygobject_connect_object_after(PyGObject *self, PyObject *args) -{ - PyObject *first, *callback, *extra_args, *object, *ret; - gchar *name; - Py_ssize_t len; - - len = PyTuple_Size(args); - if (len < 3) { - PyErr_SetString(PyExc_TypeError, - "GObject.connect_object_after requires at least 3 arguments"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 3); - if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after", - &name, &callback, &object)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - if (!PyCallable_Check(callback)) { - PyErr_SetString(PyExc_TypeError, "second argument must be callable"); - return NULL; - } - - CHECK_GOBJECT(self); - - extra_args = PySequence_GetSlice(args, 3, len); - if (extra_args == NULL) - return NULL; - - ret = connect_helper(self, name, callback, extra_args, object, TRUE); - Py_DECREF(extra_args); - return ret; -} - -static PyObject * -pygobject_emit(PyGObject *self, PyObject *args) -{ - guint signal_id, i, j; - Py_ssize_t len; - GQuark detail; - PyObject *first, *py_ret, *repr = NULL; - gchar *name; - GSignalQuery query; - GValue *params, ret = { 0, }; - - len = PyTuple_Size(args); - if (len < 1) { - PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg"); - return NULL; - } - first = PySequence_GetSlice(args, 0, 1); - if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) { - Py_DECREF(first); - return NULL; - } - Py_DECREF(first); - - CHECK_GOBJECT(self); - - if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), - &signal_id, &detail, TRUE)) { - repr = PyObject_Repr((PyObject*)self); - PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", - PYGLIB_PyUnicode_AsString(repr), - name); - Py_DECREF(repr); - return NULL; - } - g_signal_query(signal_id, &query); - if (len != query.n_params + 1) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "%d parameters needed for signal %s; %ld given", - query.n_params, name, (long int) (len - 1)); - PyErr_SetString(PyExc_TypeError, buf); - return NULL; - } - - params = g_new0(GValue, query.n_params + 1); - g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); - g_value_set_object(¶ms[0], G_OBJECT(self->obj)); - - for (i = 0; i < query.n_params; i++) - g_value_init(¶ms[i + 1], - query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); - for (i = 0; i < query.n_params; i++) { - PyObject *item = PyTuple_GetItem(args, i+1); - - if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { - gchar buf[128]; - g_snprintf(buf, sizeof(buf), - "could not convert type %s to %s required for parameter %d", - Py_TYPE(item)->tp_name, - G_VALUE_TYPE_NAME(¶ms[i+1]), i); - PyErr_SetString(PyExc_TypeError, buf); - - for (j = 0; j <= i; j++) - g_value_unset(¶ms[j]); - - g_free(params); - return NULL; - } - } - - if (query.return_type != G_TYPE_NONE) - g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); - - g_signal_emitv(params, signal_id, detail, &ret); - - for (i = 0; i < query.n_params + 1; i++) - g_value_unset(¶ms[i]); - - g_free(params); - if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) { - py_ret = pyg_value_as_pyobject(&ret, TRUE); - g_value_unset(&ret); - } else { - Py_INCREF(Py_None); - py_ret = Py_None; - } - - return py_ret; -} - -static PyObject * -pygobject_chain_from_overridden(PyGObject *self, PyObject *args) -{ - GSignalInvocationHint *ihint; - guint signal_id, i; - Py_ssize_t len; - PyObject *py_ret; - const gchar *name; - GSignalQuery query; - GValue *params, ret = { 0, }; - - CHECK_GOBJECT(self); - - ihint = g_signal_get_invocation_hint(self->obj); - if (!ihint) { - PyErr_SetString(PyExc_TypeError, "could not find signal invocation " - "information for this object."); - return NULL; - } - - signal_id = ihint->signal_id; - name = g_signal_name(signal_id); - - len = PyTuple_Size(args); - if (signal_id == 0) { - PyErr_SetString(PyExc_TypeError, "unknown signal name"); - return NULL; - } - g_signal_query(signal_id, &query); - if (len != query.n_params) { - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), - "%d parameters needed for signal %s; %ld given", - query.n_params, name, (long int) len); - PyErr_SetString(PyExc_TypeError, buf); - return NULL; - } - params = g_new0(GValue, query.n_params + 1); - g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); - g_value_set_object(¶ms[0], G_OBJECT(self->obj)); - - for (i = 0; i < query.n_params; i++) - g_value_init(¶ms[i + 1], - query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); - for (i = 0; i < query.n_params; i++) { - PyObject *item = PyTuple_GetItem(args, i); - - if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) { - g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void)); - } - else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { - gchar buf[128]; - - 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(¶ms[i+1])), i); - PyErr_SetString(PyExc_TypeError, buf); - for (i = 0; i < query.n_params + 1; i++) - g_value_unset(¶ms[i]); - g_free(params); - return NULL; - } - } - if (query.return_type != G_TYPE_NONE) - g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); - g_signal_chain_from_overridden(params, &ret); - for (i = 0; i < query.n_params + 1; i++) - g_value_unset(¶ms[i]); - g_free(params); - if (query.return_type != G_TYPE_NONE) { - py_ret = pyg_value_as_pyobject(&ret, TRUE); - g_value_unset(&ret); - } else { - Py_INCREF(Py_None); - py_ret = Py_None; - } - return py_ret; -} - - -static PyObject * -pygobject_weak_ref(PyGObject *self, PyObject *args) -{ - int len; - PyObject *callback = NULL, *user_data = NULL; - PyObject *retval; - - CHECK_GOBJECT(self); - - if ((len = PySequence_Length(args)) >= 1) { - callback = PySequence_ITEM(args, 0); - user_data = PySequence_GetSlice(args, 1, len); - } - retval = pygobject_weak_ref_new(self->obj, callback, user_data); - Py_XDECREF(callback); - Py_XDECREF(user_data); - return retval; -} - - -static PyObject * -pygobject_copy(PyGObject *self) -{ - PyErr_SetString(PyExc_TypeError, - "GObject descendants' instances are non-copyable"); - return NULL; -} - -static PyObject * -pygobject_deepcopy(PyGObject *self, PyObject *args) -{ - PyErr_SetString(PyExc_TypeError, - "GObject descendants' instances are non-copyable"); - return NULL; -} - - -static PyObject * -pygobject_disconnect_by_func(PyGObject *self, PyObject *args) -{ - PyObject *pyfunc = NULL, *repr = NULL; - GClosure *closure = NULL; - guint retval; - - CHECK_GOBJECT(self); - - if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc)) - return NULL; - - if (!PyCallable_Check(pyfunc)) { - PyErr_SetString(PyExc_TypeError, "first argument must be callable"); - return NULL; - } - - closure = gclosure_from_pyfunc(self, pyfunc); - if (!closure) { - repr = PyObject_Repr((PyObject*)pyfunc); - PyErr_Format(PyExc_TypeError, "nothing connected to %s", - PYGLIB_PyUnicode_AsString(repr)); - Py_DECREF(repr); - return NULL; - } - - retval = g_signal_handlers_disconnect_matched(self->obj, - G_SIGNAL_MATCH_CLOSURE, - 0, 0, - closure, - NULL, NULL); - return PYGLIB_PyLong_FromLong(retval); -} - -static PyObject * -pygobject_handler_block_by_func(PyGObject *self, PyObject *args) -{ - PyObject *pyfunc = NULL, *repr = NULL; - GClosure *closure = NULL; - guint retval; - - CHECK_GOBJECT(self); - - if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc)) - return NULL; - - if (!PyCallable_Check(pyfunc)) { - PyErr_SetString(PyExc_TypeError, "first argument must be callable"); - return NULL; - } - - closure = gclosure_from_pyfunc(self, pyfunc); - if (!closure) { - repr = PyObject_Repr((PyObject*)pyfunc); - PyErr_Format(PyExc_TypeError, "nothing connected to %s", - PYGLIB_PyUnicode_AsString(repr)); - Py_DECREF(repr); - return NULL; - } - - retval = g_signal_handlers_block_matched(self->obj, - G_SIGNAL_MATCH_CLOSURE, - 0, 0, - closure, - NULL, NULL); - return PYGLIB_PyLong_FromLong(retval); -} - -static PyObject * -pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args) -{ - PyObject *pyfunc = NULL, *repr = NULL; - GClosure *closure = NULL; - guint retval; - - CHECK_GOBJECT(self); - - if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc)) - return NULL; - - if (!PyCallable_Check(pyfunc)) { - PyErr_SetString(PyExc_TypeError, "first argument must be callable"); - return NULL; - } - - closure = gclosure_from_pyfunc(self, pyfunc); - if (!closure) { - repr = PyObject_Repr((PyObject*)pyfunc); - PyErr_Format(PyExc_TypeError, "nothing connected to %s", - PYGLIB_PyUnicode_AsString(repr)); - Py_DECREF(repr); - return NULL; - } - - retval = g_signal_handlers_unblock_matched(self->obj, - G_SIGNAL_MATCH_CLOSURE, - 0, 0, - closure, - NULL, NULL); - return PYGLIB_PyLong_FromLong(retval); -} - - -static PyMethodDef pygobject_methods[] = { - { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS }, - { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS }, - { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS }, - { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS }, - { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS }, - { "connect", (PyCFunction)pygobject_connect, METH_VARARGS }, - { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS }, - { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS }, - { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS }, - { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS }, - { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS }, - { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS }, - { "emit", (PyCFunction)pygobject_emit, METH_VARARGS }, - { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS }, - { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS }, - { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS }, - { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS }, - { NULL, NULL, 0 } -}; - - -static PyObject * -pygobject_get_dict(PyGObject *self, void *closure) -{ - if (self->inst_dict == NULL) { - self->inst_dict = PyDict_New(); - if (self->inst_dict == NULL) - return NULL; - if (G_LIKELY(self->obj)) - pygobject_switch_to_toggle_ref(self); - } - Py_INCREF(self->inst_dict); - return self->inst_dict; -} - -static PyObject * -pygobject_get_refcount(PyGObject *self, void *closure) -{ - if (self->obj == NULL) { - PyErr_Format(PyExc_TypeError, "GObject instance is not yet created"); - return NULL; - } - return PYGLIB_PyLong_FromLong(self->obj->ref_count); -} - -static PyObject * -pygobject_get_pointer(PyGObject *self, void *closure) -{ - return PYGLIB_CPointer_WrapPointer (self->obj, NULL); -} - -static int -pygobject_setattro(PyObject *self, PyObject *name, PyObject *value) -{ - int res; - PyGObject *gself = (PyGObject *) self; - PyObject *inst_dict_before = gself->inst_dict; - /* call parent type's setattro */ - res = PyGObject_Type.tp_base->tp_setattro(self, name, value); - if (inst_dict_before == NULL && gself->inst_dict != NULL) { - if (G_LIKELY(gself->obj)) - pygobject_switch_to_toggle_ref(gself); - } - return res; -} - -static PyGetSetDef pygobject_getsets[] = { - { "__dict__", (getter)pygobject_get_dict, (setter)0 }, - { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, }, - { "__gpointer__", (getter)pygobject_get_pointer, (setter)0, }, - { NULL, 0, 0 } -}; - -/* ------------------------------------ */ -/* ****** GObject weak reference ****** */ -/* ------------------------------------ */ - -typedef struct { - PyObject_HEAD - GObject *obj; - PyObject *callback; - PyObject *user_data; - gboolean have_floating_ref; -} PyGObjectWeakRef; - -PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef); - -static int -pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg) -{ - if (self->callback && visit(self->callback, arg) < 0) - return -1; - if (self->user_data && visit(self->user_data, arg) < 0) - return -1; - return 0; -} - -static void -pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy) -{ - self->obj = NULL; - if (self->callback) { - PyObject *retval; - PyGILState_STATE state = pyglib_gil_state_ensure(); - retval = PyObject_Call(self->callback, self->user_data, NULL); - if (retval) { - if (retval != Py_None) - PyErr_Format(PyExc_TypeError, - "GObject weak notify callback returned a value" - " of type %s, should return None", - Py_TYPE(retval)->tp_name); - Py_DECREF(retval); - PyErr_Print(); - } else - PyErr_Print(); - Py_CLEAR(self->callback); - Py_CLEAR(self->user_data); - if (self->have_floating_ref) { - self->have_floating_ref = FALSE; - Py_DECREF((PyObject *) self); - } - pyglib_gil_state_release(state); - } -} - -static inline int -pygobject_weak_ref_clear(PyGObjectWeakRef *self) -{ - Py_CLEAR(self->callback); - Py_CLEAR(self->user_data); - if (self->obj) { - g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); - self->obj = NULL; - } - return 0; -} - -static void -pygobject_weak_ref_dealloc(PyGObjectWeakRef *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - pygobject_weak_ref_clear(self); - PyObject_GC_Del(self); -} - -static PyObject * -pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data) -{ - PyGObjectWeakRef *self; - - self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type); - self->callback = callback; - self->user_data = user_data; - Py_XINCREF(self->callback); - Py_XINCREF(self->user_data); - self->obj = obj; - g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); - if (callback != NULL) { - /* when we have a callback, we should INCREF the weakref - * object to make it stay alive even if it goes out of scope */ - self->have_floating_ref = TRUE; - Py_INCREF((PyObject *) self); - } - return (PyObject *) self; -} - -static PyObject * -pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args) -{ - if (!self->obj) { - PyErr_SetString(PyExc_ValueError, "weak ref already unreffed"); - return NULL; - } - g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); - self->obj = NULL; - if (self->have_floating_ref) { - self->have_floating_ref = FALSE; - Py_DECREF(self); - } - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef pygobject_weak_ref_methods[] = { - { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS}, - { NULL, NULL, 0} -}; - -static PyObject * -pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw) -{ - static char *argnames[] = {NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames)) - return NULL; - - if (self->obj) - return pygobject_new(self->obj); - else { - Py_INCREF(Py_None); - return Py_None; - } -} - -static gpointer -pyobject_copy(gpointer boxed) -{ - PyObject *object = boxed; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - Py_INCREF(object); - pyglib_gil_state_release(state); - return object; -} - -static void -pyobject_free(gpointer boxed) -{ - PyObject *object = boxed; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - Py_DECREF(object); - pyglib_gil_state_release(state); -} - -void -pygobject_object_register_types(PyObject *d) -{ - PyObject *o, *descr; - - pygobject_custom_key = g_quark_from_static_string("PyGObject::custom"); - pygobject_class_key = g_quark_from_static_string("PyGObject::class"); - pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init"); - pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper"); - pygobject_has_updated_constructor_key = - g_quark_from_static_string("PyGObject::has-updated-constructor"); - pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data"); - - /* GObject */ - if (!PY_TYPE_OBJECT) - PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject", - pyobject_copy, - pyobject_free); - PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc; - PyGObject_Type.tp_richcompare = pygobject_richcompare; - PyGObject_Type.tp_repr = (reprfunc)pygobject_repr; - PyGObject_Type.tp_hash = (hashfunc)pygobject_hash; - PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro; - PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC); - PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse; - PyGObject_Type.tp_clear = (inquiry)pygobject_clear; - PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist); - PyGObject_Type.tp_methods = pygobject_methods; - PyGObject_Type.tp_getset = pygobject_getsets; - PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict); - PyGObject_Type.tp_init = (initproc)pygobject_init; - PyGObject_Type.tp_free = (freefunc)pygobject_free; - PyGObject_Type.tp_alloc = PyType_GenericAlloc; - PyGObject_Type.tp_new = PyType_GenericNew; - pygobject_register_class(d, "GObject", G_TYPE_OBJECT, - &PyGObject_Type, NULL); - PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__", - pyg_object_descr_doc_get()); - - /* GProps */ - PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc; - PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence; - PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro; - PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro; - PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; - PyGProps_Type.tp_doc = "The properties of the GObject accessible as " - "Python attributes."; - PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse; - PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter; - PyGProps_Type.tp_methods = pygobject_props_methods; - if (PyType_Ready(&PyGProps_Type) < 0) - return; - - /* GPropsDescr */ - PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get; - if (PyType_Ready(&PyGPropsDescr_Type) < 0) - return; - descr = PyObject_New(PyObject, &PyGPropsDescr_Type); - PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr); - PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__", - o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject")); - Py_DECREF(o); - - /* GPropsIter */ - PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc; - PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGPropsIter_Type.tp_doc = "GObject properties iterator"; - PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next; - if (PyType_Ready(&PyGPropsIter_Type) < 0) - return; - - PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc; - PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call; - PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; - PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference"; - PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse; - PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear; - PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods; - if (PyType_Ready(&PyGObjectWeakRef_Type) < 0) - return; - PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type); -} diff --git a/gi/_gobject/pygobject.h b/gi/_gobject/pygobject.h deleted file mode 100644 index 76b8b11..0000000 --- a/gi/_gobject/pygobject.h +++ /dev/null @@ -1,636 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- */ -#ifndef _PYGOBJECT_H_ -#define _PYGOBJECT_H_ - -#include - -#include -#include - -G_BEGIN_DECLS - -/* PyGClosure is a _private_ structure */ -typedef void (* PyClosureExceptionHandler) (GValue *ret, guint n_param_values, const GValue *params); -typedef struct _PyGClosure PyGClosure; -typedef struct _PyGObjectData PyGObjectData; - -struct _PyGClosure { - GClosure closure; - PyObject *callback; - PyObject *extra_args; /* tuple of extra args to pass to callback */ - PyObject *swap_data; /* other object for gtk_signal_connect__object */ - PyClosureExceptionHandler exception_handler; -}; - -typedef enum { - PYGOBJECT_USING_TOGGLE_REF = 1 << 0, - PYGOBJECT_IS_FLOATING_REF = 1 << 1, - PYGOBJECT_GOBJECT_WAS_FLOATING = 1 << 2, -} PyGObjectFlags; - - /* closures is just an alias for what is found in the - * PyGObjectData */ -typedef struct { - PyObject_HEAD - GObject *obj; - PyObject *inst_dict; /* the instance dictionary -- must be last */ - PyObject *weakreflist; /* list of weak references */ - - /*< private >*/ - /* using union to preserve ABI compatibility (structure size - * must not change) */ - union { - GSList *closures; /* stale field; no longer updated DO-NOT-USE! */ - PyGObjectFlags flags; - } private_flags; - -} PyGObject; - -#define pygobject_get(v) (((PyGObject *)(v))->obj) -#define pygobject_check(v,base) (PyObject_TypeCheck(v,base)) - -typedef struct { - PyObject_HEAD - gpointer boxed; - GType gtype; - gboolean free_on_dealloc; -} PyGBoxed; - -#define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed) -#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode) - -typedef struct { - PyObject_HEAD - gpointer pointer; - GType gtype; -} PyGPointer; - -#define pyg_pointer_get(v,t) ((t *)((PyGPointer *)(v))->pointer) -#define pyg_pointer_check(v,typecode) (PyObject_TypeCheck(v, &PyGPointer_Type) && ((PyGPointer *)(v))->gtype == typecode) - -typedef void (*PyGFatalExceptionFunc) (void); -typedef void (*PyGThreadBlockFunc) (void); - -typedef struct { - PyObject_HEAD - GParamSpec *pspec; -} PyGParamSpec; - -#define PyGParamSpec_Get(v) (((PyGParamSpec *)v)->pspec) -#define PyGParamSpec_Check(v) (PyObject_TypeCheck(v, &PyGParamSpec_Type)) - -typedef int (*PyGClassInitFunc) (gpointer gclass, PyTypeObject *pyclass); -typedef PyTypeObject * (*PyGTypeRegistrationFunction) (const gchar *name, - gpointer data); - -struct _PyGObject_Functions { - /* - * All field names in here are considered private, - * use the macros below instead, which provides stability - */ - void (* register_class)(PyObject *dict, const gchar *class_name, - GType gtype, PyTypeObject *type, PyObject *bases); - void (* register_wrapper)(PyObject *self); - PyTypeObject *(* lookup_class)(GType type); - PyObject *(* newgobj)(GObject *obj); - - GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args, - PyObject *swap_data); - void (* object_watch_closure)(PyObject *self, GClosure *closure); - GDestroyNotify destroy_notify; - - GType (* type_from_object)(PyObject *obj); - PyObject *(* type_wrapper_new)(GType type); - - gint (* enum_get_value)(GType enum_type, PyObject *obj, gint *val); - gint (* flags_get_value)(GType flag_type, PyObject *obj, guint *val); - void (* register_gtype_custom)(GType gtype, - PyObject *(* from_func)(const GValue *value), - int (* to_func)(GValue *value, PyObject *obj)); - int (* value_from_pyobject)(GValue *value, PyObject *obj); - PyObject *(* value_as_pyobject)(const GValue *value, gboolean copy_boxed); - - void (* register_interface)(PyObject *dict, const gchar *class_name, - GType gtype, PyTypeObject *type); - - PyTypeObject *boxed_type; - void (* register_boxed)(PyObject *dict, const gchar *class_name, - GType boxed_type, PyTypeObject *type); - PyObject *(* boxed_new)(GType boxed_type, gpointer boxed, - gboolean copy_boxed, gboolean own_ref); - - PyTypeObject *pointer_type; - void (* register_pointer)(PyObject *dict, const gchar *class_name, - GType pointer_type, PyTypeObject *type); - PyObject *(* pointer_new)(GType boxed_type, gpointer pointer); - - void (* enum_add_constants)(PyObject *module, GType enum_type, - const gchar *strip_prefix); - void (* flags_add_constants)(PyObject *module, GType flags_type, - const gchar *strip_prefix); - - const gchar *(* constant_strip_prefix)(const gchar *name, - const gchar *strip_prefix); - - gboolean (* error_check)(GError **error); - - /* hooks to register handlers for getting GDK threads to cooperate - * with python threading */ - void (* set_thread_block_funcs) (PyGThreadBlockFunc block_threads_func, - PyGThreadBlockFunc unblock_threads_func); - PyGThreadBlockFunc block_threads; - PyGThreadBlockFunc unblock_threads; - - PyTypeObject *paramspec_type; - PyObject *(* paramspec_new)(GParamSpec *spec); - GParamSpec *(*paramspec_get)(PyObject *tuple); - int (*pyobj_to_unichar_conv)(PyObject *pyobj, void* ptr); - gboolean (*parse_constructor_args)(GType obj_type, - char **arg_names, - char **prop_names, - GParameter *params, - guint *nparams, - PyObject **py_args); - PyObject *(* param_gvalue_as_pyobject) (const GValue* gvalue, - gboolean copy_boxed, - const GParamSpec* pspec); - int (* gvalue_from_param_pyobject) (GValue* value, - PyObject* py_obj, - const GParamSpec* pspec); - PyTypeObject *enum_type; - PyObject *(*enum_add)(PyObject *module, - const char *type_name_, - const char *strip_prefix, - GType gtype); - PyObject* (*enum_from_gtype)(GType gtype, int value); - - PyTypeObject *flags_type; - PyObject *(*flags_add)(PyObject *module, - const char *type_name_, - const char *strip_prefix, - GType gtype); - PyObject* (*flags_from_gtype)(GType gtype, guint value); - - gboolean threads_enabled; - int (*enable_threads) (void); - - int (*gil_state_ensure) (void); - void (*gil_state_release) (int flag); - - void (*register_class_init) (GType gtype, PyGClassInitFunc class_init); - void (*register_interface_info) (GType gtype, const GInterfaceInfo *info); - void (*closure_set_exception_handler) (GClosure *closure, PyClosureExceptionHandler handler); - - void (*add_warning_redirection) (const char *domain, - PyObject *warning); - void (*disable_warning_redirections) (void); - - /* type_register_custom API now removed, but leave a pointer here to not - * break ABI. */ - void *_type_register_custom; - - gboolean (*gerror_exception_check) (GError **error); - PyObject* (*option_group_new) (GOptionGroup *group); - GType (* type_from_object_strict) (PyObject *obj, gboolean strict); - - PyObject *(* newgobj_full)(GObject *obj, gboolean steal, gpointer g_class); - PyTypeObject *object_type; - int (* value_from_pyobject_with_error)(GValue *value, PyObject *obj); -}; - - -#ifdef DISABLE_THREADING -# define pyg_threads_enabled FALSE -# define pyg_gil_state_ensure() 0 -# define pyg_gil_state_release(state) -# define pyg_begin_allow_threads G_STMT_START { -# define pyg_end_allow_threads } G_STMT_END -#else -# define pyg_threads_enabled TRUE -# define pyg_gil_state_ensure PyGILState_Ensure -# define pyg_gil_state_release PyGILState_Release -# define pyg_begin_allow_threads Py_BEGIN_ALLOW_THREADS -# define pyg_end_allow_threads Py_END_ALLOW_THREADS -#endif - -/* Deprecated, only available for API compatibility. */ -#define pyg_enable_threads() -#define pyg_set_thread_block_funcs(a, b) -#define pyg_block_threads() -#define pyg_unblock_threads() - - -#ifndef _INSIDE_PYGOBJECT_ - -#if defined(NO_IMPORT) || defined(NO_IMPORT_PYGOBJECT) -extern struct _PyGObject_Functions *_PyGObject_API; -#else -struct _PyGObject_Functions *_PyGObject_API; -#endif - -#define pygobject_register_class (_PyGObject_API->register_class) -#define pygobject_register_wrapper (_PyGObject_API->register_wrapper) -#define pygobject_lookup_class (_PyGObject_API->lookup_class) -#define pygobject_new (_PyGObject_API->newgobj) -#define pygobject_new_full (_PyGObject_API->newgobj_full) -#define PyGObject_Type (*_PyGObject_API->object_type) -#define pyg_closure_new (_PyGObject_API->closure_new) -#define pygobject_watch_closure (_PyGObject_API->object_watch_closure) -#define pyg_closure_set_exception_handler (_PyGObject_API->closure_set_exception_handler) -#define pyg_destroy_notify (_PyGObject_API->destroy_notify) -#define pyg_type_from_object_strict (_PyGObject_API->type_from_object_strict) -#define pyg_type_from_object (_PyGObject_API->type_from_object) -#define pyg_type_wrapper_new (_PyGObject_API->type_wrapper_new) -#define pyg_enum_get_value (_PyGObject_API->enum_get_value) -#define pyg_flags_get_value (_PyGObject_API->flags_get_value) -#define pyg_register_gtype_custom (_PyGObject_API->register_gtype_custom) -#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject) -#define pyg_value_from_pyobject_with_error (_PyGObject_API->value_from_pyobject_with_error) -#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject) -#define pyg_register_interface (_PyGObject_API->register_interface) -#define PyGBoxed_Type (*_PyGObject_API->boxed_type) -#define pyg_register_boxed (_PyGObject_API->register_boxed) -#define pyg_boxed_new (_PyGObject_API->boxed_new) -#define PyGPointer_Type (*_PyGObject_API->pointer_type) -#define pyg_register_pointer (_PyGObject_API->register_pointer) -#define pyg_pointer_new (_PyGObject_API->pointer_new) -#define pyg_enum_add_constants (_PyGObject_API->enum_add_constants) -#define pyg_flags_add_constants (_PyGObject_API->flags_add_constants) -#define pyg_constant_strip_prefix (_PyGObject_API->constant_strip_prefix) -#define pyg_error_check (_PyGObject_API->error_check) -#define PyGParamSpec_Type (*_PyGObject_API->paramspec_type) -#define pyg_param_spec_new (_PyGObject_API->paramspec_new) -#define pyg_param_spec_from_object (_PyGObject_API->paramspec_get) -#define pyg_pyobj_to_unichar_conv (_PyGObject_API->pyobj_to_unichar_conv) -#define pyg_parse_constructor_args (_PyGObject_API->parse_constructor_args) -#define pyg_param_gvalue_as_pyobject (_PyGObject_API->value_as_pyobject) -#define pyg_param_gvalue_from_pyobject (_PyGObject_API->gvalue_from_param_pyobject) -#define PyGEnum_Type (*_PyGObject_API->enum_type) -#define pyg_enum_add (_PyGObject_API->enum_add) -#define pyg_enum_from_gtype (_PyGObject_API->enum_from_gtype) -#define PyGFlags_Type (*_PyGObject_API->flags_type) -#define pyg_flags_add (_PyGObject_API->flags_add) -#define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype) -#define pyg_register_class_init (_PyGObject_API->register_class_init) -#define pyg_register_interface_info (_PyGObject_API->register_interface_info) -#define pyg_add_warning_redirection (_PyGObject_API->add_warning_redirection) -#define pyg_disable_warning_redirections (_PyGObject_API->disable_warning_redirections) -#define pyg_gerror_exception_check (_PyGObject_API->gerror_exception_check) -#define pyg_option_group_new (_PyGObject_API->option_group_new) - - -/** - * pygobject_init: - * @req_major: minimum version major number, or -1 - * @req_minor: minimum version minor number, or -1 - * @req_micro: minimum version micro number, or -1 - * - * Imports and initializes the 'gobject' python module. Can - * optionally check for a required minimum version if @req_major, - * @req_minor, and @req_micro are all different from -1. - * - * Returns: a new reference to the gobject module on success, NULL in - * case of failure (and raises ImportError). - **/ -static inline PyObject * -pygobject_init(int req_major, int req_minor, int req_micro) -{ - PyObject *gobject, *cobject; - - gobject = PyImport_ImportModule("gi._gobject"); - if (!gobject) { - if (PyErr_Occurred()) - { - PyObject *type, *value, *traceback; - PyObject *py_orig_exc; - PyErr_Fetch(&type, &value, &traceback); - py_orig_exc = PyObject_Repr(value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - - -#if PY_VERSION_HEX < 0x03000000 - PyErr_Format(PyExc_ImportError, - "could not import gobject (error was: %s)", - PyString_AsString(py_orig_exc)); -#else - { - /* Can not use PyErr_Format because it doesn't have - * a format string for dealing with PyUnicode objects - * like PyUnicode_FromFormat has - */ - PyObject *errmsg = PyUnicode_FromFormat("could not import gobject (error was: %U)", - py_orig_exc); - - if (errmsg) { - PyErr_SetObject(PyExc_ImportError, - errmsg); - Py_DECREF(errmsg); - } - /* if errmsg is NULL then we might have OOM - * PyErr should already be set and trying to - * return our own error would be futile - */ - } -#endif - Py_DECREF(py_orig_exc); - } else { - PyErr_SetString(PyExc_ImportError, - "could not import gobject (no error given)"); - } - return NULL; - } - - cobject = PyObject_GetAttrString(gobject, "_PyGObject_API"); - if (cobject && PyCapsule_CheckExact(cobject)) - _PyGObject_API = (struct _PyGObject_Functions *) PyCapsule_GetPointer(cobject, "gobject._PyGObject_API"); - else { - PyErr_SetString(PyExc_ImportError, - "could not import gobject (could not find _PyGObject_API object)"); - Py_DECREF(gobject); - return NULL; - } - - if (req_major != -1) - { - int found_major, found_minor, found_micro; - PyObject *version; - - version = PyObject_GetAttrString(gobject, "pygobject_version"); - if (!version) { - PyErr_SetString(PyExc_ImportError, - "could not import gobject (version too old)"); - Py_DECREF(gobject); - return NULL; - } - if (!PyArg_ParseTuple(version, "iii", - &found_major, &found_minor, &found_micro)) { - PyErr_SetString(PyExc_ImportError, - "could not import gobject (version has invalid format)"); - Py_DECREF(version); - Py_DECREF(gobject); - return NULL; - } - Py_DECREF(version); - if (req_major != found_major || - req_minor > found_minor || - (req_minor == found_minor && req_micro > found_micro)) { - PyErr_Format(PyExc_ImportError, - "could not import gobject (version mismatch, %d.%d.%d is required, " - "found %d.%d.%d)", req_major, req_minor, req_micro, - found_major, found_minor, found_micro); - Py_DECREF(gobject); - return NULL; - } - } - return gobject; -} - -/** - * PYLIST_FROMGLIBLIST: - * @type: the type of the GLib list e.g. #GList or #GSList - * @prefix: the prefix of functions that manipulate a list of the type - * given by type. - * - * A macro that creates a type specific code block which converts a GLib - * list (#GSList or #GList) to a Python list. The first two args of the macro - * are used to specify the type and list function prefix so that the type - * specific macros can be generated. - * - * The rest of the args are for the standard args for the type specific - * macro(s) created from this macro. - */ - #define PYLIST_FROMGLIBLIST(type,prefix,py_list,list,item_convert_func,\ - list_free,list_item_free) \ -G_STMT_START \ -{ \ - gint i, len; \ - PyObject *item; \ - void (*glib_list_free)(type*) = list_free; \ - GFunc glib_list_item_free = (GFunc)list_item_free; \ - \ - len = prefix##_length(list); \ - py_list = PyList_New(len); \ - for (i = 0; i < len; i++) { \ - gpointer list_item = prefix##_nth_data(list, i); \ - \ - item = item_convert_func; \ - PyList_SetItem(py_list, i, item); \ - } \ - if (glib_list_item_free != NULL) \ - prefix##_foreach(list, glib_list_item_free, NULL); \ - if (glib_list_free != NULL) \ - glib_list_free(list); \ -} G_STMT_END - -/** - * PYLIST_FROMGLIST: - * @py_list: the name of the Python list - * - * @list: the #GList to be converted to a Python list - * - * @item_convert_func: the function that converts a list item to a Python - * object. The function must refer to the list item using "@list_item" and - * must return a #PyObject* object. An example conversion function is: - * [[ - * PyString_FromString(list_item) - * ]] - * A more elaborate function is: - * [[ - * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE) - * ]] - * @list_free: the name of a function that takes a single arg (the list) and - * frees its memory. Can be NULL if the list should not be freed. An example - * is: - * [[ - * g_list_free - * ]] - * @list_item_free: the name of a #GFunc function that frees the memory used - * by the items in the list or %NULL if the list items do not have to be - * freed. A simple example is: - * [[ - * g_free - * ]] - * - * A macro that adds code that converts a #GList to a Python list. - * - */ -#define PYLIST_FROMGLIST(py_list,list,item_convert_func,list_free,\ - list_item_free) \ - PYLIST_FROMGLIBLIST(GList,g_list,py_list,list,item_convert_func,\ - list_free,list_item_free) - -/** - * PYLIST_FROMGSLIST: - * @py_list: the name of the Python list - * - * @list: the #GSList to be converted to a Python list - * - * @item_convert_func: the function that converts a list item to a Python - * object. The function must refer to the list item using "@list_item" and - * must return a #PyObject* object. An example conversion function is: - * [[ - * PyString_FromString(list_item) - * ]] - * A more elaborate function is: - * [[ - * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE) - * ]] - * @list_free: the name of a function that takes a single arg (the list) and - * frees its memory. Can be %NULL if the list should not be freed. An example - * is: - * [[ - * g_list_free - * ]] - * @list_item_free: the name of a #GFunc function that frees the memory used - * by the items in the list or %NULL if the list items do not have to be - * freed. A simple example is: - * [[ - * g_free - * ]] - * - * A macro that adds code that converts a #GSList to a Python list. - * - */ -#define PYLIST_FROMGSLIST(py_list,list,item_convert_func,list_free,\ - list_item_free) \ - PYLIST_FROMGLIBLIST(GSList,g_slist,py_list,list,item_convert_func,\ - list_free,list_item_free) - -/** - * PYLIST_ASGLIBLIST - * @type: the type of the GLib list e.g. GList or GSList - * @prefix: the prefix of functions that manipulate a list of the type - * given by type e.g. g_list or g_slist - * - * A macro that creates a type specific code block to be used to convert a - * Python list to a GLib list (GList or GSList). The first two args of the - * macro are used to specify the type and list function prefix so that the - * type specific macros can be generated. - * - * The rest of the args are for the standard args for the type specific - * macro(s) created from this macro. - */ -#define PYLIST_ASGLIBLIST(type,prefix,py_list,list,check_func,\ - convert_func,child_free_func,errormsg,errorreturn) \ -G_STMT_START \ -{ \ - Py_ssize_t i, n_list; \ - GFunc glib_child_free_func = (GFunc)child_free_func; \ - \ - if (!(py_list = PySequence_Fast(py_list, ""))) { \ - errormsg; \ - return errorreturn; \ - } \ - n_list = PySequence_Fast_GET_SIZE(py_list); \ - for (i = 0; i < n_list; i++) { \ - PyObject *py_item = PySequence_Fast_GET_ITEM(py_list, i); \ - \ - if (!check_func) { \ - if (glib_child_free_func) \ - prefix##_foreach(list, glib_child_free_func, NULL); \ - prefix##_free(list); \ - Py_DECREF(py_list); \ - errormsg; \ - return errorreturn; \ - } \ - list = prefix##_prepend(list, convert_func); \ - }; \ - Py_DECREF(py_list); \ - list = prefix##_reverse(list); \ -} \ -G_STMT_END -/** - * PYLIST_ASGLIST - * @py_list: the Python list to be converted - * @list: the #GList list to be converted - * @check_func: the expression that takes a #PyObject* arg (must be named - * @py_item) and returns an int value indicating if the Python object matches - * the required list item type (0 - %False or 1 - %True). An example is: - * [[ - * (PyString_Check(py_item)||PyUnicode_Check(py_item)) - * ]] - * @convert_func: the function that takes a #PyObject* arg (must be named - * py_item) and returns a pointer to the converted list object. An example - * is: - * [[ - * pygobject_get(py_item) - * ]] - * @child_free_func: the name of a #GFunc function that frees a GLib list - * item or %NULL if the list item does not have to be freed. This function is - * used to help free the items in a partially created list if there is an - * error. An example is: - * [[ - * g_free - * ]] - * @errormsg: a function that sets up a Python error message. An example is: - * [[ - * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings - * or unicode objects") - * ]] - * @errorreturn: the value to return if an error occurs, e.g.: - * [[ - * %NULL - * ]] - * - * A macro that creates code that converts a Python list to a #GList. The - * returned list must be freed using the appropriate list free function when - * it's no longer needed. If an error occurs the child_free_func is used to - * release the memory used by the list items and then the list memory is - * freed. - */ -#define PYLIST_ASGLIST(py_list,list,check_func,convert_func,child_free_func,\ - errormsg,errorreturn) \ - PYLIST_ASGLIBLIST(GList,g_list,py_list,list,check_func,convert_func,\ - child_free_func,errormsg,errorreturn) - -/** - * PYLIST_ASGSLIST - * @py_list: the Python list to be converted - * @list: the #GSList list to be converted - * @check_func: the expression that takes a #PyObject* arg (must be named - * @py_item) and returns an int value indicating if the Python object matches - * the required list item type (0 - %False or 1 - %True). An example is: - * [[ - * (PyString_Check(py_item)||PyUnicode_Check(py_item)) - * ]] - * @convert_func: the function that takes a #PyObject* arg (must be named - * py_item) and returns a pointer to the converted list object. An example - * is: - * [[ - * pygobject_get(py_item) - * ]] - * @child_free_func: the name of a #GFunc function that frees a GLib list - * item or %NULL if the list item does not have to be freed. This function is - * used to help free the items in a partially created list if there is an - * error. An example is: - * [[ - * g_free - * ]] - * @errormsg: a function that sets up a Python error message. An example is: - * [[ - * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings - * or unicode objects") - * ]] - * @errorreturn: the value to return if an error occurs, e.g.: - * [[ - * %NULL - * ]] - * - * A macro that creates code that converts a Python list to a #GSList. The - * returned list must be freed using the appropriate list free function when - * it's no longer needed. If an error occurs the child_free_func is used to - * release the memory used by the list items and then the list memory is - * freed. - */ -#define PYLIST_ASGSLIST(py_list,list,check_func,convert_func,child_free_func,\ - errormsg,errorreturn) \ - PYLIST_ASGLIBLIST(GSList,g_slist,py_list,list,check_func,convert_func,\ - child_free_func,errormsg,errorreturn) - -#endif /* !_INSIDE_PYGOBJECT_ */ - -G_END_DECLS - -#endif /* !_PYGOBJECT_H_ */ diff --git a/gi/_gobject/pygparamspec.c b/gi/_gobject/pygparamspec.c deleted file mode 100644 index 938f797..0000000 --- a/gi/_gobject/pygparamspec.c +++ /dev/null @@ -1,418 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * Copyright (C) 2004 Johan Dahlin - * - * pygenum.c: GEnum and GFlag wrappers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "pygobject-private.h" -#include "pygparamspec.h" - -PYGLIB_DEFINE_TYPE("gobject.GParamSpec", PyGParamSpec_Type, PyGParamSpec); - -static PyObject* -pyg_param_spec_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGParamSpec_Type) - return _pyglib_generic_ptr_richcompare(((PyGParamSpec*)self)->pspec, - ((PyGParamSpec*)other)->pspec, - op); - else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - -static long -pyg_param_spec_hash(PyGParamSpec *self) -{ - return (long)self->pspec; -} - -static PyObject * -pyg_param_spec_repr(PyGParamSpec *self) -{ - char buf[80]; - - g_snprintf(buf, sizeof(buf), "<%s '%s'>", - G_PARAM_SPEC_TYPE_NAME(self->pspec), - g_param_spec_get_name(self->pspec)); - return PYGLIB_PyUnicode_FromString(buf); -} - -static void -pyg_param_spec_dealloc(PyGParamSpec *self) -{ - g_param_spec_unref(self->pspec); - PyObject_DEL(self); -} - - -static PyObject * -pygenum_from_pspec(GParamSpec *pspec) -{ - PyObject *pyclass; - GParamSpecEnum *enum_pspec; - GType enum_type; - - enum_pspec = G_PARAM_SPEC_ENUM(pspec); - enum_type = G_ENUM_CLASS_TYPE(enum_pspec->enum_class); - pyclass = (PyObject*)g_type_get_qdata(enum_type, pygenum_class_key); - if (pyclass == NULL) { - pyclass = pyg_enum_add(NULL, g_type_name(enum_type), NULL, enum_type); - if (pyclass == NULL) - pyclass = Py_None; - } - - Py_INCREF(pyclass); - return pyclass; -} - -static PyObject * -pygflags_from_pspec(GParamSpec *pspec) -{ - PyObject *pyclass; - GParamSpecFlags *flag_pspec; - GType flag_type; - - flag_pspec = G_PARAM_SPEC_FLAGS(pspec); - flag_type = G_FLAGS_CLASS_TYPE(flag_pspec->flags_class); - pyclass = (PyObject*)g_type_get_qdata(flag_type, pygflags_class_key); - if (pyclass == NULL) { - pyclass = pyg_flags_add(NULL, g_type_name(flag_type), NULL, flag_type); - if (pyclass == NULL) - pyclass = Py_None; - } - Py_INCREF(pyclass); - return pyclass; -} - -static PyObject * -pyg_param_spec_getattr(PyGParamSpec *self, const gchar *attr) -{ - GParamSpec *pspec; - - pspec = self->pspec; - - /* common attributes */ - if (!strcmp(attr, "__gtype__")) { - return pyg_type_wrapper_new(G_PARAM_SPEC_TYPE(pspec)); - } else if (!strcmp(attr, "name")) { - return Py_BuildValue("s", g_param_spec_get_name(pspec)); - } else if (!strcmp(attr, "nick")) { - return Py_BuildValue("s", g_param_spec_get_nick(pspec)); - } else if (!strcmp(attr, "blurb") || !strcmp(attr, "__doc__")) { - return Py_BuildValue("s", g_param_spec_get_blurb(pspec)); - } else if (!strcmp(attr, "flags")) { - return PYGLIB_PyLong_FromLong(pspec->flags); - } else if (!strcmp(attr, "value_type")) { - return pyg_type_wrapper_new(pspec->value_type); - } else if (!strcmp(attr, "owner_type")) { - return pyg_type_wrapper_new(pspec->owner_type); - } - - if (G_IS_PARAM_SPEC_CHAR(pspec)) { - if (!strcmp(attr, "default_value")) { - return PYGLIB_PyUnicode_FromFormat( - "%c", G_PARAM_SPEC_CHAR(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_CHAR(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_CHAR(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_UCHAR(pspec)) { - if (!strcmp(attr, "default_value")) { - return PYGLIB_PyUnicode_FromFormat( - "%c", G_PARAM_SPEC_UCHAR(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_UCHAR(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_UCHAR(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_BOOLEAN(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyBool_FromLong(G_PARAM_SPEC_BOOLEAN(pspec)->default_value); - } - } else if (G_IS_PARAM_SPEC_INT(pspec)) { - if (!strcmp(attr, "default_value")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_UINT(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_LONG(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_ULONG(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_INT64(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_UINT64(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->maximum); - } - } else if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - if (!strcmp(attr, "default_value")) { - return PYGLIB_PyUnicode_FromFormat( - "%c", G_PARAM_SPEC_UNICHAR(pspec)->default_value); - } - } else if (G_IS_PARAM_SPEC_ENUM(pspec)) { - if (!strcmp(attr, "default_value")) { - return pyg_enum_from_gtype( - pspec->value_type, G_PARAM_SPEC_ENUM(pspec)->default_value); - } else if (!strcmp(attr, "enum_class")) { - return pygenum_from_pspec(pspec); - } - } else if (G_IS_PARAM_SPEC_FLAGS(pspec)) { - if (!strcmp(attr, "default_value")) { - return pyg_flags_from_gtype( - pspec->value_type, G_PARAM_SPEC_FLAGS(pspec)->default_value); - } else if (!strcmp(attr, "flags_class")) { - return pygflags_from_pspec(pspec); - } - } else if (G_IS_PARAM_SPEC_FLOAT(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->maximum); - } else if (!strcmp(attr, "epsilon")) { - return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->epsilon); - } - } else if (G_IS_PARAM_SPEC_DOUBLE(pspec)) { - if (!strcmp(attr, "default_value")) { - return PyFloat_FromDouble( - G_PARAM_SPEC_DOUBLE(pspec)->default_value); - } else if (!strcmp(attr, "minimum")) { - return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->minimum); - } else if (!strcmp(attr, "maximum")) { - return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->maximum); - } else if (!strcmp(attr, "epsilon")) { - return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->epsilon); - } - } else if (G_IS_PARAM_SPEC_STRING(pspec)) { - if (!strcmp(attr, "default_value")) { - return Py_BuildValue( - "s", G_PARAM_SPEC_STRING(pspec)->default_value); - } else if (!strcmp(attr, "cset_first")) { - return Py_BuildValue( - "s", G_PARAM_SPEC_STRING(pspec)->cset_first); - } else if (!strcmp(attr, "cset_nth")) { - return Py_BuildValue( - "s", G_PARAM_SPEC_STRING(pspec)->cset_nth); - } else if (!strcmp(attr, "substitutor")) { - return Py_BuildValue( - "c", G_PARAM_SPEC_STRING(pspec)->substitutor); - } else if (!strcmp(attr, "null_fold_if_empty")) { - return PyBool_FromLong( - G_PARAM_SPEC_STRING(pspec)->null_fold_if_empty); - } else if (!strcmp(attr, "ensure_non_null")) { - return PyBool_FromLong( - G_PARAM_SPEC_STRING(pspec)->ensure_non_null); - } - } else { - /* This is actually not what's exported by GObjects paramspecs, - * But we exported this in earlier versions, so it's better to keep it here - * compatibility. But don't return it in __dir__, to "hide" it. - */ - if (!strcmp(attr, "default_value")) { - /* XXX: Raise deprecation warning */ - Py_INCREF(Py_None); - return Py_None; - } - } - - PyErr_SetString(PyExc_AttributeError, attr); - return NULL; -} - - -static PyObject * -pyg_param_spec_dir(PyGParamSpec *self, PyObject *dummy) -{ - GParamSpec *pspec = self->pspec; - - if (G_IS_PARAM_SPEC_CHAR(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", "flags", - "maximum", "minimum", "name", "nick", - "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_UCHAR(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", - "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_BOOLEAN(pspec)) { - return Py_BuildValue("[sssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_INT(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", "name", - "nick", "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_UINT(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", - "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_LONG(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", "name", - "nick", "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_ULONG(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", "name", - "nick", "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_INT64(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", "name", - "nick", "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_UINT64(pspec)) { - return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "maximum", "minimum", - "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - return Py_BuildValue("[sssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_ENUM(pspec)) { - return Py_BuildValue("[ssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", "enum_class", - "flags", "name", "nick", "owner_type", - "value_type"); - } else if (G_IS_PARAM_SPEC_FLAGS(pspec)) { - return Py_BuildValue("[ssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", - "flags", "flags_class", "name", "nick", - "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_FLOAT(pspec)) { - return Py_BuildValue("[ssssssssssss]", "__doc__", "__gtype__", - "blurb", "epsilon", - "flags", "maximum", "minimum", "name", "nick", "owner_type", - "value_type", - "default_value"); - } else if (G_IS_PARAM_SPEC_DOUBLE(pspec)) { - return Py_BuildValue("[ssssssssssss]", "__doc__", "__gtype__", - "blurb", "default_value", "epsilon", - "flags", "maximum", "minimum", "name", "nick", - "owner_type", "value_type"); - } else if (G_IS_PARAM_SPEC_STRING(pspec)) { - return Py_BuildValue("[ssssssssssssss]", "__doc__", "__gtype__", - "blurb", "cset_first", "cset_nth", "default_value", - "ensure_non_null", "flags", "name", "nick", - "null_fold_if_empty", "owner_type", "substitutor", - "value_type"); - } else { - return Py_BuildValue("[ssssssss]", "__doc__", "__gtype__", "blurb", - "flags", "name", "nick", - "owner_type", "value_type"); - } -} - -static PyMethodDef pyg_param_spec_methods[] = { - { "__dir__", (PyCFunction)pyg_param_spec_dir, METH_NOARGS}, - { NULL, NULL, 0} -}; - -/** - * pyg_param_spec_new: - * @pspec: a GParamSpec. - * - * Creates a wrapper for a GParamSpec. - * - * Returns: the GParamSpec wrapper. - */ -PyObject * -pyg_param_spec_new(GParamSpec *pspec) -{ - PyGParamSpec *self; - - self = (PyGParamSpec *)PyObject_NEW(PyGParamSpec, - &PyGParamSpec_Type); - if (self == NULL) - return NULL; - - self->pspec = g_param_spec_ref(pspec); - return (PyObject *)self; -} - -void -pygobject_paramspec_register_types(PyObject *d) -{ - Py_TYPE(&PyGParamSpec_Type) = &PyType_Type; - PyGParamSpec_Type.tp_dealloc = (destructor)pyg_param_spec_dealloc; - PyGParamSpec_Type.tp_getattr = (getattrfunc)pyg_param_spec_getattr; - PyGParamSpec_Type.tp_richcompare = pyg_param_spec_richcompare; - PyGParamSpec_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGParamSpec_Type.tp_repr = (reprfunc)pyg_param_spec_repr; - PyGParamSpec_Type.tp_hash = (hashfunc)pyg_param_spec_hash; - PyGParamSpec_Type.tp_methods = pyg_param_spec_methods; - - - if (PyType_Ready(&PyGParamSpec_Type)) - return; - PyDict_SetItemString(d, "GParamSpec", (PyObject *)&PyGParamSpec_Type); -} diff --git a/gi/_gobject/pygparamspec.h b/gi/_gobject/pygparamspec.h deleted file mode 100644 index 64aab0c..0000000 --- a/gi/_gobject/pygparamspec.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * pyginterface.c: wrapper for the gobject library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_PARAMSPEC_H__ -#define __PYGOBJECT_PARAMSPEC_H__ - -extern PyTypeObject PyGParamSpec_Type; -PyObject * pyg_param_spec_new (GParamSpec *pspec); - -void pygobject_paramspec_register_types(PyObject *d); - -#endif /* __PYGOBJECT_PARAMSPEC_H__ */ diff --git a/gi/_gobject/pygpointer.c b/gi/_gobject/pygpointer.c deleted file mode 100644 index 575c751..0000000 --- a/gi/_gobject/pygpointer.c +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * pygpointer.c: wrapper for GPointer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "pygobject-private.h" -#include "pygpointer.h" - -#include "pygi.h" - - -GQuark pygpointer_class_key; - -PYGLIB_DEFINE_TYPE("gobject.GPointer", PyGPointer_Type, PyGPointer); - -static void -pyg_pointer_dealloc(PyGPointer *self) -{ - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject* -pyg_pointer_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other)) - return _pyglib_generic_ptr_richcompare(((PyGPointer*)self)->pointer, - ((PyGPointer*)other)->pointer, - op); - else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - -static long -pyg_pointer_hash(PyGPointer *self) -{ - return (long)self->pointer; -} - -static PyObject * -pyg_pointer_repr(PyGPointer *self) -{ - gchar buf[128]; - - g_snprintf(buf, sizeof(buf), "<%s at 0x%lx>", g_type_name(self->gtype), - (long)self->pointer); - return PYGLIB_PyUnicode_FromString(buf); -} - -static int -pyg_pointer_init(PyGPointer *self, PyObject *args, PyObject *kwargs) -{ - gchar buf[512]; - - if (!PyArg_ParseTuple(args, ":GPointer.__init__")) - return -1; - - self->pointer = NULL; - self->gtype = 0; - - g_snprintf(buf, sizeof(buf), "%s can not be constructed", - Py_TYPE(self)->tp_name); - PyErr_SetString(PyExc_NotImplementedError, buf); - return -1; -} - -static void -pyg_pointer_free(PyObject *op) -{ - PyObject_FREE(op); -} - -/** - * pyg_register_pointer: - * @dict: the module dictionary to store the wrapper class. - * @class_name: the Python name for the wrapper class. - * @pointer_type: the GType of the pointer type being wrapped. - * @type: the wrapper class. - * - * Registers a wrapper for a pointer type. The wrapper class will be - * a subclass of gobject.GPointer, and a reference to the wrapper - * class will be stored in the provided module dictionary. - */ -void -pyg_register_pointer(PyObject *dict, const gchar *class_name, - GType pointer_type, PyTypeObject *type) -{ - PyObject *o; - - g_return_if_fail(dict != NULL); - g_return_if_fail(class_name != NULL); - g_return_if_fail(pointer_type != 0); - - if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_pointer_dealloc; - - Py_TYPE(type) = &PyType_Type; - type->tp_base = &PyGPointer_Type; - - if (PyType_Ready(type) < 0) { - g_warning("could not get type `%s' ready", type->tp_name); - return; - } - - PyDict_SetItemString(type->tp_dict, "__gtype__", - o=pyg_type_wrapper_new(pointer_type)); - Py_DECREF(o); - - g_type_set_qdata(pointer_type, pygpointer_class_key, type); - - PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); -} - -/** - * pyg_pointer_new: - * @pointer_type: the GType of the pointer value. - * @pointer: the pointer value. - * - * Creates a wrapper for a pointer value. Since G_TYPE_POINTER types - * don't register any information about how to copy/free them, there - * is no guarantee that the pointer will remain valid, and there is - * nothing registered to release the pointer when the pointer goes out - * of scope. This is why we don't recommend people use these types. - * - * Returns: the boxed wrapper. - */ -PyObject * -pyg_pointer_new(GType pointer_type, gpointer pointer) -{ - PyGILState_STATE state; - PyGPointer *self; - PyTypeObject *tp; - g_return_val_if_fail(pointer_type != 0, NULL); - - state = pyglib_gil_state_ensure(); - - if (!pointer) { - Py_INCREF(Py_None); - pyglib_gil_state_release(state); - return Py_None; - } - - tp = g_type_get_qdata(pointer_type, pygpointer_class_key); - - if (!tp) - tp = (PyTypeObject *)pygi_type_import_by_g_type(pointer_type); - - if (!tp) - tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */ - self = PyObject_NEW(PyGPointer, tp); - - pyglib_gil_state_release(state); - - if (self == NULL) - return NULL; - - self->pointer = pointer; - self->gtype = pointer_type; - - return (PyObject *)self; -} - -void -pygobject_pointer_register_types(PyObject *d) -{ - pygpointer_class_key = g_quark_from_static_string("PyGPointer::class"); - - PyGPointer_Type.tp_dealloc = (destructor)pyg_pointer_dealloc; - PyGPointer_Type.tp_richcompare = pyg_pointer_richcompare; - PyGPointer_Type.tp_repr = (reprfunc)pyg_pointer_repr; - PyGPointer_Type.tp_hash = (hashfunc)pyg_pointer_hash; - PyGPointer_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; - PyGPointer_Type.tp_init = (initproc)pyg_pointer_init; - PyGPointer_Type.tp_free = (freefunc)pyg_pointer_free; - PYGOBJECT_REGISTER_GTYPE(d, PyGPointer_Type, "GPointer", G_TYPE_POINTER); -} diff --git a/gi/_gobject/pygpointer.h b/gi/_gobject/pygpointer.h deleted file mode 100644 index f2923da..0000000 --- a/gi/_gobject/pygpointer.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_POINTER_H__ -#define __PYGOBJECT_POINTER_H__ - -void pygobject_pointer_register_types(PyObject *d); - -#endif /* __PYGOBJECT_POINTER_H__ */ diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c deleted file mode 100644 index 9dc1153..0000000 --- a/gi/_gobject/pygtype.c +++ /dev/null @@ -1,1927 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * - * pygtype.c: glue code to wrap the GType code. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "pygobject-private.h" -#include "pygparamspec.h" -#include "pygtype.h" - -/* -------------- __gtype__ objects ---------------------------- */ - -typedef struct { - PyObject_HEAD - GType type; -} PyGTypeWrapper; - -PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper); - -static PyObject* -pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op) -{ - if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type) - return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type, - ((PyGTypeWrapper*)other)->type, - op); - else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } -} - -static long -pyg_type_wrapper_hash(PyGTypeWrapper *self) -{ - return (long)self->type; -} - -static PyObject * -pyg_type_wrapper_repr(PyGTypeWrapper *self) -{ - char buf[80]; - const gchar *name = g_type_name(self->type); - - g_snprintf(buf, sizeof(buf), "", - name?name:"invalid", (unsigned long int) self->type); - return PYGLIB_PyUnicode_FromString(buf); -} - -static void -pyg_type_wrapper_dealloc(PyGTypeWrapper *self) -{ - PyObject_DEL(self); -} - -static GQuark -_pyg_type_key(GType type) { - GQuark key; - - if (g_type_is_a(type, G_TYPE_INTERFACE)) { - key = pyginterface_type_key; - } else if (g_type_is_a(type, G_TYPE_ENUM)) { - key = pygenum_class_key; - } else if (g_type_is_a(type, G_TYPE_FLAGS)) { - key = pygflags_class_key; - } else if (g_type_is_a(type, G_TYPE_POINTER)) { - key = pygpointer_class_key; - } else if (g_type_is_a(type, G_TYPE_BOXED)) { - key = pygboxed_type_key; - } else { - key = pygobject_class_key; - } - - return key; -} - -static PyObject * -_wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure) -{ - GQuark key; - PyObject *py_type; - - key = _pyg_type_key(self->type); - - py_type = g_type_get_qdata(self->type, key); - if (!py_type) - py_type = Py_None; - - Py_INCREF(py_type); - return py_type; -} - -static int -_wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure) -{ - GQuark key; - PyObject *py_type; - - key = _pyg_type_key(self->type); - - py_type = g_type_get_qdata(self->type, key); - Py_CLEAR(py_type); - if (value == Py_None) - g_type_set_qdata(self->type, key, NULL); - else if (PyType_Check(value)) { - Py_INCREF(value); - g_type_set_qdata(self->type, key, value); - } else { - PyErr_SetString(PyExc_TypeError, "Value must be None or a type object"); - return -1; - } - - return 0; -} - -static PyObject * -_wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure) -{ - const char *name = g_type_name(self->type); - return PYGLIB_PyUnicode_FromString(name ? name : "invalid"); -} - -static PyObject * -_wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure) -{ - return pyg_type_wrapper_new(g_type_parent(self->type)); -} - -static PyObject * -_wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure) -{ - return pyg_type_wrapper_new(g_type_fundamental(self->type)); -} - -static PyObject * -_wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure) -{ - guint n_children, i; - GType *children; - PyObject *retval; - - children = g_type_children(self->type, &n_children); - - retval = PyList_New(n_children); - for (i = 0; i < n_children; i++) - PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i])); - g_free(children); - - return retval; -} - -static PyObject * -_wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure) -{ - guint n_interfaces, i; - GType *interfaces; - PyObject *retval; - - interfaces = g_type_interfaces(self->type, &n_interfaces); - - retval = PyList_New(n_interfaces); - for (i = 0; i < n_interfaces; i++) - PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i])); - g_free(interfaces); - - return retval; -} - -static PyObject * -_wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure) -{ - return PYGLIB_PyLong_FromLong(g_type_depth(self->type)); -} - -static PyGetSetDef _PyGTypeWrapper_getsets[] = { - { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype }, - { "name", (getter)_wrap_g_type_wrapper__get_name, (setter)0 }, - { "fundamental", (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 }, - { "parent", (getter)_wrap_g_type_wrapper__get_parent, (setter)0 }, - { "children", (getter)_wrap_g_type_wrapper__get_children, (setter)0 }, - { "interfaces", (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 }, - { "depth", (getter)_wrap_g_type_wrapper__get_depth, (setter)0 }, - { NULL, (getter)0, (setter)0 } -}; - -static PyObject* -_wrap_g_type_is_interface(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type)); -} - -static PyObject* -_wrap_g_type_is_classed(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_CLASSED(self->type)); -} - -static PyObject* -_wrap_g_type_is_instantiatable(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_INSTANTIATABLE(self->type)); -} - -static PyObject* -_wrap_g_type_is_derivable(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_DERIVABLE(self->type)); -} - -static PyObject* -_wrap_g_type_is_deep_derivable(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_DEEP_DERIVABLE(self->type)); -} - -static PyObject* -_wrap_g_type_is_abstract(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_ABSTRACT(self->type)); -} - -static PyObject* -_wrap_g_type_is_value_abstract(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_VALUE_ABSTRACT(self->type)); -} - -static PyObject* -_wrap_g_type_is_value_type(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_IS_VALUE_TYPE(self->type)); -} - -static PyObject* -_wrap_g_type_has_value_table(PyGTypeWrapper *self) -{ - return PyBool_FromLong(G_TYPE_HAS_VALUE_TABLE(self->type)); -} - -static PyObject* -_wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args) -{ - char *type_name; - GType type; - - if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name)) - return NULL; - - type = g_type_from_name(type_name); - if (type == 0) { - PyErr_SetString(PyExc_RuntimeError, "unknown type name"); - return NULL; - } - - return pyg_type_wrapper_new(type); -} - -static PyObject* -_wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args) -{ - PyObject *gparent; - GType parent; - - if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent)) - return NULL; - else if ((parent = pyg_type_from_object(gparent)) == 0) - return NULL; - - return PyBool_FromLong(g_type_is_a(self->type, parent)); -} - -static PyMethodDef _PyGTypeWrapper_methods[] = { - { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS }, - { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS }, - { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS }, - { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS }, - { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS }, - { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS }, - { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS }, - { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS }, - { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS }, - { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC }, - { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS }, - { NULL, 0, 0 } -}; - -static int -pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "object", NULL }; - PyObject *py_object; - GType type; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O:GType.__init__", - kwlist, &py_object)) - return -1; - - if (!(type = pyg_type_from_object(py_object))) - return -1; - - self->type = type; - - return 0; -} - -/** - * pyg_type_wrapper_new: - * type: a GType - * - * Creates a Python wrapper for a GType. - * - * Returns: the Python wrapper. - */ -PyObject * -pyg_type_wrapper_new(GType type) -{ - PyGTypeWrapper *self; - - self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper, - &PyGTypeWrapper_Type); - if (self == NULL) - return NULL; - - self->type = type; - return (PyObject *)self; -} - -/** - * pyg_type_from_object_strict: - * obj: a Python object - * strict: if set to TRUE, raises an exception if it can't perform the - * conversion - * - * converts a python object to a GType. If strict is set, raises an - * exception if it can't perform the conversion, otherwise returns - * PY_TYPE_OBJECT. - * - * Returns: the corresponding GType, or 0 on error. - */ - -GType -pyg_type_from_object_strict(PyObject *obj, gboolean strict) -{ - PyObject *gtype; - GType type; - - /* NULL check */ - if (!obj) { - PyErr_SetString(PyExc_TypeError, "can't get type from NULL object"); - return 0; - } - - /* map some standard types to primitive GTypes ... */ - if (obj == Py_None) - return G_TYPE_NONE; - if (PyType_Check(obj)) { - PyTypeObject *tp = (PyTypeObject *)obj; - - if (tp == &PYGLIB_PyLong_Type) - return G_TYPE_INT; - else if (tp == &PyBool_Type) - return G_TYPE_BOOLEAN; - else if (tp == &PyLong_Type) - return G_TYPE_LONG; - else if (tp == &PyFloat_Type) - return G_TYPE_DOUBLE; - else if (tp == &PYGLIB_PyUnicode_Type) - return G_TYPE_STRING; - else if (tp == &PyBaseObject_Type) - return PY_TYPE_OBJECT; - } - - if (Py_TYPE(obj) == &PyGTypeWrapper_Type) { - return ((PyGTypeWrapper *)obj)->type; - } - - /* handle strings */ - if (PYGLIB_PyUnicode_Check(obj)) { - gchar *name = PYGLIB_PyUnicode_AsString(obj); - - type = g_type_from_name(name); - if (type != 0) { - return type; - } - } - - /* finally, look for a __gtype__ attribute on the object */ - gtype = PyObject_GetAttrString(obj, "__gtype__"); - - if (gtype) { - if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) { - type = ((PyGTypeWrapper *)gtype)->type; - Py_DECREF(gtype); - return type; - } - Py_DECREF(gtype); - } - - PyErr_Clear(); - - /* Some API like those that take GValues can hold a python object as - * a pointer. This is potentially dangerous becuase everything is - * passed in as a PyObject so we can't actually type check it. Only - * fallback to PY_TYPE_OBJECT if strict checking is disabled - */ - if (!strict) - return PY_TYPE_OBJECT; - - PyErr_SetString(PyExc_TypeError, "could not get typecode from object"); - return 0; -} - -/** - * pyg_type_from_object: - * obj: a Python object - * - * converts a python object to a GType. Raises an exception if it - * can't perform the conversion. - * - * Returns: the corresponding GType, or 0 on error. - */ -GType -pyg_type_from_object(PyObject *obj) -{ - /* Legacy call always defaults to strict type checking */ - return pyg_type_from_object_strict(obj, TRUE); -} - -/* -------------- GValue marshalling ------------------ */ - -/** - * pyg_enum_get_value: - * @enum_type: the GType of the flag. - * @obj: a Python object representing the flag value - * @val: a pointer to the location to store the integer representation of the flag. - * - * Converts a Python object to the integer equivalent. The conversion - * will depend on the type of the Python object. If the object is an - * integer, it is passed through directly. If it is a string, it will - * be treated as a full or short enum name as defined in the GType. - * - * Returns: 0 on success or -1 on failure - */ -gint -pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val) -{ - GEnumClass *eclass = NULL; - gint res = -1; - - g_return_val_if_fail(val != NULL, -1); - if (!obj) { - *val = 0; - res = 0; - } else if (PYGLIB_PyLong_Check(obj)) { - *val = PYGLIB_PyLong_AsLong(obj); - res = 0; - - if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { - g_warning("expected enumeration type %s, but got %s instead", - g_type_name(enum_type), - g_type_name(((PyGEnum *) obj)->gtype)); - } - /* Dumb code duplication, but probably not worth it to have yet another macro. */ - } else if (PyLong_Check(obj)) { - *val = PyLong_AsLong(obj); - res = 0; - - if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { - g_warning("expected enumeration type %s, but got %s instead", - g_type_name(enum_type), - g_type_name(((PyGEnum *) obj)->gtype)); - } - } else if (PYGLIB_PyUnicode_Check(obj)) { - GEnumValue *info; - char *str = PYGLIB_PyUnicode_AsString(obj); - - if (enum_type != G_TYPE_NONE) - eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); - else { - PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value"); - res = -1; - } - info = g_enum_get_value_by_name(eclass, str); - g_type_class_unref(eclass); - - if (!info) - info = g_enum_get_value_by_nick(eclass, str); - if (info) { - *val = info->value; - res = 0; - } else { - PyErr_SetString(PyExc_TypeError, "could not convert string"); - res = -1; - } - } else { - PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints"); - res = -1; - } - return res; -} - -/** - * pyg_flags_get_value: - * @flag_type: the GType of the flag. - * @obj: a Python object representing the flag value - * @val: a pointer to the location to store the integer representation of the flag. - * - * Converts a Python object to the integer equivalent. The conversion - * will depend on the type of the Python object. If the object is an - * integer, it is passed through directly. If it is a string, it will - * be treated as a full or short flag name as defined in the GType. - * If it is a tuple, then the items are treated as strings and ORed - * together. - * - * Returns: 0 on success or -1 on failure - */ -gint -pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val) -{ - GFlagsClass *fclass = NULL; - gint res = -1; - - g_return_val_if_fail(val != NULL, -1); - if (!obj) { - *val = 0; - res = 0; - } else if (PYGLIB_PyLong_Check(obj)) { - *val = PYGLIB_PyLong_AsUnsignedLong(obj); - res = 0; - } else if (PyLong_Check(obj)) { - *val = PyLong_AsLongLong(obj); - res = 0; - } else if (PYGLIB_PyUnicode_Check(obj)) { - GFlagsValue *info; - char *str = PYGLIB_PyUnicode_AsString(obj); - - if (flag_type != G_TYPE_NONE) - fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); - else { - PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); - res = -1; - } - info = g_flags_get_value_by_name(fclass, str); - g_type_class_unref(fclass); - - if (!info) - info = g_flags_get_value_by_nick(fclass, str); - if (info) { - *val = info->value; - res = 0; - } else { - PyErr_SetString(PyExc_TypeError, "could not convert string"); - res = -1; - } - } else if (PyTuple_Check(obj)) { - int i, len; - - len = PyTuple_Size(obj); - *val = 0; - res = 0; - - if (flag_type != G_TYPE_NONE) - fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); - else { - PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); - res = -1; - } - - for (i = 0; i < len; i++) { - PyObject *item = PyTuple_GetItem(obj, i); - char *str = PYGLIB_PyUnicode_AsString(item); - GFlagsValue *info = g_flags_get_value_by_name(fclass, str); - - if (!info) - info = g_flags_get_value_by_nick(fclass, str); - if (info) { - *val |= info->value; - } else { - PyErr_SetString(PyExc_TypeError, "could not convert string"); - res = -1; - break; - } - } - g_type_class_unref(fclass); - } else { - PyErr_SetString(PyExc_TypeError, - "flag values must be strings, ints, longs, or tuples"); - res = -1; - } - return res; -} - -typedef struct { - fromvaluefunc fromvalue; - tovaluefunc tovalue; -} PyGTypeMarshal; -static GQuark pyg_type_marshal_key = 0; - -static PyGTypeMarshal * -pyg_type_lookup(GType type) -{ - GType ptype = type; - PyGTypeMarshal *tm = NULL; - - /* recursively lookup types */ - while (ptype) { - if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL) - break; - ptype = g_type_parent(ptype); - } - return tm; -} - -/** - * pyg_register_gtype_custom: - * @gtype: the GType for the new type - * @from_func: a function to convert GValues to Python objects - * @to_func: a function to convert Python objects to GValues - * - * In order to handle specific conversion of gboxed types or new - * fundamental types, you may use this function to register conversion - * handlers. - */ - -void -pyg_register_gtype_custom(GType gtype, - fromvaluefunc from_func, - tovaluefunc to_func) -{ - PyGTypeMarshal *tm; - - if (!pyg_type_marshal_key) - pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal"); - - tm = g_new(PyGTypeMarshal, 1); - tm->fromvalue = from_func; - tm->tovalue = to_func; - g_type_set_qdata(gtype, pyg_type_marshal_key, tm); -} - -static int -pyg_value_array_from_pyobject(GValue *value, - PyObject *obj, - const GParamSpecValueArray *pspec) -{ - int len; - GValueArray *value_array; - int i; - - len = PySequence_Length(obj); - if (len == -1) { - PyErr_Clear(); - return -1; - } - - if (pspec && pspec->fixed_n_elements > 0 && len != pspec->fixed_n_elements) - return -1; - - value_array = g_value_array_new(len); - - 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_value_array_free(value_array); - return -1; - } - - if (pspec && pspec->element_spec) - type = G_PARAM_SPEC_VALUE_TYPE(pspec->element_spec); - else 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_value_array_free(value_array); - Py_DECREF(item); - return -1; - } - } - - g_value_init(&item_value, type); - status = (pspec && pspec->element_spec) - ? pyg_param_gvalue_from_pyobject(&item_value, item, pspec->element_spec) - : pyg_value_from_pyobject(&item_value, item); - Py_DECREF(item); - - if (status == -1) { - g_value_array_free(value_array); - g_value_unset(&item_value); - return -1; - } - - g_value_array_append(value_array, &item_value); - g_value_unset(&item_value); - } - - g_value_take_boxed(value, value_array); - 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_with_error: - * @value: the GValue object to store the converted value in. - * @obj: the Python object to convert. - * - * This function converts a Python object and stores the result in a - * GValue. The GValue must be initialised in advance with - * g_value_init(). If the Python object can't be converted to the - * type of the GValue, then an error is returned. - * - * Returns: 0 on success, -1 on error. - */ -int -pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj) -{ - PyObject *tmp; - GType value_type = G_VALUE_TYPE(value); - - switch (G_TYPE_FUNDAMENTAL(value_type)) { - case G_TYPE_INTERFACE: - /* we only handle interface types that have a GObject prereq */ - if (g_type_is_a(value_type, G_TYPE_OBJECT)) { - if (obj == Py_None) - g_value_set_object(value, NULL); - else { - if (!PyObject_TypeCheck(obj, &PyGObject_Type)) { - PyErr_SetString(PyExc_TypeError, "GObject is required"); - return -1; - } - if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj), - value_type)) { - PyErr_SetString(PyExc_TypeError, "Invalid GObject type for assignment"); - return -1; - } - g_value_set_object(value, pygobject_get(obj)); - } - } else { - PyErr_SetString(PyExc_TypeError, "Unsupported conversion"); - return -1; - } - 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 - else if (PyString_Check(obj)) { - g_value_set_schar(value, PyString_AsString(obj)[0]); - } -#endif - else if (PyUnicode_Check(obj)) { - tmp = PyUnicode_AsUTF8String(obj); - g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]); - Py_DECREF(tmp); - } else { - PyErr_SetString(PyExc_TypeError, "Cannot convert to TYPE_CHAR"); - return -1; - } - - break; - case G_TYPE_UCHAR: - if (PYGLIB_PyLong_Check(obj)) { - glong val; - val = PYGLIB_PyLong_AsLong(obj); - if (val >= 0 && val <= 255) - g_value_set_uchar(value, (guchar) val); - else - return -1; -#if PY_VERSION_HEX < 0x03000000 - } else if (PyString_Check(obj)) { - g_value_set_uchar(value, PyString_AsString(obj)[0]); -#endif - } else if (PyUnicode_Check(obj)) { - tmp = PyUnicode_AsUTF8String(obj); - g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]); - Py_DECREF(tmp); - } else { - PyErr_Clear(); - return -1; - } - break; - case G_TYPE_BOOLEAN: - g_value_set_boolean(value, PyObject_IsTrue(obj)); - break; - case G_TYPE_INT: - g_value_set_int(value, PYGLIB_PyLong_AsLong(obj)); - break; - case G_TYPE_UINT: - { - if (PYGLIB_PyLong_Check(obj)) { - guint val; - - /* check that number is not negative */ - if (PyLong_AsLongLong(obj) < 0) - return -1; - - val = PyLong_AsUnsignedLong(obj); - if (val <= G_MAXUINT) - g_value_set_uint(value, val); - else - return -1; - } else { - g_value_set_uint(value, PyLong_AsUnsignedLong(obj)); - } - } - break; - case G_TYPE_LONG: - g_value_set_long(value, PYGLIB_PyLong_AsLong(obj)); - break; - case G_TYPE_ULONG: -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - long val; - - val = PYGLIB_PyLong_AsLong(obj); - if (val < 0) { - PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property"); - return -1; - } - g_value_set_ulong(value, (gulong)val); - } else -#endif - if (PyLong_Check(obj)) - g_value_set_ulong(value, PyLong_AsUnsignedLong(obj)); - else - return -1; - break; - case G_TYPE_INT64: - g_value_set_int64(value, PyLong_AsLongLong(obj)); - break; - case G_TYPE_UINT64: -#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v < 0) { - PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property"); - return -1; - } - g_value_set_uint64(value, v); - } else -#endif - if (PyLong_Check(obj)) - g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj)); - else - return -1; - break; - case G_TYPE_ENUM: - { - gint val = 0; - if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) { - return -1; - } - g_value_set_enum(value, val); - } - break; - case G_TYPE_FLAGS: - { - guint val = 0; - if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) { - return -1; - } - g_value_set_flags(value, val); - } - break; - case G_TYPE_FLOAT: - g_value_set_float(value, PyFloat_AsDouble(obj)); - break; - case G_TYPE_DOUBLE: - g_value_set_double(value, PyFloat_AsDouble(obj)); - break; - case G_TYPE_STRING: - if (obj == Py_None) { - g_value_set_string(value, NULL); - } else { - PyObject* tmp_str = PyObject_Str(obj); - if (tmp_str == NULL) { - PyErr_Clear(); - if (PyUnicode_Check(obj)) { - tmp = PyUnicode_AsUTF8String(obj); - g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp)); - Py_DECREF(tmp); - } else { - PyErr_SetString(PyExc_TypeError, "Expected string"); - return -1; - } - } else { -#if PY_VERSION_HEX < 0x03000000 - g_value_set_string(value, PyString_AsString(tmp_str)); -#else - tmp = PyUnicode_AsUTF8String(tmp_str); - g_value_set_string(value, PyBytes_AsString(tmp)); - Py_DECREF(tmp); -#endif - } - Py_XDECREF(tmp_str); - } - break; - case G_TYPE_POINTER: - if (obj == Py_None) - g_value_set_pointer(value, NULL); - else if (PyObject_TypeCheck(obj, &PyGPointer_Type) && - G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype)) - g_value_set_pointer(value, pyg_pointer_get(obj, gpointer)); - else if (PYGLIB_CPointer_Check(obj)) - g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL)); - else if (G_VALUE_HOLDS_GTYPE (value)) - g_value_set_gtype (value, pyg_type_from_object (obj)); - else { - PyErr_SetString(PyExc_TypeError, "Expected pointer"); - return -1; - } - break; - case G_TYPE_BOXED: { - PyGTypeMarshal *bm; - - if (obj == Py_None) - g_value_set_boxed(value, NULL); - else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) - g_value_set_boxed(value, obj); - else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) && - G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype)) - g_value_set_boxed(value, pyg_boxed_get(obj, gpointer)); - else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) { - GType type; - GValue *n_value; - - type = pyg_type_from_object((PyObject*)Py_TYPE(obj)); - if (G_UNLIKELY (! type)) { - return -1; - } - n_value = g_new0 (GValue, 1); - g_value_init (n_value, type); - g_value_take_boxed (value, n_value); - return pyg_value_from_pyobject_with_error (n_value, 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; - char *buffer; - Py_ssize_t len; - if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len)) - return -1; - string = g_string_new_len(buffer, len); - g_value_set_boxed(value, string); - g_string_free (string, TRUE); - break; - } - else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) - return bm->tovalue(value, obj); - else if (PYGLIB_CPointer_Check(obj)) - g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL)); - else { - PyErr_SetString(PyExc_TypeError, "Expected Boxed"); - return -1; - } - break; - } - case G_TYPE_PARAM: - /* 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 { - PyErr_SetString(PyExc_TypeError, "Expected ParamSpec"); - return -1; - } - break; - case G_TYPE_OBJECT: - if (obj == Py_None) { - g_value_set_object(value, NULL); - } else if (PyObject_TypeCheck(obj, &PyGObject_Type) && - G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj), - G_VALUE_TYPE(value))) { - g_value_set_object(value, pygobject_get(obj)); - } else { - PyErr_SetString(PyExc_TypeError, "Expected GObject"); - return -1; - } - break; - case G_TYPE_VARIANT: - { - if (obj == Py_None) - g_value_set_variant(value, NULL); - else if (pyg_type_from_object_strict(obj, FALSE) == G_TYPE_VARIANT) - g_value_set_variant(value, pyg_boxed_get(obj, GVariant)); - else { - PyErr_SetString(PyExc_TypeError, "Expected Variant"); - return -1; - } - break; - } - default: - { - PyGTypeMarshal *bm; - if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) { - return bm->tovalue(value, obj); - } else { - PyErr_SetString(PyExc_TypeError, "Unknown value type"); - return -1; - } - break; - } - } - - /* If an error occurred, unset the GValue but don't clear the Python error. */ - if (PyErr_Occurred()) { - g_value_unset(value); - return -1; - } - - return 0; -} - -/** - * pyg_value_from_pyobject: - * @value: the GValue object to store the converted value in. - * @obj: the Python object to convert. - * - * Same basic function as pyg_value_from_pyobject_with_error but clears - * any Python errors before returning. - * - * Returns: 0 on success, -1 on error. - */ -int -pyg_value_from_pyobject(GValue *value, PyObject *obj) -{ - int res = pyg_value_from_pyobject_with_error (value, obj); - - if (PyErr_Occurred()) { - PyErr_Clear(); - return -1; - } - return res; -} - -/** - * pyg_value_as_pyobject: - * @value: the GValue object. - * @copy_boxed: true if boxed values should be copied. - * - * This function creates/returns a Python wrapper object that - * represents the GValue passed as an argument. - * - * Returns: a PyObject representing the value. - */ -PyObject * -pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed) -{ - gchar buf[128]; - - switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value))) { - case G_TYPE_INTERFACE: - if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT)) - return pygobject_new(g_value_get_object(value)); - else - break; - case G_TYPE_CHAR: { - gint8 val = g_value_get_schar(value); - return PYGLIB_PyUnicode_FromStringAndSize((char *)&val, 1); - } - case G_TYPE_UCHAR: { - guint8 val = g_value_get_uchar(value); - return PYGLIB_PyBytes_FromStringAndSize((char *)&val, 1); - } - case G_TYPE_BOOLEAN: { - return PyBool_FromLong(g_value_get_boolean(value)); - } - case G_TYPE_INT: - return PYGLIB_PyLong_FromLong(g_value_get_int(value)); - case G_TYPE_UINT: - { - /* in Python, the Int object is backed by a long. If a - long can hold the whole value of an unsigned int, use - an Int. Otherwise, use a Long object to avoid overflow. - This matches the ULongArg behavior in codegen/argtypes.h */ -#if (G_MAXUINT <= G_MAXLONG) - return PYGLIB_PyLong_FromLong((glong) g_value_get_uint(value)); -#else - return PyLong_FromUnsignedLong((gulong) g_value_get_uint(value)); -#endif - } - case G_TYPE_LONG: - return PYGLIB_PyLong_FromLong(g_value_get_long(value)); - case G_TYPE_ULONG: - { - gulong val = g_value_get_ulong(value); - - if (val <= G_MAXLONG) - return PYGLIB_PyLong_FromLong((glong) val); - else - return PyLong_FromUnsignedLong(val); - } - case G_TYPE_INT64: - { - gint64 val = g_value_get_int64(value); - - if (G_MINLONG <= val && val <= G_MAXLONG) - return PYGLIB_PyLong_FromLong((glong) val); - else - return PyLong_FromLongLong(val); - } - case G_TYPE_UINT64: - { - guint64 val = g_value_get_uint64(value); - - if (val <= G_MAXLONG) - return PYGLIB_PyLong_FromLong((glong) val); - else - return PyLong_FromUnsignedLongLong(val); - } - case G_TYPE_ENUM: - return pyg_enum_from_gtype(G_VALUE_TYPE(value), g_value_get_enum(value)); - case G_TYPE_FLAGS: - return pyg_flags_from_gtype(G_VALUE_TYPE(value), g_value_get_flags(value)); - case G_TYPE_FLOAT: - return PyFloat_FromDouble(g_value_get_float(value)); - case G_TYPE_DOUBLE: - return PyFloat_FromDouble(g_value_get_double(value)); - case G_TYPE_STRING: - { - const gchar *str = g_value_get_string(value); - - if (str) - return PYGLIB_PyUnicode_FromString(str); - Py_INCREF(Py_None); - return Py_None; - } - case G_TYPE_POINTER: - if (G_VALUE_HOLDS_GTYPE (value)) - return pyg_type_wrapper_new (g_value_get_gtype (value)); - else - return pyg_pointer_new(G_VALUE_TYPE(value), - g_value_get_pointer(value)); - case G_TYPE_BOXED: { - PyGTypeMarshal *bm; - - if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) { - PyObject *ret = (PyObject *)g_value_dup_boxed(value); - if (ret == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return ret; - } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) { - GValue *n_value = g_value_get_boxed (value); - return pyg_value_as_pyobject(n_value, copy_boxed); - } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY)) { - GValueArray *array = (GValueArray *) g_value_get_boxed(value); - PyObject *ret = PyList_New(array->n_values); - int i; - for (i = 0; i < array->n_values; ++i) - PyList_SET_ITEM(ret, i, pyg_value_as_pyobject - (array->values + i, copy_boxed)); - return ret; - } else if (G_VALUE_HOLDS(value, G_TYPE_GSTRING)) { - GString *string = (GString *) g_value_get_boxed(value); - PyObject *ret = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len); - return ret; - } - bm = pyg_type_lookup(G_VALUE_TYPE(value)); - if (bm) { - return bm->fromvalue(value); - } else { - if (copy_boxed) - return pyg_boxed_new(G_VALUE_TYPE(value), - g_value_get_boxed(value), TRUE, TRUE); - else - return pyg_boxed_new(G_VALUE_TYPE(value), - g_value_get_boxed(value),FALSE,FALSE); - } - } - case G_TYPE_PARAM: - return pyg_param_spec_new(g_value_get_param(value)); - case G_TYPE_OBJECT: - return pygobject_new(g_value_get_object(value)); - case G_TYPE_VARIANT: - { - GVariant *v = g_value_get_variant(value); - if (v == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return pyg_boxed_new(G_TYPE_VARIANT, g_variant_ref(v), FALSE, FALSE); - } - default: - { - PyGTypeMarshal *bm; - if ((bm = pyg_type_lookup(G_VALUE_TYPE(value)))) - return bm->fromvalue(value); - break; - } - } - g_snprintf(buf, sizeof(buf), "unknown type %s", - g_type_name(G_VALUE_TYPE(value))); - PyErr_SetString(PyExc_TypeError, buf); - return NULL; -} - -/* -------------- PyGClosure ----------------- */ - -static void -pyg_closure_invalidate(gpointer data, GClosure *closure) -{ - PyGClosure *pc = (PyGClosure *)closure; - PyGILState_STATE state; - - state = pyglib_gil_state_ensure(); - Py_XDECREF(pc->callback); - Py_XDECREF(pc->extra_args); - Py_XDECREF(pc->swap_data); - pyglib_gil_state_release(state); - - pc->callback = NULL; - pc->extra_args = NULL; - pc->swap_data = NULL; -} - -static void -pyg_closure_marshal(GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - PyGILState_STATE state; - PyGClosure *pc = (PyGClosure *)closure; - PyObject *params, *ret; - guint i; - - state = pyglib_gil_state_ensure(); - - /* construct Python tuple for the parameter values */ - params = PyTuple_New(n_param_values); - for (i = 0; i < n_param_values; i++) { - /* swap in a different initial data for connect_object() */ - if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) { - g_return_if_fail(pc->swap_data != NULL); - Py_INCREF(pc->swap_data); - PyTuple_SetItem(params, 0, pc->swap_data); - } else { - PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); - - /* error condition */ - if (!item) { - goto out; - } - PyTuple_SetItem(params, i, item); - } - } - /* params passed to function may have extra arguments */ - if (pc->extra_args) { - PyObject *tuple = params; - params = PySequence_Concat(tuple, pc->extra_args); - Py_DECREF(tuple); - } - ret = PyObject_CallObject(pc->callback, params); - if (ret == NULL) { - if (pc->exception_handler) - pc->exception_handler(return_value, n_param_values, param_values); - else - PyErr_Print(); - goto out; - } - - if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { - /* If we already have an exception set, use that, otherwise set a - * generic one */ - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_TypeError, - "can't convert return value to desired type"); - - if (pc->exception_handler) - pc->exception_handler(return_value, n_param_values, param_values); - else - PyErr_Print(); - } - Py_DECREF(ret); - - out: - Py_DECREF(params); - pyglib_gil_state_release(state); -} - -/** - * pyg_closure_new: - * callback: a Python callable object - * extra_args: a tuple of extra arguments, or None/NULL. - * swap_data: an alternative python object to pass first. - * - * Creates a GClosure wrapping a Python callable and optionally a set - * of additional function arguments. This is needed to attach python - * handlers to signals, for instance. - * - * Returns: the new closure. - */ -GClosure * -pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data) -{ - GClosure *closure; - - g_return_val_if_fail(callback != NULL, NULL); - closure = g_closure_new_simple(sizeof(PyGClosure), NULL); - g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate); - g_closure_set_marshal(closure, pyg_closure_marshal); - Py_INCREF(callback); - ((PyGClosure *)closure)->callback = callback; - if (extra_args && extra_args != Py_None) { - Py_INCREF(extra_args); - if (!PyTuple_Check(extra_args)) { - PyObject *tmp = PyTuple_New(1); - PyTuple_SetItem(tmp, 0, extra_args); - extra_args = tmp; - } - ((PyGClosure *)closure)->extra_args = extra_args; - } - if (swap_data) { - Py_INCREF(swap_data); - ((PyGClosure *)closure)->swap_data = swap_data; - closure->derivative_flag = TRUE; - } - return closure; -} - -/** - * pyg_closure_set_exception_handler: - * @closure: a closure created with pyg_closure_new() - * @handler: the handler to call when an exception occurs or NULL for none - * - * Sets the handler to call when an exception occurs during closure invocation. - * The handler is responsible for providing a proper return value to the - * closure invocation. If @handler is %NULL, the default handler will be used. - * The default handler prints the exception to stderr and doesn't touch the - * closure's return value. - */ -void -pyg_closure_set_exception_handler(GClosure *closure, - PyClosureExceptionHandler handler) -{ - PyGClosure *pygclosure; - - g_return_if_fail(closure != NULL); - - pygclosure = (PyGClosure *)closure; - pygclosure->exception_handler = handler; -} -/* -------------- PySignalClassClosure ----------------- */ -/* a closure used for the `class closure' of a signal. As this gets - * all the info from the first argument to the closure and the - * invocation hint, we can have a single closure that handles all - * class closure cases. We call a method by the name of the signal - * with "do_" prepended. - * - * We also remove the first argument from the * param list, as it is - * the instance object, which is passed * implicitly to the method - * object. */ - -static void -pyg_signal_class_closure_marshal(GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - PyGILState_STATE state; - GObject *object; - PyObject *object_wrapper; - GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint; - gchar *method_name, *tmp; - PyObject *method; - PyObject *params, *ret; - guint i, len; - - state = pyglib_gil_state_ensure(); - - g_return_if_fail(invocation_hint != NULL); - /* get the object passed as the first argument to the closure */ - object = g_value_get_object(¶m_values[0]); - g_return_if_fail(object != NULL && G_IS_OBJECT(object)); - - /* get the wrapper for this object */ - object_wrapper = pygobject_new(object); - g_return_if_fail(object_wrapper != NULL); - - /* construct method name for this class closure */ - method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL); - - /* convert dashes to underscores. For some reason, g_signal_name - * seems to convert all the underscores in the signal name to - dashes??? */ - for (tmp = method_name; *tmp != '\0'; tmp++) - if (*tmp == '-') *tmp = '_'; - - method = PyObject_GetAttrString(object_wrapper, method_name); - g_free(method_name); - - if (!method) { - PyErr_Clear(); - Py_DECREF(object_wrapper); - pyglib_gil_state_release(state); - return; - } - Py_DECREF(object_wrapper); - - /* construct Python tuple for the parameter values; don't copy boxed values - initially because we'll check after the call to see if a copy is needed. */ - params = PyTuple_New(n_param_values - 1); - for (i = 1; i < n_param_values; i++) { - PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); - - /* error condition */ - if (!item) { - Py_DECREF(params); - pyglib_gil_state_release(state); - return; - } - PyTuple_SetItem(params, i - 1, item); - } - - ret = PyObject_CallObject(method, params); - - /* Copy boxed values if others ref them, this needs to be done regardless of - exception status. */ - len = PyTuple_Size(params); - for (i = 0; i < len; i++) { - PyObject *item = PyTuple_GetItem(params, i); - if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type) - && item->ob_refcnt != 1) { - PyGBoxed* boxed_item = (PyGBoxed*)item; - if (!boxed_item->free_on_dealloc) { - boxed_item->boxed = g_boxed_copy(boxed_item->gtype, boxed_item->boxed); - boxed_item->free_on_dealloc = TRUE; - } - } - } - - if (ret == NULL) { - PyErr_Print(); - Py_DECREF(method); - Py_DECREF(params); - pyglib_gil_state_release(state); - return; - } - Py_DECREF(method); - Py_DECREF(params); - if (G_IS_VALUE(return_value)) - pyg_value_from_pyobject(return_value, ret); - Py_DECREF(ret); - pyglib_gil_state_release(state); -} - -/** - * pyg_signal_class_closure_get: - * - * Returns the GClosure used for the class closure of signals. When - * called, it will invoke the method do_signalname (for the signal - * "signalname"). - * - * Returns: the closure. - */ -GClosure * -pyg_signal_class_closure_get(void) -{ - static GClosure *closure; - - if (closure == NULL) { - closure = g_closure_new_simple(sizeof(GClosure), NULL); - g_closure_set_marshal(closure, pyg_signal_class_closure_marshal); - - g_closure_ref(closure); - g_closure_sink(closure); - } - return closure; -} - -GClosure * -gclosure_from_pyfunc(PyGObject *object, PyObject *func) -{ - GSList *l; - PyGObjectData *inst_data; - inst_data = pyg_object_peek_inst_data(object->obj); - if (inst_data) { - for (l = inst_data->closures; l; l = l->next) { - PyGClosure *pyclosure = l->data; - int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ); - if (res == -1) { - PyErr_Clear(); // Is there anything else to do? - } else if (res) { - return (GClosure*)pyclosure; - } - } - } - return NULL; -} - -/* ----- __doc__ descriptor for GObject and GInterface ----- */ - -static void -object_doc_dealloc(PyObject *self) -{ - PyObject_FREE(self); -} - -/* append information about signals of a particular gtype */ -static void -add_signal_docs(GType gtype, GString *string) -{ - GTypeClass *class = NULL; - guint *signal_ids, n_ids = 0, i; - - if (G_TYPE_IS_CLASSED(gtype)) - class = g_type_class_ref(gtype); - signal_ids = g_signal_list_ids(gtype, &n_ids); - - if (n_ids > 0) { - g_string_append_printf(string, "Signals from %s:\n", - g_type_name(gtype)); - - for (i = 0; i < n_ids; i++) { - GSignalQuery query; - guint j; - - g_signal_query(signal_ids[i], &query); - - g_string_append(string, " "); - g_string_append(string, query.signal_name); - g_string_append(string, " ("); - for (j = 0; j < query.n_params; j++) { - g_string_append(string, g_type_name(query.param_types[j])); - if (j != query.n_params - 1) - g_string_append(string, ", "); - } - g_string_append(string, ")"); - if (query.return_type && query.return_type != G_TYPE_NONE) { - g_string_append(string, " -> "); - g_string_append(string, g_type_name(query.return_type)); - } - g_string_append(string, "\n"); - } - g_free(signal_ids); - g_string_append(string, "\n"); - } - if (class) - g_type_class_unref(class); -} - -static void -add_property_docs(GType gtype, GString *string) -{ - GObjectClass *class; - GParamSpec **props; - guint n_props = 0, i; - gboolean has_prop = FALSE; - G_CONST_RETURN gchar *blurb=NULL; - - class = g_type_class_ref(gtype); - props = g_object_class_list_properties(class, &n_props); - - for (i = 0; i < n_props; i++) { - if (props[i]->owner_type != gtype) - continue; /* these are from a parent type */ - - /* print out the heading first */ - if (!has_prop) { - g_string_append_printf(string, "Properties from %s:\n", - g_type_name(gtype)); - has_prop = TRUE; - } - g_string_append_printf(string, " %s -> %s: %s\n", - g_param_spec_get_name(props[i]), - g_type_name(props[i]->value_type), - g_param_spec_get_nick(props[i])); - - /* g_string_append_printf crashes on win32 if the third - argument is NULL. */ - blurb=g_param_spec_get_blurb(props[i]); - if (blurb) - g_string_append_printf(string, " %s\n",blurb); - } - g_free(props); - if (has_prop) - g_string_append(string, "\n"); - g_type_class_unref(class); -} - -static PyObject * -object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type) -{ - GType gtype = 0; - GString *string; - PyObject *pystring; - - if (obj && pygobject_check(obj, &PyGObject_Type)) { - gtype = G_OBJECT_TYPE(pygobject_get(obj)); - if (!gtype) - PyErr_SetString(PyExc_RuntimeError, "could not get object type"); - } else { - gtype = pyg_type_from_object(type); - } - if (!gtype) - return NULL; - - string = g_string_new_len(NULL, 512); - - if (g_type_is_a(gtype, G_TYPE_INTERFACE)) - g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype)); - else if (g_type_is_a(gtype, G_TYPE_OBJECT)) - g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype)); - else - g_string_append_printf(string, "%s\n\n", g_type_name(gtype)); - - if (((PyTypeObject *) type)->tp_doc) - g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc); - - if (g_type_is_a(gtype, G_TYPE_OBJECT)) { - GType parent = G_TYPE_OBJECT; - GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType)); - int iparent; - - while (parent) { - g_array_append_val(parents, parent); - parent = g_type_next_base(gtype, parent); - } - - for (iparent = parents->len - 1; iparent >= 0; --iparent) { - GType *interfaces; - guint n_interfaces, i; - - parent = g_array_index(parents, GType, iparent); - add_signal_docs(parent, string); - add_property_docs(parent, string); - - /* add docs for implemented interfaces */ - interfaces = g_type_interfaces(parent, &n_interfaces); - for (i = 0; i < n_interfaces; i++) - add_signal_docs(interfaces[i], string); - g_free(interfaces); - } - g_array_free(parents, TRUE); - } - - pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len); - g_string_free(string, TRUE); - return pystring; -} - -PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject); - -/** - * pyg_object_descr_doc_get: - * - * Returns an object intended to be the __doc__ attribute of GObject - * wrappers. When read in the context of the object it will return - * some documentation about the signals and properties of the object. - * - * Returns: the descriptor. - */ -PyObject * -pyg_object_descr_doc_get(void) -{ - static PyObject *doc_descr = NULL; - - if (!doc_descr) { - Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type; - if (PyType_Ready(&PyGObjectDoc_Type)) - return NULL; - - doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type); - if (doc_descr == NULL) - return NULL; - } - return doc_descr; -} - - -/** - * pyg_pyobj_to_unichar_conv: - * - * Converts PyObject value to a unichar and write result to memory - * pointed to by ptr. Follows the calling convention of a ParseArgs - * converter (O& format specifier) so it may be used to convert function - * arguments. - * - * Returns: 1 if the conversion succeeds and 0 otherwise. If the conversion - * did not succeesd, a Python exception is raised - */ -int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr) -{ - gunichar* u = ptr; - const Py_UNICODE* uni_buffer; - PyObject* tmp_uni = NULL; - - if (PyUnicode_Check(py_obj)) { - tmp_uni = py_obj; - Py_INCREF(tmp_uni); - } - else { - tmp_uni = PyUnicode_FromObject(py_obj); - if (tmp_uni == NULL) - goto failure; - } - - if ( PyUnicode_GetSize(tmp_uni) != 1) { - PyErr_SetString(PyExc_ValueError, "unicode character value must be 1 character uniode string"); - goto failure; - } - uni_buffer = PyUnicode_AsUnicode(tmp_uni); - if ( uni_buffer == NULL) - goto failure; - *u = uni_buffer[0]; - - Py_DECREF(tmp_uni); - return 1; - - failure: - Py_XDECREF(tmp_uni); - return 0; -} - - -int -pyg_param_gvalue_from_pyobject(GValue* value, - PyObject* py_obj, - const GParamSpec* pspec) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - gunichar u; - - if (!pyg_pyobj_to_unichar_conv(py_obj, &u)) { - PyErr_Clear(); - return -1; - } - g_value_set_uint(value, u); - return 0; - } - else if (G_IS_PARAM_SPEC_VALUE_ARRAY(pspec)) - return pyg_value_array_from_pyobject(value, py_obj, - G_PARAM_SPEC_VALUE_ARRAY(pspec)); - else { - return pyg_value_from_pyobject(value, py_obj); - } -} - -PyObject* -pyg_param_gvalue_as_pyobject(const GValue* gvalue, - gboolean copy_boxed, - const GParamSpec* pspec) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - gunichar u; - Py_UNICODE uni_buffer[2] = { 0, 0 }; - - u = g_value_get_uint(gvalue); - uni_buffer[0] = u; - return PyUnicode_FromUnicode(uni_buffer, 1); - } - else { - return pyg_value_as_pyobject(gvalue, copy_boxed); - } -} - -gboolean -pyg_gtype_is_custom(GType gtype) -{ - return g_type_get_qdata (gtype, pygobject_custom_key) != NULL; -} - -static PyObject * -_pyg_strv_from_gvalue(const GValue *value) -{ - gchar **argv = (gchar **) g_value_get_boxed(value); - int argc = 0, i; - PyObject *py_argv; - - if (argv) { - while (argv[argc]) - argc++; - } - py_argv = PyList_New(argc); - for (i = 0; i < argc; ++i) - PyList_SET_ITEM(py_argv, i, PYGLIB_PyUnicode_FromString(argv[i])); - return py_argv; -} - -static int -_pyg_strv_to_gvalue(GValue *value, PyObject *obj) -{ - Py_ssize_t argc, i; - gchar **argv; - - if (!(PyTuple_Check(obj) || PyList_Check(obj))) - return -1; - - argc = PySequence_Length(obj); - for (i = 0; i < argc; ++i) - if (!PYGLIB_PyUnicode_Check(PySequence_Fast_GET_ITEM(obj, i))) - return -1; - argv = g_new(gchar *, argc + 1); - for (i = 0; i < argc; ++i) - argv[i] = g_strdup(PYGLIB_PyUnicode_AsString(PySequence_Fast_GET_ITEM(obj, i))); - argv[i] = NULL; - g_value_take_boxed(value, argv); - return 0; -} - -void -pygobject_type_register_types(PyObject *d) -{ - PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc; - PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare; - PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr; - PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash; - PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods; - PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets; - PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init; - PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType"); - - /* This type lazily registered in pyg_object_descr_doc_get */ - PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc; - PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT; - PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get; - - pyg_register_gtype_custom(G_TYPE_STRV, - _pyg_strv_from_gvalue, - _pyg_strv_to_gvalue); -} diff --git a/gi/_gobject/pygtype.h b/gi/_gobject/pygtype.h deleted file mode 100644 index 2f9e7ad..0000000 --- a/gi/_gobject/pygtype.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * pygtk- Python bindings for the GTK toolkit. - * Copyright (C) 1998-2003 James Henstridge - * 2004-2008 Johan Dahlin - * pyginterface.c: wrapper for the gobject library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGOBJECT_TYPE_H__ -#define __PYGOBJECT_TYPE_H__ - -void pygobject_type_register_types(PyObject *d); - -#endif /* __PYGOBJECT_TYPE_H__ */ diff --git a/gi/_gobject/signalhelper.py b/gi/_gobject/signalhelper.py deleted file mode 100644 index b630158..0000000 --- a/gi/_gobject/signalhelper.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- Mode: Python; py-indent-offset: 4 -*- -# pygobject - Python bindings for the GObject library -# Copyright (C) 2012 Simon Feltman -# -# gobject/signalhelper.py: GObject signal binding decorator object -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 -# USA - -import sys -import inspect - -from . import _gobject - -# Callable went away in python 3.0 and came back in 3.2. -# Use versioning to figure out when to define it, otherwise we have to deal with -# the complexity of using __builtin__ or builtin between python versions to -# check if callable exists which PyFlakes will also complain about. -if (3, 0) <= sys.version_info < (3, 2): - def callable(fn): - return hasattr(fn, '__call__') - - -class Signal(str): - """ - Object which gives a nice API for creating and binding signals. - - Example: - class Spam(GObject.GObject): - velocity = 0 - - @GObject.Signal - def pushed(self): - self.velocity += 1 - - @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST) - def pulled(self): - self.velocity -= 1 - - stomped = GObject.Signal('stomped', arg_types=(int,)) - - @GObject.Signal - def annotated_signal(self, a:int, b:str): - "Python3 annotation support for parameter types. - - def on_pushed(obj): - print(obj) - - spam = Spam() - spam.pushed.connect(on_pushed) - spam.pushed.emit() - """ - class BoundSignal(str): - """ - Temporary binding object which can be used for connecting signals - without specifying the signal name string to connect. - """ - def __new__(cls, name, *args, **kargs): - return str.__new__(cls, name) - - def __init__(self, signal, gobj): - str.__init__(self) - self.signal = signal - self.gobj = gobj - - def __repr__(self): - return 'BoundSignal("%s")' % self - - def __call__(self, *args, **kargs): - """Call the signals closure.""" - return self.signal.func(self.gobj, *args, **kargs) - - def connect(self, callback, *args, **kargs): - """Same as GObject.GObject.connect except there is no need to specify - the signal name.""" - return self.gobj.connect(self, callback, *args, **kargs) - - def connect_detailed(self, callback, detail, *args, **kargs): - """Same as GObject.GObject.connect except there is no need to specify - the signal name. In addition concats "::" to the signal name - when connecting; for use with notifications like "notify" when a property - changes. - """ - return self.gobj.connect(self + '::' + detail, callback, *args, **kargs) - - def disconnect(self, handler_id): - """Same as GObject.GObject.disconnect.""" - self.instance.disconnect(handler_id) - - def emit(self, *args, **kargs): - """Same as GObject.GObject.emit except there is no need to specify - the signal name.""" - return self.gobj.emit(str(self), *args, **kargs) - - def __new__(cls, name='', *args, **kargs): - if callable(name): - name = name.__name__ - return str.__new__(cls, name) - - def __init__(self, name='', func=None, flags=_gobject.SIGNAL_RUN_FIRST, - return_type=None, arg_types=None, doc='', accumulator=None, accu_data=None): - """ - @param name: name of signal or closure method when used as direct decorator. - @type name: string or callable - @param func: closure method. - @type func: callable - @param flags: flags specifying when to run closure - @type flags: GObject.SignalFlags - @param return_type: return type - @type return_type: type - @param arg_types: list of argument types specifying the signals function signature - @type arg_types: None - @param doc: documentation of signal object - @type doc: string - @param accumulator: accumulator method with the signature: - func(ihint, return_accu, handler_return, accu_data) -> boolean - @type accumulator: function - @param accu_data: user data passed to the accumulator - @type accu_data: object - """ - if func and not name: - name = func.__name__ - elif callable(name): - func = name - name = func.__name__ - if func and not doc: - doc = func.__doc__ - - str.__init__(self) - - if func and not (return_type or arg_types): - return_type, arg_types = get_signal_annotations(func) - if arg_types is None: - arg_types = tuple() - - self.func = func - self.flags = flags - self.return_type = return_type - self.arg_types = arg_types - self.__doc__ = doc - self.accumulator = accumulator - self.accu_data = accu_data - - def __get__(self, instance, owner=None): - """Returns a BoundSignal when accessed on an object instance.""" - if instance is None: - return self - return self.BoundSignal(self, instance) - - def __call__(self, obj, *args, **kargs): - """Allows for instantiated Signals to be used as a decorator or calling - of the underlying signal method.""" - - # If obj is a GObject, than we call this signal as a closure otherwise - # it is used as a re-application of a decorator. - if isinstance(obj, _gobject.GObject): - self.func(obj, *args, **kargs) - else: - # If self is already an allocated name, use it otherwise create a new named - # signal using the closure name as the name. - if str(self): - name = str(self) - else: - name = obj.__name__ - # Return a new value of this type since it is based on an immutable string. - return type(self)(name=name, func=obj, flags=self.flags, - return_type=self.return_type, arg_types=self.arg_types, - doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data) - - def copy(self, newName=None): - """Returns a renamed copy of the Signal.""" - if newName is None: - newName = self.name - return type(self)(name=newName, func=self.func, flags=self.flags, - return_type=self.return_type, arg_types=self.arg_types, - doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data) - - def get_signal_args(self): - """Returns a tuple of: (flags, return_type, arg_types, accumulator, accu_data)""" - return (self.flags, self.return_type, self.arg_types, self.accumulator, self.accu_data) - - -class SignalOverride(Signal): - """Specialized sub-class of signal which can be used as a decorator for overriding - existing signals on GObjects. - - Example: - class MyWidget(Gtk.Widget): - @GObject.SignalOverride - def configure_event(self): - pass - """ - def get_signal_args(self): - """Returns the string 'override'.""" - return 'override' - - -def get_signal_annotations(func): - """Attempt pulling python 3 function annotations off of 'func' for - use as a signals type information. Returns an ordered nested tuple - of (return_type, (arg_type1, arg_type2, ...)). If the given function - does not have annotations then (None, tuple()) is returned. - """ - arg_types = tuple() - return_type = None - - if hasattr(func, '__annotations__'): - spec = inspect.getfullargspec(func) - arg_types = tuple(spec.annotations[arg] for arg in spec.args - if arg in spec.annotations) - if 'return' in spec.annotations: - return_type = spec.annotations['return'] - - return return_type, arg_types - - -def install_signals(cls): - """Adds Signal instances on a GObject derived class into the '__gsignals__' - dictionary to be picked up and registered as real GObject signals. - """ - gsignals = cls.__dict__.get('__gsignals__', {}) - newsignals = {} - for name, signal in cls.__dict__.items(): - if isinstance(signal, Signal): - signalName = str(signal) - # Fixup a signal which is unnamed by using the class variable name. - # Since Signal is based on string which immutable, - # we must copy and replace the class variable. - if not signalName: - signalName = name - signal = signal.copy(name) - setattr(cls, name, signal) - if signalName in gsignals: - raise ValueError('Signal "%s" has already been registered.' % name) - newsignals[signalName] = signal - gsignals[signalName] = signal.get_signal_args() - - cls.__gsignals__ = gsignals - - # Setup signal closures by adding the specially named - # method to the class in the form of "do_". - for name, signal in newsignals.items(): - if signal.func is not None: - funcName = 'do_' + name.replace('-', '_') - if not hasattr(cls, funcName): - setattr(cls, funcName, signal.func) diff --git a/gi/_option.py b/gi/_option.py new file mode 100644 index 0000000..0649081 --- /dev/null +++ b/gi/_option.py @@ -0,0 +1,363 @@ +# -*- Mode: Python -*- +# pygobject - Python bindings for the GObject library +# Copyright (C) 2006 Johannes Hoelzl +# +# glib/option.py: GOption command line parser +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA + +"""GOption command line parser + +Extends optparse to use the GOptionGroup, GOptionEntry and GOptionContext +objects. So it is possible to use the gtk, gnome_program and gstreamer command +line groups and contexts. + +Use this interface instead of the raw wrappers of GOptionContext and +GOptionGroup in glib. +""" + +import sys +import optparse +from optparse import OptParseError, OptionError, OptionValueError, \ + BadOptionError, OptionConflictError +from .module import get_introspection_module + +if sys.version_info >= (3, 0): + _basestring = str + _bytes = lambda s: s.encode() +else: + _basestring = basestring + _bytes = str + +from gi._gi import _glib +GLib = get_introspection_module('GLib') + +OPTION_CONTEXT_ERROR_QUARK = GLib.quark_to_string(GLib.option_error_quark()) + +__all__ = [ + "OptParseError", + "OptionError", + "OptionValueError", + "BadOptionError", + "OptionConflictError", + "Option", + "OptionGroup", + "OptionParser", + "make_option", +] + + +class Option(optparse.Option): + """Represents a command line option + + To use the extended possibilities of the GOption API Option + (and make_option) are extended with new types and attributes. + + Types: + filename The supplied arguments are read as filename, GOption + parses this type in with the GLib filename encoding. + + Attributes: + optional_arg This does not need a arguement, but it can be supplied. + hidden The help list does not show this option + in_main This option apears in the main group, this should only + be used for backwards compatibility. + + Use Option.REMAINING as option name to get all positional arguments. + + NOTE: Every argument to an option is passed as utf-8 coded string, the only + exception are options which use the 'filename' type, its arguments + are passed as strings in the GLib filename encoding. + + For further help, see optparse.Option. + """ + TYPES = optparse.Option.TYPES + ( + 'filename', + ) + + ATTRS = optparse.Option.ATTRS + [ + 'hidden', + 'in_main', + 'optional_arg', + ] + + REMAINING = '--' + GLib.OPTION_REMAINING + + def __init__(self, *args, **kwargs): + optparse.Option.__init__(self, *args, **kwargs) + if not self._long_opts: + raise ValueError("%s at least one long option name.") + + if len(self._long_opts) < len(self._short_opts): + raise ValueError( + "%s at least more long option names than short option names.") + + if not self.help: + raise ValueError("%s needs a help message.", self._long_opts[0]) + + def _set_opt_string(self, opts): + if self.REMAINING in opts: + self._long_opts.append(self.REMAINING) + optparse.Option._set_opt_string(self, opts) + if len(self._short_opts) > len(self._long_opts): + raise OptionError("goption.Option needs more long option names " + "than short option names") + + def _to_goptionentries(self): + flags = 0 + + if self.hidden: + flags |= GLib.OptionFlags.HIDDEN + + if self.in_main: + flags |= GLib.OptionFlags.IN_MAIN + + if self.takes_value(): + if self.optional_arg: + flags |= GLib.OptionFlags.OPTIONAL_ARG + else: + flags |= GLib.OptionFlags.NO_ARG + + if self.type == 'filename': + flags |= GLib.OptionFlags.FILENAME + + for (long_name, short_name) in zip(self._long_opts, self._short_opts): + yield (long_name[2:], _bytes(short_name[1]), flags, self.help, self.metavar) + + for long_name in self._long_opts[len(self._short_opts):]: + yield (long_name[2:], _bytes('\0'), flags, self.help, self.metavar) + + +class OptionGroup(optparse.OptionGroup): + """A group of command line options. + + Arguements: + name: The groups name, used to create the + --help-{name} option + description: Shown as title of the groups help view + help_description: Shown as help to the --help-{name} option + option_list: The options used in this group, must be option.Option() + defaults: A dicitionary of default values + translation_domain: Sets the translation domain for gettext(). + + NOTE: This OptionGroup does not exactly map the optparse.OptionGroup + interface. There is no parser object to supply, but it is possible + to set default values and option_lists. Also the default values and + values are not shared with the OptionParser. + + To pass a OptionGroup into a function which expects a GOptionGroup (e.g. + gnome_program_init() ). OptionGroup.get_option_group() can be used. + + For further help, see optparse.OptionGroup. + """ + def __init__(self, name, description, help_description="", + option_list=None, defaults=None, + translation_domain=None): + optparse.OptionContainer.__init__(self, Option, 'error', description) + self.name = name + self.parser = None + self.help_description = help_description + if defaults: + self.defaults = defaults + + self.values = None + + self.translation_domain = translation_domain + + if option_list: + for option in option_list: + self.add_option(option) + + def _create_option_list(self): + self.option_list = [] + self._create_option_mappings() + + def _to_goptiongroup(self, parser): + def callback(option_name, option_value, group): + if option_name.startswith('--'): + opt = self._long_opt[option_name] + else: + opt = self._short_opt[option_name] + + try: + opt.process(option_name, option_value, self.values, parser) + except OptionValueError: + error = sys.exc_info()[1] + gerror = _glib.GError(str(error)) + gerror.domain = OPTION_CONTEXT_ERROR_QUARK + gerror.code = GLib.OptionError.BAD_VALUE + gerror.message = str(error) + raise gerror + + group = _glib.OptionGroup(self.name, self.description, + self.help_description, callback) + if self.translation_domain: + group.set_translation_domain(self.translation_domain) + + entries = [] + for option in self.option_list: + entries.extend(option._to_goptionentries()) + + group.add_entries(entries) + + return group + + def get_option_group(self, parser=None): + """ Returns the corresponding GOptionGroup object. + + Can be used as parameter for gnome_program_init(), gtk_init(). + """ + self.set_values_to_defaults() + return self._to_goptiongroup(parser) + + def set_values_to_defaults(self): + for option in self.option_list: + default = self.defaults.get(option.dest) + if isinstance(default, _basestring): + opt_str = option.get_opt_string() + self.defaults[option.dest] = option.check_value( + opt_str, default) + self.values = optparse.Values(self.defaults) + + +class OptionParser(optparse.OptionParser): + """Command line parser with GOption support. + + NOTE: The OptionParser interface is not the exactly the same as the + optparse.OptionParser interface. Especially the usage parameter + is only used to show the metavar of the arguements. + + Attribues: + help_enabled: The --help, --help-all and --help-{group} + options are enabled (default). + ignore_unknown_options: Do not throw a exception when a option is not + knwon, the option will be in the result list. + + OptionParser.add_option_group() does not only accept OptionGroup instances + but also glib.OptionGroup, which is returned by gtk_get_option_group(). + + Only glib.option.OptionGroup and glib.option.Option instances should + be passed as groups and options. + + For further help, see optparse.OptionParser. + """ + + def __init__(self, *args, **kwargs): + if 'option_class' not in kwargs: + kwargs['option_class'] = Option + self.help_enabled = kwargs.pop('help_enabled', True) + self.ignore_unknown_options = kwargs.pop('ignore_unknown_options', + False) + optparse.OptionParser.__init__(self, add_help_option=False, + *args, **kwargs) + + def set_usage(self, usage): + if usage is None: + self.usage = '' + elif usage.startswith("%prog"): + self.usage = usage[len("%prog"):] + else: + self.usage = usage + + def _to_goptioncontext(self, values): + if self.description: + parameter_string = self.usage + " - " + self.description + else: + parameter_string = self.usage + context = _glib.OptionContext(parameter_string) + context.set_help_enabled(self.help_enabled) + context.set_ignore_unknown_options(self.ignore_unknown_options) + + for option_group in self.option_groups: + if isinstance(option_group, _glib.OptionGroup): + g_group = option_group + else: + g_group = option_group.get_option_group(self) + context.add_group(g_group) + + def callback(option_name, option_value, group): + if option_name.startswith('--'): + opt = self._long_opt[option_name] + else: + opt = self._short_opt[option_name] + opt.process(option_name, option_value, values, self) + + main_group = _glib.OptionGroup(None, None, None, callback) + main_entries = [] + for option in self.option_list: + main_entries.extend(option._to_goptionentries()) + main_group.add_entries(main_entries) + context.set_main_group(main_group) + + return context + + def add_option_group(self, *args, **kwargs): + if isinstance(args[0], _basestring): + optparse.OptionParser.add_option_group(self, + OptionGroup(self, *args, **kwargs)) + return + elif len(args) == 1 and not kwargs: + if isinstance(args[0], OptionGroup): + if not args[0].parser: + args[0].parser = self + if args[0].parser is not self: + raise ValueError("invalid OptionGroup (wrong parser)") + if isinstance(args[0], _glib.OptionGroup): + self.option_groups.append(args[0]) + return + optparse.OptionParser.add_option_group(self, *args, **kwargs) + + def _get_all_options(self): + options = self.option_list[:] + for group in self.option_groups: + if isinstance(group, optparse.OptionGroup): + options.extend(group.option_list) + return options + + def _process_args(self, largs, rargs, values): + context = self._to_goptioncontext(values) + + # _process_args() returns the remaining parameters in rargs. + # The prepended program name is used to all g_set_prgname() + # The program name is cut away so it doesn't appear in the result. + rargs[:] = context.parse([sys.argv[0]] + rargs)[1:] + + def parse_args(self, args=None, values=None): + old_args = args or [] + try: + options, args = optparse.OptionParser.parse_args( + self, args, values) + except _glib.GError: + error = sys.exc_info()[1] + if error.domain != OPTION_CONTEXT_ERROR_QUARK: + raise + if error.code == GLib.OptionError.BAD_VALUE: + raise OptionValueError(error.message) + elif error.code == GLib.OptionError.UNKNOWN_OPTION: + raise BadOptionError(error.message) + elif error.code == GLib.OptionError.FAILED: + raise OptParseError(error.message) + else: + raise + + for group in self.option_groups: + for key, value in group.values.__dict__.items(): + options.ensure_value(key, value) + + args = args[2:-len(old_args)] + return options, args + +make_option = Option diff --git a/gi/_propertyhelper.py b/gi/_propertyhelper.py new file mode 100644 index 0000000..ddc81cc --- /dev/null +++ b/gi/_propertyhelper.py @@ -0,0 +1,417 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# pygobject - Python bindings for the GObject library +# Copyright (C) 2007 Johan Dahlin +# +# gi/_propertyhelper.py: GObject property wrapper/helper +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA + +import sys + +import gi._gi +_gobject = gi._gi._gobject + +from ._constants import \ + TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, \ + TYPE_BOOLEAN, TYPE_INT, TYPE_UINT, TYPE_LONG, \ + TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, TYPE_FLAGS, \ + TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \ + TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \ + TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT + +G_MAXFLOAT = _gobject.G_MAXFLOAT +G_MAXDOUBLE = _gobject.G_MAXDOUBLE +G_MININT = _gobject.G_MININT +G_MAXINT = _gobject.G_MAXINT +G_MAXUINT = _gobject.G_MAXUINT +G_MINLONG = _gobject.G_MINLONG +G_MAXLONG = _gobject.G_MAXLONG +G_MAXULONG = _gobject.G_MAXULONG + +if sys.version_info >= (3, 0): + _basestring = str + _long = int +else: + _basestring = basestring + _long = long + + +class Property(object): + """ + Creates a new property which in conjunction with GObject subclass will + create a property proxy: + + class MyObject(GObject.GObject): + ... prop = GObject.Property(type=str) + + obj = MyObject() + obj.prop = 'value' + + obj.prop # now is 'value' + + The API is similar to the builtin property: + + class AnotherObject(GObject.GObject): + @GObject.Property + def prop(self): + '''Read only property.''' + return ... + + @GObject.Property(type=int) + def propInt(self): + '''Read-write integer property.''' + return ... + + @propInt.setter + def propInt(self, value): + ... + """ + _type_from_pytype_lookup = { + # Put long_ first in case long_ and int are the same so int clobbers long_ + _long: TYPE_LONG, + int: TYPE_INT, + bool: TYPE_BOOLEAN, + float: TYPE_DOUBLE, + str: TYPE_STRING, + object: TYPE_PYOBJECT, + } + + _min_value_lookup = { + TYPE_UINT: 0, + TYPE_ULONG: 0, + TYPE_UINT64: 0, + # Remember that G_MINFLOAT and G_MINDOUBLE are something different. + TYPE_FLOAT: -G_MAXFLOAT, + TYPE_DOUBLE: -G_MAXDOUBLE, + TYPE_INT: G_MININT, + TYPE_LONG: G_MINLONG, + TYPE_INT64: -2 ** 63, + } + + _max_value_lookup = { + TYPE_UINT: G_MAXUINT, + TYPE_ULONG: G_MAXULONG, + TYPE_INT64: 2 ** 63 - 1, + TYPE_UINT64: 2 ** 64 - 1, + TYPE_FLOAT: G_MAXFLOAT, + TYPE_DOUBLE: G_MAXDOUBLE, + TYPE_INT: G_MAXINT, + TYPE_LONG: G_MAXLONG, + } + + _default_lookup = { + TYPE_INT: 0, + TYPE_UINT: 0, + TYPE_LONG: 0, + TYPE_ULONG: 0, + TYPE_INT64: 0, + TYPE_UINT64: 0, + TYPE_STRING: '', + TYPE_FLOAT: 0.0, + TYPE_DOUBLE: 0.0, + } + + class __metaclass__(type): + def __repr__(self): + return "" + + def __init__(self, getter=None, setter=None, type=None, default=None, + nick='', blurb='', flags=_gobject.PARAM_READWRITE, + minimum=None, maximum=None): + """ + @param getter: getter to get the value of the property + @type getter: callable + @param setter: setter to set the value of the property + @type setter: callable + @param type: type of property + @type type: type + @param default: default value + @param nick: short description + @type nick: string + @param blurb: long description + @type blurb: string + @param flags: parameter flags, one of: + - gobject.PARAM_READABLE + - gobject.PARAM_READWRITE + - gobject.PARAM_WRITABLE + - gobject.PARAM_CONSTRUCT + - gobject.PARAM_CONSTRUCT_ONLY + - gobject.PARAM_LAX_VALIDATION + @keyword minimum: minimum allowed value (int, float, long only) + @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) + self.default = self._get_default(default) + self._check_default() + + if not isinstance(nick, _basestring): + raise TypeError("nick must be a string") + self.nick = nick + + if not isinstance(blurb, _basestring): + raise TypeError("blurb must be a string") + self.blurb = blurb + # Always clobber __doc__ with blurb even if blurb is empty because + # we don't want the lengthy Property class documentation showing up + # on instances. + self.__doc__ = blurb + self.flags = flags + + # Call after setting blurb for potential __doc__ usage. + if getter and not setter: + setter = self._readonly_setter + elif setter and not getter: + getter = self._writeonly_getter + elif not setter and not getter: + getter = self._default_getter + setter = self._default_setter + self.getter(getter) + # 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(): + raise TypeError( + "Minimum for type %s cannot be lower than %d" % + (self.type, self._get_minimum())) + else: + minimum = self._get_minimum() + self.minimum = minimum + if maximum is not None: + if maximum > self._get_maximum(): + raise TypeError( + "Maximum for type %s cannot be higher than %d" % + (self.type, self._get_maximum())) + else: + maximum = self._get_maximum() + self.maximum = maximum + + self._exc = None + + def __repr__(self): + return '' % ( + self.name or '(uninitialized)', + _gobject.type_name(self.type)) + + def __get__(self, instance, klass): + if instance is None: + return self + + self._exc = None + value = instance.get_property(self.name) + if self._exc: + exc = self._exc + self._exc = None + raise exc + + return value + + def __set__(self, instance, value): + if instance is None: + raise TypeError + + self._exc = None + instance.set_property(self.name, value) + if self._exc: + exc = self._exc + self._exc = None + raise exc + + def __call__(self, fget): + """Allows application of the getter along with init arguments.""" + return self.getter(fget) + + def getter(self, fget): + """Set the getter function to fget. For use as a decorator.""" + if fget.__doc__: + # Always clobber docstring and blurb with the getter docstring. + self.blurb = fget.__doc__ + self.__doc__ = fget.__doc__ + self.fget = fget + return self + + 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_): + if type_ in self._type_from_pytype_lookup: + return self._type_from_pytype_lookup[type_] + elif (isinstance(type_, type) and + issubclass(type_, (_gobject.GObject, + _gobject.GEnum, + _gobject.GFlags, + _gobject.GBoxed, + _gobject.GInterface))): + return type_.__gtype__ + elif type_ in (TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, + TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG, + TYPE_ULONG, TYPE_INT64, TYPE_UINT64, + TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER, + TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING, + TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV, TYPE_VARIANT): + return type_ + else: + raise TypeError("Unsupported type: %r" % (type_,)) + + def _get_default(self, default): + if default is not None: + return default + return self._default_lookup.get(self.type, None) + + def _check_default(self): + ptype = self.type + default = self.default + if (ptype == TYPE_BOOLEAN and (default not in (True, False))): + raise TypeError( + "default must be True or False, not %r" % (default,)) + elif ptype == TYPE_PYOBJECT: + if default is not None: + raise TypeError("object types does not have default values") + elif ptype == TYPE_GTYPE: + if default is not None: + raise TypeError("GType types does not have default values") + elif _gobject.type_is_a(ptype, TYPE_ENUM): + if default is None: + raise TypeError("enum properties needs a default value") + elif not _gobject.type_is_a(default, ptype): + raise TypeError("enum value %s must be an instance of %r" % + (default, ptype)) + elif _gobject.type_is_a(ptype, TYPE_FLAGS): + if not _gobject.type_is_a(default, ptype): + raise TypeError("flags value %s must be an instance of %r" % + (default, ptype)) + elif _gobject.type_is_a(ptype, TYPE_STRV) and default is not None: + if not isinstance(default, list): + raise TypeError("Strv value %s must be a list" % repr(default)) + for val in default: + if type(val) not in (str, bytes): + raise TypeError("Strv value %s must contain only strings" % str(default)) + elif _gobject.type_is_a(ptype, TYPE_VARIANT) and default is not None: + if not hasattr(default, '__gtype__') or not _gobject.type_is_a(default, TYPE_VARIANT): + raise TypeError("variant value %s must be an instance of %r" % + (default, ptype)) + + def _get_minimum(self): + return self._min_value_lookup.get(self.type, None) + + def _get_maximum(self): + return self._max_value_lookup.get(self.type, None) + + # + # Getter and Setter + # + + def _default_setter(self, instance, value): + setattr(instance, '_property_helper_' + self.name, value) + + def _default_getter(self, instance): + return getattr(instance, '_property_helper_' + self.name, self.default) + + def _readonly_setter(self, instance, value): + self._exc = TypeError("%s property of %s is read-only" % ( + self.name, type(instance).__name__)) + + def _writeonly_getter(self, instance): + self._exc = TypeError("%s property of %s is write-only" % ( + self.name, type(instance).__name__)) + + # + # Public API + # + + def get_pspec_args(self): + ptype = self.type + if ptype in (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, + TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE): + args = self.minimum, self.maximum, self.default + elif (ptype == TYPE_STRING or ptype == TYPE_BOOLEAN or + ptype.is_a(TYPE_ENUM) or ptype.is_a(TYPE_FLAGS) or + ptype.is_a(TYPE_VARIANT)): + args = (self.default,) + elif ptype in (TYPE_PYOBJECT, TYPE_GTYPE): + args = () + elif ptype.is_a(TYPE_OBJECT) or ptype.is_a(TYPE_BOXED): + args = () + else: + raise NotImplementedError(ptype) + + return (self.type, self.nick, self.blurb) + args + (self.flags,) + + +def install_properties(cls): + """ + Scans the given class for instances of Property and merges them + into the classes __gproperties__ dict if it exists or adds it if not. + """ + gproperties = cls.__dict__.get('__gproperties__', {}) + + props = [] + for name, prop in cls.__dict__.items(): + if isinstance(prop, Property): # not same as the built-in + # 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: + return + + cls.__gproperties__ = gproperties + + if 'do_get_property' in cls.__dict__ or 'do_set_property' in cls.__dict__: + for prop in props: + if prop.fget != prop._default_getter or prop.fset != prop._default_setter: + raise TypeError( + "GObject subclass %r defines do_get/set_property" + " and it also uses a property with a custom setter" + " or getter. This is not allowed" % + (cls.__name__,)) + + def obj_get_property(self, pspec): + name = pspec.name.replace('-', '_') + prop = getattr(cls, name, None) + if prop: + return prop.fget(self) + cls.do_get_property = obj_get_property + + def obj_set_property(self, pspec, value): + name = pspec.name.replace('-', '_') + prop = getattr(cls, name, None) + if prop: + prop.fset(self, value) + cls.do_set_property = obj_set_property diff --git a/gi/_signalhelper.py b/gi/_signalhelper.py new file mode 100644 index 0000000..79de301 --- /dev/null +++ b/gi/_signalhelper.py @@ -0,0 +1,258 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# pygobject - Python bindings for the GObject library +# Copyright (C) 2012 Simon Feltman +# +# gi/_signalhelper.py: GObject signal binding decorator object +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +# USA + +import sys +import inspect + +from ._gi import _gobject + +# Callable went away in python 3.0 and came back in 3.2. +# Use versioning to figure out when to define it, otherwise we have to deal with +# the complexity of using __builtin__ or builtin between python versions to +# check if callable exists which PyFlakes will also complain about. +if (3, 0) <= sys.version_info < (3, 2): + def callable(fn): + return hasattr(fn, '__call__') + + +class Signal(str): + """ + Object which gives a nice API for creating and binding signals. + + Example: + class Spam(GObject.GObject): + velocity = 0 + + @GObject.Signal + def pushed(self): + self.velocity += 1 + + @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST) + def pulled(self): + self.velocity -= 1 + + stomped = GObject.Signal('stomped', arg_types=(int,)) + + @GObject.Signal + def annotated_signal(self, a:int, b:str): + "Python3 annotation support for parameter types. + + def on_pushed(obj): + print(obj) + + spam = Spam() + spam.pushed.connect(on_pushed) + spam.pushed.emit() + """ + class BoundSignal(str): + """ + Temporary binding object which can be used for connecting signals + without specifying the signal name string to connect. + """ + def __new__(cls, name, *args, **kargs): + return str.__new__(cls, name) + + def __init__(self, signal, gobj): + str.__init__(self) + self.signal = signal + self.gobj = gobj + + def __repr__(self): + return 'BoundSignal("%s")' % self + + def __call__(self, *args, **kargs): + """Call the signals closure.""" + return self.signal.func(self.gobj, *args, **kargs) + + def connect(self, callback, *args, **kargs): + """Same as GObject.GObject.connect except there is no need to specify + the signal name.""" + return self.gobj.connect(self, callback, *args, **kargs) + + def connect_detailed(self, callback, detail, *args, **kargs): + """Same as GObject.GObject.connect except there is no need to specify + the signal name. In addition concats "::" to the signal name + when connecting; for use with notifications like "notify" when a property + changes. + """ + return self.gobj.connect(self + '::' + detail, callback, *args, **kargs) + + def disconnect(self, handler_id): + """Same as GObject.GObject.disconnect.""" + self.instance.disconnect(handler_id) + + def emit(self, *args, **kargs): + """Same as GObject.GObject.emit except there is no need to specify + the signal name.""" + return self.gobj.emit(str(self), *args, **kargs) + + def __new__(cls, name='', *args, **kargs): + if callable(name): + name = name.__name__ + return str.__new__(cls, name) + + def __init__(self, name='', func=None, flags=_gobject.SIGNAL_RUN_FIRST, + return_type=None, arg_types=None, doc='', accumulator=None, accu_data=None): + """ + @param name: name of signal or closure method when used as direct decorator. + @type name: string or callable + @param func: closure method. + @type func: callable + @param flags: flags specifying when to run closure + @type flags: GObject.SignalFlags + @param return_type: return type + @type return_type: type + @param arg_types: list of argument types specifying the signals function signature + @type arg_types: None + @param doc: documentation of signal object + @type doc: string + @param accumulator: accumulator method with the signature: + func(ihint, return_accu, handler_return, accu_data) -> boolean + @type accumulator: function + @param accu_data: user data passed to the accumulator + @type accu_data: object + """ + if func and not name: + name = func.__name__ + elif callable(name): + func = name + name = func.__name__ + if func and not doc: + doc = func.__doc__ + + str.__init__(self) + + if func and not (return_type or arg_types): + return_type, arg_types = get_signal_annotations(func) + if arg_types is None: + arg_types = tuple() + + self.func = func + self.flags = flags + self.return_type = return_type + self.arg_types = arg_types + self.__doc__ = doc + self.accumulator = accumulator + self.accu_data = accu_data + + def __get__(self, instance, owner=None): + """Returns a BoundSignal when accessed on an object instance.""" + if instance is None: + return self + return self.BoundSignal(self, instance) + + def __call__(self, obj, *args, **kargs): + """Allows for instantiated Signals to be used as a decorator or calling + of the underlying signal method.""" + + # If obj is a GObject, than we call this signal as a closure otherwise + # it is used as a re-application of a decorator. + if isinstance(obj, _gobject.GObject): + self.func(obj, *args, **kargs) + else: + # If self is already an allocated name, use it otherwise create a new named + # signal using the closure name as the name. + if str(self): + name = str(self) + else: + name = obj.__name__ + # Return a new value of this type since it is based on an immutable string. + return type(self)(name=name, func=obj, flags=self.flags, + return_type=self.return_type, arg_types=self.arg_types, + doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data) + + def copy(self, newName=None): + """Returns a renamed copy of the Signal.""" + if newName is None: + newName = self.name + return type(self)(name=newName, func=self.func, flags=self.flags, + return_type=self.return_type, arg_types=self.arg_types, + doc=self.__doc__, accumulator=self.accumulator, accu_data=self.accu_data) + + def get_signal_args(self): + """Returns a tuple of: (flags, return_type, arg_types, accumulator, accu_data)""" + return (self.flags, self.return_type, self.arg_types, self.accumulator, self.accu_data) + + +class SignalOverride(Signal): + """Specialized sub-class of signal which can be used as a decorator for overriding + existing signals on GObjects. + + Example: + class MyWidget(Gtk.Widget): + @GObject.SignalOverride + def configure_event(self): + pass + """ + def get_signal_args(self): + """Returns the string 'override'.""" + return 'override' + + +def get_signal_annotations(func): + """Attempt pulling python 3 function annotations off of 'func' for + use as a signals type information. Returns an ordered nested tuple + of (return_type, (arg_type1, arg_type2, ...)). If the given function + does not have annotations then (None, tuple()) is returned. + """ + arg_types = tuple() + return_type = None + + if hasattr(func, '__annotations__'): + spec = inspect.getfullargspec(func) + arg_types = tuple(spec.annotations[arg] for arg in spec.args + if arg in spec.annotations) + if 'return' in spec.annotations: + return_type = spec.annotations['return'] + + return return_type, arg_types + + +def install_signals(cls): + """Adds Signal instances on a GObject derived class into the '__gsignals__' + dictionary to be picked up and registered as real GObject signals. + """ + gsignals = cls.__dict__.get('__gsignals__', {}) + newsignals = {} + for name, signal in cls.__dict__.items(): + if isinstance(signal, Signal): + signalName = str(signal) + # Fixup a signal which is unnamed by using the class variable name. + # Since Signal is based on string which immutable, + # we must copy and replace the class variable. + if not signalName: + signalName = name + signal = signal.copy(name) + setattr(cls, name, signal) + if signalName in gsignals: + raise ValueError('Signal "%s" has already been registered.' % name) + newsignals[signalName] = signal + gsignals[signalName] = signal.get_signal_args() + + cls.__gsignals__ = gsignals + + # Setup signal closures by adding the specially named + # method to the class in the form of "do_". + for name, signal in newsignals.items(): + if signal.func is not None: + funcName = 'do_' + name.replace('-', '_') + if not hasattr(cls, funcName): + setattr(cls, funcName, signal.func) diff --git a/gi/gimodule.c b/gi/gimodule.c index 12addbc..ef3e205 100644 --- a/gi/gimodule.c +++ b/gi/gimodule.c @@ -21,11 +21,13 @@ * USA */ +#include "pyglib-private.h" +#include "pygobject-private.h" +#include "pyginterface.h" #include "pygi-private.h" #include "pygi.h" #include "pyglib.h" -#include #include PyObject *PyGIDeprecationWarning; @@ -627,6 +629,8 @@ static struct PyGI_API CAPI = { PYGLIB_MODULE_START(_gi, "_gi") { PyObject *api; + PyObject *_glib_module; + PyObject *_gobject_module; /* Always enable Python threads since we cannot predict which GI repositories * might accept Python callbacks run within non-Python threads or might trigger @@ -635,13 +639,30 @@ PYGLIB_MODULE_START(_gi, "_gi") */ PyEval_InitThreads (); - if (pygobject_init (-1, -1, -1) == NULL) { + _glib_module = pyglib__glib_module_create (); + if (_glib_module == NULL) { return PYGLIB_MODULE_ERROR_RETURN; } + /* In Python 2.x, pyglib_..._module_create returns a borrowed reference and + * PyModule_AddObject steals a reference. Ensure we don't share a reference + * between sys.modules and gi._gi._glib by incrementing the ref count here. + * Note that we don't add this to the PYGLIB_MODULE_START macro because that + * would cause a leak for the main module gi._gi */ + if (PY_MAJOR_VERSION < 3) { + Py_INCREF (_glib_module); + } + PyModule_AddObject (module, "_glib", _glib_module); + PyModule_AddStringConstant(module, "__package__", "gi._gi"); - if (_pygobject_import() < 0) { + _gobject_module = pyglib__gobject_module_create (); + if (_gobject_module == NULL) { return PYGLIB_MODULE_ERROR_RETURN; } + if (PY_MAJOR_VERSION < 3) { + Py_INCREF (_gobject_module); + } + PyModule_AddObject (module, "_gobject", _gobject_module); + PyModule_AddStringConstant(module, "__package__", "gi._gi"); _pygi_repository_register_types (module); _pygi_info_register_types (module); diff --git a/gi/glibmodule.c b/gi/glibmodule.c new file mode 100644 index 0000000..c11f08b --- /dev/null +++ b/gi/glibmodule.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * glibmodule.c: wrapper for the glib library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "pyglib.h" +#include "pyglib-private.h" +#include "pygoptioncontext.h" +#include "pygoptiongroup.h" +#include "pygspawn.h" + +PyObject *PyGError = NULL; + +/* ---------------- glib module functions -------------------- */ + +static PyMethodDef _glib_functions[] = { + { "spawn_async", + (PyCFunction)pyglib_spawn_async, METH_VARARGS|METH_KEYWORDS, + "spawn_async(argv, envp=None, working_directory=None,\n" + " flags=0, child_setup=None, user_data=None,\n" + " standard_input=None, standard_output=None,\n" + " standard_error=None) -> (pid, stdin, stdout, stderr)\n" + "Execute a child program asynchronously within a glib.MainLoop()\n" + "See the reference manual for a complete reference." }, + { NULL, NULL, 0 } +}; + +static void +pyglib_register_error(PyObject *d) +{ + PyObject *dict; + dict = PyDict_New(); + /* This is a hack to work around the deprecation warning of + * BaseException.message in Python 2.6+. + * GError has also an "message" attribute. + */ + PyDict_SetItemString(dict, "message", Py_None); + PyGError = PyErr_NewException("gi._glib.GError", PyExc_RuntimeError, dict); + Py_DECREF(dict); + + PyDict_SetItemString(d, "GError", PyGError); +} + +PYGLIB_MODULE_START(_glib, "_glib") +{ + PyObject *d = PyModule_GetDict(module); + + pyglib_register_error(d); + pyglib_spawn_register_types(d); + pyglib_option_context_register_types(d); + pyglib_option_group_register_types(d); +} +PYGLIB_MODULE_END diff --git a/gi/gobjectmodule.c b/gi/gobjectmodule.c new file mode 100644 index 0000000..82d52a1 --- /dev/null +++ b/gi/gobjectmodule.c @@ -0,0 +1,2214 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * gobjectmodule.c: wrapper for the gobject library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include "pygobject-private.h" +#include "pygboxed.h" +#include "pygenum.h" +#include "pygflags.h" +#include "pyginterface.h" +#include "pygparamspec.h" +#include "pygpointer.h" +#include "pygtype.h" +#include "pygoptiongroup.h" + +#include "pygi-value.h" + +static GHashTable *log_handlers = NULL; +static gboolean log_handlers_disabled = FALSE; + +static void pyg_flags_add_constants(PyObject *module, GType flags_type, + const gchar *strip_prefix); + + +/* -------------- GDK threading hooks ---------------------------- */ + +/** + * pyg_set_thread_block_funcs: + * Deprecated, only available for ABI compatibility. + */ +static void +_pyg_set_thread_block_funcs (PyGThreadBlockFunc block_threads_func, + PyGThreadBlockFunc unblock_threads_func) +{ + PyGILState_STATE state = pyglib_gil_state_ensure (); + PyErr_Warn (PyExc_DeprecationWarning, + "Using pyg_set_thread_block_funcs is not longer needed. " + "PyGObject always uses Py_BLOCK/UNBLOCK_THREADS."); + pyglib_gil_state_release (state); +} + +/** + * pyg_destroy_notify: + * @user_data: a PyObject pointer. + * + * A function that can be used as a GDestroyNotify callback that will + * call Py_DECREF on the data. + */ +void +pyg_destroy_notify(gpointer user_data) +{ + PyObject *obj = (PyObject *)user_data; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_DECREF(obj); + pyglib_gil_state_release(state); +} + + +/* ---------------- gobject module functions -------------------- */ + +static PyObject * +pyg_type_name (PyObject *self, PyObject *args) +{ + PyObject *gtype; + GType type; + const gchar *name; + +#if 0 + if (PyErr_Warn(PyExc_DeprecationWarning, + "gobject.type_name is deprecated; " + "use GType.name instead")) + return NULL; +#endif + + if (!PyArg_ParseTuple(args, "O:gobject.type_name", >ype)) + return NULL; + if ((type = pyg_type_from_object(gtype)) == 0) + return NULL; + name = g_type_name(type); + if (name) + return PYGLIB_PyUnicode_FromString(name); + PyErr_SetString(PyExc_RuntimeError, "unknown typecode"); + return NULL; +} + +static PyObject * +pyg_type_from_name (PyObject *self, PyObject *args) +{ + const gchar *name; + GType type; + PyObject *repr = NULL; +#if 0 + if (PyErr_Warn(PyExc_DeprecationWarning, + "gobject.type_from_name is deprecated; " + "use GType.from_name instead")) + return NULL; +#endif + if (!PyArg_ParseTuple(args, "s:gobject.type_from_name", &name)) + return NULL; + type = g_type_from_name(name); + if (type != 0) + return pyg_type_wrapper_new(type); + repr = PyObject_Repr((PyObject*)self); + PyErr_Format(PyExc_RuntimeError, "%s: unknown type name: %s", + PYGLIB_PyUnicode_AsString(repr), + name); + Py_DECREF(repr); + return NULL; +} + +static PyObject * +pyg_type_is_a (PyObject *self, PyObject *args) +{ + PyObject *gtype, *gparent; + GType type, parent; +#if 0 + if (PyErr_Warn(PyExc_DeprecationWarning, + "gobject.type_is_a is deprecated; " + "use GType.is_a instead")) + return NULL; +#endif + if (!PyArg_ParseTuple(args, "OO:gobject.type_is_a", >ype, &gparent)) + return NULL; + if ((type = pyg_type_from_object(gtype)) == 0) + return NULL; + if ((parent = pyg_type_from_object(gparent)) == 0) + return NULL; + return PyBool_FromLong(g_type_is_a(type, parent)); +} + +static void +pyg_object_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + PyObject *object_wrapper, *retval; + PyObject *py_pspec, *py_value; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + + object_wrapper = pygobject_new(object); + + if (object_wrapper == NULL) { + pyglib_gil_state_release(state); + return; + } + + py_pspec = pyg_param_spec_new(pspec); + py_value = pyg_value_as_pyobject (value, TRUE); + + retval = PyObject_CallMethod(object_wrapper, "do_set_property", + "OO", py_pspec, py_value); + if (retval) { + Py_DECREF(retval); + } else { + PyErr_Print(); + } + + Py_DECREF(object_wrapper); + Py_DECREF(py_pspec); + Py_DECREF(py_value); + + pyglib_gil_state_release(state); +} + +static void +pyg_object_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + PyObject *object_wrapper, *retval; + PyObject *py_pspec; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + + object_wrapper = pygobject_new(object); + + if (object_wrapper == NULL) { + pyglib_gil_state_release(state); + return; + } + + py_pspec = pyg_param_spec_new(pspec); + retval = PyObject_CallMethod(object_wrapper, "do_get_property", + "O", py_pspec); + if (retval == NULL || pyg_value_from_pyobject(value, retval) < 0) { + PyErr_Print(); + } + Py_DECREF(object_wrapper); + Py_DECREF(py_pspec); + Py_XDECREF(retval); + + pyglib_gil_state_release(state); +} + +typedef struct _PyGSignalAccumulatorData { + PyObject *callable; + PyObject *user_data; +} PyGSignalAccumulatorData; + +static gboolean +_pyg_signal_accumulator(GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer _data) +{ + PyObject *py_ihint, *py_return_accu, *py_handler_return, *py_detail; + PyObject *py_retval; + gboolean retval = FALSE; + PyGSignalAccumulatorData *data = _data; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + if (ihint->detail) + py_detail = PYGLIB_PyUnicode_FromString(g_quark_to_string(ihint->detail)); + else { + Py_INCREF(Py_None); + py_detail = Py_None; + } + + py_ihint = Py_BuildValue("lNi", (long int) ihint->signal_id, + py_detail, ihint->run_type); + py_handler_return = pyg_value_as_pyobject(handler_return, TRUE); + py_return_accu = pyg_value_as_pyobject(return_accu, FALSE); + if (data->user_data) + py_retval = PyObject_CallFunction(data->callable, "NNNO", py_ihint, + py_return_accu, py_handler_return, + data->user_data); + else + py_retval = PyObject_CallFunction(data->callable, "NNN", py_ihint, + py_return_accu, py_handler_return); + if (!py_retval) + PyErr_Print(); + else { + if (!PyTuple_Check(py_retval) || PyTuple_Size(py_retval) != 2) { + PyErr_SetString(PyExc_TypeError, "accumulator function must return" + " a (bool, object) tuple"); + PyErr_Print(); + } else { + retval = PyObject_IsTrue(PyTuple_GET_ITEM(py_retval, 0)); + if (pyg_value_from_pyobject(return_accu, PyTuple_GET_ITEM(py_retval, 1))) { + PyErr_Print(); + } + } + Py_DECREF(py_retval); + } + pyglib_gil_state_release(state); + return retval; +} + +static gboolean +create_signal (GType instance_type, const gchar *signal_name, PyObject *tuple) +{ + GSignalFlags signal_flags; + PyObject *py_return_type, *py_param_types; + GType return_type; + guint n_params, i; + GType *param_types; + guint signal_id; + GSignalAccumulator accumulator = NULL; + PyGSignalAccumulatorData *accum_data = NULL; + PyObject *py_accum = NULL, *py_accum_data = NULL; + + if (!PyArg_ParseTuple(tuple, "iOO|OO", &signal_flags, &py_return_type, + &py_param_types, &py_accum, &py_accum_data)) + { + gchar buf[128]; + + PyErr_Clear(); + g_snprintf(buf, sizeof(buf), + "value for __gsignals__['%s'] not in correct format", signal_name); + PyErr_SetString(PyExc_TypeError, buf); + return FALSE; + } + + if (py_accum && py_accum != Py_None && !PyCallable_Check(py_accum)) + { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "accumulator for __gsignals__['%s'] must be callable", signal_name); + PyErr_SetString(PyExc_TypeError, buf); + return FALSE; + } + + return_type = pyg_type_from_object(py_return_type); + if (!return_type) + return FALSE; + if (!PySequence_Check(py_param_types)) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "third element of __gsignals__['%s'] tuple must be a sequence", signal_name); + PyErr_SetString(PyExc_TypeError, buf); + return FALSE; + } + n_params = PySequence_Length(py_param_types); + param_types = g_new(GType, n_params); + for (i = 0; i < n_params; i++) { + PyObject *item = PySequence_GetItem(py_param_types, i); + + param_types[i] = pyg_type_from_object(item); + if (param_types[i] == 0) { + Py_DECREF(item); + g_free(param_types); + return FALSE; + } + Py_DECREF(item); + } + + if (py_accum != NULL && py_accum != Py_None) { + accum_data = g_new(PyGSignalAccumulatorData, 1); + accum_data->callable = py_accum; + Py_INCREF(py_accum); + accum_data->user_data = py_accum_data; + Py_XINCREF(py_accum_data); + accumulator = _pyg_signal_accumulator; + } + + signal_id = g_signal_newv(signal_name, instance_type, signal_flags, + pyg_signal_class_closure_get(), + accumulator, accum_data, + gi_cclosure_marshal_generic, + return_type, n_params, param_types); + g_free(param_types); + + if (signal_id == 0) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), "could not create signal for %s", + signal_name); + PyErr_SetString(PyExc_RuntimeError, buf); + return FALSE; + } + return TRUE; +} + +static gboolean +override_signal(GType instance_type, const gchar *signal_name) +{ + guint signal_id; + + signal_id = g_signal_lookup(signal_name, instance_type); + if (!signal_id) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), "could not look up %s", signal_name); + PyErr_SetString(PyExc_TypeError, buf); + return FALSE; + } + g_signal_override_class_closure(signal_id, instance_type, + pyg_signal_class_closure_get()); + return TRUE; +} + +static PyObject * +add_signals (GObjectClass *klass, PyObject *signals) +{ + gboolean ret = TRUE; + Py_ssize_t pos = 0; + PyObject *key, *value, *overridden_signals = NULL; + GType instance_type = G_OBJECT_CLASS_TYPE (klass); + + overridden_signals = PyDict_New(); + while (PyDict_Next(signals, &pos, &key, &value)) { + const gchar *signal_name; + gchar *signal_name_canon, *c; + + if (!PYGLIB_PyUnicode_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "__gsignals__ keys must be strings"); + ret = FALSE; + break; + } + signal_name = PYGLIB_PyUnicode_AsString (key); + + if (value == Py_None || + (PYGLIB_PyUnicode_Check(value) && + !strcmp(PYGLIB_PyUnicode_AsString(value), "override"))) + { + /* canonicalize signal name, replacing '-' with '_' */ + signal_name_canon = g_strdup(signal_name); + for (c = signal_name_canon; *c; ++c) + if (*c == '-') + *c = '_'; + if (PyDict_SetItemString(overridden_signals, + signal_name_canon, key)) { + g_free(signal_name_canon); + ret = FALSE; + break; + } + g_free(signal_name_canon); + + ret = override_signal(instance_type, signal_name); + } else { + ret = create_signal(instance_type, signal_name, value); + } + + if (!ret) + break; + } + if (ret) + return overridden_signals; + else { + Py_XDECREF(overridden_signals); + return NULL; + } +} + +static GParamSpec * +create_property (const gchar *prop_name, + GType prop_type, + const gchar *nick, + const gchar *blurb, + PyObject *args, + GParamFlags flags) +{ + GParamSpec *pspec = NULL; + + switch (G_TYPE_FUNDAMENTAL(prop_type)) { + case G_TYPE_CHAR: + { + gchar minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_char (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_UCHAR: + { + gchar minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "ccc", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_uchar (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_BOOLEAN: + { + gboolean default_value; + + if (!PyArg_ParseTuple(args, "i", &default_value)) + return NULL; + pspec = g_param_spec_boolean (prop_name, nick, blurb, + default_value, flags); + } + break; + case G_TYPE_INT: + { + gint minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "iii", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_int (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_UINT: + { + guint minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "III", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_uint (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_LONG: + { + glong minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "lll", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_long (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_ULONG: + { + gulong minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "kkk", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_ulong (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_INT64: + { + gint64 minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "LLL", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_int64 (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_UINT64: + { + guint64 minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "KKK", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_uint64 (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_ENUM: + { + gint default_value; + PyObject *pydefault; + + if (!PyArg_ParseTuple(args, "O", &pydefault)) + return NULL; + + if (pyg_enum_get_value(prop_type, pydefault, + (gint *)&default_value)) + return NULL; + + pspec = g_param_spec_enum (prop_name, nick, blurb, + prop_type, default_value, flags); + } + break; + case G_TYPE_FLAGS: + { + guint default_value; + PyObject *pydefault; + + if (!PyArg_ParseTuple(args, "O", &pydefault)) + return NULL; + + if (pyg_flags_get_value(prop_type, pydefault, + &default_value)) + return NULL; + + pspec = g_param_spec_flags (prop_name, nick, blurb, + prop_type, default_value, flags); + } + break; + case G_TYPE_FLOAT: + { + gfloat minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "fff", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_float (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_DOUBLE: + { + gdouble minimum, maximum, default_value; + + if (!PyArg_ParseTuple(args, "ddd", &minimum, &maximum, + &default_value)) + return NULL; + pspec = g_param_spec_double (prop_name, nick, blurb, minimum, + maximum, default_value, flags); + } + break; + case G_TYPE_STRING: + { + const gchar *default_value; + + if (!PyArg_ParseTuple(args, "z", &default_value)) + return NULL; + pspec = g_param_spec_string (prop_name, nick, blurb, + default_value, flags); + } + break; + case G_TYPE_PARAM: + if (!PyArg_ParseTuple(args, "")) + return NULL; + pspec = g_param_spec_param (prop_name, nick, blurb, prop_type, flags); + break; + case G_TYPE_BOXED: + if (!PyArg_ParseTuple(args, "")) + return NULL; + pspec = g_param_spec_boxed (prop_name, nick, blurb, prop_type, flags); + break; + case G_TYPE_POINTER: + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (prop_type == G_TYPE_GTYPE) + pspec = g_param_spec_gtype (prop_name, nick, blurb, G_TYPE_NONE, flags); + else + pspec = g_param_spec_pointer (prop_name, nick, blurb, flags); + break; + case G_TYPE_OBJECT: + case G_TYPE_INTERFACE: + if (!PyArg_ParseTuple(args, "")) + return NULL; + pspec = g_param_spec_object (prop_name, nick, blurb, prop_type, flags); + break; + case G_TYPE_VARIANT: + { + PyObject *pydefault; + GVariant *default_value = NULL; + + if (!PyArg_ParseTuple(args, "O", &pydefault)) + return NULL; + if (pydefault != Py_None) + default_value = pyg_boxed_get (pydefault, GVariant); + pspec = g_param_spec_variant (prop_name, nick, blurb, G_VARIANT_TYPE_ANY, default_value, flags); + } + break; + default: + /* unhandled pspec type ... */ + break; + } + + if (!pspec) { + char buf[128]; + + g_snprintf(buf, sizeof(buf), "could not create param spec for type %s", + g_type_name(prop_type)); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + return pspec; +} + +static GParamSpec * +pyg_param_spec_from_object (PyObject *tuple) +{ + gint val_length; + const gchar *prop_name; + GType prop_type; + const gchar *nick, *blurb; + PyObject *slice, *item, *py_prop_type; + GParamSpec *pspec; + + val_length = PyTuple_Size(tuple); + if (val_length < 4) { + PyErr_SetString(PyExc_TypeError, + "paramspec tuples must be at least 4 elements long"); + return NULL; + } + + slice = PySequence_GetSlice(tuple, 0, 4); + if (!slice) { + return NULL; + } + + if (!PyArg_ParseTuple(slice, "sOzz", &prop_name, &py_prop_type, &nick, &blurb)) { + Py_DECREF(slice); + return NULL; + } + + Py_DECREF(slice); + + prop_type = pyg_type_from_object(py_prop_type); + if (!prop_type) { + return NULL; + } + + item = PyTuple_GetItem(tuple, val_length-1); + if (!PYGLIB_PyLong_Check(item)) { + PyErr_SetString(PyExc_TypeError, + "last element in tuple must be an int"); + return NULL; + } + + /* slice is the extra items in the tuple */ + slice = PySequence_GetSlice(tuple, 4, val_length-1); + pspec = create_property(prop_name, prop_type, + nick, blurb, slice, + PYGLIB_PyLong_AsLong(item)); + + return pspec; +} + +static gboolean +add_properties (GObjectClass *klass, PyObject *properties) +{ + gboolean ret = TRUE; + Py_ssize_t pos = 0; + PyObject *key, *value; + + while (PyDict_Next(properties, &pos, &key, &value)) { + const gchar *prop_name; + GType prop_type; + const gchar *nick, *blurb; + GParamFlags flags; + gint val_length; + PyObject *slice, *item, *py_prop_type; + GParamSpec *pspec; + + /* values are of format (type,nick,blurb, type_specific_args, flags) */ + + if (!PYGLIB_PyUnicode_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "__gproperties__ keys must be strings"); + ret = FALSE; + break; + } + prop_name = PYGLIB_PyUnicode_AsString (key); + + if (!PyTuple_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__gproperties__ values must be tuples"); + ret = FALSE; + break; + } + val_length = PyTuple_Size(value); + if (val_length < 4) { + PyErr_SetString(PyExc_TypeError, + "__gproperties__ values must be at least 4 elements long"); + ret = FALSE; + break; + } + + slice = PySequence_GetSlice(value, 0, 3); + if (!slice) { + ret = FALSE; + break; + } + if (!PyArg_ParseTuple(slice, "Ozz", &py_prop_type, &nick, &blurb)) { + Py_DECREF(slice); + ret = FALSE; + break; + } + Py_DECREF(slice); + prop_type = pyg_type_from_object(py_prop_type); + if (!prop_type) { + ret = FALSE; + break; + } + item = PyTuple_GetItem(value, val_length-1); + if (!PYGLIB_PyLong_Check(item)) { + PyErr_SetString(PyExc_TypeError, + "last element in __gproperties__ value tuple must be an int"); + ret = FALSE; + break; + } + flags = PYGLIB_PyLong_AsLong(item); + + /* slice is the extra items in the tuple */ + slice = PySequence_GetSlice(value, 3, val_length-1); + pspec = create_property(prop_name, prop_type, nick, blurb, + slice, flags); + Py_DECREF(slice); + + if (pspec) { + g_object_class_install_property(klass, 1, pspec); + } else { + PyObject *type, *value, *traceback; + ret = FALSE; + PyErr_Fetch(&type, &value, &traceback); + if (PYGLIB_PyUnicode_Check(value)) { + char msg[256]; + g_snprintf(msg, 256, + "%s (while registering property '%s' for GType '%s')", + PYGLIB_PyUnicode_AsString(value), + prop_name, G_OBJECT_CLASS_NAME(klass)); + Py_DECREF(value); + value = PYGLIB_PyUnicode_FromString(msg); + } + PyErr_Restore(type, value, traceback); + break; + } + } + + return ret; +} + +static void +pyg_object_class_init(GObjectClass *class, PyObject *py_class) +{ + PyObject *gproperties, *gsignals, *overridden_signals; + PyObject *class_dict = ((PyTypeObject*) py_class)->tp_dict; + + class->set_property = pyg_object_set_property; + class->get_property = pyg_object_get_property; + + /* install signals */ + /* we look this up in the instance dictionary, so we don't + * accidentally get a parent type's __gsignals__ attribute. */ + gsignals = PyDict_GetItemString(class_dict, "__gsignals__"); + if (gsignals) { + if (!PyDict_Check(gsignals)) { + PyErr_SetString(PyExc_TypeError, + "__gsignals__ attribute not a dict!"); + return; + } + if (!(overridden_signals = add_signals(class, gsignals))) { + return; + } + if (PyDict_SetItemString(class_dict, "__gsignals__", + overridden_signals)) { + return; + } + Py_DECREF(overridden_signals); + + PyDict_DelItemString(class_dict, "__gsignals__"); + } else { + PyErr_Clear(); + } + + /* install properties */ + /* we look this up in the instance dictionary, so we don't + * accidentally get a parent type's __gproperties__ attribute. */ + gproperties = PyDict_GetItemString(class_dict, "__gproperties__"); + if (gproperties) { + if (!PyDict_Check(gproperties)) { + PyErr_SetString(PyExc_TypeError, + "__gproperties__ attribute not a dict!"); + return; + } + if (!add_properties(class, gproperties)) { + return; + } + PyDict_DelItemString(class_dict, "__gproperties__"); + /* Borrowed reference. Py_DECREF(gproperties); */ + } else { + PyErr_Clear(); + } +} + +static void +pyg_register_class_init(GType gtype, PyGClassInitFunc class_init) +{ + GSList *list; + + list = g_type_get_qdata(gtype, pygobject_class_init_key); + list = g_slist_prepend(list, class_init); + g_type_set_qdata(gtype, pygobject_class_init_key, list); +} + +static int +pyg_run_class_init(GType gtype, gpointer gclass, PyTypeObject *pyclass) +{ + GSList *list; + PyGClassInitFunc class_init; + GType parent_type; + int rv; + + parent_type = g_type_parent(gtype); + if (parent_type) { + rv = pyg_run_class_init(parent_type, gclass, pyclass); + if (rv) + return rv; + } + + list = g_type_get_qdata(gtype, pygobject_class_init_key); + for (; list; list = list->next) { + class_init = list->data; + rv = class_init(gclass, pyclass); + if (rv) + return rv; + } + + return 0; +} + +static PyObject * +_wrap_pyg_type_register(PyObject *self, PyObject *args) +{ + PyTypeObject *class; + char *type_name = NULL; + + if (!PyArg_ParseTuple(args, "O!|z:gobject.type_register", + &PyType_Type, &class, &type_name)) + return NULL; + if (!PyType_IsSubtype(class, &PyGObject_Type)) { + PyErr_SetString(PyExc_TypeError, + "argument must be a GObject subclass"); + return NULL; + } + + /* Check if type already registered */ + if (pyg_type_from_object((PyObject *) class) == + pyg_type_from_object((PyObject *) class->tp_base)) + { + if (pyg_type_register(class, type_name)) + return NULL; + } + + Py_INCREF(class); + return (PyObject *) class; +} + +static char * +get_type_name_for_class(PyTypeObject *class) +{ + gint i, name_serial; + char name_serial_str[16]; + PyObject *module; + char *type_name = NULL; + + /* make name for new GType */ + name_serial = 1; + /* give up after 1000 tries, just in case.. */ + while (name_serial < 1000) + { + g_free(type_name); + snprintf(name_serial_str, 16, "-v%i", name_serial); + module = PyObject_GetAttrString((PyObject *)class, "__module__"); + if (module && PYGLIB_PyUnicode_Check(module)) { + type_name = g_strconcat(PYGLIB_PyUnicode_AsString(module), ".", + class->tp_name, + name_serial > 1 ? name_serial_str : NULL, + NULL); + Py_DECREF(module); + } else { + if (module) + Py_DECREF(module); + else + PyErr_Clear(); + type_name = g_strconcat(class->tp_name, + name_serial > 1 ? name_serial_str : NULL, + NULL); + } + /* convert '.' in type name to '+', which isn't banned (grumble) */ + for (i = 0; type_name[i] != '\0'; i++) + if (type_name[i] == '.') + type_name[i] = '+'; + if (g_type_from_name(type_name) == 0) + break; /* we now have a unique name */ + ++name_serial; + } + + return type_name; +} + + +static GPrivate pygobject_construction_wrapper; + +static inline void +pygobject_init_wrapper_set(PyObject *wrapper) +{ + g_private_set(&pygobject_construction_wrapper, wrapper); +} + +static inline PyObject * +pygobject_init_wrapper_get(void) +{ + return (PyObject *) g_private_get(&pygobject_construction_wrapper); +} + +int +pygobject_constructv(PyGObject *self, + guint n_parameters, + GParameter *parameters) +{ + GObject *obj; + + g_assert (self->obj == NULL); + pygobject_init_wrapper_set((PyObject *) self); + obj = g_object_newv(pyg_type_from_object((PyObject *) self), + n_parameters, parameters); + + if (g_object_is_floating (obj)) + self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING; + pygobject_sink (obj); + + pygobject_init_wrapper_set(NULL); + self->obj = obj; + pygobject_register_wrapper((PyObject *) self); + + return 0; +} + +static void +pygobject__g_instance_init(GTypeInstance *instance, + gpointer g_class) +{ + GObject *object = (GObject *) instance; + PyObject *wrapper, *args, *kwargs; + + wrapper = g_object_get_qdata(object, pygobject_wrapper_key); + if (wrapper == NULL) { + wrapper = pygobject_init_wrapper_get(); + if (wrapper && ((PyGObject *) wrapper)->obj == NULL) { + ((PyGObject *) wrapper)->obj = object; + pygobject_register_wrapper(wrapper); + } + } + pygobject_init_wrapper_set(NULL); + if (wrapper == NULL) { + /* this looks like a python object created through + * g_object_new -> we have no python wrapper, so create it + * now */ + PyGILState_STATE state; + state = pyglib_gil_state_ensure(); + wrapper = pygobject_new_full(object, + /*steal=*/ FALSE, + g_class); + + /* float the wrapper ref here because we are going to orphan it + * so we don't destroy the wrapper. The next call to pygobject_new_full + * will take the ref */ + pygobject_ref_float ((PyGObject *) wrapper); + args = PyTuple_New(0); + kwargs = PyDict_New(); + if (Py_TYPE(wrapper)->tp_init(wrapper, args, kwargs)) + PyErr_Print(); + + Py_DECREF(args); + Py_DECREF(kwargs); + pyglib_gil_state_release(state); + } +} + + +/* This implementation is bad, see bug 566571 for an example why. + * Instead of scanning explicitly declared bases for interfaces, we + * should automatically initialize all implemented interfaces to + * prevent bugs like that one. However, this will lead to + * performance degradation as each virtual method in derived classes + * will round-trip through do_*() stuff, *even* if it is not + * overriden. We need to teach codegen to retain parent method + * instead of setting virtual to *_proxy_do_*() if corresponding + * do_*() is not overriden. Ok, that was a messy explanation. + */ +static void +pyg_type_add_interfaces(PyTypeObject *class, GType instance_type, + PyObject *bases, + GType *parent_interfaces, guint n_parent_interfaces) +{ + int i; + + if (!bases) { + g_warning("type has no bases"); + return; + } + + for (i = 0; i < PyTuple_GET_SIZE(bases); ++i) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + GType itype; + const GInterfaceInfo *iinfo; + GInterfaceInfo iinfo_copy; + + /* 'base' can also be a PyClassObject, see bug #566571. */ + if (!PyType_Check(base)) + continue; + + if (!PyType_IsSubtype((PyTypeObject*) base, &PyGInterface_Type)) + continue; + + itype = pyg_type_from_object(base); + + /* Happens for _implementations_ of an interface. */ + if (!G_TYPE_IS_INTERFACE(itype)) + continue; + + iinfo = pyg_lookup_interface_info(itype); + if (!iinfo) { + gchar *error; + error = g_strdup_printf("Interface type %s " + "has no Python implementation support", + ((PyTypeObject *) base)->tp_name); + PyErr_Warn(PyExc_RuntimeWarning, error); + g_free(error); + continue; + } + + iinfo_copy = *iinfo; + iinfo_copy.interface_data = class; + g_type_add_interface_static(instance_type, itype, &iinfo_copy); + } +} + +int +pyg_type_register(PyTypeObject *class, const char *type_name) +{ + PyObject *gtype; + GType parent_type, instance_type; + GType *parent_interfaces; + guint n_parent_interfaces; + GTypeQuery query; + gpointer gclass; + GTypeInfo type_info = { + 0, /* class_size */ + + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + + (GClassInitFunc) pyg_object_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + + 0, /* instance_size */ + 0, /* n_preallocs */ + (GInstanceInitFunc) pygobject__g_instance_init + }; + gchar *new_type_name; + + /* find the GType of the parent */ + parent_type = pyg_type_from_object((PyObject *)class); + if (!parent_type) + return -1; + + parent_interfaces = g_type_interfaces(parent_type, &n_parent_interfaces); + + if (type_name) + /* care is taken below not to free this */ + new_type_name = (gchar *) type_name; + else + new_type_name = get_type_name_for_class(class); + + /* set class_data that will be passed to the class_init function. */ + type_info.class_data = class; + + /* fill in missing values of GTypeInfo struct */ + g_type_query(parent_type, &query); + type_info.class_size = query.class_size; + type_info.instance_size = query.instance_size; + + /* create new typecode */ + instance_type = g_type_register_static(parent_type, new_type_name, + &type_info, 0); + if (instance_type == 0) { + PyErr_Format(PyExc_RuntimeError, + "could not create new GType: %s (subclass of %s)", + new_type_name, + g_type_name(parent_type)); + + if (type_name == NULL) + g_free(new_type_name); + + return -1; + } + + if (type_name == NULL) + g_free(new_type_name); + + /* store pointer to the class with the GType */ + Py_INCREF(class); + g_type_set_qdata(instance_type, g_quark_from_string("PyGObject::class"), + class); + + /* Mark this GType as a custom python type */ + g_type_set_qdata(instance_type, pygobject_custom_key, + GINT_TO_POINTER (1)); + + /* set new value of __gtype__ on class */ + gtype = pyg_type_wrapper_new(instance_type); + PyObject_SetAttrString((PyObject *)class, "__gtype__", gtype); + Py_DECREF(gtype); + + /* if no __doc__, set it to the auto doc descriptor */ + if (PyDict_GetItemString(class->tp_dict, "__doc__") == NULL) { + PyDict_SetItemString(class->tp_dict, "__doc__", + pyg_object_descr_doc_get()); + } + + /* + * Note, all interfaces need to be registered before the first + * g_type_class_ref(), see bug #686149. + * + * See also comment above pyg_type_add_interfaces(). + */ + pyg_type_add_interfaces(class, instance_type, class->tp_bases, + parent_interfaces, n_parent_interfaces); + + + gclass = g_type_class_ref(instance_type); + if (PyErr_Occurred() != NULL) { + g_type_class_unref(gclass); + g_free(parent_interfaces); + return -1; + } + + if (pyg_run_class_init(instance_type, gclass, class)) { + g_type_class_unref(gclass); + g_free(parent_interfaces); + return -1; + } + g_type_class_unref(gclass); + g_free(parent_interfaces); + + if (PyErr_Occurred() != NULL) + return -1; + return 0; +} + +static PyObject * +pyg_signal_new(PyObject *self, PyObject *args) +{ + gchar *signal_name; + PyObject *py_type; + GSignalFlags signal_flags; + GType return_type; + PyObject *py_return_type, *py_param_types; + + GType instance_type = 0; + Py_ssize_t n_params, i; + GType *param_types; + + guint signal_id; + + if (!PyArg_ParseTuple(args, "sOiOO:gobject.signal_new", &signal_name, + &py_type, &signal_flags, &py_return_type, + &py_param_types)) + return NULL; + + instance_type = pyg_type_from_object(py_type); + if (!instance_type) + return NULL; + if (!(G_TYPE_IS_INSTANTIATABLE(instance_type) || G_TYPE_IS_INTERFACE(instance_type))) { + PyErr_SetString(PyExc_TypeError, + "argument 2 must be an object type or interface type"); + return NULL; + } + + return_type = pyg_type_from_object(py_return_type); + if (!return_type) + return NULL; + + if (!PySequence_Check(py_param_types)) { + PyErr_SetString(PyExc_TypeError, + "argument 5 must be a sequence of GType codes"); + return NULL; + } + n_params = PySequence_Length(py_param_types); + param_types = g_new(GType, n_params); + for (i = 0; i < n_params; i++) { + PyObject *item = PySequence_GetItem(py_param_types, i); + + param_types[i] = pyg_type_from_object(item); + if (param_types[i] == 0) { + PyErr_Clear(); + Py_DECREF(item); + PyErr_SetString(PyExc_TypeError, + "argument 5 must be a sequence of GType codes"); + g_free(param_types); + return NULL; + } + Py_DECREF(item); + } + + signal_id = g_signal_newv(signal_name, instance_type, signal_flags, + pyg_signal_class_closure_get(), + (GSignalAccumulator)0, NULL, + (GSignalCMarshaller)0, + return_type, n_params, param_types); + g_free(param_types); + if (signal_id != 0) + return PYGLIB_PyLong_FromLong(signal_id); + PyErr_SetString(PyExc_RuntimeError, "could not create signal"); + return NULL; +} + +static PyObject * +pyg_signal_query (PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist1[] = { "name", "type", NULL }; + static char *kwlist2[] = { "signal_id", NULL }; + PyObject *py_query, *params_list, *py_itype; + GObjectClass *class = NULL; + GType itype; + gchar *signal_name; + guint i; + GSignalQuery query; + guint id; + gpointer iface = NULL; + + if (PyArg_ParseTupleAndKeywords(args, kwargs, "sO:gobject.signal_query", + kwlist1, &signal_name, &py_itype)) { + if ((itype = pyg_type_from_object(py_itype)) == 0) + return NULL; + + if (G_TYPE_IS_INSTANTIATABLE(itype)) { + class = g_type_class_ref(itype); + if (!class) { + PyErr_SetString(PyExc_RuntimeError, + "could not get a reference to type class"); + return NULL; + } + } else if (!G_TYPE_IS_INTERFACE(itype)) { + PyErr_SetString(PyExc_TypeError, + "type must be instantiable or an interface"); + return NULL; + } else { + iface = g_type_default_interface_ref(itype); + } + id = g_signal_lookup(signal_name, itype); + } else { + PyErr_Clear(); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:gobject.signal_query", + kwlist2, &id)) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, + "Usage: one of:\n" + " gobject.signal_query(name, type)\n" + " gobject.signal_query(signal_id)"); + + return NULL; + } + } + + g_signal_query(id, &query); + + if (query.signal_id == 0) { + Py_INCREF(Py_None); + py_query = Py_None; + goto done; + } + py_query = PyTuple_New(6); + if (py_query == NULL) { + goto done; + } + params_list = PyTuple_New(query.n_params); + if (params_list == NULL) { + Py_DECREF(py_query); + py_query = NULL; + goto done; + } + + PyTuple_SET_ITEM(py_query, 0, PYGLIB_PyLong_FromLong(query.signal_id)); + PyTuple_SET_ITEM(py_query, 1, PYGLIB_PyUnicode_FromString(query.signal_name)); + PyTuple_SET_ITEM(py_query, 2, pyg_type_wrapper_new(query.itype)); + PyTuple_SET_ITEM(py_query, 3, PYGLIB_PyLong_FromLong(query.signal_flags)); + PyTuple_SET_ITEM(py_query, 4, pyg_type_wrapper_new(query.return_type)); + for (i = 0; i < query.n_params; i++) { + PyTuple_SET_ITEM(params_list, i, + pyg_type_wrapper_new(query.param_types[i])); + } + PyTuple_SET_ITEM(py_query, 5, params_list); + + done: + if (class) + g_type_class_unref(class); + if (iface) + g_type_default_interface_unref(iface); + + return py_query; +} + +static PyObject * +pyg_object_class_list_properties (PyObject *self, PyObject *args) +{ + GParamSpec **specs; + PyObject *py_itype, *list; + GType itype; + GObjectClass *class = NULL; + gpointer iface = NULL; + guint nprops; + guint i; + + if (!PyArg_ParseTuple(args, "O:gobject.list_properties", + &py_itype)) + return NULL; + if ((itype = pyg_type_from_object(py_itype)) == 0) + return NULL; + + if (G_TYPE_IS_INTERFACE(itype)) { + iface = g_type_default_interface_ref(itype); + if (!iface) { + PyErr_SetString(PyExc_RuntimeError, + "could not get a reference to interface type"); + return NULL; + } + specs = g_object_interface_list_properties(iface, &nprops); + } else if (g_type_is_a(itype, G_TYPE_OBJECT)) { + class = g_type_class_ref(itype); + if (!class) { + PyErr_SetString(PyExc_RuntimeError, + "could not get a reference to type class"); + return NULL; + } + specs = g_object_class_list_properties(class, &nprops); + } else { + PyErr_SetString(PyExc_TypeError, + "type must be derived from GObject or an interface"); + return NULL; + } + + list = PyTuple_New(nprops); + if (list == NULL) { + g_free(specs); + g_type_class_unref(class); + return NULL; + } + for (i = 0; i < nprops; i++) { + PyTuple_SetItem(list, i, pyg_param_spec_new(specs[i])); + } + g_free(specs); + if (class) + g_type_class_unref(class); + else + g_type_default_interface_unref(iface); + + return list; +} + +static PyObject * +pyg_object_new (PyGObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *pytype; + GType type; + GObject *obj = NULL; + GObjectClass *class; + guint n_params = 0, i; + GParameter *params = NULL; + + if (!PyArg_ParseTuple (args, "O:gobject.new", &pytype)) { + return NULL; + } + + if ((type = pyg_type_from_object (pytype)) == 0) + return NULL; + + if (G_TYPE_IS_ABSTRACT(type)) { + PyErr_Format(PyExc_TypeError, "cannot create instance of abstract " + "(non-instantiable) type `%s'", g_type_name(type)); + return NULL; + } + + if ((class = g_type_class_ref (type)) == NULL) { + PyErr_SetString(PyExc_TypeError, + "could not get a reference to type class"); + return NULL; + } + + if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms)) + goto cleanup; + + obj = g_object_newv(type, n_params, params); + if (!obj) + PyErr_SetString (PyExc_RuntimeError, "could not create object"); + + cleanup: + for (i = 0; i < n_params; i++) { + g_free((gchar *) params[i].name); + g_value_unset(¶ms[i].value); + } + g_free(params); + g_type_class_unref(class); + + if (obj) { + pygobject_sink (obj); + self = (PyGObject *) pygobject_new((GObject *)obj); + g_object_unref(obj); + } else + self = NULL; + + return (PyObject *) self; +} + +gboolean +pyg_handler_marshal(gpointer user_data) +{ + PyObject *tuple, *ret; + gboolean res; + PyGILState_STATE state; + + g_return_val_if_fail(user_data != NULL, FALSE); + + state = pyglib_gil_state_ensure(); + + tuple = (PyObject *)user_data; + ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), + PyTuple_GetItem(tuple, 1)); + if (!ret) { + PyErr_Print(); + res = FALSE; + } else { + res = PyObject_IsTrue(ret); + Py_DECREF(ret); + } + + pyglib_gil_state_release(state); + + return res; +} + +static int +pygobject_gil_state_ensure (void) +{ + return pyglib_gil_state_ensure (); +} + +static void +pygobject_gil_state_release (int flag) +{ + pyglib_gil_state_release(flag); +} + +/* Only for backwards compatibility */ +static int +pygobject_enable_threads(void) +{ + return 0; +} + +static PyObject * +pyg_signal_accumulator_true_handled(PyObject *unused, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "signal_accumulator_true_handled can only" + " be used as accumulator argument when registering signals"); + return NULL; +} + +static gboolean +marshal_emission_hook(GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer user_data) +{ + PyGILState_STATE state; + gboolean retval = FALSE; + PyObject *func, *args; + PyObject *retobj; + PyObject *params; + guint i; + + state = pyglib_gil_state_ensure(); + + /* construct Python tuple for the parameter values */ + params = PyTuple_New(n_param_values); + + for (i = 0; i < n_param_values; i++) { + PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); + + /* error condition */ + if (!item) { + goto out; + } + PyTuple_SetItem(params, i, item); + } + + args = (PyObject *)user_data; + func = PyTuple_GetItem(args, 0); + args = PySequence_Concat(params, PyTuple_GetItem(args, 1)); + Py_DECREF(params); + + /* params passed to function may have extra arguments */ + + retobj = PyObject_CallObject(func, args); + Py_DECREF(args); + if (retobj == NULL) { + PyErr_Print(); + } + + retval = (retobj == Py_True ? TRUE : FALSE); + Py_XDECREF(retobj); +out: + pyglib_gil_state_release(state); + return retval; +} + +static PyObject * +pyg_add_emission_hook(PyGObject *self, PyObject *args) +{ + PyObject *first, *callback, *extra_args, *data, *repr; + gchar *name; + gulong hook_id; + guint sigid; + Py_ssize_t len; + GQuark detail = 0; + GType gtype; + PyObject *pygtype; + + len = PyTuple_Size(args); + if (len < 3) { + PyErr_SetString(PyExc_TypeError, + "gobject.add_emission_hook requires at least 3 arguments"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 3); + if (!PyArg_ParseTuple(first, "OsO:add_emission_hook", + &pygtype, &name, &callback)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + + if ((gtype = pyg_type_from_object(pygtype)) == 0) { + return NULL; + } + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "third argument must be callable"); + return NULL; + } + + if (!g_signal_parse_name(name, gtype, &sigid, &detail, TRUE)) { + repr = PyObject_Repr((PyObject*)self); + PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", + PYGLIB_PyUnicode_AsString(repr), + name); + Py_DECREF(repr); + return NULL; + } + extra_args = PySequence_GetSlice(args, 3, len); + if (extra_args == NULL) + return NULL; + + data = Py_BuildValue("(ON)", callback, extra_args); + if (data == NULL) + return NULL; + + hook_id = g_signal_add_emission_hook(sigid, detail, + marshal_emission_hook, + data, + (GDestroyNotify)pyg_destroy_notify); + + return PyLong_FromUnsignedLong(hook_id); +} + +static PyObject * +pyg__install_metaclass(PyObject *dummy, PyTypeObject *metaclass) +{ + Py_INCREF(metaclass); + PyGObject_MetaType = metaclass; + Py_INCREF(metaclass); + + Py_TYPE(&PyGObject_Type) = metaclass; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pyg__gvalue_get(PyObject *module, PyObject *pygvalue) +{ + if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) { + PyErr_SetString (PyExc_TypeError, "Expected GValue argument."); + return NULL; + } + + return pyg_value_as_pyobject (pyg_boxed_get(pygvalue, GValue), + /*copy_boxed=*/ TRUE); +} + +static PyObject * +pyg__gvalue_set(PyObject *module, PyObject *args) +{ + PyObject *pygvalue; + PyObject *pyobject; + + if (!PyArg_ParseTuple (args, "OO:_gobject._gvalue_set", + &pygvalue, &pyobject)) + return NULL; + + if (!pyg_boxed_check (pygvalue, G_TYPE_VALUE)) { + PyErr_SetString (PyExc_TypeError, "Expected GValue argument."); + return NULL; + } + + if (pyg_value_from_pyobject_with_error (pyg_boxed_get (pygvalue, GValue), + pyobject) == -1) + return NULL; + + Py_RETURN_NONE; +} + +static PyMethodDef _gobject_functions[] = { + { "type_name", pyg_type_name, METH_VARARGS }, + { "type_from_name", pyg_type_from_name, METH_VARARGS }, + { "type_is_a", pyg_type_is_a, METH_VARARGS }, + { "type_register", _wrap_pyg_type_register, METH_VARARGS }, + { "signal_new", pyg_signal_new, METH_VARARGS }, + { "signal_query", + (PyCFunction)pyg_signal_query, METH_VARARGS|METH_KEYWORDS }, + { "list_properties", + pyg_object_class_list_properties, METH_VARARGS }, + { "new", + (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS }, + { "signal_accumulator_true_handled", + (PyCFunction)pyg_signal_accumulator_true_handled, METH_VARARGS }, + { "add_emission_hook", + (PyCFunction)pyg_add_emission_hook, METH_VARARGS }, + { "_install_metaclass", + (PyCFunction)pyg__install_metaclass, METH_O }, + { "_gvalue_get", + (PyCFunction)pyg__gvalue_get, METH_O }, + { "_gvalue_set", + (PyCFunction)pyg__gvalue_set, METH_VARARGS }, + + { NULL, NULL, 0 } +}; + + +/* ----------------- Constant extraction ------------------------ */ + +/** + * pyg_constant_strip_prefix: + * @name: the constant name. + * @strip_prefix: the prefix to strip. + * + * Advances the pointer @name by strlen(@strip_prefix) characters. If + * the resulting name does not start with a letter or underscore, the + * @name pointer will be rewound. This is to ensure that the + * resulting name is a valid identifier. Hence the returned string is + * a pointer into the string @name. + * + * Returns: the stripped constant name. + */ +const gchar * +pyg_constant_strip_prefix(const gchar *name, const gchar *strip_prefix) +{ + gint prefix_len; + guint i; + + prefix_len = strlen(strip_prefix); + + /* Check so name starts with strip_prefix, if it doesn't: + * return the rest of the part which doesn't match + */ + for (i = 0; i < prefix_len; i++) { + if (name[i] != strip_prefix[i] && name[i] != '_') { + return &name[i]; + } + } + + /* strip off prefix from value name, while keeping it a valid + * identifier */ + for (i = prefix_len; i >= 0; i--) { + if (g_ascii_isalpha(name[i]) || name[i] == '_') { + return &name[i]; + } + } + return name; +} + +/** + * pyg_enum_add_constants: + * @module: a Python module + * @enum_type: the GType of the enumeration. + * @strip_prefix: the prefix to strip from the constant names. + * + * Adds constants to the given Python module for each value name of + * the enumeration. A prefix will be stripped from each enum name. + */ +static void +pyg_enum_add_constants(PyObject *module, GType enum_type, + const gchar *strip_prefix) +{ + GEnumClass *eclass; + guint i; + + if (!G_TYPE_IS_ENUM(enum_type)) { + if (G_TYPE_IS_FLAGS(enum_type)) /* See bug #136204 */ + pyg_flags_add_constants(module, enum_type, strip_prefix); + else + g_warning("`%s' is not an enum type", g_type_name(enum_type)); + return; + } + g_return_if_fail (strip_prefix != NULL); + + eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); + + for (i = 0; i < eclass->n_values; i++) { + const gchar *name = eclass->values[i].value_name; + gint value = eclass->values[i].value; + + PyModule_AddIntConstant(module, + (char*) pyg_constant_strip_prefix(name, strip_prefix), + (long) value); + } + + g_type_class_unref(eclass); +} + +/** + * pyg_flags_add_constants: + * @module: a Python module + * @flags_type: the GType of the flags type. + * @strip_prefix: the prefix to strip from the constant names. + * + * Adds constants to the given Python module for each value name of + * the flags set. A prefix will be stripped from each flag name. + */ +static void +pyg_flags_add_constants(PyObject *module, GType flags_type, + const gchar *strip_prefix) +{ + GFlagsClass *fclass; + guint i; + + if (!G_TYPE_IS_FLAGS(flags_type)) { + if (G_TYPE_IS_ENUM(flags_type)) /* See bug #136204 */ + pyg_enum_add_constants(module, flags_type, strip_prefix); + else + g_warning("`%s' is not an flags type", g_type_name(flags_type)); + return; + } + g_return_if_fail (strip_prefix != NULL); + + fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + + for (i = 0; i < fclass->n_values; i++) { + const gchar *name = fclass->values[i].value_name; + guint value = fclass->values[i].value; + + PyModule_AddIntConstant(module, + (char*) pyg_constant_strip_prefix(name, strip_prefix), + (long) value); + } + + g_type_class_unref(fclass); +} + +/** + * pyg_error_check: + * @error: a pointer to the GError. + * + * Checks to see if the GError has been set. If the error has been + * set, then the gobject.GError Python exception will be raised, and + * the GError cleared. + * + * Returns: True if an error was set. + * + * Deprecated: Since 2.16, use pyglib_error_check instead. + */ +gboolean +pyg_error_check(GError **error) +{ +#if 0 + if (PyErr_Warn(PyExc_DeprecationWarning, + "pyg_error_check is deprecated, use " + "pyglib_error_check instead")) + return NULL; +#endif + return pyglib_error_check(error); +} + +/** + * pyg_gerror_exception_check: + * @error: a standard GLib GError ** output parameter + * + * Checks to see if a GError exception has been raised, and if so + * translates the python exception to a standard GLib GError. If the + * raised exception is not a GError then PyErr_Print() is called. + * + * Returns: 0 if no exception has been raised, -1 if it is a + * valid gobject.GError, -2 otherwise. + * + * Deprecated: Since 2.16, use pyglib_gerror_exception_check instead. + */ +gboolean +pyg_gerror_exception_check(GError **error) +{ +#if 0 + if (PyErr_Warn(PyExc_DeprecationWarning, + "pyg_gerror_exception_check is deprecated, use " + "pyglib_gerror_exception_check instead")) + return NULL; +#endif + return pyglib_gerror_exception_check(error); +} + +/** + * pyg_parse_constructor_args: helper function for PyGObject constructors + * @obj_type: GType of the GObject, for parameter introspection + * @arg_names: %NULL-terminated array of constructor argument names + * @prop_names: %NULL-terminated array of property names, with direct + * correspondence to @arg_names + * @params: GParameter array where parameters will be placed; length + * of this array must be at least equal to the number of + * arguments/properties + * @nparams: output parameter to contain actual number of arguments found + * @py_args: array of PyObject* containing the actual constructor arguments + * + * Parses an array of PyObject's and creates a GParameter array + * + * Return value: %TRUE if all is successful, otherwise %FALSE and + * python exception set. + **/ +static gboolean +pyg_parse_constructor_args(GType obj_type, + char **arg_names, + char **prop_names, + GParameter *params, + guint *nparams, + PyObject **py_args) +{ + guint arg_i, param_i; + GObjectClass *oclass; + + oclass = g_type_class_ref(obj_type); + g_return_val_if_fail(oclass, FALSE); + + for (param_i = arg_i = 0; arg_names[arg_i]; ++arg_i) { + GParamSpec *spec; + if (!py_args[arg_i]) + continue; + spec = g_object_class_find_property(oclass, prop_names[arg_i]); + params[param_i].name = prop_names[arg_i]; + g_value_init(¶ms[param_i].value, spec->value_type); + if (pyg_value_from_pyobject(¶ms[param_i].value, py_args[arg_i]) == -1) { + int i; + PyErr_Format(PyExc_TypeError, "could not convert parameter '%s' of type '%s'", + arg_names[arg_i], g_type_name(spec->value_type)); + g_type_class_unref(oclass); + for (i = 0; i < param_i; ++i) + g_value_unset(¶ms[i].value); + return FALSE; + } + ++param_i; + } + g_type_class_unref(oclass); + *nparams = param_i; + return TRUE; +} + +PyObject * +pyg_integer_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *result; + gboolean t; + + switch (op) { + case Py_EQ: t = PYGLIB_PyLong_AS_LONG(v) == PYGLIB_PyLong_AS_LONG(w); break; + case Py_NE: t = PYGLIB_PyLong_AS_LONG(v) != PYGLIB_PyLong_AS_LONG(w); break; + case Py_LE: t = PYGLIB_PyLong_AS_LONG(v) <= PYGLIB_PyLong_AS_LONG(w); break; + case Py_GE: t = PYGLIB_PyLong_AS_LONG(v) >= PYGLIB_PyLong_AS_LONG(w); break; + case Py_LT: t = PYGLIB_PyLong_AS_LONG(v) < PYGLIB_PyLong_AS_LONG(w); break; + case Py_GT: t = PYGLIB_PyLong_AS_LONG(v) > PYGLIB_PyLong_AS_LONG(w); break; + default: g_assert_not_reached(); + } + + result = t ? Py_True : Py_False; + Py_INCREF(result); + return result; +} + +static void +_log_func(const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + if (G_LIKELY(Py_IsInitialized())) + { + PyGILState_STATE state; + PyObject* warning = user_data; + + state = pyglib_gil_state_ensure(); + PyErr_Warn(warning, (char *) message); + pyglib_gil_state_release(state); + } else + g_log_default_handler(log_domain, log_level, message, user_data); +} + +static void +add_warning_redirection(const char *domain, + PyObject *warning) +{ + g_return_if_fail(domain != NULL); + g_return_if_fail(warning != NULL); + + if (!log_handlers_disabled) + { + guint handler; + gpointer old_handler; + + if (!log_handlers) + log_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + if ((old_handler = g_hash_table_lookup(log_handlers, domain))) + g_log_remove_handler(domain, GPOINTER_TO_UINT(old_handler)); + + handler = g_log_set_handler(domain, G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING, + _log_func, warning); + g_hash_table_insert(log_handlers, g_strdup(domain), GUINT_TO_POINTER(handler)); + } +} + +static void +remove_handler(gpointer domain, + gpointer handler, + gpointer unused) +{ + g_log_remove_handler(domain, GPOINTER_TO_UINT(handler)); +} + +static void +disable_warning_redirections(void) +{ + log_handlers_disabled = TRUE; + + if (log_handlers) + { + g_hash_table_foreach(log_handlers, remove_handler, NULL); + g_hash_table_destroy(log_handlers); + log_handlers = NULL; + } +} + +/* ----------------- gobject module initialisation -------------- */ + +struct _PyGObject_Functions pygobject_api_functions = { + pygobject_register_class, + pygobject_register_wrapper, + pygobject_lookup_class, + pygobject_new, + + pyg_closure_new, + pygobject_watch_closure, + pyg_destroy_notify, + + pyg_type_from_object, + pyg_type_wrapper_new, + pyg_enum_get_value, + pyg_flags_get_value, + pyg_register_gtype_custom, + pyg_value_from_pyobject, + pyg_value_as_pyobject, + + pyg_register_interface, + + &PyGBoxed_Type, + pyg_register_boxed, + pyg_boxed_new, + + &PyGPointer_Type, + pyg_register_pointer, + pyg_pointer_new, + + pyg_enum_add_constants, + pyg_flags_add_constants, + + pyg_constant_strip_prefix, + + pyg_error_check, + + _pyg_set_thread_block_funcs, + (PyGThreadBlockFunc)0, /* block_threads */ + (PyGThreadBlockFunc)0, /* unblock_threads */ + + &PyGParamSpec_Type, + pyg_param_spec_new, + pyg_param_spec_from_object, + + pyg_pyobj_to_unichar_conv, + pyg_parse_constructor_args, + pyg_param_gvalue_as_pyobject, + pyg_param_gvalue_from_pyobject, + + &PyGEnum_Type, + pyg_enum_add, + pyg_enum_from_gtype, + + &PyGFlags_Type, + pyg_flags_add, + pyg_flags_from_gtype, + + /* threads_enabled */ +#ifdef DISABLE_THREADING + FALSE, +#else + TRUE, +#endif + + pygobject_enable_threads, + pygobject_gil_state_ensure, + pygobject_gil_state_release, + pyg_register_class_init, + pyg_register_interface_info, + + pyg_closure_set_exception_handler, + + add_warning_redirection, + disable_warning_redirections, + + NULL, /* previously type_register_custom */ + + pyg_gerror_exception_check, + + pyg_option_group_new, + pyg_type_from_object_strict, + + pygobject_new_full, + &PyGObject_Type, + + pyg_value_from_pyobject_with_error +}; + +/* for addon libraries ... */ +static void +pygobject_register_api(PyObject *d) +{ + PyObject *api; + + api = PYGLIB_CPointer_WrapPointer(&pygobject_api_functions, "gobject._PyGObject_API"); + PyDict_SetItemString(d, "_PyGObject_API", api); + Py_DECREF(api); +} + +/* some constants */ +static void +pygobject_register_constants(PyObject *m) +{ + /* PyFloat_ return a new ref, and add object takes the ref */ + PyModule_AddObject(m, "G_MINFLOAT", PyFloat_FromDouble(G_MINFLOAT)); + PyModule_AddObject(m, "G_MAXFLOAT", PyFloat_FromDouble(G_MAXFLOAT)); + PyModule_AddObject(m, "G_MINDOUBLE", PyFloat_FromDouble(G_MINDOUBLE)); + PyModule_AddObject(m, "G_MAXDOUBLE", PyFloat_FromDouble(G_MAXDOUBLE)); + PyModule_AddIntConstant(m, "G_MINSHORT", G_MINSHORT); + PyModule_AddIntConstant(m, "G_MAXSHORT", G_MAXSHORT); + PyModule_AddIntConstant(m, "G_MAXUSHORT", G_MAXUSHORT); + PyModule_AddIntConstant(m, "G_MININT", G_MININT); + PyModule_AddIntConstant(m, "G_MAXINT", G_MAXINT); + PyModule_AddObject(m, "G_MAXUINT", PyLong_FromUnsignedLong(G_MAXUINT)); + PyModule_AddObject(m, "G_MINLONG", PyLong_FromLong(G_MINLONG)); + PyModule_AddObject(m, "G_MAXLONG", PyLong_FromLong(G_MAXLONG)); + PyModule_AddObject(m, "G_MAXULONG", PyLong_FromUnsignedLong(G_MAXULONG)); + PyModule_AddObject(m, "G_MAXSIZE", PyLong_FromSize_t(G_MAXSIZE)); + PyModule_AddObject(m, "G_MAXSSIZE", PyLong_FromSsize_t(G_MAXSSIZE)); + PyModule_AddObject(m, "G_MINSSIZE", PyLong_FromSsize_t(G_MINSSIZE)); + PyModule_AddObject(m, "G_MINOFFSET", PyLong_FromLongLong(G_MINOFFSET)); + PyModule_AddObject(m, "G_MAXOFFSET", PyLong_FromLongLong(G_MAXOFFSET)); + + PyModule_AddIntConstant(m, "SIGNAL_RUN_FIRST", G_SIGNAL_RUN_FIRST); + PyModule_AddIntConstant(m, "PARAM_READWRITE", G_PARAM_READWRITE); + + /* The rest of the types are set in __init__.py */ + PyModule_AddObject(m, "TYPE_INVALID", pyg_type_wrapper_new(G_TYPE_INVALID)); + PyModule_AddObject(m, "TYPE_GSTRING", pyg_type_wrapper_new(G_TYPE_GSTRING)); +} + +/* features */ +static void +pygobject_register_features(PyObject *d) +{ + PyObject *features; + + features = PyDict_New(); + PyDict_SetItemString(features, "generic-c-marshaller", Py_True); + PyDict_SetItemString(d, "features", features); + Py_DECREF(features); +} + +static void +pygobject_register_version_tuples(PyObject *d) +{ + PyObject *tuple; + + /* pygobject version */ + tuple = Py_BuildValue ("(iii)", + PYGOBJECT_MAJOR_VERSION, + PYGOBJECT_MINOR_VERSION, + PYGOBJECT_MICRO_VERSION); + PyDict_SetItemString(d, "pygobject_version", tuple); +} + +static void +pygobject_register_warnings(PyObject *d) +{ + PyObject *warning; + + warning = PyErr_NewException("gobject.Warning", PyExc_Warning, NULL); + PyDict_SetItemString(d, "Warning", warning); + add_warning_redirection("GLib", warning); + add_warning_redirection("GLib-GObject", warning); + add_warning_redirection("GThread", warning); +} + + +PYGLIB_MODULE_START(_gobject, "_gobject") +{ + PyObject *d; + + d = PyModule_GetDict(module); + pygobject_register_api(d); + pygobject_register_constants(module); + pygobject_register_features(d); + pygobject_register_version_tuples(d); + pygobject_register_warnings(d); + pygobject_type_register_types(d); + pygobject_object_register_types(d); + pygobject_interface_register_types(d); + pygobject_paramspec_register_types(d); + pygobject_boxed_register_types(d); + pygobject_pointer_register_types(d); + pygobject_enum_register_types(d); + pygobject_flags_register_types(d); +} +PYGLIB_MODULE_END diff --git a/gi/module.py b/gi/module.py index 8996926..8c25fd7 100644 --- a/gi/module.py +++ b/gi/module.py @@ -54,15 +54,15 @@ from ._gi import \ enum_add, \ enum_register_new_gtype_and_add, \ flags_add, \ - flags_register_new_gtype_and_add + flags_register_new_gtype_and_add, \ + _gobject from .types import \ GObjectMeta, \ StructMeta -from ._gobject._gobject import \ - GInterface +GInterface = _gobject.GInterface -from ._gobject.constants import \ +from ._constants import \ TYPE_NONE, \ TYPE_BOXED, \ TYPE_POINTER, \ diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py index df5654a..b17c69b 100644 --- a/gi/overrides/GLib.py +++ b/gi/overrides/GLib.py @@ -33,13 +33,13 @@ GLib = get_introspection_module('GLib') __all__ = [] -from gi._glib import option +from gi import _option as option option # pyflakes __all__.append('option') # Types and functions still needed from static bindings -from gi._glib import _glib +from gi._gi import _glib GError = _glib.GError OptionContext = _glib.OptionContext OptionGroup = _glib.OptionGroup diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py index 147a452..8c22ac5 100644 --- a/gi/overrides/GObject.py +++ b/gi/overrides/GObject.py @@ -31,16 +31,17 @@ from gi.overrides import override from gi.repository import GLib from gi import PyGIDeprecationWarning -from gi._gobject import _gobject -from gi._gobject import propertyhelper -from gi._gobject import signalhelper +from gi import _propertyhelper as propertyhelper +from gi import _signalhelper as signalhelper + +_gobject = gi._gi._gobject GObjectModule = gi.module.get_introspection_module('GObject') __all__ = [] -from gi._glib import option +from gi import _option as option sys.modules['gi._gobject.option'] = option diff --git a/gi/overrides/__init__.py b/gi/overrides/__init__.py index 9e7a0f1..2cd1345 100644 --- a/gi/overrides/__init__.py +++ b/gi/overrides/__init__.py @@ -3,7 +3,7 @@ import warnings from gi import PyGIDeprecationWarning from gi._gi import CallableInfo -from gi._gobject.constants import \ +from gi._constants import \ TYPE_NONE, \ TYPE_INVALID diff --git a/gi/pygboxed.c b/gi/pygboxed.c new file mode 100644 index 0000000..541e77b --- /dev/null +++ b/gi/pygboxed.c @@ -0,0 +1,235 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pygboxed.c: wrapper for GBoxed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pygobject-private.h" +#include "pygboxed.h" + +#include "pygi.h" + +GQuark pygboxed_type_key; +GQuark pygboxed_marshal_key; + +PYGLIB_DEFINE_TYPE("gobject.GBoxed", PyGBoxed_Type, PyGBoxed); + +static void +pyg_boxed_dealloc(PyGBoxed *self) +{ + if (self->free_on_dealloc && self->boxed) { + PyGILState_STATE state = pyglib_gil_state_ensure(); + g_boxed_free(self->gtype, self->boxed); + pyglib_gil_state_release(state); + } + + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject* +pyg_boxed_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other) && + PyObject_IsInstance(self, (PyObject*)&PyGBoxed_Type)) + return _pyglib_generic_ptr_richcompare(((PyGBoxed*)self)->boxed, + ((PyGBoxed*)other)->boxed, + op); + else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + + +static long +pyg_boxed_hash(PyGBoxed *self) +{ + return (long)self->boxed; +} + +static PyObject * +pyg_boxed_repr(PyGBoxed *self) +{ + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), "<%s at 0x%lx>", g_type_name(self->gtype), + (long)self->boxed); + return PYGLIB_PyUnicode_FromString(buf); +} + +static int +pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs) +{ + gchar buf[512]; + + if (!PyArg_ParseTuple(args, ":GBoxed.__init__")) + return -1; + + self->boxed = NULL; + self->gtype = 0; + self->free_on_dealloc = FALSE; + + g_snprintf(buf, sizeof(buf), "%s can not be constructed", + Py_TYPE(self)->tp_name); + PyErr_SetString(PyExc_NotImplementedError, buf); + return -1; +} + +static void +pyg_boxed_free(PyObject *op) +{ + PyObject_FREE(op); +} + +static PyObject * +pyg_boxed_copy(PyGBoxed *self) +{ + return pyg_boxed_new (self->gtype, self->boxed, TRUE, TRUE); +} + + + +static PyMethodDef pygboxed_methods[] = { + { "copy", (PyCFunction) pyg_boxed_copy, METH_NOARGS }, + { NULL, NULL, 0 } +}; + + +/** + * pyg_register_boxed: + * @dict: the module dictionary to store the wrapper class. + * @class_name: the Python name for the wrapper class. + * @boxed_type: the GType of the boxed type being wrapped. + * @type: the wrapper class. + * + * Registers a wrapper for a boxed type. The wrapper class will be a + * subclass of gobject.GBoxed, and a reference to the wrapper class + * will be stored in the provided module dictionary. + */ +void +pyg_register_boxed(PyObject *dict, const gchar *class_name, + GType boxed_type, PyTypeObject *type) +{ + PyObject *o; + + g_return_if_fail(dict != NULL); + g_return_if_fail(class_name != NULL); + g_return_if_fail(boxed_type != 0); + + if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc; + + Py_TYPE(type) = &PyType_Type; + type->tp_base = &PyGBoxed_Type; + + if (PyType_Ready(type) < 0) { + g_warning("could not get type `%s' ready", type->tp_name); + return; + } + + PyDict_SetItemString(type->tp_dict, "__gtype__", + o=pyg_type_wrapper_new(boxed_type)); + Py_DECREF(o); + + g_type_set_qdata(boxed_type, pygboxed_type_key, type); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); +} + +/** + * pyg_boxed_new: + * @boxed_type: the GType of the boxed value. + * @boxed: the boxed value. + * @copy_boxed: whether the new boxed wrapper should hold a copy of the value. + * @own_ref: whether the boxed wrapper should own the boxed value. + * + * Creates a wrapper for a boxed value. If @copy_boxed is set to + * True, the wrapper will hold a copy of the value, instead of the + * value itself. If @own_ref is True, then the value held by the + * wrapper will be freed when the wrapper is deallocated. If + * @copy_boxed is True, then @own_ref must also be True. + * + * Returns: the boxed wrapper. + */ +PyObject * +pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, + gboolean own_ref) +{ + PyGILState_STATE state; + PyGBoxed *self; + PyTypeObject *tp; + + g_return_val_if_fail(boxed_type != 0, NULL); + g_return_val_if_fail(!copy_boxed || (copy_boxed && own_ref), NULL); + + state = pyglib_gil_state_ensure(); + + if (!boxed) { + Py_INCREF(Py_None); + pyglib_gil_state_release(state); + return Py_None; + } + + tp = g_type_get_qdata(boxed_type, pygboxed_type_key); + + if (!tp) + tp = (PyTypeObject *)pygi_type_import_by_g_type(boxed_type); + + if (!tp) + tp = (PyTypeObject *)&PyGBoxed_Type; /* fallback */ + + self = (PyGBoxed *)tp->tp_alloc(tp, 0); + + if (self == NULL) { + pyglib_gil_state_release(state); + return NULL; + } + + if (copy_boxed) + boxed = g_boxed_copy(boxed_type, boxed); + self->boxed = boxed; + self->gtype = boxed_type; + self->free_on_dealloc = own_ref; + + pyglib_gil_state_release(state); + + return (PyObject *)self; +} + +void +pygobject_boxed_register_types(PyObject *d) +{ + pygboxed_type_key = g_quark_from_static_string("PyGBoxed::class"); + pygboxed_marshal_key = g_quark_from_static_string("PyGBoxed::marshal"); + + PyGBoxed_Type.tp_dealloc = (destructor)pyg_boxed_dealloc; + PyGBoxed_Type.tp_richcompare = pyg_boxed_richcompare; + PyGBoxed_Type.tp_repr = (reprfunc)pyg_boxed_repr; + PyGBoxed_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGBoxed_Type.tp_methods = pygboxed_methods; + PyGBoxed_Type.tp_init = (initproc)pyg_boxed_init; + PyGBoxed_Type.tp_free = (freefunc)pyg_boxed_free; + PyGBoxed_Type.tp_hash = (hashfunc)pyg_boxed_hash; + + PYGOBJECT_REGISTER_GTYPE(d, PyGBoxed_Type, "GBoxed", G_TYPE_BOXED); +} diff --git a/gi/pygboxed.h b/gi/pygboxed.h new file mode 100644 index 0000000..8433b9d --- /dev/null +++ b/gi/pygboxed.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_BOXED_H__ +#define __PYGOBJECT_BOXED_H__ + +void pygobject_boxed_register_types(PyObject *d); + +#endif /* __PYGOBJECT_BOXED_H__ */ diff --git a/gi/pygenum.c b/gi/pygenum.c new file mode 100644 index 0000000..89e3a06 --- /dev/null +++ b/gi/pygenum.c @@ -0,0 +1,371 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * Copyright (C) 2004 Johan Dahlin + * + * pygenum.c: GEnum wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pygobject-private.h" +#include "pygi.h" + +#include "pygenum.h" + +GQuark pygenum_class_key; + +PYGLIB_DEFINE_TYPE("gobject.GEnum", PyGEnum_Type, PyGEnum); + +static PyObject * +pyg_enum_val_new(PyObject* subclass, GType gtype, PyObject *intval) +{ + PyObject *args, *item; + args = Py_BuildValue("(O)", intval); + item = (&PYGLIB_PyLong_Type)->tp_new((PyTypeObject*)subclass, args, NULL); + Py_DECREF(args); + if (!item) + return NULL; + ((PyGEnum*)item)->gtype = gtype; + + return item; +} + +static PyObject * +pyg_enum_richcompare(PyGEnum *self, PyObject *other, int op) +{ + static char warning[256]; + + if (!PYGLIB_PyLong_Check(other)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + if (PyObject_TypeCheck(other, &PyGEnum_Type) && ((PyGEnum*)other)->gtype != self->gtype) { + g_snprintf(warning, sizeof(warning), "comparing different enum types: %s and %s", + g_type_name(self->gtype), g_type_name(((PyGEnum*)other)->gtype)); + if (PyErr_Warn(PyExc_Warning, warning)) + return NULL; + } + + return pyg_integer_richcompare((PyObject *)self, other, op); +} + +static PyObject * +pyg_enum_repr(PyGEnum *self) +{ + GEnumClass *enum_class; + const char *value; + guint index; + static char tmp[256]; + long l; + + enum_class = g_type_class_ref(self->gtype); + g_assert(G_IS_ENUM_CLASS(enum_class)); + + l = PYGLIB_PyLong_AS_LONG(self); + for (index = 0; index < enum_class->n_values; index++) + if (l == enum_class->values[index].value) + break; + + value = enum_class->values[index].value_name; + if (value) + sprintf(tmp, "", value, g_type_name(self->gtype)); + else + sprintf(tmp, "", PYGLIB_PyLong_AS_LONG(self), g_type_name(self->gtype)); + + g_type_class_unref(enum_class); + + return PYGLIB_PyUnicode_FromString(tmp); +} + +static PyObject * +pyg_enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "value", NULL }; + long value; + PyObject *pytc, *values, *ret, *intvalue; + GType gtype; + GEnumClass *eclass; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "l", kwlist, &value)) + return NULL; + + pytc = PyObject_GetAttrString((PyObject *)type, "__gtype__"); + if (!pytc) + return NULL; + + if (!PyObject_TypeCheck(pytc, &PyGTypeWrapper_Type)) { + Py_DECREF(pytc); + PyErr_SetString(PyExc_TypeError, + "__gtype__ attribute not a typecode"); + return NULL; + } + + gtype = pyg_type_from_object(pytc); + Py_DECREF(pytc); + + eclass = G_ENUM_CLASS(g_type_class_ref(gtype)); + + /* A check that 0 < value < eclass->n_values was here but got + * removed: enumeration values do not need to be consequitive, + * e.g. GtkPathPriorityType values are not. + */ + + values = PyObject_GetAttrString((PyObject *)type, "__enum_values__"); + if (!values) { + g_type_class_unref(eclass); + return NULL; + } + + /* Note that size of __enum_values__ dictionary can easily be less + * than 'n_values'. This happens if some values of the enum are + * numerically equal, e.g. gtk.ANCHOR_N == gtk.ANCHOR_NORTH. + * Johan said that "In retrospect, using a dictionary to store the + * values might not have been that good", but we need to keep + * backward compatibility. + */ + if (!PyDict_Check(values) || PyDict_Size(values) > eclass->n_values) { + PyErr_SetString(PyExc_TypeError, "__enum_values__ badly formed"); + Py_DECREF(values); + g_type_class_unref(eclass); + return NULL; + } + + g_type_class_unref(eclass); + + intvalue = PYGLIB_PyLong_FromLong(value); + ret = PyDict_GetItem(values, intvalue); + Py_DECREF(intvalue); + Py_DECREF(values); + if (ret) + Py_INCREF(ret); + else + PyErr_Format(PyExc_ValueError, "invalid enum value: %ld", value); + + return ret; +} + +PyObject* +pyg_enum_from_gtype (GType gtype, int value) +{ + PyObject *pyclass, *values, *retval, *intvalue; + + g_return_val_if_fail(gtype != G_TYPE_INVALID, NULL); + + /* Get a wrapper class by: + * 1. check for one attached to the gtype + * 2. lookup one in a typelib + * 3. creating a new one + */ + pyclass = (PyObject*)g_type_get_qdata(gtype, pygenum_class_key); + if (!pyclass) + pyclass = pygi_type_import_by_g_type(gtype); + if (!pyclass) + pyclass = pyg_enum_add(NULL, g_type_name(gtype), NULL, gtype); + if (!pyclass) + return PYGLIB_PyLong_FromLong(value); + + values = PyDict_GetItemString(((PyTypeObject *)pyclass)->tp_dict, + "__enum_values__"); + intvalue = PYGLIB_PyLong_FromLong(value); + retval = PyDict_GetItem(values, intvalue); + if (retval) { + Py_INCREF(retval); + } + else { + PyErr_Clear(); + retval = pyg_enum_val_new(pyclass, gtype, intvalue); + } + Py_DECREF(intvalue); + + return retval; +} + +/* + * pyg_enum_add + * Dynamically create a class derived from PyGEnum based on the given GType. + */ +PyObject * +pyg_enum_add (PyObject * module, + const char * typename, + const char * strip_prefix, + GType gtype) +{ + PyGILState_STATE state; + PyObject *instance_dict, *stub, *values, *o; + GEnumClass *eclass; + int i; + + g_return_val_if_fail(typename != NULL, NULL); + 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; + } + + state = pyglib_gil_state_ensure(); + + /* Create a new type derived from GEnum. This is the same as: + * >>> stub = type(typename, (GEnum,), {}) + */ + instance_dict = PyDict_New(); + stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", + typename, (PyObject *)&PyGEnum_Type, + instance_dict); + Py_DECREF(instance_dict); + if (!stub) { + PyErr_SetString(PyExc_RuntimeError, "can't create const"); + pyglib_gil_state_release(state); + return NULL; + } + + ((PyTypeObject *)stub)->tp_flags &= ~Py_TPFLAGS_BASETYPE; + ((PyTypeObject *)stub)->tp_new = pyg_enum_new; + + if (module) + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, + "__module__", + PYGLIB_PyUnicode_FromString(PyModule_GetName(module))); + + g_type_set_qdata(gtype, pygenum_class_key, stub); + + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, "__gtype__", o); + Py_DECREF(o); + + if (module) { + /* Add it to the module name space */ + PyModule_AddObject(module, (char*)typename, stub); + Py_INCREF(stub); + } + + /* Register enum values */ + eclass = G_ENUM_CLASS(g_type_class_ref(gtype)); + + values = PyDict_New(); + for (i = 0; i < eclass->n_values; i++) { + PyObject *item, *intval; + + intval = PYGLIB_PyLong_FromLong(eclass->values[i].value); + item = pyg_enum_val_new(stub, gtype, intval); + PyDict_SetItem(values, intval, item); + Py_DECREF(intval); + + if (module) { + char *prefix; + + prefix = g_strdup(pyg_constant_strip_prefix(eclass->values[i].value_name, strip_prefix)); + PyModule_AddObject(module, prefix, item); + g_free(prefix); + + Py_INCREF(item); + } + } + + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, + "__enum_values__", values); + Py_DECREF(values); + + g_type_class_unref(eclass); + + pyglib_gil_state_release(state); + return stub; +} + +static PyObject * +pyg_enum_reduce(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":GEnum.__reduce__")) + return NULL; + + return Py_BuildValue("(O(i)O)", Py_TYPE(self), PYGLIB_PyLong_AsLong(self), + PyObject_GetAttrString(self, "__dict__")); +} + +static PyObject * +pyg_enum_get_value_name(PyGEnum *self, void *closure) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + PyObject *retval; + + enum_class = g_type_class_ref(self->gtype); + g_assert(G_IS_ENUM_CLASS(enum_class)); + + enum_value = g_enum_get_value(enum_class, PYGLIB_PyLong_AS_LONG(self)); + + retval = PYGLIB_PyUnicode_FromString(enum_value->value_name); + g_type_class_unref(enum_class); + + return retval; +} + +static PyObject * +pyg_enum_get_value_nick(PyGEnum *self, void *closure) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + PyObject *retval; + + enum_class = g_type_class_ref(self->gtype); + g_assert(G_IS_ENUM_CLASS(enum_class)); + + enum_value = g_enum_get_value(enum_class, PYGLIB_PyLong_AS_LONG(self)); + + retval = PYGLIB_PyUnicode_FromString(enum_value->value_nick); + g_type_class_unref(enum_class); + + return retval; +} + + +static PyMethodDef pyg_enum_methods[] = { + { "__reduce__", (PyCFunction)pyg_enum_reduce, METH_VARARGS }, + { NULL, NULL, 0 } +}; + +static PyGetSetDef pyg_enum_getsets[] = { + { "value_name", (getter)pyg_enum_get_value_name, (setter)0 }, + { "value_nick", (getter)pyg_enum_get_value_nick, (setter)0 }, + { NULL, 0, 0 } +}; + +void +pygobject_enum_register_types(PyObject *d) +{ + pygenum_class_key = g_quark_from_static_string("PyGEnum::class"); + + PyGEnum_Type.tp_base = &PYGLIB_PyLong_Type; +#if PY_VERSION_HEX < 0x03000000 + PyGEnum_Type.tp_new = pyg_enum_new; +#else + PyGEnum_Type.tp_new = PyLong_Type.tp_new; + PyGEnum_Type.tp_hash = PyLong_Type.tp_hash; +#endif + PyGEnum_Type.tp_repr = (reprfunc)pyg_enum_repr; + PyGEnum_Type.tp_str = (reprfunc)pyg_enum_repr; + PyGEnum_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGEnum_Type.tp_richcompare = (richcmpfunc)pyg_enum_richcompare; + PyGEnum_Type.tp_methods = pyg_enum_methods; + PyGEnum_Type.tp_getset = pyg_enum_getsets; + PYGOBJECT_REGISTER_GTYPE(d, PyGEnum_Type, "GEnum", G_TYPE_ENUM); +} diff --git a/gi/pygenum.h b/gi/pygenum.h new file mode 100644 index 0000000..0558831 --- /dev/null +++ b/gi/pygenum.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_ENUM_H__ +#define __PYGOBJECT_ENUM_H__ + +void pygobject_enum_register_types(PyObject *d); + +#endif /* __PYGOBJECT_ENUM_H__ */ diff --git a/gi/pygflags.c b/gi/pygflags.c new file mode 100644 index 0000000..bdeaae7 --- /dev/null +++ b/gi/pygflags.c @@ -0,0 +1,497 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * Copyright (C) 2004 Johan Dahlin + * + * pygflags.c: GFlags wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pygobject-private.h" +#include "pygflags.h" + +#include "pygi.h" + +GQuark pygflags_class_key; + +PYGLIB_DEFINE_TYPE("gobject.GFlags", PyGFlags_Type, PyGFlags); + +static PyObject * +pyg_flags_val_new(PyObject* subclass, GType gtype, PyObject *intval) +{ + PyObject *args, *item; + args = Py_BuildValue("(O)", intval); + g_assert(PyObject_IsSubclass(subclass, (PyObject*) &PyGFlags_Type)); + item = PYGLIB_PyLong_Type.tp_new((PyTypeObject*)subclass, args, NULL); + Py_DECREF(args); + if (!item) + return NULL; + ((PyGFlags*)item)->gtype = gtype; + + return item; +} + +static PyObject * +pyg_flags_richcompare(PyGFlags *self, PyObject *other, int op) +{ + static char warning[256]; + + if (!PYGLIB_PyLong_Check(other)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + if (PyObject_TypeCheck(other, &PyGFlags_Type) && ((PyGFlags*)other)->gtype != self->gtype) { + g_snprintf(warning, sizeof(warning), "comparing different flags types: %s and %s", + g_type_name(self->gtype), g_type_name(((PyGFlags*)other)->gtype)); + if (PyErr_Warn(PyExc_Warning, warning)) + return NULL; + } + + return pyg_integer_richcompare((PyObject *)self, other, op); +} + +static char * +generate_repr(GType gtype, guint value) +{ + GFlagsClass *flags_class; + char *retval = NULL, *tmp; + int i; + + flags_class = g_type_class_ref(gtype); + g_assert(G_IS_FLAGS_CLASS(flags_class)); + + for (i = 0; i < flags_class->n_values; i++) { + /* Some types (eg GstElementState in GStreamer 0.8) has flags with 0 values, + * we're just ignore them for now otherwise they'll always show up + */ + if (flags_class->values[i].value == 0) + continue; + + if ((value & flags_class->values[i].value) == flags_class->values[i].value) { + if (retval) { + tmp = g_strdup_printf("%s | %s", retval, flags_class->values[i].value_name); + g_free(retval); + retval = tmp; + } else { + retval = g_strdup_printf("%s", flags_class->values[i].value_name); + } + } + } + + g_type_class_unref(flags_class); + + return retval; +} + +static PyObject * +pyg_flags_repr(PyGFlags *self) +{ + char *tmp, *retval; + PyObject *pyretval; + + tmp = generate_repr(self->gtype, PYGLIB_PyLong_AsUnsignedLong(self)); + + if (tmp) + retval = g_strdup_printf("", tmp, + g_type_name(self->gtype)); + else + retval = g_strdup_printf("", PYGLIB_PyLong_AsUnsignedLong(self), + g_type_name(self->gtype)); + g_free(tmp); + + pyretval = PYGLIB_PyUnicode_FromString(retval); + g_free(retval); + + return pyretval; +} + +static PyObject * +pyg_flags_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "value", NULL }; + gulong value; + PyObject *pytc, *values, *ret, *pyint; + GType gtype; + GFlagsClass *eclass; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "k", kwlist, &value)) + return NULL; + + pytc = PyObject_GetAttrString((PyObject *)type, "__gtype__"); + if (!pytc) + return NULL; + + if (!PyObject_TypeCheck(pytc, &PyGTypeWrapper_Type)) { + Py_DECREF(pytc); + PyErr_SetString(PyExc_TypeError, + "__gtype__ attribute not a typecode"); + return NULL; + } + + gtype = pyg_type_from_object(pytc); + Py_DECREF(pytc); + + eclass = G_FLAGS_CLASS(g_type_class_ref(gtype)); + + values = PyObject_GetAttrString((PyObject *)type, "__flags_values__"); + if (!values) { + g_type_class_unref(eclass); + return NULL; + } + + if (!PyDict_Check(values)) { + PyErr_SetString(PyExc_TypeError, "__flags_values__ badly formed"); + Py_DECREF(values); + g_type_class_unref(eclass); + return NULL; + } + + g_type_class_unref(eclass); + + pyint = PYGLIB_PyLong_FromUnsignedLong(value); + ret = PyDict_GetItem(values, pyint); + if (!ret) { + PyErr_Clear(); + + ret = pyg_flags_val_new((PyObject *)type, gtype, pyint); + g_assert(ret != NULL); + } else { + Py_INCREF(ret); + } + + Py_DECREF(pyint); + Py_DECREF(values); + + return ret; +} + +PyObject* +pyg_flags_from_gtype (GType gtype, guint value) +{ + PyObject *pyclass, *values, *retval, *pyint; + + if (PyErr_Occurred()) + return PYGLIB_PyLong_FromUnsignedLong(0); + + g_return_val_if_fail(gtype != G_TYPE_INVALID, NULL); + + /* Get a wrapper class by: + * 1. check for one attached to the gtype + * 2. lookup one in a typelib + * 3. creating a new one + */ + pyclass = (PyObject*)g_type_get_qdata(gtype, pygflags_class_key); + if (!pyclass) + pyclass = pygi_type_import_by_g_type(gtype); + if (!pyclass) + pyclass = pyg_flags_add(NULL, g_type_name(gtype), NULL, gtype); + if (!pyclass) + return PYGLIB_PyLong_FromUnsignedLong(value); + + values = PyDict_GetItemString(((PyTypeObject *)pyclass)->tp_dict, + "__flags_values__"); + pyint = PYGLIB_PyLong_FromUnsignedLong(value); + retval = PyDict_GetItem(values, pyint); + if (!retval) { + PyErr_Clear(); + + retval = pyg_flags_val_new(pyclass, gtype, pyint); + g_assert(retval != NULL); + } else { + Py_INCREF(retval); + } + Py_DECREF(pyint); + + return retval; +} + +/* + * pyg_flags_add + * Dynamically create a class derived from PyGFlags based on the given GType. + */ +PyObject * +pyg_flags_add (PyObject * module, + const char * typename, + const char * strip_prefix, + GType gtype) +{ + PyGILState_STATE state; + PyObject *instance_dict, *stub, *values, *o; + GFlagsClass *eclass; + int i; + + g_return_val_if_fail(typename != NULL, NULL); + if (!g_type_is_a(gtype, G_TYPE_FLAGS)) { + g_warning("Trying to register gtype '%s' as flags when in fact it is of type '%s'", + g_type_name(gtype), g_type_name(G_TYPE_FUNDAMENTAL(gtype))); + return NULL; + } + + state = pyglib_gil_state_ensure(); + + /* Create a new type derived from GFlags. This is the same as: + * >>> stub = type(typename, (GFlags,), {}) + */ + instance_dict = PyDict_New(); + stub = PyObject_CallFunction((PyObject *)&PyType_Type, "s(O)O", + typename, (PyObject *)&PyGFlags_Type, + instance_dict); + Py_DECREF(instance_dict); + if (!stub) { + PyErr_SetString(PyExc_RuntimeError, "can't create GFlags subtype"); + pyglib_gil_state_release(state); + return NULL; + } + + ((PyTypeObject *)stub)->tp_flags &= ~Py_TPFLAGS_BASETYPE; + ((PyTypeObject *)stub)->tp_new = pyg_flags_new; + + if (module) { + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, + "__module__", + PYGLIB_PyUnicode_FromString(PyModule_GetName(module))); + + /* Add it to the module name space */ + PyModule_AddObject(module, (char*)typename, stub); + Py_INCREF(stub); + } + g_type_set_qdata(gtype, pygflags_class_key, stub); + + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, "__gtype__", o); + Py_DECREF(o); + + /* Register flag values */ + eclass = G_FLAGS_CLASS(g_type_class_ref(gtype)); + + values = PyDict_New(); + for (i = 0; i < eclass->n_values; i++) { + PyObject *item, *intval; + + intval = PYGLIB_PyLong_FromUnsignedLong(eclass->values[i].value); + g_assert(PyErr_Occurred() == NULL); + item = pyg_flags_val_new(stub, gtype, intval); + PyDict_SetItem(values, intval, item); + Py_DECREF(intval); + + if (module) { + char *prefix; + + prefix = g_strdup(pyg_constant_strip_prefix(eclass->values[i].value_name, strip_prefix)); + Py_INCREF(item); + PyModule_AddObject(module, prefix, item); + g_free(prefix); + } + Py_DECREF(item); + } + + PyDict_SetItemString(((PyTypeObject *)stub)->tp_dict, + "__flags_values__", values); + Py_DECREF(values); + + g_type_class_unref(eclass); + + pyglib_gil_state_release(state); + + return stub; +} + +static PyObject * +pyg_flags_and(PyGFlags *a, PyGFlags *b) +{ + if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) + return PYGLIB_PyLong_Type.tp_as_number->nb_and((PyObject*)a, + (PyObject*)b); + + return pyg_flags_from_gtype(a->gtype, + PYGLIB_PyLong_AsUnsignedLong(a) & PYGLIB_PyLong_AsUnsignedLong(b)); +} + +static PyObject * +pyg_flags_or(PyGFlags *a, PyGFlags *b) +{ + if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) + return PYGLIB_PyLong_Type.tp_as_number->nb_or((PyObject*)a, + (PyObject*)b); + + return pyg_flags_from_gtype(a->gtype, PYGLIB_PyLong_AsUnsignedLong(a) | PYGLIB_PyLong_AsUnsignedLong(b)); +} + +static PyObject * +pyg_flags_xor(PyGFlags *a, PyGFlags *b) +{ + if (!PyGFlags_Check(a) || !PyGFlags_Check(b)) + return PYGLIB_PyLong_Type.tp_as_number->nb_xor((PyObject*)a, + (PyObject*)b); + + return pyg_flags_from_gtype(a->gtype, + PYGLIB_PyLong_AsUnsignedLong(a) ^ PYGLIB_PyLong_AsUnsignedLong(b)); + +} + +static PyObject * +pyg_flags_warn (PyObject *self, PyObject *args) +{ + if (PyErr_Warn(PyExc_Warning, "unsupported arithmetic operation for flags type")) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pyg_flags_get_first_value_name(PyGFlags *self, void *closure) +{ + GFlagsClass *flags_class; + GFlagsValue *flags_value; + PyObject *retval; + + flags_class = g_type_class_ref(self->gtype); + g_assert(G_IS_FLAGS_CLASS(flags_class)); + flags_value = g_flags_get_first_value(flags_class, PYGLIB_PyLong_AsUnsignedLong(self)); + if (flags_value) + retval = PYGLIB_PyUnicode_FromString(flags_value->value_name); + else { + retval = Py_None; + Py_INCREF(Py_None); + } + g_type_class_unref(flags_class); + + return retval; +} + +static PyObject * +pyg_flags_get_first_value_nick(PyGFlags *self, void *closure) +{ + GFlagsClass *flags_class; + GFlagsValue *flags_value; + PyObject *retval; + + flags_class = g_type_class_ref(self->gtype); + g_assert(G_IS_FLAGS_CLASS(flags_class)); + + flags_value = g_flags_get_first_value(flags_class, PYGLIB_PyLong_AsUnsignedLong(self)); + if (flags_value) + retval = PYGLIB_PyUnicode_FromString(flags_value->value_nick); + else { + retval = Py_None; + Py_INCREF(Py_None); + } + g_type_class_unref(flags_class); + + return retval; +} + +static PyObject * +pyg_flags_get_value_names(PyGFlags *self, void *closure) +{ + GFlagsClass *flags_class; + PyObject *retval; + int i; + + flags_class = g_type_class_ref(self->gtype); + g_assert(G_IS_FLAGS_CLASS(flags_class)); + + retval = PyList_New(0); + for (i = 0; i < flags_class->n_values; i++) + if ((PYGLIB_PyLong_AsUnsignedLong(self) & flags_class->values[i].value) == flags_class->values[i].value) + PyList_Append(retval, PYGLIB_PyUnicode_FromString(flags_class->values[i].value_name)); + + g_type_class_unref(flags_class); + + return retval; +} + +static PyObject * +pyg_flags_get_value_nicks(PyGFlags *self, void *closure) +{ + GFlagsClass *flags_class; + PyObject *retval; + int i; + + flags_class = g_type_class_ref(self->gtype); + g_assert(G_IS_FLAGS_CLASS(flags_class)); + + retval = PyList_New(0); + for (i = 0; i < flags_class->n_values; i++) + if ((PYGLIB_PyLong_AsUnsignedLong(self) & flags_class->values[i].value) == flags_class->values[i].value) { + PyObject *py_nick = PYGLIB_PyUnicode_FromString(flags_class->values[i].value_nick); + PyList_Append(retval, py_nick); + Py_DECREF (py_nick); + } + + g_type_class_unref(flags_class); + + return retval; +} + +static PyGetSetDef pyg_flags_getsets[] = { + { "first_value_name", (getter)pyg_flags_get_first_value_name, (setter)0 }, + { "first_value_nick", (getter)pyg_flags_get_first_value_nick, (setter)0 }, + { "value_names", (getter)pyg_flags_get_value_names, (setter)0 }, + { "value_nicks", (getter)pyg_flags_get_value_nicks, (setter)0 }, + { NULL, 0, 0 } +}; + +static PyNumberMethods pyg_flags_as_number = { + (binaryfunc)pyg_flags_warn, /* nb_add */ + (binaryfunc)pyg_flags_warn, /* nb_subtract */ + (binaryfunc)pyg_flags_warn, /* nb_multiply */ + (binaryfunc)pyg_flags_warn, /* nb_divide */ + (binaryfunc)pyg_flags_warn, /* nb_remainder */ +#if PY_VERSION_HEX < 0x03000000 + (binaryfunc)pyg_flags_warn, /* nb_divmod */ +#endif + (ternaryfunc)pyg_flags_warn, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_nonzero */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + (binaryfunc)pyg_flags_and, /* nb_and */ + (binaryfunc)pyg_flags_xor, /* nb_xor */ + (binaryfunc)pyg_flags_or, /* nb_or */ +}; + +void +pygobject_flags_register_types(PyObject *d) +{ + pygflags_class_key = g_quark_from_static_string("PyGFlags::class"); + + PyGFlags_Type.tp_base = &PYGLIB_PyLong_Type; +#if PY_VERSION_HEX < 0x03000000 + PyGFlags_Type.tp_new = pyg_flags_new; +#else + PyGFlags_Type.tp_new = PyLong_Type.tp_new; + PyGFlags_Type.tp_hash = PyLong_Type.tp_hash; +#endif + PyGFlags_Type.tp_repr = (reprfunc)pyg_flags_repr; + PyGFlags_Type.tp_as_number = &pyg_flags_as_number; + PyGFlags_Type.tp_str = (reprfunc)pyg_flags_repr; + PyGFlags_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGFlags_Type.tp_richcompare = (richcmpfunc)pyg_flags_richcompare; + PyGFlags_Type.tp_getset = pyg_flags_getsets; + PYGOBJECT_REGISTER_GTYPE(d, PyGFlags_Type, "GFlags", G_TYPE_FLAGS); +} diff --git a/gi/pygflags.h b/gi/pygflags.h new file mode 100644 index 0000000..e93265c --- /dev/null +++ b/gi/pygflags.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_FLAGS_H__ +#define __PYGOBJECT_FLAGS_H__ + +void pygobject_flags_register_types(PyObject *d); + +#endif /* __PYGOBJECT_FLAGS_H__ */ diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c index 6378892..63149b0 100644 --- a/gi/pygi-argument.c +++ b/gi/pygi-argument.c @@ -22,17 +22,19 @@ */ #include "pygi-private.h" +#include "pygobject-private.h" #include #include #include -#include #include #include -#include "pygi-marshal-from-py.h" -#include "pygi-marshal-to-py.h" +#include "pygi-value.h" +#include "pygi-basictype.h" +#include "pygi-object.h" +#include "pygi-struct-marshal.h" static gboolean @@ -1062,7 +1064,7 @@ array_success: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_OBJECT: /* An error within this call will result in a NULL arg */ - _pygi_marshal_from_py_gobject_out_arg (object, &arg, transfer); + pygi_arg_gobject_out_arg_from_py (object, &arg, transfer); break; default: @@ -1435,10 +1437,10 @@ _pygi_argument_to_object (GIArgument *arg, transfer == GI_TRANSFER_NOTHING && g_object_is_floating (arg->v_pointer)) { g_object_ref (arg->v_pointer); - object = _pygi_marshal_to_py_object (arg, GI_TRANSFER_EVERYTHING); + object = pygi_arg_gobject_to_py (arg, GI_TRANSFER_EVERYTHING); g_object_force_floating (arg->v_pointer); } else { - object = _pygi_marshal_to_py_object (arg, transfer); + object = pygi_arg_gobject_to_py (arg, transfer); } break; @@ -1587,131 +1589,6 @@ _pygi_argument_to_object (GIArgument *arg, return object; } - -GIArgument -_pygi_argument_from_g_value(const GValue *value, - GITypeInfo *type_info) -{ - GIArgument arg = { 0, }; - - GITypeTag type_tag = g_type_info_get_tag (type_info); - - /* For the long handling: long can be equivalent to - int32 or int64, depending on the architecture, but - gi doesn't tell us (and same for ulong) - */ - switch (type_tag) { - case GI_TYPE_TAG_BOOLEAN: - arg.v_boolean = g_value_get_boolean (value); - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_INT32: - if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG)) - arg.v_int = g_value_get_long (value); - else - arg.v_int = g_value_get_int (value); - break; - case GI_TYPE_TAG_INT64: - if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG)) - arg.v_int64 = g_value_get_long (value); - else - arg.v_int64 = g_value_get_int64 (value); - break; - case GI_TYPE_TAG_UINT8: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_UINT32: - if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG)) - arg.v_uint = g_value_get_ulong (value); - else - arg.v_uint = g_value_get_uint (value); - break; - case GI_TYPE_TAG_UINT64: - if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG)) - arg.v_uint64 = g_value_get_ulong (value); - else - arg.v_uint64 = g_value_get_uint64 (value); - break; - case GI_TYPE_TAG_UNICHAR: - arg.v_uint32 = g_value_get_schar (value); - break; - case GI_TYPE_TAG_FLOAT: - arg.v_float = g_value_get_float (value); - break; - case GI_TYPE_TAG_DOUBLE: - arg.v_double = g_value_get_double (value); - break; - case GI_TYPE_TAG_GTYPE: - arg.v_long = g_value_get_gtype (value); - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - arg.v_string = g_value_dup_string (value); - break; - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - arg.v_pointer = g_value_get_pointer (value); - break; - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_GHASH: - if (G_VALUE_HOLDS_BOXED (value)) - arg.v_pointer = g_value_get_boxed (value); - else - /* e. g. GSettings::change-event */ - arg.v_pointer = g_value_get_pointer (value); - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *info; - GIInfoType info_type; - - info = g_type_info_get_interface (type_info); - info_type = g_base_info_get_type (info); - - g_base_info_unref (info); - - switch (info_type) { - case GI_INFO_TYPE_FLAGS: - arg.v_uint = g_value_get_flags (value); - break; - case GI_INFO_TYPE_ENUM: - arg.v_int = g_value_get_enum (value); - break; - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_OBJECT: - if (G_VALUE_HOLDS_PARAM (value)) - arg.v_pointer = g_value_get_param (value); - else - arg.v_pointer = g_value_get_object (value); - break; - case GI_INFO_TYPE_BOXED: - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_UNION: - if (G_VALUE_HOLDS(value, G_TYPE_BOXED)) { - arg.v_pointer = g_value_get_boxed (value); - } else if (G_VALUE_HOLDS(value, G_TYPE_VARIANT)) { - arg.v_pointer = g_value_get_variant (value); - } else { - arg.v_pointer = g_value_get_pointer (value); - } - break; - default: - g_warning("Converting of type '%s' is not implemented", g_info_type_to_string(info_type)); - g_assert_not_reached(); - } - break; - } - case GI_TYPE_TAG_ERROR: - arg.v_pointer = g_value_get_boxed (value); - break; - case GI_TYPE_TAG_VOID: - arg.v_pointer = g_value_get_pointer (value); - break; - } - - return arg; -} - void _pygi_argument_release (GIArgument *arg, GITypeInfo *type_info, @@ -1981,6 +1858,5 @@ void _pygi_argument_init (void) { PyDateTime_IMPORT; - _pygobject_import(); } diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h index ed88214..d32bd99 100644 --- a/gi/pygi-argument.h +++ b/gi/pygi-argument.h @@ -63,9 +63,6 @@ PyObject* _pygi_argument_to_object (GIArgument *arg, GITypeInfo *type_info, GITransfer transfer); -GIArgument _pygi_argument_from_g_value(const GValue *value, - GITypeInfo *type_info); - void _pygi_argument_release (GIArgument *arg, GITypeInfo *type_info, GITransfer transfer, diff --git a/gi/pygi-array.c b/gi/pygi-array.c new file mode 100644 index 0000000..937c6b3 --- /dev/null +++ b/gi/pygi-array.c @@ -0,0 +1,909 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include + +#include "pygi-array.h" +#include "pygi-private.h" +#include "pygi-marshal-cleanup.h" + +/* Needed for _pygi_marshal_cleanup_from_py_interface_struct_gvalue hack */ +#include "pygi-struct-marshal.h" + +/* + * GArray to Python + */ + +static gboolean +gi_argument_from_py_ssize_t (GIArgument *arg_out, + Py_ssize_t size_in, + GITypeTag type_tag) +{ + switch (type_tag) { + case GI_TYPE_TAG_VOID: + case GI_TYPE_TAG_BOOLEAN: + goto unhandled_type; + + case GI_TYPE_TAG_INT8: + if (size_in >= G_MININT8 && size_in <= G_MAXINT8) { + arg_out->v_int8 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_UINT8: + if (size_in >= 0 && size_in <= G_MAXUINT8) { + arg_out->v_uint8 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_INT16: + if (size_in >= G_MININT16 && size_in <= G_MAXINT16) { + arg_out->v_int16 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_UINT16: + if (size_in >= 0 && size_in <= G_MAXUINT16) { + arg_out->v_uint16 = size_in; + return TRUE; + } else { + goto overflow; + } + + /* Ranges assume two's complement */ + case GI_TYPE_TAG_INT32: + if (size_in >= G_MININT32 && size_in <= G_MAXINT32) { + arg_out->v_int32 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_UINT32: + if (size_in >= 0 && size_in <= G_MAXUINT32) { + arg_out->v_uint32 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_INT64: + arg_out->v_int64 = size_in; + return TRUE; + + case GI_TYPE_TAG_UINT64: + if (size_in >= 0) { + arg_out->v_uint64 = size_in; + return TRUE; + } else { + goto overflow; + } + + case GI_TYPE_TAG_FLOAT: + case GI_TYPE_TAG_DOUBLE: + case GI_TYPE_TAG_GTYPE: + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + case GI_TYPE_TAG_ERROR: + case GI_TYPE_TAG_UNICHAR: + default: + goto unhandled_type; + } + + overflow: + PyErr_Format (PyExc_OverflowError, + "Unable to marshal C Py_ssize_t %zd to %s", + size_in, + g_type_tag_to_string (type_tag)); + return FALSE; + + unhandled_type: + PyErr_Format (PyExc_TypeError, + "Unable to marshal C Py_ssize_t %zd to %s", + size_in, + g_type_tag_to_string (type_tag)); + return FALSE; +} + +static gboolean +gi_argument_to_gsize (GIArgument *arg_in, + gsize *gsize_out, + GITypeTag type_tag) +{ + switch (type_tag) { + case GI_TYPE_TAG_INT8: + *gsize_out = arg_in->v_int8; + return TRUE; + case GI_TYPE_TAG_UINT8: + *gsize_out = arg_in->v_uint8; + return TRUE; + case GI_TYPE_TAG_INT16: + *gsize_out = arg_in->v_int16; + return TRUE; + case GI_TYPE_TAG_UINT16: + *gsize_out = arg_in->v_uint16; + return TRUE; + case GI_TYPE_TAG_INT32: + *gsize_out = arg_in->v_int32; + return TRUE; + case GI_TYPE_TAG_UINT32: + *gsize_out = arg_in->v_uint32; + return TRUE; + case GI_TYPE_TAG_INT64: + *gsize_out = arg_in->v_int64; + return TRUE; + case GI_TYPE_TAG_UINT64: + *gsize_out = arg_in->v_uint64; + return TRUE; + default: + PyErr_Format (PyExc_TypeError, + "Unable to marshal %s to gsize", + g_type_tag_to_string (type_tag)); + return FALSE; + } +} + +static gboolean +_pygi_marshal_from_py_array (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyGIMarshalFromPyFunc from_py_marshaller; + int i = 0; + int success_count = 0; + Py_ssize_t length; + gssize item_size; + gboolean is_ptr_array; + GArray *array_ = NULL; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache; + + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (!PySequence_Check (py_arg)) { + PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + length = PySequence_Length (py_arg); + if (length < 0) + return FALSE; + + if (array_cache->fixed_size >= 0 && + array_cache->fixed_size != length) { + PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd", + array_cache->fixed_size, length); + + return FALSE; + } + + item_size = array_cache->item_size; + is_ptr_array = (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY); + if (is_ptr_array) { + array_ = (GArray *)g_ptr_array_sized_new (length); + } else { + array_ = g_array_sized_new (array_cache->is_zero_terminated, + TRUE, + item_size, + length); + } + + if (array_ == NULL) { + PyErr_NoMemory (); + return FALSE; + } + + if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 && + PYGLIB_PyBytes_Check (py_arg)) { + memcpy(array_->data, PYGLIB_PyBytes_AsString (py_arg), length); + array_->len = length; + if (array_cache->is_zero_terminated) { + /* If array_ has been created with zero_termination, space for the + * terminator is properly allocated, so we're not off-by-one here. */ + array_->data[length] = '\0'; + } + goto array_success; + } + + from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; + for (i = 0, success_count = 0; i < length; i++) { + GIArgument item = {0}; + gpointer item_cleanup_data = NULL; + PyObject *py_item = PySequence_GetItem (py_arg, i); + if (py_item == NULL) + goto err; + + if (!from_py_marshaller ( state, + callable_cache, + sequence_cache->item_cache, + py_item, + &item, + &item_cleanup_data)) { + Py_DECREF (py_item); + goto err; + } + Py_DECREF (py_item); + + if (item_cleanup_data != NULL && item_cleanup_data != item.v_pointer) { + /* We only support one level of data discrepancy between an items + * data and its cleanup data. This is because we only track a single + * extra cleanup data pointer per-argument and cannot track the entire + * array of items differing data and cleanup_data. + * For example, this would fail if trying to marshal an array of + * callback closures marked with SCOPE call type where the cleanup data + * is different from the items v_pointer, likewise an array of arrays. + */ + PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to " + "the items data its cleanup data being different."); + goto err; + } + + /* FIXME: it is much more efficent to have seperate marshaller + * for ptr arrays than doing the evaluation + * and casting each loop iteration + */ + if (is_ptr_array) { + g_ptr_array_add((GPtrArray *)array_, item.v_pointer); + } else if (sequence_cache->item_cache->is_pointer) { + /* if the item is a pointer, simply copy the pointer */ + g_assert (item_size == sizeof (item.v_pointer)); + g_array_insert_val (array_, i, item); + } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) { + /* Special case handling of flat arrays of gvalue/boxed/struct */ + PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache; + GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info; + GIInfoType info_type = g_base_info_get_type (base_info); + + switch (info_type) { + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_STRUCT: + { + PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache; + PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup; + + if (g_type_is_a (item_iface_cache->g_type, G_TYPE_VALUE)) { + /* Special case GValue flat arrays to properly init and copy the contents. */ + GValue* dest = (GValue*) (array_->data + (i * item_size)); + if (item.v_pointer != NULL) { + memset (dest, 0, item_size); + g_value_init (dest, G_VALUE_TYPE ((GValue*) item.v_pointer)); + g_value_copy ((GValue*) item.v_pointer, dest); + } + /* Manually increment the length because we are manually setting the memory. */ + array_->len++; + + } else { + /* Handles flat arrays of boxed or struct types. */ + g_array_insert_vals (array_, i, item.v_pointer, 1); + } + + /* Cleanup any memory left by the per-item marshaler because + * _pygi_marshal_cleanup_from_py_array will not know about this + * due to "item" being a temporarily marshaled value done on the stack. + */ + if (from_py_cleanup) + from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE); + + break; + } + default: + g_array_insert_val (array_, i, item); + } + } else { + /* default value copy of a simple type */ + g_array_insert_val (array_, i, item); + } + + success_count++; + continue; +err: + if (sequence_cache->item_cache->from_py_cleanup != NULL) { + gsize j; + PyGIMarshalCleanupFunc cleanup_func = + sequence_cache->item_cache->from_py_cleanup; + + /* Only attempt per item cleanup on pointer items */ + if (sequence_cache->item_cache->is_pointer) { + for(j = 0; j < success_count; j++) { + PyObject *py_item = PySequence_GetItem (py_arg, j); + cleanup_func (state, + sequence_cache->item_cache, + py_item, + is_ptr_array ? + g_ptr_array_index ((GPtrArray *)array_, j) : + g_array_index (array_, gpointer, j), + TRUE); + Py_DECREF (py_item); + } + } + } + + if (is_ptr_array) + g_ptr_array_free ( ( GPtrArray *)array_, TRUE); + else + g_array_free (array_, TRUE); + _PyGI_ERROR_PREFIX ("Item %i: ", i); + return FALSE; + } + +array_success: + if (array_cache->len_arg_index >= 0) { + /* we have an child arg to handle */ + PyGIArgCache *child_cache = + _pygi_callable_cache_get_arg (callable_cache, array_cache->len_arg_index); + + if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) { + gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer; + /* if we are not setup yet just set the in arg */ + if (len_arg == NULL) { + if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index], + length, + child_cache->type_tag)) { + goto err; + } + } else { + *len_arg = length; + } + } else { + if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index], + length, + child_cache->type_tag)) { + goto err; + } + } + } + + if (array_cache->array_type == GI_ARRAY_TYPE_C) { + /* In the case of GI_ARRAY_C, we give the data directly as the argument + * but keep the array_ wrapper as cleanup data so we don't have to find + * it's length again. + */ + arg->v_pointer = array_->data; + + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) { + g_array_free (array_, FALSE); + *cleanup_data = NULL; + } else { + *cleanup_data = array_; + } + } else { + arg->v_pointer = array_; + + if (arg_cache->transfer == GI_TRANSFER_NOTHING) { + /* Free everything in cleanup. */ + *cleanup_data = array_; + } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { + /* Make a shallow copy so we can free the elements later in cleanup + * because it is possible invoke will free the list before our cleanup. */ + *cleanup_data = is_ptr_array ? + (gpointer)g_ptr_array_ref ((GPtrArray *)array_) : + (gpointer)g_array_ref (array_); + } else { /* GI_TRANSFER_EVERYTHING */ + /* No cleanup, everything is given to the callee. */ + *cleanup_data = NULL; + } + } + + return TRUE; +} + +static void +_pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + if (was_processed) { + GArray *array_ = NULL; + GPtrArray *ptr_array_ = NULL; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache; + + if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { + ptr_array_ = (GPtrArray *) data; + } else { + array_ = (GArray *) data; + } + + /* clean up items first */ + if (sequence_cache->item_cache->from_py_cleanup != NULL) { + gsize i; + guint len = (array_ != NULL) ? array_->len : ptr_array_->len; + PyGIMarshalCleanupFunc cleanup_func = + sequence_cache->item_cache->from_py_cleanup; + + for (i = 0; i < len; i++) { + gpointer item; + PyObject *py_item = NULL; + + /* case 1: GPtrArray */ + if (ptr_array_ != NULL) + item = g_ptr_array_index (ptr_array_, i); + /* case 2: C array or GArray with object pointers */ + else if (sequence_cache->item_cache->is_pointer) + item = g_array_index (array_, gpointer, i); + /* case 3: C array or GArray with simple types or structs */ + else { + item = array_->data + i * array_cache->item_size; + /* special-case hack: GValue array items do not get slice + * allocated in _pygi_marshal_from_py_array(), so we must + * not try to deallocate it as a slice and thus + * short-circuit cleanup_func. */ + if (cleanup_func == _pygi_marshal_cleanup_from_py_interface_struct_gvalue) { + g_value_unset ((GValue*) item); + continue; + } + } + + py_item = PySequence_GetItem (py_arg, i); + cleanup_func (state, sequence_cache->item_cache, py_item, item, TRUE); + Py_XDECREF (py_item); + } + } + + /* Only free the array when we didn't transfer ownership */ + if (array_cache->array_type == GI_ARRAY_TYPE_C) { + /* always free the GArray wrapper created in from_py marshaling and + * passed back as cleanup_data + */ + g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING); + } else { + if (array_ != NULL) + g_array_unref (array_); + else + g_ptr_array_unref (ptr_array_); + } + } +} + +/* + * GArray from Python + */ +static PyObject * +_pygi_marshal_to_py_array (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + GArray *array_; + PyObject *py_obj = NULL; + PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; + PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache; + gsize processed_items = 0; + + /* GArrays make it easier to iterate over arrays + * with different element sizes but requires that + * we allocate a GArray if the argument was a C array + */ + if (array_cache->array_type == GI_ARRAY_TYPE_C) { + gsize len; + if (array_cache->fixed_size >= 0) { + g_assert(arg->v_pointer != NULL); + len = array_cache->fixed_size; + } else if (array_cache->is_zero_terminated) { + if (arg->v_pointer == NULL) { + len = 0; + } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) { + len = strlen (arg->v_pointer); + } else { + len = g_strv_length ((gchar **)arg->v_pointer); + } + } else { + GIArgument *len_arg = state->args[array_cache->len_arg_index]; + PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache, + array_cache->len_arg_index); + + if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) { + return NULL; + } + } + + array_ = g_array_new (FALSE, + FALSE, + array_cache->item_size); + if (array_ == NULL) { + PyErr_NoMemory (); + + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL) + g_free (arg->v_pointer); + + return NULL; + } + + if (array_->data != NULL) + g_free (array_->data); + array_->data = arg->v_pointer; + array_->len = len; + } else { + array_ = arg->v_pointer; + } + + if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) { + if (arg->v_pointer == NULL) { + py_obj = PYGLIB_PyBytes_FromString (""); + } else { + py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len); + } + } else { + if (arg->v_pointer == NULL) { + py_obj = PyList_New (0); + } else { + int i; + + gsize item_size; + PyGIMarshalToPyFunc item_to_py_marshaller; + PyGIArgCache *item_arg_cache; + + py_obj = PyList_New (array_->len); + if (py_obj == NULL) + goto err; + + + item_arg_cache = seq_cache->item_cache; + item_to_py_marshaller = item_arg_cache->to_py_marshaller; + + item_size = g_array_get_element_size (array_); + + for (i = 0; i < array_->len; i++) { + GIArgument item_arg = {0}; + PyObject *py_item; + + /* If we are receiving an array of pointers, simply assign the pointer + * and move on, letting the per-item marshaler deal with the + * various transfer modes and ref counts (e.g. g_variant_ref_sink). + */ + if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { + item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i); + + } else if (item_arg_cache->is_pointer) { + item_arg.v_pointer = g_array_index (array_, gpointer, i); + + } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) { + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache; + + // FIXME: This probably doesn't work with boxed types or gvalues. See fx. _pygi_marshal_from_py_array() + switch (g_base_info_get_type (iface_cache->interface_info)) { + case GI_INFO_TYPE_STRUCT: + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && + !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) { + /* 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 { + item_arg.v_pointer = array_->data + i * item_size; + } + break; + default: + item_arg.v_pointer = g_array_index (array_, gpointer, i); + break; + } + } else { + memcpy (&item_arg, array_->data + i * item_size, item_size); + } + + py_item = item_to_py_marshaller ( state, + callable_cache, + item_arg_cache, + &item_arg); + + if (py_item == NULL) { + Py_CLEAR (py_obj); + + if (array_cache->array_type == GI_ARRAY_TYPE_C) + g_array_unref (array_); + + goto err; + } + PyList_SET_ITEM (py_obj, i, py_item); + processed_items++; + } + } + } + + if (array_cache->array_type == GI_ARRAY_TYPE_C) + g_array_free (array_, FALSE); + + return py_obj; + +err: + if (array_cache->array_type == GI_ARRAY_TYPE_C) { + g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING); + } else { + /* clean up unprocessed items */ + if (seq_cache->item_cache->to_py_cleanup != NULL) { + int j; + PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup; + for (j = processed_items; j < array_->len; j++) { + cleanup_func (state, + seq_cache->item_cache, + NULL, + g_array_index (array_, gpointer, j), + FALSE); + } + } + + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) + g_array_free (array_, TRUE); + } + + return NULL; +} + +static GArray* +_wrap_c_array (PyGIInvokeState *state, + PyGIArgGArray *array_cache, + gpointer data) +{ + GArray *array_; + gsize len = 0; + + if (array_cache->fixed_size >= 0) { + len = array_cache->fixed_size; + } else if (array_cache->is_zero_terminated) { + len = g_strv_length ((gchar **)data); + } else if (array_cache->len_arg_index >= 0) { + GIArgument *len_arg = state->args[array_cache->len_arg_index]; + len = len_arg->v_long; + } + + array_ = g_array_new (FALSE, + FALSE, + array_cache->item_size); + + if (array_ == NULL) + return NULL; + + g_free (array_->data); + array_->data = data; + array_->len = len; + + return array_; +} + +static void +_pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || + arg_cache->transfer == GI_TRANSFER_CONTAINER) { + GArray *array_ = NULL; + GPtrArray *ptr_array_ = NULL; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache; + + /* If this isn't a garray create one to help process variable sized + array elements */ + if (array_cache->array_type == GI_ARRAY_TYPE_C) { + array_ = _wrap_c_array (state, array_cache, data); + + if (array_ == NULL) + return; + + } else if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { + ptr_array_ = (GPtrArray *) data; + } else { + array_ = (GArray *) data; + } + + if (sequence_cache->item_cache->to_py_cleanup != NULL) { + gsize i; + guint len = (array_ != NULL) ? array_->len : ptr_array_->len; + + PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup; + for (i = 0; i < len; i++) { + cleanup_func (state, + sequence_cache->item_cache, + NULL, + (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i), + was_processed); + } + } + + if (array_ != NULL) + g_array_free (array_, TRUE); + else + g_ptr_array_free (ptr_array_, TRUE); + } +} + +static void +_array_cache_free_func (PyGIArgGArray *cache) +{ + if (cache != NULL) { + pygi_arg_cache_free (((PyGISequenceCache *)cache)->item_cache); + g_slice_free (PyGIArgGArray, cache); + } +} + +PyGIArgCache* +pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + PyGICallableCache *callable_cache, + PyGIDirection direction, + gssize arg_index, + gssize *py_arg_index) +{ + PyGIArgGArray *seq_cache = (PyGIArgGArray *)arg_cache; + + /* attempt len_arg_index setup for the first time */ + if (seq_cache->len_arg_index < 0) { + seq_cache->len_arg_index = g_type_info_get_array_length (type_info); + + /* offset by self arg for methods and vfuncs */ + if (seq_cache->len_arg_index >= 0 && callable_cache != NULL && + (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD || + callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC)) { + seq_cache->len_arg_index += 1; + } + } + + if (seq_cache->len_arg_index >= 0) { + PyGIArgCache *child_cache = NULL; + + child_cache = _pygi_callable_cache_get_arg (callable_cache, + seq_cache->len_arg_index); + if (child_cache == NULL) { + child_cache = pygi_arg_cache_alloc (); + } else { + /* If the "length" arg cache already exists (the length comes before + * the array in the argument list), remove it from the to_py_args list + * because it does not belong in "to python" return tuple. The length + * will implicitly be a part of the returned Python list. + */ + if (direction & PYGI_DIRECTION_TO_PYTHON) { + callable_cache->to_py_args = + g_slist_remove (callable_cache->to_py_args, child_cache); + } + + /* This is a case where the arg cache already exists and has been + * setup by another array argument sharing the same length argument. + * See: gi_marshalling_tests_multi_array_key_value_in + */ + if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD) + return child_cache; + } + + /* There is a length argument for this array, so increment the number + * of "to python" child arguments when applicable. + */ + if (direction & PYGI_DIRECTION_TO_PYTHON) + callable_cache->n_to_py_child_args++; + + child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; + child_cache->direction = direction; + child_cache->to_py_marshaller = NULL; + child_cache->from_py_marshaller = NULL; + + /* ugly edge case code: + * + * When the length comes before the array parameter we need to update + * indexes of arguments after the index argument. + */ + if (seq_cache->len_arg_index < arg_index && direction & PYGI_DIRECTION_FROM_PYTHON) { + gssize i; + (*py_arg_index) -= 1; + callable_cache->n_py_args -= 1; + + for (i = seq_cache->len_arg_index + 1; + i < _pygi_callable_cache_args_len (callable_cache); i++) { + PyGIArgCache *update_cache = _pygi_callable_cache_get_arg (callable_cache, i); + if (update_cache == NULL) + break; + + update_cache->py_arg_index -= 1; + } + } + + _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache); + return child_cache; + } + + return NULL; +} + +static gboolean +pygi_arg_garray_setup (PyGIArgGArray *sc, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction) +{ + GITypeInfo *item_type_info; + PyGIArgCache *arg_cache = (PyGIArgCache *)sc; + + if (!pygi_arg_sequence_setup ((PyGISequenceCache *)sc, + type_info, + arg_info, + transfer, + direction)) { + return FALSE; + } + + ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_array_cache_free_func; + sc->array_type = g_type_info_get_array_type (type_info); + sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info); + sc->fixed_size = g_type_info_get_array_fixed_size (type_info); + sc->len_arg_index = -1; /* setup by pygi_arg_garray_len_arg_setup */ + + item_type_info = g_type_info_get_param_type (type_info, 0); + sc->item_size = _pygi_g_type_info_size (item_type_info); + g_base_info_unref ( (GIBaseInfo *)item_type_info); + + if (direction & PYGI_DIRECTION_FROM_PYTHON) { + arg_cache->from_py_marshaller = _pygi_marshal_from_py_array; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array; + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + arg_cache->to_py_marshaller = _pygi_marshal_to_py_array; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array; + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_garray_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + PyGIArgGArray *array_cache = g_slice_new0 (PyGIArgGArray); + if (array_cache == NULL) + return NULL; + + if (!pygi_arg_garray_setup (array_cache, + type_info, + arg_info, + transfer, + direction)) { + pygi_arg_cache_free ( (PyGIArgCache *)array_cache); + return NULL; + } + + return (PyGIArgCache *)array_cache; +} diff --git a/gi/pygi-array.h b/gi/pygi-array.h new file mode 100644 index 0000000..4792ca1 --- /dev/null +++ b/gi/pygi-array.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_ARRAY_H__ +#define __PYGI_ARRAY_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_garray_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction); + +PyGIArgCache *pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + PyGICallableCache *callable_cache, + PyGIDirection direction, + gssize arg_index, + gssize *py_arg_index); + +G_END_DECLS + +#endif /*__PYGI_ARRAY_H__*/ diff --git a/gi/pygi-basictype.c b/gi/pygi-basictype.c new file mode 100644 index 0000000..6fbe929 --- /dev/null +++ b/gi/pygi-basictype.c @@ -0,0 +1,824 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include + +#include "pygi-basictype.h" +#include "pygi-argument.h" +#include "pygi-private.h" + + +/* + * From Python Marshaling + */ + +static gboolean +_pygi_marshal_from_py_void (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING); + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + } else if (PYGLIB_CPointer_Check(py_arg)) { + arg->v_pointer = PYGLIB_CPointer_GetPointer (py_arg, NULL); + } else if (PYGLIB_PyLong_Check(py_arg) || PyLong_Check(py_arg)) { + arg->v_pointer = PyLong_AsVoidPtr (py_arg); + } else { + PyErr_SetString(PyExc_ValueError, + "Pointer arguments are restricted to integers, capsules, and None. " + "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); + return FALSE; + } + + *cleanup_data = arg->v_pointer; + return TRUE; +} + +static gboolean +check_valid_double (double x, double min, double max) +{ + char buf[100]; + + if ((x < min || x > max) && x != INFINITY && x != -INFINITY && x != NAN) { + if (PyErr_Occurred()) + PyErr_Clear (); + + /* we need this as PyErr_Format() does not support float types */ + snprintf (buf, sizeof (buf), "%g not in range %g to %g", x, min, max); + PyErr_SetString (PyExc_OverflowError, buf); + return FALSE; + } + return TRUE; +} + +static gboolean +_pygi_py_arg_to_double (PyObject *py_arg, double *double_) +{ + PyObject *py_float; + + if (!PyNumber_Check (py_arg)) { + PyErr_Format (PyExc_TypeError, "Must be number, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + py_float = PyNumber_Float (py_arg); + if (!py_float) + return FALSE; + + *double_ = PyFloat_AsDouble (py_float); + Py_DECREF (py_float); + + + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_float (PyObject *py_arg, + GIArgument *arg) +{ + double double_; + + if (!_pygi_py_arg_to_double (py_arg, &double_)) + return FALSE; + + if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXFLOAT, G_MAXFLOAT)) + return FALSE; + + arg->v_float = double_; + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_double (PyObject *py_arg, + GIArgument *arg) +{ + double double_; + + if (!_pygi_py_arg_to_double (py_arg, &double_)) + return FALSE; + + if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXDOUBLE, G_MAXDOUBLE)) + return FALSE; + + arg->v_double = double_; + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_unichar (PyObject *py_arg, + GIArgument *arg) +{ + Py_ssize_t size; + gchar *string_; + + if (py_arg == Py_None) { + arg->v_uint32 = 0; + return FALSE; + } + + if (PyUnicode_Check (py_arg)) { + PyObject *py_bytes; + + size = PyUnicode_GET_SIZE (py_arg); + py_bytes = PyUnicode_AsUTF8String (py_arg); + if (!py_bytes) + return FALSE; + + string_ = g_strdup(PYGLIB_PyBytes_AsString (py_bytes)); + Py_DECREF (py_bytes); + +#if PY_VERSION_HEX < 0x03000000 + } else if (PyString_Check (py_arg)) { + PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict"); + if (!pyuni) + return FALSE; + + size = PyUnicode_GET_SIZE (pyuni); + string_ = g_strdup (PyString_AsString(py_arg)); + Py_DECREF (pyuni); +#endif + } else { + PyErr_Format (PyExc_TypeError, "Must be string, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + if (size != 1) { + PyErr_Format (PyExc_TypeError, "Must be a one character string, not %lld characters", + (long long) size); + g_free (string_); + return FALSE; + } + + arg->v_uint32 = g_utf8_get_char (string_); + g_free (string_); + + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_gtype (PyObject *py_arg, + GIArgument *arg) +{ + long type_ = pyg_type_from_object (py_arg); + + if (type_ == 0) { + PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + arg->v_long = type_; + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_utf8 (PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + gchar *string_; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (PyUnicode_Check (py_arg)) { + PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg); + if (!pystr_obj) + return FALSE; + + string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj)); + Py_DECREF (pystr_obj); + } +#if PY_VERSION_HEX < 0x03000000 + else if (PyString_Check (py_arg)) { + string_ = g_strdup (PyString_AsString (py_arg)); + } +#endif + else { + PyErr_Format (PyExc_TypeError, "Must be string, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + arg->v_string = string_; + *cleanup_data = arg->v_string; + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_filename (PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + gchar *string_; + GError *error = NULL; + + if (PyUnicode_Check (py_arg)) { + PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg); + if (!pystr_obj) + return FALSE; + + string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj)); + Py_DECREF (pystr_obj); + } +#if PY_VERSION_HEX < 0x03000000 + else if (PyString_Check (py_arg)) { + string_ = g_strdup (PyString_AsString (py_arg)); + } +#endif + else { + PyErr_Format (PyExc_TypeError, "Must be string, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error); + g_free (string_); + + if (arg->v_string == NULL) { + PyErr_SetString (PyExc_Exception, error->message); + g_error_free (error); + /* TODO: Convert the error to an exception. */ + return FALSE; + } + + *cleanup_data = arg->v_string; + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_long (PyObject *object, /* in */ + GIArgument *arg, /* out */ + GITypeTag type_tag, + GITransfer transfer) +{ + PyObject *number; + + if (!PyNumber_Check (object)) { + PyErr_Format (PyExc_TypeError, "Must be number, not %s", + object->ob_type->tp_name); + return FALSE; + } + +#if PY_MAJOR_VERSION < 3 + { + PyObject *tmp = PyNumber_Int (object); + if (tmp) { + number = PyNumber_Long (tmp); + Py_DECREF (tmp); + } else { + number = PyNumber_Long (object); + } + } +#else + number = PyNumber_Long (object); +#endif + + if (number == NULL) { + PyErr_SetString (PyExc_TypeError, "expected int argument"); + return FALSE; + } + + switch (type_tag) { + case GI_TYPE_TAG_INT8: + { + long long_value = PyLong_AsLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < G_MININT8 || long_value > G_MAXINT8) { + PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", + long_value, (long)G_MININT8, (long)G_MAXINT8); + } else { + arg->v_int8 = long_value; + } + break; + } + + case GI_TYPE_TAG_UINT8: + { + long long_value = PyLong_AsLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < 0 || long_value > G_MAXUINT8) { + PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", + long_value, (long)0, (long)G_MAXUINT8); + } else { + arg->v_uint8 = long_value; + } + break; + } + + case GI_TYPE_TAG_INT16: + { + long long_value = PyLong_AsLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < G_MININT16 || long_value > G_MAXINT16) { + PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", + long_value, (long)G_MININT16, (long)G_MAXINT16); + } else { + arg->v_int16 = long_value; + } + break; + } + + case GI_TYPE_TAG_UINT16: + { + long long_value = PyLong_AsLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < 0 || long_value > G_MAXUINT16) { + PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", + long_value, (long)0, (long)G_MAXUINT16); + } else { + arg->v_uint16 = long_value; + } + break; + } + + case GI_TYPE_TAG_INT32: + { + long long_value = PyLong_AsLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < G_MININT32 || long_value > G_MAXINT32) { + PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", + long_value, (long)G_MININT32, (long)G_MAXINT32); + } else { + arg->v_int32 = long_value; + } + break; + } + + case GI_TYPE_TAG_UINT32: + { + PY_LONG_LONG long_value = PyLong_AsLongLong (number); + if (PyErr_Occurred()) { + break; + } else if (long_value < 0 || long_value > G_MAXUINT32) { + PyErr_Format (PyExc_OverflowError, "%lld not in range %ld to %lu", + long_value, (long)0, (unsigned long)G_MAXUINT32); + } else { + arg->v_uint32 = long_value; + } + break; + } + + case GI_TYPE_TAG_INT64: + { + /* Rely on Python overflow error and convert to ValueError for 64 bit values */ + arg->v_int64 = PyLong_AsLongLong (number); + break; + } + + case GI_TYPE_TAG_UINT64: + { + /* Rely on Python overflow error and convert to ValueError for 64 bit values */ + arg->v_uint64 = PyLong_AsUnsignedLongLong (number); + break; + } + + default: + g_assert_not_reached (); + } + + Py_DECREF (number); + + if (PyErr_Occurred()) + return FALSE; + return TRUE; +} + +gboolean +_pygi_marshal_from_py_basic_type (PyObject *object, /* in */ + GIArgument *arg, /* out */ + GITypeTag type_tag, + GITransfer transfer, + gpointer *cleanup_data /* out */) +{ + switch (type_tag) { + case GI_TYPE_TAG_VOID: + g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); + if (object == Py_None) { + arg->v_pointer = NULL; + } else if (!PYGLIB_PyLong_Check(object) && !PyLong_Check(object)) { + PyErr_SetString(PyExc_TypeError, + "Pointer assignment is restricted to integer values. " + "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); + } else { + arg->v_pointer = PyLong_AsVoidPtr (object); + *cleanup_data = arg->v_pointer; + } + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + if (PYGLIB_PyBytes_Check (object)) { + if (PYGLIB_PyBytes_Size (object) != 1) { + PyErr_Format (PyExc_TypeError, "Must be a single character"); + return FALSE; + } + if (type_tag == GI_TYPE_TAG_INT8) { + arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]); + } else { + arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]); + } + } else { + return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); + } + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); + + case GI_TYPE_TAG_BOOLEAN: + arg->v_boolean = PyObject_IsTrue (object); + break; + + case GI_TYPE_TAG_FLOAT: + return _pygi_marshal_from_py_float (object, arg); + + case GI_TYPE_TAG_DOUBLE: + return _pygi_marshal_from_py_double (object, arg); + + case GI_TYPE_TAG_GTYPE: + return _pygi_marshal_from_py_gtype (object, arg); + + case GI_TYPE_TAG_UNICHAR: + return _pygi_marshal_from_py_unichar (object, arg); + + case GI_TYPE_TAG_UTF8: + return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data); + + case GI_TYPE_TAG_FILENAME: + return _pygi_marshal_from_py_filename (object, arg, cleanup_data); + + default: + return FALSE; + } + + if (PyErr_Occurred()) + return FALSE; + + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + return _pygi_marshal_from_py_basic_type (py_arg, + arg, + arg_cache->type_tag, + arg_cache->transfer, + cleanup_data); +} + +static void +_pygi_marshal_cleanup_from_py_utf8 (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + /* We strdup strings so free unless ownership is transferred to C. */ + if (was_processed && arg_cache->transfer == GI_TRANSFER_NOTHING) + g_free (data); +} + +static void +_arg_cache_from_py_void_setup (PyGIArgCache *arg_cache) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_void; +} + + +static void +_arg_cache_from_py_basic_type_setup (PyGIArgCache *arg_cache) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter; +} + +static void +_arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8; +} + + +/* + * To Python Marshaling + */ + + +static PyObject * +_pygi_marshal_to_py_void (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + if (arg_cache->is_pointer) { + return PyLong_FromVoidPtr (arg->v_pointer); + } + Py_RETURN_NONE; +} + +static PyObject * +_pygi_marshal_to_py_unichar (GIArgument *arg) +{ + PyObject *py_obj = NULL; + + /* Preserve the bidirectional mapping between 0 and "" */ + if (arg->v_uint32 == 0) { + py_obj = PYGLIB_PyUnicode_FromString (""); + } else if (g_unichar_validate (arg->v_uint32)) { + gchar utf8[6]; + gint bytes; + + bytes = g_unichar_to_utf8 (arg->v_uint32, utf8); + py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes); + } else { + /* TODO: Convert the error to an exception. */ + PyErr_Format (PyExc_TypeError, + "Invalid unicode codepoint %" G_GUINT32_FORMAT, + arg->v_uint32); + } + + return py_obj; +} + +static PyObject * +_pygi_marshal_to_py_utf8 (GIArgument *arg) +{ + PyObject *py_obj = NULL; + if (arg->v_string == NULL) { + Py_RETURN_NONE; + } + + py_obj = PYGLIB_PyUnicode_FromString (arg->v_string); + return py_obj; +} + +static PyObject * +_pygi_marshal_to_py_filename (GIArgument *arg) +{ + gchar *string = NULL; + PyObject *py_obj = NULL; + GError *error = NULL; + + if (arg->v_string == NULL) { + Py_RETURN_NONE; + } + + string = g_filename_to_utf8 (arg->v_string, -1, NULL, NULL, &error); + if (string == NULL) { + PyErr_SetString (PyExc_Exception, error->message); + /* TODO: Convert the error to an exception. */ + return NULL; + } + + py_obj = PYGLIB_PyUnicode_FromString (string); + g_free (string); + + return py_obj; +} + + +/** + * _pygi_marshal_to_py_basic_type: + * @arg: The argument to convert to an object. + * @type_tag: Type tag for @arg + * @transfer: Transfer annotation + * + * Convert the given argument to a Python object. This function + * is restricted to simple types that only require the GITypeTag + * and GITransfer. For a more complete conversion routine, use: + * _pygi_argument_to_object. + * + * Returns: A PyObject representing @arg or NULL if it cannot convert + * the argument. + */ +PyObject * +_pygi_marshal_to_py_basic_type (GIArgument *arg, + GITypeTag type_tag, + GITransfer transfer) +{ + switch (type_tag) { + case GI_TYPE_TAG_BOOLEAN: + return PyBool_FromLong (arg->v_boolean); + + case GI_TYPE_TAG_INT8: + return PYGLIB_PyLong_FromLong (arg->v_int8); + + case GI_TYPE_TAG_UINT8: + return PYGLIB_PyLong_FromLong (arg->v_uint8); + + case GI_TYPE_TAG_INT16: + return PYGLIB_PyLong_FromLong (arg->v_int16); + + case GI_TYPE_TAG_UINT16: + return PYGLIB_PyLong_FromLong (arg->v_uint16); + + case GI_TYPE_TAG_INT32: + return PYGLIB_PyLong_FromLong (arg->v_int32); + + case GI_TYPE_TAG_UINT32: + return PyLong_FromLongLong (arg->v_uint32); + + case GI_TYPE_TAG_INT64: + return PyLong_FromLongLong (arg->v_int64); + + case GI_TYPE_TAG_UINT64: + return PyLong_FromUnsignedLongLong (arg->v_uint64); + + case GI_TYPE_TAG_FLOAT: + return PyFloat_FromDouble (arg->v_float); + + case GI_TYPE_TAG_DOUBLE: + return PyFloat_FromDouble (arg->v_double); + + case GI_TYPE_TAG_GTYPE: + return pyg_type_wrapper_new ( (GType) arg->v_long); + + case GI_TYPE_TAG_UNICHAR: + return _pygi_marshal_to_py_unichar (arg); + + case GI_TYPE_TAG_UTF8: + return _pygi_marshal_to_py_utf8 (arg); + + case GI_TYPE_TAG_FILENAME: + return _pygi_marshal_to_py_filename (arg); + + default: + return NULL; + } + return NULL; +} + +static PyObject * +_pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + return _pygi_marshal_to_py_basic_type (arg, + arg_cache->type_tag, + arg_cache->transfer); +} + +static void +_pygi_marshal_cleanup_to_py_utf8 (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + /* Python copies the string so we need to free it + if the interface is transfering ownership, + whether or not it has been processed yet */ + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) + g_free (data); +} + + + +static void +_arg_cache_to_py_basic_type_setup (PyGIArgCache *arg_cache) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter; +} + +static void +_arg_cache_to_py_void_setup (PyGIArgCache *arg_cache) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_void; +} + +static void +_arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8; +} + +/* + * Basic Type Interface + */ + +static gboolean +pygi_arg_basic_type_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + GITypeTag type_tag = g_type_info_get_tag (type_info); + + if (!pygi_arg_base_setup (arg_cache, type_info, arg_info, transfer, direction)) + return FALSE; + + switch (type_tag) { + case GI_TYPE_TAG_VOID: + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_void_setup (arg_cache); + + if (direction & PYGI_DIRECTION_TO_PYTHON) + _arg_cache_to_py_void_setup (arg_cache); + + break; + case GI_TYPE_TAG_BOOLEAN: + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + case GI_TYPE_TAG_FLOAT: + case GI_TYPE_TAG_DOUBLE: + case GI_TYPE_TAG_UNICHAR: + case GI_TYPE_TAG_GTYPE: + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_basic_type_setup (arg_cache); + + if (direction & PYGI_DIRECTION_TO_PYTHON) + _arg_cache_to_py_basic_type_setup (arg_cache); + + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_utf8_setup (arg_cache, transfer); + + if (direction & PYGI_DIRECTION_TO_PYTHON) + _arg_cache_to_py_utf8_setup (arg_cache, transfer); + + break; + default: + g_assert_not_reached (); + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_basic_type_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + gboolean res = FALSE; + PyGIArgCache *arg_cache = pygi_arg_cache_alloc (); + if (arg_cache == NULL) + return NULL; + + res = pygi_arg_basic_type_setup_from_info (arg_cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return arg_cache; + } else { + pygi_arg_cache_free (arg_cache); + return NULL; + } +} diff --git a/gi/pygi-basictype.h b/gi/pygi-basictype.h new file mode 100644 index 0000000..7207e54 --- /dev/null +++ b/gi/pygi-basictype.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_ARG_BASICTYPE_H__ +#define __PYGI_ARG_BASICTYPE_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +gboolean _pygi_marshal_from_py_basic_type (PyObject *object, /* in */ + GIArgument *arg, /* out */ + GITypeTag type_tag, + GITransfer transfer, + gpointer *cleanup_data); +PyObject *_pygi_marshal_to_py_basic_type (GIArgument *arg, /* in */ + GITypeTag type_tag, + GITransfer transfer); +PyGIArgCache *pygi_arg_basic_type_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction); +G_END_DECLS + +#endif /*__PYGI_ARG_BASICTYPE_H__*/ diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c index ea798ff..a9b39c1 100644 --- a/gi/pygi-boxed.c +++ b/gi/pygi-boxed.c @@ -22,8 +22,8 @@ */ #include "pygi-private.h" +#include "pygobject-private.h" -#include #include #include diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c index 14d69b1..8055c15 100644 --- a/gi/pygi-cache.c +++ b/gi/pygi-cache.c @@ -2,6 +2,7 @@ * vim: tabstop=4 shiftwidth=4 expandtab * * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2013 Simon Feltman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,90 +20,106 @@ * USA */ +#include + #include "pygi-info.h" #include "pygi-cache.h" -#include "pygi-marshal-to-py.h" -#include "pygi-marshal-from-py.h" #include "pygi-marshal-cleanup.h" #include "pygi-type.h" -#include +#include "pygi-hashtable.h" +#include "pygi-basictype.h" +#include "pygi-list.h" +#include "pygi-array.h" +#include "pygi-closure.h" +#include "pygi-error.h" +#include "pygi-object.h" +#include "pygi-struct-marshal.h" +#include "pygi-enum-marshal.h" -PyGIArgCache * _arg_cache_new (GITypeInfo *type_info, - PyGICallableCache *callable_cache, - GIArgInfo *arg_info, - GITransfer transfer, - PyGIDirection direction, - gssize c_arg_index, - gssize py_arg_index); - -PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info, - PyGICallableCache *callable_cache, - GIArgInfo *arg_info, - GITransfer transfer, - PyGIDirection direction, - gssize c_arg_index, - gssize py_arg_index); - -/* cleanup */ -static void -_pygi_arg_cache_free (PyGIArgCache *cache) -{ - if (cache == NULL) - return; - if (cache->type_info != NULL) - g_base_info_unref ( (GIBaseInfo *)cache->type_info); - if (cache->destroy_notify) - cache->destroy_notify (cache); - else - g_slice_free (PyGIArgCache, cache); -} - -static void -_interface_cache_free_func (PyGIInterfaceCache *cache) +/* _arg_info_default_value + * info: + * arg: (out): GIArgument to fill in with default value. + * + * This is currently a place holder API which only supports "allow-none" pointer args. + * Once defaults are part of the GI API, we can replace this with: g_arg_info_default_value + * https://bugzilla.gnome.org/show_bug.cgi?id=558620 + * + * Returns: TRUE if the given argument supports a default value and was filled in. + */ +static gboolean +_arg_info_default_value (GIArgInfo *info, GIArgument *arg) { - if (cache != NULL) { - Py_XDECREF (cache->py_type); - if (cache->type_name != NULL) - g_free (cache->type_name); - if (cache->interface_info != NULL) - g_base_info_unref ( (GIBaseInfo *)cache->interface_info); - g_slice_free (PyGIInterfaceCache, cache); + if (g_arg_info_may_be_null (info)) { + arg->v_pointer = NULL; + return TRUE; } + return FALSE; } -static void -_hash_cache_free_func (PyGIHashCache *cache) -{ - if (cache != NULL) { - _pygi_arg_cache_free (cache->key_cache); - _pygi_arg_cache_free (cache->value_cache); - g_slice_free (PyGIHashCache, cache); +/* pygi_arg_base_setup: + * arg_cache: argument cache to initialize + * type_info: source for type related attributes to cache + * arg_info: (allow-none): source for argument related attributes to cache + * transfer: transfer mode to store in the argument cache + * direction: marshaling direction to store in the cache + * + * Initializer for PyGIArgCache + * + * Returns: TRUE on success and FALSE on failure + */ +gboolean +pygi_arg_base_setup (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction) +{ + arg_cache->direction = direction; + arg_cache->transfer = transfer; + arg_cache->py_arg_index = -1; + arg_cache->c_arg_index = -1; + + if (type_info != NULL) { + arg_cache->is_pointer = g_type_info_is_pointer (type_info); + arg_cache->type_tag = g_type_info_get_tag (type_info); + g_base_info_ref ( (GIBaseInfo *) type_info); + arg_cache->type_info = type_info; } -} -static void -_sequence_cache_free_func (PyGISequenceCache *cache) -{ - if (cache != NULL) { - _pygi_arg_cache_free (cache->item_cache); - g_slice_free (PyGISequenceCache, cache); + if (arg_info != NULL) { + if (!arg_cache->has_default) { + /* It is possible has_default was set somewhere else */ + arg_cache->has_default = _arg_info_default_value (arg_info, + &arg_cache->default_value); + } + arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info); + arg_cache->allow_none = g_arg_info_may_be_null (arg_info); + + if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE || arg_cache->type_tag == GI_TYPE_TAG_ARRAY) + arg_cache->is_caller_allocates = g_arg_info_is_caller_allocates (arg_info); + else + arg_cache->is_caller_allocates = FALSE; } + return TRUE; } -static void -_callback_cache_free_func (PyGICallbackCache *cache) +void +pygi_arg_cache_free (PyGIArgCache *cache) { - if (cache != NULL) { - if (cache->interface_info != NULL) - g_base_info_unref ( (GIBaseInfo *)cache->interface_info); + if (cache == NULL) + return; - g_slice_free (PyGICallbackCache, cache); - } + if (cache->type_info != NULL) + g_base_info_unref ( (GIBaseInfo *)cache->type_info); + if (cache->destroy_notify) + cache->destroy_notify (cache); + else + g_slice_free (PyGIArgCache, cache); } void -_pygi_callable_cache_free (PyGICallableCache *cache) +pygi_callable_cache_free (PyGICallableCache *cache) { if (cache == NULL) return; @@ -113,639 +130,233 @@ _pygi_callable_cache_free (PyGICallableCache *cache) g_ptr_array_unref (cache->args_cache); if (cache->return_cache != NULL) - _pygi_arg_cache_free (cache->return_cache); + pygi_arg_cache_free (cache->return_cache); g_slice_free (PyGICallableCache, cache); } -/* cache generation */ -static PyGIInterfaceCache * -_interface_cache_new (GIInterfaceInfo *iface_info) -{ - PyGIInterfaceCache *ic; - - ic = g_slice_new0 (PyGIInterfaceCache); - ( (PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func; - ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info); - ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info); - - if (ic->py_type == NULL) - return NULL; - - ic->type_name = _pygi_g_base_info_get_fullname (iface_info); - return ic; -} +/* PyGIInterfaceCache */ -static PyGISequenceCache * -_sequence_cache_new (GITypeInfo *type_info, - GIDirection direction, - GITransfer transfer, - gssize child_offset) +static void +_interface_cache_free_func (PyGIInterfaceCache *cache) { - PyGISequenceCache *sc; - GITypeInfo *item_type_info; - GITransfer item_transfer; - - sc = g_slice_new0 (PyGISequenceCache); - ( (PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func; - - sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info); - sc->fixed_size = g_type_info_get_array_fixed_size (type_info); - sc->len_arg_index = g_type_info_get_array_length (type_info); - if (sc->len_arg_index >= 0) - sc->len_arg_index += child_offset; - - item_type_info = g_type_info_get_param_type (type_info, 0); - - item_transfer = - transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer; - - sc->item_cache = _arg_cache_new (item_type_info, - NULL, - NULL, - item_transfer, - direction, - 0, 0); - - if (sc->item_cache == NULL) { - _pygi_arg_cache_free ( (PyGIArgCache *)sc); - return NULL; + if (cache != NULL) { + Py_XDECREF (cache->py_type); + if (cache->type_name != NULL) + g_free (cache->type_name); + if (cache->interface_info != NULL) + g_base_info_unref ( (GIBaseInfo *)cache->interface_info); + g_slice_free (PyGIInterfaceCache, cache); } - - sc->item_size = _pygi_g_type_info_size (item_type_info); - g_base_info_unref ( (GIBaseInfo *)item_type_info); - - return sc; } -static PyGIHashCache * -_hash_cache_new (GITypeInfo *type_info, - GIDirection direction, - GITransfer transfer) -{ - PyGIHashCache *hc; - GITypeInfo *key_type_info; - GITypeInfo *value_type_info; - GITransfer item_transfer; - hc = g_slice_new0 (PyGIHashCache); - ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func; - key_type_info = g_type_info_get_param_type (type_info, 0); - value_type_info = g_type_info_get_param_type (type_info, 1); - - item_transfer = - transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer; - - hc->key_cache = _arg_cache_new (key_type_info, - NULL, - NULL, - item_transfer, - direction, - 0, 0); - - if (hc->key_cache == NULL) { - _pygi_arg_cache_free ( (PyGIArgCache *)hc); - return NULL; - } - - hc->value_cache = _arg_cache_new (value_type_info, - NULL, - NULL, - item_transfer, - direction, - 0, 0); - - if (hc->value_cache == NULL) { - _pygi_arg_cache_free ( (PyGIArgCache *)hc); - return NULL; +/* pygi_arg_interface_setup: + * arg_cache: argument cache to initialize + * type_info: source for type related attributes to cache + * arg_info: (allow-none): source for argument related attributes to cache + * transfer: transfer mode to store in the argument cache + * direction: marshaling direction to store in the cache + * iface_info: interface info to cache + * + * Initializer for PyGIInterfaceCache + * + * Returns: TRUE on success and FALSE on failure + */ +gboolean +pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + if (!pygi_arg_base_setup ((PyGIArgCache *)iface_cache, + type_info, + arg_info, + transfer, + direction)) { + return FALSE; } - g_base_info_unref( (GIBaseInfo *)key_type_info); - g_base_info_unref( (GIBaseInfo *)value_type_info); - - return hc; -} + ( (PyGIArgCache *)iface_cache)->destroy_notify = (GDestroyNotify)_interface_cache_free_func; -static PyGICallbackCache * -_callback_cache_new (GIArgInfo *arg_info, - GIInterfaceInfo *iface_info, - gssize child_offset) -{ - PyGICallbackCache *cc; - - cc = g_slice_new0 (PyGICallbackCache); - ( (PyGIArgCache *)cc)->destroy_notify = (GDestroyNotify)_callback_cache_free_func; - - cc->user_data_index = g_arg_info_get_closure (arg_info); - if (cc->user_data_index != -1) - cc->user_data_index += child_offset; - cc->destroy_notify_index = g_arg_info_get_destroy (arg_info); - if (cc->destroy_notify_index != -1) - cc->destroy_notify_index += child_offset; - cc->scope = g_arg_info_get_scope (arg_info); - g_base_info_ref( (GIBaseInfo *)iface_info); - cc->interface_info = iface_info; - return cc; -} + g_base_info_ref ( (GIBaseInfo *)iface_info); + iface_cache->interface_info = iface_info; + iface_cache->arg_cache.type_tag = GI_TYPE_TAG_INTERFACE; + iface_cache->type_name = _pygi_g_base_info_get_fullname (iface_info); + iface_cache->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info); + iface_cache->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info); -static PyGIArgCache * -_arg_cache_alloc (void) -{ - return g_slice_new0 (PyGIArgCache); -} - -static void -_arg_cache_from_py_basic_type_setup (PyGIArgCache *arg_cache) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter; -} - -static void -_arg_cache_to_py_basic_type_setup (PyGIArgCache *arg_cache) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter; -} - -static void -_arg_cache_from_py_void_setup (PyGIArgCache *arg_cache) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_void; -} - -static void -_arg_cache_to_py_void_setup (PyGIArgCache *arg_cache) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_void; -} - -static void -_arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8; -} - -static void -_arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8; -} - -static PyGIArgCache* -_arg_cache_array_len_arg_setup (PyGIArgCache *arg_cache, - PyGICallableCache *callable_cache, - PyGIDirection direction, - gssize arg_index, - gssize *py_arg_index) -{ - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - if (seq_cache->len_arg_index >= 0) { - PyGIArgCache *child_cache = NULL; - - child_cache = _pygi_callable_cache_get_arg (callable_cache, - seq_cache->len_arg_index); - if (child_cache == NULL) { - child_cache = _arg_cache_alloc (); - } else { - /* If the "length" arg cache already exists (the length comes before - * the array in the argument list), remove it from the to_py_args list - * because it does not belong in "to python" return tuple. The length - * will implicitly be a part of the returned Python list. - */ - if (direction & PYGI_DIRECTION_TO_PYTHON) { - callable_cache->to_py_args = - g_slist_remove (callable_cache->to_py_args, child_cache); - } - - /* This is a case where the arg cache already exists and has been - * setup by another array argument sharing the same length argument. - * See: gi_marshalling_tests_multi_array_key_value_in - */ - if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD) - return child_cache; - } - - /* There is a length argument for this array, so increment the number - * of "to python" child arguments when applicable. - */ - if (direction & PYGI_DIRECTION_TO_PYTHON) - callable_cache->n_to_py_child_args++; - - child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; - child_cache->direction = direction; - child_cache->to_py_marshaller = NULL; - child_cache->from_py_marshaller = NULL; - - /* ugly edge case code: - * - * When the length comes before the array parameter we need to update - * indexes of arguments after the index argument. - */ - if (seq_cache->len_arg_index < arg_index && direction & PYGI_DIRECTION_FROM_PYTHON) { - gssize i; - (*py_arg_index) -= 1; - callable_cache->n_py_args -= 1; - - for (i = seq_cache->len_arg_index + 1; - i < _pygi_callable_cache_args_len (callable_cache); i++) { - PyGIArgCache *update_cache = _pygi_callable_cache_get_arg (callable_cache, i); - if (update_cache == NULL) - break; - - update_cache->py_arg_index -= 1; - } - } - - _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache); - return child_cache; + if (iface_cache->py_type == NULL) { + return FALSE; } - return NULL; -} - -static gboolean -_arg_cache_from_py_array_setup (PyGIArgCache *arg_cache, - PyGICallableCache *callable_cache, - GITypeInfo *type_info, - GITransfer transfer, - PyGIDirection direction, - gssize arg_index) -{ - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - seq_cache->array_type = g_type_info_get_array_type (type_info); - arg_cache->from_py_marshaller = _pygi_marshal_from_py_array; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array; return TRUE; } -static gboolean -_arg_cache_to_py_array_setup (PyGIArgCache *arg_cache, - PyGICallableCache *callable_cache, - GITypeInfo *type_info, - GITransfer transfer, - PyGIDirection direction, - gssize arg_index) -{ - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - seq_cache->array_type = g_type_info_get_array_type (type_info); - arg_cache->to_py_marshaller = _pygi_marshal_to_py_array; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array; - return TRUE; -} - -static void -_arg_cache_from_py_glist_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_glist; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist; -} - -static void -_arg_cache_to_py_glist_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_glist; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist; -} - -static void -_arg_cache_from_py_gslist_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_gslist; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist; -} - -static void -_arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_gslist; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist; -} - -static void -_arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash; -} - -static void -_arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash; -} - -static void -_arg_cache_from_py_gerror_setup (PyGIArgCache *arg_cache) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror; - arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; -} - -static void -_arg_cache_to_py_gerror_setup (PyGIArgCache *arg_cache) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror; - arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; -} - -static void -_arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache, - GITransfer transfer) +PyGIArgCache * +pygi_arg_interface_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) { - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter; -} + PyGIInterfaceCache *ic; -static void -_arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter; -} + ic = g_slice_new0 (PyGIInterfaceCache); + if (!pygi_arg_interface_setup (ic, + type_info, + arg_info, + transfer, + direction, + iface_info)) { + pygi_arg_cache_free ((PyGIArgCache *)ic); + return NULL; + } -static void -_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache, - GIInterfaceInfo *iface_info, - GITransfer transfer) -{ - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter; - - if (iface_cache->g_type == G_TYPE_VALUE) - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue; - else if (iface_cache->is_foreign) - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign; + return (PyGIArgCache *)ic; } -static void -_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache, - GIInterfaceInfo *iface_info, - GITransfer transfer) -{ - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); - arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter; - - if (iface_cache->is_foreign) - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign; -} +/* PyGISequenceCache */ static void -_arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache, - GITransfer transfer) +_sequence_cache_free_func (PyGISequenceCache *cache) { - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object; + if (cache != NULL) { + pygi_arg_cache_free (cache->item_cache); + g_slice_free (PyGISequenceCache, cache); + } } -static void -_arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache, - GITransfer transfer) +/* pygi_arg_sequence_setup: + * sc: sequence cache to initialize + * type_info: source for type related attributes to cache + * arg_info: (allow-none): source for argument related attributes to cache + * transfer: transfer mode to store in the argument cache + * direction: marshaling direction to store in the cache + * iface_info: interface info to cache + * + * Initializer for PyGISequenceCache used for holding list and array argument + * caches. + * + * Returns: TRUE on success and FALSE on failure + */ +gboolean +pygi_arg_sequence_setup (PyGISequenceCache *sc, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction) { - arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object_cache_adapter; - arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object; -} + GITypeInfo *item_type_info; + GITransfer item_transfer; -static void -_arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache, - PyGICallableCache *callable_cache) -{ - PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache; - if (callback_cache->user_data_index >= 0) { - PyGIArgCache *user_data_arg_cache = _arg_cache_alloc (); - user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG; - user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; - user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */ - _pygi_callable_cache_set_arg (callable_cache, callback_cache->user_data_index, - user_data_arg_cache); + if (!pygi_arg_base_setup ((PyGIArgCache *)sc, + type_info, + arg_info, + transfer, + direction)) { + return FALSE; } - if (callback_cache->destroy_notify_index >= 0) { - PyGIArgCache *destroy_arg_cache = _arg_cache_alloc (); - destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; - destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; - _pygi_callable_cache_set_arg (callable_cache, callback_cache->destroy_notify_index, - destroy_arg_cache); - } - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback; - arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback; -} + sc->arg_cache.destroy_notify = (GDestroyNotify)_sequence_cache_free_func; + item_type_info = g_type_info_get_param_type (type_info, 0); + item_transfer = + transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer; -static void -_arg_cache_to_py_interface_callback_setup (void) -{ - PyErr_Format(PyExc_NotImplementedError, - "Callback returns are not supported"); -} + sc->item_cache = pygi_arg_cache_new (item_type_info, + NULL, + item_transfer, + direction, + 0, 0, + NULL); -static void -_arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum; -} + g_base_info_unref ( (GIBaseInfo *)item_type_info); -static void -_arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum; -} + if (sc->item_cache == NULL) { + return FALSE; + } -static void -_arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache, - GITransfer transfer) -{ - arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags; + return TRUE; } -static void -_arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache, - GITransfer transfer) +PyGIArgCache * +pygi_arg_cache_alloc (void) { - arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags; + return g_slice_new0 (PyGIArgCache); } -PyGIArgCache * -_arg_cache_new_for_interface (GIInterfaceInfo *iface_info, - PyGICallableCache *callable_cache, - GIArgInfo *arg_info, - GITransfer transfer, - PyGIDirection direction, - gssize c_arg_index, - gssize py_arg_index) +static PyGIArgCache * +_arg_cache_new_for_interface (GIInterfaceInfo *iface_info, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + PyGICallableCache *callable_cache) { - PyGIInterfaceCache *iface_cache = NULL; - PyGIArgCache *arg_cache = NULL; - gssize child_offset = 0; GIInfoType info_type; - if (callable_cache != NULL) - child_offset = - (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD || - callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0; - info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info); - /* Callbacks are special cased */ - if (info_type != GI_INFO_TYPE_CALLBACK) { - iface_cache = _interface_cache_new (iface_info); - - arg_cache = (PyGIArgCache *)iface_cache; - if (arg_cache == NULL) - return NULL; - } - switch (info_type) { - case GI_INFO_TYPE_UNION: - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_union_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_interface_union_setup (arg_cache, transfer); - - break; - case GI_INFO_TYPE_BOXED: - case GI_INFO_TYPE_STRUCT: - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_struct_setup (arg_cache, - iface_info, - transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_interface_struct_setup (arg_cache, - iface_info, - transfer); - break; + case GI_INFO_TYPE_CALLBACK: + return pygi_arg_callback_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info, + callable_cache); case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_object_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_interface_object_setup (arg_cache, transfer); - - break; - case GI_INFO_TYPE_CALLBACK: - { - PyGICallbackCache *callback_cache; - - if (direction & PYGI_DIRECTION_TO_PYTHON) { - _arg_cache_to_py_interface_callback_setup (); - return NULL; - } - - callback_cache = - _callback_cache_new (arg_info, - iface_info, - child_offset); - - arg_cache = (PyGIArgCache *)callback_cache; - if (arg_cache == NULL) - return NULL; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_callback_setup (arg_cache, callable_cache); - - break; - } + return pygi_arg_gobject_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + return pygi_arg_struct_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); case GI_INFO_TYPE_ENUM: - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_enum_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_interface_enum_setup (arg_cache, transfer); - - break; + return pygi_arg_enum_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); case GI_INFO_TYPE_FLAGS: - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_interface_flags_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_interface_flags_setup (arg_cache, transfer); - - break; + return pygi_arg_flags_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); default: g_assert_not_reached (); } - if (arg_cache != NULL) { - arg_cache->direction = direction; - arg_cache->transfer = transfer; - arg_cache->type_tag = GI_TYPE_TAG_INTERFACE; - arg_cache->py_arg_index = py_arg_index; - arg_cache->c_arg_index = c_arg_index; - - if (iface_cache != NULL) { - g_base_info_ref ( (GIBaseInfo *)iface_info); - iface_cache->interface_info = iface_info; - } - } - - return arg_cache; -} - -/* _arg_info_default_value - * info: - * arg: (out): GIArgument to fill in with default value. - * - * This is currently a place holder API which only supports "allow-none" pointer args. - * Once defaults are part of the GI API, we can replace this with: g_arg_info_default_value - * https://bugzilla.gnome.org/show_bug.cgi?id=558620 - * - * Returns: TRUE if the given argument supports a default value and was filled in. - */ -static gboolean -_arg_info_default_value (GIArgInfo *info, GIArgument *arg) -{ - if (g_arg_info_may_be_null (info)) { - arg->v_pointer = NULL; - return TRUE; - } - return FALSE; + return NULL; } PyGIArgCache * -_arg_cache_new (GITypeInfo *type_info, - PyGICallableCache *callable_cache, - GIArgInfo *arg_info, /* may be null */ - GITransfer transfer, - PyGIDirection direction, - gssize c_arg_index, - gssize py_arg_index) +pygi_arg_cache_new (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + gssize c_arg_index, + gssize py_arg_index, + PyGICallableCache *callable_cache) { PyGIArgCache *arg_cache = NULL; - gssize child_offset = 0; GITypeTag type_tag; type_tag = g_type_info_get_tag (type_info); - if (callable_cache != NULL) - child_offset = - (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD || - callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0; - switch (type_tag) { case GI_TYPE_TAG_VOID: - arg_cache = _arg_cache_alloc (); - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_void_setup (arg_cache); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_void_setup (arg_cache); - - break; case GI_TYPE_TAG_BOOLEAN: case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: @@ -759,176 +370,78 @@ _arg_cache_new (GITypeInfo *type_info, case GI_TYPE_TAG_DOUBLE: case GI_TYPE_TAG_UNICHAR: case GI_TYPE_TAG_GTYPE: - arg_cache = _arg_cache_alloc (); - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_basic_type_setup (arg_cache); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_basic_type_setup (arg_cache); - - break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: - arg_cache = _arg_cache_alloc (); - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_utf8_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_utf8_setup (arg_cache, transfer); - + arg_cache = pygi_arg_basic_type_new_from_info (type_info, + arg_info, + transfer, + direction); break; + case GI_TYPE_TAG_ARRAY: { - PyGISequenceCache *seq_cache = - _sequence_cache_new (type_info, - direction, - transfer, - child_offset); - - arg_cache = (PyGIArgCache *)seq_cache; + arg_cache = pygi_arg_garray_new_from_info (type_info, + arg_info, + transfer, + direction); if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_array_setup (arg_cache, - callable_cache, - type_info, - transfer, - direction, - c_arg_index); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_array_setup (arg_cache, - callable_cache, - type_info, - transfer, - direction, - c_arg_index); - - _arg_cache_array_len_arg_setup (arg_cache, - callable_cache, - direction, - c_arg_index, - &py_arg_index); - - break; + return NULL; + + pygi_arg_garray_len_arg_setup (arg_cache, + type_info, + callable_cache, + direction, + c_arg_index, + &py_arg_index); } - case GI_TYPE_TAG_GLIST: - { - PyGISequenceCache *seq_cache = - _sequence_cache_new (type_info, - direction, - transfer, - child_offset); - - arg_cache = (PyGIArgCache *)seq_cache; - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_glist_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_glist_setup (arg_cache, transfer); + break; + case GI_TYPE_TAG_GLIST: + arg_cache = pygi_arg_glist_new_from_info (type_info, + arg_info, + transfer, + direction); + break; - break; - } case GI_TYPE_TAG_GSLIST: - { - PyGISequenceCache *seq_cache = - _sequence_cache_new (type_info, - direction, - transfer, - child_offset); - - arg_cache = (PyGIArgCache *)seq_cache; - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_gslist_setup (arg_cache, transfer); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_gslist_setup (arg_cache, transfer); + arg_cache = pygi_arg_gslist_new_from_info (type_info, + arg_info, + transfer, + direction); + break; - break; - } case GI_TYPE_TAG_GHASH: - arg_cache = - (PyGIArgCache *)_hash_cache_new (type_info, - direction, - transfer); - - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_ghash_setup (arg_cache); - - if (direction & PYGI_DIRECTION_TO_PYTHON) { - _arg_cache_to_py_ghash_setup (arg_cache); - } - + arg_cache = pygi_arg_hash_table_new_from_info (type_info, + arg_info, + transfer, + direction); break; + case GI_TYPE_TAG_INTERFACE: { GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info); arg_cache = _arg_cache_new_for_interface (interface_info, - callable_cache, + type_info, arg_info, transfer, direction, - c_arg_index, - py_arg_index); + callable_cache); g_base_info_unref ( (GIBaseInfo *)interface_info); - break; } - case GI_TYPE_TAG_ERROR: - arg_cache = _arg_cache_alloc (); - if (arg_cache == NULL) - break; - - if (direction & PYGI_DIRECTION_FROM_PYTHON) - _arg_cache_from_py_gerror_setup (arg_cache); - - if (direction & PYGI_DIRECTION_TO_PYTHON) - _arg_cache_to_py_gerror_setup (arg_cache); + break; + case GI_TYPE_TAG_ERROR: + arg_cache = pygi_arg_gerror_new_from_info (type_info, + arg_info, + transfer, + direction); break; } if (arg_cache != NULL) { - arg_cache->direction = direction; - arg_cache->transfer = transfer; - arg_cache->type_tag = type_tag; arg_cache->py_arg_index = py_arg_index; arg_cache->c_arg_index = c_arg_index; - arg_cache->is_pointer = g_type_info_is_pointer (type_info); - g_base_info_ref ( (GIBaseInfo *) type_info); - arg_cache->type_info = type_info; - - if (arg_info != NULL) { - if (!arg_cache->has_default) { - /* It is possible has_default was set somewhere else */ - arg_cache->has_default = _arg_info_default_value (arg_info, - &arg_cache->default_value); - } - arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info); - arg_cache->allow_none = g_arg_info_may_be_null (arg_info); - - if (type_tag == GI_TYPE_TAG_INTERFACE || type_tag == GI_TYPE_TAG_ARRAY) - arg_cache->is_caller_allocates = g_arg_info_is_caller_allocates (arg_info); - else - arg_cache->is_caller_allocates = FALSE; - } } return arg_cache; @@ -972,13 +485,13 @@ _args_cache_generate (GICallableInfo *callable_info, return_transfer = g_callable_info_get_caller_owns (callable_info); return_cache = - _arg_cache_new (return_info, - callable_cache, - NULL, - return_transfer, - return_direction, - -1, - -1); + pygi_arg_cache_new (return_info, + NULL, + return_transfer, + return_direction, + -1, + -1, + callable_cache); if (return_cache == NULL) return FALSE; @@ -996,12 +509,11 @@ _args_cache_generate (GICallableInfo *callable_info, instance_cache = _arg_cache_new_for_interface (interface_info, - callable_cache, + NULL, NULL, GI_TRANSFER_NOTHING, PYGI_DIRECTION_FROM_PYTHON, - arg_index, - 0); + callable_cache); g_base_info_unref ( (GIBaseInfo *)interface_info); @@ -1011,6 +523,8 @@ _args_cache_generate (GICallableInfo *callable_info, /* Because we are not supplied a GITypeInfo for instance arguments, * assume some defaults. */ instance_cache->is_pointer = TRUE; + instance_cache->py_arg_index = 0; + instance_cache->c_arg_index = 0; _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache); @@ -1029,7 +543,7 @@ _args_cache_generate (GICallableInfo *callable_info, if (g_arg_info_get_closure (arg_info) == i) { - arg_cache = _arg_cache_alloc (); + arg_cache = pygi_arg_cache_alloc (); _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache); direction = PYGI_DIRECTION_FROM_PYTHON; @@ -1080,13 +594,13 @@ _args_cache_generate (GICallableInfo *callable_info, } arg_cache = - _arg_cache_new (type_info, - callable_cache, - arg_info, - transfer, - direction, - arg_index, - py_arg_index); + pygi_arg_cache_new (type_info, + arg_info, + transfer, + direction, + arg_index, + py_arg_index, + callable_cache); if (arg_cache == NULL) { g_base_info_unref( (GIBaseInfo *)type_info); @@ -1172,7 +686,7 @@ _args_cache_generate (GICallableInfo *callable_info, } PyGICallableCache * -_pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) +pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) { gint n_args; PyGICallableCache *cache; @@ -1227,7 +741,7 @@ _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) n_args++; if (n_args >= 0) { - cache->args_cache = g_ptr_array_new_full (n_args, (GDestroyNotify) _pygi_arg_cache_free); + cache->args_cache = g_ptr_array_new_full (n_args, (GDestroyNotify) pygi_arg_cache_free); g_ptr_array_set_size (cache->args_cache, n_args); } @@ -1236,6 +750,6 @@ _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) return cache; err: - _pygi_callable_cache_free (cache); + pygi_callable_cache_free (cache); return NULL; } diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h index 745d0a1..5521605 100644 --- a/gi/pygi-cache.h +++ b/gi/pygi-cache.h @@ -2,6 +2,7 @@ * vim: tabstop=4 shiftwidth=4 expandtab * * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2013 Simon Feltman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -132,13 +133,18 @@ struct _PyGIArgCache typedef struct _PyGISequenceCache { PyGIArgCache arg_cache; + PyGIArgCache *item_cache; +} PyGISequenceCache; + +typedef struct _PyGIArgGArray +{ + PyGISequenceCache seq_cache; gssize fixed_size; gssize len_arg_index; gboolean is_zero_terminated; gsize item_size; GIArrayType array_type; - PyGIArgCache *item_cache; -} PyGISequenceCache; +} PyGIArgGArray; typedef struct _PyGIInterfaceCache { @@ -150,22 +156,6 @@ typedef struct _PyGIInterfaceCache gchar *type_name; } PyGIInterfaceCache; -typedef struct _PyGIHashCache -{ - PyGIArgCache arg_cache; - PyGIArgCache *key_cache; - PyGIArgCache *value_cache; -} PyGIHashCache; - -typedef struct _PyGICallbackCache -{ - PyGIArgCache arg_cache; - gssize user_data_index; - gssize destroy_notify_index; - GIScopeType scope; - GIInterfaceInfo *interface_info; -} PyGICallbackCache; - struct _PyGICallableCache { const gchar *name; @@ -203,11 +193,57 @@ struct _PyGICallableCache gssize n_py_required_args; }; -void _pygi_arg_cache_clear (PyGIArgCache *cache); -void _pygi_callable_cache_free (PyGICallableCache *cache); - -PyGICallableCache *_pygi_callable_cache_new (GICallableInfo *callable_info, - gboolean is_ccallback); +gboolean +pygi_arg_base_setup (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction); + +gboolean +pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + +gboolean +pygi_arg_sequence_setup (PyGISequenceCache *sc, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction); + +PyGIArgCache * +pygi_arg_interface_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be NULL for return arguments */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + +PyGIArgCache * +pygi_arg_cache_alloc (void); + +PyGIArgCache * +pygi_arg_cache_new (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + /* will be removed */ + gssize c_arg_index, + gssize py_arg_index, + PyGICallableCache *callable_cache); + +void +pygi_arg_cache_free (PyGIArgCache *cache); + +void +pygi_callable_cache_free (PyGICallableCache *cache); + +PyGICallableCache * +pygi_callable_cache_new (GICallableInfo *callable_info, + gboolean is_ccallback); #define _pygi_callable_cache_args_len(cache) ((cache)->args_cache)->len diff --git a/gi/pygi-ccallback.c b/gi/pygi-ccallback.c index 82777fb..01e109b 100644 --- a/gi/pygi-ccallback.c +++ b/gi/pygi-ccallback.c @@ -22,8 +22,8 @@ */ #include "pygi-private.h" +#include "pygobject-private.h" -#include #include #include @@ -34,7 +34,7 @@ _ccallback_call(PyGICCallback *self, PyObject *args, PyObject *kwargs) PyObject *result; if (self->cache == NULL) { - self->cache = _pygi_callable_cache_new (self->info, TRUE); + self->cache = pygi_callable_cache_new (self->info, TRUE); if (self->cache == NULL) return NULL; } diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index 5df4713..a30363f 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -14,12 +14,23 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA + * License along with this library; if not, see . */ #include "pygi-private.h" +#include "pygi-closure.h" + + +typedef struct _PyGICallbackCache +{ + PyGIArgCache arg_cache; + gssize user_data_index; + gssize destroy_notify_index; + GIScopeType scope; + GIInterfaceInfo *interface_info; +} PyGICallbackCache; + +static PyGICClosure *global_destroy_notify; /* This maintains a list of closures which can be free'd whenever as they have been called. We will free them on the next @@ -669,3 +680,300 @@ _pygi_make_native_closure (GICallableInfo* info, return closure; } + +/* _pygi_destroy_notify_dummy: + * + * Dummy method used in the occasion when a method has a GDestroyNotify + * argument without user data. + */ +static void +_pygi_destroy_notify_dummy (gpointer data) { +} + +static void +_pygi_destroy_notify_callback_closure (ffi_cif *cif, + void *result, + void **args, + void *data) +{ + PyGICClosure *info = * (void**) (args[0]); + + g_assert (info); + + _pygi_invoke_closure_free (info); +} + +/* _pygi_destroy_notify_create: + * + * Method used in the occasion when a method has a GDestroyNotify + * argument with user data. + */ +static PyGICClosure* +_pygi_destroy_notify_create (void) +{ + if (!global_destroy_notify) { + + PyGICClosure *destroy_notify = g_slice_new0 (PyGICClosure); + GIBaseInfo* glib_destroy_notify; + + g_assert (destroy_notify); + + glib_destroy_notify = g_irepository_find_by_name (NULL, "GLib", "DestroyNotify"); + g_assert (glib_destroy_notify != NULL); + g_assert (g_base_info_get_type (glib_destroy_notify) == GI_INFO_TYPE_CALLBACK); + + destroy_notify->closure = g_callable_info_prepare_closure ( (GICallableInfo*) glib_destroy_notify, + &destroy_notify->cif, + _pygi_destroy_notify_callback_closure, + NULL); + + global_destroy_notify = destroy_notify; + } + + return global_destroy_notify; +} + +static gboolean +_pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + GICallableInfo *callable_info; + PyGICClosure *closure; + PyGIArgCache *user_data_cache = NULL; + PyGIArgCache *destroy_cache = NULL; + PyGICallbackCache *callback_cache; + PyObject *py_user_data = NULL; + + callback_cache = (PyGICallbackCache *)arg_cache; + + if (callback_cache->user_data_index > 0) { + user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index); + if (user_data_cache->py_arg_index < state->n_py_in_args) { + /* py_user_data is a borrowed reference. */ + py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index); + if (!py_user_data) + return FALSE; + /* NULL out user_data if it was not supplied and the default arg placeholder + * was used instead. + */ + if (py_user_data == _PyGIDefaultArgPlaceholder) { + py_user_data = NULL; + } else if (callable_cache->user_data_varargs_index < 0) { + /* For non-variable length user data, place the user data in a + * single item tuple which is concatenated to the callbacks arguments. + * This allows callback input arg marshaling to always expect a + * tuple for user data. Note the + */ + py_user_data = Py_BuildValue("(O)", py_user_data, NULL); + } else { + /* increment the ref borrowed from PyTuple_GetItem above */ + Py_INCREF (py_user_data); + } + } + } + + if (py_arg == Py_None) { + return TRUE; + } + + if (!PyCallable_Check (py_arg)) { + PyErr_Format (PyExc_TypeError, + "Callback needs to be a function or method not %s", + py_arg->ob_type->tp_name); + + return FALSE; + } + + callable_info = (GICallableInfo *)callback_cache->interface_info; + + closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data); + arg->v_pointer = closure->closure; + + /* always decref the user data as _pygi_make_native_closure adds its own ref */ + Py_XDECREF (py_user_data); + + /* The PyGICClosure instance is used as user data passed into the C function. + * The return trip to python will marshal this back and pull the python user data out. + */ + if (user_data_cache != NULL) { + state->in_args[user_data_cache->c_arg_index].v_pointer = closure; + } + + /* Setup a GDestroyNotify callback if this method supports it along with + * a user data field. The user data field is a requirement in order + * free resources and ref counts associated with this arguments closure. + * In case a user data field is not available, show a warning giving + * explicit information and setup a dummy notification to avoid a crash + * later on in _pygi_destroy_notify_callback_closure. + */ + if (callback_cache->destroy_notify_index > 0) { + destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index); + } + + if (destroy_cache) { + if (user_data_cache != NULL) { + PyGICClosure *destroy_notify = _pygi_destroy_notify_create (); + state->in_args[destroy_cache->c_arg_index].v_pointer = destroy_notify->closure; + } else { + gchar *msg = g_strdup_printf("Callables passed to %s will leak references because " + "the method does not support a user_data argument. " + "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598", + callable_cache->name); + if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) { + g_free(msg); + _pygi_invoke_closure_free(closure); + return FALSE; + } + g_free(msg); + state->in_args[destroy_cache->c_arg_index].v_pointer = _pygi_destroy_notify_dummy; + } + } + + /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */ + *cleanup_data = closure; + + return TRUE; +} + +static PyObject * +_pygi_marshal_to_py_interface_callback (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + PyObject *py_obj = NULL; + + PyErr_Format (PyExc_NotImplementedError, + "Marshalling a callback to PyObject is not supported"); + return py_obj; +} + +static void +_callback_cache_free_func (PyGICallbackCache *cache) +{ + if (cache != NULL) { + if (cache->interface_info != NULL) + g_base_info_unref ( (GIBaseInfo *)cache->interface_info); + + g_slice_free (PyGICallbackCache, cache); + } +} + +static void +_pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache; + if (was_processed && callback_cache->scope == GI_SCOPE_TYPE_CALL) { + _pygi_invoke_closure_free (data); + } +} + +static void +_arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache, + PyGICallableCache *callable_cache) +{ + PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache; + if (callback_cache->user_data_index >= 0) { + PyGIArgCache *user_data_arg_cache = pygi_arg_cache_alloc (); + user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG; + user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; + user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */ + _pygi_callable_cache_set_arg (callable_cache, callback_cache->user_data_index, + user_data_arg_cache); + } + + if (callback_cache->destroy_notify_index >= 0) { + PyGIArgCache *destroy_arg_cache = pygi_arg_cache_alloc (); + destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; + destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; + _pygi_callable_cache_set_arg (callable_cache, callback_cache->destroy_notify_index, + destroy_arg_cache); + } + arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback; +} + + +static gboolean +pygi_arg_callback_setup_from_info (PyGICallbackCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info, + PyGICallableCache *callable_cache) +{ + gssize child_offset = 0; + + if (!pygi_arg_base_setup ((PyGIArgCache *)arg_cache, + type_info, + arg_info, + transfer, + direction)) { + return FALSE; + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + ((PyGIArgCache *)arg_cache)->to_py_marshaller = _pygi_marshal_to_py_interface_callback; + } + + if (callable_cache != NULL) + child_offset = + (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD || + callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0; + + ( (PyGIArgCache *)arg_cache)->destroy_notify = (GDestroyNotify)_callback_cache_free_func; + + arg_cache->user_data_index = g_arg_info_get_closure (arg_info); + if (arg_cache->user_data_index != -1) + arg_cache->user_data_index += child_offset; + arg_cache->destroy_notify_index = g_arg_info_get_destroy (arg_info); + if (arg_cache->destroy_notify_index != -1) + arg_cache->destroy_notify_index += child_offset; + arg_cache->scope = g_arg_info_get_scope (arg_info); + g_base_info_ref( (GIBaseInfo *)iface_info); + arg_cache->interface_info = iface_info; + + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_interface_callback_setup ((PyGIArgCache *)arg_cache, callable_cache); + + return TRUE; +} + +PyGIArgCache * +pygi_arg_callback_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info, + PyGICallableCache *callable_cache) +{ + gboolean res = FALSE; + PyGICallbackCache *callback_cache; + + callback_cache = g_slice_new0 (PyGICallbackCache); + if (callback_cache == NULL) + return NULL; + + res = pygi_arg_callback_setup_from_info (callback_cache, + type_info, + arg_info, + transfer, + direction, + iface_info, + callable_cache); + if (res) { + return (PyGIArgCache *)callback_cache; + } else { + pygi_arg_cache_free ((PyGIArgCache *)callback_cache); + return NULL; + } +} diff --git a/gi/pygi-closure.h b/gi/pygi-closure.h index 6f98339..0620dc7 100644 --- a/gi/pygi-closure.h +++ b/gi/pygi-closure.h @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA + * License along with this library; if not, see . */ #ifndef __PYGI_CLOSURE_H__ @@ -24,6 +22,8 @@ #include #include +#include "pygi-cache.h" + G_BEGIN_DECLS @@ -52,6 +52,13 @@ PyGICClosure* _pygi_make_native_closure (GICallableInfo* info, PyObject *function, gpointer user_data); +PyGIArgCache *pygi_arg_callback_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info, + PyGICallableCache *callable_cache); + G_END_DECLS #endif /* __PYGI_CLOSURE_H__ */ diff --git a/gi/pygi-enum-marshal.c b/gi/pygi-enum-marshal.c new file mode 100644 index 0000000..dec5924 --- /dev/null +++ b/gi/pygi-enum-marshal.c @@ -0,0 +1,408 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include + +#include "pygi-enum-marshal.h" +#include "pygi-private.h" + +#ifdef _WIN32 +#ifdef _MSC_VER +#include + +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float *) __nan) +#endif + +#ifndef INFINITY +#define INFINITY HUGE_VAL +#endif + +#endif +#endif + +static gboolean +gi_argument_from_c_long (GIArgument *arg_out, + long c_long_in, + GITypeTag type_tag) +{ + switch (type_tag) { + case GI_TYPE_TAG_INT8: + arg_out->v_int8 = c_long_in; + return TRUE; + case GI_TYPE_TAG_UINT8: + arg_out->v_uint8 = c_long_in; + return TRUE; + case GI_TYPE_TAG_INT16: + arg_out->v_int16 = c_long_in; + return TRUE; + case GI_TYPE_TAG_UINT16: + arg_out->v_uint16 = c_long_in; + return TRUE; + case GI_TYPE_TAG_INT32: + arg_out->v_int32 = c_long_in; + return TRUE; + case GI_TYPE_TAG_UINT32: + arg_out->v_uint32 = c_long_in; + return TRUE; + case GI_TYPE_TAG_INT64: + arg_out->v_int64 = c_long_in; + return TRUE; + case GI_TYPE_TAG_UINT64: + arg_out->v_uint64 = c_long_in; + return TRUE; + default: + PyErr_Format (PyExc_TypeError, + "Unable to marshal C long %ld to %s", + c_long_in, + g_type_tag_to_string (type_tag)); + return FALSE; + } +} + +static gboolean +gi_argument_to_c_long (GIArgument *arg_in, + long *c_long_out, + GITypeTag type_tag) +{ + switch (type_tag) { + case GI_TYPE_TAG_INT8: + *c_long_out = arg_in->v_int8; + return TRUE; + case GI_TYPE_TAG_UINT8: + *c_long_out = arg_in->v_uint8; + return TRUE; + case GI_TYPE_TAG_INT16: + *c_long_out = arg_in->v_int16; + return TRUE; + case GI_TYPE_TAG_UINT16: + *c_long_out = arg_in->v_uint16; + return TRUE; + case GI_TYPE_TAG_INT32: + *c_long_out = arg_in->v_int32; + return TRUE; + case GI_TYPE_TAG_UINT32: + *c_long_out = arg_in->v_uint32; + return TRUE; + case GI_TYPE_TAG_INT64: + *c_long_out = arg_in->v_int64; + return TRUE; + case GI_TYPE_TAG_UINT64: + *c_long_out = arg_in->v_uint64; + return TRUE; + default: + PyErr_Format (PyExc_TypeError, + "Unable to marshal %s to C long", + g_type_tag_to_string (type_tag)); + return FALSE; + } +} + +static gboolean +_pygi_marshal_from_py_interface_enum (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyObject *py_long; + long c_long; + gint is_instance; + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + GIBaseInfo *interface = NULL; + + is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type); + + py_long = PYGLIB_PyNumber_Long (py_arg); + if (py_long == NULL) { + PyErr_Clear(); + goto err; + } + + c_long = PYGLIB_PyLong_AsLong (py_long); + Py_DECREF (py_long); + + /* Write c_long into arg */ + interface = g_type_info_get_interface (arg_cache->type_info); + assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM); + if (!gi_argument_from_c_long(arg, + c_long, + g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { + g_assert_not_reached(); + g_base_info_unref (interface); + return FALSE; + } + + /* If this is not an instance of the Enum type that we want + * we need to check if the value is equivilant to one of the + * Enum's memebers */ + if (!is_instance) { + int i; + gboolean is_found = FALSE; + + for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) { + GIValueInfo *value_info = + g_enum_info_get_value (iface_cache->interface_info, i); + glong enum_value = g_value_info_get_value (value_info); + g_base_info_unref ( (GIBaseInfo *)value_info); + if (c_long == enum_value) { + is_found = TRUE; + break; + } + } + + if (!is_found) + goto err; + } + + g_base_info_unref (interface); + return TRUE; + +err: + if (interface) + g_base_info_unref (interface); + PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s", + iface_cache->type_name, py_arg->ob_type->tp_name); + return FALSE; +} + +static gboolean +_pygi_marshal_from_py_interface_flags (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyObject *py_long; + long c_long; + gint is_instance; + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + GIBaseInfo *interface; + + is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type); + + py_long = PYGLIB_PyNumber_Long (py_arg); + if (py_long == NULL) { + PyErr_Clear (); + goto err; + } + + c_long = PYGLIB_PyLong_AsLong (py_long); + Py_DECREF (py_long); + + /* only 0 or argument of type Flag is allowed */ + if (!is_instance && c_long != 0) + goto err; + + /* Write c_long into arg */ + interface = g_type_info_get_interface (arg_cache->type_info); + g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); + if (!gi_argument_from_c_long(arg, c_long, + g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { + g_base_info_unref (interface); + return FALSE; + } + + g_base_info_unref (interface); + return TRUE; + +err: + PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s", + iface_cache->type_name, py_arg->ob_type->tp_name); + return FALSE; + +} + +static PyObject * +_pygi_marshal_to_py_interface_enum (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + PyObject *py_obj = NULL; + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + GIBaseInfo *interface; + long c_long; + + interface = g_type_info_get_interface (arg_cache->type_info); + g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM); + + if (!gi_argument_to_c_long(arg, &c_long, + g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { + return NULL; + } + + if (iface_cache->g_type == G_TYPE_NONE) { + py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long); + } else { + py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long); + } + g_base_info_unref (interface); + return py_obj; +} + +static PyObject * +_pygi_marshal_to_py_interface_flags (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + PyObject *py_obj = NULL; + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + GIBaseInfo *interface; + long c_long; + + interface = g_type_info_get_interface (arg_cache->type_info); + g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); + + if (!gi_argument_to_c_long(arg, &c_long, + g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { + g_base_info_unref (interface); + return NULL; + } + + g_base_info_unref (interface); + if (iface_cache->g_type == G_TYPE_NONE) { + /* An enum with a GType of None is an enum without GType */ + + PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info); + PyObject *py_args = NULL; + + if (!py_type) + return NULL; + + py_args = PyTuple_New (1); + if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) { + Py_DECREF (py_args); + Py_DECREF (py_type); + return NULL; + } + + py_obj = PyObject_CallFunction (py_type, "l", c_long); + + Py_DECREF (py_args); + Py_DECREF (py_type); + } else { + py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long); + } + + return py_obj; +} + +static gboolean +pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + if (direction & PYGI_DIRECTION_FROM_PYTHON) + arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum; + + if (direction & PYGI_DIRECTION_TO_PYTHON) + arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum; + + return TRUE; +} + + +PyGIArgCache * +pygi_arg_enum_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + gboolean res = FALSE; + PyGIArgCache *cache = NULL; + + cache = pygi_arg_interface_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); + if (cache == NULL) + return NULL; + + res = pygi_arg_enum_setup_from_info (cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return cache; + } else { + pygi_arg_cache_free (cache); + return NULL; + } +} + +static gboolean +pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + if (direction & PYGI_DIRECTION_FROM_PYTHON) + arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags; + + if (direction & PYGI_DIRECTION_TO_PYTHON) + arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags; + + return TRUE; +} + + +PyGIArgCache * +pygi_arg_flags_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + gboolean res = FALSE; + PyGIArgCache *cache = NULL; + + cache = pygi_arg_interface_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); + if (cache == NULL) + return NULL; + + res = pygi_arg_flags_setup_from_info (cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return cache; + } else { + pygi_arg_cache_free (cache); + return NULL; + } +} diff --git a/gi/pygi-enum-marshal.h b/gi/pygi-enum-marshal.h new file mode 100644 index 0000000..2fdcbc4 --- /dev/null +++ b/gi/pygi-enum-marshal.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_ENUM_MARSHAL_H__ +#define __PYGI_ENUM_MARSHAL_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_enum_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + +PyGIArgCache *pygi_arg_flags_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + +G_END_DECLS + +#endif /*__PYGI_ENUM_MARSHAL_H__*/ diff --git a/gi/pygi-error.c b/gi/pygi-error.c new file mode 100644 index 0000000..349bb7e --- /dev/null +++ b/gi/pygi-error.c @@ -0,0 +1,109 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "pyglib.h" +#include "pygi-private.h" +#include "pygi-error.h" + + +static gboolean +_pygi_marshal_from_py_gerror (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyErr_Format (PyExc_NotImplementedError, + "Marshalling for GErrors is not implemented"); + return FALSE; +} + +static PyObject * +_pygi_marshal_to_py_gerror (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + GError *error = arg->v_pointer; + PyObject *py_obj = NULL; + + py_obj = pyglib_error_marshal(&error); + + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) { + g_error_free (error); + } + + if (py_obj != NULL) { + return py_obj; + } else { + Py_RETURN_NONE; + } +} + +static gboolean +pygi_arg_gerror_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + if (!pygi_arg_base_setup (arg_cache, type_info, arg_info, transfer, direction)) { + return FALSE; + } + + if (direction & PYGI_DIRECTION_FROM_PYTHON) { + arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror; + arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror; + arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_gerror_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + gboolean res = FALSE; + PyGIArgCache *arg_cache = NULL; + + arg_cache = pygi_arg_cache_alloc (); + if (arg_cache == NULL) + return NULL; + + res = pygi_arg_gerror_setup_from_info (arg_cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return arg_cache; + } else { + pygi_arg_cache_free (arg_cache); + return NULL; + } +} diff --git a/gi/pygi-error.h b/gi/pygi-error.h new file mode 100644 index 0000000..fdeb32f --- /dev/null +++ b/gi/pygi-error.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_ERROR_H__ +#define __PYGI_ERROR_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_gerror_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction); + +G_END_DECLS + +#endif /*__PYGI_ERROR_H__*/ diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c index 7537399..c046d0f 100644 --- a/gi/pygi-foreign.c +++ b/gi/pygi-foreign.c @@ -26,7 +26,7 @@ # include #endif -#include "pygobject.h" +#include "pygobject-private.h" #include "pygi-foreign.h" #include diff --git a/gi/pygi-hashtable.c b/gi/pygi-hashtable.c new file mode 100644 index 0000000..f7d5e74 --- /dev/null +++ b/gi/pygi-hashtable.c @@ -0,0 +1,413 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "pygi-hashtable.h" +#include "pygi-argument.h" +#include "pygi-private.h" + +typedef struct _PyGIHashCache +{ + PyGIArgCache arg_cache; + PyGIArgCache *key_cache; + PyGIArgCache *value_cache; +} PyGIHashCache; + + +static void +_hash_cache_free_func (PyGIHashCache *cache) +{ + if (cache != NULL) { + pygi_arg_cache_free (cache->key_cache); + pygi_arg_cache_free (cache->value_cache); + g_slice_free (PyGIHashCache, cache); + } +} + +static gboolean +_pygi_marshal_from_py_ghash (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyGIMarshalFromPyFunc key_from_py_marshaller; + PyGIMarshalFromPyFunc value_from_py_marshaller; + + int i; + Py_ssize_t length; + PyObject *py_keys, *py_values; + + GHashFunc hash_func; + GEqualFunc equal_func; + + GHashTable *hash_ = NULL; + PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + py_keys = PyMapping_Keys (py_arg); + if (py_keys == NULL) { + PyErr_Format (PyExc_TypeError, "Must be mapping, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + length = PyMapping_Length (py_arg); + if (length < 0) { + Py_DECREF (py_keys); + return FALSE; + } + + py_values = PyMapping_Values (py_arg); + if (py_values == NULL) { + Py_DECREF (py_keys); + return FALSE; + } + + key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller; + value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller; + + switch (hash_cache->key_cache->type_tag) { + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + hash_func = g_str_hash; + equal_func = g_str_equal; + break; + default: + hash_func = NULL; + equal_func = NULL; + } + + hash_ = g_hash_table_new (hash_func, equal_func); + if (hash_ == NULL) { + PyErr_NoMemory (); + Py_DECREF (py_keys); + Py_DECREF (py_values); + return FALSE; + } + + for (i = 0; i < length; i++) { + GIArgument key, value; + gpointer key_cleanup_data = NULL; + gpointer value_cleanup_data = NULL; + PyObject *py_key = PyList_GET_ITEM (py_keys, i); + PyObject *py_value = PyList_GET_ITEM (py_values, i); + if (py_key == NULL || py_value == NULL) + goto err; + + if (!key_from_py_marshaller ( state, + callable_cache, + hash_cache->key_cache, + py_key, + &key, + &key_cleanup_data)) + goto err; + + if (!value_from_py_marshaller ( state, + callable_cache, + hash_cache->value_cache, + py_value, + &value, + &value_cleanup_data)) + goto err; + + g_hash_table_insert (hash_, + _pygi_arg_to_hash_pointer (&key, hash_cache->key_cache->type_tag), + _pygi_arg_to_hash_pointer (&value, hash_cache->value_cache->type_tag)); + continue; +err: + /* FIXME: cleanup hash keys and values */ + Py_XDECREF (py_key); + Py_XDECREF (py_value); + Py_DECREF (py_keys); + Py_DECREF (py_values); + g_hash_table_unref (hash_); + _PyGI_ERROR_PREFIX ("Item %i: ", i); + return FALSE; + } + + arg->v_pointer = hash_; + + if (arg_cache->transfer == GI_TRANSFER_NOTHING) { + /* Free everything in cleanup. */ + *cleanup_data = arg->v_pointer; + } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { + /* Make a shallow copy so we can free the elements later in cleanup + * because it is possible invoke will free the list before our cleanup. */ + *cleanup_data = g_hash_table_ref (arg->v_pointer); + } else { /* GI_TRANSFER_EVERYTHING */ + /* No cleanup, everything is given to the callee. + * Note that the keys and values will leak for transfer everything because + * we do not use g_hash_table_new_full and set key/value_destroy_func. */ + *cleanup_data = NULL; + } + + return TRUE; +} + +static void +_pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + if (data == NULL) + return; + + if (was_processed) { + GHashTable *hash_; + PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; + + hash_ = (GHashTable *)data; + + /* clean up keys and values first */ + if (hash_cache->key_cache->from_py_cleanup != NULL || + hash_cache->value_cache->from_py_cleanup != NULL) { + GHashTableIter hiter; + gpointer key; + gpointer value; + + PyGIMarshalCleanupFunc key_cleanup_func = + hash_cache->key_cache->from_py_cleanup; + PyGIMarshalCleanupFunc value_cleanup_func = + hash_cache->value_cache->from_py_cleanup; + + g_hash_table_iter_init (&hiter, hash_); + while (g_hash_table_iter_next (&hiter, &key, &value)) { + if (key != NULL && key_cleanup_func != NULL) + key_cleanup_func (state, + hash_cache->key_cache, + NULL, + key, + TRUE); + if (value != NULL && value_cleanup_func != NULL) + value_cleanup_func (state, + hash_cache->value_cache, + NULL, + value, + TRUE); + } + } + + g_hash_table_unref (hash_); + } +} + +static PyObject * +_pygi_marshal_to_py_ghash (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + GHashTable *hash_; + GHashTableIter hash_table_iter; + + PyGIMarshalToPyFunc key_to_py_marshaller; + PyGIMarshalToPyFunc value_to_py_marshaller; + + PyGIArgCache *key_arg_cache; + PyGIArgCache *value_arg_cache; + PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; + + GIArgument key_arg; + GIArgument value_arg; + + PyObject *py_obj = NULL; + + hash_ = arg->v_pointer; + + if (hash_ == NULL) { + py_obj = Py_None; + Py_INCREF (py_obj); + return py_obj; + } + + py_obj = PyDict_New (); + if (py_obj == NULL) + return NULL; + + key_arg_cache = hash_cache->key_cache; + key_to_py_marshaller = key_arg_cache->to_py_marshaller; + + value_arg_cache = hash_cache->value_cache; + value_to_py_marshaller = value_arg_cache->to_py_marshaller; + + g_hash_table_iter_init (&hash_table_iter, hash_); + while (g_hash_table_iter_next (&hash_table_iter, + &key_arg.v_pointer, + &value_arg.v_pointer)) { + PyObject *py_key; + PyObject *py_value; + int retval; + + + _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag); + py_key = key_to_py_marshaller ( state, + callable_cache, + key_arg_cache, + &key_arg); + + if (py_key == NULL) { + Py_CLEAR (py_obj); + return NULL; + } + + _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag); + py_value = value_to_py_marshaller ( state, + callable_cache, + value_arg_cache, + &value_arg); + + if (py_value == NULL) { + Py_CLEAR (py_obj); + Py_DECREF(py_key); + return NULL; + } + + retval = PyDict_SetItem (py_obj, py_key, py_value); + + Py_DECREF (py_key); + Py_DECREF (py_value); + + if (retval < 0) { + Py_CLEAR (py_obj); + return NULL; + } + } + + return py_obj; +} + +static void +_pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + if (data == NULL) + return; + + /* assume hashtable has boxed key and value */ + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->transfer == GI_TRANSFER_CONTAINER) + g_hash_table_unref ( (GHashTable *)data); +} + +static void +_arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash; +} + +static void +_arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash; +} + +static gboolean +pygi_arg_hash_table_setup_from_info (PyGIHashCache *hc, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + GITypeInfo *key_type_info; + GITypeInfo *value_type_info; + GITransfer item_transfer; + + if (!pygi_arg_base_setup ((PyGIArgCache *)hc, type_info, arg_info, transfer, direction)) + return FALSE; + + ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func; + key_type_info = g_type_info_get_param_type (type_info, 0); + value_type_info = g_type_info_get_param_type (type_info, 1); + + item_transfer = + transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer; + + hc->key_cache = pygi_arg_cache_new (key_type_info, + NULL, + item_transfer, + direction, + 0, 0, + NULL); + + if (hc->key_cache == NULL) { + return FALSE; + } + + hc->value_cache = pygi_arg_cache_new (value_type_info, + NULL, + item_transfer, + direction, + 0, 0, + NULL); + + if (hc->value_cache == NULL) { + return FALSE; + } + + g_base_info_unref( (GIBaseInfo *)key_type_info); + g_base_info_unref( (GIBaseInfo *)value_type_info); + + if (direction & PYGI_DIRECTION_FROM_PYTHON) { + _arg_cache_from_py_ghash_setup ((PyGIArgCache *)hc); + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + _arg_cache_to_py_ghash_setup ((PyGIArgCache *)hc); + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_hash_table_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + gboolean res = FALSE; + PyGIHashCache *hc = NULL; + + hc = g_slice_new0 (PyGIHashCache); + if (hc == NULL) + return NULL; + + res = pygi_arg_hash_table_setup_from_info (hc, + type_info, + arg_info, + transfer, + direction); + if (res) { + return (PyGIArgCache *)hc; + } else { + pygi_arg_cache_free ((PyGIArgCache *)hc); + return NULL; + } +} diff --git a/gi/pygi-hashtable.h b/gi/pygi-hashtable.h new file mode 100644 index 0000000..a42aaf0 --- /dev/null +++ b/gi/pygi-hashtable.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2013 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_HASHTABLE_H__ +#define __PYGI_HASHTABLE_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_hash_table_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction); + +G_END_DECLS + +#endif /*__PYGI_HASHTABLE_H__*/ diff --git a/gi/pygi-info.c b/gi/pygi-info.c index af893ec..ffc9d4f 100644 --- a/gi/pygi-info.c +++ b/gi/pygi-info.c @@ -24,8 +24,8 @@ #include "pygi-private.h" #include "pygi-cache.h" +#include "pygobject-private.h" -#include #include @@ -177,7 +177,7 @@ _base_info_dealloc (PyGIBaseInfo *self) g_base_info_unref (self->info); - _pygi_callable_cache_free(self->cache); + pygi_callable_cache_free(self->cache); Py_TYPE( (PyObject *) self)->tp_free ( (PyObject *) self); } diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c index 675b0ef..1d89912 100644 --- a/gi/pygi-invoke.c +++ b/gi/pygi-invoke.c @@ -422,9 +422,9 @@ static gboolean _caller_alloc (PyGIInvokeState *state, state->args[arg_count]->v_pointer = g_malloc0 (size); } } else if (arg_cache->type_tag == GI_TYPE_TAG_ARRAY) { - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; + PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache; - state->out_args[out_count].v_pointer = g_array_new (TRUE, TRUE, seq_cache->item_size); + state->out_args[out_count].v_pointer = g_array_new (TRUE, TRUE, array_cache->item_size); state->args[arg_count] = &state->out_args[out_count]; } else { return FALSE; @@ -720,7 +720,7 @@ _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args, PyObject *kwargs) { if (self->cache == NULL) { - self->cache = _pygi_callable_cache_new (self->info, FALSE); + self->cache = pygi_callable_cache_new (self->info, FALSE); if (self->cache == NULL) return NULL; } diff --git a/gi/pygi-list.c b/gi/pygi-list.c new file mode 100644 index 0000000..af2afd8 --- /dev/null +++ b/gi/pygi-list.c @@ -0,0 +1,466 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "pygi-list.h" +#include "pygi-argument.h" +#include "pygi-private.h" + +typedef PyGISequenceCache PyGIArgGList; + +/* + * GList and GSList from Python + */ +static gboolean +_pygi_marshal_from_py_glist (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyGIMarshalFromPyFunc from_py_marshaller; + int i; + Py_ssize_t length; + GList *list_ = NULL; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (!PySequence_Check (py_arg)) { + PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + length = PySequence_Length (py_arg); + if (length < 0) + return FALSE; + + from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; + for (i = 0; i < length; i++) { + GIArgument item = {0}; + gpointer item_cleanup_data = NULL; + PyObject *py_item = PySequence_GetItem (py_arg, i); + if (py_item == NULL) + goto err; + + if (!from_py_marshaller ( state, + callable_cache, + sequence_cache->item_cache, + py_item, + &item, + &item_cleanup_data)) + goto err; + + Py_DECREF (py_item); + list_ = g_list_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag)); + continue; +err: + /* FIXME: clean up list + if (sequence_cache->item_cache->from_py_cleanup != NULL) { + PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup; + } + */ + Py_DECREF (py_item); + g_list_free (list_); + _PyGI_ERROR_PREFIX ("Item %i: ", i); + return FALSE; + } + + arg->v_pointer = g_list_reverse (list_); + + if (arg_cache->transfer == GI_TRANSFER_NOTHING) { + /* Free everything in cleanup. */ + *cleanup_data = arg->v_pointer; + } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { + /* Make a shallow copy so we can free the elements later in cleanup + * because it is possible invoke will free the list before our cleanup. */ + *cleanup_data = g_list_copy (arg->v_pointer); + } else { /* GI_TRANSFER_EVERYTHING */ + /* No cleanup, everything is given to the callee. */ + *cleanup_data = NULL; + } + return TRUE; +} + + +static gboolean +_pygi_marshal_from_py_gslist (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyGIMarshalFromPyFunc from_py_marshaller; + int i; + Py_ssize_t length; + GSList *list_ = NULL; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (!PySequence_Check (py_arg)) { + PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + length = PySequence_Length (py_arg); + if (length < 0) + return FALSE; + + from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; + for (i = 0; i < length; i++) { + GIArgument item = {0}; + gpointer item_cleanup_data = NULL; + PyObject *py_item = PySequence_GetItem (py_arg, i); + if (py_item == NULL) + goto err; + + if (!from_py_marshaller ( state, + callable_cache, + sequence_cache->item_cache, + py_item, + &item, + &item_cleanup_data)) + goto err; + + Py_DECREF (py_item); + list_ = g_slist_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag)); + continue; +err: + /* FIXME: Clean up list + if (sequence_cache->item_cache->from_py_cleanup != NULL) { + PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup; + } + */ + + Py_DECREF (py_item); + g_slist_free (list_); + _PyGI_ERROR_PREFIX ("Item %i: ", i); + return FALSE; + } + + arg->v_pointer = g_slist_reverse (list_); + + if (arg_cache->transfer == GI_TRANSFER_NOTHING) { + /* Free everything in cleanup. */ + *cleanup_data = arg->v_pointer; + } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { + /* Make a shallow copy so we can free the elements later in cleanup + * because it is possible invoke will free the list before our cleanup. */ + *cleanup_data = g_slist_copy (arg->v_pointer); + } else { /* GI_TRANSFER_EVERYTHING */ + /* No cleanup, everything is given to the callee. */ + *cleanup_data = NULL; + } + + return TRUE; +} + +static void +_pygi_marshal_cleanup_from_py_glist (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + if (was_processed) { + GSList *list_; + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + + list_ = (GSList *)data; + + /* clean up items first */ + if (sequence_cache->item_cache->from_py_cleanup != NULL) { + PyGIMarshalCleanupFunc cleanup_func = + sequence_cache->item_cache->from_py_cleanup; + GSList *node = list_; + gsize i = 0; + while (node != NULL) { + PyObject *py_item = PySequence_GetItem (py_arg, i); + cleanup_func (state, + sequence_cache->item_cache, + py_item, + node->data, + TRUE); + Py_XDECREF (py_item); + node = node->next; + i++; + } + } + + if (arg_cache->type_tag == GI_TYPE_TAG_GLIST) { + g_list_free ( (GList *)list_); + } else if (arg_cache->type_tag == GI_TYPE_TAG_GSLIST) { + g_slist_free (list_); + } else { + g_assert_not_reached(); + } + } +} + + +/* + * GList and GSList to Python + */ +static PyObject * +_pygi_marshal_to_py_glist (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + GList *list_; + gsize length; + gsize i; + + PyGIMarshalToPyFunc item_to_py_marshaller; + PyGIArgCache *item_arg_cache; + PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; + + PyObject *py_obj = NULL; + + list_ = arg->v_pointer; + length = g_list_length (list_); + + py_obj = PyList_New (length); + if (py_obj == NULL) + return NULL; + + item_arg_cache = seq_cache->item_cache; + item_to_py_marshaller = item_arg_cache->to_py_marshaller; + + for (i = 0; list_ != NULL; list_ = g_list_next (list_), i++) { + GIArgument item_arg; + PyObject *py_item; + + item_arg.v_pointer = list_->data; + _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag); + py_item = item_to_py_marshaller (state, + callable_cache, + item_arg_cache, + &item_arg); + + if (py_item == NULL) { + Py_CLEAR (py_obj); + _PyGI_ERROR_PREFIX ("Item %zu: ", i); + return NULL; + } + + PyList_SET_ITEM (py_obj, i, py_item); + } + + return py_obj; +} + +static PyObject * +_pygi_marshal_to_py_gslist (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + GSList *list_; + gsize length; + gsize i; + + PyGIMarshalToPyFunc item_to_py_marshaller; + PyGIArgCache *item_arg_cache; + PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; + + PyObject *py_obj = NULL; + + list_ = arg->v_pointer; + length = g_slist_length (list_); + + py_obj = PyList_New (length); + if (py_obj == NULL) + return NULL; + + item_arg_cache = seq_cache->item_cache; + item_to_py_marshaller = item_arg_cache->to_py_marshaller; + + for (i = 0; list_ != NULL; list_ = g_slist_next (list_), i++) { + GIArgument item_arg; + PyObject *py_item; + + item_arg.v_pointer = list_->data; + _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag); + py_item = item_to_py_marshaller (state, + callable_cache, + item_arg_cache, + &item_arg); + + if (py_item == NULL) { + Py_CLEAR (py_obj); + _PyGI_ERROR_PREFIX ("Item %zu: ", i); + return NULL; + } + + PyList_SET_ITEM (py_obj, i, py_item); + } + + return py_obj; +} + +static void +_pygi_marshal_cleanup_to_py_glist (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; + if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || + arg_cache->transfer == GI_TRANSFER_CONTAINER) { + GSList *list_ = (GSList *)data; + + if (sequence_cache->item_cache->to_py_cleanup != NULL) { + PyGIMarshalCleanupFunc cleanup_func = + sequence_cache->item_cache->to_py_cleanup; + GSList *node = list_; + + while (node != NULL) { + cleanup_func (state, + sequence_cache->item_cache, + NULL, + node->data, + was_processed); + node = node->next; + } + } + + if (arg_cache->type_tag == GI_TYPE_TAG_GLIST) { + g_list_free ( (GList *)list_); + } else if (arg_cache->type_tag == GI_TYPE_TAG_GSLIST) { + g_slist_free (list_); + } else { + g_assert_not_reached(); + } + } +} + +static void +_arg_cache_from_py_glist_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_glist; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist; +} + +static void +_arg_cache_to_py_glist_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_glist; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist; +} + +static void +_arg_cache_from_py_gslist_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->from_py_marshaller = _pygi_marshal_from_py_gslist; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist; +} + +static void +_arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache, + GITransfer transfer) +{ + arg_cache->to_py_marshaller = _pygi_marshal_to_py_gslist; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist; +} + + +/* + * GList/GSList Interface + */ + +static gboolean +pygi_arg_glist_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + GITypeTag type_tag = g_type_info_get_tag (type_info); + + if (!pygi_arg_sequence_setup ((PyGISequenceCache *)arg_cache, type_info, arg_info, transfer, direction)) + return FALSE; + + switch (type_tag) { + case GI_TYPE_TAG_GLIST: + { + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_glist_setup (arg_cache, transfer); + + if (direction & PYGI_DIRECTION_TO_PYTHON) + _arg_cache_to_py_glist_setup (arg_cache, transfer); + break; + } + case GI_TYPE_TAG_GSLIST: + { + if (direction & PYGI_DIRECTION_FROM_PYTHON) + _arg_cache_from_py_gslist_setup (arg_cache, transfer); + + if (direction & PYGI_DIRECTION_TO_PYTHON) + _arg_cache_to_py_gslist_setup (arg_cache, transfer); + + break; + } + default: + g_assert_not_reached (); + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_glist_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + gboolean res = FALSE; + + PyGIArgCache *arg_cache = (PyGIArgCache *) g_slice_new0 (PyGIArgGList); + if (arg_cache == NULL) + return NULL; + + res = pygi_arg_glist_setup_from_info (arg_cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return arg_cache; + } else { + pygi_arg_cache_free (arg_cache); + return NULL; + } +} diff --git a/gi/pygi-list.h b/gi/pygi-list.h new file mode 100644 index 0000000..59f03b2 --- /dev/null +++ b/gi/pygi-list.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_LIST_H__ +#define __PYGI_LIST_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_glist_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction); + +/* Internally dispatches GList and GSList */ +#define pygi_arg_gslist_new_from_info pygi_arg_glist_new_from_info + +G_END_DECLS + +#endif /*__PYGI_LIST_H__*/ diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c index 33d0339..3d82601 100644 --- a/gi/pygi-marshal-cleanup.c +++ b/gi/pygi-marshal-cleanup.c @@ -205,409 +205,3 @@ pygi_marshal_cleanup_args_to_py_parameter_fail (PyGIInvokeState *state, { state->failed = TRUE; } - -void -_pygi_marshal_cleanup_from_py_utf8 (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - /* We strdup strings so free unless ownership is transferred to C. */ - if (was_processed && arg_cache->transfer == GI_TRANSFER_NOTHING) - g_free (data); -} - -void -_pygi_marshal_cleanup_to_py_utf8 (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - /* Python copies the string so we need to free it - if the interface is transfering ownership, - whether or not it has been processed yet */ - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) - g_free (data); -} - -void -_pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - /* If we processed the parameter but fail before invoking the method, - we need to remove the ref we added */ - if (was_processed && state->failed && data != NULL && - arg_cache->transfer == GI_TRANSFER_EVERYTHING) - g_object_unref (G_OBJECT(data)); -} - -void -_pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - /* If we error out and the object is not marshalled into a PyGObject - we must take care of removing the ref */ - if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) - g_object_unref (G_OBJECT(data)); -} - - -void -_pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache; - if (was_processed && callback_cache->scope == GI_SCOPE_TYPE_CALL) { - _pygi_invoke_closure_free (data); - } -} - -void -_pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - /* Note py_arg can be NULL for hash table which is a bug. */ - if (was_processed && py_arg != NULL) { - GType py_object_type = - pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE); - - /* When a GValue was not passed, it means the marshalers created a new - * one to pass in, clean this up. - */ - if (py_object_type != G_TYPE_VALUE) { - g_value_unset ((GValue *) data); - g_slice_free (GValue, data); - } - } -} - -void -_pygi_marshal_cleanup_from_py_interface_struct_foreign (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - if (state->failed && was_processed) - pygi_struct_foreign_release ( - ( (PyGIInterfaceCache *)arg_cache)->interface_info, - data); -} - -void -_pygi_marshal_cleanup_to_py_interface_struct_foreign (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) - pygi_struct_foreign_release ( - ( (PyGIInterfaceCache *)arg_cache)->interface_info, - data); -} - -static GArray* -_wrap_c_array (PyGIInvokeState *state, - PyGISequenceCache *sequence_cache, - gpointer data) -{ - GArray *array_; - gsize len = 0; - - if (sequence_cache->fixed_size >= 0) { - len = sequence_cache->fixed_size; - } else if (sequence_cache->is_zero_terminated) { - len = g_strv_length ((gchar **)data); - } else if (sequence_cache->len_arg_index >= 0) { - GIArgument *len_arg = state->args[sequence_cache->len_arg_index]; - len = len_arg->v_long; - } - - array_ = g_array_new (FALSE, - FALSE, - sequence_cache->item_size); - - if (array_ == NULL) - return NULL; - - g_free (array_->data); - array_->data = data; - array_->len = len; - - return array_; -} - -void -_pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - if (was_processed) { - GArray *array_ = NULL; - GPtrArray *ptr_array_ = NULL; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - if (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { - ptr_array_ = (GPtrArray *) data; - } else { - array_ = (GArray *) data; - } - - /* clean up items first */ - if (sequence_cache->item_cache->from_py_cleanup != NULL) { - gsize i; - guint len = (array_ != NULL) ? array_->len : ptr_array_->len; - PyGIMarshalCleanupFunc cleanup_func = - sequence_cache->item_cache->from_py_cleanup; - - for (i = 0; i < len; i++) { - gpointer item; - PyObject *py_item = NULL; - - /* case 1: GPtrArray */ - if (ptr_array_ != NULL) - item = g_ptr_array_index (ptr_array_, i); - /* case 2: C array or GArray with object pointers */ - else if (sequence_cache->item_cache->is_pointer) - item = g_array_index (array_, gpointer, i); - /* case 3: C array or GArray with simple types or structs */ - else { - item = array_->data + i * sequence_cache->item_size; - /* special-case hack: GValue array items do not get slice - * allocated in _pygi_marshal_from_py_array(), so we must - * not try to deallocate it as a slice and thus - * short-circuit cleanup_func. */ - if (cleanup_func == _pygi_marshal_cleanup_from_py_interface_struct_gvalue) { - g_value_unset ((GValue*) item); - continue; - } - } - - py_item = PySequence_GetItem (py_arg, i); - cleanup_func (state, sequence_cache->item_cache, py_item, item, TRUE); - Py_XDECREF (py_item); - } - } - - /* Only free the array when we didn't transfer ownership */ - if (sequence_cache->array_type == GI_ARRAY_TYPE_C) { - /* always free the GArray wrapper created in from_py marshaling and - * passed back as cleanup_data - */ - g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING); - } else { - if (array_ != NULL) - g_array_unref (array_); - else - g_ptr_array_unref (ptr_array_); - } - } -} - -void -_pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || - arg_cache->transfer == GI_TRANSFER_CONTAINER) { - GArray *array_ = NULL; - GPtrArray *ptr_array_ = NULL; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - /* If this isn't a garray create one to help process variable sized - array elements */ - if (sequence_cache->array_type == GI_ARRAY_TYPE_C) { - array_ = _wrap_c_array (state, sequence_cache, data); - - if (array_ == NULL) - return; - - } else if (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { - ptr_array_ = (GPtrArray *) data; - } else { - array_ = (GArray *) data; - } - - if (sequence_cache->item_cache->to_py_cleanup != NULL) { - gsize i; - guint len = (array_ != NULL) ? array_->len : ptr_array_->len; - - PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup; - for (i = 0; i < len; i++) { - cleanup_func (state, - sequence_cache->item_cache, - NULL, - (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i), - was_processed); - } - } - - if (array_ != NULL) - g_array_free (array_, TRUE); - else - g_ptr_array_free (ptr_array_, TRUE); - } -} - -void -_pygi_marshal_cleanup_from_py_glist (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - if (was_processed) { - GSList *list_; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - list_ = (GSList *)data; - - /* clean up items first */ - if (sequence_cache->item_cache->from_py_cleanup != NULL) { - PyGIMarshalCleanupFunc cleanup_func = - sequence_cache->item_cache->from_py_cleanup; - GSList *node = list_; - gsize i = 0; - while (node != NULL) { - PyObject *py_item = PySequence_GetItem (py_arg, i); - cleanup_func (state, - sequence_cache->item_cache, - py_item, - node->data, - TRUE); - Py_XDECREF (py_item); - node = node->next; - i++; - } - } - - if (arg_cache->type_tag == GI_TYPE_TAG_GLIST) { - g_list_free ( (GList *)list_); - } else if (arg_cache->type_tag == GI_TYPE_TAG_GSLIST) { - g_slist_free (list_); - } else { - g_assert_not_reached(); - } - } -} - -void -_pygi_marshal_cleanup_to_py_glist (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || - arg_cache->transfer == GI_TRANSFER_CONTAINER) { - GSList *list_ = (GSList *)data; - - if (sequence_cache->item_cache->to_py_cleanup != NULL) { - PyGIMarshalCleanupFunc cleanup_func = - sequence_cache->item_cache->to_py_cleanup; - GSList *node = list_; - - while (node != NULL) { - cleanup_func (state, - sequence_cache->item_cache, - NULL, - node->data, - was_processed); - node = node->next; - } - } - - if (arg_cache->type_tag == GI_TYPE_TAG_GLIST) { - g_list_free ( (GList *)list_); - } else if (arg_cache->type_tag == GI_TYPE_TAG_GSLIST) { - g_slist_free (list_); - } else { - g_assert_not_reached(); - } - } -} - -void -_pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed) -{ - if (data == NULL) - return; - - if (was_processed) { - GHashTable *hash_; - PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; - - hash_ = (GHashTable *)data; - - /* clean up keys and values first */ - if (hash_cache->key_cache->from_py_cleanup != NULL || - hash_cache->value_cache->from_py_cleanup != NULL) { - GHashTableIter hiter; - gpointer key; - gpointer value; - - PyGIMarshalCleanupFunc key_cleanup_func = - hash_cache->key_cache->from_py_cleanup; - PyGIMarshalCleanupFunc value_cleanup_func = - hash_cache->value_cache->from_py_cleanup; - - g_hash_table_iter_init (&hiter, hash_); - while (g_hash_table_iter_next (&hiter, &key, &value)) { - if (key != NULL && key_cleanup_func != NULL) - key_cleanup_func (state, - hash_cache->key_cache, - NULL, - key, - TRUE); - if (value != NULL && value_cleanup_func != NULL) - value_cleanup_func (state, - hash_cache->value_cache, - NULL, - value, - TRUE); - } - } - - g_hash_table_unref (hash_); - } -} - -void -_pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed) -{ - if (data == NULL) - return; - - /* assume hashtable has boxed key and value */ - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->transfer == GI_TRANSFER_CONTAINER) - g_hash_table_unref ( (GHashTable *)data); -} diff --git a/gi/pygi-marshal-cleanup.h b/gi/pygi-marshal-cleanup.h index 3acfbeb..e895f37 100644 --- a/gi/pygi-marshal-cleanup.h +++ b/gi/pygi-marshal-cleanup.h @@ -39,77 +39,6 @@ void pygi_marshal_cleanup_args_return_fail (PyGIInvokeState *state, void pygi_marshal_cleanup_args_to_py_parameter_fail (PyGIInvokeState *state, PyGICallableCache *cache, gssize failed_to_py_arg_index); - -void _pygi_marshal_cleanup_from_py_utf8 (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_utf8 (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_interface_struct_foreign (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_interface_struct_foreign (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_interface_callback (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_glist (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_glist (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *py_arg, - gpointer data, - gboolean was_processed); -void _pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state, - PyGIArgCache *arg_cache, - PyObject *dummy, - gpointer data, - gboolean was_processed); G_END_DECLS #endif /* __PYGI_MARSHAL_CLEANUP_H__ */ diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c deleted file mode 100644 index 41dcf54..0000000 --- a/gi/pygi-marshal-from-py.c +++ /dev/null @@ -1,1918 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * vim: tabstop=4 shiftwidth=4 expandtab - * - * Copyright (C) 2011 John (J5) Palmieri , Red Hat, Inc. - * - * pygi-marshal-from-py.c: Functions to convert PyObjects to C types. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#include "pygi-private.h" - -#include -#include -#include -#include - -#include "pygi-cache.h" -#include "pygi-marshal-cleanup.h" -#include "pygi-marshal-from-py.h" - -#ifdef _WIN32 -#ifdef _MSC_VER -#include - -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float *) __nan) -#endif - -#ifndef INFINITY -#define INFINITY HUGE_VAL -#endif - -#endif -#endif - -static gboolean -gi_argument_from_py_ssize_t (GIArgument *arg_out, - Py_ssize_t size_in, - GITypeTag type_tag) -{ - switch (type_tag) { - case GI_TYPE_TAG_VOID: - case GI_TYPE_TAG_BOOLEAN: - goto unhandled_type; - - case GI_TYPE_TAG_INT8: - if (size_in >= G_MININT8 && size_in <= G_MAXINT8) { - arg_out->v_int8 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_UINT8: - if (size_in >= 0 && size_in <= G_MAXUINT8) { - arg_out->v_uint8 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_INT16: - if (size_in >= G_MININT16 && size_in <= G_MAXINT16) { - arg_out->v_int16 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_UINT16: - if (size_in >= 0 && size_in <= G_MAXUINT16) { - arg_out->v_uint16 = size_in; - return TRUE; - } else { - goto overflow; - } - - /* Ranges assume two's complement */ - case GI_TYPE_TAG_INT32: - if (size_in >= G_MININT32 && size_in <= G_MAXINT32) { - arg_out->v_int32 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_UINT32: - if (size_in >= 0 && size_in <= G_MAXUINT32) { - arg_out->v_uint32 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_INT64: - arg_out->v_int64 = size_in; - return TRUE; - - case GI_TYPE_TAG_UINT64: - if (size_in >= 0) { - arg_out->v_uint64 = size_in; - return TRUE; - } else { - goto overflow; - } - - case GI_TYPE_TAG_FLOAT: - case GI_TYPE_TAG_DOUBLE: - case GI_TYPE_TAG_GTYPE: - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_INTERFACE: - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - case GI_TYPE_TAG_GHASH: - case GI_TYPE_TAG_ERROR: - case GI_TYPE_TAG_UNICHAR: - default: - goto unhandled_type; - } - - overflow: - PyErr_Format (PyExc_OverflowError, - "Unable to marshal C Py_ssize_t %zd to %s", - size_in, - g_type_tag_to_string (type_tag)); - return FALSE; - - unhandled_type: - PyErr_Format (PyExc_TypeError, - "Unable to marshal C Py_ssize_t %zd to %s", - size_in, - g_type_tag_to_string (type_tag)); - return FALSE; -} - -static gboolean -gi_argument_from_c_long (GIArgument *arg_out, - long c_long_in, - GITypeTag type_tag) -{ - switch (type_tag) { - case GI_TYPE_TAG_INT8: - arg_out->v_int8 = c_long_in; - return TRUE; - case GI_TYPE_TAG_UINT8: - arg_out->v_uint8 = c_long_in; - return TRUE; - case GI_TYPE_TAG_INT16: - arg_out->v_int16 = c_long_in; - return TRUE; - case GI_TYPE_TAG_UINT16: - arg_out->v_uint16 = c_long_in; - return TRUE; - case GI_TYPE_TAG_INT32: - arg_out->v_int32 = c_long_in; - return TRUE; - case GI_TYPE_TAG_UINT32: - arg_out->v_uint32 = c_long_in; - return TRUE; - case GI_TYPE_TAG_INT64: - arg_out->v_int64 = c_long_in; - return TRUE; - case GI_TYPE_TAG_UINT64: - arg_out->v_uint64 = c_long_in; - return TRUE; - default: - PyErr_Format (PyExc_TypeError, - "Unable to marshal C long %ld to %s", - c_long_in, - g_type_tag_to_string (type_tag)); - return FALSE; - } -} - -/* - * _is_union_member - check to see if the py_arg is actually a member of the - * expected C union - */ -static gboolean -_is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) { - gint i; - gint n_fields; - GIUnionInfo *union_info; - GIInfoType info_type; - gboolean is_member = FALSE; - - info_type = g_base_info_get_type (interface_info); - - if (info_type != GI_INFO_TYPE_UNION) - return FALSE; - - union_info = (GIUnionInfo *) interface_info; - n_fields = g_union_info_get_n_fields (union_info); - - for (i = 0; i < n_fields; i++) { - GIFieldInfo *field_info; - GITypeInfo *field_type_info; - - field_info = g_union_info_get_field (union_info, i); - field_type_info = g_field_info_get_type (field_info); - - /* we can only check if the members are interfaces */ - if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) { - GIInterfaceInfo *field_iface_info; - PyObject *py_type; - - field_iface_info = g_type_info_get_interface (field_type_info); - py_type = _pygi_type_import_by_gi_info ((GIBaseInfo *) field_iface_info); - - if (py_type != NULL && PyObject_IsInstance (py_arg, py_type)) { - is_member = TRUE; - } - - Py_XDECREF (py_type); - g_base_info_unref ( ( GIBaseInfo *) field_iface_info); - } - - g_base_info_unref ( ( GIBaseInfo *) field_type_info); - g_base_info_unref ( ( GIBaseInfo *) field_info); - - if (is_member) - break; - } - - return is_member; -} - -gboolean -_pygi_marshal_from_py_void (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING); - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - } else if (PYGLIB_CPointer_Check(py_arg)) { - arg->v_pointer = PYGLIB_CPointer_GetPointer (py_arg, NULL); - } else if (PYGLIB_PyLong_Check(py_arg) || PyLong_Check(py_arg)) { - arg->v_pointer = PyLong_AsVoidPtr (py_arg); - } else { - PyErr_SetString(PyExc_ValueError, - "Pointer arguments are restricted to integers, capsules, and None. " - "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); - return FALSE; - } - - *cleanup_data = arg->v_pointer; - return TRUE; -} - -static gboolean -check_valid_double (double x, double min, double max) -{ - char buf[100]; - - if ((x < min || x > max) && x != INFINITY && x != -INFINITY && x != NAN) { - if (PyErr_Occurred()) - PyErr_Clear (); - - /* we need this as PyErr_Format() does not support float types */ - snprintf (buf, sizeof (buf), "%g not in range %g to %g", x, min, max); - PyErr_SetString (PyExc_OverflowError, buf); - return FALSE; - } - return TRUE; -} - -static gboolean -_pygi_py_arg_to_double (PyObject *py_arg, double *double_) -{ - PyObject *py_float; - - if (!PyNumber_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, "Must be number, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - py_float = PyNumber_Float (py_arg); - if (!py_float) - return FALSE; - - *double_ = PyFloat_AsDouble (py_float); - Py_DECREF (py_float); - - - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_float (PyObject *py_arg, - GIArgument *arg) -{ - double double_; - - if (!_pygi_py_arg_to_double (py_arg, &double_)) - return FALSE; - - if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXFLOAT, G_MAXFLOAT)) - return FALSE; - - arg->v_float = double_; - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_double (PyObject *py_arg, - GIArgument *arg) -{ - double double_; - - if (!_pygi_py_arg_to_double (py_arg, &double_)) - return FALSE; - - if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXDOUBLE, G_MAXDOUBLE)) - return FALSE; - - arg->v_double = double_; - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_unichar (PyObject *py_arg, - GIArgument *arg) -{ - Py_ssize_t size; - gchar *string_; - - if (py_arg == Py_None) { - arg->v_uint32 = 0; - return FALSE; - } - - if (PyUnicode_Check (py_arg)) { - PyObject *py_bytes; - - size = PyUnicode_GET_SIZE (py_arg); - py_bytes = PyUnicode_AsUTF8String (py_arg); - if (!py_bytes) - return FALSE; - - string_ = g_strdup(PYGLIB_PyBytes_AsString (py_bytes)); - Py_DECREF (py_bytes); - -#if PY_VERSION_HEX < 0x03000000 - } else if (PyString_Check (py_arg)) { - PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict"); - if (!pyuni) - return FALSE; - - size = PyUnicode_GET_SIZE (pyuni); - string_ = g_strdup (PyString_AsString(py_arg)); - Py_DECREF (pyuni); -#endif - } else { - PyErr_Format (PyExc_TypeError, "Must be string, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - if (size != 1) { - PyErr_Format (PyExc_TypeError, "Must be a one character string, not %lld characters", - (long long) size); - g_free (string_); - return FALSE; - } - - arg->v_uint32 = g_utf8_get_char (string_); - g_free (string_); - - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_gtype (PyObject *py_arg, - GIArgument *arg) -{ - long type_ = pyg_type_from_object (py_arg); - - if (type_ == 0) { - PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - arg->v_long = type_; - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_utf8 (PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - gchar *string_; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (PyUnicode_Check (py_arg)) { - PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg); - if (!pystr_obj) - return FALSE; - - string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj)); - Py_DECREF (pystr_obj); - } -#if PY_VERSION_HEX < 0x03000000 - else if (PyString_Check (py_arg)) { - string_ = g_strdup (PyString_AsString (py_arg)); - } -#endif - else { - PyErr_Format (PyExc_TypeError, "Must be string, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - arg->v_string = string_; - *cleanup_data = arg->v_string; - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_filename (PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - gchar *string_; - GError *error = NULL; - - if (PyUnicode_Check (py_arg)) { - PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg); - if (!pystr_obj) - return FALSE; - - string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj)); - Py_DECREF (pystr_obj); - } -#if PY_VERSION_HEX < 0x03000000 - else if (PyString_Check (py_arg)) { - string_ = g_strdup (PyString_AsString (py_arg)); - } -#endif - else { - PyErr_Format (PyExc_TypeError, "Must be string, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error); - g_free (string_); - - if (arg->v_string == NULL) { - PyErr_SetString (PyExc_Exception, error->message); - g_error_free (error); - /* TODO: Convert the error to an exception. */ - return FALSE; - } - - *cleanup_data = arg->v_string; - return TRUE; -} - -static gboolean -_pygi_marshal_from_py_long (PyObject *object, /* in */ - GIArgument *arg, /* out */ - GITypeTag type_tag, - GITransfer transfer) -{ - PyObject *number; - - if (!PyNumber_Check (object)) { - PyErr_Format (PyExc_TypeError, "Must be number, not %s", - object->ob_type->tp_name); - return FALSE; - } - -#if PY_MAJOR_VERSION < 3 - { - PyObject *tmp = PyNumber_Int (object); - if (tmp) { - number = PyNumber_Long (tmp); - Py_DECREF (tmp); - } else { - number = PyNumber_Long (object); - } - } -#else - number = PyNumber_Long (object); -#endif - - if (number == NULL) { - PyErr_SetString (PyExc_TypeError, "expected int argument"); - return FALSE; - } - - switch (type_tag) { - case GI_TYPE_TAG_INT8: - { - long long_value = PyLong_AsLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < G_MININT8 || long_value > G_MAXINT8) { - PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", - long_value, (long)G_MININT8, (long)G_MAXINT8); - } else { - arg->v_int8 = long_value; - } - break; - } - - case GI_TYPE_TAG_UINT8: - { - long long_value = PyLong_AsLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < 0 || long_value > G_MAXUINT8) { - PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", - long_value, (long)0, (long)G_MAXUINT8); - } else { - arg->v_uint8 = long_value; - } - break; - } - - case GI_TYPE_TAG_INT16: - { - long long_value = PyLong_AsLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < G_MININT16 || long_value > G_MAXINT16) { - PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", - long_value, (long)G_MININT16, (long)G_MAXINT16); - } else { - arg->v_int16 = long_value; - } - break; - } - - case GI_TYPE_TAG_UINT16: - { - long long_value = PyLong_AsLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < 0 || long_value > G_MAXUINT16) { - PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", - long_value, (long)0, (long)G_MAXUINT16); - } else { - arg->v_uint16 = long_value; - } - break; - } - - case GI_TYPE_TAG_INT32: - { - long long_value = PyLong_AsLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < G_MININT32 || long_value > G_MAXINT32) { - PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld", - long_value, (long)G_MININT32, (long)G_MAXINT32); - } else { - arg->v_int32 = long_value; - } - break; - } - - case GI_TYPE_TAG_UINT32: - { - PY_LONG_LONG long_value = PyLong_AsLongLong (number); - if (PyErr_Occurred()) { - break; - } else if (long_value < 0 || long_value > G_MAXUINT32) { - PyErr_Format (PyExc_OverflowError, "%lld not in range %ld to %lu", - long_value, (long)0, (unsigned long)G_MAXUINT32); - } else { - arg->v_uint32 = long_value; - } - break; - } - - case GI_TYPE_TAG_INT64: - { - /* Rely on Python overflow error and convert to ValueError for 64 bit values */ - arg->v_int64 = PyLong_AsLongLong (number); - break; - } - - case GI_TYPE_TAG_UINT64: - { - /* Rely on Python overflow error and convert to ValueError for 64 bit values */ - arg->v_uint64 = PyLong_AsUnsignedLongLong (number); - break; - } - - default: - g_assert_not_reached (); - } - - Py_DECREF (number); - - if (PyErr_Occurred()) - return FALSE; - return TRUE; -} - -gboolean -_pygi_marshal_from_py_basic_type (PyObject *object, /* in */ - GIArgument *arg, /* out */ - GITypeTag type_tag, - GITransfer transfer, - gpointer *cleanup_data /* out */) -{ - switch (type_tag) { - case GI_TYPE_TAG_VOID: - g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); - if (object == Py_None) { - arg->v_pointer = NULL; - } else if (!PYGLIB_PyLong_Check(object) && !PyLong_Check(object)) { - PyErr_SetString(PyExc_TypeError, - "Pointer assignment is restricted to integer values. " - "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); - } else { - arg->v_pointer = PyLong_AsVoidPtr (object); - *cleanup_data = arg->v_pointer; - } - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - if (PYGLIB_PyBytes_Check (object)) { - if (PYGLIB_PyBytes_Size (object) != 1) { - PyErr_Format (PyExc_TypeError, "Must be a single character"); - return FALSE; - } - if (type_tag == GI_TYPE_TAG_INT8) { - arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]); - } else { - arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]); - } - } else { - return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); - } - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); - - case GI_TYPE_TAG_BOOLEAN: - arg->v_boolean = PyObject_IsTrue (object); - break; - - case GI_TYPE_TAG_FLOAT: - return _pygi_marshal_from_py_float (object, arg); - - case GI_TYPE_TAG_DOUBLE: - return _pygi_marshal_from_py_double (object, arg); - - case GI_TYPE_TAG_GTYPE: - return _pygi_marshal_from_py_gtype (object, arg); - - case GI_TYPE_TAG_UNICHAR: - return _pygi_marshal_from_py_unichar (object, arg); - - case GI_TYPE_TAG_UTF8: - return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data); - - case GI_TYPE_TAG_FILENAME: - return _pygi_marshal_from_py_filename (object, arg, cleanup_data); - - default: - return FALSE; - } - - if (PyErr_Occurred()) - return FALSE; - - return TRUE; -} - -gboolean -_pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - return _pygi_marshal_from_py_basic_type (py_arg, - arg, - arg_cache->type_tag, - arg_cache->transfer, - cleanup_data); -} - -gboolean -_pygi_marshal_from_py_array (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyGIMarshalFromPyFunc from_py_marshaller; - int i = 0; - int success_count = 0; - Py_ssize_t length; - gssize item_size; - gboolean is_ptr_array; - GArray *array_ = NULL; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (!PySequence_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - length = PySequence_Length (py_arg); - if (length < 0) - return FALSE; - - if (sequence_cache->fixed_size >= 0 && - sequence_cache->fixed_size != length) { - PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd", - sequence_cache->fixed_size, length); - - return FALSE; - } - - item_size = sequence_cache->item_size; - is_ptr_array = (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY); - if (is_ptr_array) { - array_ = (GArray *)g_ptr_array_sized_new (length); - } else { - array_ = g_array_sized_new (sequence_cache->is_zero_terminated, - TRUE, - item_size, - length); - } - - if (array_ == NULL) { - PyErr_NoMemory (); - return FALSE; - } - - if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 && - PYGLIB_PyBytes_Check (py_arg)) { - memcpy(array_->data, PYGLIB_PyBytes_AsString (py_arg), length); - array_->len = length; - if (sequence_cache->is_zero_terminated) { - /* If array_ has been created with zero_termination, space for the - * terminator is properly allocated, so we're not off-by-one here. */ - array_->data[length] = '\0'; - } - goto array_success; - } - - from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; - for (i = 0, success_count = 0; i < length; i++) { - GIArgument item = {0}; - gpointer item_cleanup_data = NULL; - PyObject *py_item = PySequence_GetItem (py_arg, i); - if (py_item == NULL) - goto err; - - if (!from_py_marshaller ( state, - callable_cache, - sequence_cache->item_cache, - py_item, - &item, - &item_cleanup_data)) { - Py_DECREF (py_item); - goto err; - } - Py_DECREF (py_item); - - if (item_cleanup_data != NULL && item_cleanup_data != item.v_pointer) { - /* We only support one level of data discrepancy between an items - * data and its cleanup data. This is because we only track a single - * extra cleanup data pointer per-argument and cannot track the entire - * array of items differing data and cleanup_data. - * For example, this would fail if trying to marshal an array of - * callback closures marked with SCOPE call type where the cleanup data - * is different from the items v_pointer, likewise an array of arrays. - */ - PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to " - "the items data its cleanup data being different."); - goto err; - } - - /* FIXME: it is much more efficent to have seperate marshaller - * for ptr arrays than doing the evaluation - * and casting each loop iteration - */ - if (is_ptr_array) { - g_ptr_array_add((GPtrArray *)array_, item.v_pointer); - } else if (sequence_cache->item_cache->is_pointer) { - /* if the item is a pointer, simply copy the pointer */ - g_assert (item_size == sizeof (item.v_pointer)); - g_array_insert_val (array_, i, item); - } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) { - /* Special case handling of flat arrays of gvalue/boxed/struct */ - PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache; - GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info; - GIInfoType info_type = g_base_info_get_type (base_info); - - switch (info_type) { - case GI_INFO_TYPE_UNION: - case GI_INFO_TYPE_STRUCT: - { - PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache; - PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup; - - if (g_type_is_a (item_iface_cache->g_type, G_TYPE_VALUE)) { - /* Special case GValue flat arrays to properly init and copy the contents. */ - GValue* dest = (GValue*) (array_->data + (i * item_size)); - if (item.v_pointer != NULL) { - memset (dest, 0, item_size); - g_value_init (dest, G_VALUE_TYPE ((GValue*) item.v_pointer)); - g_value_copy ((GValue*) item.v_pointer, dest); - } - /* Manually increment the length because we are manually setting the memory. */ - array_->len++; - - } else { - /* Handles flat arrays of boxed or struct types. */ - g_array_insert_vals (array_, i, item.v_pointer, 1); - } - - /* Cleanup any memory left by the per-item marshaler because - * _pygi_marshal_cleanup_from_py_array will not know about this - * due to "item" being a temporarily marshaled value done on the stack. - */ - if (from_py_cleanup) - from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE); - - break; - } - default: - g_array_insert_val (array_, i, item); - } - } else { - /* default value copy of a simple type */ - g_array_insert_val (array_, i, item); - } - - success_count++; - continue; -err: - if (sequence_cache->item_cache->from_py_cleanup != NULL) { - gsize j; - PyGIMarshalCleanupFunc cleanup_func = - sequence_cache->item_cache->from_py_cleanup; - - /* Only attempt per item cleanup on pointer items */ - if (sequence_cache->item_cache->is_pointer) { - for(j = 0; j < success_count; j++) { - PyObject *py_item = PySequence_GetItem (py_arg, j); - cleanup_func (state, - sequence_cache->item_cache, - py_item, - is_ptr_array ? - g_ptr_array_index ((GPtrArray *)array_, j) : - g_array_index (array_, gpointer, j), - TRUE); - Py_DECREF (py_item); - } - } - } - - if (is_ptr_array) - g_ptr_array_free ( ( GPtrArray *)array_, TRUE); - else - g_array_free (array_, TRUE); - _PyGI_ERROR_PREFIX ("Item %i: ", i); - return FALSE; - } - -array_success: - if (sequence_cache->len_arg_index >= 0) { - /* we have an child arg to handle */ - PyGIArgCache *child_cache = - _pygi_callable_cache_get_arg (callable_cache, sequence_cache->len_arg_index); - - if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) { - gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer; - /* if we are not setup yet just set the in arg */ - if (len_arg == NULL) { - if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index], - length, - child_cache->type_tag)) { - goto err; - } - } else { - *len_arg = length; - } - } else { - if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index], - length, - child_cache->type_tag)) { - goto err; - } - } - } - - if (sequence_cache->array_type == GI_ARRAY_TYPE_C) { - /* In the case of GI_ARRAY_C, we give the data directly as the argument - * but keep the array_ wrapper as cleanup data so we don't have to find - * it's length again. - */ - arg->v_pointer = array_->data; - - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) { - g_array_free (array_, FALSE); - *cleanup_data = NULL; - } else { - *cleanup_data = array_; - } - } else { - arg->v_pointer = array_; - - if (arg_cache->transfer == GI_TRANSFER_NOTHING) { - /* Free everything in cleanup. */ - *cleanup_data = array_; - } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { - /* Make a shallow copy so we can free the elements later in cleanup - * because it is possible invoke will free the list before our cleanup. */ - *cleanup_data = is_ptr_array ? - (gpointer)g_ptr_array_ref ((GPtrArray *)array_) : - (gpointer)g_array_ref (array_); - } else { /* GI_TRANSFER_EVERYTHING */ - /* No cleanup, everything is given to the callee. */ - *cleanup_data = NULL; - } - } - - return TRUE; -} - -gboolean -_pygi_marshal_from_py_glist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyGIMarshalFromPyFunc from_py_marshaller; - int i; - Py_ssize_t length; - GList *list_ = NULL; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (!PySequence_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - length = PySequence_Length (py_arg); - if (length < 0) - return FALSE; - - if (sequence_cache->fixed_size >= 0 && - sequence_cache->fixed_size != length) { - PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd", - sequence_cache->fixed_size, length); - - return FALSE; - } - - from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; - for (i = 0; i < length; i++) { - GIArgument item = {0}; - gpointer item_cleanup_data = NULL; - PyObject *py_item = PySequence_GetItem (py_arg, i); - if (py_item == NULL) - goto err; - - if (!from_py_marshaller ( state, - callable_cache, - sequence_cache->item_cache, - py_item, - &item, - &item_cleanup_data)) - goto err; - - Py_DECREF (py_item); - list_ = g_list_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag)); - continue; -err: - /* FIXME: clean up list - if (sequence_cache->item_cache->from_py_cleanup != NULL) { - PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup; - } - */ - Py_DECREF (py_item); - g_list_free (list_); - _PyGI_ERROR_PREFIX ("Item %i: ", i); - return FALSE; - } - - arg->v_pointer = g_list_reverse (list_); - - if (arg_cache->transfer == GI_TRANSFER_NOTHING) { - /* Free everything in cleanup. */ - *cleanup_data = arg->v_pointer; - } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { - /* Make a shallow copy so we can free the elements later in cleanup - * because it is possible invoke will free the list before our cleanup. */ - *cleanup_data = g_list_copy (arg->v_pointer); - } else { /* GI_TRANSFER_EVERYTHING */ - /* No cleanup, everything is given to the callee. */ - *cleanup_data = NULL; - } - return TRUE; -} - -gboolean -_pygi_marshal_from_py_gslist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyGIMarshalFromPyFunc from_py_marshaller; - int i; - Py_ssize_t length; - GSList *list_ = NULL; - PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (!PySequence_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, "Must be sequence, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - length = PySequence_Length (py_arg); - if (length < 0) - return FALSE; - - if (sequence_cache->fixed_size >= 0 && - sequence_cache->fixed_size != length) { - PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd", - sequence_cache->fixed_size, length); - - return FALSE; - } - - from_py_marshaller = sequence_cache->item_cache->from_py_marshaller; - for (i = 0; i < length; i++) { - GIArgument item = {0}; - gpointer item_cleanup_data = NULL; - PyObject *py_item = PySequence_GetItem (py_arg, i); - if (py_item == NULL) - goto err; - - if (!from_py_marshaller ( state, - callable_cache, - sequence_cache->item_cache, - py_item, - &item, - &item_cleanup_data)) - goto err; - - Py_DECREF (py_item); - list_ = g_slist_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag)); - continue; -err: - /* FIXME: Clean up list - if (sequence_cache->item_cache->from_py_cleanup != NULL) { - PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup; - } - */ - - Py_DECREF (py_item); - g_slist_free (list_); - _PyGI_ERROR_PREFIX ("Item %i: ", i); - return FALSE; - } - - arg->v_pointer = g_slist_reverse (list_); - - if (arg_cache->transfer == GI_TRANSFER_NOTHING) { - /* Free everything in cleanup. */ - *cleanup_data = arg->v_pointer; - } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { - /* Make a shallow copy so we can free the elements later in cleanup - * because it is possible invoke will free the list before our cleanup. */ - *cleanup_data = g_slist_copy (arg->v_pointer); - } else { /* GI_TRANSFER_EVERYTHING */ - /* No cleanup, everything is given to the callee. */ - *cleanup_data = NULL; - } - - return TRUE; -} - -gboolean -_pygi_marshal_from_py_ghash (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyGIMarshalFromPyFunc key_from_py_marshaller; - PyGIMarshalFromPyFunc value_from_py_marshaller; - - int i; - Py_ssize_t length; - PyObject *py_keys, *py_values; - - GHashFunc hash_func; - GEqualFunc equal_func; - - GHashTable *hash_ = NULL; - PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - py_keys = PyMapping_Keys (py_arg); - if (py_keys == NULL) { - PyErr_Format (PyExc_TypeError, "Must be mapping, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - length = PyMapping_Length (py_arg); - if (length < 0) { - Py_DECREF (py_keys); - return FALSE; - } - - py_values = PyMapping_Values (py_arg); - if (py_values == NULL) { - Py_DECREF (py_keys); - return FALSE; - } - - key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller; - value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller; - - switch (hash_cache->key_cache->type_tag) { - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - hash_func = g_str_hash; - equal_func = g_str_equal; - break; - default: - hash_func = NULL; - equal_func = NULL; - } - - hash_ = g_hash_table_new (hash_func, equal_func); - if (hash_ == NULL) { - PyErr_NoMemory (); - Py_DECREF (py_keys); - Py_DECREF (py_values); - return FALSE; - } - - for (i = 0; i < length; i++) { - GIArgument key, value; - gpointer key_cleanup_data = NULL; - gpointer value_cleanup_data = NULL; - PyObject *py_key = PyList_GET_ITEM (py_keys, i); - PyObject *py_value = PyList_GET_ITEM (py_values, i); - if (py_key == NULL || py_value == NULL) - goto err; - - if (!key_from_py_marshaller ( state, - callable_cache, - hash_cache->key_cache, - py_key, - &key, - &key_cleanup_data)) - goto err; - - if (!value_from_py_marshaller ( state, - callable_cache, - hash_cache->value_cache, - py_value, - &value, - &value_cleanup_data)) - goto err; - - g_hash_table_insert (hash_, - _pygi_arg_to_hash_pointer (&key, hash_cache->key_cache->type_tag), - _pygi_arg_to_hash_pointer (&value, hash_cache->value_cache->type_tag)); - continue; -err: - /* FIXME: cleanup hash keys and values */ - Py_XDECREF (py_key); - Py_XDECREF (py_value); - Py_DECREF (py_keys); - Py_DECREF (py_values); - g_hash_table_unref (hash_); - _PyGI_ERROR_PREFIX ("Item %i: ", i); - return FALSE; - } - - arg->v_pointer = hash_; - - if (arg_cache->transfer == GI_TRANSFER_NOTHING) { - /* Free everything in cleanup. */ - *cleanup_data = arg->v_pointer; - } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) { - /* Make a shallow copy so we can free the elements later in cleanup - * because it is possible invoke will free the list before our cleanup. */ - *cleanup_data = g_hash_table_ref (arg->v_pointer); - } else { /* GI_TRANSFER_EVERYTHING */ - /* No cleanup, everything is given to the callee. - * Note that the keys and values will leak for transfer everything because - * we do not use g_hash_table_new_full and set key/value_destroy_func. */ - *cleanup_data = NULL; - } - - return TRUE; -} - -gboolean -_pygi_marshal_from_py_gerror (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyErr_Format (PyExc_NotImplementedError, - "Marshalling for GErrors is not implemented"); - return FALSE; -} - -/* _pygi_destroy_notify_dummy: - * - * Dummy method used in the occasion when a method has a GDestroyNotify - * argument without user data. - */ -static void -_pygi_destroy_notify_dummy (gpointer data) { -} - -static PyGICClosure *global_destroy_notify; - -static void -_pygi_destroy_notify_callback_closure (ffi_cif *cif, - void *result, - void **args, - void *data) -{ - PyGICClosure *info = * (void**) (args[0]); - - g_assert (info); - - _pygi_invoke_closure_free (info); -} - -/* _pygi_destroy_notify_create: - * - * Method used in the occasion when a method has a GDestroyNotify - * argument with user data. - */ -static PyGICClosure* -_pygi_destroy_notify_create (void) -{ - if (!global_destroy_notify) { - - PyGICClosure *destroy_notify = g_slice_new0 (PyGICClosure); - GIBaseInfo* glib_destroy_notify; - - g_assert (destroy_notify); - - glib_destroy_notify = g_irepository_find_by_name (NULL, "GLib", "DestroyNotify"); - g_assert (glib_destroy_notify != NULL); - g_assert (g_base_info_get_type (glib_destroy_notify) == GI_INFO_TYPE_CALLBACK); - - destroy_notify->closure = g_callable_info_prepare_closure ( (GICallableInfo*) glib_destroy_notify, - &destroy_notify->cif, - _pygi_destroy_notify_callback_closure, - NULL); - - global_destroy_notify = destroy_notify; - } - - return global_destroy_notify; -} - -gboolean -_pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - GICallableInfo *callable_info; - PyGICClosure *closure; - PyGIArgCache *user_data_cache = NULL; - PyGIArgCache *destroy_cache = NULL; - PyGICallbackCache *callback_cache; - PyObject *py_user_data = NULL; - - callback_cache = (PyGICallbackCache *)arg_cache; - - if (callback_cache->user_data_index > 0) { - user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index); - if (user_data_cache->py_arg_index < state->n_py_in_args) { - /* py_user_data is a borrowed reference. */ - py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index); - if (!py_user_data) - return FALSE; - /* NULL out user_data if it was not supplied and the default arg placeholder - * was used instead. - */ - if (py_user_data == _PyGIDefaultArgPlaceholder) { - py_user_data = NULL; - } else if (callable_cache->user_data_varargs_index < 0) { - /* For non-variable length user data, place the user data in a - * single item tuple which is concatenated to the callbacks arguments. - * This allows callback input arg marshaling to always expect a - * tuple for user data. Note the - */ - py_user_data = Py_BuildValue("(O)", py_user_data, NULL); - } else { - /* increment the ref borrowed from PyTuple_GetItem above */ - Py_INCREF (py_user_data); - } - } - } - - if (py_arg == Py_None) { - return TRUE; - } - - if (!PyCallable_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, - "Callback needs to be a function or method not %s", - py_arg->ob_type->tp_name); - - return FALSE; - } - - callable_info = (GICallableInfo *)callback_cache->interface_info; - - closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data); - arg->v_pointer = closure->closure; - - /* always decref the user data as _pygi_make_native_closure adds its own ref */ - Py_XDECREF (py_user_data); - - /* The PyGICClosure instance is used as user data passed into the C function. - * The return trip to python will marshal this back and pull the python user data out. - */ - if (user_data_cache != NULL) { - state->in_args[user_data_cache->c_arg_index].v_pointer = closure; - } - - /* Setup a GDestroyNotify callback if this method supports it along with - * a user data field. The user data field is a requirement in order - * free resources and ref counts associated with this arguments closure. - * In case a user data field is not available, show a warning giving - * explicit information and setup a dummy notification to avoid a crash - * later on in _pygi_destroy_notify_callback_closure. - */ - if (callback_cache->destroy_notify_index > 0) { - destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index); - } - - if (destroy_cache) { - if (user_data_cache != NULL) { - PyGICClosure *destroy_notify = _pygi_destroy_notify_create (); - state->in_args[destroy_cache->c_arg_index].v_pointer = destroy_notify->closure; - } else { - gchar *msg = g_strdup_printf("Callables passed to %s will leak references because " - "the method does not support a user_data argument. " - "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598", - callable_cache->name); - if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) { - g_free(msg); - _pygi_invoke_closure_free(closure); - return FALSE; - } - g_free(msg); - state->in_args[destroy_cache->c_arg_index].v_pointer = _pygi_destroy_notify_dummy; - } - } - - /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */ - *cleanup_data = closure; - - return TRUE; -} - -gboolean -_pygi_marshal_from_py_interface_enum (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyObject *py_long; - long c_long; - gint is_instance; - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - GIBaseInfo *interface = NULL; - - is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type); - - py_long = PYGLIB_PyNumber_Long (py_arg); - if (py_long == NULL) { - PyErr_Clear(); - goto err; - } - - c_long = PYGLIB_PyLong_AsLong (py_long); - Py_DECREF (py_long); - - /* Write c_long into arg */ - interface = g_type_info_get_interface (arg_cache->type_info); - assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM); - if (!gi_argument_from_c_long(arg, - c_long, - g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { - g_assert_not_reached(); - g_base_info_unref (interface); - return FALSE; - } - - /* If this is not an instance of the Enum type that we want - * we need to check if the value is equivilant to one of the - * Enum's memebers */ - if (!is_instance) { - int i; - gboolean is_found = FALSE; - - for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) { - GIValueInfo *value_info = - g_enum_info_get_value (iface_cache->interface_info, i); - glong enum_value = g_value_info_get_value (value_info); - g_base_info_unref ( (GIBaseInfo *)value_info); - if (c_long == enum_value) { - is_found = TRUE; - break; - } - } - - if (!is_found) - goto err; - } - - g_base_info_unref (interface); - return TRUE; - -err: - if (interface) - g_base_info_unref (interface); - PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s", - iface_cache->type_name, py_arg->ob_type->tp_name); - return FALSE; -} - -gboolean -_pygi_marshal_from_py_interface_flags (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyObject *py_long; - long c_long; - gint is_instance; - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - GIBaseInfo *interface; - - is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type); - - py_long = PYGLIB_PyNumber_Long (py_arg); - if (py_long == NULL) { - PyErr_Clear (); - goto err; - } - - c_long = PYGLIB_PyLong_AsLong (py_long); - Py_DECREF (py_long); - - /* only 0 or argument of type Flag is allowed */ - if (!is_instance && c_long != 0) - goto err; - - /* Write c_long into arg */ - interface = g_type_info_get_interface (arg_cache->type_info); - g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); - if (!gi_argument_from_c_long(arg, c_long, - g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { - g_base_info_unref (interface); - return FALSE; - } - - g_base_info_unref (interface); - return TRUE; - -err: - PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s", - iface_cache->type_name, py_arg->ob_type->tp_name); - return FALSE; - -} - -gboolean -_pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - - gboolean res = _pygi_marshal_from_py_interface_struct (py_arg, - arg, - arg_cache->arg_name, - iface_cache->interface_info, - iface_cache->g_type, - iface_cache->py_type, - arg_cache->transfer, - TRUE, /*copy_reference*/ - iface_cache->is_foreign, - arg_cache->is_pointer); - - /* Assume struct marshaling is always a pointer and assign cleanup_data - * here rather than passing it further down the chain. - */ - *cleanup_data = arg->v_pointer; - return res; -} - -gboolean -_pygi_marshal_from_py_interface_boxed (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyErr_Format (PyExc_NotImplementedError, - "Marshalling for this type is not implemented yet"); - return FALSE; -} - -gboolean -_pygi_marshal_from_py_interface_object (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - gboolean res = FALSE; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (!PyObject_IsInstance (py_arg, ( (PyGIInterfaceCache *)arg_cache)->py_type)) { - PyObject *module = PyObject_GetAttrString(py_arg, "__module__"); - - PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s", - arg_cache->arg_name ? arg_cache->arg_name : "self", - ( (PyGIInterfaceCache *)arg_cache)->type_name, - module ? PYGLIB_PyUnicode_AsString(module) : "", - module ? "." : "", - py_arg->ob_type->tp_name); - if (module) - Py_DECREF (module); - return FALSE; - } - - res = _pygi_marshal_from_py_gobject (py_arg, arg, arg_cache->transfer); - *cleanup_data = arg->v_pointer; - return res; -} - -gboolean -_pygi_marshal_from_py_interface_union (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - PyErr_Format(PyExc_NotImplementedError, - "Marshalling for this type is not implemented yet"); - return FALSE; -} - -/* _pygi_marshal_from_py_gobject: - * py_arg: (in): - * arg: (out): - */ -gboolean -_pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/ - GIArgument *arg, /*out*/ - GITransfer transfer) { - GObject *gobj; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - if (!pygobject_check (py_arg, &PyGObject_Type)) { - PyObject *repr = PyObject_Repr (py_arg); - PyErr_Format(PyExc_TypeError, "expected GObject but got %s", - PYGLIB_PyUnicode_AsString (repr)); - Py_DECREF (repr); - return FALSE; - } - - gobj = pygobject_get (py_arg); - if (transfer == GI_TRANSFER_EVERYTHING) { - /* For transfer everything, add a new ref that the callee will take ownership of. - * Pythons existing ref to the GObject will be managed with the PyGObject wrapper. - */ - g_object_ref (gobj); - } - - arg->v_pointer = gobj; - return TRUE; -} - -/* _pygi_marshal_from_py_gobject_out_arg: - * py_arg: (in): - * arg: (out): - * - * A specialization for marshaling Python GObjects used for out/return values - * from a Python implemented vfuncs, signals, or an assignment to a GObject property. - */ -gboolean -_pygi_marshal_from_py_gobject_out_arg (PyObject *py_arg, /*in*/ - GIArgument *arg, /*out*/ - GITransfer transfer) { - GObject *gobj; - if (!_pygi_marshal_from_py_gobject (py_arg, arg, transfer)) { - return FALSE; - } - - /* HACK: At this point the basic marshaling of the GObject was successful - * but we add some special case hacks for vfunc returns due to buggy APIs: - * https://bugzilla.gnome.org/show_bug.cgi?id=693393 - */ - gobj = arg->v_pointer; - if (py_arg->ob_refcnt == 1 && gobj->ref_count == 1) { - /* If both object ref counts are only 1 at this point (the reference held - * in a return tuple), we assume the GObject will be free'd before reaching - * its target and become invalid. So instead of getting invalid object errors - * we add a new GObject ref. - */ - g_object_ref (gobj); - - if (((PyGObject *)py_arg)->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) { - /* - * We want to re-float instances that were floating and the Python - * wrapper assumed ownership. With the additional caveat that there - * are not any strong references beyond the return tuple. - */ - g_object_force_floating (gobj); - - } else { - PyObject *repr = PyObject_Repr (py_arg); - gchar *msg = g_strdup_printf ("Expecting to marshal a borrowed reference for %s, " - "but nothing in Python is holding a reference to this object. " - "See: https://bugzilla.gnome.org/show_bug.cgi?id=687522", - PYGLIB_PyUnicode_AsString(repr)); - Py_DECREF (repr); - if (PyErr_WarnEx (PyExc_RuntimeWarning, msg, 2)) { - g_free (msg); - return FALSE; - } - g_free (msg); - } - } - - return TRUE; -} - -/* _pygi_marshal_from_py_gvalue: - * py_arg: (in): - * arg: (out): - * transfer: - * copy_reference: TRUE if arg should use the pointer reference held by py_arg - * when it is already holding a GValue vs. copying the value. - */ -gboolean -_pygi_marshal_from_py_gvalue (PyObject *py_arg, - GIArgument *arg, - GITransfer transfer, - gboolean copy_reference) { - GValue *value; - GType object_type; - - object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE); - if (object_type == G_TYPE_INVALID) { - PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType"); - return FALSE; - } - - /* if already a gvalue, use that, else marshal into gvalue */ - if (object_type == G_TYPE_VALUE) { - GValue *source_value = pyg_boxed_get (py_arg, GValue); - if (copy_reference) { - value = source_value; - } else { - value = g_slice_new0 (GValue); - g_value_init (value, G_VALUE_TYPE (source_value)); - g_value_copy (source_value, value); - } - } else { - value = g_slice_new0 (GValue); - g_value_init (value, object_type); - if (pyg_value_from_pyobject (value, py_arg) < 0) { - g_slice_free (GValue, value); - PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed"); - return FALSE; - } - } - - arg->v_pointer = value; - return TRUE; -} - -/* _pygi_marshal_from_py_gclosure: - * py_arg: (in): - * arg: (out): - */ -gboolean -_pygi_marshal_from_py_gclosure(PyObject *py_arg, - GIArgument *arg) -{ - GClosure *closure; - GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE); - - if ( !(PyCallable_Check(py_arg) || - g_type_is_a (object_gtype, G_TYPE_CLOSURE))) { - PyErr_Format (PyExc_TypeError, "Must be callable, not %s", - py_arg->ob_type->tp_name); - return FALSE; - } - - if (g_type_is_a (object_gtype, G_TYPE_CLOSURE)) - closure = (GClosure *)pyg_boxed_get (py_arg, void); - else - closure = pyg_closure_new (py_arg, NULL, NULL); - - if (closure == NULL) { - PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed"); - return FALSE; - } - - arg->v_pointer = closure; - return TRUE; -} - -gboolean -_pygi_marshal_from_py_interface_struct (PyObject *py_arg, - GIArgument *arg, - const gchar *arg_name, - GIBaseInfo *interface_info, - GType g_type, - PyObject *py_type, - GITransfer transfer, - gboolean copy_reference, - gboolean is_foreign, - gboolean is_pointer) -{ - gboolean is_union = FALSE; - - if (py_arg == Py_None) { - arg->v_pointer = NULL; - return TRUE; - } - - /* FIXME: handle this large if statement in the cache - * and set the correct marshaller - */ - - if (g_type_is_a (g_type, G_TYPE_CLOSURE)) { - return _pygi_marshal_from_py_gclosure (py_arg, arg); - } else if (g_type_is_a (g_type, G_TYPE_VALUE)) { - return _pygi_marshal_from_py_gvalue(py_arg, - arg, - transfer, - copy_reference); - } else if (is_foreign) { - PyObject *success; - success = pygi_struct_foreign_convert_to_g_argument (py_arg, - interface_info, - transfer, - arg); - - return (success == Py_None); - } else if (!PyObject_IsInstance (py_arg, py_type)) { - /* first check to see if this is a member of the expected union */ - is_union = _is_union_member (interface_info, py_arg); - if (!is_union) { - goto type_error; - } - } - - if (g_type_is_a (g_type, G_TYPE_BOXED)) { - /* Additionally use pyg_type_from_object to pull the stashed __gtype__ - * attribute off of the input argument for type checking. This is needed - * to work around type discrepancies in cases with aliased (typedef) types. - * e.g. GtkAllocation, GdkRectangle. - * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140 - */ - if (is_union || pyg_boxed_check (py_arg, g_type) || - g_type_is_a (pyg_type_from_object (py_arg), g_type)) { - arg->v_pointer = pyg_boxed_get (py_arg, void); - if (transfer == GI_TRANSFER_EVERYTHING) { - arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer); - } - } else { - goto type_error; - } - - } else if (g_type_is_a (g_type, G_TYPE_POINTER) || - g_type_is_a (g_type, G_TYPE_VARIANT) || - g_type == G_TYPE_NONE) { - g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING); - - if (g_type_is_a (g_type, G_TYPE_VARIANT) && - pyg_type_from_object (py_arg) != G_TYPE_VARIANT) { - PyErr_SetString (PyExc_TypeError, "expected GLib.Variant"); - return FALSE; - } - arg->v_pointer = pyg_pointer_get (py_arg, void); - if (transfer == GI_TRANSFER_EVERYTHING) { - g_variant_ref ((GVariant *)arg->v_pointer); - } - - } else { - PyErr_Format (PyExc_NotImplementedError, - "structure type '%s' is not supported yet", - g_type_name(g_type)); - return FALSE; - } - return TRUE; - -type_error: - { - gchar *type_name = _pygi_g_base_info_get_fullname (interface_info); - PyObject *module = PyObject_GetAttrString(py_arg, "__module__"); - - PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s", - arg_name ? arg_name : "self", - type_name, - module ? PYGLIB_PyUnicode_AsString(module) : "", - module ? "." : "", - py_arg->ob_type->tp_name); - if (module) - Py_DECREF (module); - g_free (type_name); - return FALSE; - } -} diff --git a/gi/pygi-marshal-from-py.h b/gi/pygi-marshal-from-py.h deleted file mode 100644 index f8e4699..0000000 --- a/gi/pygi-marshal-from-py.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * vim: tabstop=4 shiftwidth=4 expandtab - * - * Copyright (C) 2011 John (J5) Palmieri , Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGI_MARSHAL_from_py_PY_H__ -#define __PYGI_MARSHAL_from_py_PY_H__ - -#include - -#include - -#include "pygi-private.h" - -G_BEGIN_DECLS - -gboolean _pygi_marshal_from_py_ssize_t (PyGIArgCache *arg_cache, - Py_ssize_t size, - GIArgument *arg); -gboolean _pygi_marshal_from_py_void (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_array (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_glist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_gslist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_ghash (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_gerror (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_boxed (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_object (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_interface_union (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); - -/* Simplified marshalers shared between vfunc/closure and direct function calls. */ -gboolean _pygi_marshal_from_py_basic_type (PyObject *object, /* in */ - GIArgument *arg, /* out */ - GITypeTag type_tag, - GITransfer transfer, - gpointer *cleanup_data); -gboolean _pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data); - -gboolean _pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/ - GIArgument *arg, /*out*/ - GITransfer transfer); -gboolean _pygi_marshal_from_py_gobject_out_arg (PyObject *py_arg, /*in*/ - GIArgument *arg, /*out*/ - GITransfer transfer); - -gboolean _pygi_marshal_from_py_gvalue (PyObject *py_arg, /*in*/ - GIArgument *arg, /*out*/ - GITransfer transfer, - gboolean is_allocated); - -gboolean _pygi_marshal_from_py_gclosure(PyObject *py_arg, /*in*/ - GIArgument *arg); /*out*/ - -gboolean _pygi_marshal_from_py_interface_struct (PyObject *py_arg, - GIArgument *arg, - const gchar *arg_name, - GIBaseInfo *interface_info, - GType g_type, - PyObject *py_type, - GITransfer transfer, - gboolean is_allocated, - gboolean is_foreign, - gboolean is_pointer); - -G_END_DECLS - -#endif /* __PYGI_MARSHAL_from_py_PY__ */ diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c deleted file mode 100644 index 2c7a8de..0000000 --- a/gi/pygi-marshal-to-py.c +++ /dev/null @@ -1,884 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * vim: tabstop=4 shiftwidth=4 expandtab - * - * Copyright (C) 2011 John (J5) Palmieri , Red Hat, Inc. - * - * pygi-marshal-from-py.c: functions for converting C types to PyObject - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#include "pygi-private.h" - -#include -#include - -#include -#include -#include - -#include "pygi-cache.h" -#include "pygi-marshal-cleanup.h" -#include "pygi-marshal-to-py.h" -#include "pygi-argument.h" - -static gboolean -gi_argument_to_c_long (GIArgument *arg_in, - long *c_long_out, - GITypeTag type_tag) -{ - switch (type_tag) { - case GI_TYPE_TAG_INT8: - *c_long_out = arg_in->v_int8; - return TRUE; - case GI_TYPE_TAG_UINT8: - *c_long_out = arg_in->v_uint8; - return TRUE; - case GI_TYPE_TAG_INT16: - *c_long_out = arg_in->v_int16; - return TRUE; - case GI_TYPE_TAG_UINT16: - *c_long_out = arg_in->v_uint16; - return TRUE; - case GI_TYPE_TAG_INT32: - *c_long_out = arg_in->v_int32; - return TRUE; - case GI_TYPE_TAG_UINT32: - *c_long_out = arg_in->v_uint32; - return TRUE; - case GI_TYPE_TAG_INT64: - *c_long_out = arg_in->v_int64; - return TRUE; - case GI_TYPE_TAG_UINT64: - *c_long_out = arg_in->v_uint64; - return TRUE; - default: - PyErr_Format (PyExc_TypeError, - "Unable to marshal %s to C long", - g_type_tag_to_string (type_tag)); - return FALSE; - } -} - -static gboolean -gi_argument_to_gsize (GIArgument *arg_in, - gsize *gsize_out, - GITypeTag type_tag) -{ - switch (type_tag) { - case GI_TYPE_TAG_INT8: - *gsize_out = arg_in->v_int8; - return TRUE; - case GI_TYPE_TAG_UINT8: - *gsize_out = arg_in->v_uint8; - return TRUE; - case GI_TYPE_TAG_INT16: - *gsize_out = arg_in->v_int16; - return TRUE; - case GI_TYPE_TAG_UINT16: - *gsize_out = arg_in->v_uint16; - return TRUE; - case GI_TYPE_TAG_INT32: - *gsize_out = arg_in->v_int32; - return TRUE; - case GI_TYPE_TAG_UINT32: - *gsize_out = arg_in->v_uint32; - return TRUE; - case GI_TYPE_TAG_INT64: - *gsize_out = arg_in->v_int64; - return TRUE; - case GI_TYPE_TAG_UINT64: - *gsize_out = arg_in->v_uint64; - return TRUE; - default: - PyErr_Format (PyExc_TypeError, - "Unable to marshal %s to gsize", - g_type_tag_to_string (type_tag)); - return FALSE; - } -} - -PyObject * -_pygi_marshal_to_py_void (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - if (arg_cache->is_pointer) { - return PyLong_FromVoidPtr (arg->v_pointer); - } - Py_RETURN_NONE; -} - -static PyObject * -_pygi_marshal_to_py_unichar (GIArgument *arg) -{ - PyObject *py_obj = NULL; - - /* Preserve the bidirectional mapping between 0 and "" */ - if (arg->v_uint32 == 0) { - py_obj = PYGLIB_PyUnicode_FromString (""); - } else if (g_unichar_validate (arg->v_uint32)) { - gchar utf8[6]; - gint bytes; - - bytes = g_unichar_to_utf8 (arg->v_uint32, utf8); - py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes); - } else { - /* TODO: Convert the error to an exception. */ - PyErr_Format (PyExc_TypeError, - "Invalid unicode codepoint %" G_GUINT32_FORMAT, - arg->v_uint32); - } - - return py_obj; -} - -static PyObject * -_pygi_marshal_to_py_utf8 (GIArgument *arg) -{ - PyObject *py_obj = NULL; - if (arg->v_string == NULL) { - Py_RETURN_NONE; - } - - py_obj = PYGLIB_PyUnicode_FromString (arg->v_string); - return py_obj; -} - -static PyObject * -_pygi_marshal_to_py_filename (GIArgument *arg) -{ - gchar *string = NULL; - PyObject *py_obj = NULL; - GError *error = NULL; - - if (arg->v_string == NULL) { - Py_RETURN_NONE; - } - - string = g_filename_to_utf8 (arg->v_string, -1, NULL, NULL, &error); - if (string == NULL) { - PyErr_SetString (PyExc_Exception, error->message); - /* TODO: Convert the error to an exception. */ - return NULL; - } - - py_obj = PYGLIB_PyUnicode_FromString (string); - g_free (string); - - return py_obj; -} - - -/** - * _pygi_marshal_to_py_basic_type: - * @arg: The argument to convert to an object. - * @type_tag: Type tag for @arg - * @transfer: Transfer annotation - * - * Convert the given argument to a Python object. This function - * is restricted to simple types that only require the GITypeTag - * and GITransfer. For a more complete conversion routine, use: - * _pygi_argument_to_object. - * - * Returns: A PyObject representing @arg or NULL if it cannot convert - * the argument. - */ -PyObject * -_pygi_marshal_to_py_basic_type (GIArgument *arg, - GITypeTag type_tag, - GITransfer transfer) -{ - switch (type_tag) { - case GI_TYPE_TAG_BOOLEAN: - return PyBool_FromLong (arg->v_boolean); - - case GI_TYPE_TAG_INT8: - return PYGLIB_PyLong_FromLong (arg->v_int8); - - case GI_TYPE_TAG_UINT8: - return PYGLIB_PyLong_FromLong (arg->v_uint8); - - case GI_TYPE_TAG_INT16: - return PYGLIB_PyLong_FromLong (arg->v_int16); - - case GI_TYPE_TAG_UINT16: - return PYGLIB_PyLong_FromLong (arg->v_uint16); - - case GI_TYPE_TAG_INT32: - return PYGLIB_PyLong_FromLong (arg->v_int32); - - case GI_TYPE_TAG_UINT32: - return PyLong_FromLongLong (arg->v_uint32); - - case GI_TYPE_TAG_INT64: - return PyLong_FromLongLong (arg->v_int64); - - case GI_TYPE_TAG_UINT64: - return PyLong_FromUnsignedLongLong (arg->v_uint64); - - case GI_TYPE_TAG_FLOAT: - return PyFloat_FromDouble (arg->v_float); - - case GI_TYPE_TAG_DOUBLE: - return PyFloat_FromDouble (arg->v_double); - - case GI_TYPE_TAG_GTYPE: - return pyg_type_wrapper_new ( (GType) arg->v_long); - - case GI_TYPE_TAG_UNICHAR: - return _pygi_marshal_to_py_unichar (arg); - - case GI_TYPE_TAG_UTF8: - return _pygi_marshal_to_py_utf8 (arg); - - case GI_TYPE_TAG_FILENAME: - return _pygi_marshal_to_py_filename (arg); - - default: - return NULL; - } - return NULL; -} - -PyObject * -_pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - return _pygi_marshal_to_py_basic_type (arg, - arg_cache->type_tag, - arg_cache->transfer); -} - -PyObject * -_pygi_marshal_to_py_array (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - GArray *array_; - PyObject *py_obj = NULL; - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - gsize processed_items = 0; - - /* GArrays make it easier to iterate over arrays - * with different element sizes but requires that - * we allocate a GArray if the argument was a C array - */ - if (seq_cache->array_type == GI_ARRAY_TYPE_C) { - gsize len; - if (seq_cache->fixed_size >= 0) { - g_assert(arg->v_pointer != NULL); - len = seq_cache->fixed_size; - } else if (seq_cache->is_zero_terminated) { - if (arg->v_pointer == NULL) { - len = 0; - } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) { - len = strlen (arg->v_pointer); - } else { - len = g_strv_length ((gchar **)arg->v_pointer); - } - } else { - GIArgument *len_arg = state->args[seq_cache->len_arg_index]; - PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache, - seq_cache->len_arg_index); - - if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) { - return NULL; - } - } - - array_ = g_array_new (FALSE, - FALSE, - seq_cache->item_size); - if (array_ == NULL) { - PyErr_NoMemory (); - - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL) - g_free (arg->v_pointer); - - return NULL; - } - - if (array_->data != NULL) - g_free (array_->data); - array_->data = arg->v_pointer; - array_->len = len; - } else { - array_ = arg->v_pointer; - } - - if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) { - if (arg->v_pointer == NULL) { - py_obj = PYGLIB_PyBytes_FromString (""); - } else { - py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len); - } - } else { - if (arg->v_pointer == NULL) { - py_obj = PyList_New (0); - } else { - int i; - - gsize item_size; - PyGIMarshalToPyFunc item_to_py_marshaller; - PyGIArgCache *item_arg_cache; - - py_obj = PyList_New (array_->len); - if (py_obj == NULL) - goto err; - - - item_arg_cache = seq_cache->item_cache; - item_to_py_marshaller = item_arg_cache->to_py_marshaller; - - item_size = g_array_get_element_size (array_); - - for (i = 0; i < array_->len; i++) { - GIArgument item_arg = {0}; - PyObject *py_item; - - /* If we are receiving an array of pointers, simply assign the pointer - * and move on, letting the per-item marshaler deal with the - * various transfer modes and ref counts (e.g. g_variant_ref_sink). - */ - if (seq_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) { - item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i); - - } else if (item_arg_cache->is_pointer) { - item_arg.v_pointer = g_array_index (array_, gpointer, i); - - } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) { - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache; - - // FIXME: This probably doesn't work with boxed types or gvalues. See fx. _pygi_marshal_from_py_array() - switch (g_base_info_get_type (iface_cache->interface_info)) { - case GI_INFO_TYPE_STRUCT: - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && - !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) { - /* 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 { - item_arg.v_pointer = array_->data + i * item_size; - } - break; - default: - item_arg.v_pointer = g_array_index (array_, gpointer, i); - break; - } - } else { - memcpy (&item_arg, array_->data + i * item_size, item_size); - } - - py_item = item_to_py_marshaller ( state, - callable_cache, - item_arg_cache, - &item_arg); - - if (py_item == NULL) { - Py_CLEAR (py_obj); - - if (seq_cache->array_type == GI_ARRAY_TYPE_C) - g_array_unref (array_); - - goto err; - } - PyList_SET_ITEM (py_obj, i, py_item); - processed_items++; - } - } - } - - if (seq_cache->array_type == GI_ARRAY_TYPE_C) - g_array_free (array_, FALSE); - - return py_obj; - -err: - if (seq_cache->array_type == GI_ARRAY_TYPE_C) { - g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING); - } else { - /* clean up unprocessed items */ - if (seq_cache->item_cache->to_py_cleanup != NULL) { - int j; - PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup; - for (j = processed_items; j < array_->len; j++) { - cleanup_func (state, - seq_cache->item_cache, - NULL, - g_array_index (array_, gpointer, j), - FALSE); - } - } - - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) - g_array_free (array_, TRUE); - } - - return NULL; -} - -PyObject * -_pygi_marshal_to_py_glist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - GList *list_; - gsize length; - gsize i; - - PyGIMarshalToPyFunc item_to_py_marshaller; - PyGIArgCache *item_arg_cache; - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - - PyObject *py_obj = NULL; - - list_ = arg->v_pointer; - length = g_list_length (list_); - - py_obj = PyList_New (length); - if (py_obj == NULL) - return NULL; - - item_arg_cache = seq_cache->item_cache; - item_to_py_marshaller = item_arg_cache->to_py_marshaller; - - for (i = 0; list_ != NULL; list_ = g_list_next (list_), i++) { - GIArgument item_arg; - PyObject *py_item; - - item_arg.v_pointer = list_->data; - _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag); - py_item = item_to_py_marshaller (state, - callable_cache, - item_arg_cache, - &item_arg); - - if (py_item == NULL) { - Py_CLEAR (py_obj); - _PyGI_ERROR_PREFIX ("Item %zu: ", i); - return NULL; - } - - PyList_SET_ITEM (py_obj, i, py_item); - } - - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_gslist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - GSList *list_; - gsize length; - gsize i; - - PyGIMarshalToPyFunc item_to_py_marshaller; - PyGIArgCache *item_arg_cache; - PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; - - PyObject *py_obj = NULL; - - list_ = arg->v_pointer; - length = g_slist_length (list_); - - py_obj = PyList_New (length); - if (py_obj == NULL) - return NULL; - - item_arg_cache = seq_cache->item_cache; - item_to_py_marshaller = item_arg_cache->to_py_marshaller; - - for (i = 0; list_ != NULL; list_ = g_slist_next (list_), i++) { - GIArgument item_arg; - PyObject *py_item; - - item_arg.v_pointer = list_->data; - _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag); - py_item = item_to_py_marshaller (state, - callable_cache, - item_arg_cache, - &item_arg); - - if (py_item == NULL) { - Py_CLEAR (py_obj); - _PyGI_ERROR_PREFIX ("Item %zu: ", i); - return NULL; - } - - PyList_SET_ITEM (py_obj, i, py_item); - } - - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_ghash (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - GHashTable *hash_; - GHashTableIter hash_table_iter; - - PyGIMarshalToPyFunc key_to_py_marshaller; - PyGIMarshalToPyFunc value_to_py_marshaller; - - PyGIArgCache *key_arg_cache; - PyGIArgCache *value_arg_cache; - PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache; - - GIArgument key_arg; - GIArgument value_arg; - - PyObject *py_obj = NULL; - - hash_ = arg->v_pointer; - - if (hash_ == NULL) { - py_obj = Py_None; - Py_INCREF (py_obj); - return py_obj; - } - - py_obj = PyDict_New (); - if (py_obj == NULL) - return NULL; - - key_arg_cache = hash_cache->key_cache; - key_to_py_marshaller = key_arg_cache->to_py_marshaller; - - value_arg_cache = hash_cache->value_cache; - value_to_py_marshaller = value_arg_cache->to_py_marshaller; - - g_hash_table_iter_init (&hash_table_iter, hash_); - while (g_hash_table_iter_next (&hash_table_iter, - &key_arg.v_pointer, - &value_arg.v_pointer)) { - PyObject *py_key; - PyObject *py_value; - int retval; - - - _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag); - py_key = key_to_py_marshaller ( state, - callable_cache, - key_arg_cache, - &key_arg); - - if (py_key == NULL) { - Py_CLEAR (py_obj); - return NULL; - } - - _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag); - py_value = value_to_py_marshaller ( state, - callable_cache, - value_arg_cache, - &value_arg); - - if (py_value == NULL) { - Py_CLEAR (py_obj); - Py_DECREF(py_key); - return NULL; - } - - retval = PyDict_SetItem (py_obj, py_key, py_value); - - Py_DECREF (py_key); - Py_DECREF (py_value); - - if (retval < 0) { - Py_CLEAR (py_obj); - return NULL; - } - } - - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_gerror (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - GError *error = arg->v_pointer; - PyObject *py_obj = NULL; - - py_obj = pyglib_error_marshal(&error); - - if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) { - g_error_free (error); - } - - if (py_obj != NULL) { - return py_obj; - } else { - Py_RETURN_NONE; - } -} - -PyObject * -_pygi_marshal_to_py_interface_callback (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - - PyErr_Format (PyExc_NotImplementedError, - "Marshalling a callback to PyObject is not supported"); - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_interface_enum (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - GIBaseInfo *interface; - long c_long; - - interface = g_type_info_get_interface (arg_cache->type_info); - g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM); - - if (!gi_argument_to_c_long(arg, &c_long, - g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { - return NULL; - } - - if (iface_cache->g_type == G_TYPE_NONE) { - py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long); - } else { - py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long); - } - g_base_info_unref (interface); - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_interface_flags (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - GIBaseInfo *interface; - long c_long; - - interface = g_type_info_get_interface (arg_cache->type_info); - g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS); - - if (!gi_argument_to_c_long(arg, &c_long, - g_enum_info_get_storage_type ((GIEnumInfo *)interface))) { - g_base_info_unref (interface); - return NULL; - } - - g_base_info_unref (interface); - if (iface_cache->g_type == G_TYPE_NONE) { - /* An enum with a GType of None is an enum without GType */ - - PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info); - PyObject *py_args = NULL; - - if (!py_type) - return NULL; - - py_args = PyTuple_New (1); - if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) { - Py_DECREF (py_args); - Py_DECREF (py_type); - return NULL; - } - - py_obj = PyObject_CallFunction (py_type, "l", c_long); - - Py_DECREF (py_args); - Py_DECREF (py_type); - } else { - py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long); - } - - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - - return _pygi_marshal_to_py_interface_struct (arg, - iface_cache->interface_info, - iface_cache->g_type, - iface_cache->py_type, - arg_cache->transfer, - arg_cache->is_caller_allocates, - iface_cache->is_foreign); -} - -PyObject * -_pygi_marshal_to_py_interface_interface (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - - PyErr_Format (PyExc_NotImplementedError, - "Marshalling for this type is not implemented yet"); - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_interface_boxed (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - - PyErr_Format (PyExc_NotImplementedError, - "Marshalling for this type is not implemented yet"); - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_interface_object_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - return _pygi_marshal_to_py_object(arg, arg_cache->transfer); -} - -PyObject * -_pygi_marshal_to_py_interface_union (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg) -{ - PyObject *py_obj = NULL; - - PyErr_Format (PyExc_NotImplementedError, - "Marshalling for this type is not implemented yet"); - return py_obj; -} - -PyObject * -_pygi_marshal_to_py_object (GIArgument *arg, GITransfer transfer) { - PyObject *pyobj; - - if (arg->v_pointer == NULL) { - pyobj = Py_None; - Py_INCREF (pyobj); - - } else if (G_IS_PARAM_SPEC(arg->v_pointer)) { - pyobj = pyg_param_spec_new (arg->v_pointer); - if (transfer == GI_TRANSFER_EVERYTHING) - g_param_spec_unref (arg->v_pointer); - - } else { - pyobj = pygobject_new_full (arg->v_pointer, - /*steal=*/ transfer == GI_TRANSFER_EVERYTHING, - /*type=*/ NULL); - } - - return pyobj; -} - -PyObject * -_pygi_marshal_to_py_interface_struct (GIArgument *arg, - GIInterfaceInfo *interface_info, - GType g_type, - PyObject *py_type, - GITransfer transfer, - gboolean is_allocated, - gboolean is_foreign) -{ - PyObject *py_obj = NULL; - - if (arg->v_pointer == NULL) { - Py_RETURN_NONE; - } - - if (g_type_is_a (g_type, G_TYPE_VALUE)) { - py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE); - } else if (is_foreign) { - py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info, - arg->v_pointer); - } else if (g_type_is_a (g_type, G_TYPE_BOXED)) { - if (py_type) { - py_obj = _pygi_boxed_new ((PyTypeObject *) py_type, - arg->v_pointer, - transfer == GI_TRANSFER_EVERYTHING || is_allocated, - is_allocated ? - g_struct_info_get_size(interface_info) : 0); - } - } else if (g_type_is_a (g_type, G_TYPE_POINTER)) { - if (py_type == NULL || - !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) { - g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); - py_obj = pyg_pointer_new (g_type, arg->v_pointer); - } else { - py_obj = _pygi_struct_new ( (PyTypeObject *) py_type, - arg->v_pointer, - transfer == GI_TRANSFER_EVERYTHING); - } - } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) { - /* Note: sink the variant (add a ref) only if we are not transfered ownership. - * GLib.Variant overrides __del__ which will then call "g_variant_unref" for - * cleanup in either case. */ - if (py_type) { - if (transfer == GI_TRANSFER_NOTHING) { - g_variant_ref_sink (arg->v_pointer); - } - py_obj = _pygi_struct_new ((PyTypeObject *) py_type, - arg->v_pointer, - FALSE); - } - } else if (g_type == G_TYPE_NONE) { - if (py_type) { - py_obj = _pygi_struct_new ((PyTypeObject *) py_type, - arg->v_pointer, - transfer == GI_TRANSFER_EVERYTHING); - } - } else { - PyErr_Format (PyExc_NotImplementedError, - "structure type '%s' is not supported yet", - g_type_name (g_type)); - } - - return py_obj; -} diff --git a/gi/pygi-marshal-to-py.h b/gi/pygi-marshal-to-py.h deleted file mode 100644 index 1378630..0000000 --- a/gi/pygi-marshal-to-py.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4 -*- - * vim: tabstop=4 shiftwidth=4 expandtab - * - * Copyright (C) 2011 John (J5) Palmieri , Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __PYGI_MARSHAL_TO_PY_H__ -#define __PYGI_MARSHAL_TO_PY_H__ - -PyObject *_pygi_marshal_to_py_basic_type (GIArgument *arg, - GITypeTag type_tag, - GITransfer transfer); -PyObject *_pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_void (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_array (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_glist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_gslist (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_ghash (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_gerror (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_callback(PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_enum (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_flags (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_interface(PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_boxed (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_object_cache_adapter (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); -PyObject *_pygi_marshal_to_py_interface_union (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - GIArgument *arg); - -/* Simplified marshalers shared between vfunc/closure and direct function calls. */ - -PyObject *_pygi_marshal_to_py_object (GIArgument *arg, - GITransfer transfer); - -PyObject *_pygi_marshal_to_py_interface_struct (GIArgument *arg, - GIInterfaceInfo *interface_info, - GType g_type, - PyObject *py_type, - GITransfer transfer, - gboolean is_allocated, - gboolean is_foreign); - -G_END_DECLS - -#endif /* __PYGI_MARSHAL_TO_PY_H__ */ diff --git a/gi/pygi-object.c b/gi/pygi-object.c new file mode 100644 index 0000000..2aefee1 --- /dev/null +++ b/gi/pygi-object.c @@ -0,0 +1,273 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include + +#include "pygi-object.h" +#include "pygi-private.h" +#include "pygparamspec.h" + +/* + * GObject from Python + */ + +/* _pygi_marshal_from_py_gobject: + * py_arg: (in): + * arg: (out): + */ +static gboolean +_pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/ + GIArgument *arg, /*out*/ + GITransfer transfer) { + GObject *gobj; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (!pygobject_check (py_arg, &PyGObject_Type)) { + PyObject *repr = PyObject_Repr (py_arg); + PyErr_Format(PyExc_TypeError, "expected GObject but got %s", + PYGLIB_PyUnicode_AsString (repr)); + Py_DECREF (repr); + return FALSE; + } + + gobj = pygobject_get (py_arg); + if (transfer == GI_TRANSFER_EVERYTHING) { + /* For transfer everything, add a new ref that the callee will take ownership of. + * Pythons existing ref to the GObject will be managed with the PyGObject wrapper. + */ + g_object_ref (gobj); + } + + arg->v_pointer = gobj; + return TRUE; +} + +/* pygi_arg_gobject_out_arg_from_py: + * py_arg: (in): + * arg: (out): + * + * A specialization for marshaling Python GObjects used for out/return values + * from a Python implemented vfuncs, signals, or an assignment to a GObject property. + */ +gboolean +pygi_arg_gobject_out_arg_from_py (PyObject *py_arg, /*in*/ + GIArgument *arg, /*out*/ + GITransfer transfer) { + GObject *gobj; + if (!_pygi_marshal_from_py_gobject (py_arg, arg, transfer)) { + return FALSE; + } + + /* HACK: At this point the basic marshaling of the GObject was successful + * but we add some special case hacks for vfunc returns due to buggy APIs: + * https://bugzilla.gnome.org/show_bug.cgi?id=693393 + */ + gobj = arg->v_pointer; + if (py_arg->ob_refcnt == 1 && gobj->ref_count == 1) { + /* If both object ref counts are only 1 at this point (the reference held + * in a return tuple), we assume the GObject will be free'd before reaching + * its target and become invalid. So instead of getting invalid object errors + * we add a new GObject ref. + */ + g_object_ref (gobj); + + if (((PyGObject *)py_arg)->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) { + /* + * We want to re-float instances that were floating and the Python + * wrapper assumed ownership. With the additional caveat that there + * are not any strong references beyond the return tuple. + */ + g_object_force_floating (gobj); + + } else { + PyObject *repr = PyObject_Repr (py_arg); + gchar *msg = g_strdup_printf ("Expecting to marshal a borrowed reference for %s, " + "but nothing in Python is holding a reference to this object. " + "See: https://bugzilla.gnome.org/show_bug.cgi?id=687522", + PYGLIB_PyUnicode_AsString(repr)); + Py_DECREF (repr); + if (PyErr_WarnEx (PyExc_RuntimeWarning, msg, 2)) { + g_free (msg); + return FALSE; + } + g_free (msg); + } + } + + return TRUE; +} + +static gboolean +_pygi_marshal_from_py_interface_object (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + gboolean res = FALSE; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + if (!PyObject_IsInstance (py_arg, ( (PyGIInterfaceCache *)arg_cache)->py_type)) { + PyObject *module = PyObject_GetAttrString(py_arg, "__module__"); + + PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s", + arg_cache->arg_name ? arg_cache->arg_name : "self", + ( (PyGIInterfaceCache *)arg_cache)->type_name, + module ? PYGLIB_PyUnicode_AsString(module) : "", + module ? "." : "", + py_arg->ob_type->tp_name); + if (module) + Py_DECREF (module); + return FALSE; + } + + res = _pygi_marshal_from_py_gobject (py_arg, arg, arg_cache->transfer); + *cleanup_data = arg->v_pointer; + return res; +} + +static void +_pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + /* If we processed the parameter but fail before invoking the method, + we need to remove the ref we added */ + if (was_processed && state->failed && data != NULL && + arg_cache->transfer == GI_TRANSFER_EVERYTHING) + g_object_unref (G_OBJECT(data)); +} + + +/* + * GObject to Python + */ + +PyObject * +pygi_arg_gobject_to_py (GIArgument *arg, GITransfer transfer) { + PyObject *pyobj; + + if (arg->v_pointer == NULL) { + pyobj = Py_None; + Py_INCREF (pyobj); + + } else if (G_IS_PARAM_SPEC(arg->v_pointer)) { + pyobj = pyg_param_spec_new (arg->v_pointer); + if (transfer == GI_TRANSFER_EVERYTHING) + g_param_spec_unref (arg->v_pointer); + + } else { + pyobj = pygobject_new_full (arg->v_pointer, + /*steal=*/ transfer == GI_TRANSFER_EVERYTHING, + /*type=*/ NULL); + } + + return pyobj; +} + +static PyObject * +_pygi_marshal_to_py_interface_object_cache_adapter (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + return pygi_arg_gobject_to_py(arg, arg_cache->transfer); +} + +static void +_pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + /* If we error out and the object is not marshalled into a PyGObject + we must take care of removing the ref */ + if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) + g_object_unref (G_OBJECT(data)); +} + +static gboolean +pygi_arg_gobject_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction) +{ + /* NOTE: usage of pygi_arg_interface_new_from_info already calls + * pygi_arg_interface_setup so no need to do it here. + */ + + if (direction & PYGI_DIRECTION_FROM_PYTHON) { + arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object; + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object; + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object_cache_adapter; + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object; + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_gobject_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + gboolean res = FALSE; + PyGIArgCache *cache = NULL; + + cache = pygi_arg_interface_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); + if (cache == NULL) + return NULL; + + res = pygi_arg_gobject_setup_from_info (cache, + type_info, + arg_info, + transfer, + direction); + if (res) { + return cache; + } else { + pygi_arg_cache_free (cache); + return NULL; + } +} diff --git a/gi/pygi-object.h b/gi/pygi-object.h new file mode 100644 index 0000000..4a8800e --- /dev/null +++ b/gi/pygi-object.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_OBJECT_H__ +#define __PYGI_OBJECT_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +gboolean +pygi_arg_gobject_out_arg_from_py (PyObject *py_arg, /* in */ + GIArgument *arg, /* out */ + GITransfer transfer); + +PyObject * +pygi_arg_gobject_to_py (GIArgument *arg, + GITransfer transfer); + +PyGIArgCache * +pygi_arg_gobject_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + +G_END_DECLS + +#endif /*__PYGI_OBJECT_H__*/ diff --git a/gi/pygi-private.h b/gi/pygi-private.h index 97eced5..af12f1c 100644 --- a/gi/pygi-private.h +++ b/gi/pygi-private.h @@ -16,7 +16,7 @@ #include "pygi.h" -#include "pygobject-external.h" +#include "pygobject-private.h" #include "pygi-repository.h" #include "pygi-info.h" diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c index bcd1320..60f6657 100644 --- a/gi/pygi-signal-closure.c +++ b/gi/pygi-signal-closure.c @@ -19,6 +19,7 @@ */ #include "pygi-private.h" +#include "pygi-value.h" static GISignalInfo * _pygi_lookup_signal_from_g_type (GType g_type, diff --git a/gi/pygi-source.c b/gi/pygi-source.c index 66bbc3c..d2f39c6 100644 --- a/gi/pygi-source.c +++ b/gi/pygi-source.c @@ -23,8 +23,7 @@ * IN THE SOFTWARE. */ -#define NO_IMPORT -#include "pygobject.h" +#include "pygobject-private.h" #include "pygi-private.h" #include "pyglib.h" diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c new file mode 100644 index 0000000..338f2be --- /dev/null +++ b/gi/pygi-struct-marshal.c @@ -0,0 +1,517 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include + +#include "pygi-struct-marshal.h" +#include "pygi-private.h" +#include "pygi-value.h" + +/* + * _is_union_member - check to see if the py_arg is actually a member of the + * expected C union + */ +static gboolean +_is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) { + gint i; + gint n_fields; + GIUnionInfo *union_info; + GIInfoType info_type; + gboolean is_member = FALSE; + + info_type = g_base_info_get_type (interface_info); + + if (info_type != GI_INFO_TYPE_UNION) + return FALSE; + + union_info = (GIUnionInfo *) interface_info; + n_fields = g_union_info_get_n_fields (union_info); + + for (i = 0; i < n_fields; i++) { + GIFieldInfo *field_info; + GITypeInfo *field_type_info; + + field_info = g_union_info_get_field (union_info, i); + field_type_info = g_field_info_get_type (field_info); + + /* we can only check if the members are interfaces */ + if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) { + GIInterfaceInfo *field_iface_info; + PyObject *py_type; + + field_iface_info = g_type_info_get_interface (field_type_info); + py_type = _pygi_type_import_by_gi_info ((GIBaseInfo *) field_iface_info); + + if (py_type != NULL && PyObject_IsInstance (py_arg, py_type)) { + is_member = TRUE; + } + + Py_XDECREF (py_type); + g_base_info_unref ( ( GIBaseInfo *) field_iface_info); + } + + g_base_info_unref ( ( GIBaseInfo *) field_type_info); + g_base_info_unref ( ( GIBaseInfo *) field_info); + + if (is_member) + break; + } + + return is_member; +} + + +/* + * GValue from Python + */ + +/* _pygi_marshal_from_py_gvalue: + * py_arg: (in): + * arg: (out): + * transfer: + * copy_reference: TRUE if arg should use the pointer reference held by py_arg + * when it is already holding a GValue vs. copying the value. + */ +gboolean +_pygi_marshal_from_py_gvalue (PyObject *py_arg, + GIArgument *arg, + GITransfer transfer, + gboolean copy_reference) { + GValue *value; + GType object_type; + + object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE); + if (object_type == G_TYPE_INVALID) { + PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType"); + return FALSE; + } + + /* if already a gvalue, use that, else marshal into gvalue */ + if (object_type == G_TYPE_VALUE) { + GValue *source_value = pyg_boxed_get (py_arg, GValue); + if (copy_reference) { + value = source_value; + } else { + value = g_slice_new0 (GValue); + g_value_init (value, G_VALUE_TYPE (source_value)); + g_value_copy (source_value, value); + } + } else { + value = g_slice_new0 (GValue); + g_value_init (value, object_type); + if (pyg_value_from_pyobject (value, py_arg) < 0) { + g_slice_free (GValue, value); + PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed"); + return FALSE; + } + } + + arg->v_pointer = value; + return TRUE; +} + +void +_pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + /* Note py_arg can be NULL for hash table which is a bug. */ + if (was_processed && py_arg != NULL) { + GType py_object_type = + pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE); + + /* When a GValue was not passed, it means the marshalers created a new + * one to pass in, clean this up. + */ + if (py_object_type != G_TYPE_VALUE) { + g_value_unset ((GValue *) data); + g_slice_free (GValue, data); + } + } +} + +/* _pygi_marshal_from_py_gclosure: + * py_arg: (in): + * arg: (out): + */ +gboolean +_pygi_marshal_from_py_gclosure(PyObject *py_arg, + GIArgument *arg) +{ + GClosure *closure; + GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE); + + if ( !(PyCallable_Check(py_arg) || + g_type_is_a (object_gtype, G_TYPE_CLOSURE))) { + PyErr_Format (PyExc_TypeError, "Must be callable, not %s", + py_arg->ob_type->tp_name); + return FALSE; + } + + if (g_type_is_a (object_gtype, G_TYPE_CLOSURE)) + closure = (GClosure *)pyg_boxed_get (py_arg, void); + else + closure = pyg_closure_new (py_arg, NULL, NULL); + + if (closure == NULL) { + PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed"); + return FALSE; + } + + arg->v_pointer = closure; + return TRUE; +} + +/* _pygi_marshal_from_py_interface_struct: + * + * Dispatcher to various sub marshalers + */ +gboolean +_pygi_marshal_from_py_interface_struct (PyObject *py_arg, + GIArgument *arg, + const gchar *arg_name, + GIBaseInfo *interface_info, + GType g_type, + PyObject *py_type, + GITransfer transfer, + gboolean copy_reference, + gboolean is_foreign, + gboolean is_pointer) +{ + gboolean is_union = FALSE; + + if (py_arg == Py_None) { + arg->v_pointer = NULL; + return TRUE; + } + + /* FIXME: handle this large if statement in the cache + * and set the correct marshaller + */ + + if (g_type_is_a (g_type, G_TYPE_CLOSURE)) { + return _pygi_marshal_from_py_gclosure (py_arg, arg); + } else if (g_type_is_a (g_type, G_TYPE_VALUE)) { + return _pygi_marshal_from_py_gvalue(py_arg, + arg, + transfer, + copy_reference); + } else if (is_foreign) { + PyObject *success; + success = pygi_struct_foreign_convert_to_g_argument (py_arg, + interface_info, + transfer, + arg); + + return (success == Py_None); + } else if (!PyObject_IsInstance (py_arg, py_type)) { + /* first check to see if this is a member of the expected union */ + is_union = _is_union_member (interface_info, py_arg); + if (!is_union) { + goto type_error; + } + } + + if (g_type_is_a (g_type, G_TYPE_BOXED)) { + /* Additionally use pyg_type_from_object to pull the stashed __gtype__ + * attribute off of the input argument for type checking. This is needed + * to work around type discrepancies in cases with aliased (typedef) types. + * e.g. GtkAllocation, GdkRectangle. + * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140 + */ + if (is_union || pyg_boxed_check (py_arg, g_type) || + g_type_is_a (pyg_type_from_object (py_arg), g_type)) { + arg->v_pointer = pyg_boxed_get (py_arg, void); + if (transfer == GI_TRANSFER_EVERYTHING) { + arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer); + } + } else { + goto type_error; + } + + } else if (g_type_is_a (g_type, G_TYPE_POINTER) || + g_type_is_a (g_type, G_TYPE_VARIANT) || + g_type == G_TYPE_NONE) { + g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING); + + if (g_type_is_a (g_type, G_TYPE_VARIANT) && + pyg_type_from_object (py_arg) != G_TYPE_VARIANT) { + PyErr_SetString (PyExc_TypeError, "expected GLib.Variant"); + return FALSE; + } + arg->v_pointer = pyg_pointer_get (py_arg, void); + if (transfer == GI_TRANSFER_EVERYTHING) { + g_variant_ref ((GVariant *)arg->v_pointer); + } + + } else { + PyErr_Format (PyExc_NotImplementedError, + "structure type '%s' is not supported yet", + g_type_name(g_type)); + return FALSE; + } + return TRUE; + +type_error: + { + gchar *type_name = _pygi_g_base_info_get_fullname (interface_info); + PyObject *module = PyObject_GetAttrString(py_arg, "__module__"); + + PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s", + arg_name ? arg_name : "self", + type_name, + module ? PYGLIB_PyUnicode_AsString(module) : "", + module ? "." : "", + py_arg->ob_type->tp_name); + if (module) + Py_DECREF (module); + g_free (type_name); + return FALSE; + } +} + +static gboolean +_pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + PyObject *py_arg, + GIArgument *arg, + gpointer *cleanup_data) +{ + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + + gboolean res = _pygi_marshal_from_py_interface_struct (py_arg, + arg, + arg_cache->arg_name, + iface_cache->interface_info, + iface_cache->g_type, + iface_cache->py_type, + arg_cache->transfer, + TRUE, /*copy_reference*/ + iface_cache->is_foreign, + arg_cache->is_pointer); + + /* Assume struct marshaling is always a pointer and assign cleanup_data + * here rather than passing it further down the chain. + */ + *cleanup_data = arg->v_pointer; + return res; +} + +static void +_pygi_marshal_cleanup_from_py_interface_struct_foreign (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed) +{ + if (state->failed && was_processed) + pygi_struct_foreign_release ( + ( (PyGIInterfaceCache *)arg_cache)->interface_info, + data); +} + + +PyObject * +_pygi_marshal_to_py_interface_struct (GIArgument *arg, + GIInterfaceInfo *interface_info, + GType g_type, + PyObject *py_type, + GITransfer transfer, + gboolean is_allocated, + gboolean is_foreign) +{ + PyObject *py_obj = NULL; + + if (arg->v_pointer == NULL) { + Py_RETURN_NONE; + } + + if (g_type_is_a (g_type, G_TYPE_VALUE)) { + py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE); + } else if (is_foreign) { + py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info, + arg->v_pointer); + } else if (g_type_is_a (g_type, G_TYPE_BOXED)) { + if (py_type) { + py_obj = _pygi_boxed_new ((PyTypeObject *) py_type, + arg->v_pointer, + transfer == GI_TRANSFER_EVERYTHING || is_allocated, + is_allocated ? + g_struct_info_get_size(interface_info) : 0); + } + } else if (g_type_is_a (g_type, G_TYPE_POINTER)) { + if (py_type == NULL || + !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) { + g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); + py_obj = pyg_pointer_new (g_type, arg->v_pointer); + } else { + py_obj = _pygi_struct_new ( (PyTypeObject *) py_type, + arg->v_pointer, + transfer == GI_TRANSFER_EVERYTHING); + } + } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) { + /* Note: sink the variant (add a ref) only if we are not transfered ownership. + * GLib.Variant overrides __del__ which will then call "g_variant_unref" for + * cleanup in either case. */ + if (py_type) { + if (transfer == GI_TRANSFER_NOTHING) { + g_variant_ref_sink (arg->v_pointer); + } + py_obj = _pygi_struct_new ((PyTypeObject *) py_type, + arg->v_pointer, + FALSE); + } + } else if (g_type == G_TYPE_NONE) { + if (py_type) { + py_obj = _pygi_struct_new ((PyTypeObject *) py_type, + arg->v_pointer, + transfer == GI_TRANSFER_EVERYTHING); + } + } else { + PyErr_Format (PyExc_NotImplementedError, + "structure type '%s' is not supported yet", + g_type_name (g_type)); + } + + return py_obj; +} + +static PyObject * +_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState *state, + PyGICallableCache *callable_cache, + PyGIArgCache *arg_cache, + GIArgument *arg) +{ + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + + return _pygi_marshal_to_py_interface_struct (arg, + iface_cache->interface_info, + iface_cache->g_type, + iface_cache->py_type, + arg_cache->transfer, + arg_cache->is_caller_allocates, + iface_cache->is_foreign); +} + +static void +_pygi_marshal_cleanup_to_py_interface_struct_foreign (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *dummy, + gpointer data, + gboolean was_processed) +{ + if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) + pygi_struct_foreign_release ( + ( (PyGIInterfaceCache *)arg_cache)->interface_info, + data); +} + + +static void +_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache, + GIInterfaceInfo *iface_info, + GITransfer transfer) +{ + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); + arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter; + + if (iface_cache->g_type == G_TYPE_VALUE) + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue; + else if (iface_cache->is_foreign) + arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign; +} + +static void +_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache, + GIInterfaceInfo *iface_info, + GITransfer transfer) +{ + PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; + iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); + arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter; + + if (iface_cache->is_foreign) + arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign; +} + +static gboolean +pygi_arg_struct_setup_from_info (PyGIArgCache *arg_cache, + GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + /* NOTE: usage of pygi_arg_interface_new_from_info already calls + * pygi_arg_interface_setup so no need to do it here. + */ + + if (direction & PYGI_DIRECTION_FROM_PYTHON) { + _arg_cache_from_py_interface_struct_setup (arg_cache, + iface_info, + transfer); + } + + if (direction & PYGI_DIRECTION_TO_PYTHON) { + _arg_cache_to_py_interface_struct_setup (arg_cache, + iface_info, + transfer); + } + + return TRUE; +} + +PyGIArgCache * +pygi_arg_struct_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info) +{ + gboolean res = FALSE; + PyGIArgCache *cache = NULL; + + cache = pygi_arg_interface_new_from_info (type_info, + arg_info, + transfer, + direction, + iface_info); + if (cache == NULL) + return NULL; + + res = pygi_arg_struct_setup_from_info (cache, + type_info, + arg_info, + transfer, + direction, + iface_info); + if (res) { + return cache; + } else { + pygi_arg_cache_free (cache); + return NULL; + } +} diff --git a/gi/pygi-struct-marshal.h b/gi/pygi-struct-marshal.h new file mode 100644 index 0000000..66e3ecf --- /dev/null +++ b/gi/pygi-struct-marshal.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2011 John (J5) Palmieri + * Copyright (C) 2014 Simon Feltman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_STRUCT_MARSHAL_H__ +#define __PYGI_STRUCT_MARSHAL_H__ + +#include +#include "pygi-cache.h" + +G_BEGIN_DECLS + +PyGIArgCache *pygi_arg_struct_new_from_info (GITypeInfo *type_info, + GIArgInfo *arg_info, /* may be null */ + GITransfer transfer, + PyGIDirection direction, + GIInterfaceInfo *iface_info); + + +gboolean _pygi_marshal_from_py_gvalue (PyObject *py_arg, /*in*/ + GIArgument *arg, /*out*/ + GITransfer transfer, + gboolean is_allocated); + + +gboolean _pygi_marshal_from_py_gclosure(PyObject *py_arg, /*in*/ + GIArgument *arg); /*out*/ + +gboolean _pygi_marshal_from_py_interface_struct (PyObject *py_arg, + GIArgument *arg, + const gchar *arg_name, + GIBaseInfo *interface_info, + GType g_type, + PyObject *py_type, + GITransfer transfer, + gboolean is_allocated, + gboolean is_foreign, + gboolean is_pointer); + +PyObject *_pygi_marshal_to_py_interface_struct (GIArgument *arg, + GIInterfaceInfo *interface_info, + GType g_type, + PyObject *py_type, + GITransfer transfer, + gboolean is_allocated, + gboolean is_foreign); + +/* Needed for hack in pygi-arg-garray.c */ +void _pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state, + PyGIArgCache *arg_cache, + PyObject *py_arg, + gpointer data, + gboolean was_processed); + +G_END_DECLS + +#endif /*__PYGI_STRUCT_MARSHAL_H__*/ diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c index 296c47c..40bfb6d 100644 --- a/gi/pygi-struct.c +++ b/gi/pygi-struct.c @@ -22,8 +22,8 @@ */ #include "pygi-private.h" +#include "pygobject-private.h" -#include #include #include diff --git a/gi/pygi-value.c b/gi/pygi-value.c new file mode 100644 index 0000000..f2cc27b --- /dev/null +++ b/gi/pygi-value.c @@ -0,0 +1,862 @@ + +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "pygi-value.h" +#include "pyglib-python-compat.h" +#include "pygobject-private.h" +#include "pygtype.h" +#include "pygparamspec.h" + +GIArgument +_pygi_argument_from_g_value(const GValue *value, + GITypeInfo *type_info) +{ + GIArgument arg = { 0, }; + + GITypeTag type_tag = g_type_info_get_tag (type_info); + + /* For the long handling: long can be equivalent to + int32 or int64, depending on the architecture, but + gi doesn't tell us (and same for ulong) + */ + switch (type_tag) { + case GI_TYPE_TAG_BOOLEAN: + arg.v_boolean = g_value_get_boolean (value); + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_INT32: + if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG)) + arg.v_int = g_value_get_long (value); + else + arg.v_int = g_value_get_int (value); + break; + case GI_TYPE_TAG_INT64: + if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_LONG)) + arg.v_int64 = g_value_get_long (value); + else + arg.v_int64 = g_value_get_int64 (value); + break; + case GI_TYPE_TAG_UINT8: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_UINT32: + if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG)) + arg.v_uint = g_value_get_ulong (value); + else + arg.v_uint = g_value_get_uint (value); + break; + case GI_TYPE_TAG_UINT64: + if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ULONG)) + arg.v_uint64 = g_value_get_ulong (value); + else + arg.v_uint64 = g_value_get_uint64 (value); + break; + case GI_TYPE_TAG_UNICHAR: + arg.v_uint32 = g_value_get_schar (value); + break; + case GI_TYPE_TAG_FLOAT: + arg.v_float = g_value_get_float (value); + break; + case GI_TYPE_TAG_DOUBLE: + arg.v_double = g_value_get_double (value); + break; + case GI_TYPE_TAG_GTYPE: + arg.v_long = g_value_get_gtype (value); + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + arg.v_string = g_value_dup_string (value); + break; + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + arg.v_pointer = g_value_get_pointer (value); + break; + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GHASH: + if (G_VALUE_HOLDS_BOXED (value)) + arg.v_pointer = g_value_get_boxed (value); + else + /* e. g. GSettings::change-event */ + arg.v_pointer = g_value_get_pointer (value); + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *info; + GIInfoType info_type; + + info = g_type_info_get_interface (type_info); + info_type = g_base_info_get_type (info); + + g_base_info_unref (info); + + switch (info_type) { + case GI_INFO_TYPE_FLAGS: + arg.v_uint = g_value_get_flags (value); + break; + case GI_INFO_TYPE_ENUM: + arg.v_int = g_value_get_enum (value); + break; + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_OBJECT: + if (G_VALUE_HOLDS_PARAM (value)) + arg.v_pointer = g_value_get_param (value); + else + arg.v_pointer = g_value_get_object (value); + break; + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + if (G_VALUE_HOLDS(value, G_TYPE_BOXED)) { + arg.v_pointer = g_value_get_boxed (value); + } else if (G_VALUE_HOLDS(value, G_TYPE_VARIANT)) { + arg.v_pointer = g_value_get_variant (value); + } else { + arg.v_pointer = g_value_get_pointer (value); + } + break; + default: + g_warning("Converting of type '%s' is not implemented", g_info_type_to_string(info_type)); + g_assert_not_reached(); + } + break; + } + case GI_TYPE_TAG_ERROR: + arg.v_pointer = g_value_get_boxed (value); + break; + case GI_TYPE_TAG_VOID: + arg.v_pointer = g_value_get_pointer (value); + break; + } + + return arg; +} + + +static int +pyg_value_array_from_pyobject(GValue *value, + PyObject *obj, + const GParamSpecValueArray *pspec) +{ + int len; + GValueArray *value_array; + int i; + + len = PySequence_Length(obj); + if (len == -1) { + PyErr_Clear(); + return -1; + } + + if (pspec && pspec->fixed_n_elements > 0 && len != pspec->fixed_n_elements) + return -1; + + value_array = g_value_array_new(len); + + 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_value_array_free(value_array); + return -1; + } + + if (pspec && pspec->element_spec) + type = G_PARAM_SPEC_VALUE_TYPE(pspec->element_spec); + else 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_value_array_free(value_array); + Py_DECREF(item); + return -1; + } + } + + g_value_init(&item_value, type); + status = (pspec && pspec->element_spec) + ? pyg_param_gvalue_from_pyobject(&item_value, item, pspec->element_spec) + : pyg_value_from_pyobject(&item_value, item); + Py_DECREF(item); + + if (status == -1) { + g_value_array_free(value_array); + g_value_unset(&item_value); + return -1; + } + + g_value_array_append(value_array, &item_value); + g_value_unset(&item_value); + } + + g_value_take_boxed(value, value_array); + 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_with_error: + * @value: the GValue object to store the converted value in. + * @obj: the Python object to convert. + * + * This function converts a Python object and stores the result in a + * GValue. The GValue must be initialised in advance with + * g_value_init(). If the Python object can't be converted to the + * type of the GValue, then an error is returned. + * + * Returns: 0 on success, -1 on error. + */ +int +pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj) +{ + PyObject *tmp; + GType value_type = G_VALUE_TYPE(value); + + switch (G_TYPE_FUNDAMENTAL(value_type)) { + case G_TYPE_INTERFACE: + /* we only handle interface types that have a GObject prereq */ + if (g_type_is_a(value_type, G_TYPE_OBJECT)) { + if (obj == Py_None) + g_value_set_object(value, NULL); + else { + if (!PyObject_TypeCheck(obj, &PyGObject_Type)) { + PyErr_SetString(PyExc_TypeError, "GObject is required"); + return -1; + } + if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj), + value_type)) { + PyErr_SetString(PyExc_TypeError, "Invalid GObject type for assignment"); + return -1; + } + g_value_set_object(value, pygobject_get(obj)); + } + } else { + PyErr_SetString(PyExc_TypeError, "Unsupported conversion"); + return -1; + } + 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 + else if (PyString_Check(obj)) { + g_value_set_schar(value, PyString_AsString(obj)[0]); + } +#endif + else if (PyUnicode_Check(obj)) { + tmp = PyUnicode_AsUTF8String(obj); + g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]); + Py_DECREF(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "Cannot convert to TYPE_CHAR"); + return -1; + } + + break; + case G_TYPE_UCHAR: + if (PYGLIB_PyLong_Check(obj)) { + glong val; + val = PYGLIB_PyLong_AsLong(obj); + if (val >= 0 && val <= 255) + g_value_set_uchar(value, (guchar) val); + else + return -1; +#if PY_VERSION_HEX < 0x03000000 + } else if (PyString_Check(obj)) { + g_value_set_uchar(value, PyString_AsString(obj)[0]); +#endif + } else if (PyUnicode_Check(obj)) { + tmp = PyUnicode_AsUTF8String(obj); + g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]); + Py_DECREF(tmp); + } else { + PyErr_Clear(); + return -1; + } + break; + case G_TYPE_BOOLEAN: + g_value_set_boolean(value, PyObject_IsTrue(obj)); + break; + case G_TYPE_INT: + g_value_set_int(value, PYGLIB_PyLong_AsLong(obj)); + break; + case G_TYPE_UINT: + { + if (PYGLIB_PyLong_Check(obj)) { + guint val; + + /* check that number is not negative */ + if (PyLong_AsLongLong(obj) < 0) + return -1; + + val = PyLong_AsUnsignedLong(obj); + if (val <= G_MAXUINT) + g_value_set_uint(value, val); + else + return -1; + } else { + g_value_set_uint(value, PyLong_AsUnsignedLong(obj)); + } + } + break; + case G_TYPE_LONG: + g_value_set_long(value, PYGLIB_PyLong_AsLong(obj)); + break; + case G_TYPE_ULONG: +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_Check(obj)) { + long val; + + val = PYGLIB_PyLong_AsLong(obj); + if (val < 0) { + PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property"); + return -1; + } + g_value_set_ulong(value, (gulong)val); + } else +#endif + if (PyLong_Check(obj)) + g_value_set_ulong(value, PyLong_AsUnsignedLong(obj)); + else + return -1; + break; + case G_TYPE_INT64: + g_value_set_int64(value, PyLong_AsLongLong(obj)); + break; + case G_TYPE_UINT64: +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v < 0) { + PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property"); + return -1; + } + g_value_set_uint64(value, v); + } else +#endif + if (PyLong_Check(obj)) + g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj)); + else + return -1; + break; + case G_TYPE_ENUM: + { + gint val = 0; + if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) { + return -1; + } + g_value_set_enum(value, val); + } + break; + case G_TYPE_FLAGS: + { + guint val = 0; + if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) { + return -1; + } + g_value_set_flags(value, val); + } + break; + case G_TYPE_FLOAT: + g_value_set_float(value, PyFloat_AsDouble(obj)); + break; + case G_TYPE_DOUBLE: + g_value_set_double(value, PyFloat_AsDouble(obj)); + break; + case G_TYPE_STRING: + if (obj == Py_None) { + g_value_set_string(value, NULL); + } else { + PyObject* tmp_str = PyObject_Str(obj); + if (tmp_str == NULL) { + PyErr_Clear(); + if (PyUnicode_Check(obj)) { + tmp = PyUnicode_AsUTF8String(obj); + g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp)); + Py_DECREF(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "Expected string"); + return -1; + } + } else { +#if PY_VERSION_HEX < 0x03000000 + g_value_set_string(value, PyString_AsString(tmp_str)); +#else + tmp = PyUnicode_AsUTF8String(tmp_str); + g_value_set_string(value, PyBytes_AsString(tmp)); + Py_DECREF(tmp); +#endif + } + Py_XDECREF(tmp_str); + } + break; + case G_TYPE_POINTER: + if (obj == Py_None) + g_value_set_pointer(value, NULL); + else if (PyObject_TypeCheck(obj, &PyGPointer_Type) && + G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype)) + g_value_set_pointer(value, pyg_pointer_get(obj, gpointer)); + else if (PYGLIB_CPointer_Check(obj)) + g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL)); + else if (G_VALUE_HOLDS_GTYPE (value)) + g_value_set_gtype (value, pyg_type_from_object (obj)); + else { + PyErr_SetString(PyExc_TypeError, "Expected pointer"); + return -1; + } + break; + case G_TYPE_BOXED: { + PyGTypeMarshal *bm; + + if (obj == Py_None) + g_value_set_boxed(value, NULL); + else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) + g_value_set_boxed(value, obj); + else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) && + G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype)) + g_value_set_boxed(value, pyg_boxed_get(obj, gpointer)); + else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) { + GType type; + GValue *n_value; + + type = pyg_type_from_object((PyObject*)Py_TYPE(obj)); + if (G_UNLIKELY (! type)) { + return -1; + } + n_value = g_new0 (GValue, 1); + g_value_init (n_value, type); + g_value_take_boxed (value, n_value); + return pyg_value_from_pyobject_with_error (n_value, 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; + char *buffer; + Py_ssize_t len; + if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len)) + return -1; + string = g_string_new_len(buffer, len); + g_value_set_boxed(value, string); + g_string_free (string, TRUE); + break; + } + else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) + return bm->tovalue(value, obj); + else if (PYGLIB_CPointer_Check(obj)) + g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL)); + else { + PyErr_SetString(PyExc_TypeError, "Expected Boxed"); + return -1; + } + break; + } + case G_TYPE_PARAM: + /* 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 { + PyErr_SetString(PyExc_TypeError, "Expected ParamSpec"); + return -1; + } + break; + case G_TYPE_OBJECT: + if (obj == Py_None) { + g_value_set_object(value, NULL); + } else if (PyObject_TypeCheck(obj, &PyGObject_Type) && + G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj), + G_VALUE_TYPE(value))) { + g_value_set_object(value, pygobject_get(obj)); + } else { + PyErr_SetString(PyExc_TypeError, "Expected GObject"); + return -1; + } + break; + case G_TYPE_VARIANT: + { + if (obj == Py_None) + g_value_set_variant(value, NULL); + else if (pyg_type_from_object_strict(obj, FALSE) == G_TYPE_VARIANT) + g_value_set_variant(value, pyg_boxed_get(obj, GVariant)); + else { + PyErr_SetString(PyExc_TypeError, "Expected Variant"); + return -1; + } + break; + } + default: + { + PyGTypeMarshal *bm; + if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) { + return bm->tovalue(value, obj); + } else { + PyErr_SetString(PyExc_TypeError, "Unknown value type"); + return -1; + } + break; + } + } + + /* If an error occurred, unset the GValue but don't clear the Python error. */ + if (PyErr_Occurred()) { + g_value_unset(value); + return -1; + } + + return 0; +} + +/** + * pyg_value_from_pyobject: + * @value: the GValue object to store the converted value in. + * @obj: the Python object to convert. + * + * Same basic function as pyg_value_from_pyobject_with_error but clears + * any Python errors before returning. + * + * Returns: 0 on success, -1 on error. + */ +int +pyg_value_from_pyobject(GValue *value, PyObject *obj) +{ + int res = pyg_value_from_pyobject_with_error (value, obj); + + if (PyErr_Occurred()) { + PyErr_Clear(); + return -1; + } + return res; +} + +/** + * pyg_value_as_pyobject: + * @value: the GValue object. + * @copy_boxed: true if boxed values should be copied. + * + * This function creates/returns a Python wrapper object that + * represents the GValue passed as an argument. + * + * Returns: a PyObject representing the value. + */ +PyObject * +pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed) +{ + gchar buf[128]; + + switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value))) { + case G_TYPE_INTERFACE: + if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT)) + return pygobject_new(g_value_get_object(value)); + else + break; + case G_TYPE_CHAR: { + gint8 val = g_value_get_schar(value); + return PYGLIB_PyUnicode_FromStringAndSize((char *)&val, 1); + } + case G_TYPE_UCHAR: { + guint8 val = g_value_get_uchar(value); + return PYGLIB_PyBytes_FromStringAndSize((char *)&val, 1); + } + case G_TYPE_BOOLEAN: { + return PyBool_FromLong(g_value_get_boolean(value)); + } + case G_TYPE_INT: + return PYGLIB_PyLong_FromLong(g_value_get_int(value)); + case G_TYPE_UINT: + { + /* in Python, the Int object is backed by a long. If a + long can hold the whole value of an unsigned int, use + an Int. Otherwise, use a Long object to avoid overflow. + This matches the ULongArg behavior in codegen/argtypes.h */ +#if (G_MAXUINT <= G_MAXLONG) + return PYGLIB_PyLong_FromLong((glong) g_value_get_uint(value)); +#else + return PyLong_FromUnsignedLong((gulong) g_value_get_uint(value)); +#endif + } + case G_TYPE_LONG: + return PYGLIB_PyLong_FromLong(g_value_get_long(value)); + case G_TYPE_ULONG: + { + gulong val = g_value_get_ulong(value); + + if (val <= G_MAXLONG) + return PYGLIB_PyLong_FromLong((glong) val); + else + return PyLong_FromUnsignedLong(val); + } + case G_TYPE_INT64: + { + gint64 val = g_value_get_int64(value); + + if (G_MINLONG <= val && val <= G_MAXLONG) + return PYGLIB_PyLong_FromLong((glong) val); + else + return PyLong_FromLongLong(val); + } + case G_TYPE_UINT64: + { + guint64 val = g_value_get_uint64(value); + + if (val <= G_MAXLONG) + return PYGLIB_PyLong_FromLong((glong) val); + else + return PyLong_FromUnsignedLongLong(val); + } + case G_TYPE_ENUM: + return pyg_enum_from_gtype(G_VALUE_TYPE(value), g_value_get_enum(value)); + case G_TYPE_FLAGS: + return pyg_flags_from_gtype(G_VALUE_TYPE(value), g_value_get_flags(value)); + case G_TYPE_FLOAT: + return PyFloat_FromDouble(g_value_get_float(value)); + case G_TYPE_DOUBLE: + return PyFloat_FromDouble(g_value_get_double(value)); + case G_TYPE_STRING: + { + const gchar *str = g_value_get_string(value); + + if (str) + return PYGLIB_PyUnicode_FromString(str); + Py_INCREF(Py_None); + return Py_None; + } + case G_TYPE_POINTER: + if (G_VALUE_HOLDS_GTYPE (value)) + return pyg_type_wrapper_new (g_value_get_gtype (value)); + else + return pyg_pointer_new(G_VALUE_TYPE(value), + g_value_get_pointer(value)); + case G_TYPE_BOXED: { + PyGTypeMarshal *bm; + + if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT)) { + PyObject *ret = (PyObject *)g_value_dup_boxed(value); + if (ret == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return ret; + } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) { + GValue *n_value = g_value_get_boxed (value); + return pyg_value_as_pyobject(n_value, copy_boxed); + } else if (G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY)) { + GValueArray *array = (GValueArray *) g_value_get_boxed(value); + PyObject *ret = PyList_New(array->n_values); + int i; + for (i = 0; i < array->n_values; ++i) + PyList_SET_ITEM(ret, i, pyg_value_as_pyobject + (array->values + i, copy_boxed)); + return ret; + } else if (G_VALUE_HOLDS(value, G_TYPE_GSTRING)) { + GString *string = (GString *) g_value_get_boxed(value); + PyObject *ret = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len); + return ret; + } + bm = pyg_type_lookup(G_VALUE_TYPE(value)); + if (bm) { + return bm->fromvalue(value); + } else { + if (copy_boxed) + return pyg_boxed_new(G_VALUE_TYPE(value), + g_value_get_boxed(value), TRUE, TRUE); + else + return pyg_boxed_new(G_VALUE_TYPE(value), + g_value_get_boxed(value),FALSE,FALSE); + } + } + case G_TYPE_PARAM: + return pyg_param_spec_new(g_value_get_param(value)); + case G_TYPE_OBJECT: + return pygobject_new(g_value_get_object(value)); + case G_TYPE_VARIANT: + { + GVariant *v = g_value_get_variant(value); + if (v == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return pyg_boxed_new(G_TYPE_VARIANT, g_variant_ref(v), FALSE, FALSE); + } + default: + { + PyGTypeMarshal *bm; + if ((bm = pyg_type_lookup(G_VALUE_TYPE(value)))) + return bm->fromvalue(value); + break; + } + } + g_snprintf(buf, sizeof(buf), "unknown type %s", + g_type_name(G_VALUE_TYPE(value))); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; +} + + +int +pyg_param_gvalue_from_pyobject(GValue* value, + PyObject* py_obj, + const GParamSpec* pspec) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + gunichar u; + + if (!pyg_pyobj_to_unichar_conv(py_obj, &u)) { + PyErr_Clear(); + return -1; + } + g_value_set_uint(value, u); + return 0; + } + else if (G_IS_PARAM_SPEC_VALUE_ARRAY(pspec)) + return pyg_value_array_from_pyobject(value, py_obj, + G_PARAM_SPEC_VALUE_ARRAY(pspec)); + else { + return pyg_value_from_pyobject(value, py_obj); + } +} + +PyObject* +pyg_param_gvalue_as_pyobject(const GValue* gvalue, + gboolean copy_boxed, + const GParamSpec* pspec) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + gunichar u; + Py_UNICODE uni_buffer[2] = { 0, 0 }; + + u = g_value_get_uint(gvalue); + uni_buffer[0] = u; + return PyUnicode_FromUnicode(uni_buffer, 1); + } + else { + return pyg_value_as_pyobject(gvalue, copy_boxed); + } +} + +PyObject * +pyg_strv_from_gvalue(const GValue *value) +{ + gchar **argv = (gchar **) g_value_get_boxed(value); + int argc = 0, i; + PyObject *py_argv; + + if (argv) { + while (argv[argc]) + argc++; + } + py_argv = PyList_New(argc); + for (i = 0; i < argc; ++i) + PyList_SET_ITEM(py_argv, i, PYGLIB_PyUnicode_FromString(argv[i])); + return py_argv; +} + +int +pyg_strv_to_gvalue(GValue *value, PyObject *obj) +{ + Py_ssize_t argc, i; + gchar **argv; + + if (!(PyTuple_Check(obj) || PyList_Check(obj))) + return -1; + + argc = PySequence_Length(obj); + for (i = 0; i < argc; ++i) + if (!PYGLIB_PyUnicode_Check(PySequence_Fast_GET_ITEM(obj, i))) + return -1; + argv = g_new(gchar *, argc + 1); + for (i = 0; i < argc; ++i) + argv[i] = g_strdup(PYGLIB_PyUnicode_AsString(PySequence_Fast_GET_ITEM(obj, i))); + argv[i] = NULL; + g_value_take_boxed(value, argv); + return 0; +} diff --git a/gi/pygi-value.h b/gi/pygi-value.h new file mode 100644 index 0000000..544da3c --- /dev/null +++ b/gi/pygi-value.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef __PYGI_VALUE_H__ +#define __PYGI_VALUE_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +GIArgument _pygi_argument_from_g_value(const GValue *value, + GITypeInfo *type_info); + +int pyg_value_from_pyobject(GValue *value, PyObject *obj); +int pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj); +PyObject *pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed); +int pyg_param_gvalue_from_pyobject(GValue* value, + PyObject* py_obj, + const GParamSpec* pspec); +PyObject *pyg_param_gvalue_as_pyobject(const GValue* gvalue, + gboolean copy_boxed, + const GParamSpec* pspec); +PyObject *pyg_strv_from_gvalue(const GValue *value); +int pyg_strv_to_gvalue(GValue *value, PyObject *obj); + +G_END_DECLS + +#endif /* __PYGI_VALUE_H__ */ diff --git a/gi/pygi.h b/gi/pygi.h index dcd91b3..3a1591f 100644 --- a/gi/pygi.h +++ b/gi/pygi.h @@ -26,8 +26,7 @@ # include #endif -#define NO_IMPORT_PYGOBJECT -#include +#include #include #include "pygi-cache.h" diff --git a/gi/pyginterface.c b/gi/pyginterface.c new file mode 100644 index 0000000..eb76ba0 --- /dev/null +++ b/gi/pyginterface.c @@ -0,0 +1,124 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * pyginterface.c: wrapper for the gobject library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pyglib.h" +#include "pygobject-private.h" + +#include "pyginterface.h" + +GQuark pyginterface_type_key; +GQuark pyginterface_info_key; + +PYGLIB_DEFINE_TYPE("gobject.GInterface", PyGInterface_Type, PyObject) + +static int +pyg_interface_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + gchar buf[512]; + + if (!PyArg_ParseTuple(args, ":GInterface.__init__")) + return -1; + + g_snprintf(buf, sizeof(buf), "%s can not be constructed", + Py_TYPE(self)->tp_name); + PyErr_SetString(PyExc_NotImplementedError, buf); + return -1; +} + +static void +pyg_interface_free(PyObject *op) +{ + PyObject_FREE(op); +} + +/** + * pyg_register_interface: + * @dict: a module dictionary. + * @class_name: the class name for the wrapper class. + * @gtype: the GType of the interface. + * @type: the wrapper class for the interface. + * + * Registers a Python class as the wrapper for a GInterface. As a + * convenience it will also place a reference to the wrapper class in + * the provided module dictionary. + */ +void +pyg_register_interface(PyObject *dict, const gchar *class_name, + GType gtype, PyTypeObject *type) +{ + PyObject *o; + + Py_TYPE(type) = &PyType_Type; + type->tp_base = &PyGInterface_Type; + + if (PyType_Ready(type) < 0) { + g_warning("could not ready `%s'", type->tp_name); + return; + } + + if (gtype) { + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(type->tp_dict, "__gtype__", o); + Py_DECREF(o); + } + + g_type_set_qdata(gtype, pyginterface_type_key, type); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); + +} + +void +pyg_register_interface_info(GType gtype, const GInterfaceInfo *info) +{ + g_type_set_qdata(gtype, pyginterface_info_key, (gpointer) info); +} + +const GInterfaceInfo * +pyg_lookup_interface_info(GType gtype) +{ + return g_type_get_qdata(gtype, pyginterface_info_key); +} + +void +pygobject_interface_register_types(PyObject *d) +{ + pyginterface_type_key = g_quark_from_static_string("PyGInterface::type"); + pyginterface_info_key = g_quark_from_static_string("PyGInterface::info"); + + PyGInterface_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGInterface_Type.tp_init = (initproc)pyg_interface_init; + PyGInterface_Type.tp_free = (freefunc)pyg_interface_free; + + PYGOBJECT_REGISTER_GTYPE(d, PyGInterface_Type, "GInterface", G_TYPE_INTERFACE) + + PyDict_SetItemString(PyGInterface_Type.tp_dict, "__doc__", + pyg_object_descr_doc_get()); + PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gdoc__", + pyg_object_descr_doc_get()); + +} diff --git a/gi/pyginterface.h b/gi/pyginterface.h new file mode 100644 index 0000000..0f390c2 --- /dev/null +++ b/gi/pyginterface.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * pyginterface.c: wrapper for the gobject library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_INTERFACE_H__ +#define __PYGOBJECT_INTERFACE_H__ + +extern GQuark pyginterface_type_key; +extern GQuark pyginterface_info_key; + +extern PyTypeObject PyGInterface_Type; + +void pyg_register_interface(PyObject *dict, + const gchar *class_name, + GType gtype, + PyTypeObject *type); +const GInterfaceInfo * pyg_lookup_interface_info(GType gtype); +void pyg_register_interface_info(GType gtype, const + GInterfaceInfo *info); +void pygobject_interface_register_types(PyObject *d); + +#endif /* __PYGOBJECT_INTERFACE_H__ */ diff --git a/gi/pyglib-private.h b/gi/pyglib-private.h new file mode 100644 index 0000000..9f05816 --- /dev/null +++ b/gi/pyglib-private.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGLIB_PRIVATE_H__ +#define __PYGLIB_PRIVATE_H__ + +#include +#include + +#include +#include + +G_BEGIN_DECLS + +gboolean _pyglib_handler_marshal(gpointer user_data); +void _pyglib_destroy_notify(gpointer user_data); + +extern PyObject *PyGError; +extern PyObject *pyglib__glib_module_create (void); + +G_END_DECLS + +#endif /* __PYGLIB_PRIVATE_H__ */ + + diff --git a/gi/pyglib-python-compat.h b/gi/pyglib-python-compat.h new file mode 100644 index 0000000..40e79b4 --- /dev/null +++ b/gi/pyglib-python-compat.h @@ -0,0 +1,194 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGLIB_PYTHON_COMPAT_H__ +#define __PYGLIB_PYTHON_COMPAT_H__ + +# define PYGLIB_CPointer_Check PyCapsule_CheckExact +# define PYGLIB_CPointer_WrapPointer(ptr, typename) \ + PyCapsule_New(ptr, typename, NULL) +# define PYGLIB_CPointer_GetPointer(obj, typename) \ + PyCapsule_GetPointer(obj, typename) +# define PYGLIB_CPointer_Import(module, symbol) \ + PyCapsule_Import(##module##.##symbol##, FALSE) + + +#define PYGLIB_MODULE_ERROR_RETURN NULL + +/* Compilation on Python 2.x */ +#if PY_VERSION_HEX < 0x03000000 + +#define RO READONLY + +#define PYGLIB_PyBaseString_Check(ob) (PyString_Check(ob) || PyUnicode_Check(ob)) + +#define PYGLIB_PyUnicode_Check PyString_Check +#define PYGLIB_PyUnicode_AsString PyString_AsString +#define PYGLIB_PyUnicode_AsStringAndSize PyString_AsStringAndSize +#define PYGLIB_PyUnicode_FromString PyString_FromString +#define PYGLIB_PyUnicode_FromStringAndSize PyString_FromStringAndSize +#define PYGLIB_PyUnicode_FromFormat PyString_FromFormat +#define PYGLIB_PyUnicode_AS_STRING PyString_AS_STRING +#define PYGLIB_PyUnicode_GET_SIZE PyString_GET_SIZE +#define PYGLIB_PyUnicode_Type PyString_Type +#define PYGLIB_PyUnicode_InternFromString PyString_InternFromString +#define PYGLIB_PyUnicode_InternInPlace PyString_InternInPlace + +#define PYGLIB_PyBytes_FromString PyString_FromString +#define PYGLIB_PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PYGLIB_PyBytes_Resize _PyString_Resize +#define PYGLIB_PyBytes_AsString PyString_AsString +#define PYGLIB_PyBytes_Size PyString_Size +#define PYGLIB_PyBytes_Check PyString_Check + +#define PYGLIB_PyLong_Check PyInt_Check +#define PYGLIB_PyLong_FromLong PyInt_FromLong +#define PYGLIB_PyLong_FromSsize_t PyInt_FromSsize_t +#define PYGLIB_PyLong_FromSize_t PyInt_FromSize_t +#define PYGLIB_PyLong_AsLong PyInt_AsLong +#define PYGLIB_PyLongObject PyIntObject +#define PYGLIB_PyLong_Type PyInt_Type +#define PYGLIB_PyLong_AS_LONG PyInt_AS_LONG +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) + +/* Python 2.7 lacks a PyInt_FromUnsignedLong function; use signed longs, and + * rely on PyInt_AsUnsignedLong() to interpret them correctly */ +#define PYGLIB_PyLong_FromUnsignedLong PyInt_FromLong +#define PYGLIB_PyLong_AsUnsignedLong(o) PyInt_AsUnsignedLongMask((PyObject*)(o)) + +#define PYGLIB_PyNumber_Long PyNumber_Int + +#ifndef PyVarObject_HEAD_INIT +#define PyVarObject_HEAD_INIT(base, size) \ + PyObject_HEAD_INIT(base) \ + size, +#endif + +#define PYGLIB_MODULE_START(symbol, modname) \ +PyObject * pyglib_##symbol##_module_create(void); \ +DL_EXPORT(void) init##symbol(void); \ +DL_EXPORT(void) init##symbol(void) { \ + pyglib_##symbol##_module_create(); \ +}; \ +PyObject * pyglib_##symbol##_module_create(void) \ +{ \ + PyObject *module; \ + module = Py_InitModule(modname, symbol##_functions); + +#define PYGLIB_MODULE_END return module; } + +#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \ +PyTypeObject symbol = { \ + PyObject_HEAD_INIT(NULL) \ + 0, \ + typename, \ + sizeof(csymbol), \ + 0, \ +}; + +#define PYGLIB_REGISTER_TYPE(d, type, name) \ + if (!type.tp_alloc) \ + type.tp_alloc = PyType_GenericAlloc; \ + if (!type.tp_new) \ + type.tp_new = PyType_GenericNew; \ + if (PyType_Ready(&type)) \ + return; \ + PyDict_SetItemString(d, name, (PyObject *)&type); + +#else + +#define PYGLIB_MODULE_START(symbol, modname) \ + static struct PyModuleDef _##symbol##module = { \ + PyModuleDef_HEAD_INIT, \ + modname, \ + NULL, \ + -1, \ + symbol##_functions, \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +}; \ +PyObject * pyglib_##symbol##_module_create(void); \ +PyMODINIT_FUNC PyInit_##symbol(void); \ +PyMODINIT_FUNC PyInit_##symbol(void) { \ + return pyglib_##symbol##_module_create(); \ +}; \ +PyObject * pyglib_##symbol##_module_create(void) \ +{ \ + PyObject *module; \ + module = PyModule_Create(&_##symbol##module); + +#define PYGLIB_MODULE_END return module; } + +#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \ +PyTypeObject symbol = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + typename, \ + sizeof(csymbol) \ +}; + +#define PYGLIB_REGISTER_TYPE(d, type, name) \ + if (!type.tp_alloc) \ + type.tp_alloc = PyType_GenericAlloc; \ + if (!type.tp_new) \ + type.tp_new = PyType_GenericNew; \ + if (PyType_Ready(&type)) \ + return; \ + PyDict_SetItemString(d, name, (PyObject *)&type); + +#define PYGLIB_PyBaseString_Check PyUnicode_Check + +#define PYGLIB_PyUnicode_Check PyUnicode_Check +#define PYGLIB_PyUnicode_AsString _PyUnicode_AsString +#define PYGLIB_PyUnicode_AsStringAndSize(obj, buf, size) \ + (((*(buf) = _PyUnicode_AsStringAndSize(obj, size)) != NULL) ? 0 : -1) +#define PYGLIB_PyUnicode_FromString PyUnicode_FromString +#define PYGLIB_PyUnicode_FromStringAndSize PyUnicode_FromStringAndSize +#define PYGLIB_PyUnicode_FromFormat PyUnicode_FromFormat +#define PYGLIB_PyUnicode_GET_SIZE PyUnicode_GET_SIZE +#define PYGLIB_PyUnicode_Resize PyUnicode_Resize +#define PYGLIB_PyUnicode_Type PyUnicode_Type +#define PYGLIB_PyUnicode_InternFromString PyUnicode_InternFromString +#define PYGLIB_PyUnicode_InternInPlace PyUnicode_InternInPlace + +#define PYGLIB_PyLong_Check PyLong_Check +#define PYGLIB_PyLong_FromLong PyLong_FromLong +#define PYGLIB_PyLong_FromSize_t PyLong_FromSize_t +#define PYGLIB_PyLong_AsLong PyLong_AsLong +#define PYGLIB_PyLong_AS_LONG(o) PyLong_AS_LONG((PyObject*)(o)) +#define PYGLIB_PyLongObject PyLongObject +#define PYGLIB_PyLong_Type PyLong_Type + +#define PYGLIB_PyLong_FromUnsignedLong PyLong_FromUnsignedLong +#define PYGLIB_PyLong_AsUnsignedLong(o) PyLong_AsUnsignedLongMask((PyObject*)(o)) + +#define PYGLIB_PyBytes_FromString PyBytes_FromString +#define PYGLIB_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +#define PYGLIB_PyBytes_Resize(o, len) _PyBytes_Resize(o, len) +#define PYGLIB_PyBytes_AsString PyBytes_AsString +#define PYGLIB_PyBytes_Size PyBytes_Size +#define PYGLIB_PyBytes_Check PyBytes_Check + +#define PYGLIB_PyNumber_Long PyNumber_Long + +#endif + +#endif /* __PYGLIB_PYTHON_COMPAT_H__ */ diff --git a/gi/pyglib.c b/gi/pyglib.c new file mode 100644 index 0000000..15109fd --- /dev/null +++ b/gi/pyglib.c @@ -0,0 +1,402 @@ +/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "pyglib.h" +#include "pyglib-private.h" +#include "pygoptioncontext.h" +#include "pygoptiongroup.h" + +static PyObject *exception_table = NULL; + +/** + * pyglib_error_marshal: + * @error: a pointer to the GError. + * + * Checks to see if @error has been set. If @error has been set, then a + * GLib.GError Python exception object is returned (but not raised). + * + * Returns: a GLib.GError Python exception object, or NULL. + */ +PyObject * +pyglib_error_marshal (GError **error) +{ + PyGILState_STATE state; + PyObject *exc_type; + PyObject *exc_instance; + PyObject *d; + + g_return_val_if_fail(error != NULL, NULL); + + if (*error == NULL) + return NULL; + + state = pyglib_gil_state_ensure(); + + exc_type = PyGError; + if (exception_table != NULL) + { + PyObject *item; + item = PyDict_GetItem(exception_table, PYGLIB_PyLong_FromLong((*error)->domain)); + if (item != NULL) + exc_type = item; + } + + exc_instance = PyObject_CallFunction(exc_type, "z", (*error)->message); + + if ((*error)->domain) { + PyObject_SetAttrString(exc_instance, "domain", + d=PYGLIB_PyUnicode_FromString(g_quark_to_string((*error)->domain))); + Py_DECREF(d); + } + else + PyObject_SetAttrString(exc_instance, "domain", Py_None); + + PyObject_SetAttrString(exc_instance, "code", + d=PYGLIB_PyLong_FromLong((*error)->code)); + Py_DECREF(d); + + if ((*error)->message) { + PyObject_SetAttrString(exc_instance, "message", + d=PYGLIB_PyUnicode_FromString((*error)->message)); + Py_DECREF(d); + } else { + PyObject_SetAttrString(exc_instance, "message", Py_None); + } + + pyglib_gil_state_release(state); + + return exc_instance; +} + +/** + * pyglib_error_check: + * @error: a pointer to the GError. + * + * Checks to see if the GError has been set. If the error has been + * set, then the glib.GError Python exception will be raised, and + * the GError cleared. + * + * Returns: True if an error was set. + */ +gboolean +pyglib_error_check(GError **error) +{ + PyGILState_STATE state; + PyObject *exc_instance; + + g_return_val_if_fail(error != NULL, FALSE); + if (*error == NULL) + return FALSE; + + state = pyglib_gil_state_ensure(); + + exc_instance = pyglib_error_marshal (error); + PyErr_SetObject(PyGError, exc_instance); + Py_DECREF(exc_instance); + g_clear_error(error); + + pyglib_gil_state_release(state); + + return TRUE; +} + +/** + * pyglib_gerror_exception_check: + * @error: a standard GLib GError ** output parameter + * + * Checks to see if a GError exception has been raised, and if so + * translates the python exception to a standard GLib GError. If the + * raised exception is not a GError then PyErr_Print() is called. + * + * Returns: 0 if no exception has been raised, -1 if it is a + * valid glib.GError, -2 otherwise. + */ +gboolean +pyglib_gerror_exception_check(GError **error) +{ + PyObject *type, *value, *traceback; + PyObject *py_message, *py_domain, *py_code; + const char *bad_gerror_message; + + PyErr_Fetch(&type, &value, &traceback); + if (type == NULL) + return 0; + PyErr_NormalizeException(&type, &value, &traceback); + if (value == NULL) { + PyErr_Restore(type, value, traceback); + PyErr_Print(); + return -2; + } + if (!value || + !PyErr_GivenExceptionMatches(type, + (PyObject *) PyGError)) { + PyErr_Restore(type, value, traceback); + PyErr_Print(); + return -2; + } + Py_DECREF(type); + Py_XDECREF(traceback); + + py_message = PyObject_GetAttrString(value, "message"); + if (!py_message || !PYGLIB_PyUnicode_Check(py_message)) { + bad_gerror_message = "gi._glib.GError instances must have a 'message' string attribute"; + Py_XDECREF(py_message); + goto bad_gerror; + } + + py_domain = PyObject_GetAttrString(value, "domain"); + if (!py_domain || !PYGLIB_PyUnicode_Check(py_domain)) { + bad_gerror_message = "gi._glib.GError instances must have a 'domain' string attribute"; + Py_DECREF(py_message); + Py_XDECREF(py_domain); + goto bad_gerror; + } + + py_code = PyObject_GetAttrString(value, "code"); + if (!py_code || !PYGLIB_PyLong_Check(py_code)) { + bad_gerror_message = "gi._glib.GError instances must have a 'code' int attribute"; + Py_DECREF(py_message); + Py_DECREF(py_domain); + Py_XDECREF(py_code); + goto bad_gerror; + } + + g_set_error(error, g_quark_from_string(PYGLIB_PyUnicode_AsString(py_domain)), + PYGLIB_PyLong_AsLong(py_code), "%s", PYGLIB_PyUnicode_AsString(py_message)); + + Py_DECREF(py_message); + Py_DECREF(py_code); + Py_DECREF(py_domain); + return -1; + +bad_gerror: + Py_DECREF(value); + g_set_error(error, g_quark_from_static_string("pyglib"), 0, "%s", bad_gerror_message); + PyErr_SetString(PyExc_ValueError, bad_gerror_message); + PyErr_Print(); + return -2; +} + +/** + * pyglib_register_exception_for_domain: + * @name: name of the exception + * @error_domain: error domain + * + * Registers a new glib.GError exception subclass called #name for + * a specific #domain. This exception will be raised when a GError + * of the same domain is passed in to pyglib_error_check(). + * + * Returns: the new exception + */ +PyObject * +pyglib_register_exception_for_domain(gchar *name, + gint error_domain) +{ + PyObject *exception; + + exception = PyErr_NewException(name, PyGError, NULL); + + if (exception_table == NULL) + exception_table = PyDict_New(); + + PyDict_SetItem(exception_table, + PYGLIB_PyLong_FromLong(error_domain), + exception); + + return exception; +} + +/** + * pyg_option_group_transfer_group: + * @group: a GOptionGroup wrapper + * + * This is used to transfer the GOptionGroup to a GOptionContext. After this + * is called, the calle must handle the release of the GOptionGroup. + * + * When #NULL is returned, the GOptionGroup was already transfered. + * + * Returns: Either #NULL or the wrapped GOptionGroup. + */ +GOptionGroup * +pyglib_option_group_transfer_group(PyObject *obj) +{ + PyGOptionGroup *self = (PyGOptionGroup*)obj; + + if (self->is_in_context) + return NULL; + + self->is_in_context = TRUE; + + /* Here we increase the reference count of the PyGOptionGroup, because now + * the GOptionContext holds an reference to us (it is the userdata passed + * to g_option_group_new(). + * + * The GOptionGroup is freed with the GOptionContext. + * + * We set it here because if we would do this in the init method we would + * hold two references and the PyGOptionGroup would never be freed. + */ + Py_INCREF(self); + + return self->group; +} + + +/****** Private *****/ + +/** + * _pyglib_destroy_notify: + * @user_data: a PyObject pointer. + * + * A function that can be used as a GDestroyNotify callback that will + * call Py_DECREF on the data. + */ +void +_pyglib_destroy_notify(gpointer user_data) +{ + PyObject *obj = (PyObject *)user_data; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_DECREF(obj); + pyglib_gil_state_release(state); +} + +gboolean +_pyglib_handler_marshal(gpointer user_data) +{ + PyObject *tuple, *ret; + gboolean res; + PyGILState_STATE state; + + g_return_val_if_fail(user_data != NULL, FALSE); + + state = pyglib_gil_state_ensure(); + + tuple = (PyObject *)user_data; + ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0), + PyTuple_GetItem(tuple, 1)); + if (!ret) { + PyErr_Print(); + res = FALSE; + } else { + res = PyObject_IsTrue(ret); + Py_DECREF(ret); + } + + pyglib_gil_state_release(state); + + return res; +} + +PyObject* +_pyglib_generic_ptr_richcompare(void* a, void *b, int op) +{ + PyObject *res; + + switch (op) { + + case Py_EQ: + res = (a == b) ? Py_True : Py_False; + break; + + case Py_NE: + res = (a != b) ? Py_True : Py_False; + break; + + case Py_LT: + res = (a < b) ? Py_True : Py_False; + break; + + case Py_LE: + res = (a <= b) ? Py_True : Py_False; + break; + + case Py_GT: + res = (a > b) ? Py_True : Py_False; + break; + + case Py_GE: + res = (a >= b) ? Py_True : Py_False; + break; + + default: + res = Py_NotImplemented; + break; + } + + Py_INCREF(res); + return res; +} + +PyObject* +_pyglib_generic_long_richcompare(long a, long b, int op) +{ + PyObject *res; + + switch (op) { + + case Py_EQ: + res = (a == b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + case Py_NE: + res = (a != b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + + case Py_LT: + res = (a < b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + case Py_LE: + res = (a <= b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + case Py_GT: + res = (a > b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + case Py_GE: + res = (a >= b) ? Py_True : Py_False; + Py_INCREF(res); + break; + + default: + res = Py_NotImplemented; + Py_INCREF(res); + break; + } + + return res; +} + diff --git a/gi/pyglib.h b/gi/pyglib.h new file mode 100644 index 0000000..9c7b22b --- /dev/null +++ b/gi/pyglib.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGLIB_H__ +#define __PYGLIB_H__ + +#include + +#include + +G_BEGIN_DECLS + +typedef void (*PyGLibThreadsEnabledFunc) (void); +typedef void (*PyGLibThreadBlockFunc) (void); + +#ifdef DISABLE_THREADING +# define pyglib_gil_state_ensure() PyGILState_LOCKED +# define pyglib_gil_state_release(state) state +#else +# define pyglib_gil_state_ensure PyGILState_Ensure +# define pyglib_gil_state_release PyGILState_Release +#endif + +gboolean pyglib_error_check(GError **error); +PyObject *pyglib_error_marshal (GError **error); +gboolean pyglib_gerror_exception_check(GError **error); +PyObject *pyglib_register_exception_for_domain(gchar *name, + gint error_domain); +GOptionGroup * pyglib_option_group_transfer_group(PyObject *self); + +/* Private: for gobject <-> glib interaction only. */ +PyObject* _pyglib_generic_ptr_richcompare(void* a, void *b, int op); +PyObject* _pyglib_generic_long_richcompare(long a, long b, int op); + + +#define PYGLIB_REGISTER_TYPE(d, type, name) \ + if (!type.tp_alloc) \ + type.tp_alloc = PyType_GenericAlloc; \ + if (!type.tp_new) \ + type.tp_new = PyType_GenericNew; \ + if (PyType_Ready(&type)) \ + return; \ + PyDict_SetItemString(d, name, (PyObject *)&type); + + +G_END_DECLS + +#endif /* __PYGLIB_H__ */ + diff --git a/gi/pygobject-private.h b/gi/pygobject-private.h new file mode 100644 index 0000000..be565d6 --- /dev/null +++ b/gi/pygobject-private.h @@ -0,0 +1,189 @@ +#ifndef _PYGOBJECT_PRIVATE_H_ +#define _PYGOBJECT_PRIVATE_H_ + +#ifdef _PYGOBJECT_H_ +# error "include pygobject.h or pygobject-private.h, but not both" +#endif + +#define _INSIDE_PYGOBJECT_ +#include "pygobject.h" + +#include "pyglib-python-compat.h" + +#define PYGOBJECT_REGISTER_GTYPE(d, type, name, gtype) \ + { \ + PyObject *o; \ + PYGLIB_REGISTER_TYPE(d, type, name); \ + PyDict_SetItemString(type.tp_dict, "__gtype__", \ + o=pyg_type_wrapper_new(gtype)); \ + Py_DECREF(o); \ +} + +/* from gobjectmodule.c */ +extern struct _PyGObject_Functions pygobject_api_functions; + + +#ifndef Py_CLEAR /* since Python 2.4 */ +# define Py_CLEAR(op) \ + do { \ + if (op) { \ + PyObject *tmp = (PyObject *)(op); \ + (op) = NULL; \ + Py_DECREF(tmp); \ + } \ + } while (0) +#endif + +extern GType PY_TYPE_OBJECT; + +extern GQuark pygboxed_type_key; +extern GQuark pygboxed_marshal_key; +extern GQuark pygenum_class_key; +extern GQuark pygflags_class_key; +extern GQuark pyginterface_type_key; +extern GQuark pyginterface_info_key; +extern GQuark pygobject_class_init_key; +extern GQuark pygobject_class_key; +extern GQuark pygobject_wrapper_key; +extern GQuark pygpointer_class_key; +extern GQuark pygobject_has_updated_constructor_key; +extern GQuark pygobject_instance_data_key; +extern GQuark pygobject_custom_key; + +void pygobject_data_free (PyGObjectData *data); +void pyg_destroy_notify (gpointer user_data); +gboolean pyg_handler_marshal (gpointer user_data); +gboolean pyg_error_check (GError **error); +int pygobject_constructv (PyGObject *self, + guint n_parameters, + GParameter *parameters); + +PyObject *pyg_integer_richcompare(PyObject *v, + PyObject *w, + int op); + +gboolean pyg_gerror_exception_check(GError **error); + +void pygobject_ref_float(PyGObject *self); +void pygobject_ref_sink(PyGObject *self); + +/* from pygtype.h */ +extern PyTypeObject PyGTypeWrapper_Type; + +PyObject *pyg_type_wrapper_new (GType type); +GType pyg_type_from_object_strict (PyObject *obj, gboolean strict); +GType pyg_type_from_object (PyObject *obj); + +gint pyg_enum_get_value (GType enum_type, PyObject *obj, gint *val); +gint pyg_flags_get_value (GType flag_type, PyObject *obj, guint *val); +int pyg_pyobj_to_unichar_conv (PyObject* py_obj, void* ptr); + +GClosure *pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data); +void pyg_closure_set_exception_handler(GClosure *closure, + PyClosureExceptionHandler handler); +GClosure *pyg_signal_class_closure_get(void); +GClosure *gclosure_from_pyfunc(PyGObject *object, PyObject *func); + +PyObject *pyg_object_descr_doc_get(void); +void pygobject_object_register_types(PyObject *d); + +extern PyTypeObject *PyGObject_MetaType; + +/* from pygobject.h */ +extern PyTypeObject PyGObject_Type; +extern PyTypeObject PyGProps_Type; +extern PyTypeObject PyGPropsDescr_Type; +extern PyTypeObject PyGPropsIter_Type; + + /* Data that belongs to the GObject instance, not the Python wrapper */ +struct _PyGObjectData { + PyTypeObject *type; /* wrapper type for this instance */ + GSList *closures; +}; + +void pygobject_register_class (PyObject *dict, + const gchar *type_name, + GType gtype, PyTypeObject *type, + PyObject *bases); +void pygobject_register_wrapper (PyObject *self); +PyObject * pygobject_new (GObject *obj); +PyObject * pygobject_new_full (GObject *obj, gboolean steal, gpointer g_class); +void pygobject_sink (GObject *obj); +PyTypeObject *pygobject_lookup_class (GType gtype); +void pygobject_watch_closure (PyObject *self, GClosure *closure); +int pyg_type_register (PyTypeObject *class, + const gchar *type_name); + +/* from pygboxed.c */ +extern PyTypeObject PyGBoxed_Type; + +void pyg_register_boxed (PyObject *dict, const gchar *class_name, + GType boxed_type, PyTypeObject *type); +PyObject * pyg_boxed_new (GType boxed_type, gpointer boxed, + gboolean copy_boxed, gboolean own_ref); + +extern PyTypeObject PyGPointer_Type; + +void pyg_register_pointer (PyObject *dict, const gchar *class_name, + GType pointer_type, PyTypeObject *type); +PyObject * pyg_pointer_new (GType pointer_type, gpointer pointer); + +const gchar * pyg_constant_strip_prefix(const gchar *name, const gchar *strip_prefix); + +/* pygflags */ +typedef struct { + PYGLIB_PyLongObject parent; + int zero_pad; /* must always be 0 */ + GType gtype; +} PyGFlags; + +extern PyTypeObject PyGFlags_Type; + +#define PyGFlags_Check(x) (PyObject_IsInstance((PyObject *)x, (PyObject *)&PyGFlags_Type) && g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_FLAGS)) + +extern PyObject * pyg_flags_add (PyObject * module, + const char * type_name, + const char * strip_prefix, + GType gtype); +extern PyObject * pyg_flags_from_gtype (GType gtype, + guint value); + +/* pygenum */ +#define PyGEnum_Check(x) (PyObject_IsInstance((PyObject *)x, (PyObject *)&PyGEnum_Type) && g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_ENUM)) + +typedef struct { + PYGLIB_PyLongObject parent; + int zero_pad; /* must always be 0 */ + GType gtype; +} PyGEnum; + +extern PyTypeObject PyGEnum_Type; + +extern PyObject * pyg_enum_add (PyObject * module, + const char * type_name, + const char * strip_prefix, + GType gtype); +extern PyObject * pyg_enum_from_gtype (GType gtype, + int value); + +/* pygtype.c */ +extern gboolean pyg_gtype_is_custom (GType gtype); + +/* pygobject.c */ +extern PyTypeObject PyGObjectWeakRef_Type; + +static inline PyGObjectData * +pyg_object_peek_inst_data(GObject *obj) +{ + return ((PyGObjectData *) + g_object_get_qdata(obj, pygobject_instance_data_key)); +} + +gboolean pygobject_prepare_construct_properties (GObjectClass *class, + PyObject *kwargs, + guint *n_params, + GParameter **params); +/* Defined by PYGLIB_MODULE_START */ +extern PyObject *pyglib__gobject_module_create (void); + +#endif /*_PYGOBJECT_PRIVATE_H_*/ diff --git a/gi/pygobject.c b/gi/pygobject.c new file mode 100644 index 0000000..215376b --- /dev/null +++ b/gi/pygobject.c @@ -0,0 +1,2473 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pygobject.c: wrapper for the GObject type. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pygobject-private.h" +#include "pyginterface.h" +#include "pygparamspec.h" + +#include "pygi.h" +#include "pygi-value.h" + +static void pygobject_dealloc(PyGObject *self); +static int pygobject_traverse(PyGObject *self, visitproc visit, void *arg); +static int pygobject_clear(PyGObject *self); +static PyObject * pyg_type_get_bases(GType gtype); +static inline int pygobject_clear(PyGObject *self); +static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data); +static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj); +static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, + gboolean check_for_present); +static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset, + gboolean check_for_present); +GType PY_TYPE_OBJECT = 0; +GQuark pygobject_custom_key; +GQuark pygobject_class_key; +GQuark pygobject_class_init_key; +GQuark pygobject_wrapper_key; +GQuark pygobject_has_updated_constructor_key; +GQuark pygobject_instance_data_key; + +/* Copied from glib. gobject uses hyphens in property names, but in Python + * we can only represent hyphens as underscores. Convert underscores to + * hyphens for glib compatibility. */ +static void +canonicalize_key (gchar *key) +{ + gchar *p; + + for (p = key; *p != 0; p++) + { + gchar c = *p; + + if (c != '-' && + (c < '0' || c > '9') && + (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) + *p = '-'; + } +} + +/* -------------- class <-> wrapper manipulation --------------- */ + +void +pygobject_data_free(PyGObjectData *data) +{ + /* This function may be called after the python interpreter has already + * been shut down. If this happens, we cannot do any python calls, so just + * free the memory. */ + PyGILState_STATE state; + PyThreadState *_save = NULL; + + GSList *closures, *tmp; + + if (Py_IsInitialized()) { + state = pyglib_gil_state_ensure(); + Py_DECREF(data->type); + /* We cannot use Py_BEGIN_ALLOW_THREADS here because this is inside + * a branch. */ + Py_UNBLOCK_THREADS; /* Modifies _save */ + } + + tmp = closures = data->closures; +#ifndef NDEBUG + data->closures = NULL; + data->type = NULL; +#endif + while (tmp) { + GClosure *closure = tmp->data; + + /* we get next item first, because the current link gets + * invalidated by pygobject_unwatch_closure */ + tmp = tmp->next; + g_closure_invalidate(closure); + } + + if (data->closures != NULL) + g_warning("invalidated all closures, but data->closures != NULL !"); + + g_free(data); + + if (Py_IsInitialized()) { + Py_BLOCK_THREADS; /* Restores _save */ + pyglib_gil_state_release(state); + } +} + +static inline PyGObjectData * +pygobject_data_new(void) +{ + PyGObjectData *data; + data = g_new0(PyGObjectData, 1); + return data; +} + +static inline PyGObjectData * +pygobject_get_inst_data(PyGObject *self) +{ + PyGObjectData *inst_data; + + if (G_UNLIKELY(!self->obj)) + return NULL; + inst_data = g_object_get_qdata(self->obj, pygobject_instance_data_key); + if (inst_data == NULL) + { + inst_data = pygobject_data_new(); + + inst_data->type = Py_TYPE(self); + Py_INCREF((PyObject *) inst_data->type); + + g_object_set_qdata_full(self->obj, pygobject_instance_data_key, + inst_data, (GDestroyNotify) pygobject_data_free); + } + return inst_data; +} + + +PyTypeObject *PyGObject_MetaType = NULL; + +/** + * pygobject_sink: + * @obj: a GObject + * + * As Python handles reference counting for us, the "floating + * reference" code in GTK is not all that useful. In fact, it can + * cause leaks. This function should be called to remove the floating + * references on objects on construction. + **/ +void +pygobject_sink(GObject *obj) +{ + /* The default behaviour for GInitiallyUnowned subclasses is to call ref_sink(). + * - if the object is new and owned by someone else, its ref has been sunk and + * we need to keep the one from that someone and add our own "fresh ref" + * - if the object is not and owned by nobody, its ref is floating and we need + * to transform it into a regular ref. + */ + if (G_IS_INITIALLY_UNOWNED(obj)) { + g_object_ref_sink(obj); + } +} + +typedef struct { + PyObject_HEAD + GParamSpec **props; + guint n_props; + guint index; +} PyGPropsIter; + +PYGLIB_DEFINE_TYPE("gi._gobject.GPropsIter", PyGPropsIter_Type, PyGPropsIter); + +static void +pyg_props_iter_dealloc(PyGPropsIter *self) +{ + g_free(self->props); + PyObject_Del((PyObject*) self); +} + +static PyObject* +pygobject_props_iter_next(PyGPropsIter *iter) +{ + if (iter->index < iter->n_props) + return pyg_param_spec_new(iter->props[iter->index++]); + else { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } +} + +typedef struct { + PyObject_HEAD + /* a reference to the object containing the properties */ + PyGObject *pygobject; + GType gtype; +} PyGProps; + +static void +PyGProps_dealloc(PyGProps* self) +{ + PyGObject *tmp; + + PyObject_GC_UnTrack((PyObject*)self); + + tmp = self->pygobject; + self->pygobject = NULL; + Py_XDECREF(tmp); + + PyObject_GC_Del((PyObject*)self); +} + +static PyObject* +build_parameter_list(GObjectClass *class) +{ + GParamSpec **props; + guint n_props = 0, i; + PyObject *prop_str; + PyObject *props_list; + + props = g_object_class_list_properties(class, &n_props); + props_list = PyList_New(n_props); + for (i = 0; i < n_props; i++) { + char *name; + name = g_strdup(g_param_spec_get_name(props[i])); + /* hyphens cannot belong in identifiers */ + g_strdelimit(name, "-", '_'); + prop_str = PYGLIB_PyUnicode_FromString(name); + + PyList_SetItem(props_list, i, prop_str); + g_free(name); + } + + if (props) + g_free(props); + + return props_list; +} + + +static PyObject* +PyGProps_getattro(PyGProps *self, PyObject *attr) +{ + char *attr_name, *property_name; + GObjectClass *class; + GParamSpec *pspec; + GValue value = { 0, }; + PyObject *ret; + + attr_name = PYGLIB_PyUnicode_AsString(attr); + if (!attr_name) { + PyErr_Clear(); + return PyObject_GenericGetAttr((PyObject *)self, attr); + } + + class = g_type_class_ref(self->gtype); + + /* g_object_class_find_property recurses through the class hierarchy, + * so the resulting pspec tells us the owner_type that owns the property + * we're dealing with. */ + property_name = g_strdup(attr_name); + canonicalize_key(property_name); + pspec = g_object_class_find_property(class, property_name); + g_free(property_name); + g_type_class_unref(class); + + if (!pspec) { + return PyObject_GenericGetAttr((PyObject *)self, attr); + } + + if (!(pspec->flags & G_PARAM_READABLE)) { + PyErr_Format(PyExc_TypeError, + "property '%s' is not readable", attr_name); + return NULL; + } + + if (!self->pygobject) { + /* If we're doing it without an instance, return a GParamSpec */ + return pyg_param_spec_new(pspec); + } + + if (!pyg_gtype_is_custom (pspec->owner_type)) { + /* The GType is not implemented at the Python level: see if we can + * read the property value via gi. */ + ret = pygi_get_property_value (self->pygobject, pspec); + if (ret) + return ret; + } + + /* The GType is implemented in Python, or we failed to read it via gi: + * do a straightforward read. */ + Py_BEGIN_ALLOW_THREADS; + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + g_object_get_property(self->pygobject->obj, pspec->name, &value); + Py_END_ALLOW_THREADS; + + ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); + g_value_unset(&value); + + return ret; +} + +static gboolean +set_property_from_pspec(GObject *obj, + GParamSpec *pspec, + PyObject *pvalue) +{ + GValue value = { 0, }; + + if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) { + PyErr_Format(PyExc_TypeError, + "property '%s' can only be set in constructor", + pspec->name); + return FALSE; + } + + if (!(pspec->flags & G_PARAM_WRITABLE)) { + PyErr_Format(PyExc_TypeError, + "property '%s' is not writable", pspec->name); + return FALSE; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) { + PyObject *pvalue_str = PyObject_Str(pvalue); + PyErr_Format(PyExc_TypeError, + "could not convert '%s' to type '%s' when setting property '%s.%s'", + PYGLIB_PyUnicode_AsString(pvalue_str), + g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec)), + G_OBJECT_TYPE_NAME(obj), + pspec->name); + Py_DECREF(pvalue_str); + return FALSE; + } + + Py_BEGIN_ALLOW_THREADS; + g_object_set_property(obj, pspec->name, &value); + g_value_unset(&value); + Py_END_ALLOW_THREADS; + + return TRUE; +} + +PYGLIB_DEFINE_TYPE("gi._gobject.GProps", PyGProps_Type, PyGProps); + +static int +PyGProps_setattro(PyGProps *self, PyObject *attr, PyObject *pvalue) +{ + GParamSpec *pspec; + char *attr_name, *property_name; + GObject *obj; + int ret = -1; + + if (pvalue == NULL) { + PyErr_SetString(PyExc_TypeError, "properties cannot be " + "deleted"); + return -1; + } + + attr_name = PYGLIB_PyUnicode_AsString(attr); + if (!attr_name) { + PyErr_Clear(); + return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue); + } + + if (!self->pygobject) { + PyErr_SetString(PyExc_TypeError, + "cannot set GOject properties without an instance"); + return -1; + } + + obj = self->pygobject->obj; + + property_name = g_strdup(attr_name); + canonicalize_key(property_name); + + /* g_object_class_find_property recurses through the class hierarchy, + * so the resulting pspec tells us the owner_type that owns the property + * we're dealing with. */ + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), + property_name); + g_free(property_name); + if (!pspec) { + return PyObject_GenericSetAttr((PyObject *)self, attr, pvalue); + } + if (!pyg_gtype_is_custom (pspec->owner_type)) { + /* This GType is not implemented in Python: see if we can set the + * property via gi. */ + ret = pygi_set_property_value (self->pygobject, pspec, pvalue); + if (ret == 0) + return 0; + else if (ret == -1 && PyErr_Occurred()) + return -1; + } + + /* This GType is implemented in Python, or we failed to set it via gi: + * do a straightforward set. */ + if (!set_property_from_pspec(obj, pspec, pvalue)) + return -1; + + return 0; +} + +static int +pygobject_props_traverse(PyGProps *self, visitproc visit, void *arg) +{ + if (self->pygobject && visit((PyObject *) self->pygobject, arg) < 0) + return -1; + return 0; +} + +static PyObject* +pygobject_props_get_iter(PyGProps *self) +{ + PyGPropsIter *iter; + GObjectClass *class; + + iter = PyObject_NEW(PyGPropsIter, &PyGPropsIter_Type); + class = g_type_class_ref(self->gtype); + iter->props = g_object_class_list_properties(class, &iter->n_props); + iter->index = 0; + g_type_class_unref(class); + return (PyObject *) iter; +} + +static PyObject* +pygobject_props_dir(PyGProps *self) +{ + PyObject *ret; + GObjectClass *class; + + class = g_type_class_ref (self->gtype); + ret = build_parameter_list (class); + g_type_class_unref (class); + + return ret; +} + +static PyMethodDef pygobject_props_methods[] = { + { "__dir__", (PyCFunction)pygobject_props_dir, METH_NOARGS}, + { NULL, NULL, 0} +}; + + +static Py_ssize_t +PyGProps_length(PyGProps *self) +{ + GObjectClass *class; + GParamSpec **props; + guint n_props; + + class = g_type_class_ref(self->gtype); + props = g_object_class_list_properties(class, &n_props); + g_type_class_unref(class); + g_free(props); + + return (Py_ssize_t)n_props; +} + +static PySequenceMethods _PyGProps_as_sequence = { + (lenfunc) PyGProps_length, + 0, + 0, + 0, + 0, + 0, + 0 +}; + +PYGLIB_DEFINE_TYPE("gi._gobject.GPropsDescr", PyGPropsDescr_Type, PyObject); + +static PyObject * +pyg_props_descr_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + PyGProps *gprops; + + gprops = PyObject_GC_New(PyGProps, &PyGProps_Type); + if (obj == NULL || obj == Py_None) { + gprops->pygobject = NULL; + gprops->gtype = pyg_type_from_object(type); + } else { + if (!PyObject_IsInstance(obj, (PyObject *) &PyGObject_Type)) { + PyErr_SetString(PyExc_TypeError, "cannot use GObject property" + " descriptor on non-GObject instances"); + return NULL; + } + Py_INCREF(obj); + gprops->pygobject = (PyGObject *) obj; + gprops->gtype = pyg_type_from_object(obj); + } + return (PyObject *) gprops; +} + +/** + * pygobject_register_class: + * @dict: the module dictionary. A reference to the type will be stored here. + * @type_name: not used ? + * @gtype: the GType of the GObject subclass. + * @type: the Python type object for this wrapper. + * @static_bases: a tuple of Python type objects that are the bases of + * this type + * + * This function is used to register a Python type as the wrapper for + * a particular GObject subclass. It will also insert a reference to + * the wrapper class into the module dictionary passed as a reference, + * which simplifies initialisation. + */ +void +pygobject_register_class(PyObject *dict, const gchar *type_name, + GType gtype, PyTypeObject *type, + PyObject *static_bases) +{ + PyObject *o; + const char *class_name, *s; + PyObject *runtime_bases; + PyObject *bases_list, *bases, *mod_name; + int i; + + class_name = type->tp_name; + s = strrchr(class_name, '.'); + if (s != NULL) + class_name = s + 1; + + runtime_bases = pyg_type_get_bases(gtype); + if (static_bases) { + PyTypeObject *py_parent_type = (PyTypeObject *) PyTuple_GET_ITEM(static_bases, 0); + bases_list = PySequence_List(static_bases); + /* we start at index 1 because we want to skip the primary + * base, otherwise we might get MRO conflict */ + for (i = 1; i < PyTuple_GET_SIZE(runtime_bases); ++i) + { + PyObject *base = PyTuple_GET_ITEM(runtime_bases, i); + int contains = PySequence_Contains(bases_list, base); + if (contains < 0) + PyErr_Print(); + else if (!contains) { + if (!PySequence_Contains(py_parent_type->tp_mro, base)) { +#if 0 + g_message("Adding missing base %s to type %s", + ((PyTypeObject *)base)->tp_name, type->tp_name); +#endif + PyList_Append(bases_list, base); + } + } + } + bases = PySequence_Tuple(bases_list); + Py_DECREF(bases_list); + Py_DECREF(runtime_bases); + } else + bases = runtime_bases; + + Py_TYPE(type) = PyGObject_MetaType; + type->tp_bases = bases; + if (G_LIKELY(bases)) { + type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0); + Py_INCREF(type->tp_base); + } + + pygobject_inherit_slots(type, bases, TRUE); + + if (PyType_Ready(type) < 0) { + g_warning ("couldn't make the type `%s' ready", type->tp_name); + return; + } + + /* Set type.__module__ to the name of the module, + * otherwise it'll default to 'gobject', see #376099 + */ + s = strrchr(type->tp_name, '.'); + if (s != NULL) { + mod_name = PYGLIB_PyUnicode_FromStringAndSize(type->tp_name, (int)(s - type->tp_name)); + PyDict_SetItemString(type->tp_dict, "__module__", mod_name); + Py_DECREF(mod_name); + } + + if (gtype) { + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(type->tp_dict, "__gtype__", o); + Py_DECREF(o); + + /* stash a pointer to the python class with the GType */ + Py_INCREF(type); + g_type_set_qdata(gtype, pygobject_class_key, type); + } + + /* set up __doc__ descriptor on type */ + PyDict_SetItemString(type->tp_dict, "__doc__", + pyg_object_descr_doc_get()); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); +} + +static void +pyg_toggle_notify (gpointer data, GObject *object, gboolean is_last_ref) +{ + PyGObject *self; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + + /* Avoid thread safety problems by using qdata for wrapper retrieval + * instead of the user data argument. + * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223 + */ + self = (PyGObject *)g_object_get_qdata (object, pygobject_wrapper_key); + if (self) { + if (is_last_ref) + Py_DECREF(self); + else + Py_INCREF(self); + } + + pyglib_gil_state_release(state); +} + + /* Called when the inst_dict is first created; switches the + reference counting strategy to start using toggle ref to keep the + wrapper alive while the GObject lives. In contrast, while + inst_dict was NULL the python wrapper is allowed to die at + will and is recreated on demand. */ +static inline void +pygobject_switch_to_toggle_ref(PyGObject *self) +{ + g_assert(self->obj->ref_count >= 1); + + if (self->private_flags.flags & PYGOBJECT_USING_TOGGLE_REF) + return; /* already using toggle ref */ + self->private_flags.flags |= PYGOBJECT_USING_TOGGLE_REF; + /* Note that add_toggle_ref will never immediately call back into + pyg_toggle_notify */ + Py_INCREF((PyObject *) self); + g_object_add_toggle_ref(self->obj, pyg_toggle_notify, NULL); + g_object_unref(self->obj); +} + +/* Called when an custom gobject is initalized via g_object_new instead of + its constructor. The next time the wrapper is access via + pygobject_new_full it will sink the floating reference instead of + adding a new reference and causing a leak */ + +void +pygobject_ref_float(PyGObject *self) +{ + /* should only be floated once */ + g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)); + + self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF; +} + +/* Called by gobject_new_full, if the floating flag is set remove it, otherwise + ref the pyobject */ +void +pygobject_ref_sink(PyGObject *self) +{ + if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF) + self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF; + else + Py_INCREF ( (PyObject *) self); +} + +/** + * pygobject_register_wrapper: + * @self: the wrapper instance + * + * In the constructor of PyGTK wrappers, this function should be + * called after setting the obj member. It will tie the wrapper + * instance to the GObject so that the same wrapper instance will + * always be used for this GObject instance. + */ +void +pygobject_register_wrapper(PyObject *self) +{ + PyGObject *gself; + + g_return_if_fail(self != NULL); + g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type)); + + gself = (PyGObject *)self; + + g_assert(gself->obj->ref_count >= 1); + /* save wrapper pointer so we can access it later */ + g_object_set_qdata_full(gself->obj, pygobject_wrapper_key, gself, NULL); + if (gself->inst_dict) + pygobject_switch_to_toggle_ref(gself); +} + +static PyObject * +pyg_type_get_bases(GType gtype) +{ + GType *interfaces, parent_type, interface_type; + guint n_interfaces; + PyTypeObject *py_parent_type, *py_interface_type; + PyObject *bases; + int i; + + if (G_UNLIKELY(gtype == G_TYPE_OBJECT)) + return NULL; + + /* Lookup the parent type */ + parent_type = g_type_parent(gtype); + py_parent_type = pygobject_lookup_class(parent_type); + interfaces = g_type_interfaces(gtype, &n_interfaces); + bases = PyTuple_New(n_interfaces + 1); + /* We will always put the parent at the first position in bases */ + Py_INCREF(py_parent_type); /* PyTuple_SetItem steals a reference */ + PyTuple_SetItem(bases, 0, (PyObject *) py_parent_type); + + /* And traverse interfaces */ + if (n_interfaces) { + for (i = 0; i < n_interfaces; i++) { + interface_type = interfaces[i]; + py_interface_type = pygobject_lookup_class(interface_type); + Py_INCREF(py_interface_type); /* PyTuple_SetItem steals a reference */ + PyTuple_SetItem(bases, i + 1, (PyObject *) py_interface_type); + } + } + g_free(interfaces); + return bases; +} + +/** + * pygobject_new_with_interfaces + * @gtype: the GType of the GObject subclass. + * + * Creates a new PyTypeObject from the given GType with interfaces attached in + * bases. + * + * Returns: a PyTypeObject for the new type or NULL if it couldn't be created + */ +static PyTypeObject * +pygobject_new_with_interfaces(GType gtype) +{ + PyGILState_STATE state; + PyObject *o; + PyTypeObject *type; + PyObject *dict; + PyTypeObject *py_parent_type; + PyObject *bases; + PyObject *modules, *module; + gchar *type_name, *mod_name, *gtype_name; + + state = pyglib_gil_state_ensure(); + + bases = pyg_type_get_bases(gtype); + py_parent_type = (PyTypeObject *) PyTuple_GetItem(bases, 0); + + dict = PyDict_New(); + + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(dict, "__gtype__", o); + Py_DECREF(o); + + /* set up __doc__ descriptor on type */ + PyDict_SetItemString(dict, "__doc__", pyg_object_descr_doc_get()); + + /* generate the pygtk module name and extract the base type name */ + gtype_name = (gchar*)g_type_name(gtype); + if (g_str_has_prefix(gtype_name, "Gtk")) { + mod_name = "gtk"; + gtype_name += 3; + type_name = g_strconcat(mod_name, ".", gtype_name, NULL); + } else if (g_str_has_prefix(gtype_name, "Gdk")) { + mod_name = "gtk.gdk"; + gtype_name += 3; + type_name = g_strconcat(mod_name, ".", gtype_name, NULL); + } else if (g_str_has_prefix(gtype_name, "Atk")) { + mod_name = "atk"; + gtype_name += 3; + type_name = g_strconcat(mod_name, ".", gtype_name, NULL); + } else if (g_str_has_prefix(gtype_name, "Pango")) { + mod_name = "pango"; + gtype_name += 5; + type_name = g_strconcat(mod_name, ".", gtype_name, NULL); + } else { + mod_name = "__main__"; + type_name = g_strconcat(mod_name, ".", gtype_name, NULL); + } + + type = (PyTypeObject*)PyObject_CallFunction((PyObject *) Py_TYPE(py_parent_type), + "sNN", type_name, bases, dict); + g_free(type_name); + + if (type == NULL) { + PyErr_Print(); + pyglib_gil_state_release(state); + return NULL; + } + + /* Workaround python tp_(get|set)attr slot inheritance bug. + * Fixes bug #144135. */ + if (!type->tp_getattr && py_parent_type->tp_getattr) { + type->tp_getattro = NULL; + type->tp_getattr = py_parent_type->tp_getattr; + } + if (!type->tp_setattr && py_parent_type->tp_setattr) { + type->tp_setattro = NULL; + type->tp_setattr = py_parent_type->tp_setattr; + } + /* override more python stupid hacks behind our back */ + type->tp_dealloc = py_parent_type->tp_dealloc; + type->tp_alloc = py_parent_type->tp_alloc; + type->tp_free = py_parent_type->tp_free; + type->tp_traverse = py_parent_type->tp_traverse; + type->tp_clear = py_parent_type->tp_clear; + + pygobject_inherit_slots(type, bases, FALSE); + + if (PyType_Ready(type) < 0) { + g_warning ("couldn't make the type `%s' ready", type->tp_name); + pyglib_gil_state_release(state); + return NULL; + } + /* insert type name in module dict */ + modules = PyImport_GetModuleDict(); + if ((module = PyDict_GetItemString(modules, mod_name)) != NULL) { + if (PyObject_SetAttrString(module, gtype_name, (PyObject *)type) < 0) + PyErr_Clear(); + } + + /* stash a pointer to the python class with the GType */ + Py_INCREF(type); + g_type_set_qdata(gtype, pygobject_class_key, type); + + pyglib_gil_state_release(state); + + return type; +} + +/* Pick appropriate value for given slot (at slot_offset inside + * PyTypeObject structure). It must be a pointer, e.g. a pointer to a + * function. We use the following heuristic: + * + * - Scan all types listed as bases of the type. + * - If for exactly one base type slot value is non-NULL and + * different from that of 'object' and 'GObject', set current type + * slot into that value. + * - Otherwise (if there is more than one such base type or none at + * all) don't touch it and live with Python default. + * + * The intention here is to propagate slot from custom wrappers to + * wrappers created at runtime when appropriate. We prefer to be on + * the safe side, so if there is potential collision (more than one + * custom slot value), we discard custom overrides altogether. + * + * When registering type with pygobject_register_class(), i.e. a type + * that has been manually created (likely with Codegen help), + * `check_for_present' should be set to TRUE. In this case, the + * function will never overwrite any non-NULL slots already present in + * the type. If `check_for_present' is FALSE, such non-NULL slots are + * though to be set by Python interpreter and so will be overwritten + * if heuristic above says so. + */ +static void +pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present) +{ + static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare), +#if PY_VERSION_HEX < 0x03000000 + offsetof(PyTypeObject, tp_compare), +#endif + offsetof(PyTypeObject, tp_richcompare), + offsetof(PyTypeObject, tp_hash), + offsetof(PyTypeObject, tp_iter), + offsetof(PyTypeObject, tp_repr), + offsetof(PyTypeObject, tp_str), + offsetof(PyTypeObject, tp_print) }; + int i; + + /* Happens when registering gobject.GObject itself, at least. */ + if (!bases) + return; + + for (i = 0; i < G_N_ELEMENTS(slot_offsets); ++i) + pygobject_find_slot_for(type, bases, slot_offsets[i], check_for_present); +} + +static void +pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset, + gboolean check_for_present) +{ +#define TYPE_SLOT(type) (* (void **) (((char *) (type)) + slot_offset)) + + void *found_slot = NULL; + int num_bases = PyTuple_Size(bases); + int i; + + if (check_for_present && TYPE_SLOT(type) != NULL) { + /* We are requested to check if there is any custom slot value + * in this type already and there actually is. Don't + * overwrite it. + */ + return; + } + + for (i = 0; i < num_bases; ++i) { + PyTypeObject *base_type = (PyTypeObject *) PyTuple_GetItem(bases, i); + void *slot = TYPE_SLOT(base_type); + + if (slot == NULL) + continue; + if (slot == TYPE_SLOT(&PyGObject_Type) || + slot == TYPE_SLOT(&PyBaseObject_Type)) + continue; + + if (found_slot != NULL && found_slot != slot) { + /* We have a conflict: more than one base use different + * custom slots. To be on the safe side, we bail out. + */ + return; + } + + found_slot = slot; + } + + /* Only perform the final assignment if at least one base has a + * custom value. Otherwise just leave this type's slot untouched. + */ + if (found_slot != NULL) + TYPE_SLOT(type) = found_slot; + +#undef TYPE_SLOT +} + +/** + * pygobject_lookup_class: + * @gtype: the GType of the GObject subclass. + * + * This function looks up the wrapper class used to represent + * instances of a GObject represented by @gtype. If no wrapper class + * or interface has been registered for the given GType, then a new + * type will be created. + * + * Returns: The wrapper class for the GObject or NULL if the + * GType has no registered type and a new type couldn't be created + */ +PyTypeObject * +pygobject_lookup_class(GType gtype) +{ + PyTypeObject *py_type; + + if (gtype == G_TYPE_INTERFACE) + return &PyGInterface_Type; + + py_type = g_type_get_qdata(gtype, pygobject_class_key); + if (py_type == NULL) { + py_type = g_type_get_qdata(gtype, pyginterface_type_key); + + if (py_type == NULL) + py_type = (PyTypeObject *)pygi_type_import_by_g_type(gtype); + + if (py_type == NULL) { + py_type = pygobject_new_with_interfaces(gtype); + g_type_set_qdata(gtype, pyginterface_type_key, py_type); + } + } + + return py_type; +} + +/** + * pygobject_new_full: + * @obj: a GObject instance. + * @steal: whether to steal a ref from the GObject or add (sink) a new one. + * @g_class: the GObjectClass + * + * This function gets a reference to a wrapper for the given GObject + * instance. If a wrapper has already been created, a new reference + * to that wrapper will be returned. Otherwise, a wrapper instance + * will be created. + * + * Returns: a reference to the wrapper for the GObject. + */ +PyObject * +pygobject_new_full(GObject *obj, gboolean steal, gpointer g_class) +{ + PyGObject *self; + + if (obj == NULL) { + Py_RETURN_NONE; + } + + /* If the GObject already has a PyObject wrapper stashed in its qdata, re-use it. + */ + self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key); + if (self != NULL) { + /* Note the use of "pygobject_ref_sink" here only deals with PyObject + * wrapper ref counts and has nothing to do with GObject. + */ + pygobject_ref_sink(self); + + /* If steal is true, we also want to decref the incoming GObjects which + * already have a Python wrapper because the wrapper is already holding a + * strong reference. + */ + if (steal) + g_object_unref (obj); + + } else { + /* create wrapper */ + PyGObjectData *inst_data = pyg_object_peek_inst_data(obj); + PyTypeObject *tp; + if (inst_data) + tp = inst_data->type; + else { + if (g_class) + tp = pygobject_lookup_class(G_OBJECT_CLASS_TYPE(g_class)); + else + tp = pygobject_lookup_class(G_OBJECT_TYPE(obj)); + } + g_assert(tp != NULL); + + /* need to bump type refcount if created with + pygobject_new_with_interfaces(). fixes bug #141042 */ + if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_INCREF(tp); + self = PyObject_GC_New(PyGObject, tp); + if (self == NULL) + return NULL; + self->inst_dict = NULL; + self->weakreflist = NULL; + self->private_flags.flags = 0; + self->obj = obj; + + /* If we are not stealing a ref or the object is floating, + * add a regular ref or sink the object. */ + if (g_object_is_floating (obj)) + self->private_flags.flags |= PYGOBJECT_GOBJECT_WAS_FLOATING; + if (!steal || self->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) + g_object_ref_sink (obj); + + pygobject_register_wrapper((PyObject *)self); + PyObject_GC_Track((PyObject *)self); + } + + return (PyObject *)self; +} + + +PyObject * +pygobject_new(GObject *obj) +{ + return pygobject_new_full(obj, + /*steal=*/FALSE, + NULL); +} + +static void +pygobject_unwatch_closure(gpointer data, GClosure *closure) +{ + PyGObjectData *inst_data = data; + + inst_data->closures = g_slist_remove (inst_data->closures, closure); +} + +/** + * pygobject_watch_closure: + * @self: a GObject wrapper instance + * @closure: a GClosure to watch + * + * Adds a closure to the list of watched closures for the wrapper. + * The closure must be one returned by pyg_closure_new(). When the + * cycle GC traverses the wrapper instance, it will enumerate the + * references to Python objects stored in watched closures. If the + * cycle GC tells the wrapper to clear itself, the watched closures + * will be invalidated. + */ +void +pygobject_watch_closure(PyObject *self, GClosure *closure) +{ + PyGObject *gself; + PyGObjectData *data; + + g_return_if_fail(self != NULL); + g_return_if_fail(PyObject_TypeCheck(self, &PyGObject_Type)); + g_return_if_fail(closure != NULL); + + gself = (PyGObject *)self; + data = pygobject_get_inst_data(gself); + g_return_if_fail(g_slist_find(data->closures, closure) == NULL); + data->closures = g_slist_prepend(data->closures, closure); + g_closure_add_invalidate_notifier(closure, data, pygobject_unwatch_closure); +} + + +/* -------------- PyGObject behaviour ----------------- */ + +PYGLIB_DEFINE_TYPE("gi._gobject.GObject", PyGObject_Type, PyGObject); + +static void +pygobject_dealloc(PyGObject *self) +{ + /* Untrack must be done first. This is because followup calls such as + * ClearWeakRefs could call into Python and cause new allocations to + * happen, which could in turn could trigger the garbage collector, + * which would then get confused as it is tracking this half-deallocated + * object. */ + PyObject_GC_UnTrack((PyObject *)self); + + PyObject_ClearWeakRefs((PyObject *)self); + /* this forces inst_data->type to be updated, which could prove + * important if a new wrapper has to be created and it is of a + * unregistered type */ + pygobject_get_inst_data(self); + pygobject_clear(self); + /* the following causes problems with subclassed types */ + /* Py_TYPE(self)->tp_free((PyObject *)self); */ + PyObject_GC_Del(self); +} + +static PyObject* +pygobject_richcompare(PyObject *self, PyObject *other, int op) +{ + int isinst; + + isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type); + if (isinst == -1) + return NULL; + if (!isinst) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type); + if (isinst == -1) + return NULL; + if (!isinst) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj, + ((PyGObject*)other)->obj, + op); +} + +static long +pygobject_hash(PyGObject *self) +{ + return (long)self->obj; +} + +static PyObject * +pygobject_repr(PyGObject *self) +{ + gchar buf[256]; + + g_snprintf(buf, sizeof(buf), + "<%s object at 0x%lx (%s at 0x%lx)>", + Py_TYPE(self)->tp_name, + (long)self, + self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized", + (long)self->obj); + return PYGLIB_PyUnicode_FromString(buf); +} + + +static int +pygobject_traverse(PyGObject *self, visitproc visit, void *arg) +{ + int ret = 0; + GSList *tmp; + PyGObjectData *data = pygobject_get_inst_data(self); + + if (self->inst_dict) ret = visit(self->inst_dict, arg); + if (ret != 0) return ret; + + if (data) { + + for (tmp = data->closures; tmp != NULL; tmp = tmp->next) { + PyGClosure *closure = tmp->data; + + if (closure->callback) ret = visit(closure->callback, arg); + if (ret != 0) return ret; + + if (closure->extra_args) ret = visit(closure->extra_args, arg); + if (ret != 0) return ret; + + if (closure->swap_data) ret = visit(closure->swap_data, arg); + if (ret != 0) return ret; + } + } + return ret; +} + +static inline int +pygobject_clear(PyGObject *self) +{ + if (self->obj) { + g_object_set_qdata_full(self->obj, pygobject_wrapper_key, NULL, NULL); + if (self->inst_dict) { + g_object_remove_toggle_ref(self->obj, pyg_toggle_notify, NULL); + self->private_flags.flags &= ~PYGOBJECT_USING_TOGGLE_REF; + } else { + Py_BEGIN_ALLOW_THREADS; + g_object_unref(self->obj); + Py_END_ALLOW_THREADS; + } + self->obj = NULL; + } + Py_CLEAR(self->inst_dict); + return 0; +} + +static void +pygobject_free(PyObject *op) +{ + PyObject_GC_Del(op); +} + +gboolean +pygobject_prepare_construct_properties(GObjectClass *class, PyObject *kwargs, + guint *n_params, GParameter **params) +{ + *n_params = 0; + *params = NULL; + + if (kwargs) { + Py_ssize_t pos = 0; + PyObject *key; + PyObject *value; + + *params = g_new0(GParameter, PyDict_Size(kwargs)); + while (PyDict_Next(kwargs, &pos, &key, &value)) { + GParamSpec *pspec; + GParameter *param = &(*params)[*n_params]; + const gchar *key_str = PYGLIB_PyUnicode_AsString(key); + + pspec = g_object_class_find_property(class, key_str); + if (!pspec) { + PyErr_Format(PyExc_TypeError, + "gobject `%s' doesn't support property `%s'", + G_OBJECT_CLASS_NAME(class), key_str); + return FALSE; + } + g_value_init(¶m->value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + if (pyg_param_gvalue_from_pyobject(¶m->value, value, pspec) < 0) { + PyErr_Format(PyExc_TypeError, + "could not convert value for property `%s' from %s to %s", + key_str, Py_TYPE(value)->tp_name, + g_type_name(G_PARAM_SPEC_VALUE_TYPE(pspec))); + return FALSE; + } + param->name = g_strdup(key_str); + ++(*n_params); + } + } + return TRUE; +} + +/* ---------------- PyGObject methods ----------------- */ + +static int +pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + GType object_type; + guint n_params = 0, i; + GParameter *params = NULL; + GObjectClass *class; + + /* Only do GObject creation and property setting if the GObject hasn't + * already been created. The case where self->obj already exists can occur + * when C constructors are called directly (Gtk.Button.new_with_label) + * and we are simply wrapping the result with a PyGObject. + * In these cases we want to ignore any keyword arguments passed along + * to __init__ and simply return. + * + * See: https://bugzilla.gnome.org/show_bug.cgi?id=705810 + */ + if (self->obj != NULL) + return 0; + + if (!PyArg_ParseTuple(args, ":GObject.__init__", NULL)) + return -1; + + object_type = pyg_type_from_object((PyObject *)self); + if (!object_type) + return -1; + + if (G_TYPE_IS_ABSTRACT(object_type)) { + PyErr_Format(PyExc_TypeError, "cannot create instance of abstract " + "(non-instantiable) type `%s'", g_type_name(object_type)); + return -1; + } + + if ((class = g_type_class_ref (object_type)) == NULL) { + PyErr_SetString(PyExc_TypeError, + "could not get a reference to type class"); + return -1; + } + + if (!pygobject_prepare_construct_properties (class, kwargs, &n_params, ¶ms)) + goto cleanup; + + if (pygobject_constructv(self, n_params, params)) + PyErr_SetString(PyExc_RuntimeError, "could not create object"); + + cleanup: + for (i = 0; i < n_params; i++) { + g_free((gchar *) params[i].name); + g_value_unset(¶ms[i].value); + } + g_free(params); + g_type_class_unref(class); + + return (self->obj) ? 0 : -1; +} + +#define CHECK_GOBJECT(self) \ + if (!G_IS_OBJECT(self->obj)) { \ + PyErr_Format(PyExc_TypeError, \ + "object at %p of type %s is not initialized", \ + self, Py_TYPE(self)->tp_name); \ + return NULL; \ + } + +static PyObject * +pygobject_get_property(PyGObject *self, PyObject *args) +{ + gchar *param_name; + GParamSpec *pspec; + GValue value = { 0, }; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s:GObject.get_property", ¶m_name)) + return NULL; + + CHECK_GOBJECT(self); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), + param_name); + if (!pspec) { + PyErr_Format(PyExc_TypeError, + "object of type `%s' does not have property `%s'", + g_type_name(G_OBJECT_TYPE(self->obj)), param_name); + return NULL; + } + if (!(pspec->flags & G_PARAM_READABLE)) { + PyErr_Format(PyExc_TypeError, "property %s is not readable", + param_name); + return NULL; + } + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + Py_BEGIN_ALLOW_THREADS; + g_object_get_property(self->obj, param_name, &value); + Py_END_ALLOW_THREADS; + + ret = pyg_param_gvalue_as_pyobject(&value, TRUE, pspec); + g_value_unset(&value); + return ret; +} + +static PyObject * +pygobject_get_properties(PyGObject *self, PyObject *args) +{ + GObjectClass *class; + int len, i; + PyObject *tuple; + + if ((len = PyTuple_Size(args)) < 1) { + PyErr_SetString(PyExc_TypeError, "requires at least one argument"); + return NULL; + } + + tuple = PyTuple_New(len); + class = G_OBJECT_GET_CLASS(self->obj); + for (i = 0; i < len; i++) { + PyObject *py_property = PyTuple_GetItem(args, i); + gchar *property_name; + GParamSpec *pspec; + GValue value = { 0 }; + PyObject *item; + + if (!PYGLIB_PyUnicode_Check(py_property)) { + PyErr_SetString(PyExc_TypeError, + "Expected string argument for property."); + return NULL; + } + + property_name = PYGLIB_PyUnicode_AsString(py_property); + + pspec = g_object_class_find_property(class, + property_name); + if (!pspec) { + PyErr_Format(PyExc_TypeError, + "object of type `%s' does not have property `%s'", + g_type_name(G_OBJECT_TYPE(self->obj)), property_name); + return NULL; + } + if (!(pspec->flags & G_PARAM_READABLE)) { + PyErr_Format(PyExc_TypeError, "property %s is not readable", + property_name); + return NULL; + } + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + Py_BEGIN_ALLOW_THREADS; + g_object_get_property(self->obj, property_name, &value); + Py_END_ALLOW_THREADS; + + item = pyg_value_as_pyobject(&value, TRUE); + PyTuple_SetItem(tuple, i, item); + + g_value_unset(&value); + } + + return tuple; +} + +static PyObject * +pygobject_set_property(PyGObject *self, PyObject *args) +{ + gchar *param_name; + GParamSpec *pspec; + PyObject *pvalue; + int ret = -1; + + if (!PyArg_ParseTuple(args, "sO:GObject.set_property", ¶m_name, + &pvalue)) + return NULL; + + CHECK_GOBJECT(self); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), + param_name); + if (!pspec) { + PyErr_Format(PyExc_TypeError, + "object of type `%s' does not have property `%s'", + g_type_name(G_OBJECT_TYPE(self->obj)), param_name); + return NULL; + } + + ret = pygi_set_property_value (self, pspec, pvalue); + if (ret == 0) + goto done; + else if (PyErr_Occurred()) + return NULL; + + if (!set_property_from_pspec(self->obj, pspec, pvalue)) + return NULL; + +done: + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs) +{ + GObjectClass *class; + Py_ssize_t pos; + PyObject *value; + PyObject *key; + PyObject *result = NULL; + + CHECK_GOBJECT(self); + + class = G_OBJECT_GET_CLASS(self->obj); + + g_object_freeze_notify (G_OBJECT(self->obj)); + pos = 0; + + while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) { + gchar *key_str = PYGLIB_PyUnicode_AsString(key); + GParamSpec *pspec; + int ret = -1; + + pspec = g_object_class_find_property(class, key_str); + if (!pspec) { + gchar buf[512]; + + g_snprintf(buf, sizeof(buf), + "object `%s' doesn't support property `%s'", + g_type_name(G_OBJECT_TYPE(self->obj)), key_str); + PyErr_SetString(PyExc_TypeError, buf); + goto exit; + } + + ret = pygi_set_property_value (self, pspec, value); + if (ret != 0) { + /* Non-zero return code means that either an error occured ...*/ + if (PyErr_Occurred()) + goto exit; + + /* ... or the property couldn't be found , so let's try the default + * call. */ + if (!set_property_from_pspec(G_OBJECT(self->obj), pspec, value)) + goto exit; + } + } + + result = Py_None; + + exit: + g_object_thaw_notify (G_OBJECT(self->obj)); + Py_XINCREF(result); + return result; +} + +/* custom closure for gobject bindings */ +static void +pygbinding_closure_invalidate(gpointer data, GClosure *closure) +{ + PyGClosure *pc = (PyGClosure *)closure; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_XDECREF(pc->callback); + Py_XDECREF(pc->extra_args); + pyglib_gil_state_release(state); + + pc->callback = NULL; + pc->extra_args = NULL; +} + +static void +pygbinding_marshal (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + PyGILState_STATE state; + PyGClosure *pc = (PyGClosure *)closure; + PyObject *params, *ret; + GValue *out_value; + + state = pyglib_gil_state_ensure(); + + /* construct Python tuple for the parameter values */ + params = PyTuple_New(2); + PyTuple_SetItem (params, 0, pyg_value_as_pyobject(¶m_values[0], FALSE)); + PyTuple_SetItem (params, 1, pyg_value_as_pyobject(¶m_values[1], FALSE)); + + /* params passed to function may have extra arguments */ + if (pc->extra_args) { + PyObject *tuple = params; + params = PySequence_Concat(tuple, pc->extra_args); + Py_DECREF(tuple); + } + ret = PyObject_CallObject(pc->callback, params); + if (!ret) { + PyErr_Print (); + goto out; + } else if (ret == Py_None) { + g_value_set_boolean (return_value, FALSE); + goto out; + } + + out_value = g_value_get_boxed (¶m_values[2]); + if (pyg_value_from_pyobject (out_value, ret) != 0) { + PyErr_SetString (PyExc_ValueError, "can't convert value"); + PyErr_Print (); + g_value_set_boolean (return_value, FALSE); + } else { + g_value_set_boolean (return_value, TRUE); + } + + Py_DECREF(ret); + +out: + Py_DECREF(params); + pyglib_gil_state_release(state); +} + +static GClosure * +pygbinding_closure_new (PyObject *callback, PyObject *extra_args) +{ + GClosure *closure; + + g_return_val_if_fail(callback != NULL, NULL); + closure = g_closure_new_simple(sizeof(PyGClosure), NULL); + g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate); + g_closure_set_marshal(closure, pygbinding_marshal); + Py_INCREF(callback); + ((PyGClosure *)closure)->callback = callback; + if (extra_args && extra_args != Py_None) { + Py_INCREF(extra_args); + if (!PyTuple_Check(extra_args)) { + PyObject *tmp = PyTuple_New(1); + PyTuple_SetItem(tmp, 0, extra_args); + extra_args = tmp; + } + ((PyGClosure *)closure)->extra_args = extra_args; + } + return closure; +} + +static PyObject * +pygobject_bind_property(PyGObject *self, PyObject *args) +{ + gchar *source_name, *target_name; + gchar *source_canon, *target_canon; + PyObject *target, *source_repr, *target_repr; + PyObject *transform_to, *transform_from, *user_data = NULL; + GBinding *binding; + GBindingFlags flags = G_BINDING_DEFAULT; + GClosure *to_closure = NULL, *from_closure = NULL; + + transform_from = NULL; + transform_to = NULL; + + if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property", + &source_name, &target, &target_name, &flags, + &transform_to, &transform_from, &user_data)) + return NULL; + + CHECK_GOBJECT(self); + if (!PyObject_TypeCheck(target, &PyGObject_Type)) { + PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject"); + return NULL; + } + + if (transform_to && transform_to != Py_None) { + if (!PyCallable_Check (transform_to)) { + PyErr_SetString (PyExc_TypeError, + "transform_to must be callable or None"); + return NULL; + } + to_closure = pygbinding_closure_new (transform_to, user_data); + } + + if (transform_from && transform_from != Py_None) { + if (!PyCallable_Check (transform_from)) { + PyErr_SetString (PyExc_TypeError, + "transform_from must be callable or None"); + return NULL; + } + from_closure = pygbinding_closure_new (transform_from, user_data); + } + + /* Canonicalize underscores to hyphens. Note the results must be freed. */ + source_canon = g_strdelimit(g_strdup(source_name), "_", '-'); + target_canon = g_strdelimit(g_strdup(target_name), "_", '-'); + + binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon, + pygobject_get(target), target_canon, + flags, to_closure, from_closure); + g_free(source_canon); + g_free(target_canon); + source_canon = target_canon = NULL; + + if (binding == NULL) { + source_repr = PyObject_Repr((PyObject*)self); + target_repr = PyObject_Repr(target); + PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s", + PYGLIB_PyUnicode_AsString(source_repr), source_name, + PYGLIB_PyUnicode_AsString(target_repr), target_name); + Py_DECREF(source_repr); + Py_DECREF(target_repr); + return NULL; + } + + return pygobject_new (G_OBJECT (binding)); +} + +static PyObject * +connect_helper(PyGObject *self, gchar *name, PyObject *callback, PyObject *extra_args, PyObject *object, gboolean after) +{ + guint sigid; + GQuark detail = 0; + GClosure *closure = NULL; + gulong handlerid; + GSignalQuery query_info; + + if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), + &sigid, &detail, TRUE)) { + PyObject *repr = PyObject_Repr((PyObject*)self); + PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", + PYGLIB_PyUnicode_AsString(repr), + name); + Py_DECREF(repr); + return NULL; + } + + g_signal_query (sigid, &query_info); + if (!pyg_gtype_is_custom (query_info.itype)) { + /* The signal is implemented by a non-Python class, probably + * something in the gi repository. */ + closure = pygi_signal_closure_new (self, query_info.itype, + query_info.signal_name, callback, + extra_args, object); + } + + if (!closure) { + /* The signal is either implemented at the Python level, or it comes + * from a foreign class that we don't have introspection data for. */ + closure = pyg_closure_new (callback, extra_args, object); + } + + pygobject_watch_closure((PyObject *)self, closure); + handlerid = g_signal_connect_closure_by_id(self->obj, sigid, detail, + closure, after); + return PyLong_FromUnsignedLong(handlerid); +} + +static PyObject * +pygobject_connect(PyGObject *self, PyObject *args) +{ + PyObject *first, *callback, *extra_args, *ret; + gchar *name; + guint len; + + len = PyTuple_Size(args); + if (len < 2) { + PyErr_SetString(PyExc_TypeError, + "GObject.connect requires at least 2 arguments"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 2); + if (!PyArg_ParseTuple(first, "sO:GObject.connect", &name, &callback)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "second argument must be callable"); + return NULL; + } + + CHECK_GOBJECT(self); + + extra_args = PySequence_GetSlice(args, 2, len); + if (extra_args == NULL) + return NULL; + + ret = connect_helper(self, name, callback, extra_args, NULL, FALSE); + Py_DECREF(extra_args); + return ret; +} + +static PyObject * +pygobject_connect_after(PyGObject *self, PyObject *args) +{ + PyObject *first, *callback, *extra_args, *ret; + gchar *name; + Py_ssize_t len; + + len = PyTuple_Size(args); + if (len < 2) { + PyErr_SetString(PyExc_TypeError, + "GObject.connect_after requires at least 2 arguments"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 2); + if (!PyArg_ParseTuple(first, "sO:GObject.connect_after", + &name, &callback)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "second argument must be callable"); + return NULL; + } + + CHECK_GOBJECT(self); + + extra_args = PySequence_GetSlice(args, 2, len); + if (extra_args == NULL) + return NULL; + + ret = connect_helper(self, name, callback, extra_args, NULL, TRUE); + Py_DECREF(extra_args); + return ret; +} + +static PyObject * +pygobject_connect_object(PyGObject *self, PyObject *args) +{ + PyObject *first, *callback, *extra_args, *object, *ret; + gchar *name; + Py_ssize_t len; + + len = PyTuple_Size(args); + if (len < 3) { + PyErr_SetString(PyExc_TypeError, + "GObject.connect_object requires at least 3 arguments"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 3); + if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object", + &name, &callback, &object)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "second argument must be callable"); + return NULL; + } + + CHECK_GOBJECT(self); + + extra_args = PySequence_GetSlice(args, 3, len); + if (extra_args == NULL) + return NULL; + + ret = connect_helper(self, name, callback, extra_args, object, FALSE); + Py_DECREF(extra_args); + return ret; +} + +static PyObject * +pygobject_connect_object_after(PyGObject *self, PyObject *args) +{ + PyObject *first, *callback, *extra_args, *object, *ret; + gchar *name; + Py_ssize_t len; + + len = PyTuple_Size(args); + if (len < 3) { + PyErr_SetString(PyExc_TypeError, + "GObject.connect_object_after requires at least 3 arguments"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 3); + if (!PyArg_ParseTuple(first, "sOO:GObject.connect_object_after", + &name, &callback, &object)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "second argument must be callable"); + return NULL; + } + + CHECK_GOBJECT(self); + + extra_args = PySequence_GetSlice(args, 3, len); + if (extra_args == NULL) + return NULL; + + ret = connect_helper(self, name, callback, extra_args, object, TRUE); + Py_DECREF(extra_args); + return ret; +} + +static PyObject * +pygobject_emit(PyGObject *self, PyObject *args) +{ + guint signal_id, i, j; + Py_ssize_t len; + GQuark detail; + PyObject *first, *py_ret, *repr = NULL; + gchar *name; + GSignalQuery query; + GValue *params, ret = { 0, }; + + len = PyTuple_Size(args); + if (len < 1) { + PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg"); + return NULL; + } + first = PySequence_GetSlice(args, 0, 1); + if (!PyArg_ParseTuple(first, "s:GObject.emit", &name)) { + Py_DECREF(first); + return NULL; + } + Py_DECREF(first); + + CHECK_GOBJECT(self); + + if (!g_signal_parse_name(name, G_OBJECT_TYPE(self->obj), + &signal_id, &detail, TRUE)) { + repr = PyObject_Repr((PyObject*)self); + PyErr_Format(PyExc_TypeError, "%s: unknown signal name: %s", + PYGLIB_PyUnicode_AsString(repr), + name); + Py_DECREF(repr); + return NULL; + } + g_signal_query(signal_id, &query); + if (len != query.n_params + 1) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "%d parameters needed for signal %s; %ld given", + query.n_params, name, (long int) (len - 1)); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + + params = g_new0(GValue, query.n_params + 1); + g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); + g_value_set_object(¶ms[0], G_OBJECT(self->obj)); + + for (i = 0; i < query.n_params; i++) + g_value_init(¶ms[i + 1], + query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); + for (i = 0; i < query.n_params; i++) { + PyObject *item = PyTuple_GetItem(args, i+1); + + if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { + gchar buf[128]; + g_snprintf(buf, sizeof(buf), + "could not convert type %s to %s required for parameter %d", + Py_TYPE(item)->tp_name, + G_VALUE_TYPE_NAME(¶ms[i+1]), i); + PyErr_SetString(PyExc_TypeError, buf); + + for (j = 0; j <= i; j++) + g_value_unset(¶ms[j]); + + g_free(params); + return NULL; + } + } + + if (query.return_type != G_TYPE_NONE) + g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + + g_signal_emitv(params, signal_id, detail, &ret); + + for (i = 0; i < query.n_params + 1; i++) + g_value_unset(¶ms[i]); + + g_free(params); + if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) { + py_ret = pyg_value_as_pyobject(&ret, TRUE); + g_value_unset(&ret); + } else { + Py_INCREF(Py_None); + py_ret = Py_None; + } + + return py_ret; +} + +static PyObject * +pygobject_chain_from_overridden(PyGObject *self, PyObject *args) +{ + GSignalInvocationHint *ihint; + guint signal_id, i; + Py_ssize_t len; + PyObject *py_ret; + const gchar *name; + GSignalQuery query; + GValue *params, ret = { 0, }; + + CHECK_GOBJECT(self); + + ihint = g_signal_get_invocation_hint(self->obj); + if (!ihint) { + PyErr_SetString(PyExc_TypeError, "could not find signal invocation " + "information for this object."); + return NULL; + } + + signal_id = ihint->signal_id; + name = g_signal_name(signal_id); + + len = PyTuple_Size(args); + if (signal_id == 0) { + PyErr_SetString(PyExc_TypeError, "unknown signal name"); + return NULL; + } + g_signal_query(signal_id, &query); + if (len != query.n_params) { + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), + "%d parameters needed for signal %s; %ld given", + query.n_params, name, (long int) len); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + params = g_new0(GValue, query.n_params + 1); + g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); + g_value_set_object(¶ms[0], G_OBJECT(self->obj)); + + for (i = 0; i < query.n_params; i++) + g_value_init(¶ms[i + 1], + query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); + for (i = 0; i < query.n_params; i++) { + PyObject *item = PyTuple_GetItem(args, i); + + if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) { + g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void)); + } + else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { + gchar buf[128]; + + 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(¶ms[i+1])), i); + PyErr_SetString(PyExc_TypeError, buf); + for (i = 0; i < query.n_params + 1; i++) + g_value_unset(¶ms[i]); + g_free(params); + return NULL; + } + } + if (query.return_type != G_TYPE_NONE) + g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_chain_from_overridden(params, &ret); + for (i = 0; i < query.n_params + 1; i++) + g_value_unset(¶ms[i]); + g_free(params); + if (query.return_type != G_TYPE_NONE) { + py_ret = pyg_value_as_pyobject(&ret, TRUE); + g_value_unset(&ret); + } else { + Py_INCREF(Py_None); + py_ret = Py_None; + } + return py_ret; +} + + +static PyObject * +pygobject_weak_ref(PyGObject *self, PyObject *args) +{ + int len; + PyObject *callback = NULL, *user_data = NULL; + PyObject *retval; + + CHECK_GOBJECT(self); + + if ((len = PySequence_Length(args)) >= 1) { + callback = PySequence_ITEM(args, 0); + user_data = PySequence_GetSlice(args, 1, len); + } + retval = pygobject_weak_ref_new(self->obj, callback, user_data); + Py_XDECREF(callback); + Py_XDECREF(user_data); + return retval; +} + + +static PyObject * +pygobject_copy(PyGObject *self) +{ + PyErr_SetString(PyExc_TypeError, + "GObject descendants' instances are non-copyable"); + return NULL; +} + +static PyObject * +pygobject_deepcopy(PyGObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "GObject descendants' instances are non-copyable"); + return NULL; +} + + +static PyObject * +pygobject_disconnect_by_func(PyGObject *self, PyObject *args) +{ + PyObject *pyfunc = NULL, *repr = NULL; + GClosure *closure = NULL; + guint retval; + + CHECK_GOBJECT(self); + + if (!PyArg_ParseTuple(args, "O:GObject.disconnect_by_func", &pyfunc)) + return NULL; + + if (!PyCallable_Check(pyfunc)) { + PyErr_SetString(PyExc_TypeError, "first argument must be callable"); + return NULL; + } + + closure = gclosure_from_pyfunc(self, pyfunc); + if (!closure) { + repr = PyObject_Repr((PyObject*)pyfunc); + PyErr_Format(PyExc_TypeError, "nothing connected to %s", + PYGLIB_PyUnicode_AsString(repr)); + Py_DECREF(repr); + return NULL; + } + + retval = g_signal_handlers_disconnect_matched(self->obj, + G_SIGNAL_MATCH_CLOSURE, + 0, 0, + closure, + NULL, NULL); + return PYGLIB_PyLong_FromLong(retval); +} + +static PyObject * +pygobject_handler_block_by_func(PyGObject *self, PyObject *args) +{ + PyObject *pyfunc = NULL, *repr = NULL; + GClosure *closure = NULL; + guint retval; + + CHECK_GOBJECT(self); + + if (!PyArg_ParseTuple(args, "O:GObject.handler_block_by_func", &pyfunc)) + return NULL; + + if (!PyCallable_Check(pyfunc)) { + PyErr_SetString(PyExc_TypeError, "first argument must be callable"); + return NULL; + } + + closure = gclosure_from_pyfunc(self, pyfunc); + if (!closure) { + repr = PyObject_Repr((PyObject*)pyfunc); + PyErr_Format(PyExc_TypeError, "nothing connected to %s", + PYGLIB_PyUnicode_AsString(repr)); + Py_DECREF(repr); + return NULL; + } + + retval = g_signal_handlers_block_matched(self->obj, + G_SIGNAL_MATCH_CLOSURE, + 0, 0, + closure, + NULL, NULL); + return PYGLIB_PyLong_FromLong(retval); +} + +static PyObject * +pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args) +{ + PyObject *pyfunc = NULL, *repr = NULL; + GClosure *closure = NULL; + guint retval; + + CHECK_GOBJECT(self); + + if (!PyArg_ParseTuple(args, "O:GObject.handler_unblock_by_func", &pyfunc)) + return NULL; + + if (!PyCallable_Check(pyfunc)) { + PyErr_SetString(PyExc_TypeError, "first argument must be callable"); + return NULL; + } + + closure = gclosure_from_pyfunc(self, pyfunc); + if (!closure) { + repr = PyObject_Repr((PyObject*)pyfunc); + PyErr_Format(PyExc_TypeError, "nothing connected to %s", + PYGLIB_PyUnicode_AsString(repr)); + Py_DECREF(repr); + return NULL; + } + + retval = g_signal_handlers_unblock_matched(self->obj, + G_SIGNAL_MATCH_CLOSURE, + 0, 0, + closure, + NULL, NULL); + return PYGLIB_PyLong_FromLong(retval); +} + + +static PyMethodDef pygobject_methods[] = { + { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS }, + { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS }, + { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS }, + { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS }, + { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS }, + { "connect", (PyCFunction)pygobject_connect, METH_VARARGS }, + { "connect_after", (PyCFunction)pygobject_connect_after, METH_VARARGS }, + { "connect_object", (PyCFunction)pygobject_connect_object, METH_VARARGS }, + { "connect_object_after", (PyCFunction)pygobject_connect_object_after, METH_VARARGS }, + { "disconnect_by_func", (PyCFunction)pygobject_disconnect_by_func, METH_VARARGS }, + { "handler_block_by_func", (PyCFunction)pygobject_handler_block_by_func, METH_VARARGS }, + { "handler_unblock_by_func", (PyCFunction)pygobject_handler_unblock_by_func, METH_VARARGS }, + { "emit", (PyCFunction)pygobject_emit, METH_VARARGS }, + { "chain", (PyCFunction)pygobject_chain_from_overridden,METH_VARARGS }, + { "weak_ref", (PyCFunction)pygobject_weak_ref, METH_VARARGS }, + { "__copy__", (PyCFunction)pygobject_copy, METH_NOARGS }, + { "__deepcopy__", (PyCFunction)pygobject_deepcopy, METH_VARARGS }, + { NULL, NULL, 0 } +}; + + +static PyObject * +pygobject_get_dict(PyGObject *self, void *closure) +{ + if (self->inst_dict == NULL) { + self->inst_dict = PyDict_New(); + if (self->inst_dict == NULL) + return NULL; + if (G_LIKELY(self->obj)) + pygobject_switch_to_toggle_ref(self); + } + Py_INCREF(self->inst_dict); + return self->inst_dict; +} + +static PyObject * +pygobject_get_refcount(PyGObject *self, void *closure) +{ + if (self->obj == NULL) { + PyErr_Format(PyExc_TypeError, "GObject instance is not yet created"); + return NULL; + } + return PYGLIB_PyLong_FromLong(self->obj->ref_count); +} + +static PyObject * +pygobject_get_pointer(PyGObject *self, void *closure) +{ + return PYGLIB_CPointer_WrapPointer (self->obj, NULL); +} + +static int +pygobject_setattro(PyObject *self, PyObject *name, PyObject *value) +{ + int res; + PyGObject *gself = (PyGObject *) self; + PyObject *inst_dict_before = gself->inst_dict; + /* call parent type's setattro */ + res = PyGObject_Type.tp_base->tp_setattro(self, name, value); + if (inst_dict_before == NULL && gself->inst_dict != NULL) { + if (G_LIKELY(gself->obj)) + pygobject_switch_to_toggle_ref(gself); + } + return res; +} + +static PyGetSetDef pygobject_getsets[] = { + { "__dict__", (getter)pygobject_get_dict, (setter)0 }, + { "__grefcount__", (getter)pygobject_get_refcount, (setter)0, }, + { "__gpointer__", (getter)pygobject_get_pointer, (setter)0, }, + { NULL, 0, 0 } +}; + +/* ------------------------------------ */ +/* ****** GObject weak reference ****** */ +/* ------------------------------------ */ + +typedef struct { + PyObject_HEAD + GObject *obj; + PyObject *callback; + PyObject *user_data; + gboolean have_floating_ref; +} PyGObjectWeakRef; + +PYGLIB_DEFINE_TYPE("gi._gobject.GObjectWeakRef", PyGObjectWeakRef_Type, PyGObjectWeakRef); + +static int +pygobject_weak_ref_traverse(PyGObjectWeakRef *self, visitproc visit, void *arg) +{ + if (self->callback && visit(self->callback, arg) < 0) + return -1; + if (self->user_data && visit(self->user_data, arg) < 0) + return -1; + return 0; +} + +static void +pygobject_weak_ref_notify(PyGObjectWeakRef *self, GObject *dummy) +{ + self->obj = NULL; + if (self->callback) { + PyObject *retval; + PyGILState_STATE state = pyglib_gil_state_ensure(); + retval = PyObject_Call(self->callback, self->user_data, NULL); + if (retval) { + if (retval != Py_None) + PyErr_Format(PyExc_TypeError, + "GObject weak notify callback returned a value" + " of type %s, should return None", + Py_TYPE(retval)->tp_name); + Py_DECREF(retval); + PyErr_Print(); + } else + PyErr_Print(); + Py_CLEAR(self->callback); + Py_CLEAR(self->user_data); + if (self->have_floating_ref) { + self->have_floating_ref = FALSE; + Py_DECREF((PyObject *) self); + } + pyglib_gil_state_release(state); + } +} + +static inline int +pygobject_weak_ref_clear(PyGObjectWeakRef *self) +{ + Py_CLEAR(self->callback); + Py_CLEAR(self->user_data); + if (self->obj) { + g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); + self->obj = NULL; + } + return 0; +} + +static void +pygobject_weak_ref_dealloc(PyGObjectWeakRef *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + pygobject_weak_ref_clear(self); + PyObject_GC_Del(self); +} + +static PyObject * +pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data) +{ + PyGObjectWeakRef *self; + + self = PyObject_GC_New(PyGObjectWeakRef, &PyGObjectWeakRef_Type); + self->callback = callback; + self->user_data = user_data; + Py_XINCREF(self->callback); + Py_XINCREF(self->user_data); + self->obj = obj; + g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); + if (callback != NULL) { + /* when we have a callback, we should INCREF the weakref + * object to make it stay alive even if it goes out of scope */ + self->have_floating_ref = TRUE; + Py_INCREF((PyObject *) self); + } + return (PyObject *) self; +} + +static PyObject * +pygobject_weak_ref_unref(PyGObjectWeakRef *self, PyObject *args) +{ + if (!self->obj) { + PyErr_SetString(PyExc_ValueError, "weak ref already unreffed"); + return NULL; + } + g_object_weak_unref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self); + self->obj = NULL; + if (self->have_floating_ref) { + self->have_floating_ref = FALSE; + Py_DECREF(self); + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef pygobject_weak_ref_methods[] = { + { "unref", (PyCFunction)pygobject_weak_ref_unref, METH_NOARGS}, + { NULL, NULL, 0} +}; + +static PyObject * +pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw) +{ + static char *argnames[] = {NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames)) + return NULL; + + if (self->obj) + return pygobject_new(self->obj); + else { + Py_INCREF(Py_None); + return Py_None; + } +} + +static gpointer +pyobject_copy(gpointer boxed) +{ + PyObject *object = boxed; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_INCREF(object); + pyglib_gil_state_release(state); + return object; +} + +static void +pyobject_free(gpointer boxed) +{ + PyObject *object = boxed; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_DECREF(object); + pyglib_gil_state_release(state); +} + +void +pygobject_object_register_types(PyObject *d) +{ + PyObject *o, *descr; + + pygobject_custom_key = g_quark_from_static_string("PyGObject::custom"); + pygobject_class_key = g_quark_from_static_string("PyGObject::class"); + pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init"); + pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper"); + pygobject_has_updated_constructor_key = + g_quark_from_static_string("PyGObject::has-updated-constructor"); + pygobject_instance_data_key = g_quark_from_static_string("PyGObject::instance-data"); + + /* GObject */ + if (!PY_TYPE_OBJECT) + PY_TYPE_OBJECT = g_boxed_type_register_static("PyObject", + pyobject_copy, + pyobject_free); + PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc; + PyGObject_Type.tp_richcompare = pygobject_richcompare; + PyGObject_Type.tp_repr = (reprfunc)pygobject_repr; + PyGObject_Type.tp_hash = (hashfunc)pygobject_hash; + PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro; + PyGObject_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC); + PyGObject_Type.tp_traverse = (traverseproc)pygobject_traverse; + PyGObject_Type.tp_clear = (inquiry)pygobject_clear; + PyGObject_Type.tp_weaklistoffset = offsetof(PyGObject, weakreflist); + PyGObject_Type.tp_methods = pygobject_methods; + PyGObject_Type.tp_getset = pygobject_getsets; + PyGObject_Type.tp_dictoffset = offsetof(PyGObject, inst_dict); + PyGObject_Type.tp_init = (initproc)pygobject_init; + PyGObject_Type.tp_free = (freefunc)pygobject_free; + PyGObject_Type.tp_alloc = PyType_GenericAlloc; + PyGObject_Type.tp_new = PyType_GenericNew; + pygobject_register_class(d, "GObject", G_TYPE_OBJECT, + &PyGObject_Type, NULL); + PyDict_SetItemString(PyGObject_Type.tp_dict, "__gdoc__", + pyg_object_descr_doc_get()); + + /* GProps */ + PyGProps_Type.tp_dealloc = (destructor)PyGProps_dealloc; + PyGProps_Type.tp_as_sequence = (PySequenceMethods*)&_PyGProps_as_sequence; + PyGProps_Type.tp_getattro = (getattrofunc)PyGProps_getattro; + PyGProps_Type.tp_setattro = (setattrofunc)PyGProps_setattro; + PyGProps_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; + PyGProps_Type.tp_doc = "The properties of the GObject accessible as " + "Python attributes."; + PyGProps_Type.tp_traverse = (traverseproc)pygobject_props_traverse; + PyGProps_Type.tp_iter = (getiterfunc)pygobject_props_get_iter; + PyGProps_Type.tp_methods = pygobject_props_methods; + if (PyType_Ready(&PyGProps_Type) < 0) + return; + + /* GPropsDescr */ + PyGPropsDescr_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGPropsDescr_Type.tp_descr_get = pyg_props_descr_descr_get; + if (PyType_Ready(&PyGPropsDescr_Type) < 0) + return; + descr = PyObject_New(PyObject, &PyGPropsDescr_Type); + PyDict_SetItemString(PyGObject_Type.tp_dict, "props", descr); + PyDict_SetItemString(PyGObject_Type.tp_dict, "__module__", + o=PYGLIB_PyUnicode_FromString("gi._gobject._gobject")); + Py_DECREF(o); + + /* GPropsIter */ + PyGPropsIter_Type.tp_dealloc = (destructor)pyg_props_iter_dealloc; + PyGPropsIter_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGPropsIter_Type.tp_doc = "GObject properties iterator"; + PyGPropsIter_Type.tp_iternext = (iternextfunc)pygobject_props_iter_next; + if (PyType_Ready(&PyGPropsIter_Type) < 0) + return; + + PyGObjectWeakRef_Type.tp_dealloc = (destructor)pygobject_weak_ref_dealloc; + PyGObjectWeakRef_Type.tp_call = (ternaryfunc)pygobject_weak_ref_call; + PyGObjectWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; + PyGObjectWeakRef_Type.tp_doc = "A GObject weak reference"; + PyGObjectWeakRef_Type.tp_traverse = (traverseproc)pygobject_weak_ref_traverse; + PyGObjectWeakRef_Type.tp_clear = (inquiry)pygobject_weak_ref_clear; + PyGObjectWeakRef_Type.tp_methods = pygobject_weak_ref_methods; + if (PyType_Ready(&PyGObjectWeakRef_Type) < 0) + return; + PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type); +} diff --git a/gi/pygobject.h b/gi/pygobject.h new file mode 100644 index 0000000..76b8b11 --- /dev/null +++ b/gi/pygobject.h @@ -0,0 +1,636 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- */ +#ifndef _PYGOBJECT_H_ +#define _PYGOBJECT_H_ + +#include + +#include +#include + +G_BEGIN_DECLS + +/* PyGClosure is a _private_ structure */ +typedef void (* PyClosureExceptionHandler) (GValue *ret, guint n_param_values, const GValue *params); +typedef struct _PyGClosure PyGClosure; +typedef struct _PyGObjectData PyGObjectData; + +struct _PyGClosure { + GClosure closure; + PyObject *callback; + PyObject *extra_args; /* tuple of extra args to pass to callback */ + PyObject *swap_data; /* other object for gtk_signal_connect__object */ + PyClosureExceptionHandler exception_handler; +}; + +typedef enum { + PYGOBJECT_USING_TOGGLE_REF = 1 << 0, + PYGOBJECT_IS_FLOATING_REF = 1 << 1, + PYGOBJECT_GOBJECT_WAS_FLOATING = 1 << 2, +} PyGObjectFlags; + + /* closures is just an alias for what is found in the + * PyGObjectData */ +typedef struct { + PyObject_HEAD + GObject *obj; + PyObject *inst_dict; /* the instance dictionary -- must be last */ + PyObject *weakreflist; /* list of weak references */ + + /*< private >*/ + /* using union to preserve ABI compatibility (structure size + * must not change) */ + union { + GSList *closures; /* stale field; no longer updated DO-NOT-USE! */ + PyGObjectFlags flags; + } private_flags; + +} PyGObject; + +#define pygobject_get(v) (((PyGObject *)(v))->obj) +#define pygobject_check(v,base) (PyObject_TypeCheck(v,base)) + +typedef struct { + PyObject_HEAD + gpointer boxed; + GType gtype; + gboolean free_on_dealloc; +} PyGBoxed; + +#define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed) +#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode) + +typedef struct { + PyObject_HEAD + gpointer pointer; + GType gtype; +} PyGPointer; + +#define pyg_pointer_get(v,t) ((t *)((PyGPointer *)(v))->pointer) +#define pyg_pointer_check(v,typecode) (PyObject_TypeCheck(v, &PyGPointer_Type) && ((PyGPointer *)(v))->gtype == typecode) + +typedef void (*PyGFatalExceptionFunc) (void); +typedef void (*PyGThreadBlockFunc) (void); + +typedef struct { + PyObject_HEAD + GParamSpec *pspec; +} PyGParamSpec; + +#define PyGParamSpec_Get(v) (((PyGParamSpec *)v)->pspec) +#define PyGParamSpec_Check(v) (PyObject_TypeCheck(v, &PyGParamSpec_Type)) + +typedef int (*PyGClassInitFunc) (gpointer gclass, PyTypeObject *pyclass); +typedef PyTypeObject * (*PyGTypeRegistrationFunction) (const gchar *name, + gpointer data); + +struct _PyGObject_Functions { + /* + * All field names in here are considered private, + * use the macros below instead, which provides stability + */ + void (* register_class)(PyObject *dict, const gchar *class_name, + GType gtype, PyTypeObject *type, PyObject *bases); + void (* register_wrapper)(PyObject *self); + PyTypeObject *(* lookup_class)(GType type); + PyObject *(* newgobj)(GObject *obj); + + GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args, + PyObject *swap_data); + void (* object_watch_closure)(PyObject *self, GClosure *closure); + GDestroyNotify destroy_notify; + + GType (* type_from_object)(PyObject *obj); + PyObject *(* type_wrapper_new)(GType type); + + gint (* enum_get_value)(GType enum_type, PyObject *obj, gint *val); + gint (* flags_get_value)(GType flag_type, PyObject *obj, guint *val); + void (* register_gtype_custom)(GType gtype, + PyObject *(* from_func)(const GValue *value), + int (* to_func)(GValue *value, PyObject *obj)); + int (* value_from_pyobject)(GValue *value, PyObject *obj); + PyObject *(* value_as_pyobject)(const GValue *value, gboolean copy_boxed); + + void (* register_interface)(PyObject *dict, const gchar *class_name, + GType gtype, PyTypeObject *type); + + PyTypeObject *boxed_type; + void (* register_boxed)(PyObject *dict, const gchar *class_name, + GType boxed_type, PyTypeObject *type); + PyObject *(* boxed_new)(GType boxed_type, gpointer boxed, + gboolean copy_boxed, gboolean own_ref); + + PyTypeObject *pointer_type; + void (* register_pointer)(PyObject *dict, const gchar *class_name, + GType pointer_type, PyTypeObject *type); + PyObject *(* pointer_new)(GType boxed_type, gpointer pointer); + + void (* enum_add_constants)(PyObject *module, GType enum_type, + const gchar *strip_prefix); + void (* flags_add_constants)(PyObject *module, GType flags_type, + const gchar *strip_prefix); + + const gchar *(* constant_strip_prefix)(const gchar *name, + const gchar *strip_prefix); + + gboolean (* error_check)(GError **error); + + /* hooks to register handlers for getting GDK threads to cooperate + * with python threading */ + void (* set_thread_block_funcs) (PyGThreadBlockFunc block_threads_func, + PyGThreadBlockFunc unblock_threads_func); + PyGThreadBlockFunc block_threads; + PyGThreadBlockFunc unblock_threads; + + PyTypeObject *paramspec_type; + PyObject *(* paramspec_new)(GParamSpec *spec); + GParamSpec *(*paramspec_get)(PyObject *tuple); + int (*pyobj_to_unichar_conv)(PyObject *pyobj, void* ptr); + gboolean (*parse_constructor_args)(GType obj_type, + char **arg_names, + char **prop_names, + GParameter *params, + guint *nparams, + PyObject **py_args); + PyObject *(* param_gvalue_as_pyobject) (const GValue* gvalue, + gboolean copy_boxed, + const GParamSpec* pspec); + int (* gvalue_from_param_pyobject) (GValue* value, + PyObject* py_obj, + const GParamSpec* pspec); + PyTypeObject *enum_type; + PyObject *(*enum_add)(PyObject *module, + const char *type_name_, + const char *strip_prefix, + GType gtype); + PyObject* (*enum_from_gtype)(GType gtype, int value); + + PyTypeObject *flags_type; + PyObject *(*flags_add)(PyObject *module, + const char *type_name_, + const char *strip_prefix, + GType gtype); + PyObject* (*flags_from_gtype)(GType gtype, guint value); + + gboolean threads_enabled; + int (*enable_threads) (void); + + int (*gil_state_ensure) (void); + void (*gil_state_release) (int flag); + + void (*register_class_init) (GType gtype, PyGClassInitFunc class_init); + void (*register_interface_info) (GType gtype, const GInterfaceInfo *info); + void (*closure_set_exception_handler) (GClosure *closure, PyClosureExceptionHandler handler); + + void (*add_warning_redirection) (const char *domain, + PyObject *warning); + void (*disable_warning_redirections) (void); + + /* type_register_custom API now removed, but leave a pointer here to not + * break ABI. */ + void *_type_register_custom; + + gboolean (*gerror_exception_check) (GError **error); + PyObject* (*option_group_new) (GOptionGroup *group); + GType (* type_from_object_strict) (PyObject *obj, gboolean strict); + + PyObject *(* newgobj_full)(GObject *obj, gboolean steal, gpointer g_class); + PyTypeObject *object_type; + int (* value_from_pyobject_with_error)(GValue *value, PyObject *obj); +}; + + +#ifdef DISABLE_THREADING +# define pyg_threads_enabled FALSE +# define pyg_gil_state_ensure() 0 +# define pyg_gil_state_release(state) +# define pyg_begin_allow_threads G_STMT_START { +# define pyg_end_allow_threads } G_STMT_END +#else +# define pyg_threads_enabled TRUE +# define pyg_gil_state_ensure PyGILState_Ensure +# define pyg_gil_state_release PyGILState_Release +# define pyg_begin_allow_threads Py_BEGIN_ALLOW_THREADS +# define pyg_end_allow_threads Py_END_ALLOW_THREADS +#endif + +/* Deprecated, only available for API compatibility. */ +#define pyg_enable_threads() +#define pyg_set_thread_block_funcs(a, b) +#define pyg_block_threads() +#define pyg_unblock_threads() + + +#ifndef _INSIDE_PYGOBJECT_ + +#if defined(NO_IMPORT) || defined(NO_IMPORT_PYGOBJECT) +extern struct _PyGObject_Functions *_PyGObject_API; +#else +struct _PyGObject_Functions *_PyGObject_API; +#endif + +#define pygobject_register_class (_PyGObject_API->register_class) +#define pygobject_register_wrapper (_PyGObject_API->register_wrapper) +#define pygobject_lookup_class (_PyGObject_API->lookup_class) +#define pygobject_new (_PyGObject_API->newgobj) +#define pygobject_new_full (_PyGObject_API->newgobj_full) +#define PyGObject_Type (*_PyGObject_API->object_type) +#define pyg_closure_new (_PyGObject_API->closure_new) +#define pygobject_watch_closure (_PyGObject_API->object_watch_closure) +#define pyg_closure_set_exception_handler (_PyGObject_API->closure_set_exception_handler) +#define pyg_destroy_notify (_PyGObject_API->destroy_notify) +#define pyg_type_from_object_strict (_PyGObject_API->type_from_object_strict) +#define pyg_type_from_object (_PyGObject_API->type_from_object) +#define pyg_type_wrapper_new (_PyGObject_API->type_wrapper_new) +#define pyg_enum_get_value (_PyGObject_API->enum_get_value) +#define pyg_flags_get_value (_PyGObject_API->flags_get_value) +#define pyg_register_gtype_custom (_PyGObject_API->register_gtype_custom) +#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject) +#define pyg_value_from_pyobject_with_error (_PyGObject_API->value_from_pyobject_with_error) +#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject) +#define pyg_register_interface (_PyGObject_API->register_interface) +#define PyGBoxed_Type (*_PyGObject_API->boxed_type) +#define pyg_register_boxed (_PyGObject_API->register_boxed) +#define pyg_boxed_new (_PyGObject_API->boxed_new) +#define PyGPointer_Type (*_PyGObject_API->pointer_type) +#define pyg_register_pointer (_PyGObject_API->register_pointer) +#define pyg_pointer_new (_PyGObject_API->pointer_new) +#define pyg_enum_add_constants (_PyGObject_API->enum_add_constants) +#define pyg_flags_add_constants (_PyGObject_API->flags_add_constants) +#define pyg_constant_strip_prefix (_PyGObject_API->constant_strip_prefix) +#define pyg_error_check (_PyGObject_API->error_check) +#define PyGParamSpec_Type (*_PyGObject_API->paramspec_type) +#define pyg_param_spec_new (_PyGObject_API->paramspec_new) +#define pyg_param_spec_from_object (_PyGObject_API->paramspec_get) +#define pyg_pyobj_to_unichar_conv (_PyGObject_API->pyobj_to_unichar_conv) +#define pyg_parse_constructor_args (_PyGObject_API->parse_constructor_args) +#define pyg_param_gvalue_as_pyobject (_PyGObject_API->value_as_pyobject) +#define pyg_param_gvalue_from_pyobject (_PyGObject_API->gvalue_from_param_pyobject) +#define PyGEnum_Type (*_PyGObject_API->enum_type) +#define pyg_enum_add (_PyGObject_API->enum_add) +#define pyg_enum_from_gtype (_PyGObject_API->enum_from_gtype) +#define PyGFlags_Type (*_PyGObject_API->flags_type) +#define pyg_flags_add (_PyGObject_API->flags_add) +#define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype) +#define pyg_register_class_init (_PyGObject_API->register_class_init) +#define pyg_register_interface_info (_PyGObject_API->register_interface_info) +#define pyg_add_warning_redirection (_PyGObject_API->add_warning_redirection) +#define pyg_disable_warning_redirections (_PyGObject_API->disable_warning_redirections) +#define pyg_gerror_exception_check (_PyGObject_API->gerror_exception_check) +#define pyg_option_group_new (_PyGObject_API->option_group_new) + + +/** + * pygobject_init: + * @req_major: minimum version major number, or -1 + * @req_minor: minimum version minor number, or -1 + * @req_micro: minimum version micro number, or -1 + * + * Imports and initializes the 'gobject' python module. Can + * optionally check for a required minimum version if @req_major, + * @req_minor, and @req_micro are all different from -1. + * + * Returns: a new reference to the gobject module on success, NULL in + * case of failure (and raises ImportError). + **/ +static inline PyObject * +pygobject_init(int req_major, int req_minor, int req_micro) +{ + PyObject *gobject, *cobject; + + gobject = PyImport_ImportModule("gi._gobject"); + if (!gobject) { + if (PyErr_Occurred()) + { + PyObject *type, *value, *traceback; + PyObject *py_orig_exc; + PyErr_Fetch(&type, &value, &traceback); + py_orig_exc = PyObject_Repr(value); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + + +#if PY_VERSION_HEX < 0x03000000 + PyErr_Format(PyExc_ImportError, + "could not import gobject (error was: %s)", + PyString_AsString(py_orig_exc)); +#else + { + /* Can not use PyErr_Format because it doesn't have + * a format string for dealing with PyUnicode objects + * like PyUnicode_FromFormat has + */ + PyObject *errmsg = PyUnicode_FromFormat("could not import gobject (error was: %U)", + py_orig_exc); + + if (errmsg) { + PyErr_SetObject(PyExc_ImportError, + errmsg); + Py_DECREF(errmsg); + } + /* if errmsg is NULL then we might have OOM + * PyErr should already be set and trying to + * return our own error would be futile + */ + } +#endif + Py_DECREF(py_orig_exc); + } else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (no error given)"); + } + return NULL; + } + + cobject = PyObject_GetAttrString(gobject, "_PyGObject_API"); + if (cobject && PyCapsule_CheckExact(cobject)) + _PyGObject_API = (struct _PyGObject_Functions *) PyCapsule_GetPointer(cobject, "gobject._PyGObject_API"); + else { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (could not find _PyGObject_API object)"); + Py_DECREF(gobject); + return NULL; + } + + if (req_major != -1) + { + int found_major, found_minor, found_micro; + PyObject *version; + + version = PyObject_GetAttrString(gobject, "pygobject_version"); + if (!version) { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (version too old)"); + Py_DECREF(gobject); + return NULL; + } + if (!PyArg_ParseTuple(version, "iii", + &found_major, &found_minor, &found_micro)) { + PyErr_SetString(PyExc_ImportError, + "could not import gobject (version has invalid format)"); + Py_DECREF(version); + Py_DECREF(gobject); + return NULL; + } + Py_DECREF(version); + if (req_major != found_major || + req_minor > found_minor || + (req_minor == found_minor && req_micro > found_micro)) { + PyErr_Format(PyExc_ImportError, + "could not import gobject (version mismatch, %d.%d.%d is required, " + "found %d.%d.%d)", req_major, req_minor, req_micro, + found_major, found_minor, found_micro); + Py_DECREF(gobject); + return NULL; + } + } + return gobject; +} + +/** + * PYLIST_FROMGLIBLIST: + * @type: the type of the GLib list e.g. #GList or #GSList + * @prefix: the prefix of functions that manipulate a list of the type + * given by type. + * + * A macro that creates a type specific code block which converts a GLib + * list (#GSList or #GList) to a Python list. The first two args of the macro + * are used to specify the type and list function prefix so that the type + * specific macros can be generated. + * + * The rest of the args are for the standard args for the type specific + * macro(s) created from this macro. + */ + #define PYLIST_FROMGLIBLIST(type,prefix,py_list,list,item_convert_func,\ + list_free,list_item_free) \ +G_STMT_START \ +{ \ + gint i, len; \ + PyObject *item; \ + void (*glib_list_free)(type*) = list_free; \ + GFunc glib_list_item_free = (GFunc)list_item_free; \ + \ + len = prefix##_length(list); \ + py_list = PyList_New(len); \ + for (i = 0; i < len; i++) { \ + gpointer list_item = prefix##_nth_data(list, i); \ + \ + item = item_convert_func; \ + PyList_SetItem(py_list, i, item); \ + } \ + if (glib_list_item_free != NULL) \ + prefix##_foreach(list, glib_list_item_free, NULL); \ + if (glib_list_free != NULL) \ + glib_list_free(list); \ +} G_STMT_END + +/** + * PYLIST_FROMGLIST: + * @py_list: the name of the Python list + * + * @list: the #GList to be converted to a Python list + * + * @item_convert_func: the function that converts a list item to a Python + * object. The function must refer to the list item using "@list_item" and + * must return a #PyObject* object. An example conversion function is: + * [[ + * PyString_FromString(list_item) + * ]] + * A more elaborate function is: + * [[ + * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE) + * ]] + * @list_free: the name of a function that takes a single arg (the list) and + * frees its memory. Can be NULL if the list should not be freed. An example + * is: + * [[ + * g_list_free + * ]] + * @list_item_free: the name of a #GFunc function that frees the memory used + * by the items in the list or %NULL if the list items do not have to be + * freed. A simple example is: + * [[ + * g_free + * ]] + * + * A macro that adds code that converts a #GList to a Python list. + * + */ +#define PYLIST_FROMGLIST(py_list,list,item_convert_func,list_free,\ + list_item_free) \ + PYLIST_FROMGLIBLIST(GList,g_list,py_list,list,item_convert_func,\ + list_free,list_item_free) + +/** + * PYLIST_FROMGSLIST: + * @py_list: the name of the Python list + * + * @list: the #GSList to be converted to a Python list + * + * @item_convert_func: the function that converts a list item to a Python + * object. The function must refer to the list item using "@list_item" and + * must return a #PyObject* object. An example conversion function is: + * [[ + * PyString_FromString(list_item) + * ]] + * A more elaborate function is: + * [[ + * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE) + * ]] + * @list_free: the name of a function that takes a single arg (the list) and + * frees its memory. Can be %NULL if the list should not be freed. An example + * is: + * [[ + * g_list_free + * ]] + * @list_item_free: the name of a #GFunc function that frees the memory used + * by the items in the list or %NULL if the list items do not have to be + * freed. A simple example is: + * [[ + * g_free + * ]] + * + * A macro that adds code that converts a #GSList to a Python list. + * + */ +#define PYLIST_FROMGSLIST(py_list,list,item_convert_func,list_free,\ + list_item_free) \ + PYLIST_FROMGLIBLIST(GSList,g_slist,py_list,list,item_convert_func,\ + list_free,list_item_free) + +/** + * PYLIST_ASGLIBLIST + * @type: the type of the GLib list e.g. GList or GSList + * @prefix: the prefix of functions that manipulate a list of the type + * given by type e.g. g_list or g_slist + * + * A macro that creates a type specific code block to be used to convert a + * Python list to a GLib list (GList or GSList). The first two args of the + * macro are used to specify the type and list function prefix so that the + * type specific macros can be generated. + * + * The rest of the args are for the standard args for the type specific + * macro(s) created from this macro. + */ +#define PYLIST_ASGLIBLIST(type,prefix,py_list,list,check_func,\ + convert_func,child_free_func,errormsg,errorreturn) \ +G_STMT_START \ +{ \ + Py_ssize_t i, n_list; \ + GFunc glib_child_free_func = (GFunc)child_free_func; \ + \ + if (!(py_list = PySequence_Fast(py_list, ""))) { \ + errormsg; \ + return errorreturn; \ + } \ + n_list = PySequence_Fast_GET_SIZE(py_list); \ + for (i = 0; i < n_list; i++) { \ + PyObject *py_item = PySequence_Fast_GET_ITEM(py_list, i); \ + \ + if (!check_func) { \ + if (glib_child_free_func) \ + prefix##_foreach(list, glib_child_free_func, NULL); \ + prefix##_free(list); \ + Py_DECREF(py_list); \ + errormsg; \ + return errorreturn; \ + } \ + list = prefix##_prepend(list, convert_func); \ + }; \ + Py_DECREF(py_list); \ + list = prefix##_reverse(list); \ +} \ +G_STMT_END +/** + * PYLIST_ASGLIST + * @py_list: the Python list to be converted + * @list: the #GList list to be converted + * @check_func: the expression that takes a #PyObject* arg (must be named + * @py_item) and returns an int value indicating if the Python object matches + * the required list item type (0 - %False or 1 - %True). An example is: + * [[ + * (PyString_Check(py_item)||PyUnicode_Check(py_item)) + * ]] + * @convert_func: the function that takes a #PyObject* arg (must be named + * py_item) and returns a pointer to the converted list object. An example + * is: + * [[ + * pygobject_get(py_item) + * ]] + * @child_free_func: the name of a #GFunc function that frees a GLib list + * item or %NULL if the list item does not have to be freed. This function is + * used to help free the items in a partially created list if there is an + * error. An example is: + * [[ + * g_free + * ]] + * @errormsg: a function that sets up a Python error message. An example is: + * [[ + * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings + * or unicode objects") + * ]] + * @errorreturn: the value to return if an error occurs, e.g.: + * [[ + * %NULL + * ]] + * + * A macro that creates code that converts a Python list to a #GList. The + * returned list must be freed using the appropriate list free function when + * it's no longer needed. If an error occurs the child_free_func is used to + * release the memory used by the list items and then the list memory is + * freed. + */ +#define PYLIST_ASGLIST(py_list,list,check_func,convert_func,child_free_func,\ + errormsg,errorreturn) \ + PYLIST_ASGLIBLIST(GList,g_list,py_list,list,check_func,convert_func,\ + child_free_func,errormsg,errorreturn) + +/** + * PYLIST_ASGSLIST + * @py_list: the Python list to be converted + * @list: the #GSList list to be converted + * @check_func: the expression that takes a #PyObject* arg (must be named + * @py_item) and returns an int value indicating if the Python object matches + * the required list item type (0 - %False or 1 - %True). An example is: + * [[ + * (PyString_Check(py_item)||PyUnicode_Check(py_item)) + * ]] + * @convert_func: the function that takes a #PyObject* arg (must be named + * py_item) and returns a pointer to the converted list object. An example + * is: + * [[ + * pygobject_get(py_item) + * ]] + * @child_free_func: the name of a #GFunc function that frees a GLib list + * item or %NULL if the list item does not have to be freed. This function is + * used to help free the items in a partially created list if there is an + * error. An example is: + * [[ + * g_free + * ]] + * @errormsg: a function that sets up a Python error message. An example is: + * [[ + * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings + * or unicode objects") + * ]] + * @errorreturn: the value to return if an error occurs, e.g.: + * [[ + * %NULL + * ]] + * + * A macro that creates code that converts a Python list to a #GSList. The + * returned list must be freed using the appropriate list free function when + * it's no longer needed. If an error occurs the child_free_func is used to + * release the memory used by the list items and then the list memory is + * freed. + */ +#define PYLIST_ASGSLIST(py_list,list,check_func,convert_func,child_free_func,\ + errormsg,errorreturn) \ + PYLIST_ASGLIBLIST(GSList,g_slist,py_list,list,check_func,convert_func,\ + child_free_func,errormsg,errorreturn) + +#endif /* !_INSIDE_PYGOBJECT_ */ + +G_END_DECLS + +#endif /* !_PYGOBJECT_H_ */ diff --git a/gi/pygoptioncontext.c b/gi/pygoptioncontext.c new file mode 100644 index 0000000..8ecbff8 --- /dev/null +++ b/gi/pygoptioncontext.c @@ -0,0 +1,337 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 2006 Johannes Hoelzl + * + * pygoptioncontext.c: GOptionContext wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pyglib-private.h" +#include "pygoptioncontext.h" + +PYGLIB_DEFINE_TYPE("gi._glib.OptionContext", PyGOptionContext_Type, PyGOptionContext) + +/** + * pyg_option_context_new: + * @context: a GOptionContext + * + * Returns: A new GOptionContext wrapper. + */ +PyObject * +pyg_option_context_new (GOptionContext *context) +{ + PyGOptionContext *self; + + self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext, &PyGOptionContext_Type); + if (self == NULL) + return NULL; + + self->context = context; + self->main_group = NULL; + + return (PyObject *)self; +} + +static int +pyg_option_context_init(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + char *parameter_string; + + if (!PyArg_ParseTuple(args, "s:gi._glib.GOptionContext.__init__", + ¶meter_string)) + return -1; + + self->context = g_option_context_new(parameter_string); + return 0; +} + +static void +pyg_option_context_dealloc(PyGOptionContext *self) +{ + Py_CLEAR(self->main_group); + + if (self->context != NULL) + { + GOptionContext *tmp = self->context; + self->context = NULL; + g_option_context_free(tmp); + } + + PyObject_Del(self); +} + +static PyObject * +pyg_option_context_parse(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "argv", NULL }; + PyObject *arg; + PyObject *new_argv, *argv; + Py_ssize_t argv_length, pos; + gint argv_length_int; + char **argv_content, **original; + GError *error = NULL; + gboolean result; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.parse", + kwlist, &argv)) + return NULL; + + if (!PyList_Check(argv)) + { + PyErr_SetString(PyExc_TypeError, + "GOptionContext.parse expects a list of strings."); + return NULL; + } + + argv_length = PyList_Size(argv); + if (argv_length == -1) + { + PyErr_SetString(PyExc_TypeError, + "GOptionContext.parse expects a list of strings."); + return NULL; + } + + argv_content = g_new(char*, argv_length + 1); + argv_content[argv_length] = NULL; + for (pos = 0; pos < argv_length; pos++) + { + arg = PyList_GetItem(argv, pos); + argv_content[pos] = g_strdup(PYGLIB_PyUnicode_AsString(arg)); + if (argv_content[pos] == NULL) + { + g_strfreev(argv_content); + return NULL; + } + } + original = g_strdupv(argv_content); + + g_assert(argv_length <= G_MAXINT); + argv_length_int = argv_length; + Py_BEGIN_ALLOW_THREADS; + result = g_option_context_parse(self->context, &argv_length_int, &argv_content, + &error); + Py_END_ALLOW_THREADS; + argv_length = argv_length_int; + + if (!result) + { + g_strfreev(argv_content); + g_strfreev(original); + pyglib_error_check(&error); + return NULL; + } + + new_argv = PyList_New(g_strv_length(argv_content)); + for (pos = 0; pos < argv_length; pos++) + { + arg = PYGLIB_PyUnicode_FromString(argv_content[pos]); + PyList_SetItem(new_argv, pos, arg); + } + + g_strfreev(original); + g_strfreev(argv_content); + return new_argv; +} + +static PyObject * +pyg_option_context_set_help_enabled(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "help_enable", NULL }; + + PyObject *help_enabled; + if (! PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GOptionContext.set_help_enabled", + kwlist, &help_enabled)) + return NULL; + + g_option_context_set_help_enabled(self->context, PyObject_IsTrue(help_enabled)); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pyg_option_context_get_help_enabled(PyGOptionContext *self) +{ + return PyBool_FromLong(g_option_context_get_help_enabled(self->context)); +} + +static PyObject * +pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "ignore_unknown_options", NULL }; + PyObject *ignore_unknown_options; + + if (! PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GOptionContext.set_ignore_unknown_options", + kwlist, &ignore_unknown_options)) + return NULL; + + g_option_context_set_ignore_unknown_options(self->context, + PyObject_IsTrue(ignore_unknown_options)); + + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self) +{ + return PyBool_FromLong( + g_option_context_get_ignore_unknown_options(self->context)); +} + +static PyObject * +pyg_option_context_set_main_group(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "group", NULL }; + GOptionGroup *g_group; + PyObject *group; + + if (! PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GOptionContext.set_main_group", + kwlist, &group)) + return NULL; + + if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { + PyErr_SetString(PyExc_TypeError, + "GOptionContext.set_main_group expects a GOptionGroup."); + return NULL; + } + + g_group = pyglib_option_group_transfer_group(group); + if (g_group == NULL) + { + PyErr_SetString(PyExc_RuntimeError, + "Group is already in a OptionContext."); + return NULL; + } + + g_option_context_set_main_group(self->context, g_group); + + Py_INCREF(group); + self->main_group = (PyGOptionGroup*) group; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pyg_option_context_get_main_group(PyGOptionContext *self) +{ + if (self->main_group == NULL) + { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(self->main_group); + return (PyObject*) self->main_group; +} + +static PyObject * +pyg_option_context_add_group(PyGOptionContext *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "group", NULL }; + GOptionGroup *g_group; + PyObject *group; + + if (! PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GOptionContext.add_group", + kwlist, &group)) + return NULL; + + if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { + PyErr_SetString(PyExc_TypeError, + "GOptionContext.add_group expects a GOptionGroup."); + return NULL; + } + + g_group = pyglib_option_group_transfer_group(group); + if (g_group == NULL) + { + PyErr_SetString(PyExc_RuntimeError, + "Group is already in a OptionContext."); + return NULL; + } + Py_INCREF(group); + + g_option_context_add_group(self->context, g_group); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +pyg_option_context_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGOptionContext_Type) + return _pyglib_generic_ptr_richcompare(((PyGOptionContext*)self)->context, + ((PyGOptionContext*)other)->context, + op); + else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + +static PyObject * +pyg_option_get_context(PyGOptionContext *self) +{ + return PYGLIB_CPointer_WrapPointer(self->context, "goption.context"); +} + +static PyMethodDef pyg_option_context_methods[] = { + { "parse", (PyCFunction)pyg_option_context_parse, METH_VARARGS | METH_KEYWORDS }, + { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_VARARGS | METH_KEYWORDS }, + { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS }, + { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_VARARGS | METH_KEYWORDS }, + { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS }, + { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_VARARGS | METH_KEYWORDS }, + { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS }, + { "add_group", (PyCFunction)pyg_option_context_add_group, METH_VARARGS | METH_KEYWORDS }, + { "_get_context", (PyCFunction)pyg_option_get_context, METH_NOARGS }, + { NULL, NULL, 0 }, +}; + +void +pyglib_option_context_register_types(PyObject *d) +{ + PyGOptionContext_Type.tp_dealloc = (destructor)pyg_option_context_dealloc; + PyGOptionContext_Type.tp_richcompare = pyg_option_context_richcompare; + PyGOptionContext_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGOptionContext_Type.tp_methods = pyg_option_context_methods; + PyGOptionContext_Type.tp_init = (initproc)pyg_option_context_init; + PYGLIB_REGISTER_TYPE(d, PyGOptionContext_Type, "OptionContext"); +} diff --git a/gi/pygoptioncontext.h b/gi/pygoptioncontext.h new file mode 100644 index 0000000..efe5ffa --- /dev/null +++ b/gi/pygoptioncontext.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYG_OPTIONCONTEXT_H__ +#define __PYG_OPTIONCONTEXT_H__ + +#include "pygoptiongroup.h" + +extern PyTypeObject PyGOptionContext_Type; + +typedef struct { + PyObject_HEAD + PyGOptionGroup *main_group; + GOptionContext *context; +} PyGOptionContext; + +PyObject* pyg_option_context_new(GOptionContext *context); + +void pyglib_option_context_register_types(PyObject *d); + +#endif /* __PYG_OPTIONCONTEXT_H__ */ diff --git a/gi/pygoptiongroup.c b/gi/pygoptiongroup.c new file mode 100644 index 0000000..2990342 --- /dev/null +++ b/gi/pygoptiongroup.c @@ -0,0 +1,298 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygobject - Python bindings for the GLib, GObject and GIO + * Copyright (C) 2006 Johannes Hoelzl + * + * pygoptiongroup.c: GOptionContext and GOptionGroup wrapper + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pyglib-private.h" +#include "pygoptiongroup.h" + +PYGLIB_DEFINE_TYPE("gi._glib.OptionGroup", PyGOptionGroup_Type, PyGOptionGroup) + +/** + * pyg_option_group_new: + * @group: a GOptionGroup + * + * The returned GOptionGroup can't be used to set any hooks, translation domains + * or add entries. It's only intend is, to use for GOptionContext.add_group(). + * + * Returns: the GOptionGroup wrapper. + */ +PyObject * +pyg_option_group_new (GOptionGroup *group) +{ + PyGOptionGroup *self; + + self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup, + &PyGOptionGroup_Type); + if (self == NULL) + return NULL; + + self->group = group; + self->other_owner = TRUE; + self->is_in_context = FALSE; + + return (PyObject *)self; +} + +static gboolean +check_if_owned(PyGOptionGroup *self) +{ + if (self->other_owner) + { + PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by " + "gi._glib.OptionGroup(), so operation is not possible."); + return TRUE; + } + return FALSE; +} + +static void +destroy_g_group(PyGOptionGroup *self) +{ + PyGILState_STATE state; + state = pyglib_gil_state_ensure(); + + self->group = NULL; + Py_CLEAR(self->callback); + g_slist_foreach(self->strings, (GFunc) g_free, NULL); + g_slist_free(self->strings); + self->strings = NULL; + + if (self->is_in_context) + { + Py_DECREF(self); + } + + pyglib_gil_state_release(state); +} + +static int +pyg_option_group_init(PyGOptionGroup *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", "description", "help_description", + "callback", NULL }; + char *name, *description, *help_description; + PyObject *callback; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zzzO:GOptionGroup.__init__", + kwlist, &name, &description, + &help_description, &callback)) + return -1; + + self->group = g_option_group_new(name, description, help_description, + self, (GDestroyNotify) destroy_g_group); + self->other_owner = FALSE; + self->is_in_context = FALSE; + + Py_INCREF(callback); + self->callback = callback; + + return 0; +} + +static void +pyg_option_group_dealloc(PyGOptionGroup *self) +{ + if (!self->other_owner && !self->is_in_context) + { + GOptionGroup *tmp = self->group; + self->group = NULL; + if (tmp) + g_option_group_free(tmp); + } + + PyObject_Del(self); +} + +static gboolean +arg_func(const gchar *option_name, + const gchar *value, + PyGOptionGroup *self, + GError **error) +{ + PyObject *ret; + PyGILState_STATE state; + gboolean no_error; + + state = pyglib_gil_state_ensure(); + + if (value == NULL) + ret = PyObject_CallFunction(self->callback, "sOO", + option_name, Py_None, self); + else + ret = PyObject_CallFunction(self->callback, "ssO", + option_name, value, self); + + if (ret != NULL) + { + Py_DECREF(ret); + no_error = TRUE; + } else + no_error = pyglib_gerror_exception_check(error) != -1; + + pyglib_gil_state_release(state); + return no_error; +} + +static PyObject * +pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "entries", NULL }; + gssize entry_count, pos; + PyObject *entry_tuple, *list; + GOptionEntry *entries; + + if (check_if_owned(self)) + return NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionGroup.add_entries", + kwlist, &list)) + return NULL; + + if (!PyList_Check(list)) + { + PyErr_SetString(PyExc_TypeError, + "GOptionGroup.add_entries expected a list of entries"); + return NULL; + } + + entry_count = PyList_Size(list); + if (entry_count == -1) + { + PyErr_SetString(PyExc_TypeError, + "GOptionGroup.add_entries expected a list of entries"); + return NULL; + } + + entries = g_new0(GOptionEntry, entry_count + 1); + for (pos = 0; pos < entry_count; pos++) + { + gchar *long_name, *description, *arg_description; + entry_tuple = PyList_GetItem(list, pos); + if (!PyTuple_Check(entry_tuple)) + { + PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries " + "expected a list of entries"); + g_free(entries); + return NULL; + } + if (!PyArg_ParseTuple(entry_tuple, "scisz", + &long_name, + &(entries[pos].short_name), + &(entries[pos].flags), + &description, + &arg_description)) + { + PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries " + "expected a list of entries"); + g_free(entries); + return NULL; + } + long_name = g_strdup(long_name); + self->strings = g_slist_prepend(self->strings, long_name); + entries[pos].long_name = long_name; + + description = g_strdup(description); + self->strings = g_slist_prepend(self->strings, description); + entries[pos].description = description; + + arg_description = g_strdup(arg_description); + self->strings = g_slist_prepend(self->strings, arg_description); + entries[pos].arg_description = arg_description; + + entries[pos].arg = G_OPTION_ARG_CALLBACK; + entries[pos].arg_data = arg_func; + } + + g_option_group_add_entries(self->group, entries); + + g_free(entries); + + Py_INCREF(Py_None); + return Py_None; +} + + +static PyObject * +pyg_option_group_set_translation_domain(PyGOptionGroup *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "domain", NULL }; + char *domain; + + if (check_if_owned(self)) + return NULL; + + if (self->group == NULL) + { + PyErr_SetString(PyExc_RuntimeError, + "The corresponding GOptionGroup was already freed, " + "probably through the release of GOptionContext"); + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "z:GOptionGroup.set_translate_domain", + kwlist, &domain)) + return NULL; + + g_option_group_set_translation_domain(self->group, domain); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +pyg_option_group_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other) && + Py_TYPE(self) == &PyGOptionGroup_Type) { + return _pyglib_generic_ptr_richcompare(((PyGOptionGroup*)self)->group, + ((PyGOptionGroup*)other)->group, + op); + } else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + +static PyMethodDef pyg_option_group_methods[] = { + { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_VARARGS | METH_KEYWORDS }, + { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS | METH_KEYWORDS }, + { NULL, NULL, 0 }, +}; + +void +pyglib_option_group_register_types(PyObject *d) +{ + PyGOptionGroup_Type.tp_dealloc = (destructor)pyg_option_group_dealloc; + PyGOptionGroup_Type.tp_richcompare = pyg_option_group_richcompare; + PyGOptionGroup_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGOptionGroup_Type.tp_methods = pyg_option_group_methods; + PyGOptionGroup_Type.tp_init = (initproc)pyg_option_group_init; + PYGLIB_REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup"); +} diff --git a/gi/pygoptiongroup.h b/gi/pygoptiongroup.h new file mode 100644 index 0000000..872b9c6 --- /dev/null +++ b/gi/pygoptiongroup.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYG_OPTIONGROUP_H__ +#define __PYG_OPTIONGROUP_H__ + +extern PyTypeObject PyGOptionGroup_Type; + +typedef struct { + PyObject_HEAD + GOptionGroup *group; + gboolean other_owner, is_in_context; + PyObject *callback; + GSList *strings; /* all strings added with the entries, are freed on + GOptionGroup.destroy() */ +} PyGOptionGroup; + +PyObject* pyg_option_group_new(GOptionGroup *group); + +void pyglib_option_group_register_types(PyObject *d); + +#endif /* __PYG_OPTIONGROUP_H__ */ + + diff --git a/gi/pygparamspec.c b/gi/pygparamspec.c new file mode 100644 index 0000000..938f797 --- /dev/null +++ b/gi/pygparamspec.c @@ -0,0 +1,418 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * Copyright (C) 2004 Johan Dahlin + * + * pygenum.c: GEnum and GFlag wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "pygobject-private.h" +#include "pygparamspec.h" + +PYGLIB_DEFINE_TYPE("gobject.GParamSpec", PyGParamSpec_Type, PyGParamSpec); + +static PyObject* +pyg_param_spec_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGParamSpec_Type) + return _pyglib_generic_ptr_richcompare(((PyGParamSpec*)self)->pspec, + ((PyGParamSpec*)other)->pspec, + op); + else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + +static long +pyg_param_spec_hash(PyGParamSpec *self) +{ + return (long)self->pspec; +} + +static PyObject * +pyg_param_spec_repr(PyGParamSpec *self) +{ + char buf[80]; + + g_snprintf(buf, sizeof(buf), "<%s '%s'>", + G_PARAM_SPEC_TYPE_NAME(self->pspec), + g_param_spec_get_name(self->pspec)); + return PYGLIB_PyUnicode_FromString(buf); +} + +static void +pyg_param_spec_dealloc(PyGParamSpec *self) +{ + g_param_spec_unref(self->pspec); + PyObject_DEL(self); +} + + +static PyObject * +pygenum_from_pspec(GParamSpec *pspec) +{ + PyObject *pyclass; + GParamSpecEnum *enum_pspec; + GType enum_type; + + enum_pspec = G_PARAM_SPEC_ENUM(pspec); + enum_type = G_ENUM_CLASS_TYPE(enum_pspec->enum_class); + pyclass = (PyObject*)g_type_get_qdata(enum_type, pygenum_class_key); + if (pyclass == NULL) { + pyclass = pyg_enum_add(NULL, g_type_name(enum_type), NULL, enum_type); + if (pyclass == NULL) + pyclass = Py_None; + } + + Py_INCREF(pyclass); + return pyclass; +} + +static PyObject * +pygflags_from_pspec(GParamSpec *pspec) +{ + PyObject *pyclass; + GParamSpecFlags *flag_pspec; + GType flag_type; + + flag_pspec = G_PARAM_SPEC_FLAGS(pspec); + flag_type = G_FLAGS_CLASS_TYPE(flag_pspec->flags_class); + pyclass = (PyObject*)g_type_get_qdata(flag_type, pygflags_class_key); + if (pyclass == NULL) { + pyclass = pyg_flags_add(NULL, g_type_name(flag_type), NULL, flag_type); + if (pyclass == NULL) + pyclass = Py_None; + } + Py_INCREF(pyclass); + return pyclass; +} + +static PyObject * +pyg_param_spec_getattr(PyGParamSpec *self, const gchar *attr) +{ + GParamSpec *pspec; + + pspec = self->pspec; + + /* common attributes */ + if (!strcmp(attr, "__gtype__")) { + return pyg_type_wrapper_new(G_PARAM_SPEC_TYPE(pspec)); + } else if (!strcmp(attr, "name")) { + return Py_BuildValue("s", g_param_spec_get_name(pspec)); + } else if (!strcmp(attr, "nick")) { + return Py_BuildValue("s", g_param_spec_get_nick(pspec)); + } else if (!strcmp(attr, "blurb") || !strcmp(attr, "__doc__")) { + return Py_BuildValue("s", g_param_spec_get_blurb(pspec)); + } else if (!strcmp(attr, "flags")) { + return PYGLIB_PyLong_FromLong(pspec->flags); + } else if (!strcmp(attr, "value_type")) { + return pyg_type_wrapper_new(pspec->value_type); + } else if (!strcmp(attr, "owner_type")) { + return pyg_type_wrapper_new(pspec->owner_type); + } + + if (G_IS_PARAM_SPEC_CHAR(pspec)) { + if (!strcmp(attr, "default_value")) { + return PYGLIB_PyUnicode_FromFormat( + "%c", G_PARAM_SPEC_CHAR(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_CHAR(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_CHAR(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_UCHAR(pspec)) { + if (!strcmp(attr, "default_value")) { + return PYGLIB_PyUnicode_FromFormat( + "%c", G_PARAM_SPEC_UCHAR(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_UCHAR(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_UCHAR(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_BOOLEAN(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyBool_FromLong(G_PARAM_SPEC_BOOLEAN(pspec)->default_value); + } + } else if (G_IS_PARAM_SPEC_INT(pspec)) { + if (!strcmp(attr, "default_value")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PYGLIB_PyLong_FromLong(G_PARAM_SPEC_INT(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_UINT(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_UINT(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_LONG(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyLong_FromLong(G_PARAM_SPEC_LONG(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_ULONG(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyLong_FromUnsignedLong(G_PARAM_SPEC_ULONG(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_INT64(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyLong_FromLongLong(G_PARAM_SPEC_INT64(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_UINT64(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyLong_FromUnsignedLongLong(G_PARAM_SPEC_UINT64(pspec)->maximum); + } + } else if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + if (!strcmp(attr, "default_value")) { + return PYGLIB_PyUnicode_FromFormat( + "%c", G_PARAM_SPEC_UNICHAR(pspec)->default_value); + } + } else if (G_IS_PARAM_SPEC_ENUM(pspec)) { + if (!strcmp(attr, "default_value")) { + return pyg_enum_from_gtype( + pspec->value_type, G_PARAM_SPEC_ENUM(pspec)->default_value); + } else if (!strcmp(attr, "enum_class")) { + return pygenum_from_pspec(pspec); + } + } else if (G_IS_PARAM_SPEC_FLAGS(pspec)) { + if (!strcmp(attr, "default_value")) { + return pyg_flags_from_gtype( + pspec->value_type, G_PARAM_SPEC_FLAGS(pspec)->default_value); + } else if (!strcmp(attr, "flags_class")) { + return pygflags_from_pspec(pspec); + } + } else if (G_IS_PARAM_SPEC_FLOAT(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->maximum); + } else if (!strcmp(attr, "epsilon")) { + return PyFloat_FromDouble(G_PARAM_SPEC_FLOAT(pspec)->epsilon); + } + } else if (G_IS_PARAM_SPEC_DOUBLE(pspec)) { + if (!strcmp(attr, "default_value")) { + return PyFloat_FromDouble( + G_PARAM_SPEC_DOUBLE(pspec)->default_value); + } else if (!strcmp(attr, "minimum")) { + return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->minimum); + } else if (!strcmp(attr, "maximum")) { + return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->maximum); + } else if (!strcmp(attr, "epsilon")) { + return PyFloat_FromDouble(G_PARAM_SPEC_DOUBLE(pspec)->epsilon); + } + } else if (G_IS_PARAM_SPEC_STRING(pspec)) { + if (!strcmp(attr, "default_value")) { + return Py_BuildValue( + "s", G_PARAM_SPEC_STRING(pspec)->default_value); + } else if (!strcmp(attr, "cset_first")) { + return Py_BuildValue( + "s", G_PARAM_SPEC_STRING(pspec)->cset_first); + } else if (!strcmp(attr, "cset_nth")) { + return Py_BuildValue( + "s", G_PARAM_SPEC_STRING(pspec)->cset_nth); + } else if (!strcmp(attr, "substitutor")) { + return Py_BuildValue( + "c", G_PARAM_SPEC_STRING(pspec)->substitutor); + } else if (!strcmp(attr, "null_fold_if_empty")) { + return PyBool_FromLong( + G_PARAM_SPEC_STRING(pspec)->null_fold_if_empty); + } else if (!strcmp(attr, "ensure_non_null")) { + return PyBool_FromLong( + G_PARAM_SPEC_STRING(pspec)->ensure_non_null); + } + } else { + /* This is actually not what's exported by GObjects paramspecs, + * But we exported this in earlier versions, so it's better to keep it here + * compatibility. But don't return it in __dir__, to "hide" it. + */ + if (!strcmp(attr, "default_value")) { + /* XXX: Raise deprecation warning */ + Py_INCREF(Py_None); + return Py_None; + } + } + + PyErr_SetString(PyExc_AttributeError, attr); + return NULL; +} + + +static PyObject * +pyg_param_spec_dir(PyGParamSpec *self, PyObject *dummy) +{ + GParamSpec *pspec = self->pspec; + + if (G_IS_PARAM_SPEC_CHAR(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", "flags", + "maximum", "minimum", "name", "nick", + "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_UCHAR(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", + "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_BOOLEAN(pspec)) { + return Py_BuildValue("[sssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_INT(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", "name", + "nick", "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_UINT(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", + "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_LONG(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", "name", + "nick", "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_ULONG(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", "name", + "nick", "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_INT64(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", "name", + "nick", "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_UINT64(pspec)) { + return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "maximum", "minimum", + "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + return Py_BuildValue("[sssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_ENUM(pspec)) { + return Py_BuildValue("[ssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", "enum_class", + "flags", "name", "nick", "owner_type", + "value_type"); + } else if (G_IS_PARAM_SPEC_FLAGS(pspec)) { + return Py_BuildValue("[ssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", + "flags", "flags_class", "name", "nick", + "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_FLOAT(pspec)) { + return Py_BuildValue("[ssssssssssss]", "__doc__", "__gtype__", + "blurb", "epsilon", + "flags", "maximum", "minimum", "name", "nick", "owner_type", + "value_type", + "default_value"); + } else if (G_IS_PARAM_SPEC_DOUBLE(pspec)) { + return Py_BuildValue("[ssssssssssss]", "__doc__", "__gtype__", + "blurb", "default_value", "epsilon", + "flags", "maximum", "minimum", "name", "nick", + "owner_type", "value_type"); + } else if (G_IS_PARAM_SPEC_STRING(pspec)) { + return Py_BuildValue("[ssssssssssssss]", "__doc__", "__gtype__", + "blurb", "cset_first", "cset_nth", "default_value", + "ensure_non_null", "flags", "name", "nick", + "null_fold_if_empty", "owner_type", "substitutor", + "value_type"); + } else { + return Py_BuildValue("[ssssssss]", "__doc__", "__gtype__", "blurb", + "flags", "name", "nick", + "owner_type", "value_type"); + } +} + +static PyMethodDef pyg_param_spec_methods[] = { + { "__dir__", (PyCFunction)pyg_param_spec_dir, METH_NOARGS}, + { NULL, NULL, 0} +}; + +/** + * pyg_param_spec_new: + * @pspec: a GParamSpec. + * + * Creates a wrapper for a GParamSpec. + * + * Returns: the GParamSpec wrapper. + */ +PyObject * +pyg_param_spec_new(GParamSpec *pspec) +{ + PyGParamSpec *self; + + self = (PyGParamSpec *)PyObject_NEW(PyGParamSpec, + &PyGParamSpec_Type); + if (self == NULL) + return NULL; + + self->pspec = g_param_spec_ref(pspec); + return (PyObject *)self; +} + +void +pygobject_paramspec_register_types(PyObject *d) +{ + Py_TYPE(&PyGParamSpec_Type) = &PyType_Type; + PyGParamSpec_Type.tp_dealloc = (destructor)pyg_param_spec_dealloc; + PyGParamSpec_Type.tp_getattr = (getattrfunc)pyg_param_spec_getattr; + PyGParamSpec_Type.tp_richcompare = pyg_param_spec_richcompare; + PyGParamSpec_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGParamSpec_Type.tp_repr = (reprfunc)pyg_param_spec_repr; + PyGParamSpec_Type.tp_hash = (hashfunc)pyg_param_spec_hash; + PyGParamSpec_Type.tp_methods = pyg_param_spec_methods; + + + if (PyType_Ready(&PyGParamSpec_Type)) + return; + PyDict_SetItemString(d, "GParamSpec", (PyObject *)&PyGParamSpec_Type); +} diff --git a/gi/pygparamspec.h b/gi/pygparamspec.h new file mode 100644 index 0000000..b3ba8ca --- /dev/null +++ b/gi/pygparamspec.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * pyginterface.c: wrapper for the gobject library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_PARAMSPEC_H__ +#define __PYGOBJECT_PARAMSPEC_H__ + +#include + +extern PyTypeObject PyGParamSpec_Type; +PyObject * pyg_param_spec_new (GParamSpec *pspec); + +void pygobject_paramspec_register_types(PyObject *d); + +#endif /* __PYGOBJECT_PARAMSPEC_H__ */ diff --git a/gi/pygpointer.c b/gi/pygpointer.c new file mode 100644 index 0000000..575c751 --- /dev/null +++ b/gi/pygpointer.c @@ -0,0 +1,198 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pygpointer.c: wrapper for GPointer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "pygobject-private.h" +#include "pygpointer.h" + +#include "pygi.h" + + +GQuark pygpointer_class_key; + +PYGLIB_DEFINE_TYPE("gobject.GPointer", PyGPointer_Type, PyGPointer); + +static void +pyg_pointer_dealloc(PyGPointer *self) +{ + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject* +pyg_pointer_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other)) + return _pyglib_generic_ptr_richcompare(((PyGPointer*)self)->pointer, + ((PyGPointer*)other)->pointer, + op); + else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + +static long +pyg_pointer_hash(PyGPointer *self) +{ + return (long)self->pointer; +} + +static PyObject * +pyg_pointer_repr(PyGPointer *self) +{ + gchar buf[128]; + + g_snprintf(buf, sizeof(buf), "<%s at 0x%lx>", g_type_name(self->gtype), + (long)self->pointer); + return PYGLIB_PyUnicode_FromString(buf); +} + +static int +pyg_pointer_init(PyGPointer *self, PyObject *args, PyObject *kwargs) +{ + gchar buf[512]; + + if (!PyArg_ParseTuple(args, ":GPointer.__init__")) + return -1; + + self->pointer = NULL; + self->gtype = 0; + + g_snprintf(buf, sizeof(buf), "%s can not be constructed", + Py_TYPE(self)->tp_name); + PyErr_SetString(PyExc_NotImplementedError, buf); + return -1; +} + +static void +pyg_pointer_free(PyObject *op) +{ + PyObject_FREE(op); +} + +/** + * pyg_register_pointer: + * @dict: the module dictionary to store the wrapper class. + * @class_name: the Python name for the wrapper class. + * @pointer_type: the GType of the pointer type being wrapped. + * @type: the wrapper class. + * + * Registers a wrapper for a pointer type. The wrapper class will be + * a subclass of gobject.GPointer, and a reference to the wrapper + * class will be stored in the provided module dictionary. + */ +void +pyg_register_pointer(PyObject *dict, const gchar *class_name, + GType pointer_type, PyTypeObject *type) +{ + PyObject *o; + + g_return_if_fail(dict != NULL); + g_return_if_fail(class_name != NULL); + g_return_if_fail(pointer_type != 0); + + if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_pointer_dealloc; + + Py_TYPE(type) = &PyType_Type; + type->tp_base = &PyGPointer_Type; + + if (PyType_Ready(type) < 0) { + g_warning("could not get type `%s' ready", type->tp_name); + return; + } + + PyDict_SetItemString(type->tp_dict, "__gtype__", + o=pyg_type_wrapper_new(pointer_type)); + Py_DECREF(o); + + g_type_set_qdata(pointer_type, pygpointer_class_key, type); + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); +} + +/** + * pyg_pointer_new: + * @pointer_type: the GType of the pointer value. + * @pointer: the pointer value. + * + * Creates a wrapper for a pointer value. Since G_TYPE_POINTER types + * don't register any information about how to copy/free them, there + * is no guarantee that the pointer will remain valid, and there is + * nothing registered to release the pointer when the pointer goes out + * of scope. This is why we don't recommend people use these types. + * + * Returns: the boxed wrapper. + */ +PyObject * +pyg_pointer_new(GType pointer_type, gpointer pointer) +{ + PyGILState_STATE state; + PyGPointer *self; + PyTypeObject *tp; + g_return_val_if_fail(pointer_type != 0, NULL); + + state = pyglib_gil_state_ensure(); + + if (!pointer) { + Py_INCREF(Py_None); + pyglib_gil_state_release(state); + return Py_None; + } + + tp = g_type_get_qdata(pointer_type, pygpointer_class_key); + + if (!tp) + tp = (PyTypeObject *)pygi_type_import_by_g_type(pointer_type); + + if (!tp) + tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */ + self = PyObject_NEW(PyGPointer, tp); + + pyglib_gil_state_release(state); + + if (self == NULL) + return NULL; + + self->pointer = pointer; + self->gtype = pointer_type; + + return (PyObject *)self; +} + +void +pygobject_pointer_register_types(PyObject *d) +{ + pygpointer_class_key = g_quark_from_static_string("PyGPointer::class"); + + PyGPointer_Type.tp_dealloc = (destructor)pyg_pointer_dealloc; + PyGPointer_Type.tp_richcompare = pyg_pointer_richcompare; + PyGPointer_Type.tp_repr = (reprfunc)pyg_pointer_repr; + PyGPointer_Type.tp_hash = (hashfunc)pyg_pointer_hash; + PyGPointer_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; + PyGPointer_Type.tp_init = (initproc)pyg_pointer_init; + PyGPointer_Type.tp_free = (freefunc)pyg_pointer_free; + PYGOBJECT_REGISTER_GTYPE(d, PyGPointer_Type, "GPointer", G_TYPE_POINTER); +} diff --git a/gi/pygpointer.h b/gi/pygpointer.h new file mode 100644 index 0000000..f2923da --- /dev/null +++ b/gi/pygpointer.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_POINTER_H__ +#define __PYGOBJECT_POINTER_H__ + +void pygobject_pointer_register_types(PyObject *d); + +#endif /* __PYGOBJECT_POINTER_H__ */ diff --git a/gi/pygspawn.c b/gi/pygspawn.c new file mode 100644 index 0000000..72746b8 --- /dev/null +++ b/gi/pygspawn.c @@ -0,0 +1,259 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * pygspawn.c: wrapper for the glib library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#include +#include + +#include "pyglib.h" +#include "pyglib-private.h" + +#include "pygspawn.h" + +struct _PyGChildSetupData { + PyObject *func; + PyObject *data; +}; + +PYGLIB_DEFINE_TYPE("gi._glib.Pid", PyGPid_Type, PYGLIB_PyLongObject) + +static PyObject * +pyg_pid_close(PyObject *self, PyObject *args, PyObject *kwargs) +{ + g_spawn_close_pid(PYGLIB_PyLong_AsLong(self)); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef pyg_pid_methods[] = { + { "close", (PyCFunction)pyg_pid_close, METH_NOARGS }, + { NULL, NULL, 0 } +}; + +static void +pyg_pid_free(PyObject *gpid) +{ + g_spawn_close_pid((GPid) PYGLIB_PyLong_AsLong(gpid)); + PYGLIB_PyLong_Type.tp_free((void *) gpid); +} + +static int +pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyErr_SetString(PyExc_TypeError, "gi._glib.Pid cannot be manually instantiated"); + return -1; +} + +PyObject * +pyg_pid_new(GPid pid) +{ + return PyObject_CallMethod((PyObject*)&PyGPid_Type, "__new__", "Oi", + &PyGPid_Type, pid); +} + +static void +_pyg_spawn_async_callback(gpointer user_data) +{ + struct _PyGChildSetupData *data; + PyObject *retval; + PyGILState_STATE gil; + + data = (struct _PyGChildSetupData *) user_data; + gil = pyglib_gil_state_ensure(); + if (data->data) + retval = PyObject_CallFunction(data->func, "O", data->data); + else + retval = PyObject_CallFunction(data->func, NULL); + if (retval) + Py_DECREF(retval); + else + PyErr_Print(); + Py_DECREF(data->func); + Py_XDECREF(data->data); + g_slice_free(struct _PyGChildSetupData, data); + pyglib_gil_state_release(gil); +} + +PyObject * +pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "argv", "envp", "working_directory", "flags", + "child_setup", "user_data", "standard_input", + "standard_output", "standard_error", NULL }; + PyObject *pyargv, *pyenvp = NULL; + char **argv, **envp = NULL; + PyObject *func = Py_None, *user_data = NULL; + char *working_directory = NULL; + int flags = 0, _stdin = -1, _stdout = -1, _stderr = -1; + PyObject *pystdin = NULL, *pystdout = NULL, *pystderr = NULL; + gint *standard_input, *standard_output, *standard_error; + struct _PyGChildSetupData *callback_data = NULL; + GError *error = NULL; + GPid child_pid = -1; + Py_ssize_t len, i; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsiOOOOO:gi._glib.spawn_async", + kwlist, + &pyargv, &pyenvp, &working_directory, &flags, + &func, &user_data, + &pystdin, &pystdout, &pystderr)) + return NULL; + + if (pystdin && PyObject_IsTrue(pystdin)) + standard_input = &_stdin; + else + standard_input = NULL; + + if (pystdout && PyObject_IsTrue(pystdout)) + standard_output = &_stdout; + else + standard_output = NULL; + + if (pystderr && PyObject_IsTrue(pystderr)) + standard_error = &_stderr; + else + standard_error = NULL; + + /* parse argv */ + if (!PySequence_Check(pyargv)) { + PyErr_SetString(PyExc_TypeError, + "gi._glib.spawn_async: " + "first argument must be a sequence of strings"); + return NULL; + } + len = PySequence_Length(pyargv); + argv = g_new0(char *, len + 1); + for (i = 0; i < len; ++i) { + PyObject *tmp = PySequence_ITEM(pyargv, i); + if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) { + PyErr_SetString(PyExc_TypeError, + "gi._glib.spawn_async: " + "first argument must be a sequence of strings"); + g_free(argv); + Py_XDECREF(tmp); + return NULL; + } + argv[i] = PYGLIB_PyUnicode_AsString(tmp); + Py_DECREF(tmp); + } + + /* parse envp */ + if (pyenvp) { + if (!PySequence_Check(pyenvp)) { + PyErr_SetString(PyExc_TypeError, + "gi._glib.spawn_async: " + "second argument must be a sequence of strings"); + g_free(argv); + return NULL; + } + len = PySequence_Length(pyenvp); + envp = g_new0(char *, len + 1); + for (i = 0; i < len; ++i) { + PyObject *tmp = PySequence_ITEM(pyenvp, i); + if (tmp == NULL || !PYGLIB_PyUnicode_Check(tmp)) { + PyErr_SetString(PyExc_TypeError, + "gi._glib.spawn_async: " + "second argument must be a sequence of strings"); + g_free(envp); + Py_XDECREF(tmp); + g_free(argv); + return NULL; + } + envp[i] = PYGLIB_PyUnicode_AsString(tmp); + Py_DECREF(tmp); + } + } + + if (func != Py_None) { + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "child_setup parameter must be callable or None"); + g_free(argv); + if (envp) + g_free(envp); + return NULL; + } + callback_data = g_slice_new(struct _PyGChildSetupData); + callback_data->func = func; + callback_data->data = user_data; + Py_INCREF(callback_data->func); + if (callback_data->data) + Py_INCREF(callback_data->data); + } + + if (!g_spawn_async_with_pipes(working_directory, argv, envp, flags, + (func != Py_None ? _pyg_spawn_async_callback : NULL), + callback_data, &child_pid, + standard_input, + standard_output, + standard_error, + &error)) + + + { + g_free(argv); + if (envp) g_free(envp); + if (callback_data) { + Py_DECREF(callback_data->func); + Py_XDECREF(callback_data->data); + g_slice_free(struct _PyGChildSetupData, callback_data); + } + pyglib_error_check(&error); + return NULL; + } + g_free(argv); + if (envp) g_free(envp); + + if (standard_input) + pystdin = PYGLIB_PyLong_FromLong(*standard_input); + else { + Py_INCREF(Py_None); + pystdin = Py_None; + } + + if (standard_output) + pystdout = PYGLIB_PyLong_FromLong(*standard_output); + else { + Py_INCREF(Py_None); + pystdout = Py_None; + } + + if (standard_error) + pystderr = PYGLIB_PyLong_FromLong(*standard_error); + else { + Py_INCREF(Py_None); + pystderr = Py_None; + } + + return Py_BuildValue("NNNN", pyg_pid_new(child_pid), pystdin, pystdout, pystderr); +} + +void +pyglib_spawn_register_types(PyObject *d) +{ + PyGPid_Type.tp_base = &PYGLIB_PyLong_Type; + PyGPid_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGPid_Type.tp_methods = pyg_pid_methods; + PyGPid_Type.tp_init = pyg_pid_tp_init; + PyGPid_Type.tp_free = (freefunc)pyg_pid_free; + PyGPid_Type.tp_new = PYGLIB_PyLong_Type.tp_new; + PYGLIB_REGISTER_TYPE(d, PyGPid_Type, "Pid"); +} diff --git a/gi/pygspawn.h b/gi/pygspawn.h new file mode 100644 index 0000000..2e8dd3c --- /dev/null +++ b/gi/pygspawn.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pyglib - Python bindings for GLib toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYG_PID_H__ +#define __PYG_PID_H__ + +PyObject * pyg_pid_new(GPid pid); +void pyglib_spawn_register_types(PyObject *d); + +PyObject * pyglib_spawn_async(PyObject *self, PyObject *args, PyObject *kwargs); + + +#endif /* __PYG_PID_H__ */ + diff --git a/gi/pygtype.c b/gi/pygtype.c new file mode 100644 index 0000000..e1fb4e6 --- /dev/null +++ b/gi/pygtype.c @@ -0,0 +1,1209 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pygtype.c: glue code to wrap the GType code. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "pygobject-private.h" +#include "pygparamspec.h" +#include "pygtype.h" + +#include "pygi-value.h" + +/* -------------- __gtype__ objects ---------------------------- */ + +typedef struct { + PyObject_HEAD + GType type; +} PyGTypeWrapper; + +PYGLIB_DEFINE_TYPE("gobject.GType", PyGTypeWrapper_Type, PyGTypeWrapper); + +static PyObject* +pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op) +{ + if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type) + return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type, + ((PyGTypeWrapper*)other)->type, + op); + else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } +} + +static long +pyg_type_wrapper_hash(PyGTypeWrapper *self) +{ + return (long)self->type; +} + +static PyObject * +pyg_type_wrapper_repr(PyGTypeWrapper *self) +{ + char buf[80]; + const gchar *name = g_type_name(self->type); + + g_snprintf(buf, sizeof(buf), "", + name?name:"invalid", (unsigned long int) self->type); + return PYGLIB_PyUnicode_FromString(buf); +} + +static void +pyg_type_wrapper_dealloc(PyGTypeWrapper *self) +{ + PyObject_DEL(self); +} + +static GQuark +_pyg_type_key(GType type) { + GQuark key; + + if (g_type_is_a(type, G_TYPE_INTERFACE)) { + key = pyginterface_type_key; + } else if (g_type_is_a(type, G_TYPE_ENUM)) { + key = pygenum_class_key; + } else if (g_type_is_a(type, G_TYPE_FLAGS)) { + key = pygflags_class_key; + } else if (g_type_is_a(type, G_TYPE_POINTER)) { + key = pygpointer_class_key; + } else if (g_type_is_a(type, G_TYPE_BOXED)) { + key = pygboxed_type_key; + } else { + key = pygobject_class_key; + } + + return key; +} + +static PyObject * +_wrap_g_type_wrapper__get_pytype(PyGTypeWrapper *self, void *closure) +{ + GQuark key; + PyObject *py_type; + + key = _pyg_type_key(self->type); + + py_type = g_type_get_qdata(self->type, key); + if (!py_type) + py_type = Py_None; + + Py_INCREF(py_type); + return py_type; +} + +static int +_wrap_g_type_wrapper__set_pytype(PyGTypeWrapper *self, PyObject* value, void *closure) +{ + GQuark key; + PyObject *py_type; + + key = _pyg_type_key(self->type); + + py_type = g_type_get_qdata(self->type, key); + Py_CLEAR(py_type); + if (value == Py_None) + g_type_set_qdata(self->type, key, NULL); + else if (PyType_Check(value)) { + Py_INCREF(value); + g_type_set_qdata(self->type, key, value); + } else { + PyErr_SetString(PyExc_TypeError, "Value must be None or a type object"); + return -1; + } + + return 0; +} + +static PyObject * +_wrap_g_type_wrapper__get_name(PyGTypeWrapper *self, void *closure) +{ + const char *name = g_type_name(self->type); + return PYGLIB_PyUnicode_FromString(name ? name : "invalid"); +} + +static PyObject * +_wrap_g_type_wrapper__get_parent(PyGTypeWrapper *self, void *closure) +{ + return pyg_type_wrapper_new(g_type_parent(self->type)); +} + +static PyObject * +_wrap_g_type_wrapper__get_fundamental(PyGTypeWrapper *self, void *closure) +{ + return pyg_type_wrapper_new(g_type_fundamental(self->type)); +} + +static PyObject * +_wrap_g_type_wrapper__get_children(PyGTypeWrapper *self, void *closure) +{ + guint n_children, i; + GType *children; + PyObject *retval; + + children = g_type_children(self->type, &n_children); + + retval = PyList_New(n_children); + for (i = 0; i < n_children; i++) + PyList_SetItem(retval, i, pyg_type_wrapper_new(children[i])); + g_free(children); + + return retval; +} + +static PyObject * +_wrap_g_type_wrapper__get_interfaces(PyGTypeWrapper *self, void *closure) +{ + guint n_interfaces, i; + GType *interfaces; + PyObject *retval; + + interfaces = g_type_interfaces(self->type, &n_interfaces); + + retval = PyList_New(n_interfaces); + for (i = 0; i < n_interfaces; i++) + PyList_SetItem(retval, i, pyg_type_wrapper_new(interfaces[i])); + g_free(interfaces); + + return retval; +} + +static PyObject * +_wrap_g_type_wrapper__get_depth(PyGTypeWrapper *self, void *closure) +{ + return PYGLIB_PyLong_FromLong(g_type_depth(self->type)); +} + +static PyGetSetDef _PyGTypeWrapper_getsets[] = { + { "pytype", (getter)_wrap_g_type_wrapper__get_pytype, (setter)_wrap_g_type_wrapper__set_pytype }, + { "name", (getter)_wrap_g_type_wrapper__get_name, (setter)0 }, + { "fundamental", (getter)_wrap_g_type_wrapper__get_fundamental, (setter)0 }, + { "parent", (getter)_wrap_g_type_wrapper__get_parent, (setter)0 }, + { "children", (getter)_wrap_g_type_wrapper__get_children, (setter)0 }, + { "interfaces", (getter)_wrap_g_type_wrapper__get_interfaces, (setter)0 }, + { "depth", (getter)_wrap_g_type_wrapper__get_depth, (setter)0 }, + { NULL, (getter)0, (setter)0 } +}; + +static PyObject* +_wrap_g_type_is_interface(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_INTERFACE(self->type)); +} + +static PyObject* +_wrap_g_type_is_classed(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_CLASSED(self->type)); +} + +static PyObject* +_wrap_g_type_is_instantiatable(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_INSTANTIATABLE(self->type)); +} + +static PyObject* +_wrap_g_type_is_derivable(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_DERIVABLE(self->type)); +} + +static PyObject* +_wrap_g_type_is_deep_derivable(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_DEEP_DERIVABLE(self->type)); +} + +static PyObject* +_wrap_g_type_is_abstract(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_ABSTRACT(self->type)); +} + +static PyObject* +_wrap_g_type_is_value_abstract(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_VALUE_ABSTRACT(self->type)); +} + +static PyObject* +_wrap_g_type_is_value_type(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_IS_VALUE_TYPE(self->type)); +} + +static PyObject* +_wrap_g_type_has_value_table(PyGTypeWrapper *self) +{ + return PyBool_FromLong(G_TYPE_HAS_VALUE_TABLE(self->type)); +} + +static PyObject* +_wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args) +{ + char *type_name; + GType type; + + if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name)) + return NULL; + + type = g_type_from_name(type_name); + if (type == 0) { + PyErr_SetString(PyExc_RuntimeError, "unknown type name"); + return NULL; + } + + return pyg_type_wrapper_new(type); +} + +static PyObject* +_wrap_g_type_is_a(PyGTypeWrapper *self, PyObject *args) +{ + PyObject *gparent; + GType parent; + + if (!PyArg_ParseTuple(args, "O:GType.is_a", &gparent)) + return NULL; + else if ((parent = pyg_type_from_object(gparent)) == 0) + return NULL; + + return PyBool_FromLong(g_type_is_a(self->type, parent)); +} + +static PyMethodDef _PyGTypeWrapper_methods[] = { + { "is_interface", (PyCFunction)_wrap_g_type_is_interface, METH_NOARGS }, + { "is_classed", (PyCFunction)_wrap_g_type_is_classed, METH_NOARGS }, + { "is_instantiatable", (PyCFunction)_wrap_g_type_is_instantiatable, METH_NOARGS }, + { "is_derivable", (PyCFunction)_wrap_g_type_is_derivable, METH_NOARGS }, + { "is_deep_derivable", (PyCFunction)_wrap_g_type_is_deep_derivable, METH_NOARGS }, + { "is_abstract", (PyCFunction)_wrap_g_type_is_abstract, METH_NOARGS }, + { "is_value_abstract", (PyCFunction)_wrap_g_type_is_value_abstract, METH_NOARGS }, + { "is_value_type", (PyCFunction)_wrap_g_type_is_value_type, METH_NOARGS }, + { "has_value_table", (PyCFunction)_wrap_g_type_has_value_table, METH_NOARGS }, + { "from_name", (PyCFunction)_wrap_g_type_from_name, METH_VARARGS | METH_STATIC }, + { "is_a", (PyCFunction)_wrap_g_type_is_a, METH_VARARGS }, + { NULL, 0, 0 } +}; + +static int +pyg_type_wrapper_init(PyGTypeWrapper *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "object", NULL }; + PyObject *py_object; + GType type; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:GType.__init__", + kwlist, &py_object)) + return -1; + + if (!(type = pyg_type_from_object(py_object))) + return -1; + + self->type = type; + + return 0; +} + +/** + * pyg_type_wrapper_new: + * type: a GType + * + * Creates a Python wrapper for a GType. + * + * Returns: the Python wrapper. + */ +PyObject * +pyg_type_wrapper_new(GType type) +{ + PyGTypeWrapper *self; + + self = (PyGTypeWrapper *)PyObject_NEW(PyGTypeWrapper, + &PyGTypeWrapper_Type); + if (self == NULL) + return NULL; + + self->type = type; + return (PyObject *)self; +} + +/** + * pyg_type_from_object_strict: + * obj: a Python object + * strict: if set to TRUE, raises an exception if it can't perform the + * conversion + * + * converts a python object to a GType. If strict is set, raises an + * exception if it can't perform the conversion, otherwise returns + * PY_TYPE_OBJECT. + * + * Returns: the corresponding GType, or 0 on error. + */ + +GType +pyg_type_from_object_strict(PyObject *obj, gboolean strict) +{ + PyObject *gtype; + GType type; + + /* NULL check */ + if (!obj) { + PyErr_SetString(PyExc_TypeError, "can't get type from NULL object"); + return 0; + } + + /* map some standard types to primitive GTypes ... */ + if (obj == Py_None) + return G_TYPE_NONE; + if (PyType_Check(obj)) { + PyTypeObject *tp = (PyTypeObject *)obj; + + if (tp == &PYGLIB_PyLong_Type) + return G_TYPE_INT; + else if (tp == &PyBool_Type) + return G_TYPE_BOOLEAN; + else if (tp == &PyLong_Type) + return G_TYPE_LONG; + else if (tp == &PyFloat_Type) + return G_TYPE_DOUBLE; + else if (tp == &PYGLIB_PyUnicode_Type) + return G_TYPE_STRING; + else if (tp == &PyBaseObject_Type) + return PY_TYPE_OBJECT; + } + + if (Py_TYPE(obj) == &PyGTypeWrapper_Type) { + return ((PyGTypeWrapper *)obj)->type; + } + + /* handle strings */ + if (PYGLIB_PyUnicode_Check(obj)) { + gchar *name = PYGLIB_PyUnicode_AsString(obj); + + type = g_type_from_name(name); + if (type != 0) { + return type; + } + } + + /* finally, look for a __gtype__ attribute on the object */ + gtype = PyObject_GetAttrString(obj, "__gtype__"); + + if (gtype) { + if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) { + type = ((PyGTypeWrapper *)gtype)->type; + Py_DECREF(gtype); + return type; + } + Py_DECREF(gtype); + } + + PyErr_Clear(); + + /* Some API like those that take GValues can hold a python object as + * a pointer. This is potentially dangerous becuase everything is + * passed in as a PyObject so we can't actually type check it. Only + * fallback to PY_TYPE_OBJECT if strict checking is disabled + */ + if (!strict) + return PY_TYPE_OBJECT; + + PyErr_SetString(PyExc_TypeError, "could not get typecode from object"); + return 0; +} + +/** + * pyg_type_from_object: + * obj: a Python object + * + * converts a python object to a GType. Raises an exception if it + * can't perform the conversion. + * + * Returns: the corresponding GType, or 0 on error. + */ +GType +pyg_type_from_object(PyObject *obj) +{ + /* Legacy call always defaults to strict type checking */ + return pyg_type_from_object_strict(obj, TRUE); +} + +/** + * pyg_enum_get_value: + * @enum_type: the GType of the flag. + * @obj: a Python object representing the flag value + * @val: a pointer to the location to store the integer representation of the flag. + * + * Converts a Python object to the integer equivalent. The conversion + * will depend on the type of the Python object. If the object is an + * integer, it is passed through directly. If it is a string, it will + * be treated as a full or short enum name as defined in the GType. + * + * Returns: 0 on success or -1 on failure + */ +gint +pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val) +{ + GEnumClass *eclass = NULL; + gint res = -1; + + g_return_val_if_fail(val != NULL, -1); + if (!obj) { + *val = 0; + res = 0; + } else if (PYGLIB_PyLong_Check(obj)) { + *val = PYGLIB_PyLong_AsLong(obj); + res = 0; + + if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { + g_warning("expected enumeration type %s, but got %s instead", + g_type_name(enum_type), + g_type_name(((PyGEnum *) obj)->gtype)); + } + /* Dumb code duplication, but probably not worth it to have yet another macro. */ + } else if (PyLong_Check(obj)) { + *val = PyLong_AsLong(obj); + res = 0; + + if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { + g_warning("expected enumeration type %s, but got %s instead", + g_type_name(enum_type), + g_type_name(((PyGEnum *) obj)->gtype)); + } + } else if (PYGLIB_PyUnicode_Check(obj)) { + GEnumValue *info; + char *str = PYGLIB_PyUnicode_AsString(obj); + + if (enum_type != G_TYPE_NONE) + eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); + else { + PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value"); + res = -1; + } + info = g_enum_get_value_by_name(eclass, str); + g_type_class_unref(eclass); + + if (!info) + info = g_enum_get_value_by_nick(eclass, str); + if (info) { + *val = info->value; + res = 0; + } else { + PyErr_SetString(PyExc_TypeError, "could not convert string"); + res = -1; + } + } else { + PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints"); + res = -1; + } + return res; +} + +/** + * pyg_flags_get_value: + * @flag_type: the GType of the flag. + * @obj: a Python object representing the flag value + * @val: a pointer to the location to store the integer representation of the flag. + * + * Converts a Python object to the integer equivalent. The conversion + * will depend on the type of the Python object. If the object is an + * integer, it is passed through directly. If it is a string, it will + * be treated as a full or short flag name as defined in the GType. + * If it is a tuple, then the items are treated as strings and ORed + * together. + * + * Returns: 0 on success or -1 on failure + */ +gint +pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val) +{ + GFlagsClass *fclass = NULL; + gint res = -1; + + g_return_val_if_fail(val != NULL, -1); + if (!obj) { + *val = 0; + res = 0; + } else if (PYGLIB_PyLong_Check(obj)) { + *val = PYGLIB_PyLong_AsUnsignedLong(obj); + res = 0; + } else if (PyLong_Check(obj)) { + *val = PyLong_AsLongLong(obj); + res = 0; + } else if (PYGLIB_PyUnicode_Check(obj)) { + GFlagsValue *info; + char *str = PYGLIB_PyUnicode_AsString(obj); + + if (flag_type != G_TYPE_NONE) + fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); + else { + PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); + res = -1; + } + info = g_flags_get_value_by_name(fclass, str); + g_type_class_unref(fclass); + + if (!info) + info = g_flags_get_value_by_nick(fclass, str); + if (info) { + *val = info->value; + res = 0; + } else { + PyErr_SetString(PyExc_TypeError, "could not convert string"); + res = -1; + } + } else if (PyTuple_Check(obj)) { + int i, len; + + len = PyTuple_Size(obj); + *val = 0; + res = 0; + + if (flag_type != G_TYPE_NONE) + fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); + else { + PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); + res = -1; + } + + for (i = 0; i < len; i++) { + PyObject *item = PyTuple_GetItem(obj, i); + char *str = PYGLIB_PyUnicode_AsString(item); + GFlagsValue *info = g_flags_get_value_by_name(fclass, str); + + if (!info) + info = g_flags_get_value_by_nick(fclass, str); + if (info) { + *val |= info->value; + } else { + PyErr_SetString(PyExc_TypeError, "could not convert string"); + res = -1; + break; + } + } + g_type_class_unref(fclass); + } else { + PyErr_SetString(PyExc_TypeError, + "flag values must be strings, ints, longs, or tuples"); + res = -1; + } + return res; +} + +static GQuark pyg_type_marshal_key = 0; + +PyGTypeMarshal * +pyg_type_lookup(GType type) +{ + GType ptype = type; + PyGTypeMarshal *tm = NULL; + + /* recursively lookup types */ + while (ptype) { + if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL) + break; + ptype = g_type_parent(ptype); + } + return tm; +} + +/** + * pyg_register_gtype_custom: + * @gtype: the GType for the new type + * @from_func: a function to convert GValues to Python objects + * @to_func: a function to convert Python objects to GValues + * + * In order to handle specific conversion of gboxed types or new + * fundamental types, you may use this function to register conversion + * handlers. + */ + +void +pyg_register_gtype_custom(GType gtype, + fromvaluefunc from_func, + tovaluefunc to_func) +{ + PyGTypeMarshal *tm; + + if (!pyg_type_marshal_key) + pyg_type_marshal_key = g_quark_from_static_string("PyGType::marshal"); + + tm = g_new(PyGTypeMarshal, 1); + tm->fromvalue = from_func; + tm->tovalue = to_func; + g_type_set_qdata(gtype, pyg_type_marshal_key, tm); +} + +/* -------------- PyGClosure ----------------- */ + +static void +pyg_closure_invalidate(gpointer data, GClosure *closure) +{ + PyGClosure *pc = (PyGClosure *)closure; + PyGILState_STATE state; + + state = pyglib_gil_state_ensure(); + Py_XDECREF(pc->callback); + Py_XDECREF(pc->extra_args); + Py_XDECREF(pc->swap_data); + pyglib_gil_state_release(state); + + pc->callback = NULL; + pc->extra_args = NULL; + pc->swap_data = NULL; +} + +static void +pyg_closure_marshal(GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + PyGILState_STATE state; + PyGClosure *pc = (PyGClosure *)closure; + PyObject *params, *ret; + guint i; + + state = pyglib_gil_state_ensure(); + + /* construct Python tuple for the parameter values */ + params = PyTuple_New(n_param_values); + for (i = 0; i < n_param_values; i++) { + /* swap in a different initial data for connect_object() */ + if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) { + g_return_if_fail(pc->swap_data != NULL); + Py_INCREF(pc->swap_data); + PyTuple_SetItem(params, 0, pc->swap_data); + } else { + PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); + + /* error condition */ + if (!item) { + goto out; + } + PyTuple_SetItem(params, i, item); + } + } + /* params passed to function may have extra arguments */ + if (pc->extra_args) { + PyObject *tuple = params; + params = PySequence_Concat(tuple, pc->extra_args); + Py_DECREF(tuple); + } + ret = PyObject_CallObject(pc->callback, params); + if (ret == NULL) { + if (pc->exception_handler) + pc->exception_handler(return_value, n_param_values, param_values); + else + PyErr_Print(); + goto out; + } + + if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { + /* If we already have an exception set, use that, otherwise set a + * generic one */ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "can't convert return value to desired type"); + + if (pc->exception_handler) + pc->exception_handler(return_value, n_param_values, param_values); + else + PyErr_Print(); + } + Py_DECREF(ret); + + out: + Py_DECREF(params); + pyglib_gil_state_release(state); +} + +/** + * pyg_closure_new: + * callback: a Python callable object + * extra_args: a tuple of extra arguments, or None/NULL. + * swap_data: an alternative python object to pass first. + * + * Creates a GClosure wrapping a Python callable and optionally a set + * of additional function arguments. This is needed to attach python + * handlers to signals, for instance. + * + * Returns: the new closure. + */ +GClosure * +pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data) +{ + GClosure *closure; + + g_return_val_if_fail(callback != NULL, NULL); + closure = g_closure_new_simple(sizeof(PyGClosure), NULL); + g_closure_add_invalidate_notifier(closure, NULL, pyg_closure_invalidate); + g_closure_set_marshal(closure, pyg_closure_marshal); + Py_INCREF(callback); + ((PyGClosure *)closure)->callback = callback; + if (extra_args && extra_args != Py_None) { + Py_INCREF(extra_args); + if (!PyTuple_Check(extra_args)) { + PyObject *tmp = PyTuple_New(1); + PyTuple_SetItem(tmp, 0, extra_args); + extra_args = tmp; + } + ((PyGClosure *)closure)->extra_args = extra_args; + } + if (swap_data) { + Py_INCREF(swap_data); + ((PyGClosure *)closure)->swap_data = swap_data; + closure->derivative_flag = TRUE; + } + return closure; +} + +/** + * pyg_closure_set_exception_handler: + * @closure: a closure created with pyg_closure_new() + * @handler: the handler to call when an exception occurs or NULL for none + * + * Sets the handler to call when an exception occurs during closure invocation. + * The handler is responsible for providing a proper return value to the + * closure invocation. If @handler is %NULL, the default handler will be used. + * The default handler prints the exception to stderr and doesn't touch the + * closure's return value. + */ +void +pyg_closure_set_exception_handler(GClosure *closure, + PyClosureExceptionHandler handler) +{ + PyGClosure *pygclosure; + + g_return_if_fail(closure != NULL); + + pygclosure = (PyGClosure *)closure; + pygclosure->exception_handler = handler; +} +/* -------------- PySignalClassClosure ----------------- */ +/* a closure used for the `class closure' of a signal. As this gets + * all the info from the first argument to the closure and the + * invocation hint, we can have a single closure that handles all + * class closure cases. We call a method by the name of the signal + * with "do_" prepended. + * + * We also remove the first argument from the * param list, as it is + * the instance object, which is passed * implicitly to the method + * object. */ + +static void +pyg_signal_class_closure_marshal(GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + PyGILState_STATE state; + GObject *object; + PyObject *object_wrapper; + GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint; + gchar *method_name, *tmp; + PyObject *method; + PyObject *params, *ret; + guint i, len; + + state = pyglib_gil_state_ensure(); + + g_return_if_fail(invocation_hint != NULL); + /* get the object passed as the first argument to the closure */ + object = g_value_get_object(¶m_values[0]); + g_return_if_fail(object != NULL && G_IS_OBJECT(object)); + + /* get the wrapper for this object */ + object_wrapper = pygobject_new(object); + g_return_if_fail(object_wrapper != NULL); + + /* construct method name for this class closure */ + method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL); + + /* convert dashes to underscores. For some reason, g_signal_name + * seems to convert all the underscores in the signal name to + dashes??? */ + for (tmp = method_name; *tmp != '\0'; tmp++) + if (*tmp == '-') *tmp = '_'; + + method = PyObject_GetAttrString(object_wrapper, method_name); + g_free(method_name); + + if (!method) { + PyErr_Clear(); + Py_DECREF(object_wrapper); + pyglib_gil_state_release(state); + return; + } + Py_DECREF(object_wrapper); + + /* construct Python tuple for the parameter values; don't copy boxed values + initially because we'll check after the call to see if a copy is needed. */ + params = PyTuple_New(n_param_values - 1); + for (i = 1; i < n_param_values; i++) { + PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); + + /* error condition */ + if (!item) { + Py_DECREF(params); + pyglib_gil_state_release(state); + return; + } + PyTuple_SetItem(params, i - 1, item); + } + + ret = PyObject_CallObject(method, params); + + /* Copy boxed values if others ref them, this needs to be done regardless of + exception status. */ + len = PyTuple_Size(params); + for (i = 0; i < len; i++) { + PyObject *item = PyTuple_GetItem(params, i); + if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type) + && item->ob_refcnt != 1) { + PyGBoxed* boxed_item = (PyGBoxed*)item; + if (!boxed_item->free_on_dealloc) { + boxed_item->boxed = g_boxed_copy(boxed_item->gtype, boxed_item->boxed); + boxed_item->free_on_dealloc = TRUE; + } + } + } + + if (ret == NULL) { + PyErr_Print(); + Py_DECREF(method); + Py_DECREF(params); + pyglib_gil_state_release(state); + return; + } + Py_DECREF(method); + Py_DECREF(params); + if (G_IS_VALUE(return_value)) + pyg_value_from_pyobject(return_value, ret); + Py_DECREF(ret); + pyglib_gil_state_release(state); +} + +/** + * pyg_signal_class_closure_get: + * + * Returns the GClosure used for the class closure of signals. When + * called, it will invoke the method do_signalname (for the signal + * "signalname"). + * + * Returns: the closure. + */ +GClosure * +pyg_signal_class_closure_get(void) +{ + static GClosure *closure; + + if (closure == NULL) { + closure = g_closure_new_simple(sizeof(GClosure), NULL); + g_closure_set_marshal(closure, pyg_signal_class_closure_marshal); + + g_closure_ref(closure); + g_closure_sink(closure); + } + return closure; +} + +GClosure * +gclosure_from_pyfunc(PyGObject *object, PyObject *func) +{ + GSList *l; + PyGObjectData *inst_data; + inst_data = pyg_object_peek_inst_data(object->obj); + if (inst_data) { + for (l = inst_data->closures; l; l = l->next) { + PyGClosure *pyclosure = l->data; + int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ); + if (res == -1) { + PyErr_Clear(); // Is there anything else to do? + } else if (res) { + return (GClosure*)pyclosure; + } + } + } + return NULL; +} + +/* ----- __doc__ descriptor for GObject and GInterface ----- */ + +static void +object_doc_dealloc(PyObject *self) +{ + PyObject_FREE(self); +} + +/* append information about signals of a particular gtype */ +static void +add_signal_docs(GType gtype, GString *string) +{ + GTypeClass *class = NULL; + guint *signal_ids, n_ids = 0, i; + + if (G_TYPE_IS_CLASSED(gtype)) + class = g_type_class_ref(gtype); + signal_ids = g_signal_list_ids(gtype, &n_ids); + + if (n_ids > 0) { + g_string_append_printf(string, "Signals from %s:\n", + g_type_name(gtype)); + + for (i = 0; i < n_ids; i++) { + GSignalQuery query; + guint j; + + g_signal_query(signal_ids[i], &query); + + g_string_append(string, " "); + g_string_append(string, query.signal_name); + g_string_append(string, " ("); + for (j = 0; j < query.n_params; j++) { + g_string_append(string, g_type_name(query.param_types[j])); + if (j != query.n_params - 1) + g_string_append(string, ", "); + } + g_string_append(string, ")"); + if (query.return_type && query.return_type != G_TYPE_NONE) { + g_string_append(string, " -> "); + g_string_append(string, g_type_name(query.return_type)); + } + g_string_append(string, "\n"); + } + g_free(signal_ids); + g_string_append(string, "\n"); + } + if (class) + g_type_class_unref(class); +} + +static void +add_property_docs(GType gtype, GString *string) +{ + GObjectClass *class; + GParamSpec **props; + guint n_props = 0, i; + gboolean has_prop = FALSE; + G_CONST_RETURN gchar *blurb=NULL; + + class = g_type_class_ref(gtype); + props = g_object_class_list_properties(class, &n_props); + + for (i = 0; i < n_props; i++) { + if (props[i]->owner_type != gtype) + continue; /* these are from a parent type */ + + /* print out the heading first */ + if (!has_prop) { + g_string_append_printf(string, "Properties from %s:\n", + g_type_name(gtype)); + has_prop = TRUE; + } + g_string_append_printf(string, " %s -> %s: %s\n", + g_param_spec_get_name(props[i]), + g_type_name(props[i]->value_type), + g_param_spec_get_nick(props[i])); + + /* g_string_append_printf crashes on win32 if the third + argument is NULL. */ + blurb=g_param_spec_get_blurb(props[i]); + if (blurb) + g_string_append_printf(string, " %s\n",blurb); + } + g_free(props); + if (has_prop) + g_string_append(string, "\n"); + g_type_class_unref(class); +} + +static PyObject * +object_doc_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + GType gtype = 0; + GString *string; + PyObject *pystring; + + if (obj && pygobject_check(obj, &PyGObject_Type)) { + gtype = G_OBJECT_TYPE(pygobject_get(obj)); + if (!gtype) + PyErr_SetString(PyExc_RuntimeError, "could not get object type"); + } else { + gtype = pyg_type_from_object(type); + } + if (!gtype) + return NULL; + + string = g_string_new_len(NULL, 512); + + if (g_type_is_a(gtype, G_TYPE_INTERFACE)) + g_string_append_printf(string, "Interface %s\n\n", g_type_name(gtype)); + else if (g_type_is_a(gtype, G_TYPE_OBJECT)) + g_string_append_printf(string, "Object %s\n\n", g_type_name(gtype)); + else + g_string_append_printf(string, "%s\n\n", g_type_name(gtype)); + + if (((PyTypeObject *) type)->tp_doc) + g_string_append_printf(string, "%s\n\n", ((PyTypeObject *) type)->tp_doc); + + if (g_type_is_a(gtype, G_TYPE_OBJECT)) { + GType parent = G_TYPE_OBJECT; + GArray *parents = g_array_new(FALSE, FALSE, sizeof(GType)); + int iparent; + + while (parent) { + g_array_append_val(parents, parent); + parent = g_type_next_base(gtype, parent); + } + + for (iparent = parents->len - 1; iparent >= 0; --iparent) { + GType *interfaces; + guint n_interfaces, i; + + parent = g_array_index(parents, GType, iparent); + add_signal_docs(parent, string); + add_property_docs(parent, string); + + /* add docs for implemented interfaces */ + interfaces = g_type_interfaces(parent, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + add_signal_docs(interfaces[i], string); + g_free(interfaces); + } + g_array_free(parents, TRUE); + } + + pystring = PYGLIB_PyUnicode_FromStringAndSize(string->str, string->len); + g_string_free(string, TRUE); + return pystring; +} + +PYGLIB_DEFINE_TYPE("gobject.GObject.__doc__", PyGObjectDoc_Type, PyObject); + +/** + * pyg_object_descr_doc_get: + * + * Returns an object intended to be the __doc__ attribute of GObject + * wrappers. When read in the context of the object it will return + * some documentation about the signals and properties of the object. + * + * Returns: the descriptor. + */ +PyObject * +pyg_object_descr_doc_get(void) +{ + static PyObject *doc_descr = NULL; + + if (!doc_descr) { + Py_TYPE(&PyGObjectDoc_Type) = &PyType_Type; + if (PyType_Ready(&PyGObjectDoc_Type)) + return NULL; + + doc_descr = PyObject_NEW(PyObject, &PyGObjectDoc_Type); + if (doc_descr == NULL) + return NULL; + } + return doc_descr; +} + + +/** + * pyg_pyobj_to_unichar_conv: + * + * Converts PyObject value to a unichar and write result to memory + * pointed to by ptr. Follows the calling convention of a ParseArgs + * converter (O& format specifier) so it may be used to convert function + * arguments. + * + * Returns: 1 if the conversion succeeds and 0 otherwise. If the conversion + * did not succeesd, a Python exception is raised + */ +int pyg_pyobj_to_unichar_conv(PyObject* py_obj, void* ptr) +{ + gunichar* u = ptr; + const Py_UNICODE* uni_buffer; + PyObject* tmp_uni = NULL; + + if (PyUnicode_Check(py_obj)) { + tmp_uni = py_obj; + Py_INCREF(tmp_uni); + } + else { + tmp_uni = PyUnicode_FromObject(py_obj); + if (tmp_uni == NULL) + goto failure; + } + + if ( PyUnicode_GetSize(tmp_uni) != 1) { + PyErr_SetString(PyExc_ValueError, "unicode character value must be 1 character uniode string"); + goto failure; + } + uni_buffer = PyUnicode_AsUnicode(tmp_uni); + if ( uni_buffer == NULL) + goto failure; + *u = uni_buffer[0]; + + Py_DECREF(tmp_uni); + return 1; + + failure: + Py_XDECREF(tmp_uni); + return 0; +} + +gboolean +pyg_gtype_is_custom(GType gtype) +{ + return g_type_get_qdata (gtype, pygobject_custom_key) != NULL; +} + +void +pygobject_type_register_types(PyObject *d) +{ + PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc; + PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare; + PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr; + PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash; + PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGTypeWrapper_Type.tp_methods = _PyGTypeWrapper_methods; + PyGTypeWrapper_Type.tp_getset = _PyGTypeWrapper_getsets; + PyGTypeWrapper_Type.tp_init = (initproc)pyg_type_wrapper_init; + PYGLIB_REGISTER_TYPE(d, PyGTypeWrapper_Type, "GType"); + + /* This type lazily registered in pyg_object_descr_doc_get */ + PyGObjectDoc_Type.tp_dealloc = (destructor)object_doc_dealloc; + PyGObjectDoc_Type.tp_flags = Py_TPFLAGS_DEFAULT; + PyGObjectDoc_Type.tp_descr_get = (descrgetfunc)object_doc_descr_get; + + pyg_register_gtype_custom(G_TYPE_STRV, + pyg_strv_from_gvalue, + pyg_strv_to_gvalue); +} diff --git a/gi/pygtype.h b/gi/pygtype.h new file mode 100644 index 0000000..204c146 --- /dev/null +++ b/gi/pygtype.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * 2004-2008 Johan Dahlin + * pyginterface.c: wrapper for the gobject library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + */ + +#ifndef __PYGOBJECT_TYPE_H__ +#define __PYGOBJECT_TYPE_H__ + +#include +#include + +typedef PyObject *(* fromvaluefunc)(const GValue *value); +typedef int (*tovaluefunc)(GValue *value, PyObject *obj); + +typedef struct { + fromvaluefunc fromvalue; + tovaluefunc tovalue; +} PyGTypeMarshal; + +PyGTypeMarshal *pyg_type_lookup(GType type); + +void pyg_register_gtype_custom(GType gtype, + fromvaluefunc from_func, + tovaluefunc to_func); + +void pygobject_type_register_types(PyObject *d); + +#endif /* __PYGOBJECT_TYPE_H__ */ diff --git a/gi/types.py b/gi/types.py index 41efc05..4f0d76e 100644 --- a/gi/types.py +++ b/gi/types.py @@ -25,9 +25,7 @@ from __future__ import absolute_import import sys import warnings -from . import _gobject -from ._gobject._gobject import GInterface -from ._gobject.constants import TYPE_INVALID +from ._constants import TYPE_INVALID from .docstring import generate_doc_string from ._gi import \ @@ -36,11 +34,16 @@ from ._gi import \ StructInfo, \ VFuncInfo, \ register_interface_info, \ - hook_up_vfunc_implementation + hook_up_vfunc_implementation, \ + _gobject +GInterface = _gobject.GInterface StructInfo # pyflakes +from . import _propertyhelper as propertyhelper +from . import _signalhelper as signalhelper + if (3, 0) <= sys.version_info < (3, 3): # callable not available for python 3.0 thru 3.2 def callable(obj): @@ -170,7 +173,30 @@ def find_vfunc_conflict_in_bases(vfunc, bases): return None -class GObjectMeta(_gobject.GObjectMeta, MetaClassHelper): +class _GObjectMetaBase(type): + "Metaclass for automatically registering GObject classes" + def __init__(cls, name, bases, dict_): + type.__init__(cls, name, bases, dict_) + propertyhelper.install_properties(cls) + signalhelper.install_signals(cls) + cls._type_register(cls.__dict__) + + def _type_register(cls, namespace): + ## don't register the class if already registered + if '__gtype__' in namespace: + return + + # Do not register a new GType for the overrides, as this would sort of + # defeat the purpose of overrides... + if cls.__module__.startswith('gi.overrides.'): + return + + _gobject.type_register(cls, namespace.get('__gtype_name__')) + +_gobject._install_metaclass(_GObjectMetaBase) + + +class GObjectMeta(_GObjectMetaBase, MetaClassHelper): def __init__(cls, name, bases, dict_): super(GObjectMeta, cls).__init__(name, bases, dict_) diff --git a/pygtkcompat/pygtkcompat.py b/pygtkcompat/pygtkcompat.py index 67571ac..d5b7b94 100644 --- a/pygtkcompat/pygtkcompat.py +++ b/pygtkcompat/pygtkcompat.py @@ -90,8 +90,8 @@ def enable(): # gobject from gi.repository import GObject sys.modules['gobject'] = GObject - from gi._gobject import propertyhelper - sys.modules['gobject.propertyhelper'] = propertyhelper + from gi import _propertyhelper + sys.modules['gobject.propertyhelper'] = _propertyhelper # gio from gi.repository import Gio diff --git a/tests/Makefile.am b/tests/Makefile.am index a7b0323..d69bbad 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -54,7 +54,7 @@ CLEANFILES += Regress-1.0.gir Regress-1.0.typelib GIMarshallingTests-1.0.gir GIM check_LTLIBRARIES += testhelper.la -testhelper_la_CFLAGS = -I$(top_srcdir)/gi/_gobject -I$(top_srcdir)/gi/_glib $(PYTHON_INCLUDES) $(GLIB_CFLAGS) +testhelper_la_CFLAGS = -I$(top_srcdir)/gi $(PYTHON_INCLUDES) $(GLIB_CFLAGS) testhelper_la_LDFLAGS = -module -avoid-version testhelper_la_LIBADD = $(GLIB_LIBS) testhelper_la_SOURCES = \ @@ -134,12 +134,6 @@ RUN_TESTS_ENV_VARS= \ # pygtkcompat tests need to be run in a separate process as they # clobber global name space check-local: $(check_LTLIBRARIES:.la=.so) $(test_typelibs) gschemas.compiled - @echo " CHECK Pyflakes" - @if type pyflakes >/dev/null 2>&1; then pyflakes $(top_srcdir); else echo "skipped, pyflakes not installed"; fi - @if test -z "$$SKIP_PEP8"; then \ - echo " CHECK PEP8"; \ - if type pep8 >/dev/null 2>&1; then pep8 --ignore=E501,E123,E124 --repeat --show-source $(top_srcdir); else echo "skipped, pep8 not installed"; fi; \ - fi export `$(DBUS_LAUNCH)` && \ $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd $(srcdir)/runtests.py; rc=$$?; \ [ "$$rc" -ne 0 ] || [ -n "$$TEST_NAMES" ] || { TEST_NAMES=compat_test_pygtk $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd -Werror::PendingDeprecationWarning -Werror::DeprecationWarning -Werror::RuntimeWarning $(srcdir)/runtests.py; rc=$$?; }; \ @@ -153,12 +147,12 @@ check.nemiver: EXEC_NAME="nemiver" $(MAKE) check check.valgrind: - EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check check.valgrindlog: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check check.valgrindxml: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check diff --git a/tests/Makefile.in b/tests/Makefile.in index b034f67..d5b1610 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -311,7 +311,7 @@ libgimarshallingtests_la_LDFLAGS = -module -avoid-version $(GLIB_LIBS) @ENABLE_CAIRO_TRUE@nodist_libregress_la_SOURCES = $(GI_DATADIR)/tests/regress.c $(GI_DATADIR)/tests/regress.h @ENABLE_CAIRO_TRUE@libregress_la_CFLAGS = $(GIO_CFLAGS) $(CAIRO_CFLAGS) @ENABLE_CAIRO_TRUE@libregress_la_LDFLAGS = -module -avoid-version $(GIO_LIBS) $(CAIRO_LIBS) -testhelper_la_CFLAGS = -I$(top_srcdir)/gi/_gobject -I$(top_srcdir)/gi/_glib $(PYTHON_INCLUDES) $(GLIB_CFLAGS) +testhelper_la_CFLAGS = -I$(top_srcdir)/gi $(PYTHON_INCLUDES) $(GLIB_CFLAGS) testhelper_la_LDFLAGS = -module -avoid-version testhelper_la_LIBADD = $(GLIB_LIBS) testhelper_la_SOURCES = \ @@ -757,12 +757,6 @@ clean-local: # pygtkcompat tests need to be run in a separate process as they # clobber global name space check-local: $(check_LTLIBRARIES:.la=.so) $(test_typelibs) gschemas.compiled - @echo " CHECK Pyflakes" - @if type pyflakes >/dev/null 2>&1; then pyflakes $(top_srcdir); else echo "skipped, pyflakes not installed"; fi - @if test -z "$$SKIP_PEP8"; then \ - echo " CHECK PEP8"; \ - if type pep8 >/dev/null 2>&1; then pep8 --ignore=E501,E123,E124 --repeat --show-source $(top_srcdir); else echo "skipped, pep8 not installed"; fi; \ - fi export `$(DBUS_LAUNCH)` && \ $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd $(srcdir)/runtests.py; rc=$$?; \ [ "$$rc" -ne 0 ] || [ -n "$$TEST_NAMES" ] || { TEST_NAMES=compat_test_pygtk $(RUN_TESTS_ENV_VARS) $(EXEC_NAME) $(PYTHON) -Wd -Werror::PendingDeprecationWarning -Werror::DeprecationWarning -Werror::RuntimeWarning $(srcdir)/runtests.py; rc=$$?; }; \ @@ -776,15 +770,15 @@ check.nemiver: EXEC_NAME="nemiver" $(MAKE) check check.valgrind: - EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check check.valgrindlog: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check check.valgrindxml: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=python.supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc valgrind --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/tests/test_everything.py b/tests/test_everything.py index 61b40e1..0cd1804 100644 --- a/tests/test_everything.py +++ b/tests/test_everything.py @@ -761,6 +761,54 @@ class TestCallbacks(unittest.TestCase): self.assertEqual(TestCallbacks.called, 10) self.assertSequenceEqual(collected_user_data, [1, 2] * 10) + def test_callback_user_data_middle_none(self): + cb_info = {} + + def callback(userdata): + cb_info['called'] = True + cb_info['userdata'] = userdata + return 1 + + (y, z, q) = Everything.test_torture_signature_2( + 42, callback, None, 'some string', 3) + self.assertEqual(y, 42) + self.assertEqual(z, 84) + self.assertEqual(q, 14) + self.assertTrue(cb_info['called']) + self.assertEqual(cb_info['userdata'], None) + + def test_callback_user_data_middle_single(self): + cb_info = {} + + def callback(userdata): + cb_info['called'] = True + cb_info['userdata'] = userdata + return 1 + + (y, z, q) = Everything.test_torture_signature_2( + 42, callback, 'User Data', 'some string', 3) + self.assertEqual(y, 42) + self.assertEqual(z, 84) + self.assertEqual(q, 14) + self.assertTrue(cb_info['called']) + self.assertEqual(cb_info['userdata'], 'User Data') + + def test_callback_user_data_middle_tuple(self): + cb_info = {} + + def callback(userdata): + cb_info['called'] = True + cb_info['userdata'] = userdata + return 1 + + (y, z, q) = Everything.test_torture_signature_2( + 42, callback, (-5, 'User Data'), 'some string', 3) + self.assertEqual(y, 42) + self.assertEqual(z, 84) + self.assertEqual(q, 14) + self.assertTrue(cb_info['called']) + self.assertEqual(cb_info['userdata'], (-5, 'User Data')) + def test_async_ready_callback(self): TestCallbacks.called = False TestCallbacks.main_loop = GLib.MainLoop() @@ -1138,7 +1186,7 @@ class TestTortureProfile(unittest.TestCase): sys.stdout.write("\ttorture test 4 (10000 iterations): ") def callback(userdata): - pass + return 0 userdata = [1, 2, 3, 4] start_time = time.clock() diff --git a/tests/test_gi.py b/tests/test_gi.py index 2411a49..2a6cc3d 100644 --- a/tests/test_gi.py +++ b/tests/test_gi.py @@ -2266,6 +2266,20 @@ class TestPythonGObject(unittest.TestCase): obj = self.ErrorObject() self.assertEqual(obj.vfunc_return_value_only(), 0) + @unittest.skipUnless(hasattr(GIMarshallingTests, 'callback_owned_boxed'), + 'requires newer version of GI') + @unittest.expectedFailure # bug 722899 + def test_callback_owned_box(self): + def callback(box, data): + self.box = box + + def nop_callback(box, data): + pass + + GIMarshallingTests.callback_owned_boxed(callback, None) + GIMarshallingTests.callback_owned_boxed(nop_callback, None) + self.assertEqual(self.box.long_, 1) + class TestMultiOutputArgs(unittest.TestCase): @@ -2406,7 +2420,7 @@ class TestMRO(unittest.TestCase): pass expected = (E, D, B, C, A, GIMarshallingTests.Object, - GObject.Object, GObject.Object.__base__, gi._gobject.GObject, + GObject.Object, GObject.Object.__base__, gi._gi._gobject.GObject, object) self.assertEqual(expected, E.__mro__) diff --git a/tests/test_gobject.py b/tests/test_gobject.py index d49011f..a88a4bc 100644 --- a/tests/test_gobject.py +++ b/tests/test_gobject.py @@ -8,7 +8,9 @@ import warnings from gi.repository import GObject, GLib from gi import PyGIDeprecationWarning from gi.module import get_introspection_module -from gi._gobject import _gobject + +import gi +_gobject = gi._gi._gobject import testhelper diff --git a/tests/test_properties.py b/tests/test_properties.py index ef6b867..d7ceb89 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -23,7 +23,7 @@ from gi.repository import Gio from gi.repository import GLib from gi.repository import Regress from gi.repository import GIMarshallingTests -from gi._gobject import propertyhelper +from gi import _propertyhelper as propertyhelper if sys.version_info < (3, 0): TEST_UTF8 = "\xe2\x99\xa5" diff --git a/tests/test_signal.py b/tests/test_signal.py index e90264a..429afc9 100644 --- a/tests/test_signal.py +++ b/tests/test_signal.py @@ -5,7 +5,7 @@ import unittest import sys from gi.repository import GObject, GLib -from gi._gobject import signalhelper +from gi import _signalhelper as signalhelper import testhelper from compathelper import _long diff --git a/tests/test_source.py b/tests/test_source.py index 6f69927..e0910f9 100644 --- a/tests/test_source.py +++ b/tests/test_source.py @@ -220,6 +220,51 @@ class TestSource(unittest.TestCase): del source self.assertTrue(self.finalized) + @unittest.skip('https://bugzilla.gnome.org/show_bug.cgi?id=722387') + def test_python_unref_with_active_source(self): + # Tests a Python derived Source which is free'd in the context of + # Python, but remains active in the MainContext (via source.attach()) + self.dispatched = False + self.finalized = False + + class S(GLib.Source): + def prepare(s): + return (True, 1) + + def check(s): + pass + + def dispatch(s, callback, args): + self.dispatched = True + return False + + def finalize(s): + self.finalized = True + + source = S() + id = source.attach() + self.assertFalse(self.finalized) + self.assertFalse(source.is_destroyed()) + + # Delete the source from Python but should still remain + # active in the main context. + del source + + context = GLib.MainContext.default() + while context.iteration(may_block=False): + pass + + self.assertTrue(self.dispatched) + self.assertFalse(self.finalized) + + source = context.find_source_by_id(id) + source.destroy() # Remove from main context. + self.assertTrue(source.is_destroyed()) + + # Source should be finalized called after del + del source + self.assertTrue(self.finalized) + def test_extra_init_args(self): class SourceWithInitArgs(GLib.Source): def __init__(self, arg, kwarg=None):