Imported Upstream version 3.13.2 65/138265/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:41:54 +0000 (08:41 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 11 Jul 2017 23:41:58 +0000 (08:41 +0900)
Change-Id: Icce9be2c1bf0568fc95f75ff0a714c017e6171ec
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
72 files changed:
ChangeLog
Makefile.am
Makefile.in
NEWS
PKG-INFO
configure
configure.ac
gi/Makefile.am
gi/Makefile.in
gi/__init__.py
gi/_error.py [new file with mode: 0644]
gi/_option.py
gi/gimodule.c
gi/glibmodule.c
gi/gobjectmodule.c
gi/overrides/GIMarshallingTests.py
gi/overrides/GLib.py
gi/overrides/Gio.py
gi/overrides/Gtk.py
gi/pygboxed.c
gi/pygenum.c
gi/pygflags.c
gi/pygi-argument.c
gi/pygi-array.c
gi/pygi-boxed.c
gi/pygi-cache.c
gi/pygi-error.c
gi/pygi-error.h
gi/pygi-foreign-api.h [new file with mode: 0644]
gi/pygi-foreign-cairo.c
gi/pygi-foreign.c
gi/pygi-foreign.h
gi/pygi-info.c
gi/pygi-invoke.c
gi/pygi-property.c
gi/pygi-property.h
gi/pygi-signal-closure.c
gi/pygi-signal-closure.h
gi/pygi-struct-marshal.c
gi/pygi-struct-marshal.h
gi/pygi-struct.c
gi/pygi-type.c
gi/pygi-type.h
gi/pygi-value.c
gi/pygi.h
gi/pyglib-private.h
gi/pyglib.c
gi/pyglib.h
gi/pygobject-private.h
gi/pygobject.c
gi/pygobject.h
gi/pygoptioncontext.c
gi/pygoptiongroup.c
gi/pygparamspec.c
gi/pygpointer.c
gi/pygspawn.c
gi/pygtype.c
gi/types.py
pygtkcompat/pygtkcompat.py
tests/Makefile.am
tests/Makefile.in
tests/test_cairo.py [new file with mode: 0644]
tests/test_error.py [new file with mode: 0644]
tests/test_everything.py
tests/test_gi.py
tests/test_gio.py
tests/test_iochannel.py
tests/test_option.py
tests/test_overrides_gtk.py
tests/test_repository.py
tests/test_signal.py
tests/test_typeclass.py [new file with mode: 0644]

index fc22733..1998f37 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,525 @@
+commit 32542a4ba24d413fb6e0d509bff05f4ac3f642a1
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon May 26 03:01:13 2014 -0700
+
+    Python 3.4 make check fixes
+
+    Bump GI required version to 1.39.0. This is needed to get rid of
+    expectedFailures which pass when built with 1.39.0 (unexpected
+    successes
+    fail unittesting in Python 3.4).
+    Silence deprecation warning when using imp.reload.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=730411
+
+ configure.ac               | 2 +-
+ pygtkcompat/pygtkcompat.py | 4 +++-
+ tests/test_gi.py           | 1 -
+ tests/test_repository.py   | 2 --
+ 4 files changed, 4 insertions(+), 5 deletions(-)
+
+commit dbdc662b5743bb54fcc3621db775a6e948ec360c
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon May 26 01:53:14 2014 -0700
+
+    tests: Don't use deprecated positional argument for Gio.Settings
+    schema
+
+ tests/test_gio.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d0b23f08eebd4377f066a4483900fe6d09e3795e
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 25 23:03:35 2014 -0700
+
+    overrides: Add Gtk.Container.child_get/set overrides
+
+    Add overrides for child_get and child_set to Gtk.Container since these
+    are not introspectable methods.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685076
+
+ gi/overrides/Gtk.py         | 10 ++++++++++
+ tests/test_overrides_gtk.py | 16 ++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+commit 45a5fb2b0d6c7f46d355c83c73d829532e5a72ce
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 25 22:07:07 2014 -0700
+
+    overrides: Make value argument to Widget.style_get_property optional
+
+    Override Gtk.Widget.style_get_property to optionally accept the
+    "value"
+    argument. If "value" is not supplied, the override will locate
+    the child
+    property value type and create the GValue. Additionally return
+    the resulting
+    GValue converted to a native Python value.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685076
+
+ gi/overrides/Gtk.py         | 11 +++++++++++
+ tests/test_overrides_gtk.py | 29 +++++++++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+
+commit 6f5a9a37bcdec5074332b1066396321d40b15d99
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 25 21:08:47 2014 -0700
+
+    overrides: Make value argument to Container.child_get_property
+    optional
+
+    Override Gtk.Container.child_get_property to optionally accept the
+    "value"
+    argument. If "value" is not supplied, the override will locate
+    the child
+    property value type and create the GValue. Additionally return
+    the resulting
+    GValue converted to a native Python value.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685076
+
+ gi/overrides/Gtk.py         | 11 +++++++++++
+ tests/test_overrides_gtk.py | 47
+ +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 58 insertions(+)
+
+commit bf84915f89fd5fd502b4fb162eef7bc0a48c8783
+Author: Johan Dahlin <johan@gnome.org>
+Date:   Mon Oct 1 06:42:24 2012 -0700
+
+    Add GTypeClass methods as Python GObject class methods
+
+    Take all the methods from an objects type classs and add them
+    as class methods. For instance, GObject.ObjectClass.list_properties
+    is available as GObject.Object.list_properties().
+
+    Co-Authored-By: Simon Feltman <sfeltman@src.gnome.org>
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685218
+
+ gi/types.py             | 13 +++++++++++++
+ tests/test_typeclass.py | 13 +++++++++++++
+ 2 files changed, 26 insertions(+)
+
+commit 778d05c93e079ba207a250b754bda9377cb47457
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 25 19:05:56 2014 -0700
+
+    Add marshalling coercion for Python classes and instances to
+    GTypeClass
+
+    Automatically marshal Python GObject classes and instances to
+    GTypeClass
+    structs (GObjectClass). This allows usage of the GTypeClass methods by
+    passing a Python GObject class or instance to the GTypeClass method.
+    This is needed to support usage of GTypeClass methods since we don't
+    manually bind GTypeClasses and they are not very well supported with
+    introspection.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685218
+
+ gi/pygi-struct-marshal.c | 54 ++++++++++++++++++++++++++++++++++----
+ tests/Makefile.am        |  1 +
+ tests/test_typeclass.py  | 67
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 117 insertions(+), 5 deletions(-)
+
+commit 1e606287e1244cba45e3bb174d27f1c01e4f9577
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 25 02:00:00 2014 -0700
+
+    Cleanup struct marshalling function names
+
+    Use a consistent naming scheme for struct marshalling cache related
+    functions. This removes prefixed underscores from function names
+    as well as redundant wording.
+
+    To ignore this commit with git blame use:
+      git blame <this-commit-sha>^ -- gi/pygi-struct-marshal.c
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=685218
+
+ gi/pygi-argument.c       |  34 ++++----
+ gi/pygi-array.c          |   2 +-
+ gi/pygi-struct-marshal.c | 221
+ ++++++++++++++++++++---------------------------
+ gi/pygi-struct-marshal.h |  56 ++++++------
+ 4 files changed, 142 insertions(+), 171 deletions(-)
+
+commit bbbfa967d06eb8fdef6d6ebe705cc8df2869ddf3
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Fri May 16 15:08:35 2014 -0700
+
+    Use accessors for getting and setting PyGParamSpec pointers
+
+    Add pyg_param_spec_get and pyg_param_spec_set macros for getting and
+    setting the GParamSpec pointer field held by the Python wrapper. This
+    is preliminary cleanup work for supporting fundamental types.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=631901
+
+ gi/pygi-value.c   |  2 +-
+ gi/pygobject.h    |  9 +++++++--
+ gi/pygparamspec.c | 22 +++++++++++-----------
+ 3 files changed, 19 insertions(+), 14 deletions(-)
+
+commit b49179ba3b39576c0c8fe8586b7091dbbaef8046
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Fri May 16 14:50:57 2014 -0700
+
+    Use accessors for getting and setting PyGPointer fields
+
+    Add pyg_pointer_get_ptr and pyg_pointer_set_ptr macros for getting and
+    setting the pointer field. This is preliminary cleanup work for
+    supporting
+    fundamental types.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=631901
+
+ gi/gimodule.c    |  2 +-
+ gi/pygi-struct.c |  6 +++---
+ gi/pygobject.h   |  2 ++
+ gi/pygpointer.c  | 14 +++++++-------
+ 4 files changed, 13 insertions(+), 11 deletions(-)
+
+commit 92fe52243d819ffe91597744a6a1c2362a295bce
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Fri May 16 14:19:47 2014 -0700
+
+    Use accessors for getting and setting PyGBoxed pointers
+
+    Add pyg_boxed_get_ptr and pyg_boxed_set_ptr macros for getting
+    and setting
+    the boxed pointer field. This is preliminary cleanup work for
+    supporting
+    fundamental types.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=631901
+
+ gi/pygboxed.c   | 20 ++++++++++----------
+ gi/pygi-boxed.c |  6 +++---
+ gi/pygobject.h  |  2 ++
+ gi/pygtype.c    |  3 ++-
+ 4 files changed, 17 insertions(+), 14 deletions(-)
+
+commit 0a4f13a571cb9bd110f435f8b23ed942e3b007b0
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 11 16:04:55 2014 -0700
+
+    tests: Use assertRaises as a context manager for GError test
+
+    Simplify tests/test_error.py:TestMarshalling.test_exception so that
+    it no longer needs to pull exception information out of sys.exc_info.
+
+ tests/test_error.py | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit bc7b0b69f651a118a053106fcae2d7c0f2173430
+Author: Andrew Grigorev <andrew@ei-grad.ru>
+Date:   Sun May 11 23:54:46 2014 +0400
+
+    Replace direct parent class call by super()
+
+    Super works, it just needs the correct class.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=729970
+
+ demos/gtk-demo/gtk-demo.py | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit de827d00762f2a741f90bc38f8b55518593f4509
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun Mar 23 01:59:00 2014 -0700
+
+    Add cairo marshaling support for non-introspected signals
+
+    Add link dependency of cairo-gobject to _gi_cairo_la needed for
+    retrieving
+    the GTypes of cairo classes.
+    Add GValue marshalers for cairo Context, Surface, FontFace,
+    ScaledFont,
+    and Pattern classes.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=694604
+
+ gi/Makefile.am          |   2 +
+ gi/pygi-foreign-cairo.c | 186
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ gi/pygi-type.h          |   1 +
+ gi/pygtype.c            |   2 +
+ tests/test_cairo.py     |  65 +++++++++++++++++
+ 5 files changed, 256 insertions(+)
+
+commit 22a952ec532cc83c8227861a7d5bfa2957608c3f
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon May 5 19:37:18 2014 -0700
+
+    [New API] Add gi.require_foreign
+
+    Add gi.require_foreign(namespace, symbol=None) API for determining
+    if a foreign marshaling module is available. This can be used in an
+    applications import statement block to verify the existence of a
+    specific foreign marshaling module (cairo).
+    Additionally it forces loading of the foreign marshaling module as
+    well as the GI repository module. This allows non-introspected signal
+    closures to correctly marshal their arguments (bug 694604).
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=707735
+
+ gi/__init__.py      | 28 +++++++++++++++++++++++++
+ gi/gimodule.c       |  2 ++
+ gi/pygi-foreign.c   | 60
+ ++++++++++++++++++++++++++++++++++++++++++++++-------
+ gi/pygi-foreign.h   |  4 ++++
+ tests/test_cairo.py |  9 ++++++++
+ 5 files changed, 95 insertions(+), 8 deletions(-)
+
+commit 4ee91a4cd0018d069c7aaf66d83e2f8235f2262a
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon May 5 19:48:06 2014 -0700
+
+    tests: Move cairo tests into test_cairo.py
+
+    Move cairo related tests from test_everything.py into test_cairo.py
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=694604
+
+ tests/Makefile.am        |  1 +
+ tests/test_cairo.py      | 67
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ tests/test_everything.py | 43 +------------------------------
+ 3 files changed, 69 insertions(+), 42 deletions(-)
+
+commit 31ecd935564984068e6646676392122bdc03e42e
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon May 5 19:42:59 2014 -0700
+
+    Initialize the foreign API at PyGI load time
+
+    Initialize the foreign struct list at gi._gi module load time. This
+    ensures
+    we always have a valid (non-null) list of foreign marshalers outside
+    of the
+    context of marshaling.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=694604
+
+ gi/gimodule.c     |  3 ++-
+ gi/pygi-foreign.c | 12 ++++++++----
+ gi/pygi-foreign.h |  2 ++
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+commit def47144b63a1492ebf47a4eadb535f45253ff3a
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sat Mar 22 14:13:01 2014 -0700
+
+    Move pygi foreign API into pygi-foreign-api.h
+
+    Move limited set of APIs necessary for registering foreign marshalers
+    into
+    pygi-foreign-api.h. Remove "_real" from internally used APIs and
+    add necessary
+    includes to the rest of pygobject for calling directly (instead of
+    going through
+    the PyCapsule API within PyGI itself).
+    This is needed to avoid compilation errors when including pygobject.h
+    in
+    foreign marshaling plugins which conflicts with pygobject-private.h.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=694604
+
+ gi/Makefile.am           |   1 +
+ gi/gimodule.c            |   6 +--
+ gi/pygboxed.c            |   1 +
+ gi/pygenum.c             |   1 +
+ gi/pygflags.c            |   1 +
+ gi/pygi-foreign-api.h    |  85 +++++++++++++++++++++++++++++++++++++
+ gi/pygi-foreign-cairo.c  |   8 ++--
+ gi/pygi-foreign.c        |  10 ++---
+ gi/pygi-foreign.h        |  14 +++----
+ gi/pygi-property.c       |   8 ++--
+ gi/pygi-property.h       |  14 ++++---
+ gi/pygi-signal-closure.c |  12 +++---
+ gi/pygi-signal-closure.h |  15 +++----
+ gi/pygi-type.c           |   4 +-
+ gi/pygi-type.h           |   2 +-
+ gi/pygi.h                | 107
+ -----------------------------------------------
+ gi/pygobject.c           |   3 ++
+ gi/pygpointer.c          |   1 +
+ 18 files changed, 139 insertions(+), 154 deletions(-)
+
+commit 4c2e6914bf0277ebc3a6a4426f33a1b378a04b00
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 4 23:19:30 2014 -0700
+
+    Clobber GLib.Error with custom implementation
+
+    Clobber the introspection GLib.Error class with the custom Python
+    implementation found in gi._error.GError. Update references to
+    GLib.GError
+    to use GLib.Error.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=712519
+
+ gi/_error.py         |  3 ++-
+ gi/overrides/GLib.py |  9 ++++++---
+ gi/pygi-error.c      | 10 +++++-----
+ tests/test_error.py  | 24 ++++++++++++------------
+ 4 files changed, 25 insertions(+), 21 deletions(-)
+
+commit f80f5ec434ed868ab1f35d6a81537384e753b09d
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 4 23:43:50 2014 -0700
+
+    Simplify pygi_error_marshal to use GError initializer arguments
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=712519
+
+ gi/pygi-error.c | 25 ++++++-------------------
+ 1 file changed, 6 insertions(+), 19 deletions(-)
+
+commit 3083daf420ac1900bb20604c22fd61e5187b4ae8
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 4 04:13:46 2014 -0700
+
+    Add Python implementation of GError
+
+    Add internally used gi/_error.py module as a basis for implementing
+    a unified GError between introspection and static bindings. Patch
+    Python
+    implementations of GError.matches and GError.new_literal in the GLib
+    overrides
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=712519
+
+ Makefile.am          |  3 ++-
+ gi/_error.py         | 53
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ gi/_option.py        |  3 ++-
+ gi/overrides/GLib.py | 25 ++++++++++++++++++++++++-
+ gi/pygi-error.c      | 18 +++++++-----------
+ tests/test_error.py  | 37 ++++++++++++++++++++++++++++++++++++
+ 6 files changed, 125 insertions(+), 14 deletions(-)
+
+commit 664bfa6fdf2196a0d1449baaca62a9a496121f67
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 4 23:14:27 2014 -0700
+
+    tests: Move GError tests into test_error.py
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=712519
+
+ tests/Makefile.am   |  1 +
+ tests/test_error.py | 81
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ tests/test_gi.py    | 49 --------------------------------
+ 3 files changed, 82 insertions(+), 49 deletions(-)
+
+commit 649895d83a90cd3a370da215a6f98a606b987419
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sun May 4 00:18:41 2014 -0700
+
+    Consolidate GError related code into pygi-error
+
+    Rename all pyglib_error_* functions to pygi_error_* and move them into
+    pygi-error.[h|c].
+    Register GError as part of the gi._gi module instead of gi._gi._glib.
+    Update all code to use new naming.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=712519
+
+ gi/_option.py          |   6 +-
+ gi/gimodule.c          |   4 +-
+ gi/glibmodule.c        |  19 -----
+ gi/gobjectmodule.c     |  54 +-----------
+ gi/overrides/GLib.py   |   3 +-
+ gi/pygi-argument.c     |   6 +-
+ gi/pygi-cache.c        |   4 +-
+ gi/pygi-error.c        | 222
+ ++++++++++++++++++++++++++++++++++++++++++++++++-
+ gi/pygi-error.h        |  21 ++++-
+ gi/pygi-invoke.c       |   5 +-
+ gi/pyglib-private.h    |   1 -
+ gi/pyglib.c            | 199 --------------------------------------------
+ gi/pyglib.h            |   5 --
+ gi/pygobject-private.h |   3 -
+ gi/pygoptioncontext.c  |   3 +-
+ gi/pygoptiongroup.c    |   3 +-
+ gi/pygspawn.c          |   3 +-
+ 17 files changed, 262 insertions(+), 299 deletions(-)
+
+commit 9080215e862a73ddcce16476f4dc4492a88dd3f2
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sat May 3 22:56:49 2014 -0700
+
+    Add gi.CallableInfo.can_throw_gerror()
+
+    Add static binding for g_callable_info_can_throw_gerror.
+
+ gi/pygi-info.c           | 10 ++++++++++
+ tests/test_repository.py | 16 ++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+commit f129e78d579b7897cb86111c524d87b5b12019ad
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Sat May 3 22:56:03 2014 -0700
+
+    Derive PyCallbackInfo from PyCallableInfo
+
+    Update the static GI bindings for PyGICallbackInfo to derive
+    from PyGICallableInfo. This makes all the gi.CallableInfo methods
+    available to gi.CallbackInfo for use from Python.
+
+ gi/pygi-info.c           | 4 ++--
+ tests/test_repository.py | 7 +++++++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+commit 833f96807037e85445ac103d6fb6ad9c4fab65e4
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Fri May 2 21:36:25 2014 -0700
+
+    PEP8 fixes
+
+    Use infix 'not' instead of prefixed.
+    Don't use double comments (##).
+    Use space between comment and text.
+    Un-comment tests that now work.
+    Move broken (and won't fix) implicit int64 signal tests into
+    a new skipped test function.
+
+ gi/overrides/GIMarshallingTests.py |  4 ++--
+ gi/overrides/Gio.py                |  4 ++--
+ gi/overrides/Gtk.py                |  6 +++---
+ gi/types.py                        |  2 +-
+ pygtkcompat/pygtkcompat.py         |  4 ++--
+ tests/test_everything.py           |  1 -
+ tests/test_gi.py                   |  9 +++------
+ tests/test_iochannel.py            |  2 +-
+ tests/test_option.py               |  2 +-
+ tests/test_signal.py               | 28 +++++++++++++---------------
+ 10 files changed, 28 insertions(+), 34 deletions(-)
+
+commit 07af141dd8dcac551cb2e962f6bf338b3485006b
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon Apr 28 14:06:30 2014 -0700
+
+    configure.ac: post release version bump to 3.13.2
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ba652c1fd9dbef6d3ff57e39b400ea827374a95e
+Author: Simon Feltman <sfeltman@src.gnome.org>
+Date:   Mon Apr 28 14:00:59 2014 -0700
+
+    release 3.13.1
+
+ NEWS | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
 commit 3a2bfc8bf01fcae386355bc3652780e198e54d49
 Author: Christoph Reiter <reiter.christoph@gmail.com>
 Date:   Mon Apr 14 23:33:52 2014 +0200
index 208ed13..968b6c9 100644 (file)
@@ -65,7 +65,8 @@ nobase_pyexec_PYTHON = \
        gi/_constants.py \
        gi/_propertyhelper.py \
        gi/_signalhelper.py \
-       gi/_option.py
+       gi/_option.py \
+       gi/_error.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
index ff37526..dba6bc8 100644 (file)
@@ -463,7 +463,8 @@ nobase_pyexec_PYTHON = \
        gi/_constants.py \
        gi/_propertyhelper.py \
        gi/_signalhelper.py \
-       gi/_option.py
+       gi/_option.py \
+       gi/_error.py
 
 
 # pkg-config files
diff --git a/NEWS b/NEWS
index a7eef2c..81a9090 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,24 @@
+3.13.2  26-May-2014
+        - Python 3.4 make check fixes (Simon Feltman) (#730411)
+        - overrides: Add Gtk.Container.child_get/set overrides (Simon Feltman)
+          (#685076)
+        - overrides: Make value argument to Widget.style_get_property optional
+          (Simon Feltman) (#685076)
+        - overrides: Make value argument to Container.child_get_property optional
+          (Simon Feltman) (#685076)
+        - Add GTypeClass methods as Python GObject class methods
+          (Johan Dahlin) (#685218)
+        - Add marshalling coercion for Python classes and instances to GTypeClass
+          (Simon Feltman) (#685218)
+        - Replace direct parent class call by super() (Andrew Grigorev) (#729970)
+        - Add cairo marshaling support for non-introspected signals
+          (Simon Feltman) (#694604)
+        - [New API] Add gi.require_foreign (Simon Feltman) (#707735)
+        - Initialize the foreign API at PyGI load time (Simon Feltman) (#694604)
+        - Move pygi foreign API into pygi-foreign-api.h (Simon Feltman) (#694604)
+        - Unify GLib.GError and GLib.Error (Simon Feltman) (#712519)
+        - PEP8 fixes (Simon Feltman)
+
 3.13.1  28-Apr-2014
         - Raise TypeError if arguments are passed to Boxed.__init__
           (Christoph Reiter) (#727810)
index f1eca4b..397928c 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: PyGObject
-Version: 3.13.1
+Version: 3.13.2
 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.13/pygobject-3.13.1.tar.gz
+Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.13/pygobject-3.13.2.tar.gz
 Description: Python bindings for GLib and GObject
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
index eca8ab5..c83c26e 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pygobject 3.13.1.
+# Generated by GNU Autoconf 2.69 for pygobject 3.13.2.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='pygobject'
 PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.13.1'
-PACKAGE_STRING='pygobject 3.13.1'
+PACKAGE_VERSION='3.13.2'
+PACKAGE_STRING='pygobject 3.13.2'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
 PACKAGE_URL='https://wiki.gnome.org/Projects/PyGObject/'
 
@@ -1395,7 +1395,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.13.1 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.13.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1465,7 +1465,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pygobject 3.13.1:";;
+     short | recursive ) echo "Configuration of pygobject 3.13.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1603,7 +1603,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pygobject configure 3.13.1
+pygobject configure 3.13.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1881,7 +1881,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.13.1, which was
+It was created by pygobject $as_me 3.13.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2245,9 +2245,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 13" >>confdefs.h
 PYGOBJECT_MINOR_VERSION=13
 
 
-$as_echo "#define PYGOBJECT_MICRO_VERSION 1" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 2" >>confdefs.h
 
-PYGOBJECT_MICRO_VERSION=1
+PYGOBJECT_MICRO_VERSION=2
 
 
 ac_config_headers="$ac_config_headers config.h"
@@ -2767,7 +2767,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pygobject'
- VERSION='3.13.1'
+ VERSION='3.13.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13840,16 +13840,16 @@ if test -n "$GI_CFLAGS"; then
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 \""; } >&5
   ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 ") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GI_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 " 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
@@ -13863,16 +13863,16 @@ if test -n "$GI_LIBS"; then
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 \""; } >&5
   ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 ") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_GI_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 " 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
 else
@@ -13895,18 +13895,18 @@ else
 fi
         if test $_pkg_short_errors_supported = yes; then
                GI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 " 2>&1`
         else
                GI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 " 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$GI_PKG_ERRORS" >&5
 
        as_fn_error $? "Package requirements (glib-2.0 >= 2.38.0
-    gobject-introspection-1.0 >= 1.38.0
+    gobject-introspection-1.0 >= 1.39.0
 ) were not met:
 
 $GI_PKG_ERRORS
@@ -15370,7 +15370,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.13.1, which was
+This file was extended by pygobject $as_me 3.13.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15437,7 +15437,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.13.1
+pygobject config.status 3.13.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index a21c489..77fe449 100644 (file)
@@ -18,11 +18,11 @@ m4_define(python3_min_ver, 3.1)
 dnl the pygobject version number
 m4_define(pygobject_major_version, 3)
 m4_define(pygobject_minor_version, 13)
-m4_define(pygobject_micro_version, 1)
+m4_define(pygobject_micro_version, 2)
 m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
 
 dnl versions of packages we require ...
-m4_define(introspection_required_version, 1.38.0)
+m4_define(introspection_required_version, 1.39.0)
 m4_define(py2cairo_required_version, 1.2.0)
 m4_define(py3cairo_required_version, 1.10.0)
 m4_define(glib_required_version, 2.38.0)
index b00d30a..6fb1c5d 100644 (file)
@@ -71,6 +71,7 @@ _gi_la_SOURCES = \
        pygi-info.h \
        pygi-foreign.c \
        pygi-foreign.h \
+       pygi-foreign-api.h \
        pygi-struct.c \
        pygi-struct.h \
        pygi-source.c \
@@ -139,12 +140,14 @@ _gi_cairo_la_SOURCES = \
        pygi-foreign-cairo.c
 _gi_cairo_la_CFLAGS = \
        $(GI_CFLAGS) \
+       $(CAIRO_CFLAGS) \
        $(PYCAIRO_CFLAGS)
 _gi_cairo_la_CPPFLAGS = \
        $(extension_cppflags)
 _gi_cairo_la_LIBADD = \
        $(extension_libadd) \
        $(GI_LIBS) \
+       $(CAIRO_LIBS) \
        $(PYCAIRO_LIBS)
 _gi_cairo_la_LDFLAGS = \
        $(extension_ldflags) \
index 82ee5e7..256b41a 100644 (file)
@@ -155,7 +155,8 @@ _gi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_gi_la_CFLAGS) $(CFLAGS) \
        $(_gi_la_LDFLAGS) $(LDFLAGS) -o $@
 _gi_cairo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \
-       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+       $(am__DEPENDENCIES_1)
 am__gi_cairo_la_OBJECTS = _gi_cairo_la-pygi-foreign-cairo.lo
 _gi_cairo_la_OBJECTS = $(am__gi_cairo_la_OBJECTS)
 _gi_cairo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -492,6 +493,7 @@ _gi_la_SOURCES = \
        pygi-info.h \
        pygi-foreign.c \
        pygi-foreign.h \
+       pygi-foreign-api.h \
        pygi-struct.c \
        pygi-struct.h \
        pygi-source.c \
@@ -561,6 +563,7 @@ _gi_cairo_la_SOURCES = \
 
 _gi_cairo_la_CFLAGS = \
        $(GI_CFLAGS) \
+       $(CAIRO_CFLAGS) \
        $(PYCAIRO_CFLAGS)
 
 _gi_cairo_la_CPPFLAGS = \
@@ -569,6 +572,7 @@ _gi_cairo_la_CPPFLAGS = \
 _gi_cairo_la_LIBADD = \
        $(extension_libadd) \
        $(GI_LIBS) \
+       $(CAIRO_LIBS) \
        $(PYCAIRO_LIBS)
 
 _gi_cairo_la_LDFLAGS = \
index 7c1a279..df6843c 100644 (file)
@@ -26,6 +26,7 @@ __path__ = extend_path(__path__, __name__)
 
 import sys
 import os
+import importlib
 
 # we can't have pygobject 2 loaded at the same time we load the internal _gobject
 if 'gobject' in sys.modules:
@@ -33,6 +34,7 @@ if 'gobject' in sys.modules:
                       'modules like "gobject". Please change all occurrences '
                       'of "import gobject" to "from gi.repository import GObject".')
 
+from . import _gi
 from ._gi import _gobject
 from ._gi import _API
 from ._gi import Repository
@@ -87,3 +89,29 @@ def require_version(namespace, version):
 
 def get_required_version(namespace):
     return _versions.get(namespace, None)
+
+
+def require_foreign(namespace, symbol=None):
+    """Ensure the given foreign marshaling module is available and loaded.
+
+    :param str namespace:
+        Introspection namespace of the foreign module (e.g. "cairo")
+    :param symbol:
+        Optional symbol typename to ensure a converter exists.
+    :type symbol: str or None
+    :raises: ImportError
+
+    :Example:
+
+    .. code-block:: python
+
+        import gi
+        import cairo
+        gi.require_foreign('cairo')
+
+    """
+    try:
+        _gi.require_foreign(namespace, symbol)
+    except Exception as e:
+        raise ImportError(str(e))
+    importlib.import_module('gi.repository', namespace)
diff --git a/gi/_error.py b/gi/_error.py
new file mode 100644 (file)
index 0000000..6b684ce
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
+#
+#   _error.py: GError Python implementation
+#
+# 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 St, Fifth Floor, Boston, MA  02110-1301
+# USA
+
+
+# NOTE: This file should not have any dependencies on introspection libs
+# like gi.repository.GLib because it would cause a circular dependency.
+# Developers wanting to use the GError class in their applications should
+# use gi.repository.GLib.GError
+
+
+class GError(RuntimeError):
+    def __init__(self, message='unknown error', domain='pygi-error', code=0):
+        super(GError, self).__init__(message)
+        self.message = message
+        self.domain = domain
+        self.code = code
+
+    def __str__(self):
+        return "%s: %s (%d)" % (self.domain, self.message, self.code)
+
+    def __repr__(self):
+        return "%s.%s('%s', '%s', %d)" % (GError.__module__, GError.__name__,
+                                          self.message, self.domain, self.code)
+
+    def copy(self):
+        return GError(self.message, self.domain, self.code)
+
+    def matches(self, domain, code):
+        """Placeholder that will be monkey patched in GLib overrides."""
+        raise NotImplementedError
+
+    @staticmethod
+    def new_literal(domain, message, code):
+        """Placeholder that will be monkey patched in GLib overrides."""
+        raise NotImplementedError
index 422c53f..2d30abf 100644 (file)
@@ -41,6 +41,7 @@ else:
     _bytes = str
 
 from gi._gi import _glib
+from gi._error import GError
 GLib = get_introspection_module('GLib')
 
 OPTION_CONTEXT_ERROR_QUARK = GLib.quark_to_string(GLib.option_error_quark())
@@ -202,7 +203,7 @@ class OptionGroup(optparse.OptionGroup):
                 opt.process(option_name, option_value, self.values, parser)
             except OptionValueError:
                 error = sys.exc_info()[1]
-                gerror = _glib.GError(str(error))
+                gerror = GError(str(error))
                 gerror.domain = OPTION_CONTEXT_ERROR_QUARK
                 gerror.code = GLib.OptionError.BAD_VALUE
                 gerror.message = str(error)
@@ -347,7 +348,7 @@ class OptionParser(optparse.OptionParser):
         try:
             options, args = optparse.OptionParser.parse_args(
                 self, args, values)
-        except _glib.GError:
+        except GError:
             error = sys.exc_info()[1]
             if error.domain != OPTION_CONTEXT_ERROR_QUARK:
                 raise
index 25fc3d6..44a8fbd 100644 (file)
@@ -27,6 +27,8 @@
 #include "pygi-private.h"
 #include "pygi.h"
 #include "pyglib.h"
+#include "pygi-error.h"
+#include "pygi-foreign.h"
 
 #include <pyglib-python-compat.h>
 
@@ -494,7 +496,7 @@ _wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
             return NULL;
         }
 
-        values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
+        values[i] = pyg_pointer_get (value, GVariant);
     }
 
     variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
@@ -584,7 +586,7 @@ pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs)
         status = g_io_channel_read_chars (iochannel, buf, buf_size, &single_read, &error);
         Py_END_ALLOW_THREADS;
 
-        if (pyglib_error_check(&error))
+        if (pygi_error_check (&error))
            goto failure;
        
        total_read += single_read;
@@ -615,15 +617,12 @@ static PyMethodDef _gi_functions[] = {
     { "source_new", (PyCFunction) _wrap_pyg_source_new, METH_NOARGS },
     { "source_set_callback", (PyCFunction) pyg_source_set_callback, METH_VARARGS },
     { "io_channel_read", (PyCFunction) pyg_channel_read, METH_VARARGS },
+    { "require_foreign", (PyCFunction) pygi_require_foreign, METH_VARARGS | METH_KEYWORDS },
     { NULL, NULL, 0 }
 };
 
 static struct PyGI_API CAPI = {
-  pygi_type_import_by_g_type_real,
-  pygi_get_property_value_real,
-  pygi_set_property_value_real,
-  pygi_signal_closure_new_real,
-  pygi_register_foreign_struct_real,
+  pygi_register_foreign_struct,
 };
 
 PYGLIB_MODULE_START(_gi, "_gi")
@@ -664,12 +663,14 @@ PYGLIB_MODULE_START(_gi, "_gi")
     PyModule_AddObject (module, "_gobject", _gobject_module);
     PyModule_AddStringConstant(module, "__package__", "gi._gi");
 
+    pygi_foreign_init ();
+    pygi_error_register_types (module);
     _pygi_repository_register_types (module);
     _pygi_info_register_types (module);
     _pygi_struct_register_types (module);
     _pygi_boxed_register_types (module);
     _pygi_ccallback_register_types (module);
-    _pygi_argument_init();
+    _pygi_argument_init ();
 
     /* Use RuntimeWarning as the base class of PyGIDeprecationWarning
      * for unstable (odd minor version) and use DeprecationWarning for
index e859158..297805a 100644 (file)
@@ -31,8 +31,6 @@
 #include "pygoptiongroup.h"
 #include "pygspawn.h"
 
-PyObject *PyGError = NULL;
-
 /* ---------------- glib module functions -------------------- */
 
 static PyMethodDef _glib_functions[] = {
@@ -48,27 +46,10 @@ static PyMethodDef _glib_functions[] = {
     { 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);
index a20d93a..458884b 100644 (file)
@@ -37,6 +37,7 @@
 #include "pygoptiongroup.h"
 
 #include "pygi-value.h"
+#include "pygi-error.h"
 
 static GHashTable *log_handlers = NULL;
 static gboolean log_handlers_disabled = FALSE;
@@ -1834,55 +1835,6 @@ pyg_flags_add_constants(PyObject *module, GType flags_type,
 }
 
 /**
- * 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
@@ -2055,7 +2007,7 @@ struct _PyGObject_Functions pygobject_api_functions = {
 
   pyg_constant_strip_prefix,
 
-  pyg_error_check,
+  pygi_error_check,
 
   _pyg_set_thread_block_funcs,
   (PyGThreadBlockFunc)0, /* block_threads */
@@ -2098,7 +2050,7 @@ struct _PyGObject_Functions pygobject_api_functions = {
 
   NULL, /* previously type_register_custom */
 
-  pyg_gerror_exception_check,
+  pygi_gerror_exception_check,
 
   pyg_option_group_new,
   pyg_type_from_object_strict,
index cc967b4..b675adf 100644 (file)
@@ -53,13 +53,13 @@ class OverridesObject(GIMarshallingTests.OverridesObject):
     def __init__(self, long_):
         GIMarshallingTests.OverridesObject.__init__(self)
         # FIXME: doesn't work yet
-        #self.long_ = long_
+        # self.long_ = long_
 
     @classmethod
     def new(cls, long_):
         self = GIMarshallingTests.OverridesObject.new()
         # FIXME: doesn't work yet
-        #self.long_ = long_
+        # self.long_ = long_
         return self
 
     def method(self):
index 0e8f694..214d507 100644 (file)
@@ -40,7 +40,9 @@ __all__.append('option')
 
 # Types and functions still needed from static bindings
 from gi._gi import _glib
-GError = _glib.GError
+from gi._error import GError
+
+Error = GError
 OptionContext = _glib.OptionContext
 OptionGroup = _glib.OptionGroup
 Pid = _glib.Pid
@@ -52,7 +54,30 @@ def threads_init():
                   'See: https://wiki.gnome.org/PyGObject/Threading',
                   PyGIDeprecationWarning, stacklevel=2)
 
-__all__ += ['GError', 'OptionContext', 'OptionGroup', 'Pid',
+
+def gerror_matches(self, domain, code):
+    # Handle cases where self.domain was set to an integer for compatibility
+    # with the introspected GLib.Error.
+    if isinstance(self.domain, str):
+        self_domain_quark = GLib.quark_from_string(self.domain)
+    else:
+        self_domain_quark = self.domain
+    return (self_domain_quark, self.code) == (domain, code)
+
+
+def gerror_new_literal(domain, message, code):
+    domain_quark = GLib.quark_to_string(domain)
+    return GError(message, domain_quark, code)
+
+
+# Monkey patch methods that rely on GLib introspection to be loaded at runtime.
+Error.__name__ = 'Error'
+Error.__module__ = 'GLib'
+Error.matches = gerror_matches
+Error.new_literal = staticmethod(gerror_new_literal)
+
+
+__all__ += ['GError', 'Error', 'OptionContext', 'OptionGroup', 'Pid',
             'spawn_async', 'threads_init']
 
 
index 5a5dd2f..e646821 100644 (file)
@@ -82,14 +82,14 @@ class Settings(Gio.Settings):
 
     def __getitem__(self, key):
         # get_value() aborts the program on an unknown key
-        if not key in self:
+        if key not in self:
             raise KeyError('unknown key: %r' % (key,))
 
         return self.get_value(key).unpack()
 
     def __setitem__(self, key, value):
         # set_value() aborts the program on an unknown key
-        if not key in self:
+        if key not in self:
             raise KeyError('unknown key: %r' % (key,))
 
         # determine type string of this key
index df55c2d..561bdf0 100644 (file)
@@ -86,6 +86,17 @@ class Widget(Gtk.Widget):
             target_list = Gtk.TargetList.new(_construct_target_list(target_list))
         super(Widget, self).drag_source_set_target_list(target_list)
 
+    def style_get_property(self, property_name, value=None):
+        if value is None:
+            prop = self.find_style_property(property_name)
+            if prop is None:
+                raise ValueError('Class "%s" does not contain style property "%s"' %
+                                 (self, property_name))
+            value = GObject.Value(prop.value_type)
+
+        Gtk.Widget.style_get_property(self, property_name, value)
+        return value.get_value()
+
 
 Widget = override(Widget)
 __all__.append('Widget')
@@ -110,6 +121,27 @@ class Container(Gtk.Container, Widget):
 
     get_focus_chain = strip_boolean_result(Gtk.Container.get_focus_chain)
 
+    def child_get_property(self, child, property_name, value=None):
+        if value is None:
+            prop = self.find_child_property(property_name)
+            if prop is None:
+                raise ValueError('Class "%s" does not contain child property "%s"' %
+                                 (self, property_name))
+            value = GObject.Value(prop.value_type)
+
+        Gtk.Container.child_get_property(self, child, property_name, value)
+        return value.get_value()
+
+    def child_get(self, child, *prop_names):
+        """Returns a list of child property values for the given names."""
+        return [self.child_get_property(child, name) for name in prop_names]
+
+    def child_set(self, child, **kwargs):
+        """Set a child properties on the given child to key/value pairs."""
+        for name, value in kwargs.items():
+            name = name.replace('_', '-')
+            self.child_set_property(child, name, value)
+
 
 Container = override(Container)
 __all__.append('Container')
@@ -1122,13 +1154,13 @@ class TreePath(Gtk.TreePath):
         return self.to_string()
 
     def __lt__(self, other):
-        return not other is None and self.compare(other) < 0
+        return other is not None and self.compare(other) < 0
 
     def __le__(self, other):
-        return not other is None and self.compare(other) <= 0
+        return other is not None and self.compare(other) <= 0
 
     def __eq__(self, other):
-        return not other is None and self.compare(other) == 0
+        return other is not None and self.compare(other) == 0
 
     def __ne__(self, other):
         return other is None or self.compare(other) != 0
index 35716a2..9faa652 100644 (file)
@@ -27,6 +27,7 @@
 #include "pygboxed.h"
 
 #include "pygi.h"
+#include "pygi-type.h"
 
 GQuark pygboxed_type_key;
 GQuark pygboxed_marshal_key;
@@ -36,9 +37,9 @@ PYGLIB_DEFINE_TYPE("gobject.GBoxed", PyGBoxed_Type, PyGBoxed);
 static void
 pyg_boxed_dealloc(PyGBoxed *self)
 {
-    if (self->free_on_dealloc && self->boxed) {
+    if (self->free_on_dealloc && pyg_boxed_get_ptr (self)) {
        PyGILState_STATE state = pyglib_gil_state_ensure();
-       g_boxed_free(self->gtype, self->boxed);
+       g_boxed_free (self->gtype, pyg_boxed_get_ptr (self));
        pyglib_gil_state_release(state);
     }
 
@@ -50,9 +51,9 @@ 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);
+        return _pyglib_generic_ptr_richcompare (pyg_boxed_get_ptr (self),
+                                                pyg_boxed_get_ptr (other),
+                                                op);
     else {
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
@@ -63,7 +64,7 @@ pyg_boxed_richcompare(PyObject *self, PyObject *other, int op)
 static long
 pyg_boxed_hash(PyGBoxed *self)
 {
-    return (long)self->boxed;
+    return (long)pyg_boxed_get_ptr (self);
 }
 
 static PyObject *
@@ -72,7 +73,7 @@ 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);
+              (long)pyg_boxed_get_ptr (self));
     return PYGLIB_PyUnicode_FromString(buf);
 }
 
@@ -84,7 +85,7 @@ pyg_boxed_init(PyGBoxed *self, PyObject *args, PyObject *kwargs)
     if (!PyArg_ParseTuple(args, ":GBoxed.__init__"))
        return -1;
 
-    self->boxed = NULL;
+    pyg_boxed_set_ptr (self, NULL);
     self->gtype = 0;
     self->free_on_dealloc = FALSE;
 
@@ -103,7 +104,7 @@ pyg_boxed_free(PyObject *op)
 static PyObject *
 pyg_boxed_copy(PyGBoxed *self)
 {
-    return pyg_boxed_new (self->gtype, self->boxed, TRUE, TRUE);
+    return pyg_boxed_new (self->gtype, pyg_boxed_get_ptr (self), TRUE, TRUE);
 }
 
 
@@ -205,7 +206,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed,
 
     if (copy_boxed)
        boxed = g_boxed_copy(boxed_type, boxed);
-    self->boxed = boxed;
+    pyg_boxed_set_ptr (self, boxed);
     self->gtype = boxed_type;
     self->free_on_dealloc = own_ref;
 
index 1b9b50e..053518f 100644 (file)
@@ -26,6 +26,7 @@
 #include <pyglib.h>
 #include "pygobject-private.h"
 #include "pygi.h"
+#include "pygi-type.h"
 
 #include "pygenum.h"
 
index c14bf7d..a7df8ce 100644 (file)
@@ -28,6 +28,7 @@
 #include "pygflags.h"
 
 #include "pygi.h"
+#include "pygi-type.h"
 
 GQuark pygflags_class_key;
 
index 4094c3d..15be78c 100644 (file)
@@ -33,7 +33,7 @@
 #include "pygi-basictype.h"
 #include "pygi-object.h"
 #include "pygi-struct-marshal.h"
-
+#include "pygi-error.h"
 
 static gboolean
 gi_argument_to_gssize (GIArgument *arg_in,
@@ -1029,16 +1029,16 @@ array_success:
                      * Further re-factoring is needed to fix this leak.
                      * See: https://bugzilla.gnome.org/show_bug.cgi?id=693405
                      */
-                    _pygi_marshal_from_py_interface_struct (object,
-                                                            &arg,
-                                                            NULL, /*arg_name*/
-                                                            info, /*interface_info*/
-                                                            g_type,
-                                                            py_type,
-                                                            transfer,
-                                                            FALSE, /*copy_reference*/
-                                                            g_struct_info_is_foreign (info),
-                                                            g_type_info_is_pointer (type_info));
+                    pygi_arg_struct_from_py_marshal (object,
+                                                     &arg,
+                                                     NULL, /*arg_name*/
+                                                     info, /*interface_info*/
+                                                     g_type,
+                                                     py_type,
+                                                     transfer,
+                                                     FALSE, /*copy_reference*/
+                                                     g_struct_info_is_foreign (info),
+                                                     g_type_info_is_pointer (type_info));
 
                     Py_DECREF (py_type);
                     break;
@@ -1372,13 +1372,13 @@ _pygi_argument_to_object (GIArgument  *arg,
                         py_type = _pygi_type_get_from_g_type (g_type);
                     }
 
-                    object = _pygi_marshal_to_py_interface_struct (arg,
-                                                                   info, /*interface_info*/
-                                                                   g_type,
-                                                                   py_type,
-                                                                   transfer,
-                                                                   FALSE, /*is_allocated*/
-                                                                   g_struct_info_is_foreign (info));
+                    object = pygi_arg_struct_to_py_marshal (arg,
+                                                            info, /*interface_info*/
+                                                            g_type,
+                                                            py_type,
+                                                            transfer,
+                                                            FALSE, /*is_allocated*/
+                                                            g_struct_info_is_foreign (info));
 
                     Py_XDECREF (py_type);
                     break;
@@ -1558,12 +1558,12 @@ _pygi_argument_to_object (GIArgument  *arg,
             GError *error = (GError *) arg->v_pointer;
             if (error != NULL && transfer == GI_TRANSFER_NOTHING) {
                 /* If we have not been transferred the ownership we must copy
-                 * the error, because pyglib_error_check() is going to free it.
+                 * the error, because pygi_error_check() is going to free it.
                  */
                 error = g_error_copy (error);
             }
 
-            if (pyglib_error_check (&error)) {
+            if (pygi_error_check (&error)) {
                 PyObject *err_type;
                 PyObject *err_value;
                 PyObject *err_trace;
index c17ace0..fceffc6 100644 (file)
@@ -454,7 +454,7 @@ _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
                      * 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) {
+                    if (cleanup_func == pygi_arg_gvalue_from_py_cleanup) {
                         g_value_unset ((GValue*) item);
                         continue;
                     }
index c52858b..b46cdcc 100644 (file)
@@ -32,10 +32,10 @@ _boxed_dealloc (PyGIBoxed *self)
 
     if ( ( (PyGBoxed *) self)->free_on_dealloc) {
         if (self->slice_allocated) {
-            g_slice_free1 (self->size, ( (PyGBoxed *) self)->boxed);
+            g_slice_free1 (self->size, pyg_boxed_get_ptr (self));
         } else {
             g_type = pyg_type_from_object ( (PyObject *) self);
-            g_boxed_free (g_type, ( (PyGBoxed *) self)->boxed);
+            g_boxed_free (g_type, pyg_boxed_get_ptr (self));
         }
     }
 
@@ -158,8 +158,8 @@ _pygi_boxed_new (PyTypeObject *type,
     }
 
     ( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type);
-    ( (PyGBoxed *) self)->boxed = boxed;
     ( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc;
+    pyg_boxed_set_ptr (self, boxed);
     if (allocated_slice > 0) {
         self->size = allocated_slice;
         self->slice_allocated = TRUE;
index c8da66f..24bb1a4 100644 (file)
@@ -695,7 +695,7 @@ _setup_invoker (GICallableInfo *callable_info,
                                           &error)) {
             return TRUE;
         }
-        if (!pyglib_error_check (&error)) {
+        if (!pygi_error_check (&error)) {
             PyErr_Format (PyExc_RuntimeError,
                           "unknown error creating invoker for %s",
                           g_base_info_get_name ((GIBaseInfo *)callable_info));
@@ -707,7 +707,7 @@ _setup_invoker (GICallableInfo *callable_info,
                                                  (GIFunctionInfo *)callable_info,
                                                  invoker,
                                                  &error)) {
-            if (!pyglib_error_check (&error)) {
+            if (!pygi_error_check (&error)) {
                 PyErr_Format (PyExc_RuntimeError,
                               "unknown error creating invoker for %s",
                               g_base_info_get_name ((GIBaseInfo *)callable_info));
index 349bb7e..2e9150f 100644 (file)
@@ -1,6 +1,8 @@
 /* -*- Mode: C; c-basic-offset: 4 -*-
  * vim: tabstop=4 shiftwidth=4 expandtab
  *
+ * Copyright (C) 1998-2003  James Henstridge
+ *               2004-2008  Johan Dahlin
  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
  *
 #include "pygi-error.h"
 
 
+static PyObject *PyGError = NULL;
+static PyObject *exception_table = NULL;
+
+/**
+ * pygi_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 *
+pygi_error_marshal (GError **error)
+{
+    PyGILState_STATE state;
+    PyObject *exc_type;
+    PyObject *exc_instance;
+    const char *domain = NULL;
+
+    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;
+    }
+
+    if ((*error)->domain) {
+        domain = g_quark_to_string ((*error)->domain);
+    }
+
+    exc_instance = PyObject_CallFunction (exc_type, "ssi",
+                                          (*error)->message,
+                                          domain,
+                                          (*error)->code);
+
+    pyglib_gil_state_release(state);
+
+    return exc_instance;
+}
+
+/**
+ * pygi_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
+pygi_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 = pygi_error_marshal (error);
+    PyErr_SetObject(PyGError, exc_instance);
+    Py_DECREF(exc_instance);
+    g_clear_error(error);
+
+    pyglib_gil_state_release(state);
+
+    return TRUE;
+}
+
+/**
+ * pygi_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
+pygi_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 = "GLib.Error 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 = "GLib.Error 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 = "GLib.Error 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("pygi"), 0, "%s", bad_gerror_message);
+    PyErr_SetString(PyExc_ValueError, bad_gerror_message);
+    PyErr_Print();
+    return -2;
+}
+
+/**
+ * pygi_register_exception_for_domain:
+ * @name: name of the exception
+ * @error_domain: error domain
+ *
+ * Registers a new GLib.Error exception subclass called #name for
+ * a specific #domain. This exception will be raised when a GError
+ * of the same domain is passed in to pygi_error_check().
+ *
+ * Returns: the new exception
+ */
+PyObject *
+pygi_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;
+}
+
 static gboolean
 _pygi_marshal_from_py_gerror (PyGIInvokeState   *state,
                               PyGICallableCache *callable_cache,
@@ -45,7 +235,7 @@ _pygi_marshal_to_py_gerror (PyGIInvokeState   *state,
     GError *error = arg->v_pointer;
     PyObject *py_obj = NULL;
 
-    py_obj = pyglib_error_marshal(&error);
+    py_obj = pygi_error_marshal (&error);
 
     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) {
         g_error_free (error);
@@ -107,3 +297,16 @@ pygi_arg_gerror_new_from_info (GITypeInfo   *type_info,
         return NULL;
     }
 }
+
+void
+pygi_error_register_types (PyObject *module)
+{
+    PyObject *error_module = PyImport_ImportModule ("gi._error");
+    if (!error_module) {
+        return;
+    }
+
+    /* Stash a reference to the Python implemented gi._error.GError. */
+    PyGError = PyObject_GetAttrString (error_module, "GError");
+}
+
index fdeb32f..72d2be0 100644 (file)
@@ -1,6 +1,8 @@
 /* -*- Mode: C; c-basic-offset: 4 -*-
  * vim: tabstop=4 shiftwidth=4 expandtab
  *
+ * Copyright (C) 1998-2003  James Henstridge
+ *               2004-2008  Johan Dahlin
  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
  *
  * This library is free software; you can redistribute it and/or
 
 G_BEGIN_DECLS
 
-PyGIArgCache *pygi_arg_gerror_new_from_info  (GITypeInfo    *type_info,
-                                              GIArgInfo     *arg_info,   /* may be null */
-                                              GITransfer     transfer,
-                                              PyGIDirection  direction);
+gboolean      pygi_error_check              (GError **error);
+
+PyObject*     pygi_error_marshal            (GError **error);
+
+gboolean      pygi_gerror_exception_check   (GError **error);
+
+PyObject*     pygi_register_exception_for_domain (gchar *name,
+                                                  gint   error_domain);
+
+PyGIArgCache* pygi_arg_gerror_new_from_info (GITypeInfo    *type_info,
+                                             GIArgInfo     *arg_info,   /* may be null */
+                                             GITransfer     transfer,
+                                             PyGIDirection  direction);
+
+void          pygi_error_register_types     (PyObject *module);
 
 G_END_DECLS
 
diff --git a/gi/pygi-foreign-api.h b/gi/pygi-foreign-api.h
new file mode 100644 (file)
index 0000000..9367518
--- /dev/null
@@ -0,0 +1,85 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PYGI_FOREIGN_API_H__
+#define __PYGI_FOREIGN_API_H__
+
+#include <girepository.h>
+#include <pygobject.h>
+
+typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc)   (PyObject        *value,
+                                                         GIInterfaceInfo *interface_info,
+                                                         GITransfer       transfer,
+                                                         GIArgument      *arg);
+typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info,
+                                                         GITransfer       transfer,
+                                                         gpointer         data);
+typedef PyObject * (*PyGIArgOverrideReleaseFunc)        (GITypeInfo *type_info,
+                                                         gpointer  struct_);
+
+
+struct PyGI_API {
+    void (*register_foreign_struct) (const char* namespace_,
+                                     const char* name,
+                                     PyGIArgOverrideToGIArgumentFunc to_func,
+                                     PyGIArgOverrideFromGIArgumentFunc from_func,
+                                     PyGIArgOverrideReleaseFunc release_func);
+};
+
+
+#ifndef _INSIDE_PYGOBJECT_
+
+static struct PyGI_API *PyGI_API = NULL;
+
+static int
+_pygi_import (void)
+{
+    if (PyGI_API != NULL) {
+        return 1;
+    }
+    PyGI_API = (struct PyGI_API*) PyCapsule_Import("gi._API", FALSE);
+    if (PyGI_API == NULL) {
+        return -1;
+    }
+
+    return 0;
+}
+
+
+static inline PyObject *
+pygi_register_foreign_struct (const char* namespace_,
+                              const char* name,
+                              PyGIArgOverrideToGIArgumentFunc to_func,
+                              PyGIArgOverrideFromGIArgumentFunc from_func,
+                              PyGIArgOverrideReleaseFunc release_func)
+{
+    if (_pygi_import() < 0) {
+        return NULL;
+    }
+    PyGI_API->register_foreign_struct(namespace_,
+                                      name,
+                                      to_func,
+                                      from_func,
+                                      release_func);
+    Py_RETURN_NONE;
+}
+
+#endif /* _INSIDE_PYGOBJECT_ */
+
+#endif /* __PYGI_FOREIGN_API_H__ */
index 8261a07..5937759 100644 (file)
@@ -31,11 +31,19 @@ static Pycairo_CAPI_t *Pycairo_CAPI;
 #include <pycairo/py3cairo.h>
 #endif
 
+#include <cairo-gobject.h>
 
-#include "pygi-foreign.h"
-
+/* Limit includes from PyGI to APIs which do not have link dependencies
+ * (pygobject.h and pygi-foreign-api.h) since _gi_cairo is built as a separate
+ * shared library that interacts with PyGI through a PyCapsule API at runtime.
+ */
+#include <pygi-foreign-api.h>
 #include <pyglib-python-compat.h>
 
+/*
+ * cairo_t marshaling
+ */
+
 static PyObject *
 cairo_context_to_arg (PyObject        *value,
                       GIInterfaceInfo *interface_info,
@@ -68,6 +76,7 @@ cairo_context_from_arg (GIInterfaceInfo *interface_info,
     return PycairoContext_FromContext (context, &PycairoContext_Type, NULL);
 }
 
+
 static PyObject *
 cairo_context_release (GIBaseInfo *base_info,
                        gpointer    struct_)
@@ -76,6 +85,36 @@ cairo_context_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+static int
+cairo_context_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_t *cr = PycairoContext_GET (obj);
+    if (!cr) {
+        return -1;
+    }
+
+    /* PycairoContext_GET returns a borrowed reference, use set_boxed
+     * to add new ref to the context which will be managed by the GValue. */
+    g_value_set_boxed (value, cr);
+    return 0;
+}
+
+static PyObject *
+cairo_context_from_gvalue (const GValue *value)
+{
+    /* PycairoContext_FromContext steals a ref, so we dup it out of the GValue. */
+    cairo_t *cr = g_value_dup_boxed (value);
+    if (!cr) {
+        return NULL;
+    }
+
+    return PycairoContext_FromContext (cr, &PycairoContext_Type, NULL);
+}
+
+
+/*
+ * cairo_surface_t marshaling
+ */
 
 static PyObject *
 cairo_surface_to_arg (PyObject        *value,
@@ -118,6 +157,36 @@ cairo_surface_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+static int
+cairo_surface_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_surface_t *surface = ((PycairoSurface*) obj)->surface;
+    if (!surface) {
+        return -1;
+    }
+
+    /* surface is a borrowed reference, use set_boxed
+     * to add new ref to the context which will be managed by the GValue. */
+    g_value_set_boxed (value, surface);
+    return 0;
+}
+
+static PyObject *
+cairo_surface_from_gvalue (const GValue *value)
+{
+    /* PycairoSurface_FromSurface steals a ref, so we dup it out of the GValue. */
+    cairo_surface_t *surface = g_value_dup_boxed (value);
+    if (!surface) {
+        return NULL;
+    }
+
+    return PycairoSurface_FromSurface (surface, NULL);
+}
+
+
+/*
+ * cairo_path_t marshaling
+ */
 
 static PyObject *
 cairo_path_to_arg (PyObject        *value,
@@ -162,6 +231,39 @@ cairo_path_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+
+/*
+ * cairo_font_face_t marshaling
+ */
+
+static int
+cairo_font_face_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_font_face_t *font_face = ((PycairoFontFace*) obj)->font_face;
+    if (!font_face) {
+        return -1;
+    }
+
+    g_value_set_boxed (value, font_face);
+    return 0;
+}
+
+static PyObject *
+cairo_font_face_from_gvalue (const GValue *value)
+{
+    cairo_font_face_t *font_face = g_value_dup_boxed (value);
+    if (!font_face) {
+        return NULL;
+    }
+
+    return PycairoFontFace_FromFontFace (font_face);
+}
+
+
+/*
+ * cairo_font_options_t marshaling
+ */
+
 static PyObject *
 cairo_font_options_to_arg (PyObject        *value,
                            GIInterfaceInfo *interface_info,
@@ -203,6 +305,69 @@ cairo_font_options_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+
+/*
+ * scaled_font_t marshaling
+ */
+
+static int
+cairo_scaled_font_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_scaled_font_t *scaled_font = ((PycairoScaledFont*) obj)->scaled_font;
+    if (!scaled_font) {
+        return -1;
+    }
+
+    /* scaled_font is a borrowed reference, use set_boxed
+     * to add new ref to the context which will be managed by the GValue. */
+    g_value_set_boxed (value, scaled_font);
+    return 0;
+}
+
+static PyObject *
+cairo_scaled_font_from_gvalue (const GValue *value)
+{
+    /* PycairoScaledFont_FromScaledFont steals a ref, so we dup it out of the GValue. */
+    cairo_scaled_font_t *scaled_font = g_value_dup_boxed (value);
+    if (!scaled_font) {
+        return NULL;
+    }
+
+    return PycairoScaledFont_FromScaledFont (scaled_font);
+}
+
+
+/*
+ * cairo_pattern_t marshaling
+ */
+
+static int
+cairo_pattern_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_pattern_t *pattern = ((PycairoPattern*) obj)->pattern;
+    if (!pattern) {
+        return -1;
+    }
+
+    /* pattern is a borrowed reference, use set_boxed
+     * to add new ref to the context which will be managed by the GValue. */
+    g_value_set_boxed (value, pattern);
+    return 0;
+}
+
+static PyObject *
+cairo_pattern_from_gvalue (const GValue *value)
+{
+    /* PycairoPattern_FromPattern steals a ref, so we dup it out of the GValue. */
+    cairo_pattern_t *pattern = g_value_dup_boxed (value);
+    if (!pattern) {
+        return NULL;
+    }
+
+    return PycairoPattern_FromPattern (pattern, NULL);
+}
+
+
 static PyMethodDef _gi_cairo_functions[] = { {0,} };
 PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
 {
@@ -215,6 +380,8 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
     if (Pycairo_CAPI == NULL)
         return PYGLIB_MODULE_ERROR_RETURN;
 
+    pygobject_init (3, 13, 2);
+
     pygi_register_foreign_struct ("cairo",
                                   "Context",
                                   cairo_context_to_arg,
@@ -238,5 +405,26 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
                                   cairo_font_options_to_arg,
                                   cairo_font_options_from_arg,
                                   cairo_font_options_release);
+
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_CONTEXT,
+                               cairo_context_from_gvalue,
+                               cairo_context_to_gvalue);
+
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SURFACE,
+                               cairo_surface_from_gvalue,
+                               cairo_surface_to_gvalue);
+
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_FONT_FACE,
+                               cairo_font_face_from_gvalue,
+                               cairo_font_face_to_gvalue);
+
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SCALED_FONT,
+                               cairo_scaled_font_from_gvalue,
+                               cairo_scaled_font_to_gvalue);
+
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_PATTERN,
+                               cairo_pattern_from_gvalue,
+                               cairo_pattern_to_gvalue);
+
 }
 PYGLIB_MODULE_END;
index f3c1a34..82392be 100644 (file)
@@ -63,24 +63,24 @@ do_lookup (const gchar *namespace, const gchar *name)
     return NULL;
 }
 
+static PyObject *
+pygi_struct_foreign_load_module (const char *namespace)
+{
+    gchar *module_name = g_strconcat ("gi._gi_", namespace, NULL);
+    PyObject *module = PyImport_ImportModule (module_name);
+    g_free (module_name);
+    return module;
+}
+
 static PyGIForeignStruct *
-pygi_struct_foreign_lookup (GIBaseInfo *base_info)
+pygi_struct_foreign_lookup_by_name (const char *namespace, const char *name)
 {
     PyGIForeignStruct *result;
-    const gchar *namespace = g_base_info_get_namespace (base_info);
-    const gchar *name = g_base_info_get_name (base_info);
-
-    if (foreign_structs == NULL) {
-        init_foreign_structs ();
-    }
 
     result = do_lookup (namespace, name);
 
     if (result == NULL) {
-        gchar *module_name = g_strconcat ("gi._gi_", namespace, NULL);
-        PyObject *module = PyImport_ImportModule (module_name);
-
-        g_free (module_name);
+        PyObject *module = pygi_struct_foreign_load_module (namespace);
 
         if (module == NULL)
             PyErr_Clear ();
@@ -92,7 +92,7 @@ pygi_struct_foreign_lookup (GIBaseInfo *base_info)
 
     if (result == NULL) {
         PyErr_Format (PyExc_TypeError,
-                      "Couldn't find conversion for foreign struct '%s.%s'",
+                      "Couldn't find foreign struct converter for '%s.%s'",
                       namespace,
                       name);
     }
@@ -100,6 +100,15 @@ pygi_struct_foreign_lookup (GIBaseInfo *base_info)
     return result;
 }
 
+static PyGIForeignStruct *
+pygi_struct_foreign_lookup (GIBaseInfo *base_info)
+{
+    const gchar *namespace = g_base_info_get_namespace (base_info);
+    const gchar *name = g_base_info_get_name (base_info);
+
+    return pygi_struct_foreign_lookup_by_name (namespace, name);
+}
+
 PyObject *
 pygi_struct_foreign_convert_to_g_argument (PyObject        *value,
                                            GIInterfaceInfo *interface_info,
@@ -151,11 +160,11 @@ pygi_struct_foreign_release (GIBaseInfo *base_info,
 }
 
 void
-pygi_register_foreign_struct_real (const char* namespace_,
-                                   const char* name,
-                                   PyGIArgOverrideToGIArgumentFunc to_func,
-                                   PyGIArgOverrideFromGIArgumentFunc from_func,
-                                   PyGIArgOverrideReleaseFunc release_func)
+pygi_register_foreign_struct (const char* namespace_,
+                              const char* name,
+                              PyGIArgOverrideToGIArgumentFunc to_func,
+                              PyGIArgOverrideFromGIArgumentFunc from_func,
+                              PyGIArgOverrideReleaseFunc release_func)
 {
     PyGIForeignStruct *new_struct = g_slice_new (PyGIForeignStruct);
     new_struct->namespace = namespace_;
@@ -166,3 +175,42 @@ pygi_register_foreign_struct_real (const char* namespace_,
 
     g_ptr_array_add (foreign_structs, new_struct);
 }
+
+PyObject *
+pygi_require_foreign (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = { "namespace", "symbol", NULL };
+    const char *namespace = NULL;
+    const char *symbol = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+                                      "s|z:require_foreign",
+                                      kwlist, &namespace, &symbol)) {
+        return NULL;
+    }
+
+    if (symbol) {
+        PyGIForeignStruct *foreign;
+        foreign = pygi_struct_foreign_lookup_by_name (namespace, symbol);
+        if (foreign == NULL) {
+            return NULL;
+        }
+    } else {
+        PyObject *module = pygi_struct_foreign_load_module (namespace);
+        if (module) {
+            Py_DECREF (module);
+        } else {
+            return NULL;
+        }
+    }
+
+    Py_RETURN_NONE;
+}
+
+void
+pygi_foreign_init (void)
+{
+    if (foreign_structs == NULL) {
+        init_foreign_structs ();
+    }
+}
index 478d759..afa4768 100644 (file)
@@ -26,9 +26,7 @@
 #define __PYGI_FOREIGN_H__
 
 #include <Python.h>
-#include <girepository.h>
-
-#include "pygi.h"
+#include "pygi-foreign-api.h"
 
 PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject           *value,
                                                      GIInterfaceInfo    *interface_info,
@@ -40,10 +38,16 @@ PyObject *pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interfac
 PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,
                                        gpointer struct_);
 
-void pygi_register_foreign_struct_real (const char* namespace_,
-                                        const char* name,
-                                        PyGIArgOverrideToGIArgumentFunc to_func,
-                                        PyGIArgOverrideFromGIArgumentFunc from_func,
-                                        PyGIArgOverrideReleaseFunc release_func);
+void pygi_register_foreign_struct (const char* namespace_,
+                                   const char* name,
+                                   PyGIArgOverrideToGIArgumentFunc to_func,
+                                   PyGIArgOverrideFromGIArgumentFunc from_func,
+                                   PyGIArgOverrideReleaseFunc release_func);
+
+PyObject *pygi_require_foreign    (PyObject *self,
+                                   PyObject *args,
+                                   PyObject *kwargs);
+
+void pygi_foreign_init (void);
 
 #endif /* __PYGI_FOREIGN_H__ */
index 065d470..43ee711 100644 (file)
@@ -754,6 +754,15 @@ _wrap_g_callable_info_get_return_attribute (PyGIBaseInfo *self, PyObject *py_nam
     }
 }
 
+static PyObject *
+_wrap_g_callable_info_can_throw_gerror (PyGIBaseInfo *self)
+{
+    if (g_callable_info_can_throw_gerror (self->info))
+        Py_RETURN_TRUE;
+    else
+        Py_RETURN_FALSE;
+}
+
 static PyMethodDef _PyGICallableInfo_methods[] = {
     { "invoke", (PyCFunction) _wrap_g_callable_info_invoke, METH_VARARGS | METH_KEYWORDS },
     { "get_arguments", (PyCFunction) _wrap_g_callable_info_get_arguments, METH_NOARGS },
@@ -762,11 +771,12 @@ static PyMethodDef _PyGICallableInfo_methods[] = {
     { "may_return_null", (PyCFunction) _wrap_g_callable_info_may_return_null, METH_NOARGS },
     { "skip_return", (PyCFunction) _wrap_g_callable_info_skip_return, METH_NOARGS },
     { "get_return_attribute", (PyCFunction) _wrap_g_callable_info_get_return_attribute, METH_O },
+    { "can_throw_gerror", (PyCFunction) _wrap_g_callable_info_can_throw_gerror, METH_NOARGS },
     { NULL, NULL, 0 }
 };
 
 /* CallbackInfo */
-PYGLIB_DEFINE_TYPE ("gi.CallbackInfo", PyGICallbackInfo_Type, PyGIBaseInfo);
+PYGLIB_DEFINE_TYPE ("gi.CallbackInfo", PyGICallbackInfo_Type, PyGICallableInfo);
 
 static PyMethodDef _PyGICallbackInfo_methods[] = {
     { NULL, NULL, 0 }
@@ -2185,7 +2195,7 @@ _pygi_info_register_types (PyObject *m)
     _PyGI_REGISTER_TYPE (m, PyGIUnresolvedInfo_Type, UnresolvedInfo,
                          PyGIBaseInfo_Type);
     _PyGI_REGISTER_TYPE (m, PyGICallbackInfo_Type, CallbackInfo,
-                         PyGIBaseInfo_Type);
+                         PyGICallableInfo_Type);
     _PyGI_REGISTER_TYPE (m, PyGIRegisteredTypeInfo_Type, RegisteredTypeInfo,
                          PyGIBaseInfo_Type);
     _PyGI_REGISTER_TYPE (m, PyGIStructInfo_Type, StructInfo,
index 4af2e72..eebf959 100644 (file)
@@ -23,6 +23,7 @@
 #include <pyglib.h>
 #include "pygi-invoke.h"
 #include "pygi-marshal-cleanup.h"
+#include "pygi-error.h"
 
 static inline gboolean
 _invoke_callable (PyGIInvokeState *state,
@@ -46,7 +47,7 @@ _invoke_callable (PyGIInvokeState *state,
      * state->error allowing for easy checking here.
      */
     if (state->error != NULL) {
-        if (pyglib_error_check (&(state->error))) {
+        if (pygi_error_check (&(state->error))) {
             /* even though we errored out, the call itself was successful,
                so we assume the call processed all of the parameters */
             pygi_marshal_cleanup_args_from_py_marshal_success (state, cache);
@@ -308,7 +309,7 @@ _invoke_state_init_from_callable_cache (GIBaseInfo *info,
         state->function_ptr = g_vfunc_info_get_address ((GIVFuncInfo *)info,
                                                         state->implementor_gtype,
                                                         &error);
-        if (pyglib_error_check (&error)) {
+        if (pygi_error_check (&error)) {
             return FALSE;
         }
     }
index 6f80506..f7cb032 100644 (file)
@@ -105,7 +105,7 @@ g_value_get_or_dup_boxed (const GValue *value, GITransfer transfer)
 }
 
 PyObject *
-pygi_get_property_value_real (PyGObject *instance, GParamSpec *pspec)
+pygi_get_property_value (PyGObject *instance, GParamSpec *pspec)
 {
     GIPropertyInfo *property_info = NULL;
     GValue value = { 0, };
@@ -271,9 +271,9 @@ out:
 }
 
 gint
-pygi_set_property_value_real (PyGObject *instance,
-                              GParamSpec *pspec,
-                              PyObject *py_value)
+pygi_set_property_value (PyGObject *instance,
+                         GParamSpec *pspec,
+                         PyObject *py_value)
 {
     GIPropertyInfo *property_info = NULL;
     GITypeInfo *type_info = NULL;
index 875d21e..5678bc3 100644 (file)
 #include <Python.h>
 #include <girepository.h>
 
-#include "pygi.h"
+#include "pygobject.h"
 
-PyObject *pygi_get_property_value_real (PyGObject *instance,
-                                        GParamSpec *pspec);
+PyObject *
+pygi_get_property_value (PyGObject *instance,
+                         GParamSpec *pspec);
 
-gint pygi_set_property_value_real (PyGObject *instance,
-                                   GParamSpec *pspec,
-                                   PyObject *py_value);
+gint
+pygi_set_property_value (PyGObject *instance,
+                         GParamSpec *pspec,
+                         PyObject *py_value);
 
 #endif /* __PYGI_PROPERTY_H__ */
index c5f51af..079669c 100644 (file)
@@ -171,12 +171,12 @@ pygi_signal_closure_marshal(GClosure *closure,
 }
 
 GClosure *
-pygi_signal_closure_new_real (PyGObject *instance,
-                              GType g_type,
-                              const gchar *signal_name,
-                              PyObject *callback,
-                              PyObject *extra_args,
-                              PyObject *swap_data)
+pygi_signal_closure_new (PyGObject *instance,
+                         GType g_type,
+                         const gchar *signal_name,
+                         PyObject *callback,
+                         PyObject *extra_args,
+                         PyObject *swap_data)
 {
     GClosure *closure = NULL;
     PyGISignalClosure *pygi_closure = NULL;
index ffdd29c..5cc191b 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __PYGI_SIGNAL_CLOSURE_H__
 #define __PYGI_SIGNAL_CLOSURE_H__
 
-#include "pygi.h"
+#include "pygobject.h"
 
 G_BEGIN_DECLS
 
@@ -35,12 +35,13 @@ typedef struct _PyGISignalClosure
     GISignalInfo *signal_info;
 } PyGISignalClosure;
 
-GClosure * pygi_signal_closure_new_real (PyGObject *instance,
-                                         GType g_type,
-                                         const gchar *sig_name,
-                                         PyObject *callback,
-                                         PyObject *extra_args,
-                                         PyObject *swap_data);
+GClosure *
+pygi_signal_closure_new (PyGObject *instance,
+                         GType g_type,
+                         const gchar *sig_name,
+                         PyObject *callback,
+                         PyObject *extra_args,
+                         PyObject *swap_data);
 
 G_END_DECLS
 
index 7346eae..9abaaae 100644 (file)
@@ -84,7 +84,7 @@ _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
  * GValue from Python
  */
 
-/* _pygi_marshal_from_py_gvalue:
+/* pygi_arg_gvalue_from_py_marshal:
  * py_arg: (in):
  * arg: (out):
  * transfer:
@@ -92,10 +92,10 @@ _is_union_member (GIInterfaceInfo *interface_info, PyObject *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) {
+pygi_arg_gvalue_from_py_marshal (PyObject *py_arg,
+                                 GIArgument *arg,
+                                 GITransfer transfer,
+                                 gboolean copy_reference) {
     GValue *value;
     GType object_type;
 
@@ -130,11 +130,11 @@ _pygi_marshal_from_py_gvalue (PyObject *py_arg,
 }
 
 void
-_pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state,
-                                                       PyGIArgCache    *arg_cache,
-                                                       PyObject        *py_arg,
-                                                       gpointer         data,
-                                                       gboolean         was_processed)
+pygi_arg_gvalue_from_py_cleanup (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) {
@@ -151,13 +151,13 @@ _pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state,
     }
 }
 
-/* _pygi_marshal_from_py_gclosure:
+/* pygi_arg_gclosure_from_py_marshal:
  * py_arg: (in):
  * arg: (out):
  */
 gboolean
-_pygi_marshal_from_py_gclosure(PyObject *py_arg,
-                               GIArgument *arg)
+pygi_arg_gclosure_from_py_marshal (PyObject *py_arg,
+                                   GIArgument *arg)
 {
     GClosure *closure;
     GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
@@ -183,21 +183,21 @@ _pygi_marshal_from_py_gclosure(PyObject *py_arg,
     return TRUE;
 }
 
-/* _pygi_marshal_from_py_interface_struct:
+/* pygi_arg_struct_from_py_marshal:
  *
  * 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)
+pygi_arg_struct_from_py_marshal (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;
 
@@ -211,12 +211,12 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
      */
 
     if (g_type_is_a (g_type, G_TYPE_CLOSURE)) {
-        return _pygi_marshal_from_py_gclosure (py_arg, arg);
+        return pygi_arg_gclosure_from_py_marshal (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);
+        return pygi_arg_gvalue_from_py_marshal(py_arg,
+                                               arg,
+                                               transfer,
+                                               copy_reference);
     } else if (is_foreign) {
         PyObject *success;
         success = pygi_struct_foreign_convert_to_g_argument (py_arg,
@@ -292,25 +292,25 @@ type_error:
 }
 
 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)
+arg_struct_from_py_marshal_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);
+    gboolean res =  pygi_arg_struct_from_py_marshal (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.
@@ -320,27 +320,28 @@ _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState   *state,
 }
 
 static void
-_pygi_marshal_cleanup_from_py_interface_struct_foreign (PyGIInvokeState *state,
-                                                        PyGIArgCache    *arg_cache,
-                                                        PyObject        *py_arg,
-                                                        gpointer         data,
-                                                        gboolean         was_processed)
+arg_foreign_from_py_cleanup (PyGIInvokeState *state,
+                             PyGIArgCache    *arg_cache,
+                             PyObject        *py_arg,
+                             gpointer         data,
+                             gboolean         was_processed)
 {
-    if (state->failed && 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)
+pygi_arg_struct_to_py_marshal (GIArgument *arg,
+                               GIInterfaceInfo *interface_info,
+                               GType g_type,
+                               PyObject *py_type,
+                               GITransfer transfer,
+                               gboolean is_allocated,
+                               gboolean is_foreign)
 {
     PyObject *py_obj = NULL;
 
@@ -400,89 +401,107 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg,
 }
 
 static PyObject *
-_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState   *state,
-                                                    PyGICallableCache *callable_cache,
-                                                    PyGIArgCache      *arg_cache,
-                                                    GIArgument        *arg)
+arg_struct_to_py_marshal_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);
+    return pygi_arg_struct_to_py_marshal (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)
+arg_foreign_to_py_cleanup (PyGIInvokeState *state,
+                           PyGIArgCache    *arg_cache,
+                           PyObject        *dummy,
+                           gpointer         data,
+                           gboolean         was_processed)
 {
-    if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+    if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
         pygi_struct_foreign_release (
             ( (PyGIInterfaceCache *)arg_cache)->interface_info,
             data);
+    }
 }
 
+static gboolean
+arg_type_class_from_py_marshal (PyGIInvokeState   *state,
+                                PyGICallableCache *callable_cache,
+                                PyGIArgCache      *arg_cache,
+                                PyObject          *py_arg,
+                                GIArgument        *arg,
+                                gpointer          *cleanup_data)
+{
+    GType gtype = pyg_type_from_object (py_arg);
+
+    if (G_TYPE_IS_CLASSED (gtype)) {
+        arg->v_pointer = g_type_class_ref (gtype);
+        *cleanup_data = arg->v_pointer;
+        return TRUE;
+    } else {
+        PyErr_Format (PyExc_TypeError,
+                      "Unable to retrieve a GObject type class from \"%s\".",
+                      Py_TYPE(py_arg)->tp_name);
+        return FALSE;
+    }
+}
 
 static void
-_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
-                                           GIInterfaceInfo *iface_info,
-                                           GITransfer transfer)
+arg_type_class_from_py_cleanup (PyGIInvokeState *state,
+                                PyGIArgCache    *arg_cache,
+                                PyObject        *py_arg,
+                                gpointer         data,
+                                gboolean         was_processed)
 {
-    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;
+    if (was_processed) {
+        g_type_class_unref (data);
+    }
 }
 
 static void
-_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
-                                         GIInterfaceInfo *iface_info,
-                                         GITransfer transfer)
+arg_struct_from_py_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;
-}
+    if (g_struct_info_is_gtype_struct ((GIStructInfo*)iface_info)) {
+        arg_cache->from_py_marshaller = arg_type_class_from_py_marshal;
+        /* Since we always add a ref in the marshalling, only unref the
+         * GTypeClass when we don't transfer ownership. */
+        if (transfer == GI_TRANSFER_NOTHING) {
+            arg_cache->from_py_cleanup = arg_type_class_from_py_cleanup;
+        }
 
-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.
-     */
+    } else {
+        arg_cache->from_py_marshaller = arg_struct_from_py_marshal_adapter;
 
-    if (direction & PYGI_DIRECTION_FROM_PYTHON) {
-        _arg_cache_from_py_interface_struct_setup (arg_cache,
-                                                   iface_info,
-                                                   transfer);
+        if (iface_cache->g_type == G_TYPE_VALUE)
+            arg_cache->from_py_cleanup = pygi_arg_gvalue_from_py_cleanup;
+        else if (iface_cache->is_foreign)
+            arg_cache->from_py_cleanup = arg_foreign_from_py_cleanup;
     }
+}
 
-    if (direction & PYGI_DIRECTION_TO_PYTHON) {
-        _arg_cache_to_py_interface_struct_setup (arg_cache,
-                                                 iface_info,
-                                                 transfer);
-    }
+static void
+arg_struct_to_py_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 = arg_struct_to_py_marshal_adapter;
 
-    return TRUE;
+    if (iface_cache->is_foreign)
+        arg_cache->to_py_cleanup = arg_foreign_to_py_cleanup;
 }
 
 PyGIArgCache *
@@ -492,7 +511,6 @@ pygi_arg_struct_new_from_info (GITypeInfo      *type_info,
                                PyGIDirection    direction,
                                GIInterfaceInfo *iface_info)
 {
-    gboolean res = FALSE;
     PyGIArgCache *cache = NULL;
 
     cache = pygi_arg_interface_new_from_info (type_info,
@@ -503,16 +521,13 @@ pygi_arg_struct_new_from_info (GITypeInfo      *type_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;
+    if (direction & PYGI_DIRECTION_FROM_PYTHON) {
+        arg_struct_from_py_setup (cache, iface_info, transfer);
     }
+
+    if (direction & PYGI_DIRECTION_TO_PYTHON) {
+        arg_struct_to_py_setup (cache, iface_info, transfer);
+    }
+
+    return cache;
 }
index 66e3ecf..6a7f92d 100644 (file)
@@ -33,40 +33,40 @@ PyGIArgCache *pygi_arg_struct_new_from_info  (GITypeInfo      *type_info,
                                               GIInterfaceInfo *iface_info);
 
 
-gboolean _pygi_marshal_from_py_gvalue (PyObject *py_arg, /*in*/
-                                       GIArgument *arg,  /*out*/
-                                       GITransfer transfer,
-                                       gboolean is_allocated);
+gboolean pygi_arg_gvalue_from_py_marshal     (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_arg_gclosure_from_py_marshal   (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);
+gboolean pygi_arg_struct_from_py_marshal     (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);
+PyObject *pygi_arg_struct_to_py_marshal      (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);
+void pygi_arg_gvalue_from_py_cleanup         (PyGIInvokeState *state,
+                                              PyGIArgCache    *arg_cache,
+                                              PyObject        *py_arg,
+                                              gpointer         data,
+                                              gboolean         was_processed);
 
 G_END_DECLS
 
index b1db8a4..692068b 100644 (file)
@@ -60,9 +60,9 @@ _struct_dealloc (PyGIStruct *self)
     GIBaseInfo *info = _struct_get_info ( (PyObject *) self );
 
     if (info != NULL && g_struct_info_is_foreign ( (GIStructInfo *) info)) {
-        pygi_struct_foreign_release (info, ( (PyGPointer *) self)->pointer);
+        pygi_struct_foreign_release (info, pyg_pointer_get_ptr (self));
     } else if (self->free_on_dealloc) {
-        g_free ( ( (PyGPointer *) self)->pointer);
+        g_free (pyg_pointer_get_ptr (self));
     }
 
     if (info != NULL) {
@@ -152,8 +152,8 @@ _pygi_struct_new (PyTypeObject *type,
 
     g_type = pyg_type_from_object ( (PyObject *) type);
 
+    pyg_pointer_set_ptr (self, pointer);
     ( (PyGPointer *) self)->gtype = g_type;
-    ( (PyGPointer *) self)->pointer = pointer;
     self->free_on_dealloc = free_on_dealloc;
 
     return (PyObject *) self;
index b8d4c65..924e0b8 100644 (file)
@@ -50,7 +50,7 @@ _pygi_type_import_by_name (const char *namespace_,
 }
 
 PyObject *
-pygi_type_import_by_g_type_real (GType g_type)
+pygi_type_import_by_g_type (GType g_type)
 {
     GIRepository *repository;
     GIBaseInfo *info;
@@ -89,7 +89,7 @@ _pygi_type_get_from_g_type (GType g_type)
 
     py_type = PyObject_GetAttrString (py_g_type, "pytype");
     if (py_type == Py_None) {
-        py_type = pygi_type_import_by_g_type_real (g_type);
+        py_type = pygi_type_import_by_g_type (g_type);
     }
 
     Py_DECREF (py_g_type);
index 822a441..85f7551 100644 (file)
 #define __PYGI_TYPE_H__
 
 #include <Python.h>
+#include <girepository.h>
 
 G_BEGIN_DECLS
 
 /* Public */
 
-PyObject *pygi_type_import_by_g_type_real (GType g_type);
+PyObject *pygi_type_import_by_g_type (GType g_type);
 
 
 /* Private */
index 8235116..f54f8e1 100644 (file)
@@ -555,7 +555,7 @@ pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj)
          * 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))
+        else if (pyg_param_spec_check (obj))
             g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
         else {
             PyErr_SetString(PyExc_TypeError, "Expected ParamSpec");
index a67696e..2a9ee14 100644 (file)
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -78,112 +78,5 @@ typedef struct {
     PyGICallableCache *cache;
 } PyGICCallback;
 
-typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject        *value,
-                                                       GIInterfaceInfo *interface_info,
-                                                       GITransfer       transfer,
-                                                       GIArgument      *arg);
-typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info,
-                                                         GITransfer       transfer,
-                                                         gpointer         data);
-typedef PyObject * (*PyGIArgOverrideReleaseFunc) (GITypeInfo *type_info,
-                                                  gpointer  struct_);
-
-struct PyGI_API {
-    PyObject* (*type_import_by_g_type) (GType g_type);
-    PyObject* (*get_property_value) (PyGObject *instance,
-                                     GParamSpec *pspec);
-    gint (*set_property_value) (PyGObject *instance,
-                                GParamSpec *pspec,
-                                PyObject *value);
-    GClosure * (*signal_closure_new) (PyGObject *instance,
-                                      GType g_type,
-                                      const gchar *sig_name,
-                                      PyObject *callback,
-                                      PyObject *extra_args,
-                                      PyObject *swap_data);
-    void (*register_foreign_struct) (const char* namespace_,
-                                     const char* name,
-                                     PyGIArgOverrideToGIArgumentFunc to_func,
-                                     PyGIArgOverrideFromGIArgumentFunc from_func,
-                                     PyGIArgOverrideReleaseFunc release_func);
-};
-
-static struct PyGI_API *PyGI_API = NULL;
-
-static int
-_pygi_import (void)
-{
-    if (PyGI_API != NULL) {
-        return 1;
-    }
-    PyGI_API = (struct PyGI_API*) PyCapsule_Import("gi._API", FALSE);
-    if (PyGI_API == NULL) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static inline PyObject *
-pygi_type_import_by_g_type (GType g_type)
-{
-    if (_pygi_import() < 0) {
-        return NULL;
-    }
-    return PyGI_API->type_import_by_g_type(g_type);
-}
-
-static inline PyObject *
-pygi_get_property_value (PyGObject *instance,
-                         GParamSpec *pspec)
-{
-    if (_pygi_import() < 0) {
-        return NULL;
-    }
-    return PyGI_API->get_property_value(instance, pspec);
-}
-
-static inline gint
-pygi_set_property_value (PyGObject *instance,
-                         GParamSpec *pspec,
-                         PyObject *value)
-{
-    if (_pygi_import() < 0) {
-        return -1;
-    }
-    return PyGI_API->set_property_value(instance, pspec, value);
-}
-
-static inline GClosure *
-pygi_signal_closure_new (PyGObject *instance,
-                         GType g_type,
-                         const gchar *sig_name,
-                         PyObject *callback,
-                         PyObject *extra_args,
-                         PyObject *swap_data)
-{
-    if (_pygi_import() < 0) {
-        return NULL;
-    }
-    return PyGI_API->signal_closure_new(instance, g_type, sig_name, callback, extra_args, swap_data);
-}
-
-static inline PyObject *
-pygi_register_foreign_struct (const char* namespace_,
-                              const char* name,
-                              PyGIArgOverrideToGIArgumentFunc to_func,
-                              PyGIArgOverrideFromGIArgumentFunc from_func,
-                              PyGIArgOverrideReleaseFunc release_func)
-{
-    if (_pygi_import() < 0) {
-        return NULL;
-    }
-    PyGI_API->register_foreign_struct(namespace_,
-                                      name,
-                                      to_func,
-                                      from_func,
-                                      release_func);
-    Py_RETURN_NONE;
-}
 
 #endif /* __PYGI_H__ */
index 3569c6b..78dd489 100644 (file)
@@ -31,7 +31,6 @@ 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
index 6c52f31..8db9b17 100644 (file)
 #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:
index 544bada..00228dd 100644 (file)
@@ -37,11 +37,6 @@ typedef void (*PyGLibThreadBlockFunc) (void);
 #    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. */
index be565d6..b6242cd 100644 (file)
@@ -53,7 +53,6 @@ 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);
@@ -62,8 +61,6 @@ 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);
 
index 04fd6a5..1a011e1 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "pygi.h"
 #include "pygi-value.h"
+#include "pygi-type.h"
+#include "pygi-property.h"
+#include "pygi-signal-closure.h"
 
 static void pygobject_dealloc(PyGObject *self);
 static int  pygobject_traverse(PyGObject *self, visitproc visit, void *arg);
index 76b8b11..85359a5 100644 (file)
@@ -57,6 +57,8 @@ typedef struct {
 } PyGBoxed;
 
 #define pyg_boxed_get(v,t)      ((t *)((PyGBoxed *)(v))->boxed)
+#define pyg_boxed_get_ptr(v)    (((PyGBoxed *)(v))->boxed)
+#define pyg_boxed_set_ptr(v,p)  (((PyGBoxed *)(v))->boxed = (gpointer)p)
 #define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
 
 typedef struct {
@@ -66,6 +68,8 @@ typedef struct {
 } PyGPointer;
 
 #define pyg_pointer_get(v,t)      ((t *)((PyGPointer *)(v))->pointer)
+#define pyg_pointer_get_ptr(v)    (((PyGPointer *)(v))->pointer)
+#define pyg_pointer_set_ptr(v,p)  (((PyGPointer *)(v))->pointer = (gpointer)p)
 #define pyg_pointer_check(v,typecode) (PyObject_TypeCheck(v, &PyGPointer_Type) && ((PyGPointer *)(v))->gtype == typecode)
 
 typedef void (*PyGFatalExceptionFunc) (void);
@@ -76,8 +80,13 @@ typedef struct {
     GParamSpec *pspec;
 } PyGParamSpec;
 
-#define PyGParamSpec_Get(v) (((PyGParamSpec *)v)->pspec)
-#define PyGParamSpec_Check(v) (PyObject_TypeCheck(v, &PyGParamSpec_Type))
+#define pyg_param_spec_get(v)    (((PyGParamSpec *)v)->pspec)
+#define pyg_param_spec_set(v,p)  (((PyGParamSpec *)v)->pspec = (GParamSpec*)p)
+#define pyg_param_spec_check(v)  (PyObject_TypeCheck(v, &PyGParamSpec_Type))
+
+/* Deprecated in favor of lower case with underscore macros above. */
+#define PyGParamSpec_Get    pyg_param_spec_get
+#define PyGParamSpec_Check  pyg_param_spec_check
 
 typedef int (*PyGClassInitFunc) (gpointer gclass, PyTypeObject *pyclass);
 typedef PyTypeObject * (*PyGTypeRegistrationFunction) (const gchar *name,
index f6bb223..ab439f0 100644 (file)
@@ -25,6 +25,7 @@
 #include <pyglib.h>
 #include "pyglib-private.h"
 #include "pygoptioncontext.h"
+#include "pygi-error.h"
 
 PYGLIB_DEFINE_TYPE("gi._glib.OptionContext", PyGOptionContext_Type, PyGOptionContext)
 
@@ -138,7 +139,7 @@ pyg_option_context_parse(PyGOptionContext *self,
     {
         g_strfreev(argv_content);
         g_strfreev(original);
-        pyglib_error_check(&error);
+        pygi_error_check(&error);
         return NULL;
     }
 
index 613232f..4c1664d 100644 (file)
@@ -25,6 +25,7 @@
 #include <pyglib.h>
 #include "pyglib-private.h"
 #include "pygoptiongroup.h"
+#include "pygi-error.h"
 
 PYGLIB_DEFINE_TYPE("gi._glib.OptionGroup", PyGOptionGroup_Type, PyGOptionGroup)
 
@@ -148,7 +149,7 @@ arg_func(const gchar *option_name,
         Py_DECREF(ret);
         no_error = TRUE;
     } else
-       no_error = pyglib_gerror_exception_check(error) != -1;
+       no_error = pygi_gerror_exception_check(error) != -1;
 
     pyglib_gil_state_release(state);
     return no_error;
index 9e6c467..ff53243 100644 (file)
@@ -34,9 +34,9 @@ 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);
+        return _pyglib_generic_ptr_richcompare (pyg_param_spec_get (self),
+                                                pyg_param_spec_get (other),
+                                                op);
     else {
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
@@ -46,7 +46,7 @@ pyg_param_spec_richcompare(PyObject *self, PyObject *other, int op)
 static long
 pyg_param_spec_hash(PyGParamSpec *self)
 {
-    return (long)self->pspec;
+    return (long)pyg_param_spec_get (self);
 }
 
 static PyObject *
@@ -55,15 +55,15 @@ 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));
+              G_PARAM_SPEC_TYPE_NAME (pyg_param_spec_get (self)),
+              g_param_spec_get_name (pyg_param_spec_get (self)));
     return PYGLIB_PyUnicode_FromString(buf);
 }
 
 static void
 pyg_param_spec_dealloc(PyGParamSpec *self)
 {
-    g_param_spec_unref(self->pspec);
+    g_param_spec_unref (pyg_param_spec_get (self));
     PyObject_DEL(self);
 }
 
@@ -112,8 +112,8 @@ pyg_param_spec_getattr(PyGParamSpec *self, const gchar *attr)
 {
     GParamSpec *pspec;
 
-    pspec = self->pspec;
-    
+    pspec = pyg_param_spec_get (self);
+
     /* common attributes */
     if (!strcmp(attr, "__gtype__")) {
        return pyg_type_wrapper_new(G_PARAM_SPEC_TYPE(pspec));
@@ -281,7 +281,7 @@ pyg_param_spec_getattr(PyGParamSpec *self, const gchar *attr)
 static PyObject *
 pyg_param_spec_dir(PyGParamSpec *self, PyObject *dummy)
 {
-    GParamSpec *pspec = self->pspec;
+    GParamSpec *pspec = pyg_param_spec_get (self);
 
     if (G_IS_PARAM_SPEC_CHAR(pspec)) {
         return Py_BuildValue("[sssssssssss]", "__doc__", "__gtype__",
@@ -393,7 +393,7 @@ pyg_param_spec_new(GParamSpec *pspec)
     if (self == NULL)
        return NULL;
 
-    self->pspec = g_param_spec_ref(pspec);
+    pyg_param_spec_set (self, g_param_spec_ref (pspec));
     return (PyObject *)self;
 }
 
index 2729695..d728a40 100644 (file)
@@ -27,6 +27,7 @@
 #include "pygpointer.h"
 
 #include "pygi.h"
+#include "pygi-type.h"
 
 
 GQuark pygpointer_class_key;
@@ -43,9 +44,9 @@ 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);
+        return _pyglib_generic_ptr_richcompare (pyg_pointer_get_ptr (self),
+                                                pyg_pointer_get_ptr (other),
+                                                op);
     else {
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
@@ -55,7 +56,7 @@ pyg_pointer_richcompare(PyObject *self, PyObject *other, int op)
 static long
 pyg_pointer_hash(PyGPointer *self)
 {
-    return (long)self->pointer;
+    return (long)pyg_pointer_get_ptr (self);
 }
 
 static PyObject *
@@ -64,7 +65,7 @@ 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);
+              (long)pyg_pointer_get_ptr (self));
     return PYGLIB_PyUnicode_FromString(buf);
 }
 
@@ -76,7 +77,7 @@ pyg_pointer_init(PyGPointer *self, PyObject *args, PyObject *kwargs)
     if (!PyArg_ParseTuple(args, ":GPointer.__init__"))
        return -1;
 
-    self->pointer = NULL;
+    pyg_pointer_set_ptr (self, NULL);
     self->gtype = 0;
 
     g_snprintf(buf, sizeof(buf), "%s can not be constructed",
@@ -174,7 +175,7 @@ pyg_pointer_new(GType pointer_type, gpointer pointer)
     if (self == NULL)
        return NULL;
 
-    self->pointer = pointer;
+    pyg_pointer_set_ptr (self, pointer);
     self->gtype = pointer_type;
 
     return (PyObject *)self;
index 8f3ff51..3851ad9 100644 (file)
@@ -26,6 +26,7 @@
 #include "pyglib-private.h"
 
 #include "pygspawn.h"
+#include "pygi-error.h"
 
 struct _PyGChildSetupData {
     PyObject *func;
@@ -214,7 +215,7 @@ pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs)
             Py_XDECREF(callback_data->data);
             g_slice_free(struct _PyGChildSetupData, callback_data);
         }
-        pyglib_error_check(&error);
+        pygi_error_check(&error);
         return NULL;
     }
     g_free(argv);
index 131a271..985e969 100644 (file)
@@ -28,6 +28,7 @@
 #include "pygparamspec.h"
 #include "pygtype.h"
 
+#include "pygi-type.h"
 #include "pygi-value.h"
 
 /* -------------- __gtype__ objects ---------------------------- */
@@ -621,6 +622,7 @@ pyg_type_lookup(GType type)
 
     /* recursively lookup types */
     while (ptype) {
+        pygi_type_import_by_g_type (ptype);
        if ((tm = g_type_get_qdata(ptype, pyg_type_marshal_key)) != NULL)
            break;
        ptype = g_type_parent(ptype);
@@ -888,7 +890,8 @@ pyg_signal_class_closure_marshal(GClosure *closure,
            && 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);
+               gpointer boxed_ptr = pyg_boxed_get_ptr (boxed_item);
+               pyg_boxed_set_ptr (boxed_item, g_boxed_copy (boxed_item->gtype, boxed_ptr));
                boxed_item->free_on_dealloc = TRUE;
            }
        }
index e6e3903..aa5bcb4 100644 (file)
@@ -55,6 +55,17 @@ class MetaClassHelper(object):
         for method_info in cls.__info__.get_methods():
             setattr(cls, method_info.__name__, method_info)
 
+    def _setup_class_methods(cls):
+        info = cls.__info__
+        class_struct = info.get_class_struct()
+        if class_struct is None:
+            return
+        for method_info in class_struct.get_methods():
+            name = method_info.__name__
+            # Don't mask regular methods or base class methods with TypeClass methods.
+            if not hasattr(cls, name):
+                setattr(cls, name, classmethod(method_info))
+
     def _setup_fields(cls):
         for field_info in cls.__info__.get_fields():
             name = field_info.get_name().replace('-', '_')
@@ -182,7 +193,7 @@ class _GObjectMetaBase(type):
         cls._type_register(cls.__dict__)
 
     def _type_register(cls, namespace):
-        ## don't register the class if already registered
+        # don't register the class if already registered
         if '__gtype__' in namespace:
             return
 
@@ -211,6 +222,8 @@ class GObjectMeta(_GObjectMetaBase, MetaClassHelper):
         if is_python_defined:
             cls._setup_vfuncs()
         elif is_gi_defined:
+            if isinstance(cls.__info__, ObjectInfo):
+                cls._setup_class_methods()
             cls._setup_methods()
             cls._setup_constants()
             cls._setup_native_vfuncs()
index d5b7b94..7ee2de4 100644 (file)
@@ -38,8 +38,10 @@ import warnings
 try:
     # Python 3
     from collections import UserList
-    from imp import reload
     UserList  # pyflakes
+    with warnings.catch_warnings():
+        warnings.simplefilter('ignore')
+        from imp import reload
 except ImportError:
     # Python 2 ships that in a different module
     from UserList import UserList
@@ -357,10 +359,10 @@ def enable_gtk(version='3.0'):
     except AttributeError:
         pass
 
-    #AccelGroup
+    # AccelGroup
     Gtk.AccelGroup.connect_group = Gtk.AccelGroup.connect
 
-    #StatusIcon
+    # StatusIcon
     Gtk.status_icon_position_menu = Gtk.StatusIcon.position_menu
     Gtk.StatusIcon.set_tooltip = Gtk.StatusIcon.set_tooltip_text
 
index 3468740..c0f34f8 100644 (file)
@@ -84,6 +84,8 @@ EXTRA_DIST = \
        test-unknown.h \
        te_ST@nouppera \
        org.gnome.test.gschema.xml \
+       test_cairo.py \
+       test_error.py \
        test_gio.py \
        test_glib.py \
        test_gobject.py \
@@ -99,6 +101,7 @@ EXTRA_DIST = \
        test_source.py \
        test_subprocess.py \
        test_thread.py \
+       test_typeclass.py \
        test_everything.py \
        test_gi.py \
        test_gdbus.py \
index 5b94b34..cdadc6f 100644 (file)
@@ -382,6 +382,8 @@ EXTRA_DIST = \
        test-unknown.h \
        te_ST@nouppera \
        org.gnome.test.gschema.xml \
+       test_cairo.py \
+       test_error.py \
        test_gio.py \
        test_glib.py \
        test_gobject.py \
@@ -397,6 +399,7 @@ EXTRA_DIST = \
        test_source.py \
        test_subprocess.py \
        test_thread.py \
+       test_typeclass.py \
        test_everything.py \
        test_gi.py \
        test_gdbus.py \
diff --git a/tests/test_cairo.py b/tests/test_cairo.py
new file mode 100644 (file)
index 0000000..fdf86a2
--- /dev/null
@@ -0,0 +1,141 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# coding=utf-8
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+
+import gi
+
+try:
+    gi.require_foreign('cairo')
+    import cairo
+    from gi.repository import Regress
+    has_cairo = True
+except ImportError:
+    has_cairo = False
+
+try:
+    from gi.repository import Gtk
+    Gtk  # pyflakes
+except:
+    Gtk = None
+
+from gi.repository import GObject
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
+class Test(unittest.TestCase):
+    def test_cairo_context(self):
+        context = Regress.test_cairo_context_full_return()
+        self.assertTrue(isinstance(context, cairo.Context))
+
+        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
+        context = cairo.Context(surface)
+        Regress.test_cairo_context_none_in(context)
+
+    def test_cairo_surface(self):
+        surface = Regress.test_cairo_surface_none_return()
+        self.assertTrue(isinstance(surface, cairo.ImageSurface))
+        self.assertTrue(isinstance(surface, cairo.Surface))
+        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+        self.assertEqual(surface.get_width(), 10)
+        self.assertEqual(surface.get_height(), 10)
+
+        surface = Regress.test_cairo_surface_full_return()
+        self.assertTrue(isinstance(surface, cairo.ImageSurface))
+        self.assertTrue(isinstance(surface, cairo.Surface))
+        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+        self.assertEqual(surface.get_width(), 10)
+        self.assertEqual(surface.get_height(), 10)
+
+        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
+        Regress.test_cairo_surface_none_in(surface)
+
+        surface = Regress.test_cairo_surface_full_out()
+        self.assertTrue(isinstance(surface, cairo.ImageSurface))
+        self.assertTrue(isinstance(surface, cairo.Surface))
+        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
+        self.assertEqual(surface.get_width(), 10)
+        self.assertEqual(surface.get_height(), 10)
+
+    def test_require_foreign(self):
+        self.assertEqual(gi.require_foreign('cairo'), None)
+        self.assertEqual(gi.require_foreign('cairo', 'Context'), None)
+        self.assertRaises(ImportError, gi.require_foreign, 'invalid_module')
+        self.assertRaises(ImportError, gi.require_foreign, 'invalid_module', 'invalid_symbol')
+        self.assertRaises(ImportError, gi.require_foreign, 'cairo', 'invalid_symbol')
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestPango(unittest.TestCase):
+    def test_cairo_font_options(self):
+        screen = Gtk.Window().get_screen()
+        font_opts = screen.get_font_options()
+        self.assertEqual(type(font_opts.get_subpixel_order()), int)
+
+
+if has_cairo:
+    from gi.repository import cairo as CairoGObject
+
+    # Use PyGI signals to test non-introspected foreign marshaling.
+    class CairoSignalTester(GObject.Object):
+        sig_context = GObject.Signal(arg_types=[CairoGObject.Context])
+        sig_surface = GObject.Signal(arg_types=[CairoGObject.Surface])
+        sig_font_face = GObject.Signal(arg_types=[CairoGObject.FontFace])
+        sig_scaled_font = GObject.Signal(arg_types=[CairoGObject.ScaledFont])
+        sig_pattern = GObject.Signal(arg_types=[CairoGObject.Pattern])
+
+
+@unittest.skipUnless(has_cairo, 'built without cairo support')
+class TestSignalMarshaling(unittest.TestCase):
+    # Tests round tripping of cairo objects through non-introspected signals.
+
+    def setUp(self):
+        self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
+        self.context = cairo.Context(self.surface)
+        self.tester = CairoSignalTester()
+
+    def pass_object_through_signal(self, obj, signal):
+        """Pass the given `obj` through the `signal` emission storing the
+        `obj` passed through the signal and returning it."""
+        passthrough_result = []
+
+        def callback(instance, passthrough):
+            passthrough_result.append(passthrough)
+
+        signal.connect(callback)
+        signal.emit(obj)
+
+        return passthrough_result[0]
+
+    def test_context(self):
+        result = self.pass_object_through_signal(self.context, self.tester.sig_context)
+        self.assertTrue(isinstance(result, cairo.Context))
+
+    def test_surface(self):
+        result = self.pass_object_through_signal(self.surface, self.tester.sig_surface)
+        self.assertTrue(isinstance(result, cairo.Surface))
+
+    def test_font_face(self):
+        font_face = self.context.get_font_face()
+        result = self.pass_object_through_signal(font_face, self.tester.sig_font_face)
+        self.assertTrue(isinstance(result, cairo.FontFace))
+
+    def test_scaled_font(self):
+        scaled_font = cairo.ScaledFont(self.context.get_font_face(),
+                                       cairo.Matrix(),
+                                       cairo.Matrix(),
+                                       self.context.get_font_options())
+        result = self.pass_object_through_signal(scaled_font, self.tester.sig_scaled_font)
+        self.assertTrue(isinstance(result, cairo.ScaledFont))
+
+    def test_pattern(self):
+        pattern = cairo.SolidPattern(1, 1, 1, 1)
+        result = self.pass_object_through_signal(pattern, self.tester.sig_pattern)
+        self.assertTrue(isinstance(result, cairo.Pattern))
+        self.assertTrue(isinstance(result, cairo.SolidPattern))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_error.py b/tests/test_error.py
new file mode 100644 (file)
index 0000000..baccef5
--- /dev/null
@@ -0,0 +1,116 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# test_error.py: Tests for GError wrapper implementation
+#
+# Copyright (C) 2012 Will Thompson
+# Copyright (C) 2013 Martin Pitt
+# Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
+#
+# 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 St, Fifth Floor, Boston, MA  02110-1301
+# USA
+
+import unittest
+
+from gi.repository import GLib
+from gi.repository import GIMarshallingTests
+
+
+class TestType(unittest.TestCase):
+    def test_attributes(self):
+        e = GLib.Error('test message', 'mydomain', 42)
+        self.assertEqual(e.message, 'test message')
+        self.assertEqual(e.domain, 'mydomain')
+        self.assertEqual(e.code, 42)
+
+    def test_new_literal(self):
+        mydomain = GLib.quark_from_string('mydomain')
+        e = GLib.Error.new_literal(mydomain, 'test message', 42)
+        self.assertEqual(e.message, 'test message')
+        self.assertEqual(e.domain, 'mydomain')
+        self.assertEqual(e.code, 42)
+
+    def test_matches(self):
+        mydomain = GLib.quark_from_string('mydomain')
+        notmydomain = GLib.quark_from_string('notmydomain')
+        e = GLib.Error('test message', 'mydomain', 42)
+        self.assertTrue(e.matches(mydomain, 42))
+        self.assertFalse(e.matches(notmydomain, 42))
+        self.assertFalse(e.matches(mydomain, 40))
+
+    def test_str(self):
+        e = GLib.Error('test message', 'mydomain', 42)
+        self.assertEqual(str(e),
+                         'mydomain: test message (42)')
+
+    def test_repr(self):
+        e = GLib.Error('test message', 'mydomain', 42)
+        self.assertEqual(repr(e),
+                         "GLib.Error('test message', 'mydomain', 42)")
+
+    def test_inheritance(self):
+        self.assertTrue(issubclass(GLib.Error, RuntimeError))
+
+
+class TestMarshalling(unittest.TestCase):
+    def test_array_in_crash(self):
+        # Previously there was a bug in invoke, in which C arrays were unwrapped
+        # from inside GArrays to be passed to the C function. But when a GError was
+        # set, invoke would attempt to free the C array as if it were a GArray.
+        # This crash is only for C arrays. It does not happen for C functions which
+        # take in GArrays. See https://bugzilla.gnome.org/show_bug.cgi?id=642708
+        self.assertRaises(GLib.Error, GIMarshallingTests.gerror_array_in, [1, 2, 3])
+
+    def test_out(self):
+        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+        error, debug = GIMarshallingTests.gerror_out()
+
+        self.assertIsInstance(error, GLib.Error)
+        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+        self.assertEqual(debug, GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE)
+
+    def test_out_transfer_none(self):
+        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+        error, debug = GIMarshallingTests.gerror_out_transfer_none()
+
+        self.assertIsInstance(error, GLib.Error)
+        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+        self.assertEqual(GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE, debug)
+
+    def test_return(self):
+        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
+        error = GIMarshallingTests.gerror_return()
+
+        self.assertIsInstance(error, GLib.Error)
+        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+
+    def test_exception(self):
+        with self.assertRaises(GLib.Error) as context:
+            GIMarshallingTests.gerror()
+
+        e = context.exception
+        self.assertEqual(e.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+        self.assertEqual(e.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+        self.assertEqual(e.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+
+
+if __name__ == '__main__':
+    unittest.main()
index 0cd1804..f6017e4 100644 (file)
@@ -10,12 +10,12 @@ import sys
 
 try:
     import cairo
+    cairo  # Pyflakes
     has_cairo = True
     from gi.repository import Regress as Everything
 except ImportError:
     has_cairo = False
 
-#import gi
 from gi.repository import GObject
 from gi.repository import GLib
 from gi.repository import Gio
@@ -47,39 +47,6 @@ class RawGList(ctypes.Structure):
 @unittest.skipUnless(has_cairo, 'built without cairo support')
 class TestEverything(unittest.TestCase):
 
-    def test_cairo_context(self):
-        context = Everything.test_cairo_context_full_return()
-        self.assertTrue(isinstance(context, cairo.Context))
-
-        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
-        context = cairo.Context(surface)
-        Everything.test_cairo_context_none_in(context)
-
-    def test_cairo_surface(self):
-        surface = Everything.test_cairo_surface_none_return()
-        self.assertTrue(isinstance(surface, cairo.ImageSurface))
-        self.assertTrue(isinstance(surface, cairo.Surface))
-        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
-        self.assertEqual(surface.get_width(), 10)
-        self.assertEqual(surface.get_height(), 10)
-
-        surface = Everything.test_cairo_surface_full_return()
-        self.assertTrue(isinstance(surface, cairo.ImageSurface))
-        self.assertTrue(isinstance(surface, cairo.Surface))
-        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
-        self.assertEqual(surface.get_width(), 10)
-        self.assertEqual(surface.get_height(), 10)
-
-        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
-        Everything.test_cairo_surface_none_in(surface)
-
-        surface = Everything.test_cairo_surface_full_out()
-        self.assertTrue(isinstance(surface, cairo.ImageSurface))
-        self.assertTrue(isinstance(surface, cairo.Surface))
-        self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
-        self.assertEqual(surface.get_width(), 10)
-        self.assertEqual(surface.get_height(), 10)
-
     def test_bool(self):
         self.assertEqual(Everything.test_boolean(False), False)
         self.assertEqual(Everything.test_boolean(True), True)
@@ -1347,12 +1314,3 @@ class TestSignals(unittest.TestCase):
         self.assertEqual(obj.callback_i, 42)
         self.assertEqual(type(rv), GLib.Array)
         self.assertEqual(rv.len, 2)
-
-
-@unittest.skipUnless(has_cairo, 'built without cairo support')
-@unittest.skipUnless(Gtk, 'Gtk not available')
-class TestPango(unittest.TestCase):
-    def test_cairo_font_options(self):
-        screen = Gtk.Window().get_screen()
-        font_opts = screen.get_font_options()
-        self.assertEqual(type(font_opts.get_subpixel_order()), int)
index 9846440..4a5d510 100644 (file)
@@ -61,9 +61,8 @@ class Sequence(object):
 
 class TestConstant(unittest.TestCase):
 
-# Blocked by https://bugzilla.gnome.org/show_bug.cgi?id=595773
-#    def test_constant_utf8(self):
-#        self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.CONSTANT_UTF8)
+    def test_constant_utf8(self):
+        self.assertEqual(CONSTANT_UTF8, GIMarshallingTests.CONSTANT_UTF8)
 
     def test_constant_number(self):
         self.assertEqual(CONSTANT_NUMBER, GIMarshallingTests.CONSTANT_NUMBER)
@@ -2009,7 +2008,6 @@ class TestGObject(unittest.TestCase):
 
         GIMarshallingTests.Object.none_inout(GIMarshallingTests.SubObject(int=42))
 
-    @unittest.expectedFailure  # https://bugzilla.gnome.org/show_bug.cgi?id=709796
     def test_object_full_inout(self):
         # Using gimarshallingtests.c from GI versions > 1.38.0 will show this
         # test as an "unexpected success" due to reference leak fixes in that file.
@@ -2524,9 +2522,7 @@ class TestOverrides(unittest.TestCase):
 
         # not overridden
         self.assertEqual(GIMarshallingTests.SubObject.__module__, 'gi.repository.GIMarshallingTests')
-        # FIXME: does not work with TEST_NAMES='test_thread test_gi.TestOverrides',
-        # it is importlib._bootstrap then
-        #self.assertEqual(GObject.InitiallyUnowned.__module__, 'gi.repository.GObject')
+        self.assertEqual(GObject.InitiallyUnowned.__module__, 'gi.repository.GObject')
 
 
 class TestDir(unittest.TestCase):
@@ -2554,55 +2550,6 @@ class TestDir(unittest.TestCase):
         # self.assertTrue('DoNotImportDummyTests' in list)
 
 
-class TestGError(unittest.TestCase):
-    def test_array_in_crash(self):
-        # Previously there was a bug in invoke, in which C arrays were unwrapped
-        # from inside GArrays to be passed to the C function. But when a GError was
-        # set, invoke would attempt to free the C array as if it were a GArray.
-        # This crash is only for C arrays. It does not happen for C functions which
-        # take in GArrays. See https://bugzilla.gnome.org/show_bug.cgi?id=642708
-        self.assertRaises(GObject.GError, GIMarshallingTests.gerror_array_in, [1, 2, 3])
-
-    def test_out(self):
-        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
-        error, debug = GIMarshallingTests.gerror_out()
-
-        self.assertIsInstance(error, GObject.GError)
-        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
-        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
-        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
-        self.assertEqual(debug, GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE)
-
-    def test_out_transfer_none(self):
-        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
-        error, debug = GIMarshallingTests.gerror_out_transfer_none()
-
-        self.assertIsInstance(error, GObject.GError)
-        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
-        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
-        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
-        self.assertEqual(GIMarshallingTests.CONSTANT_GERROR_DEBUG_MESSAGE, debug)
-
-    def test_return(self):
-        # See https://bugzilla.gnome.org/show_bug.cgi?id=666098
-        error = GIMarshallingTests.gerror_return()
-
-        self.assertIsInstance(error, GObject.GError)
-        self.assertEqual(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
-        self.assertEqual(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
-        self.assertEqual(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
-
-    def test_exception(self):
-        self.assertRaises(GObject.GError, GIMarshallingTests.gerror)
-        try:
-            GIMarshallingTests.gerror()
-        except Exception:
-            etype, e = sys.exc_info()[:2]
-            self.assertEqual(e.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
-            self.assertEqual(e.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
-            self.assertEqual(e.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
-
-
 class TestParamSpec(unittest.TestCase):
     # https://bugzilla.gnome.org/show_bug.cgi?id=682355
     @unittest.expectedFailure
index 57ab013..986d6dc 100644 (file)
@@ -40,7 +40,7 @@ class TestGio(unittest.TestCase):
 
 class TestGSettings(unittest.TestCase):
     def setUp(self):
-        self.settings = Gio.Settings('org.gnome.test')
+        self.settings = Gio.Settings(schema='org.gnome.test')
         # we change the values in the tests, so set them to predictable start
         # value
         self.settings.reset('test-string')
@@ -78,7 +78,7 @@ class TestGSettings(unittest.TestCase):
         self.assertEqual(self.settings.get_property('path'), '/tests/')
 
         # optional constructor arguments
-        with_path = Gio.Settings('org.gnome.nopathtest', path='/mypath/')
+        with_path = Gio.Settings(schema='org.gnome.nopathtest', path='/mypath/')
         self.assertEqual(with_path.get_property('path'), '/mypath/')
         self.assertEqual(with_path['np-int'], 42)
 
@@ -115,7 +115,7 @@ class TestGSettings(unittest.TestCase):
         self.assertRaises(KeyError, self.settings.__setitem__, 'unknown', 'moo')
 
     def test_empty(self):
-        empty = Gio.Settings('org.gnome.empty', path='/tests/')
+        empty = Gio.Settings(schema='org.gnome.empty', path='/tests/')
         self.assertEqual(len(empty), 0)
         self.assertEqual(bool(empty), True)
         self.assertEqual(empty.keys(), [])
index 0cc1b4b..259171b 100644 (file)
@@ -108,7 +108,7 @@ second line
 
         ch.seek(2, 2)  # SEEK_END
         # FIXME: does not work currently
-        #self.assertEqual(ch.read(2), b'n!')
+        # self.assertEqual(ch.read(2), b'n!')
 
         # invalid whence value
         self.assertRaises(ValueError, ch.seek, 0, 3)
index 2900edd..fe25746 100644 (file)
@@ -71,7 +71,7 @@ class TestOption(unittest.TestCase):
     def test_parse_args_double_dash(self):
         options, args = self.parser.parse_args(
             ["test_option.py", "--", "-xxx"])
-        #self.assertEqual(args, ["-xxx"])
+        # self.assertEqual(args, ["-xxx"])
 
     def test_parse_args_group(self):
         group = self._create_group()
index 2a0fd90..d339adf 100644 (file)
@@ -632,6 +632,35 @@ class TestGtk(unittest.TestCase):
 
 
 @unittest.skipUnless(Gtk, 'Gtk not available')
+class TestWidget(unittest.TestCase):
+    def test_style_get_property_gvalue(self):
+        button = Gtk.Button()
+        value = GObject.Value(int, -42)
+        button.style_get_property('focus-padding', value)
+        # Test only that the style property changed since we can't actuall
+        # set it.
+        self.assertNotEqual(value.get_int(), -42)
+
+    def test_style_get_property_return_with_explicit_gvalue(self):
+        button = Gtk.Button()
+        value = GObject.Value(int, -42)
+        result = button.style_get_property('focus-padding', value)
+        self.assertIsInstance(result, int)
+        self.assertNotEqual(result, -42)
+
+    def test_style_get_property_return_with_implicit_gvalue(self):
+        button = Gtk.Button()
+        result = button.style_get_property('focus-padding')
+        self.assertIsInstance(result, int)
+        self.assertNotEqual(result, -42)
+
+    def test_style_get_property_error(self):
+        button = Gtk.Button()
+        with self.assertRaises(ValueError):
+            button.style_get_property('not-a-valid-style-property')
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
 class TestSignals(unittest.TestCase):
     def test_class_closure_override_with_aliased_type(self):
         class WindowWithSizeAllocOverride(Gtk.ScrolledWindow):
@@ -1796,3 +1825,66 @@ class TestTextBuffer(unittest.TestCase):
                                         None)
         self.assertEqual(start.get_offset(), 6)
         self.assertEqual(end.get_offset(), 11)
+
+
+@unittest.skipUnless(Gtk, 'Gtk not available')
+class TestContainer(unittest.TestCase):
+    def test_child_set_property(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=False, fill=True, padding=0)
+
+        box.child_set_property(child, 'padding', 42)
+
+        value = GObject.Value(int)
+        box.child_get_property(child, 'padding', value)
+        self.assertEqual(value.get_int(), 42)
+
+    def test_child_get_property_gvalue(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=False, fill=True, padding=42)
+
+        value = GObject.Value(int)
+        box.child_get_property(child, 'padding', value)
+        self.assertEqual(value.get_int(), 42)
+
+    def test_child_get_property_return_with_explicit_gvalue(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=False, fill=True, padding=42)
+
+        value = GObject.Value(int)
+        result = box.child_get_property(child, 'padding', value)
+        self.assertEqual(result, 42)
+
+    def test_child_get_property_return_with_implicit_gvalue(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=False, fill=True, padding=42)
+
+        result = box.child_get_property(child, 'padding')
+        self.assertEqual(result, 42)
+
+    def test_child_get_property_error(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=False, fill=True, padding=42)
+        with self.assertRaises(ValueError):
+            box.child_get_property(child, 'not-a-valid-child-property')
+
+    def test_child_get_and_set(self):
+        box = Gtk.Box()
+        child = Gtk.Button()
+        box.pack_start(child, expand=True, fill=True, padding=42)
+
+        expand, fill, padding = box.child_get(child, 'expand', 'fill', 'padding')
+        self.assertEqual(expand, True)
+        self.assertEqual(fill, True)
+        self.assertEqual(padding, 42)
+
+        box.child_set(child, expand=False, fill=False, padding=21, pack_type=1)
+        expand, fill, padding, pack_type = box.child_get(child, 'expand', 'fill', 'padding', 'pack-type')
+        self.assertEqual(expand, False)
+        self.assertEqual(fill, False)
+        self.assertEqual(padding, 21)
index c02581c..b73fbf9 100644 (file)
@@ -100,6 +100,13 @@ class Test(unittest.TestCase):
         self.assertFalse(info.get_fundamental())
         self.assertEqual(info.get_parent(), repo.find_by_name('GObject', 'Object'))
 
+    def test_callable_inheritance(self):
+        self.assertTrue(issubclass(GIRepository.CallableInfo, GIRepository.BaseInfo))
+        self.assertTrue(issubclass(GIRepository.CallbackInfo, GIRepository.CallableInfo))
+        self.assertTrue(issubclass(GIRepository.FunctionInfo, GIRepository.CallableInfo))
+        self.assertTrue(issubclass(GIRepository.VFuncInfo, GIRepository.CallableInfo))
+        self.assertTrue(issubclass(GIRepository.SignalInfo, GIRepository.CallableInfo))
+
     def test_registered_type_info(self):
         info = repo.find_by_name('GIMarshallingTests', 'Object')
         # Call these from the class because GIObjectInfo overrides them
@@ -213,7 +220,6 @@ class Test(unittest.TestCase):
         self.assertEqual(func_info.get_return_type().get_tag(), GIRepository.TypeTag.VOID)
         self.assertRaises(AttributeError, func_info.get_return_attribute, '_not_an_attr')
 
-    @unittest.expectedFailure  # https://bugzilla.gnome.org/show_bug.cgi?id=709462
     @unittest.skipUnless(has_cairo, 'Regress needs cairo')
     def test_signal_info(self):
         repo.require('Regress')
@@ -231,7 +237,6 @@ class Test(unittest.TestCase):
         self.assertFalse(sig_info.true_stops_emit())
         self.assertEqual(sig_info.get_flags(), sig_flags)
 
-    @unittest.expectedFailure  # https://bugzilla.gnome.org/show_bug.cgi?id=709462
     @unittest.skipUnless(has_cairo, 'Regress needs cairo')
     def test_notify_signal_info_with_obj(self):
         repo.require('Regress')
@@ -302,6 +307,22 @@ class Test(unittest.TestCase):
         self.assertEqual(vfunc.get_offset(), 0xFFFF)  # unknown offset
         self.assertEqual(vfunc.get_signal(), None)
 
+    def test_callable_can_throw_gerror(self):
+        info = repo.find_by_name('GIMarshallingTests', 'Object')
+        invoker = find_child_info(info, 'get_methods', 'vfunc_meth_with_error')
+        vfunc = find_child_info(info, 'get_vfuncs', 'vfunc_meth_with_err')
+
+        self.assertTrue(invoker.can_throw_gerror())
+        self.assertTrue(vfunc.can_throw_gerror())
+
+        # Test that args do not include the GError**
+        self.assertEqual(len(invoker.get_arguments()), 1)
+        self.assertEqual(len(vfunc.get_arguments()), 1)
+
+        # Sanity check method that does not throw.
+        invoker_no_throws = find_child_info(info, 'get_methods', 'method_int8_in')
+        self.assertFalse(invoker_no_throws.can_throw_gerror())
+
     def test_flags_double_registration_error(self):
         # a warning is printed for double registration and pygobject will
         # also raise a RuntimeError.
index 429afc9..80d4ac5 100644 (file)
@@ -136,9 +136,9 @@ class TestAccumulator(unittest.TestCase):
         inst = Foo()
         inst.my_acc_signal.connect(lambda obj: 1)
         inst.my_acc_signal.connect(lambda obj: 2)
-        ## the value returned in the following handler will not be
-        ## considered, because at this point the accumulator already
-        ## reached its limit.
+        # the value returned in the following handler will not be
+        # considered, because at this point the accumulator already
+        # reached its limit.
         inst.my_acc_signal.connect(lambda obj: 3)
         retval = inst.my_acc_signal.emit()
         self.assertEqual(retval, 3)
@@ -147,8 +147,8 @@ class TestAccumulator(unittest.TestCase):
         inst = Foo()
         inst.my_other_acc_signal.connect(self._true_handler1)
         inst.my_other_acc_signal.connect(self._true_handler2)
-        ## the following handler will not be called because handler2
-        ## returns True, so it should stop the emission.
+        # the following handler will not be called because handler2
+        # returns True, so it should stop the emission.
         inst.my_other_acc_signal.connect(self._true_handler3)
         self.__true_val = None
         inst.my_other_acc_signal.emit()
@@ -629,20 +629,20 @@ class _TestCMarshaller:
         rv = self.obj.emit("test-gvalue", v)
         self.assertEqual(rv, GObject.G_MAXINT64)
 
-        # implicit int64
-        # does not work, see https://bugzilla.gnome.org/show_bug.cgi?id=683775
-        #rv = self.obj.emit("test-gvalue", GObject.G_MAXINT64)
-        #self.assertEqual(rv, GObject.G_MAXINT64)
-
         # explicit uint64
         v = GObject.Value(GObject.TYPE_UINT64, GObject.G_MAXUINT64)
         rv = self.obj.emit("test-gvalue", v)
         self.assertEqual(rv, GObject.G_MAXUINT64)
 
+    @unittest.expectedFailure  # https://bugzilla.gnome.org/show_bug.cgi?id=705291
+    def test_gvalue_implicit_int64(self):
+        # implicit int64
+        rv = self.obj.emit("test-gvalue", GObject.G_MAXINT64)
+        self.assertEqual(rv, GObject.G_MAXINT64)
+
         # implicit uint64
-        # does not work, see https://bugzilla.gnome.org/show_bug.cgi?id=683775
-        #rv = self.obj.emit("test-gvalue", GObject.G_MAXUINT64)
-        #self.assertEqual(rv, GObject.G_MAXUINT64)
+        rv = self.obj.emit("test-gvalue", GObject.G_MAXUINT64)
+        self.assertEqual(rv, GObject.G_MAXUINT64)
 
     def test_gvalue_ret(self):
         self.assertEqual(self.obj.emit("test-gvalue-ret", GObject.TYPE_INT),
@@ -705,7 +705,6 @@ class TestSignalDecorator(unittest.TestCase):
         @GObject.SignalOverride
         def notify(self, *args, **kargs):
             self.overridden_closure_called = True
-            #GObject.GObject.notify(self, *args, **kargs)
 
         def on_notify(self, obj, prop):
             self.notify_called = True
@@ -763,7 +762,6 @@ class TestSignalDecorator(unittest.TestCase):
         obj = self.DecoratedOverride()
         obj.connect("notify", obj.on_notify)
         self.assertEqual(obj.value, 0)
-        #obj.notify.emit()
         obj.value = 1
         self.assertEqual(obj.value, 1)
         self.assertTrue(obj.overridden_closure_called)
diff --git a/tests/test_typeclass.py b/tests/test_typeclass.py
new file mode 100644 (file)
index 0000000..3ece684
--- /dev/null
@@ -0,0 +1,80 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# test_typeclass.py: Tests for GTypeClass related methods and marshalling.
+#
+# Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
+#
+# 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 St, Fifth Floor, Boston, MA  02110-1301
+# USA
+
+import unittest
+
+from gi.repository import GObject
+from gi.repository import GIMarshallingTests
+
+
+class TestCoercion(unittest.TestCase):
+    def test_coerce_from_class(self):
+        prop = GObject.ObjectClass.find_property(GIMarshallingTests.PropertiesObject,
+                                                 'some-int')
+
+        self.assertIsInstance(prop, GObject.GParamSpec)
+        self.assertEqual(prop.name, 'some-int')
+        self.assertEqual(prop.value_type, GObject.TYPE_INT)
+        self.assertEqual(prop.owner_type,
+                         GIMarshallingTests.PropertiesObject.__gtype__)
+
+    def test_coerce_from_gtype(self):
+        gtype = GIMarshallingTests.PropertiesObject.__gtype__
+        prop = GObject.ObjectClass.find_property(gtype, 'some-int')
+
+        self.assertIsInstance(prop, GObject.GParamSpec)
+        self.assertEqual(prop.name, 'some-int')
+        self.assertEqual(prop.value_type, GObject.TYPE_INT)
+        self.assertEqual(prop.owner_type, gtype)
+
+    def test_coerce_from_instance(self):
+        obj = GIMarshallingTests.PropertiesObject()
+        prop = GObject.ObjectClass.find_property(obj, 'some-int')
+
+        self.assertIsInstance(prop, GObject.GParamSpec)
+        self.assertEqual(prop.name, 'some-int')
+        self.assertEqual(prop.value_type, GObject.TYPE_INT)
+        self.assertEqual(prop.owner_type, obj.__gtype__)
+
+    def test_marshalling_error(self):
+        with self.assertRaises(TypeError):
+            GObject.ObjectClass.find_property(object, 'some-int')
+
+        with self.assertRaises(TypeError):
+            GObject.ObjectClass.find_property(42, 'some-int')
+
+
+class TestTypeClassMethodsMovedToClass(unittest.TestCase):
+    def test_list_child_properties(self):
+        pspecs = GIMarshallingTests.PropertiesObject.list_properties()
+        pnames = [pspec.name for pspec in pspecs]
+        self.assertTrue('some-int' in pnames)
+        self.assertTrue('some-float' in pnames)
+        self.assertTrue('some-char' in pnames)
+
+    def test_find_child_property(self):
+        pspec = GIMarshallingTests.PropertiesObject.find_property('some-int')
+        self.assertEqual(pspec.name, 'some-int')
+
+
+if __name__ == '__main__':
+    unittest.main()