summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:41:54 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-07-12 08:41:58 +0900
commit4bfc3de521c8d93613e5153028da35406609a64f (patch)
tree98175ed0ab42bc56bec3d45d69364a988a00de1f /gi
parent5a89ec21697bd9e08c9102b2a7b6c60b4652e66c (diff)
downloadpygobject2-4bfc3de521c8d93613e5153028da35406609a64f.tar.gz
pygobject2-4bfc3de521c8d93613e5153028da35406609a64f.tar.bz2
pygobject2-4bfc3de521c8d93613e5153028da35406609a64f.zip
Imported Upstream version 3.13.2
Change-Id: Icce9be2c1bf0568fc95f75ff0a714c017e6171ec Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'gi')
-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
51 files changed, 1058 insertions, 686 deletions
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()