summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog522
-rw-r--r--Makefile.am3
-rw-r--r--Makefile.in3
-rw-r--r--NEWS21
-rw-r--r--PKG-INFO4
-rwxr-xr-xconfigure42
-rw-r--r--configure.ac4
-rw-r--r--gi/Makefile.am3
-rw-r--r--gi/Makefile.in6
-rw-r--r--gi/__init__.py28
-rw-r--r--gi/_error.py54
-rw-r--r--gi/_option.py5
-rw-r--r--gi/gimodule.c17
-rw-r--r--gi/glibmodule.c19
-rw-r--r--gi/gobjectmodule.c54
-rw-r--r--gi/overrides/GIMarshallingTests.py4
-rw-r--r--gi/overrides/GLib.py29
-rw-r--r--gi/overrides/Gio.py4
-rw-r--r--gi/overrides/Gtk.py38
-rw-r--r--gi/pygboxed.c21
-rw-r--r--gi/pygenum.c1
-rw-r--r--gi/pygflags.c1
-rw-r--r--gi/pygi-argument.c40
-rw-r--r--gi/pygi-array.c2
-rw-r--r--gi/pygi-boxed.c6
-rw-r--r--gi/pygi-cache.c4
-rw-r--r--gi/pygi-error.c205
-rw-r--r--gi/pygi-error.h21
-rw-r--r--gi/pygi-foreign-api.h85
-rw-r--r--gi/pygi-foreign-cairo.c192
-rw-r--r--gi/pygi-foreign.c82
-rw-r--r--gi/pygi-foreign.h20
-rw-r--r--gi/pygi-info.c14
-rw-r--r--gi/pygi-invoke.c5
-rw-r--r--gi/pygi-property.c8
-rw-r--r--gi/pygi-property.h14
-rw-r--r--gi/pygi-signal-closure.c12
-rw-r--r--gi/pygi-signal-closure.h15
-rw-r--r--gi/pygi-struct-marshal.c267
-rw-r--r--gi/pygi-struct-marshal.h56
-rw-r--r--gi/pygi-struct.c6
-rw-r--r--gi/pygi-type.c4
-rw-r--r--gi/pygi-type.h3
-rw-r--r--gi/pygi-value.c2
-rw-r--r--gi/pygi.h107
-rw-r--r--gi/pyglib-private.h1
-rw-r--r--gi/pyglib.c199
-rw-r--r--gi/pyglib.h5
-rw-r--r--gi/pygobject-private.h3
-rw-r--r--gi/pygobject.c3
-rw-r--r--gi/pygobject.h13
-rw-r--r--gi/pygoptioncontext.c3
-rw-r--r--gi/pygoptiongroup.c3
-rw-r--r--gi/pygparamspec.c22
-rw-r--r--gi/pygpointer.c15
-rw-r--r--gi/pygspawn.c3
-rw-r--r--gi/pygtype.c5
-rw-r--r--gi/types.py15
-rw-r--r--pygtkcompat/pygtkcompat.py8
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/Makefile.in3
-rw-r--r--tests/test_cairo.py141
-rw-r--r--tests/test_error.py116
-rw-r--r--tests/test_everything.py44
-rw-r--r--tests/test_gi.py59
-rw-r--r--tests/test_gio.py6
-rw-r--r--tests/test_iochannel.py2
-rw-r--r--tests/test_option.py2
-rw-r--r--tests/test_overrides_gtk.py92
-rw-r--r--tests/test_repository.py25
-rw-r--r--tests/test_signal.py28
-rw-r--r--tests/test_typeclass.py80
72 files changed, 2115 insertions, 837 deletions
diff --git a/ChangeLog b/ChangeLog
index fc22733..1998f37 100644
--- 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
diff --git a/Makefile.am b/Makefile.am
index 208ed13..968b6c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/Makefile.in b/Makefile.in
index ff37526..dba6bc8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -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
--- 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)
diff --git a/PKG-INFO b/PKG-INFO
index f1eca4b..397928c 100644
--- 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
diff --git a/configure b/configure
index eca8ab5..c83c26e 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pygobject 3.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\\"
diff --git a/configure.ac b/configure.ac
index a21c489..77fe449 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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)
diff --git a/gi/Makefile.am b/gi/Makefile.am
index b00d30a..6fb1c5d 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -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) \
diff --git a/gi/Makefile.in b/gi/Makefile.in
index 82ee5e7..256b41a 100644
--- a/gi/Makefile.in
+++ b/gi/Makefile.in
@@ -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 = \
diff --git a/gi/__init__.py b/gi/__init__.py
index 7c1a279..df6843c 100644
--- a/gi/__init__.py
+++ b/gi/__init__.py
@@ -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
index 0000000..6b684ce
--- /dev/null
+++ b/gi/_error.py
@@ -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
diff --git a/gi/_option.py b/gi/_option.py
index 422c53f..2d30abf 100644
--- a/gi/_option.py
+++ b/gi/_option.py
@@ -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
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 25fc3d6..44a8fbd 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -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
diff --git a/gi/glibmodule.c b/gi/glibmodule.c
index e859158..297805a 100644
--- a/gi/glibmodule.c
+++ b/gi/glibmodule.c
@@ -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);
diff --git a/gi/gobjectmodule.c b/gi/gobjectmodule.c
index a20d93a..458884b 100644
--- a/gi/gobjectmodule.c
+++ b/gi/gobjectmodule.c
@@ -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,
diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py
index cc967b4..b675adf 100644
--- a/gi/overrides/GIMarshallingTests.py
+++ b/gi/overrides/GIMarshallingTests.py
@@ -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):
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index 0e8f694..214d507 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -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']
diff --git a/gi/overrides/Gio.py b/gi/overrides/Gio.py
index 5a5dd2f..e646821 100644
--- a/gi/overrides/Gio.py
+++ b/gi/overrides/Gio.py
@@ -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
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index df55c2d..561bdf0 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -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
diff --git a/gi/pygboxed.c b/gi/pygboxed.c
index 35716a2..9faa652 100644
--- a/gi/pygboxed.c
+++ b/gi/pygboxed.c
@@ -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;
diff --git a/gi/pygenum.c b/gi/pygenum.c
index 1b9b50e..053518f 100644
--- a/gi/pygenum.c
+++ b/gi/pygenum.c
@@ -26,6 +26,7 @@
#include <pyglib.h>
#include "pygobject-private.h"
#include "pygi.h"
+#include "pygi-type.h"
#include "pygenum.h"
diff --git a/gi/pygflags.c b/gi/pygflags.c
index c14bf7d..a7df8ce 100644
--- a/gi/pygflags.c
+++ b/gi/pygflags.c
@@ -28,6 +28,7 @@
#include "pygflags.h"
#include "pygi.h"
+#include "pygi-type.h"
GQuark pygflags_class_key;
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 4094c3d..15be78c 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -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;
diff --git a/gi/pygi-array.c b/gi/pygi-array.c
index c17ace0..fceffc6 100644
--- a/gi/pygi-array.c
+++ b/gi/pygi-array.c
@@ -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;
}
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index c52858b..b46cdcc 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -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;
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index c8da66f..24bb1a4 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -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));
diff --git a/gi/pygi-error.c b/gi/pygi-error.c
index 349bb7e..2e9150f 100644
--- a/gi/pygi-error.c
+++ b/gi/pygi-error.c
@@ -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>
*
@@ -23,6 +25,194 @@
#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");
+}
+
diff --git a/gi/pygi-error.h b/gi/pygi-error.h
index fdeb32f..72d2be0 100644
--- a/gi/pygi-error.h
+++ b/gi/pygi-error.h
@@ -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
@@ -25,10 +27,21 @@
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
index 0000000..9367518
--- /dev/null
+++ b/gi/pygi-foreign-api.h
@@ -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__ */
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 8261a07..5937759 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -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;
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index f3c1a34..82392be 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -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 ();
+ }
+}
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index 478d759..afa4768 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -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__ */
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 065d470..43ee711 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -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,
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 4af2e72..eebf959 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -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;
}
}
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
index 6f80506..f7cb032 100644
--- a/gi/pygi-property.c
+++ b/gi/pygi-property.c
@@ -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;
diff --git a/gi/pygi-property.h b/gi/pygi-property.h
index 875d21e..5678bc3 100644
--- a/gi/pygi-property.h
+++ b/gi/pygi-property.h
@@ -27,13 +27,15 @@
#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__ */
diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c
index c5f51af..079669c 100644
--- a/gi/pygi-signal-closure.c
+++ b/gi/pygi-signal-closure.c
@@ -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;
diff --git a/gi/pygi-signal-closure.h b/gi/pygi-signal-closure.h
index ffdd29c..5cc191b 100644
--- a/gi/pygi-signal-closure.h
+++ b/gi/pygi-signal-closure.h
@@ -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
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 7346eae..9abaaae 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -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;
}
diff --git a/gi/pygi-struct-marshal.h b/gi/pygi-struct-marshal.h
index 66e3ecf..6a7f92d 100644
--- a/gi/pygi-struct-marshal.h
+++ b/gi/pygi-struct-marshal.h
@@ -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
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
index b1db8a4..692068b 100644
--- a/gi/pygi-struct.c
+++ b/gi/pygi-struct.c
@@ -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;
diff --git a/gi/pygi-type.c b/gi/pygi-type.c
index b8d4c65..924e0b8 100644
--- a/gi/pygi-type.c
+++ b/gi/pygi-type.c
@@ -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);
diff --git a/gi/pygi-type.h b/gi/pygi-type.h
index 822a441..85f7551 100644
--- a/gi/pygi-type.h
+++ b/gi/pygi-type.h
@@ -21,12 +21,13 @@
#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 */
diff --git a/gi/pygi-value.c b/gi/pygi-value.c
index 8235116..f54f8e1 100644
--- a/gi/pygi-value.c
+++ b/gi/pygi-value.c
@@ -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");
diff --git a/gi/pygi.h b/gi/pygi.h
index a67696e..2a9ee14 100644
--- 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__ */
diff --git a/gi/pyglib-private.h b/gi/pyglib-private.h
index 3569c6b..78dd489 100644
--- a/gi/pyglib-private.h
+++ b/gi/pyglib-private.h
@@ -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
diff --git a/gi/pyglib.c b/gi/pyglib.c
index 6c52f31..8db9b17 100644
--- a/gi/pyglib.c
+++ b/gi/pyglib.c
@@ -28,205 +28,6 @@
#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:
diff --git a/gi/pyglib.h b/gi/pyglib.h
index 544bada..00228dd 100644
--- a/gi/pyglib.h
+++ b/gi/pyglib.h
@@ -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. */
diff --git a/gi/pygobject-private.h b/gi/pygobject-private.h
index be565d6..b6242cd 100644
--- a/gi/pygobject-private.h
+++ b/gi/pygobject-private.h
@@ -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);
diff --git a/gi/pygobject.c b/gi/pygobject.c
index 04fd6a5..1a011e1 100644
--- a/gi/pygobject.c
+++ b/gi/pygobject.c
@@ -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);
diff --git a/gi/pygobject.h b/gi/pygobject.h
index 76b8b11..85359a5 100644
--- a/gi/pygobject.h
+++ b/gi/pygobject.h
@@ -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,
diff --git a/gi/pygoptioncontext.c b/gi/pygoptioncontext.c
index f6bb223..ab439f0 100644
--- a/gi/pygoptioncontext.c
+++ b/gi/pygoptioncontext.c
@@ -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;
}
diff --git a/gi/pygoptiongroup.c b/gi/pygoptiongroup.c
index 613232f..4c1664d 100644
--- a/gi/pygoptiongroup.c
+++ b/gi/pygoptiongroup.c
@@ -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;
diff --git a/gi/pygparamspec.c b/gi/pygparamspec.c
index 9e6c467..ff53243 100644
--- a/gi/pygparamspec.c
+++ b/gi/pygparamspec.c
@@ -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;
}
diff --git a/gi/pygpointer.c b/gi/pygpointer.c
index 2729695..d728a40 100644
--- a/gi/pygpointer.c
+++ b/gi/pygpointer.c
@@ -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;
diff --git a/gi/pygspawn.c b/gi/pygspawn.c
index 8f3ff51..3851ad9 100644
--- a/gi/pygspawn.c
+++ b/gi/pygspawn.c
@@ -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);
diff --git a/gi/pygtype.c b/gi/pygtype.c
index 131a271..985e969 100644
--- a/gi/pygtype.c
+++ b/gi/pygtype.c
@@ -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;
}
}
diff --git a/gi/types.py b/gi/types.py
index e6e3903..aa5bcb4 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -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()
diff --git a/pygtkcompat/pygtkcompat.py b/pygtkcompat/pygtkcompat.py
index d5b7b94..7ee2de4 100644
--- a/pygtkcompat/pygtkcompat.py
+++ b/pygtkcompat/pygtkcompat.py
@@ -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
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3468740..c0f34f8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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 \
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5b94b34..cdadc6f 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -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
index 0000000..fdf86a2
--- /dev/null
+++ b/tests/test_cairo.py
@@ -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
index 0000000..baccef5
--- /dev/null
+++ b/tests/test_error.py
@@ -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()
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 0cd1804..f6017e4 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -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)
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 9846440..4a5d510 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -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
diff --git a/tests/test_gio.py b/tests/test_gio.py
index 57ab013..986d6dc 100644
--- a/tests/test_gio.py
+++ b/tests/test_gio.py
@@ -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(), [])
diff --git a/tests/test_iochannel.py b/tests/test_iochannel.py
index 0cc1b4b..259171b 100644
--- a/tests/test_iochannel.py
+++ b/tests/test_iochannel.py
@@ -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)
diff --git a/tests/test_option.py b/tests/test_option.py
index 2900edd..fe25746 100644
--- a/tests/test_option.py
+++ b/tests/test_option.py
@@ -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()
diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py
index 2a0fd90..d339adf 100644
--- a/tests/test_overrides_gtk.py
+++ b/tests/test_overrides_gtk.py
@@ -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)
diff --git a/tests/test_repository.py b/tests/test_repository.py
index c02581c..b73fbf9 100644
--- a/tests/test_repository.py
+++ b/tests/test_repository.py
@@ -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.
diff --git a/tests/test_signal.py b/tests/test_signal.py
index 429afc9..80d4ac5 100644
--- a/tests/test_signal.py
+++ b/tests/test_signal.py
@@ -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
index 0000000..3ece684
--- /dev/null
+++ b/tests/test_typeclass.py
@@ -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()